API — ICoreBlocks/ICoreStudio/StudioObjects/StudioSurface
The public contract of 2 header(s) under src/ICoreBlocks/ICoreStudio/StudioObjects/StudioSurface — 2 class/struct definition(s), 39 declaration(s). Each section shows the header's banner and its public (and protected-virtual) surface exactly as the file writes it.
| Header | Defines | Declarations | Bases |
|---|---|---|---|
ICoreFloatingPanelsGraphicsView.h | ICoreFloatingPanelsGraphicsView | 3 | public ICoreGraphicsView |
ICoreStudioSurface.h | ICoreStudioSurface | 36 | public ICoreWidget |
ICoreFloatingPanelsGraphicsView.h#
src/ICoreBlocks/ICoreStudio/StudioObjects/StudioSurface/ICoreFloatingPanelsGraphicsView.h
No Q_OBJECT: ICoreGraphicsView is no longer a QObject (P2.11b), and this class declared no signal, slot, property or Q_INVOKABLE, and nothing qobject_casts to it. Checked before removing rather than inferred.
ICoreFloatingPanelsGraphicsView#
ICoreFloatingPanelsGraphicsView.h:10 · class · bases public ICoreGraphicsView · pImpl · 3 declaration(s)
class ICoreFloatingPanelsGraphicsView : public ICoreGraphicsView {
public:
explicit ICoreFloatingPanelsGraphicsView(ICoreWidget* parent = nullptr);
ICoreGraphicsScene* getScene();
~ICoreFloatingPanelsGraphicsView() override;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreStudioSurface.h#
src/ICoreBlocks/ICoreStudio/StudioObjects/StudioSurface/ICoreStudioSurface.h
withLeftFixedPanel: build the left rail and every page it slides out (the Library, the navigator, the tools). ONLY the primary window's surface asks for it (owner, 2026-09-25): the app has ONE rail, and a spawned editor window -- one a tab was dragged into -- is a canvas with its top bar and nothing else. Building a Library per dragged tab cost the bulk of a surface's construction and bought a second copy of a panel that already exists.
ICoreStudioSurface#
ICoreStudioSurface.h:19 · class · bases public ICoreWidget · pImpl · 36 declaration(s)
class ICoreStudioSurface : public ICoreWidget {
public:
// `withLeftFixedPanel`: build the left rail and every page it slides out
// (the Library, the navigator, the tools). ONLY the primary window's
// surface asks for it (owner, 2026-09-25): the app has ONE rail, and a
// spawned editor window -- one a tab was dragged into -- is a canvas with
// its top bar and nothing else. Building a Library per dragged tab cost the
// bulk of a surface's construction and bought a second copy of a panel that
// already exists.
explicit ICoreStudioSurface(ICoreWidget *parent = nullptr, bool withLeftFixedPanel = false);
// ======= Tab Manager
//
// A tab INDEX is a position in getAllTabs(), which is also the order the
// headers are drawn in (`W10.123` -- the two used to drift: a header was
// inserted by layout slot and the tab appended to the list regardless).
// -1, or anything past the end, means "at the end".
ICoreTab* addNewTab(int newTabIndex, ICoreSubsystemTreeNode* treeNodeToLoad);
void acquireOwnership_Tab(ICoreTab* tab, ICoreSubsystemTreeNode* treeNodeToLoad, int tabIndex = -1);
void giveOwnershipUp_Tab(const ICoreTab* tab);
// Moves one of this surface's own tabs to `tabIndex`, counted among the
// OTHER tabs -- the index a drop target reports, since the dragged tab's own
// slot is not a place it can be dropped. Focus and canvas are untouched.
void moveTab(ICoreTab* tab, int tabIndex);
// Where a tab dropped at `desktopPoint` would go: the number of tabs other
// than `ignoring` whose header centre lies left of the point.
[[nodiscard]] int tabInsertionIndexAt(const ICorePoint& desktopPoint, const ICoreTab* ignoring) const;
// The tab a drop at `tabIndex` lands in front of, or null for the end.
[[nodiscard]] ICoreTab* tabAtInsertionIndex(int tabIndex, const ICoreTab* ignoring) const;
// True when this surface is hosted in a spawned editor window -- one that
// closes once its last tab leaves -- rather than in the primary window.
[[nodiscard]] bool isInSpawnedEditorWindow() const;
void deleteTab(ICoreTab* tabToDelete);
void setFocusedTab(ICoreTab* tabToBeFocused);
void resetTabFocus();
void sendParentWindowToFront() const;
void closeAllTabs();
void deleteAllTabs_NoAnimation();
// No-op unless this editor is empty AND hosted in a spawned ICoreWindow;
// the primary window's editor stays open showing the new-tab panel.
void closeParentWindowIfEmpty();
// Call before the window hosting this surface is destroyed. See the .cpp:
// a canvas left in the dying scene has its item tree deleted underneath it,
// and the recycle pool hands the wreckage back on the next new tab.
void releaseCanvasBeforeWindowTeardown() const;
void loadNavigationBar(const std::string& pathToLoad) const;
void ensureNavBarHasTheLoadedPath();
ICoreCanvasParent* getCanvasParent() const;
ICoreWidget* getTabHeaderBar() const;
ICoreTabHeadersBar* getTabHeadersBar() const;
std::vector<ICoreTab*> getAllTabs();
ICoreTab* getFocusedTab() const;
ICoreInfoLabel* getInfoLabel() const;
void toggleToNewStudioSurfacel();
void toggleToCanvasParent() const;
// ⚠ NULL ON EVERY SURFACE BUT THE PRIMARY WINDOW'S -- see the constructor.
// A caller that wants "the rail" whichever window it is acting for asks
// ICoreStudioSurfaceRegistry::getAppLeftFixedPanel() instead.
ICoreLeftFixedPanel* getLeftFixedPanel() const;
ICoreTopFixedPanel* getTopFixedPanel() const;
// ⚠⚠ IS THIS POINT UNDER A PANEL THAT FLOATS OVER THE CANVAS? (`W10.84` /
// `W10.56`.) ⚠ `point` MUST BE IN mapToScreen SPACE -- what
// ICoreWidget::mapToScreen() answers on this backend, which the caller gets
// for a canvas point from ICoreGraphicsView::mapViewportToGlobal(). The
// panels are put into the same space here, so the two are comparable on all
// three seats without either side naming one.
//
// ⚠⚠ THE CANVAS LIES **UNDER** EVERY FLOATING PANEL, WHICH IS WHY THIS HAS
// TO EXIST. Measured: a wheel notch anywhere in the window reaches the
// canvas with an `event.pos` that tracks the pointer exactly, so a notch the
// panel above did not consume -- over its scroll bar, its header, a gap
// between its children, or the band at its bottom edge -- falls straight
// through and ZOOMS THE DIAGRAM UNDER THE PANEL THE USER IS POINTING AT.
// Making every one of those regions consume the wheel individually is a list
// nobody can finish; asking "is the pointer over a panel at all" is one
// question with one answer.
[[nodiscard]] bool isPointOverFloatingPanel(const ICorePoint& point) const;
// ⚠⚠ ANY OTHER WIDGET THAT FLOATS OVER THE CANVAS, REGISTERED RATHER THAN
// ENUMERATED (`W10.97`, 2026-09-21). The three panels above are members of
// this surface and are tested by name; everything else that can end up on
// top of the canvas -- a hover card, a drop-down, a transient overlay owned
// by somebody else entirely -- says so here and is covered by the same one
// question.
//
// ⚠ THE LIST ABOVE IS WHY THIS EXISTS. isPointOverFloatingPanel's own
// banner rejects "make every region consume the wheel" as a list nobody can
// finish, and then answers from a list of three panels, which has the same
// defect one level up. It took exactly one new floating surface to find it:
// the Library's hover card had been invisible on one backend for its whole
// life, so when `W10.88` made it appear, every notch over it zoomed the
// diagram underneath. 📌 *A rule that protects a fixed set protects the set,
// not the rule.*
//
// Registration is by raw pointer and is NOT ownership; a registered widget
// must deregister before it dies. A widget that is hidden stays registered
// and simply does not cover anything -- the test asks isVisible() -- so a
// show/hide overlay registers ONCE and never touches this again.
void registerFloatingOverlay(const ICoreWidget* overlay);
void unregisterFloatingOverlay(const ICoreWidget* overlay);
ICoreCopilotFloatingButton* getCopilotFloatingButton() const;
// Notice strips shown UNDER THE TOP PANEL rather than under the window's
// title bar -- the licence banner (owner, 2026-09-25) and, since
// 2026-09-28, the update banner (owner: "same as the license banner").
// Each `strip` must be built with this surface as its parent; the surface
// floats them over the canvas like the panel above, spans the panel's body,
// STACKS THE VISIBLE ONES in the order they were added, re-places them when
// the surface is resized, and counts each as a floating panel for
// isPointOverFloatingPanel(). A strip still decides its own visibility --
// and must call relayoutStripsUnderTopPanel() when it changes it, or the
// one below keeps a gap (or sits under it). Null is ignored.
void addStripUnderTopPanel(ICoreWidget* strip);
void relayoutStripsUnderTopPanel();
~ICoreStudioSurface() override;
protected:
void resized(const ICoreSizeF& newSize, const ICoreSizeF& oldSize) override;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};