API — ICoreBlocks/ICoreStudio/Registry
The public contract of 3 header(s) under src/ICoreBlocks/ICoreStudio/Registry — 4 class/struct definition(s), 72 declaration(s). Each section shows the header's banner and its public (and protected-virtual) surface exactly as the file writes it.
ICoreStudioRegistry.h#
src/ICoreBlocks/ICoreStudio/Registry/ICoreStudioRegistry.h
ICoreStudioToolWindow#
ICoreStudioRegistry.h:23 · struct · 1 declaration(s)
A window a module opens from the editor (ED8.2): ICore 3D today.
struct ICoreStudioToolWindow {
public:
std::string title; // "ICore 3D" -- the menu item's and the rail button's text
std::string iconPath; // a resource path (":/SVGs/..."), or empty for none
std::function<void()> open;
};
};
ICoreStudioRegistry#
ICoreStudioRegistry.h:29 · class · 42 declaration(s)
class ICoreStudioRegistry {
public:
static long initializeStudioRegistry();
static void forceCloseSoftware();
// The app's one hover info label, parented to nothing so it can float over
// whichever window the cursor is on. Null until the registry is initialized.
static ICoreInfoLabel* getInfoLabel();
// ====================[Windows and dialogs]======================
// Every top level the studio puts on screen is tracked here so shutdown can
// walk them.
//
// ICoreWindow and ICoreDialog know NOTHING about this registry. They used
// to register themselves from their own constructors and destructors, which
// made two general-purpose UI classes depend on a studio-level singleton
// and gave callers no say in it. The traffic runs one way now: ask here for
// a window or a dialog, and what comes back is already tracked.
//
// auto* navigator = ICoreStudioRegistry::requestNewWindow<ICoreProjectNavigator>();
// auto* dialog = ICoreStudioRegistry::requestNewDialog<ICoreDialog>(parent);
//
// Subclasses go through the same door -- the template constructs whatever
// type is named, forwarding its constructor arguments, so there is no
// separate path for ICoreProjectNavigator or ICoreSubsystemPickerDialog to
// slip through untracked.
//
// Deregistration is NOT the delete function's job. It is driven off the
// object's destructor (via the lifetime hook installed below), because most
// of these windows are never deleted through requestDeleteWindow: the
// project navigator carries WA_DeleteOnClose, and a parented dialog is
// destroyed by its parent. Hooking only the deliberate path would leave
// dangling pointers here for every other one.
template <typename WindowT, typename... Args>
static WindowT* requestNewWindow(Args&&... args) {
static_assert(std::is_base_of_v<ICoreWindow, WindowT>,
"requestNewWindow only builds ICoreWindow and its subclasses");
WindowT* window = new WindowT(std::forward<Args>(args)...);
adoptWindow(window);
return window;
}
static void requestDeleteWindow(ICoreWindow* window);
template <typename DialogT, typename... Args>
static DialogT* requestNewDialog(Args&&... args) {
static_assert(std::is_base_of_v<ICoreDialog, DialogT>,
"requestNewDialog only builds ICoreDialog and its subclasses");
DialogT* dialog = new DialogT(std::forward<Args>(args)...);
adoptDialog(dialog);
return dialog;
}
static void requestDeleteDialog(ICoreDialog* dialog);
// The plain QWidget top levels -- detached menu panels, block code editors,
// decorated windows -- are tracked through this pair instead. Still
// self-registering from ICoreWidget; untouched by the change above.
static void registerWidgetAsWindow(ICoreWidget* widget);
static void unregisterWidgetAsWindow(ICoreWidget* widget);
static std::pair<ICoreWindow*, ICoreStudioSurface*> requestNewEditorWindow();
static void closeAllWindows();
// True when one of the windows this registry holds is the active window --
// the application is in front and the user is in it. Read by the telemetry
// tick (ACCOUNT_MANAGER A6.6) to decide whether time counts as foreground.
// Only ICoreWindow can answer the question: dialogs and widget top levels
// carry no isActiveWindow(), so time spent in one of those reads as away.
[[nodiscard]] static bool anyWindowIsActive();
static ICoreFloatingElementsWindow* getFloatingElementsWindow();
// The app's one menu strip, owned by the primary window. Registered there
// so anything that has to reach it -- the toggle on the editor's top panel
// -- does not have to know about ICorePrimaryWindow. Null until the primary
// window has built it.
static void registerMainMenuBar(ICoreMenuBar* menuBar);
static ICoreMenuBar* getMainMenuBar();
// The one account panel (ACCOUNT_MANAGER A8.2 -- its own panel, not a
// Preferences section). Registered by the primary window, which OWNS it, so
// that anything with a reason to open it -- the Account button on the
// editor's top panel, the licence banner -- does not have to know about
// ICorePrimaryWindow. The same shape and the same reason as the menu strip
// above.
//
// ⚠ AN OPENER, NOT THE PANEL. What the callers need is "put it on screen",
// and there must be exactly ONE panel to put there: two would show one
// licence twice and let a user press "deactivate this machine" on the stale
// one. Handing out the widget would let a caller build a second.
//
// openAccountPanel() is a NO-OP until the primary window has registered
// one, which is the honest answer for a --console session that has no
// window at all.
static void registerAccountPanelOpener(std::function<void()> open);
static void openAccountPanel();
// ---- startup steps, for the application's startup screen -------------
//
// Building the primary window is most of what startup costs (the studio
// surface and its block library, then the first canvas), and it is built
// here, one layer below the Shell that reports startup to the caller
// (icore::StartupProgress). The Shell installs a reporter for the length of
// startup; the window reports its big steps through it and does not know
// who is listening. reportStartupStep() is a NO-OP with none installed --
// every window after the first, a headless run, an embedder that asked for
// no reports. Pass an empty function to uninstall.
static void setStartupStepReporter(
std::function<void(const std::string& status, double fraction)> reporter);
static void reportStartupStep(const std::string& status, double fraction);
// A module's own top-level window, reachable from the editor (ED8.2). Each
// registered entry is an item under "Windows" at the end of the Tools menu
// and a button at the end of the "Tools" section of every editor's left
// rail -- the SAME list, so the two can never disagree.
//
// ⚠ REGISTER DURING START-UP, before the primary window exists. The menu is
// built once, with the primary window, and each rail when its editor is;
// neither re-reads the list, so an entry added later appears in neither.
// A module registers from its registerAll(), which Shell/Initialization.cpp
// runs first. An entry without an `open` is ignored.
static void registerToolWindow(ICoreStudioToolWindow entry);
[[nodiscard]] static std::vector<ICoreStudioToolWindow> toolWindows();
// Registering applies the solver state the other bars are in; a bar that
// can die before the app does deregisters in its destructor.
static void registerRunToolBar(ICoreRunToolBar *toolBar);
static void unregisterRunToolBar(const ICoreRunToolBar *toolBar);
static void setSolverStartedRunToolBar();
static void setDebugModeStartedRunToolBar();
static void setSolverPausedRunToolBar();
static void setSolverStoppedRunToolBar();
static void setModelBuildingRunToolBar();
static ICoreTimeLine* requestTimeLine(ICorePrimaryWindow* parent);
static void refreshStartTimeUIs();
static void refreshStopTimeUIs();
static void resetProgressBarUpdates();
static void enableAutoProgressBarUpdates();
static void disableAutoProgressBarUpdates();
// ====================[Solver UIs]======================
// Called from the solver thread: each one hops onto the GUI thread before
// touching the tool bars and time lines above.
static void resetProgressUIs();
static void setModelBuildStartedUIs();
static void setModelBuildFinishedUIs(const bool& succeeded);
static void setSolverStartedUIs();
static void setDebugModeStartedUIs();
static void setSolverPausedUIs();
static void setSolverStoppedUIs(const bool& wasAborted);
static void setSolverStartupAbortedUIs();
};
ICoreStudioStaticCommands.h#
src/ICoreBlocks/ICoreStudio/Registry/ICoreStudioStaticCommands.h
ICoreStudioStaticCommands#
ICoreStudioStaticCommands.h:21 · class · 4 declaration(s)
The UI half of the static-helper pair.
class ICoreStudioStaticCommands {
public:
static std::unordered_map<std::string, std::string> serializeFont(const ICoreFont& font, const std::string& prefix = "");
static ICoreFont loadSerializedFont(const std::unordered_map<std::string, std::string>& serializedState);
static std::unordered_map<std::string, std::string> serializeColor(const ICoreColor& color, const std::string& prefix = "");
static ICoreColor loadSerializedColor(const std::unordered_map<std::string, std::string>& serializedState);
};
};
ICoreStudioSurfaceRegistry.h#
src/ICoreBlocks/ICoreStudio/Registry/ICoreStudioSurfaceRegistry.h
withLeftFixedPanelis the primary window's alone -- see ICoreStudioSurface's constructor. A spawned editor window's surface has no rail.
ICoreStudioSurfaceRegistry#
ICoreStudioSurfaceRegistry.h:14 · class · 25 declaration(s)
class ICoreStudioSurfaceRegistry {
public:
static long initializeStudioSurfaceRegistry();
// `withLeftFixedPanel` is the primary window's alone -- see ICoreStudioSurface's
// constructor. A spawned editor window's surface has no rail.
static ICoreStudioSurface* requestNewStudioSurface_WithoutWindow(ICoreWidget* parent,
bool withLeftFixedPanel = false);
// static std::pair<ICoreWindow*, ICoreStudioSurface*> requestNewStudioSurface_WithWindow(); // Moved to Main Registry
static void requestDeleteStudioSurface(const ICoreStudioSurface* paneToDelete);
static void setFocusedStudioSurface(ICoreStudioSurface* newFocusedStudioSurface);
static ICoreStudioSurface* getFocusedStudioSurface();
// The app's ONE left rail -- the primary window's -- whichever window is
// asking. Null before the primary window has built it and after it is gone.
static ICoreLeftFixedPanel* getAppLeftFixedPanel();
static void checkOutCanvasPointers(ICoreCanvas *canvasToCheckOut);
static bool checkIfTreeNodeLoadedToAnyTab(const ICoreSubsystemTreeNode* nodeToCheck);
static void ensureAllStudioSurfacesShowingTheLoadedDirectories();
// Batches ensureAllStudioSurfacesShowingTheLoadedDirectories() (per-subsystem
// undo, H13). While deferred, a call only records that a refresh is owed; the matching
// resume runs it ONCE if one is. Nests. A whole replay holds it across the wipe:
// every subsystem the wipe deletes used to rebuild every window's navigation bar,
// and each rebuilt segment builds a context menu that creates a native window --
// measured as 193 of 193 main-thread samples of an undo at 200 blocks / 41 levels.
static void deferLoadedDirectoryRefresh();
// Returns whether it ran the owed refresh.
static bool resumeLoadedDirectoryRefresh();
static void deleteAllTabsWithoutLoadedTreeNode();
// Deletes every tab showing a node the user is not allowed to see under the registry's
// current navigation-root access setting (and every tab with no node at all). With access
// switched on nothing outside Home is off-limits, so only the node-less tabs go.
static void deleteAllTabsOutsideHomeTreeNode();
// Re-applies the navigation-root access setting to what is already on screen: sweeps the
// tabs that may no longer be shown, then redraws each window's breadcrumb, tab-header
// names and nav buttons. The navigators rebuild on every open, so they need no refresh.
static void applyNavigationAccessToOpenWindows();
// While paused, deleteAllTabsWithoutLoadedTreeNode() and deleteAllTabsOutsideHomeTreeNode()
// no-op. Used by ICoreStudioStateMachine::undo()/redo() to skip tab cleanup during recipe replay.
static void pauseTabCleanup();
static void resumeTabCleanup();
// An undo/redo step brackets its replay with these two: every tab remembers where
// its origin anchor sits, then is re-pointed at the rebuilt node and put back under
// the same view (ICoreTab::rememberOriginAnchorPosition()).
static void rememberAllTabsOriginAnchorPositions();
static void refreshAllTabsLoadedTreeNodePointers();
// Re-runs each tab's per-load passes over the node it is already showing.
// ICoreStudioStateMachine::applyRecipeSnapshot() calls this after a replay: the
// replay repopulates a node UNDER a loaded tab, so ICoreTab::loadTreeNode() --
// which is where those passes otherwise run -- is never reached.
static void rerunPerLoadPassesOnAllTabs();
// `posToCheck` is in DESKTOP space -- ICoreCursor::pos() -- because the bar
// may be in any window (`W10.123`). A bar the point is on beats one it is
// merely near.
static ICoreTabHeadersBar* getTabHeadersBarUnderCursor(const ICorePoint& posToCheck);
static void resetTabHeadersReceivingStyle(const ICoreTabHeadersBar* barToExclude);
static void clearAllCanvasesSelections();
// Used by ICoreCanvasObjectCreationMode to show/clear the crosshair on every canvas
// Narrowed to the shape enum at P2.9d-5c -- see the retraction note on the
// body before widening it again.
static void setAllCanvasesCursor(ICoreCursorShape shape);
static void unsetAllCanvasesCursors();
static void ungrabMouseFromAllScenes();
static void refreshAllCanvasesUIs();
};
};