API — ICoreEssentials/UI/Windows
The public contract of 8 header(s) under src/ICoreEssentials/UI/Windows — 9 class/struct definition(s), 87 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 |
|---|---|---|---|
ICoreDialog.h | ICoreDialog | 25 | public ICoreNativeWidget |
ICoreFloatingElementsWindow.h | — | 0 | — |
ICoreInputDialog.h | ICoreInputDialog | 2 | — |
ICoreMessageBox.h | ICoreMessageBox | 4 | — |
ICoreNativeDialogs.h | ICoreFileDialog, ICoreColorDialog, ICoreFontDialog, ICoreDesktopReveal | 10 | — |
ICoreShortcut.h | ICoreShortcut | 4 | — |
ICoreWindow.h | ICoreWindow | 42 | public ICoreNativeWidget |
ICoreWindowAccess.h | — | 0 | — |
ICoreDialog.h#
src/ICoreEssentials/UI/Windows/ICoreDialog.h
Q1.3: the ctor's QWidget* parent became ICoreNativeWidget*, which was the last QWidget on this header. <QWidget> is gone rather than forward-declared -- nothing here names the type at all any more.
ICoreDialog#
ICoreDialog.h:26 · class · bases public ICoreNativeWidget · pImpl · 25 declaration(s)
P5.11: converted.
class ICoreDialog : public ICoreNativeWidget {
public:
ICoreNativeHandle nativeWidgetHandle() const override;
// E1b: this parameter was named `contentToPopulate`, was never passed
// anything by its one call site and was dropped on the floor -- the body
// passed a literal nullptr to QDialog. It is the parent now, and it is
// forwarded.
//
// That is what makes ICoreDialog adoptable as a BASE. A QDialog subclass
// outside StudioObjects passes its parent up (ICoreSubsystemPickerDialog is
// the first), and a base that silently discarded it would have changed
// modality, stacking and ownership at every such site while compiling
// cleanly -- the kind of adoption that looks like a rename and is not one.
explicit ICoreDialog(ICoreNativeWidget* parent = nullptr);
// Mirrors of the QDialog outcome signals.
ICoreSignal<> onAccepted;
ICoreSignal<> onRejected;
void moveToScreenBottomRightCorner(const double& padding_x = 20, const double& padding_y = 20);
// Runs from the destructor, whichever way this dialog dies -- an explicit
// delete, or destruction by its parent widget.
//
// A bare callback, not a call to any particular tracker. This destructor
// used to name ICoreStudioRegistry, which put an ICoreEssentials class in
// debt to a studio-level singleton one layer up; it compiled only because
// the precompiled header happened to pull that declaration in, so the
// dependency was invisible at this file and would have broken the moment
// this file was built without the PCH. Whoever owns the dialog's lifetime
// installs this instead -- today that is
// ICoreStudioRegistry::requestNewDialog, which this file no longer knows.
//
// ONE slot, not a subscription list: a second call REPLACES the first, and
// on a registry-issued dialog that silently unhooks the registry. See the
// same note on ICoreWindow::setDestroyedHook.
void setDestroyedHook(std::function<void()> hook);
// ------------------------------------------------------------------
// Facade members now that the QDialog base is gone; the flip's harvest
// enumerated them.
// ------------------------------------------------------------------
// Unscoped so `ICoreDialog::Accepted` call sites read unchanged; pinned
// to the toolkit's values in the .cpp.
enum DialogCode { Rejected = 0, Accepted = 1 };
int exec();
void accept();
void reject();
void open();
void close();
void show();
void hide();
void resize(int width, int height);
void setWindowTitle(const ICoreString& title);
void setFixedSize(int width, int height);
void setMinimumSize(int width, int height);
void setMinimumWidth(int width);
void raise();
void activateWindow();
void setModal(bool modal);
[[nodiscard]] int width() const;
[[nodiscard]] int height() const;
void setStyleSheet(const ICoreString& styleSheet);
void setAttribute(ICoreWidgetAttribute attribute, bool on = true);
virtual ~ICoreDialog();
protected:
// The dialog is on screen. Same hook, and the same timing, as
// ICoreWidget::shown() -- which a dialog cannot inherit, since it is a
// parallel wrapper.
//
// It is where work that needs a laid-out window goes: a view filled in the
// constructor of a dialog has no item layout yet and comes up blank. Note
// that it runs on EVERY show, not only the first, so a subclass that must
// do its work once says so itself.
virtual void shown();
// ⚠ nativeDialog() WAS HERE AND IS GONE (H4.25), for the reason
// ICoreWindow::nativeWindow() is: a protected non-virtual helper is what
// the header surface rule removes, and this one had no callers in the tree
// at all. See that header's note before re-adding anything like it.
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreFloatingElementsWindow.h#
src/ICoreEssentials/UI/Windows/ICoreFloatingElementsWindow.h
Q1.3: <QWidget> went with populateWithWidgetSnapshot's parameter. H4.26 took <QPixmap> with the private
snapshotmember it was here for; the two event headers are dead already and belong to Q5.3's sweep, not here.
Declares no class of its own — see the file.
ICoreInputDialog.h#
src/ICoreEssentials/UI/Windows/ICoreInputDialog.h
ICoreInputDialog#
ICoreInputDialog.h:12 · class · 2 declaration(s)
Quick modal prompts, in the ICoreNativeDialogs static-facade shape.
class ICoreInputDialog {
public:
ICoreInputDialog() = delete;
static std::optional<ICoreString> getText(ICoreNativeWidget* parent,
const ICoreString& title,
const ICoreString& label,
const ICoreString& initial = ICoreString());
static std::optional<ICoreString> getItem(ICoreNativeWidget* parent,
const ICoreString& title,
const ICoreString& label,
const ICoreStringList& items,
int currentIndex = 0,
bool editable = false);
};
};
ICoreMessageBox.h#
src/ICoreEssentials/UI/Windows/ICoreMessageBox.h
ICoreMessageBox#
ICoreMessageBox.h:42 · class · final · pImpl · 4 declaration(s)
ICoreMessageBox — the app's modal alert.
class ICoreMessageBox final {
public:
ICoreMessageBox() = delete;
// What a three-way "you have unsaved work" prompt came back with.
enum class SaveAnswer { Save, Discard, Cancel };
// The prompt itself, with Save as the default button. A named method
// rather than a generic button-set builder: this exact three-way question
// is the only one the app asks, and spelling it once keeps the button
// order and the default from drifting between call sites.
//
// ⚠ Preserve, do not tidy: this one raises the TOOLKIT's static box, not
// the themed Impl the other five use, so it has always come up in the
// platform's own colours. That is a real divergence and predates the
// conversion; routing it through the themed path here would be a visual
// change smuggled in under a refactor.
static SaveAnswer askSaveDiscardCancel(ICoreNativeWidget* parent, const ICoreString& title,
const ICoreString& text);
// ---- the three notifications ------------------------------------------
static void critical(ICoreNativeWidget* parent, const ICoreString& title, const ICoreString& text);
static void warning(ICoreNativeWidget* parent, const ICoreString& title, const ICoreString& text);
static void information(ICoreNativeWidget* parent, const ICoreString& title, const ICoreString& text);
// ---- the two questions -------------------------------------------------
// Yes / No. True for Yes; false for No, Escape and a closed window.
// `defaultToYes` picks which of the two starts focused — pass false for a
// destructive action, so a stray Return does not confirm it.
static bool question(ICoreNativeWidget* parent, const ICoreString& title, const ICoreString& text,
bool defaultToYes = true);
// Same, but the affirmative carries its own label and the dismissive is
// Cancel. True only if the labelled button was the one clicked.
//
// The two widths are opt-in, and both default to "leave it to the toolkit"
// so the five other call sites are unchanged:
//
// * `minimumWidth` widens the BOX. An alert sizes itself to its text, so a
// long body -- a how-to with a bulleted command list, say -- comes up in
// a tall narrow column with every line wrapped. There is no setter for
// this on the toolkit's box; see the .cpp for what it takes.
// * `acceptButtonMinimumWidth` widens the AFFIRMATIVE only, for a label
// that says what it will do ("Choose Recipe File...") rather than "OK".
// Cancel keeps the shared minimum -- buttons carrying different labels
// are not obliged to be the same width.
//
// Both are in unscaled pixels, like every other size in this tree.
static bool confirm(ICoreNativeWidget* parent, const ICoreString& title, const ICoreString& text,
const ICoreString& acceptText,
int minimumWidth = 0, int acceptButtonMinimumWidth = 0);
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreNativeDialogs.h#
src/ICoreEssentials/UI/Windows/ICoreNativeDialogs.h
ICoreFileDialog#
ICoreNativeDialogs.h:44 · class · 4 declaration(s)
ICoreFileDialog / ICoreColorDialog / ICoreFontDialog — the three pickers the app hands to the operating system.
class ICoreFileDialog {
public:
ICoreFileDialog() = delete;
// Empty return means cancelled — the platform gives no other answer, and
// every call site already reads it that way.
static ICoreString getOpenFileName(ICoreNativeWidget* parent, const ICoreString& caption,
const ICoreString& directory = ICoreString(),
const ICoreString& filter = ICoreString());
static ICoreString getSaveFileName(ICoreNativeWidget* parent, const ICoreString& caption,
const ICoreString& directory = ICoreString(),
const ICoreString& filter = ICoreString());
// The overload that reports which filter the user picked, for callers that
// append an extension the typed name is missing.
static ICoreString getSaveFileName(ICoreNativeWidget* parent, const ICoreString& caption,
const ICoreString& directory,
const ICoreString& filter,
ICoreString* selectedFilter);
// Picks a FOLDER rather than a file — an export destination, a project
// root. No filter parameter, because a directory picker has nothing to
// filter. Empty return means cancelled, as above.
static ICoreString getExistingDirectory(ICoreNativeWidget* parent, const ICoreString& caption,
const ICoreString& directory = ICoreString());
};
};
ICoreColorDialog#
ICoreNativeDialogs.h:73 · class · 2 declaration(s)
class ICoreColorDialog {
public:
ICoreColorDialog() = delete;
// Empty optional means cancelled.
static std::optional<ICoreColor> getColor(const ICoreColor& initial, ICoreNativeWidget* parent,
const ICoreString& title = ICoreString());
};
};
ICoreFontDialog#
ICoreNativeDialogs.h:83 · class · 2 declaration(s)
class ICoreFontDialog {
public:
ICoreFontDialog() = delete;
// Empty optional means cancelled.
static std::optional<ICoreFont> getFont(const ICoreFont& initial, ICoreNativeWidget* parent);
};
};
ICoreDesktopReveal#
ICoreNativeDialogs.h:96 · class · 2 declaration(s)
The fourth thing this file hands to the operating system: the platform's own file browser.
class ICoreDesktopReveal {
public:
ICoreDesktopReveal() = delete;
// Show `folderPath` in the platform's file manager (Finder / Explorer /
// the desktop's default). A path that does not exist opens nothing; the
// platform gives no answer either way, so neither does this.
static void openFolder(const ICoreString& folderPath);
};
};
ICoreShortcut.h#
src/ICoreEssentials/UI/Windows/ICoreShortcut.h
ICoreShortcut#
ICoreShortcut.h:17 · class · pImpl · 4 declaration(s)
A standalone keyboard shortcut scoped to a host widget (the ICoreMenu rows register their own; this is for shortcuts with no menu row, like copy in the diagnosis panel).
class ICoreShortcut {
public:
// `scope` is how wide the key listens. It defaults to Window, which is
// what every call site got before the parameter existed, so adding it
// changed nothing that was already here. A panel whose key means something
// only inside itself -- Ctrl+C copying THAT panel's log rather than the
// window's -- asks for WidgetWithChildren.
// ⚠ `host` is an ICoreNativeWidget*, REPLACING the QWidget* it used to be
// rather than overloading beside it. P4.3's task line asked for an overload
// and that would not compile at the call sites it exists to serve: every
// unconverted wrapper is BOTH a QWidget and an ICoreNativeWidget, so the
// two candidates are ambiguous for an ICoreLabel*, ICoreButton*,
// ICoreWidget* and 15 more (§2 R4). P0.1 escaped that by renaming
// subscribe -> subscribeNative; a CONSTRUCTOR cannot be renamed, which
// P2.5 and P3.1 both recorded hitting. Replacing costs nothing here --
// there is exactly one construction site in the tree -- and it is
// unambiguous permanently rather than until Phase 8 tidies a second name.
ICoreShortcut(const ICoreKeySequence& sequence, ICoreNativeWidget* host,
std::function<void()> onActivated,
ICoreShortcutScope scope = ICoreShortcutScope::Window);
~ICoreShortcut();
ICoreShortcut(const ICoreShortcut&) = delete;
ICoreShortcut& operator=(const ICoreShortcut&) = delete;
void setEnabled(bool enabled);
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreWindow.h#
src/ICoreEssentials/UI/Windows/ICoreWindow.h
ICoreWindow#
ICoreWindow.h:35 · class · bases public ICoreNativeWidget · pImpl · 42 declaration(s)
P5.11: converted.
class ICoreWindow : public ICoreNativeWidget {
public:
ICoreNativeHandle nativeWidgetHandle() const override;
// Takes the widget INTERFACE rather than QMainWindow*, for the reason the
// QWidget* form used to give: a top-level window can be parented to any
// widget, and a narrower type turned away subclasses parented to a plain
// one. Q1.3 swapped the Qt spelling out; a sanctioned-zone caller holding a
// raw QWidget* reaches the toolkit form through ICoreWindowAccess.h.
explicit ICoreWindow(ICoreNativeWidget* parent = nullptr);
void populate(ICoreNativeWidget* widget);
// The two things this window used to do to its content by recognising what
// the content WAS. It no longer recognises anything: whoever populates the
// window teaches it what to do, which is what lets this class live in
// ICoreEssentials without dragging the studio in behind it.
//
// Teardown runs from closeEvent once closing() has agreed. Answer true if
// the content has been disposed of, and the window will delete itself as it
// closes. Answer false, or install nothing, and the window simply closes.
void setContentTeardownHook(std::function<bool()> hook);
// Runs when this window becomes the active window.
void setActivatedHook(std::function<void()> hook);
// Runs when the window is ASKED to close -- before closing() is consulted,
// and so before any teardown the subclass does there. An observer, not a
// veto: it fires whether the close is honoured or refused, and answering
// nothing cannot stop it. A subclass that wants to refuse still overrides
// closing().
//
// This is what an owner outside the wrapper zone uses to hear about a
// close without subclassing the window and without an event filter --
// icore::EditorWindow::Impl is the caller, and it is why that file needs no
// Qt at all. ONE slot, replaced rather than accumulated, matching the three
// hooks above; an owner needing to fan out multiplexes on its own side.
void setCloseRequestedHook(std::function<void()> hook);
void moveToScreenBottomRightCorner(const double& padding_x = 20, const double& padding_y = 20);
// Centres the window in the available area of the screen it is on -- the
// work area, so it clears the menu bar and the dock rather than centring in
// the raw display and sitting under them. Call it AFTER the window is at
// its final size; it centres what the window measures right now.
void moveToScreenCenter();
// Opens `window` if it is closed, and — when it is already open but minimized
// or buried behind other windows — restores it and pulls it to the front of
// the screen. Every button that "opens" a reused top-level window (Script
// Runner, Code Export Verification, ...) goes through here so a second click
// never looks like it did nothing.
static void bringToFront(ICoreNativeWidget* window);
// The shell hosting `topLevel`, or null if that window is not an
// ICoreWindow's Impl. The Impl carries the shell as a dynamic property --
// P6.5's record-what-you-own doctrine, per class, because a converted
// wrapper is invisible to qobject_cast walks (ICoreStudioSurface's
// spawned-window walk is the consumer). Test a specific shell type with
// plain dynamic_cast on the result; the shells are polymorphic.
//
// ⚠ Q1.3: the interesting lookups start from a raw toolkit widget -- the
// result of QWidget::window() -- which by definition has no wrapper to hand
// in here. That form is icoreWindowOfNative() in ICoreWindowAccess.h, and it
// is where ICoreStudioSurface's walk went. This overload stays for a caller
// that already holds a wrapper and would otherwise unwrap it just to ask.
static ICoreWindow* windowOf(ICoreNativeWidget* topLevel);
// One spelling now that the `using QMainWindow::…` re-export died with the
// base and Q1.3 deleted the QWidget* twin.
void setCentralWidget(ICoreNativeWidget* widget);
// Runs from the destructor, whichever way this window dies: an explicit
// delete, destruction by a parent widget, or WA_DeleteOnClose.
//
// This is deliberately a bare callback and not a call to any particular
// tracker. The window used to reach into ICoreStudioRegistry from its own
// constructor and destructor, which meant a class in the wrapper zone knew
// the name of a studio-level singleton and no caller could opt out of it.
// Now whoever owns the window's lifetime installs this, and the window
// neither knows nor cares who that is -- see
// ICoreStudioRegistry::requestNewWindow, which is the only caller today.
//
// ONE slot, not a subscription list: a second call REPLACES the first.
// The registry installs its own here as it hands the window out, so a
// caller that sets this on a registry-issued window silently unhooks the
// registry and leaves a dangling entry behind on destruction. If a second
// observer is ever genuinely needed, this becomes a list -- do not solve
// it by chaining onto whatever is already installed.
void setDestroyedHook(std::function<void()> hook);
// ------------------------------------------------------------------
// Facade members now that the QMainWindow base is gone; the flip's
// harvest enumerated them.
// ------------------------------------------------------------------
void resize(int width, int height);
void show();
void raise();
void activateWindow();
void close();
void setWindowTitle(const ICoreString& title);
void setAttribute(ICoreWidgetAttribute attribute, bool on = true);
[[nodiscard]] int width() const;
[[nodiscard]] int height() const;
void move(int x, int y);
[[nodiscard]] bool isVisible() const;
[[nodiscard]] bool isMinimized() const;
[[nodiscard]] bool isActiveWindow() const;
// Q5.1. The opaque blob the toolkit uses to remember where a window was:
// size, position, screen, maximised state. Deliberately NOT interpreted
// here -- ICoreUserPreferences stores it and hands it straight back, and
// the one consumer (ICorePrimaryWindowBackend) never looks inside it.
[[nodiscard]] ICoreByteArray saveGeometry() const;
bool restoreGeometry(const ICoreByteArray& geometry);
void hide();
// Q2.4: ICoreSizeF per Q0.2's one-size-story decision. Call sites that
// write resize(QSize(w, h)) compile untouched — ICoreSizeF converts
// implicitly from QSize — and the toolkit sink takes it back via
// toQSize(), so the integer rounding is unchanged.
void resize(const ICoreSizeF& size);
// Q3.2: Q0.1's value-pinned flag set. ICoreWindowFlags is `unsigned int`
// (ICoreMouseButtons' shape), so an or-ed expression of ICoreWindowFlag
// enumerators arrives here as a plain integer, exactly as Qt::WindowFlags did.
void setWindowFlags(ICoreWindowFlags flags);
void setWindowOpacity(double opacity);
void setStyleSheet(const ICoreString& styleSheet);
// ⚠ installEventFilter(ICoreNativeObject*) WAS HERE AND IS GONE (2026-08-14).
// Q1.3 gave it an ICoreNativeObject parameter so a filter could hand over
// the QObject it also derived from; EditorWindow's CloseWatcher was the only
// caller in the tree, and being a filter is precisely what forced a QObject
// into a file that now names no Qt. The window says when it is closing
// (setCloseRequestedHook), when it is activated, and when it dies -- ask for
// a hook for whatever else is needed rather than restoring this. Watching a
// window's raw toolkit events from outside is not a capability this class
// means to offer.
void setMinimumSize(int width, int height);
[[nodiscard]] int minimumWidth() const;
[[nodiscard]] int minimumHeight() const;
[[nodiscard]] QWidget* centralWidget() const;
[[nodiscard]] double devicePixelRatio() const;
virtual ~ICoreWindow();
protected:
// Qt-boundary hooks, the same shape ICoreWidget carries: a subclass
// overrides these instead of the toolkit handlers (it cannot even spell
// them now). Returning true consumes the event.
virtual bool keyPressed(const ICoreKeyEvent& event);
// Return false to veto the close.
virtual bool closing();
// The window is on screen; runs on EVERY show. Same contract as
// ICoreWidget::shown().
virtual void shown();
// Same contract as ICoreWidget::resized().
virtual void resized(const ICoreSizeF& newSize, const ICoreSizeF& oldSize);
// ⚠ nativeWindow() WAS HERE AND IS GONE (H4.24). It handed the Impl
// QMainWindow to wrapper-zone subclasses, and the header surface rule bans
// a protected non-virtual helper. It had NO callers in the tree -- only its
// own declaration and definition -- so this deletes a seam nobody had taken
// up rather than a capability anybody was using. A subclass that needs
// toolkit API the facade lacks should have the facade grow it, or ask for a
// deliberate public accessor; do not re-add a protected one.
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreWindowAccess.h#
src/ICoreEssentials/UI/Windows/ICoreWindowAccess.h
IMPLEMENTATION SIDE ONLY -- the ICoreNativeHandleAccess.h pattern, for the window tier (task Q1.3). Include this from a .cpp inside a sanctioned zone; never from a public wrapper header, because it names Qt.
ICoreWindow.h used to declare
windowOf(QWidget*)itself, which put QWidget on the public surface of every TU that merely wanted to open a window. The lookup is still needed and still inherently toolkit-facing, so it moved here rather than disappearing.WHY THIS ONE CANNOT TAKE A WRAPPER. The whole point of the lookup is to start from a widget you did NOT create -- typically
someQWidget->window(), which answers with a top-level QWidget* and no wrapper at all. A caller that already holds an ICoreNativeWidget never needed the lookup: it can use ICoreWindow::windowOf(ICoreNativeWidget*) instead. So the Qt-typed form is
Declares no class of its own — see the file.