Generated reference › API — ICoreBlocks/ICoreStudio/StudioObjects/StudioSurface
kind: generated#api#icoreblocks-icorestudio-studioobjects-studiosurface

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.

HeaderDefinesDeclarationsBases
ICoreFloatingPanelsGraphicsView.hICoreFloatingPanelsGraphicsView3public ICoreGraphicsView
ICoreStudioSurface.hICoreStudioSurface36public 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;
};