API — ICoreEssentials/UI/Graphics
The public contract of 24 header(s) under src/ICoreEssentials/UI/Graphics — 20 class/struct definition(s), 354 declaration(s). Each section shows the header's banner and its public (and protected-virtual) surface exactly as the file writes it.
ICoreAnyGraphicsItem.h#
src/ICoreEssentials/UI/Graphics/ICoreAnyGraphicsItem.h
A scene item of no particular kind: the parent-pointer type every graphics object takes.
This is the scene tier's ICoreAnyWidget, and it exists for the same reason. SoftwareLayout/README.md S11 already records that the toolkit's item type in its PARENT-POINTER shape is not adoptable debt -- it is how the scene graph is spelled, on every item, by the toolkit's own API. Naming it ICore lets code outside the wrapper zone pass a parent through without spelling a Qt type, which is all those call sites ever do with it.
File-scope declarations#
// A scene item of no particular kind: the parent-pointer type every graphics
// object takes.
//
// This is the scene tier's ICoreAnyWidget, and it exists for the same reason.
// SoftwareLayout/README.md S11 already records that the toolkit's item type in
// its PARENT-POINTER shape is not adoptable debt -- it is how the scene graph
using ICoreAnyGraphicsItem = QGraphicsItem;
// The same, one rung up: a scene item that is also a toolkit object, which is
// what a parent parameter means when the callee will connect to it.
using ICoreAnyGraphicsObject = QGraphicsObject;
// A toolkit object of no particular kind, for parameters that accept anything
// with a toolkit lifetime -- the widest of the three.
using ICoreAnyObject = QObject;
ICoreGraphicsBoxedText.h#
src/ICoreEssentials/UI/Graphics/ICoreGraphicsBoxedText.h
Its ink is its own (applyThemeColors picks between two field tokens on a themeChanged of its own), so the base's Ink stands down the first time this class sets a colour -- that is the sticky-override rule doing its job, not a conflict.
ICoreGraphicsBoxedText#
ICoreGraphicsBoxedText.h:17 · class · bases public ICoreGraphicsText · pImpl · 27 declaration(s)
class ICoreGraphicsBoxedText : public ICoreGraphicsText {
public:
// ⚠ REPLACED, NOT OVERLOADED (P2.10b-3b), and the distinction is the whole
// reason this took its own commit. The warning that stood here still holds
// and is kept verbatim below: adding an ICoreNativeItem* overload BESIDE
// the QGraphicsItem* one is R4-ambiguous, because every ICoreGraphicsObject
// subclass is BOTH -- and ICoreGraphicsTableEntryRow is exactly such a
// caller. Replacing the parameter has no such problem: that same `this`
// converts to the one remaining overload unambiguously, and the callers
// that were unwrapping with icoreNativeItem() stop needing to.
//
// *(The superseded warning, preserved because the overload is still wrong:)*
// ⚠ Do NOT add an ICoreNativeItem* overload beside this. It was tried in
// P2.5 and it is R4: every ICoreGraphicsObject subclass is BOTH a
// QGraphicsItem and an ICoreNativeItem, so the two constructors are
// ambiguous for the arguments most call sites already pass --
// ICoreGraphicsTableEntryRow.cpp:25 fails to compile immediately. A caller
// holding a converted (non-Qt) parent unwraps with icoreNativeItem() at the
// call site instead.
explicit ICoreGraphicsBoxedText(ICoreNativeItem* parent = nullptr);
// WAS `QRectF boundingRect() const override` returning the same rectangle.
// The box states its size explicitly rather than measuring its document,
// which is exactly what contentBounds() is for; boundingRect() is derived
// from this on the base now, so the toolkit still sees the same rectangle.
[[nodiscard]] ICoreRect contentBounds() const override;
void autoCalcHeight();
virtual void setWidth(const double& width);
virtual void setHeight(const double& height);
void setBackgroundColor(const ICoreColor& color);
void setBoldText(bool isBold);
void setManualFocus(bool isFocus);
void setBorderColor(ICoreColor color);
// Keep the border invisible, and keep it that way across theme switches. A
// bare setBorderColor(Qt::transparent) is caller-owned and never refreshed,
// so the next theme re-derivation restored field.border — which is what drew
// a hairline box around the chart's axis labels under Light.
void hideBorder();
void setUserEditable(const bool& userEditable);
// Read-only boxes otherwise fill with field.background — the same colour the
// editable ones wear, so a value the user cannot type in looks exactly like
// one they can. This opts a box into the treatment the variables space gives
// its derived column: field.readOnlyBackground plus secondary text. Both
// themes carry that token, so the split holds on light as well as dark.
void useRaisedReadOnlyStyle();
// Wear field.background, and keep wearing it across theme switches. This is
// what an editable box in a themed dialog wants: a bare setBackgroundColor
// is caller-owned and never refreshed, so a box painted white under Light
// stayed white after a switch to Dark.
void useFieldFill();
void setFocusable_DisableUserEdit();
// ⚠ WAS `const`, AND THAT WAS ALWAYS WRONG -- it mutates the item's text
// layout. It only compiled because QGraphicsTextItem::document() is a
// const member returning a NON-const QTextDocument*, so the body mutated
// straight through the const. Routing it via setTextAlignment (P2.10b-1)
// is what surfaced it; both call sites hold a non-const pointer, so
// dropping const costs nothing.
void centerTextHorizontally();
double predictTextWidthPx(const ICoreString& text) const;
virtual double getPredictedTextWidthPx() const; // This is separate because virtual
double getWidth() const;
double getHeight() const;
void resetToInitialState(ICoreNativeItem* parent = nullptr);
// The recycler's liveness bookkeeping -- see ICoreGraphicsRecycler.
void kill();
void setAlive();
[[nodiscard]] bool isAlive() const;
// Out of line: Impl is incomplete here, so the unique_ptr's deleter cannot
// be instantiated in this header. It was an empty inline body before H5.2.
~ICoreGraphicsBoxedText() override;
protected:
// All of this class's focus-out work ran before the toolkit base, so it
// is focusLosing. See the .cpp.
void focusLosing(const ICoreFocusEvent& event) override;
bool keyPressed(const ICoreKeyEvent& event) override;
// WAS one paint() override, split at the base call the way P2.10a/P2.11b
// split the focus and key handlers: the fill ran BEFORE
// ICoreGraphicsText::paint and the border and focus ring ran AFTER it, and
// those are exactly the two points the base calls these hooks from.
void paintBackground(ICorePainter& painter) override;
void paintContent(ICorePainter& painter) override;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreGraphicsButton.h#
src/ICoreEssentials/UI/Graphics/ICoreGraphicsButton.h
The Q_PROPERTY(backgroundOpacity) that stood here is GONE (P2.9d-5d): the fade drives setBackgroundOpacity() through ICoreValueAnimation::onValueChanged now, so nothing resolves the name through the metaobject. The Q_OBJECT that outlived it left with the flip (P2.9d-5e): the base is not a QObject any more, so the macro stopped being removable-with-care and became a compile error.
ICoreGraphicsButton#
ICoreGraphicsButton.h:16 · class · bases public ICoreGraphicsObject · pImpl · 36 declaration(s)
class ICoreGraphicsButton : public ICoreGraphicsObject {
public:
// The graphics-scene twin of ICoreButton::Variant, remembered for the same
// reason: the fill, the opacities AND the opaque canvas-coloured backdrop
// under the glass are all theme tokens, and a button configured under one
// theme used to keep every one of them after a switch — leaving a light
// rectangle sitting on the dark canvas.
enum class Variant { None, Primary };
explicit ICoreGraphicsButton(ICoreNativeItem* parent = nullptr, const ICoreString& initialText = "");
// Wear a variant, now and after every theme switch. Prefer
// setVariant(Variant::Primary), called directly by the port buttons.
void setVariant(Variant variant);
// contentBounds(), not boundingRect() (P2.9d-2). Same value, same members:
// the base derives boundingRect() from this, so nothing about the geometry
// changes -- what goes away is an override of a Qt virtual that would stop
// being called at all once this tier drops its Qt base.
[[nodiscard]] ICoreRect contentBounds() const override;
void reconstructDescendents();
void animateShow();
void animateHide();
void setHoldHoveredStyle(bool newValue);
void setHoverColor(ICoreColor newHoverColor);
// Wear the app's nav-row hover treatment — the ICoreNavItemStyle wash,
// hairline and accent edge that an ICoreMenu row and every plain
// ICoreButton light with — instead of the flat hover pill.
//
// ⚠ OFF BY DEFAULT, and deliberately so. Turning it on for every graphics
// button would restyle the canvas context menu's own rows, the combo box
// options and the auto-inserter along with whatever asked for it; a button
// that wants the treatment says so. A glass finish still wins over it —
// setGlassFinish paints the whole body itself, so the two cannot both draw.
void setNavItemStyle(bool on);
// The hover wash a plain (non-glass) graphics button wears under `theme`.
// On dark that is ICoreButton's hover, so a canvas button and a panel button
// answer the pointer the same way; on light it stays the royal-tinted pill.
// Public so the few buttons that re-apply a hover colour of their own can
// ask for the default rather than hardcoding a token.
static ICoreColor resolveHoverFill(const ICoreTheme& theme);
// ⚠ applyVariant() and m_variant MOVED INTO Impl (H5.1). applyVariant
// re-derives the variant's backdrop, fill and opacities from the active
// theme and runs from the constructor's theme subscription.
// Forgets that the pointer is over the button. A button that is hidden (or moved
// out from under the pointer) never receives its hoverLeaveEvent, so without this
// it comes back still wearing the hover wash.
void clearHoverState();
void setFillColor(ICoreColor newFillColor);
void setBorderColor(ICoreColor newBorderColor);
// Wear the app's tinted variant finish in `fill` — the graphics-scene twin of
// ICoreButton::setGlassFinish, so a purple button looks the same on the canvas
// as it does in a panel. Since 2026-08-15 that finish is a SOLID, unbordered
// plate: `fill` lands at full alpha in every state, and `restOpacity` /
// setHoverOpacity() name the ends of the hover animation whose travel the
// painter spends lightening the plate by theme.button.tintedHoverLighter.
// (The name is the widget button's and is kept so the twins still match.)
void setGlassFinish(const ICoreColor& fill, const double& restOpacity);
void setHoverOpacity(const double& newOpacity);
[[nodiscard]] double backgroundOpacity() const;
void setBackgroundOpacity(double newOpacity);
void setText(const ICoreString& newText);
// The label rests in the theme's primary text color; a button that fills itself
// with a strong color on selection needs to repaint its text to match.
void setLabelColor(const ICoreColor& color);
void setWidth(double width) override;
void setHeight(double height);
void setIcon(const ICoreIcon& icon);
void setIconPos(const ICorePoint& newIconPos);
void setIconSize(const ICoreSizeF& newIconSize);
void setLabelXPos(const double& newXPos);
// Centers the caption in the button instead of leaving it pinned to the left
// edge, which is what a text button (rather than an icon one with a padded
// caption) needs. Call it once the text AND the width are both set.
void centerLabel();
[[nodiscard]] double getWidth() const;
[[nodiscard]] double getHeight() const;
[[nodiscard]] ICoreString getText() const;
void resetToInitialState_GraphicsButton(ICoreNativeItem* parent, const ICoreString& initialText = "");
// ⚠ Declared here and DEFINED OUT OF LINE, which it did not used to be:
// m_backgroundFade is a unique_ptr to a forward-declared ICoreAnimation, and
// its deleter has to be instantiated where that type is complete. An empty
// inline body compiles here and then fails in every TU that includes this
// header without ICoreAnimation.h -- four of them, none of them this class's
// own. (P4.2 hit the same rule; it is the third wrapper to grow an owning
// member and the third to need this.)
~ICoreGraphicsButton() override;
protected:
// The old paint() override, split at the base's own seam (P2.9d-2b) -- the
// last Qt virtual this tier had. paintBody() draws the button's own rounded
// body, paintContent() the icon on top of it, and the base calls them in
// that order, so the painted sequence is unchanged.
//
// ⚠ paintBody() TURNS ON ANTIALIASING ITSELF, and dropping that line is a
// silent regression rather than a compile error. The old paint() set
// Antialiasing AND SmoothPixmapTransform; the base's paint() sets only
// Antialiasing, deliberately (see its note). ICorePainter::setAntialiasing
// sets both, so this class -- which draws a pixmap in paintContent() -- has
// to ask for the pair the way the other pixmap-drawing subclasses do.
void paintBody(ICorePainter& painter) override;
void paintContent(ICorePainter& painter) override;
void pointerEntered(const ICoreMouseEvent& event) override;
void pointerLeft() override;
void visibilityChanged(bool visible) override;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreGraphicsComboBox.h#
src/ICoreEssentials/UI/Graphics/ICoreGraphicsComboBox.h
Retyped with its base in P2.10b-3b. Still no ICoreNativeItem* OVERLOAD -- R4, see the note on ICoreGraphicsBoxedText, which explains why replacing the parameter is safe where adding a second one is not.
ICoreGraphicsComboBox#
ICoreGraphicsComboBox.h:14 · class · bases public ICoreGraphicsBoxedText · pImpl · 13 declaration(s)
class ICoreGraphicsComboBox : public ICoreGraphicsBoxedText {
public:
// Retyped with its base in P2.10b-3b. Still no ICoreNativeItem* OVERLOAD --
// R4, see the note on ICoreGraphicsBoxedText, which explains why replacing
// the parameter is safe where adding a second one is not.
explicit ICoreGraphicsComboBox(ICoreNativeItem* parent);
void populate(const std::pair<std::vector<std::string>, std::string>& options);
void setWidth(const double& width) override;
void setHeight(const double& height) override;
virtual void setChosenOption(const std::string& newChosenOption);
virtual void animateComboDialogHide();
virtual void animateComboDialogShow();
double getPredictedTextWidthPx() const override;
ICoreGraphicsComboBoxDialog* getOptionsDialog() const;
void resetToInitialState_GraphicsComboBox(ICoreNativeItem* parent);
// Out of line: Impl is incomplete here, so the unique_ptr's deleter cannot
// be instantiated in this header. It was an empty inline body before H5.14.
~ICoreGraphicsComboBox() override;
protected:
// Returns true: the old body accepted and never reached the toolkit
// base. P2.8's press rule -- false here would hand the press to
// QGraphicsTextItem as well and cost the item its grab.
bool mousePressed(const ICoreMouseEvent& event) override;
void focusLosing(const ICoreFocusEvent& event) override;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreGraphicsComboBoxDialog.h#
src/ICoreEssentials/UI/Graphics/ICoreGraphicsComboBoxDialog.h
⚠⚠ THE ONE SIGNATURE P2.9c COULD NOT RETYPE, AND IT IS P2.9d'S GATE.
parenthere is always an ICoreGraphicsComboBox, which is TEXT tier (ICoreGraphicsBoxedText -> ICoreGraphicsText -> QGraphicsTextItem) -- a SEPARATE hierarchy that implements no ICoreNativeItem, so there is no handle to narrow this to. It stays QGraphicsObject* until P2.10 gives ICoreGraphicsText the interface (2 additive lines, the shape P6.4 used for ICoreLabel). P2.9d cannot flip while this is raw, because after the flip a QGraphicsObject* is not something a converted item can be parented to at all. ✅ NARROWED BY P2.10b-6, which is the event the note above was waiting for: the text tier is converted, soparentis an ICoreNativeItem and is no longer a QGraphicsObject at all.
ICoreGraphicsComboBoxDialog#
ICoreGraphicsComboBoxDialog.h:12 · class · bases public ICoreGraphicsObject · pImpl · 13 declaration(s)
class ICoreGraphicsComboBoxDialog : public ICoreGraphicsObject {
public:
// ⚠⚠ THE ONE SIGNATURE P2.9c COULD NOT RETYPE, AND IT IS P2.9d'S GATE.
// `parent` here is always an ICoreGraphicsComboBox, which is TEXT tier
// (ICoreGraphicsBoxedText -> ICoreGraphicsText -> QGraphicsTextItem) -- a
// SEPARATE hierarchy that implements no ICoreNativeItem, so there is no
// handle to narrow this to. It stays QGraphicsObject* until P2.10 gives
// ICoreGraphicsText the interface (2 additive lines, the shape P6.4 used
// for ICoreLabel). **P2.9d cannot flip while this is raw**, because after
// the flip a QGraphicsObject* is not something a converted item can be
// parented to at all.
// ✅ NARROWED BY P2.10b-6, which is the event the note above was waiting
// for: the text tier is converted, so `parent` is an ICoreNativeItem and
// is no longer a QGraphicsObject at all.
explicit ICoreGraphicsComboBoxDialog(ICoreNativeItem* parent, ICoreGraphicsComboBox* parentComboBox);
void populateList(const std::vector<std::string> &options);
void clearAllComboOptions();
void autoCalculateComboOptionsSizes();
void setWidth(double width) override;
void setOptionHeight(double newOptionHeight);
void setPadding(double newPadding);
void setChosenOptionCheckIcon(const std::string& newChosenOption) const;
double getCachedHeight() const;
// Same gate as the constructor above.
void resetToInitialState(ICoreNativeItem* parent, ICoreGraphicsComboBox* parentComboBox);
// The recycler's liveness bookkeeping -- see ICoreGraphicsRecycler. This
// class has no isAlive(); only kill() and setAlive() were ever called.
void kill();
void setAlive();
// Out of line: Impl is incomplete here, so the unique_ptr's deleter cannot
// be instantiated in this header. It was an empty inline body before H5.8.
~ICoreGraphicsComboBoxDialog() override;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreGraphicsComboBox_ComboOption.h#
src/ICoreEssentials/UI/Graphics/ICoreGraphicsComboBox_ComboOption.h
Out of line: Impl is incomplete here, so the unique_ptr's deleter cannot be instantiated in this header.
ICoreGraphicsComboBox_ComboOption#
ICoreGraphicsComboBox_ComboOption.h:10 · class · bases public ICoreGraphicsButton · pImpl · 7 declaration(s)
class ICoreGraphicsComboBox_ComboOption : public ICoreGraphicsButton {
public:
explicit ICoreGraphicsComboBox_ComboOption(ICoreNativeItem* parent, ICoreGraphicsComboBox* grandParentComboBox, const ICoreString& initialText);
// Out of line: Impl is incomplete here, so the unique_ptr's deleter cannot
// be instantiated in this header.
~ICoreGraphicsComboBox_ComboOption() override;
void resetToInitialState(ICoreNativeItem* parent, ICoreGraphicsComboBox* grandParentComboBox, const ICoreString& initialText);
// The recycler's liveness bookkeeping: collect_ComboOption() kill()s an
// option before pooling it and request_ComboOption() setAlive()s it on the
// way back out, so a handle held across a recycle reports itself dead.
void kill();
void setAlive();
[[nodiscard]] bool isAlive() const;
protected:
bool mousePressed(const ICoreMouseEvent& event) override;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreGraphicsCommands.h#
src/ICoreEssentials/UI/Graphics/ICoreGraphicsCommands.h
ICoreGraphicsCommands#
ICoreGraphicsCommands.h:22 · class · 7 declaration(s)
Scene-side helpers callable from OUTSIDE the wrapper zone without naming a Qt type: the parameter is only ever a pointer a wrapper API handed the caller, so the call site spells nothing but its own...
class ICoreGraphicsCommands {
public:
ICoreGraphicsCommands() = delete;
// Release the scene's mouse grab if (and only if) `item` holds it.
static void ungrabMouseSafely(ICoreNativeItem* item);
// Detach `item` from whatever scene currently owns it; no-op when none.
static void removeFromScene(ICoreNativeItem* item);
// removeFromScene, then repaint the scene the item just left.
static void removeFromSceneAndRefresh(ICoreNativeItem* item);
// Stop every animation parented to `owner`; no-op when null or childless.
//
// Deliberately reaches ALL animations, not only the ICore-wrapped ones: a
// recycled object may own a plain toolkit animation as well, and one left
// running would keep writing to an object that has been handed back.
//
// ⚠ Q1.7 REPLACED THE SINGLE `QObject*` ENTRY POINT WITH THREE NAMED ONES,
// one per wrapper interface, and the names are NOT interchangeable
// overloads. The comment that stood here said this "takes the widest owner
// type" -- but post-conversion there is no widest ICore type: a widget
// wrapper implements ICoreNativeWidget, a scene item ICoreNativeItem, a
// model ICoreNativeObject, and none of the three derives from another. An
// overload set would have been fine, but stopChildAnimationsOfItem was
// already a distinct NAME for exactly this reason (see its own note), so
// the other two follow it rather than splitting the file's convention.
static void stopChildAnimationsOfWidget(ICoreNativeWidget* widget);
static void stopChildAnimationsOfObject(ICoreNativeObject* object);
// The same walk for an ITEM wrapper (P2.9d-5c). A different NAME, not an
// overload of the above: until P2.9d-5e a scene item converts to QObject*
// through its Qt base AND to ICoreNativeItem* through its seam base, so an
// overload pair would be R4-ambiguous at every graphics-tier call site --
// the same reason ICoreThemeBinding grew subscribeNative rather than a
// subscribe overload. Widgets and pre-unwrapped handles keep the QObject*
// spelling above.
//
// No-op for a null wrapper AND for a wrapper whose item is not a
// QGraphicsObject (a bare-QGraphicsItem wrapper has no object tree to
// walk, hence nothing parented to it to stop).
static void stopChildAnimationsOfItem(ICoreNativeItem* item);
// ⚠ stopChildAnimations(QObject*) -- what all three of the above forward
// to once each has resolved its own wrapper -- MOVED TO THE .cpp as a
// file-local function by the header surface rule (H5.15). It was private
// since Q1.7 because it is the shared body rather than an entry point,
// which is exactly why it does not belong on the class at all. It was also
// this header's last mention of QObject.
};
};
ICoreGraphicsInfoLabel.h#
src/ICoreEssentials/UI/Graphics/ICoreGraphicsInfoLabel.h
Complete type, not a forward declaration: the unique_ptr<ICoreValueAnimation> member needs sizeof(ICoreValueAnimation) wherever a label is destroyed. The destructor is ALSO out of line (belt and braces from two concurrent fixes of the same incomplete-type error; either alone would do).
ICoreGraphicsInfoLabel#
ICoreGraphicsInfoLabel.h:19 · class · bases public ICoreGraphicsObject · pImpl · 8 declaration(s)
class ICoreGraphicsInfoLabel : public ICoreGraphicsObject {
public:
explicit ICoreGraphicsInfoLabel(ICoreNativeItem* parentToolBar = nullptr);
// contentBounds(), not boundingRect() (P2.9d-2). Same value, same members:
// the base derives boundingRect() from this, so nothing about the geometry
// changes -- what goes away is an override of a Qt virtual that would stop
// being called at all once this tier drops its Qt base.
[[nodiscard]] ICoreRect contentBounds() const override;
void paintBody(ICorePainter& painter) override;
void paintContent(ICorePainter& painter) override;
// Seam-typed since P2.9d-5c: both callers (the two ToolBarButton classes)
// pass themselves, and a wrapper upcasts to ICoreNativeItem* by itself --
// the QGraphicsObject* this took would have needed a conversion that stops
// existing at the flip.
void showInfoLabel(const ICoreString& title, ICoreNativeItem* objectUnderCursor, const ICoreString& technique, double delayDuration);
void hideInfoLabel();
void setText(const ICoreString& text);
// Out of line: the unique_ptr member below is over a forward-declared
// type, so the destructor must live where ICoreValueAnimation is complete.
~ICoreGraphicsInfoLabel() override;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreGraphicsItem.h#
src/ICoreEssentials/UI/Graphics/ICoreGraphicsItem.h
ICoreGraphicsItem#
ICoreGraphicsItem.h:31 · class · bases public ICoreNativeItem · pImpl · 20 declaration(s)
ICoreGraphicsItem -- the non-QObject half of the scene tier: a rounded body with a fill and a border that a subclass draws on top of.
class ICoreGraphicsItem : public ICoreNativeItem {
public:
explicit ICoreGraphicsItem(ICoreNativeItem* parent = nullptr);
~ICoreGraphicsItem() override;
ICoreGraphicsItem(const ICoreGraphicsItem&) = delete;
ICoreGraphicsItem& operator=(const ICoreGraphicsItem&) = delete;
// This item's own area, origin at (0,0). Overriding it is how a subclass
// states its size; the toolkit's boundingRect() is derived from it.
virtual ICoreRect contentBounds() const;
virtual void setWidth(double newWidth);
void setHeight(double newHeight);
void setFillColor(ICoreColor newColor);
void setBorderColor(ICoreColor newColor);
double getWidth() const;
double getHeight() const;
// --- Scene-tree placement. Forwarders, discovered from call sites: under
// --- pImpl nothing is inherited, so each one exists because something asks
// --- for it (§9).
void setPos(const ICorePoint& position);
void setPos(double x, double y);
// A null parent detaches the item from the scene tree.
void setParentItem(ICoreNativeItem* parent);
void setZValue(double z);
void setVisible(bool visible);
void show();
void hide();
ICoreNativeHandle nativeItemHandle() const override;
protected:
// Called on every repaint, after the rounded body has been drawn. The same
// hook ICoreGraphicsObject carries; this base is the non-QObject half of
// the scene tier and needs the identical surface.
virtual void paintContent(ICorePainter& painter);
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreGraphicsObject.h#
src/ICoreEssentials/UI/Graphics/ICoreGraphicsObject.h
Declares no class of its own — see the file.
ICoreGraphicsPixmap.h#
src/ICoreEssentials/UI/Graphics/ICoreGraphicsPixmap.h
ICoreGraphicsPixmap#
ICoreGraphicsPixmap.h:41 · class · final · bases public ICoreNativeItem · pImpl · 8 declaration(s)
ICoreGraphicsPixmap -- a raster image sitting on a graphics scene.
class ICoreGraphicsPixmap final : public ICoreNativeItem {
public:
explicit ICoreGraphicsPixmap(ICoreNativeItem* parent = nullptr);
~ICoreGraphicsPixmap() override;
ICoreGraphicsPixmap(const ICoreGraphicsPixmap&) = delete;
ICoreGraphicsPixmap& operator=(const ICoreGraphicsPixmap&) = delete;
// Fills exactly `width` x `height`, ignoring the source aspect ratio and
// smoothing the result. Ignoring the ratio is deliberate and is what the
// canvas image object has always done: the frame is resized by its own
// handles, and letterboxing inside a frame the user just dragged reads as
// the drag not having worked.
//
// A null source clears the item rather than scaling nothing, so a caller
// does not need the isNull() guard the sites used to carry.
void setStretchedPixmap(const ICorePixmap& source, int width, int height);
// Drops the raster and shows nothing. This is the ICore spelling of the one
// call site that set a deliberately-null pixmap to mean "empty"; it is the
// same operation setStretchedPixmap() performs for a null source, named.
void clearPixmap();
// A null parent detaches the item from the scene tree, which the image
// object's clear path relies on -- so null is forwarded, not rejected.
void setParentItem(ICoreNativeItem* parent);
ICoreNativeHandle nativeItemHandle() const override;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreGraphicsProxyWidget.h#
src/ICoreEssentials/UI/Graphics/ICoreGraphicsProxyWidget.h
Declares no class of its own — see the file.
ICoreGraphicsRect.h#
src/ICoreEssentials/UI/Graphics/ICoreGraphicsRect.h
ICoreGraphicsRect#
ICoreGraphicsRect.h:35 · class · bases public ICoreNativeItem · pImpl · 17 declaration(s)
ICoreGraphicsRect -- a themed rectangle on a graphics scene.
class ICoreGraphicsRect : public ICoreNativeItem {
public:
enum class Style {
None, // pen and brush untouched -- the default
Marquee, // solid 1px selection border at 150 alpha, selection fill
MarqueeDashed // dashed selection border at full alpha, selection fill
};
explicit ICoreGraphicsRect(ICoreNativeItem* parent = nullptr);
explicit ICoreGraphicsRect(Style style, ICoreNativeItem* parent = nullptr);
~ICoreGraphicsRect() override;
ICoreGraphicsRect(const ICoreGraphicsRect&) = delete;
ICoreGraphicsRect& operator=(const ICoreGraphicsRect&) = delete;
void setRectStyle(Style style);
Style rectStyle() const;
// The band itself, in the item's own coordinates.
void setRect(const ICoreRect& rect);
ICoreRect rect() const;
// The band in SCENE coordinates -- what every hit test against it actually
// wants. This replaces `mapToScene(rect()).boundingRect()`, which
// ICoreCanvasSelectionRectangle spelled out FIVE times, once per kind of
// thing it scans. One expression, one place, and the mapping can no longer
// drift between the five.
ICoreRect sceneBounds() const;
void setVisible(bool visible);
bool isVisible() const;
void setZValue(double z);
void setPos(const ICorePoint& position);
ICorePoint scenePos() const;
void setParentItem(ICoreNativeItem* parent);
ICoreNativeHandle nativeItemHandle() const override;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreGraphicsRecycler.h#
src/ICoreEssentials/UI/Graphics/ICoreGraphicsRecycler.h
ICoreGraphicsRecycler#
ICoreGraphicsRecycler.h:34 · class · 5 declaration(s)
ICoreGraphicsRecycler -- pools for the high-churn graphics items Essentials itself builds tables and combo dialogs out of (ESSENTIALS_INDEPENDENCE D5).
class ICoreGraphicsRecycler {
public:
static ICoreGraphicsTableEntryRow* request_TableEntryRow(
ICoreGraphicsTable* parentTable, const std::vector<std::string>& columns);
static void collect_TableEntryRow(ICoreGraphicsTableEntryRow* entry);
static ICoreGraphicsBoxedText* request_BoxedText(ICoreNativeItem* parent);
static void collect_BoxedText(ICoreGraphicsBoxedText* box);
static ICoreGraphicsTableTitleRowSplitter* request_TableTitleRowSplitter(
ICoreGraphicsTableTitlesRow* parent, ICoreGraphicsTable* grandParentTable);
static void collect_TableTitleRowSplitter(ICoreGraphicsTableTitleRowSplitter* splitter);
static ICoreGraphicsComboBox_ComboOption* request_ComboOption(
ICoreNativeItem* parent, ICoreGraphicsComboBox* grandParentComboBox,
const ICoreString& initialText);
static void collect_ComboOption(ICoreGraphicsComboBox_ComboOption* option);
};
};
ICoreGraphicsScene.h#
src/ICoreEssentials/UI/Graphics/ICoreGraphicsScene.h
ICoreGraphicsScene -- the scene every canvas, chart and floating-panel view runs on.
⚠ THIS CLASS CARRIES NO APPEARANCE, AND THAT IS THE POINT OF ITS HISTORY.
It used to own a
Backdropenum (None/Canvas/Panel) and a theme subscription that re-derived the background brush on every Light <-> Dark switch. Every one of those parts is gone, because the whole mechanism was unreachable: all three construction sites in the tree (ICoreCanvasParent, ICoreChart, ICoreFloatingPanelsGraphicsView) used the parent-only constructor, which meant Backdrop::None, which made applyTheme() return before touching the brush. The component had exactly one reachable state and it was "do nothing".
ICoreGraphicsScene#
ICoreGraphicsScene.h:41 · class · final · bases public ICoreNativeScene · pImpl · 12 declaration(s)
class ICoreGraphicsScene final : public ICoreNativeScene {
public:
// The parent owns the scene's lifetime, exactly as the QObject parent did.
// Two of the three construction sites pass nothing and keep the scene in a
// member instead.
explicit ICoreGraphicsScene(ICoreNativeWidget* parent = nullptr);
~ICoreGraphicsScene() override;
ICoreGraphicsScene(const ICoreGraphicsScene&) = delete;
ICoreGraphicsScene& operator=(const ICoreGraphicsScene&) = delete;
void setSceneRect(const ICoreRect& rect);
void addItem(ICoreNativeItem* item);
void removeItem(ICoreNativeItem* item);
// Empties the scene, releasing the mouse grab first if the item being
// removed is holding it.
//
// This replaces an items() getter, and the ordering is why it is a method
// rather than a loop at the call site: removing the grabber without
// ungrabbing leaves Qt dispatching moves to a detached item. The one caller
// (ICoreCanvasParent::loadCanvas) had that dance written out by hand, and
// it is the kind of thing the second caller gets wrong.
void removeAllItems();
// Releases the scene's mouse grab, if the grab is both held and still
// valid. A grabber whose scene() is no longer this one is stale and is
// skipped -- ICoreStudioSurfaceRegistry paid for that check and it moved
// here with the rest of the operation.
void ungrabMouse();
// Whether the item is currently in THIS scene. Replaces the two sites that
// compared a raw item->scene() against the scene pointer, which the pImpl
// boundary no longer lets them spell.
bool contains(const ICoreNativeItem* item) const;
// Draws `source` (in scene coordinates) onto `target` (in the painter's
// coordinates). Added for P2.9d-4, whose survey found this to be the ONE
// site in the whole scene tier that wants the scene object back rather than
// a bool -- ICoreCanvasPrinter, printing the diagram onto a page.
//
// ⚠ THE SOURCE IS STRETCHED TO FILL THE TARGET EXACTLY -- no letterbox,
// i.e. Qt's IgnoreAspectRatio and not its KeepAspectRatio default. That is
// what the one caller wants (it sizes `target` to the diagram's own
// proportions first, so a second fit would only round it), and it is spelled
// into the operation rather than exposed as a mode: an aspect-ratio enum at
// a consumer site is the re-export hole P6.4 records neither guard seeing.
// A caller that genuinely wants a letterbox should scale its own target.
//
// ⚠ It takes an ICorePainter& rather than growing a Qt parameter, following
// ICoreChartBase::renderSceneToPainter, which P7.1 gave this exact shape.
// QGraphicsScene::render is the only route a scene has onto a painter and it
// takes a QPainter*, so the body composes with the toolkit through
// ICorePainter::qt() -- the seam working, not an escape from it.
void renderTo(ICorePainter& painter, const ICoreRect& target, const ICoreRect& source);
ICoreNativeHandle nativeSceneHandle() const override;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreGraphicsScrollPane.h#
src/ICoreEssentials/UI/Graphics/ICoreGraphicsScrollPane.h
Q_OBJECT removed (P2.9d-3): this class declares no signal, slot, Q_PROPERTY or Q_INVOKABLE of its own, and nothing qobject_casts to it, holds a QPointer to it, animates it by name or reaches its metaObject(). It therefore had a meta-object nobody consulted -- and it could not keep one past P2.9d-5, when the base stops being a QObject.
Declares no class of its own — see the file.
ICoreGraphicsScrollPaneScrollBar.h#
src/ICoreEssentials/UI/Graphics/ICoreGraphicsScrollPaneScrollBar.h
ICoreGraphicsScrollPaneScrollBar#
ICoreGraphicsScrollPaneScrollBar.h:14 · class · bases public ICoreGraphicsObject · pImpl · 10 declaration(s)
Draggable vertical scroll bar for ICoreGraphicsScrollPane.
class ICoreGraphicsScrollPaneScrollBar : public ICoreGraphicsObject {
public:
explicit ICoreGraphicsScrollPaneScrollBar(ICoreGraphicsScrollPaneScrollableArea* scrollableArea,
ICoreNativeItem* parent = nullptr);
// contentBounds(), not boundingRect() (P2.9d-2). Same value, same members:
// the base derives boundingRect() from this, so nothing about the geometry
// changes -- what goes away is an override of a Qt virtual that would stop
// being called at all once this tier drops its Qt base.
[[nodiscard]] ICoreRect contentBounds() const override;
void paintBody(ICorePainter& painter) override;
void setWidth(double width) override;
void setTrackHeight(double height);
// ⚠ Deliberately HIDES ICoreGraphicsObject::getWidth() and always did;
// moving the body out of line does not change that.
[[nodiscard]] double getWidth() const;
// Recomputes the thumb size/position and visibility from the current
// scrollable-area state. Called whenever the scroll offset or content
// height changes.
void refresh();
// Out of line: Impl is incomplete here, so the unique_ptr's deleter cannot
// be instantiated in this header. It was an empty inline body before H5.5.
~ICoreGraphicsScrollPaneScrollBar() override;
protected:
bool mousePressed(const ICoreMouseEvent& event) override;
bool mouseMoved(const ICoreMouseEvent& event) override;
bool mouseReleased(const ICoreMouseEvent& event) override;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreGraphicsScrollPaneScrollableArea.h#
src/ICoreEssentials/UI/Graphics/ICoreGraphicsScrollPaneScrollableArea.h
Q_OBJECT removed (P2.9d-3): this class declares no signal, slot, Q_PROPERTY or Q_INVOKABLE of its own, and nothing qobject_casts to it, holds a QPointer to it, animates it by name or reaches its metaObject(). It therefore had a meta-object nobody consulted -- and it could not keep one past P2.9d-5, when the base stops being a QObject.
ICoreGraphicsScrollPaneScrollableArea#
ICoreGraphicsScrollPaneScrollableArea.h:23 · class · bases public ICoreGraphicsObject · pImpl · 16 declaration(s)
class ICoreGraphicsScrollPaneScrollableArea : public ICoreGraphicsObject {
public:
explicit ICoreGraphicsScrollPaneScrollableArea(ICoreNativeItem* parent = nullptr);
// contentBounds(), not boundingRect() (P2.9d-2). Same value, same members:
// the base derives boundingRect() from this, so nothing about the geometry
// changes -- what goes away is an override of a Qt virtual that would stop
// being called at all once this tier drops its Qt base.
[[nodiscard]] ICoreRect contentBounds() const override;
[[nodiscard]] ICorePainterPath contentShape() const override;
void paintBody(ICorePainter& painter) override;
// Seam-typed since P2.9d-5c (see ICoreGraphicsScrollPane::setContentItem).
void setContentItem(ICoreNativeItem* content);
void setWidth(double width) override;
void setHeight(double height);
void setFillColor(ICoreColor fillColor);
void setBorderColor(ICoreColor borderColor);
void scroll(double scrollValue);
// Scroll-bar support.
void setScrollBar(ICoreGraphicsScrollPaneScrollBar* scrollBar);
void setScrollY(double scrollY); // absolute offset; clamped + applied
[[nodiscard]] double getScrollY() const;
[[nodiscard]] double getViewportHeight() const;
double getContentHeight() const;
// Out of line: Impl is incomplete here, so the unique_ptr's deleter cannot
// be instantiated in this header. It was an empty inline body before H5.7.
~ICoreGraphicsScrollPaneScrollableArea() override;
protected:
bool wheelScrolled(const ICoreWheelEvent& event) override;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreGraphicsTable.h#
src/ICoreEssentials/UI/Graphics/ICoreGraphicsTable.h
Q_OBJECT removed (P2.9d-3): this class declares no signal, slot, Q_PROPERTY or Q_INVOKABLE of its own, and nothing qobject_casts to it, holds a QPointer to it, animates it by name or reaches its metaObject(). It therefore had a meta-object nobody consulted -- and it could not keep one past P2.9d-5, when the base stops being a QObject.
ICoreGraphicsTable#
ICoreGraphicsTable.h:14 · class · bases public ICoreGraphicsObject · pImpl · 15 declaration(s)
class ICoreGraphicsTable : public ICoreGraphicsObject {
public:
explicit ICoreGraphicsTable(ICoreNativeItem* parent = nullptr, const std::vector<std::string>& initialColumnsNames = {});
// contentBounds(), not boundingRect() (P2.9d-2). Same value, same members:
// the base derives boundingRect() from this, so nothing about the geometry
// changes -- what goes away is an override of a Qt virtual that would stop
// being called at all once this tier drops its Qt base.
[[nodiscard]] ICoreRect contentBounds() const override;
void paintBody(ICorePainter& painter) override;
void setInitialEntryRowTexts(const std::vector<std::string>& entryDefaultInitialTexts_Candidate);
ICoreGraphicsTableEntryRow* createNewEntryRow(const std::vector<std::string>& entryInitialTexts);
void deleteEntryRow(ICoreGraphicsTableEntryRow *entryToDelete);
void setWidth(double width) override;
void setHeight(double height);
void setColumnEditable(const int& columnIndex, const bool& enabled);
void setColumnsWidthRatios(const std::vector<double>& newSpaces);
void autoCalculateEntriesYPos();
void reconstructDescendents();
void clearAllEntries();
void resetToInitialState(ICoreNativeItem* parent = nullptr, const std::vector<std::string>& initialColumnsNames = {});
~ICoreGraphicsTable() override;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreGraphicsTableEntryRow.h#
src/ICoreEssentials/UI/Graphics/ICoreGraphicsTableEntryRow.h
Q_OBJECT removed (P2.9d-3): this class declares no signal, slot, Q_PROPERTY or Q_INVOKABLE of its own, and nothing qobject_casts to it, holds a QPointer to it, animates it by name or reaches its metaObject(). It therefore had a meta-object nobody consulted -- and it could not keep one past P2.9d-5, when the base stops being a QObject.
ICoreGraphicsTableEntryRow#
ICoreGraphicsTableEntryRow.h:13 · class · bases public ICoreGraphicsObject · pImpl · 12 declaration(s)
class ICoreGraphicsTableEntryRow : public ICoreGraphicsObject {
public:
explicit ICoreGraphicsTableEntryRow(ICoreGraphicsTable* parentTable, const std::vector<std::string>& columns);
// contentBounds(), not boundingRect() (P2.9d-2). Same value, same members:
// the base derives boundingRect() from this, so nothing about the geometry
// changes -- what goes away is an override of a Qt virtual that would stop
// being called at all once this tier drops its Qt base.
[[nodiscard]] ICoreRect contentBounds() const override;
void paintBody(ICorePainter& painter) override;
void setColumnsWidths(std::vector<double> columnsWidths);
void setHeight(double height);
std::vector<ICoreGraphicsBoxedText*> getAllTextItems() const;
void reconstructDescendents();
void resetToInitialState(ICoreGraphicsTable* parentTable, const std::vector<std::string>& columns);
// The recycler's liveness bookkeeping -- see ICoreGraphicsRecycler.
void kill();
void setAlive();
[[nodiscard]] bool isAlive() const;
~ICoreGraphicsTableEntryRow() override;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreGraphicsTableTitleRowSplitter.h#
src/ICoreEssentials/UI/Graphics/ICoreGraphicsTableTitleRowSplitter.h
Q_OBJECT removed (P2.9d-3): this class declares no signal, slot, Q_PROPERTY or Q_INVOKABLE of its own, and nothing qobject_casts to it, holds a QPointer to it, animates it by name or reaches its metaObject(). It therefore had a meta-object nobody consulted -- and it could not keep one past P2.9d-5, when the base stops being a QObject.
ICoreGraphicsTableTitleRowSplitter#
ICoreGraphicsTableTitleRowSplitter.h:14 · class · bases public ICoreGraphicsObject · pImpl · 13 declaration(s)
class ICoreGraphicsTableTitleRowSplitter : public ICoreGraphicsObject {
public:
explicit ICoreGraphicsTableTitleRowSplitter(ICoreGraphicsTableTitlesRow* parentTitlesRow, ICoreGraphicsTable* grandParentTable);
// contentBounds(), not boundingRect() (P2.9d-2). Same value, same members:
// the base derives boundingRect() from this, so nothing about the geometry
// changes -- what goes away is an override of a Qt virtual that would stop
// being called at all once this tier drops its Qt base.
[[nodiscard]] ICoreRect contentBounds() const override;
void paintBody(ICorePainter& painter) override;
void resetToInitialState(ICoreGraphicsTableTitlesRow* parentTitlesRow, ICoreGraphicsTable* grandParentTable);
// The recycler's liveness bookkeeping -- see ICoreGraphicsRecycler.
void kill();
void setAlive();
[[nodiscard]] bool isAlive() const;
~ICoreGraphicsTableTitleRowSplitter() override;
protected:
void pointerEntered(const ICoreMouseEvent& event) override;
void pointerLeft() override;
bool mousePressed(const ICoreMouseEvent& event) override;
bool mouseMoved(const ICoreMouseEvent& event) override;
bool mouseReleased(const ICoreMouseEvent& event) override;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreGraphicsTableTitlesRow.h#
src/ICoreEssentials/UI/Graphics/ICoreGraphicsTableTitlesRow.h
Q_OBJECT removed (P2.9d-3): this class declares no signal, slot, Q_PROPERTY or Q_INVOKABLE of its own, and nothing qobject_casts to it, holds a QPointer to it, animates it by name or reaches its metaObject(). It therefore had a meta-object nobody consulted -- and it could not keep one past P2.9d-5, when the base stops being a QObject.
ICoreGraphicsTableTitlesRow#
ICoreGraphicsTableTitlesRow.h:14 · class · bases public ICoreGraphicsObject · pImpl · 11 declaration(s)
class ICoreGraphicsTableTitlesRow : public ICoreGraphicsObject {
public:
explicit ICoreGraphicsTableTitlesRow(ICoreGraphicsTable* parentTable, const std::vector<std::string>& columns);
// contentBounds(), not boundingRect() (P2.9d-2). Same value, same members:
// the base derives boundingRect() from this, so nothing about the geometry
// changes -- what goes away is an override of a Qt virtual that would stop
// being called at all once this tier drops its Qt base.
[[nodiscard]] ICoreRect contentBounds() const override;
void paintBody(ICorePainter& painter) override;
void setColumnsWidths(std::vector<double> newColumnsWidths);
void setHeight(double height);
std::vector<ICoreGraphicsBoxedText*> getAllTextItems() const;
std::vector<double> getColumnsWidths() const;
qsizetype getSplitterIndex(ICoreGraphicsTableTitleRowSplitter* splitter);
// [[nodiscard]] std::vector<double> getAllSplitters() const;
void reconstructDescendents();
void resetToInitialState(ICoreGraphicsTable* parentTable, const std::vector<std::string>& columns);
~ICoreGraphicsTableTitlesRow() override;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreGraphicsText.h#
src/ICoreEssentials/UI/Graphics/ICoreGraphicsText.h
ICoreGraphicsText#
ICoreGraphicsText.h:66 · class · bases public ICoreNativeItem · pImpl · 62 declaration(s)
⚠ IMPLEMENTS ICoreNativeItem, added by P2.10 at P2.9's request.
class ICoreGraphicsText : public ICoreNativeItem {
public:
// The Impl's QGraphicsTextItem, not `this`. R2 still applies inside:
// QGraphicsTextItem reaches QGraphicsItem through QGraphicsObject, so the
// cast is written out in the .cpp where Impl is complete.
ICoreNativeHandle nativeItemHandle() const override;
// ⚠ Takes ICoreFont, and deliberately does NOT re-export the inherited
// QGraphicsTextItem::setFont(const QFont&) with a `using`. P7.6 converted ICoreFont, so
// it no longer converts to QFont and every call site passing one needs a
// sink that speaks the wrapper. A `using` here would reopen exactly the
// re-export hole §9 records neither guard being able to see, since the Qt
// name would appear only at the call site. Hiding the base overload is
// safe: QGraphicsTextItem::setFont is not virtual, and a caller still holding a raw
// QFont converts through ICoreFont's implicit inbound constructor.
void setFont(const ICoreFont& font);
// The getter setFont has always implied, added by P2.10b-6a because the
// flip needs it: 9 sites read the item's font and today reach
// QGraphicsTextItem::font() through the base, which stops existing at
// P2.10b-6.
//
// Returns ICoreFont, not QFont, and that costs those 9 sites NOTHING today:
// every sink already speaks the wrapper -- serializeFont(const ICoreFont&),
// ICoreNativeDialogs::getFont(const ICoreFont&, ...) -- and four of them
// already write `ICoreFont f = ...->font()`, which was converting from QFont
// through ICoreFont's implicit inbound constructor on the way in.
//
// ⚠ Shadows the base's non-virtual font() rather than `using`-ing it, for
// exactly the reason setFont above spells out: a `using` would re-export a
// QFont-returning overload that neither guard can see at the call site.
[[nodiscard]] ICoreFont font() const;
// The item's own area, origin at (0,0) -- the ICore spelling of
// boundingRect(). The default computes it from the document; overriding
// THIS is how a subclass states its own size, exactly as it is on
// ICoreGraphicsObject.
//
// ⚠ THE DEFAULT MUST CALL QGraphicsTextItem::boundingRect() QUALIFIED, AND
// THAT IS NOT A STYLE CHOICE. boundingRect() below is now derived from
// this, so an unqualified boundingRect() here is INFINITE RECURSION -- it
// would re-enter the override that just called us. The .cpp says so again
// at the body.
[[nodiscard]] virtual ICoreRect contentBounds() const;
// ⚠ boundingRect() IS GONE FROM THIS TYPE, as this comment promised it
// would be. It lives on Impl and is derived from contentBounds() there, so
// a subclass still states its size by overriding contentBounds() and the
// toolkit still sees the same rectangle. A caller that wants the rectangle
// asks contentBounds().
// ------------------------------------------------------------------
// P2.10b-1 -- THE TEXT/DOCUMENT FACADE. Additive; the toolkit base is
// still here, so nothing below changes behaviour yet. It exists so the
// flip (P2.10b-6) changes these BODIES and not the ~114 call sites that
// reach QGraphicsTextItem's own surface through this type.
//
// ⚠ THIS HALF BREAKS NOTHING, AND THAT IS A PROPERTY OF ICoreString
// RATHER THAN OF THE DESIGN. ICoreString converts to and from QString
// IMPLICITLY BOTH WAYS (its header says so at the conversion block), so a
// caller passing a QString or a literal, or assigning the result to a
// QString, keeps compiling untouched. Do NOT generalise that to the item
// half in P2.10b-2: ICorePoint and ICoreRect convert IN implicitly and
// OUT only by a named call, which is why P2.9d-1 broke 12 TUs on purpose.
//
// ⚠ Deliberately absent, each because reading the call sites said so:
// * document() -- 15 sites, and NOT ONE of them wants a document.
// They want the four operations below. Exposing a
// QTextDocument* would put a raw Qt type through
// the seam to serve nobody.
// * textCursor()/setTextCursor() -- 4 sites, all four BYTE-IDENTICAL:
// get cursor, clearSelection, set it back. That is
// clearTextSelection(), and QTextCursor never has
// to cross. (Fifth and sixth copies of the same
// duplication P2.11a and P2.9d-1 each removed.)
// * textInteractionFlags() -- 1 site, and it only asks "is this
// editable". A flags getter would hand out
// Qt::TextInteractionFlags for a bool question.
// ------------------------------------------------------------------
// Content. These SHADOW the non-virtual base methods, exactly as setFont
// and setDefaultTextColor above already do.
void setPlainText(const ICoreString& text);
[[nodiscard]] ICoreString toPlainText() const;
void setHtml(const ICoreString& html);
// Layout. setTextWidth is a pure forwarder today and costs its 14 call
// sites nothing -- it is here because at the flip there is no base to
// inherit it from, not because anything needs rewriting.
void setTextWidth(double width);
[[nodiscard]] double textWidth() const;
// document()->setDocumentMargin(). Four sites, all of them margin 0.
void setDocumentMargin(double margin);
// document()->setDefaultTextOption() with an alignment. Five sites, all
// of them ICoreAlignment::Center. The enum is already pinned 1:1 to
// Qt::Alignment in ICoreInputEnumsVerify.cpp, so the seam is a cast.
void setTextAlignment(ICoreAlignment alignment);
// document()->adjustSize(), then the laid-out size. Split in two because
// the one site that needs the size mutates first and then reads, and
// folding a mutation into a getter would hide that.
void adjustTextSize();
// The DOCUMENT's laid-out size as a rect at origin (0,0) -- the same
// convention contentBounds() documents above. ⚠ NOT a synonym for
// contentBounds(): that one is boundingRect(), which is the ITEM's area.
// The two are close and are not defined to be equal, so they stay two
// methods mapping to two toolkit calls rather than one guess.
[[nodiscard]] ICoreRect textBounds() const;
// Interaction. Four values because four are used; the pairing with Qt is
// in the .cpp. TextBrowserInteraction and the widget tier's combinations
// are deliberately absent -- no site in this tier asks for them.
enum class TextInteraction {
None, // Qt::NoTextInteraction
SelectableByMouse, // Qt::TextSelectableByMouse
SelectableByMouseAndKeyboard, // ... | Qt::TextSelectableByKeyboard
Editable // Qt::TextEditorInteraction
};
void setTextInteraction(TextInteraction interaction);
// The one question the single flags reader actually asks.
[[nodiscard]] bool isTextEditable() const;
// The four-line block that was copy-pasted into four classes.
void clearTextSelection();
// ------------------------------------------------------------------
// P2.10b-2 -- THE ITEM FACADE. The plain-QGraphicsItem half, and unlike
// b-1 above it is mostly a COPY: ICoreGraphicsObject already spells all
// of this (P2.9a + P2.9d-1), and the text tier gets the SAME names so one
// concept does not end up with two spellings across two tiers.
//
// ⚠ THIS HALF DOES BREAK CALL SITES, AND THAT IS THE MECHANISM WORKING.
// Two reasons, both inherited from P2.9a's write-ups:
// * Name hiding in C++ is per-NAME, not per-signature, so declaring
// setPos here hides the base's whole overload set. That is what makes
// a leftover Qt spelling a compile error rather than a silent
// survivor. Do NOT "fix" it with `using QGraphicsTextItem::setPos;`.
// * pos() returns ICorePoint, and ICorePoint converts IN from QPointF
// implicitly but OUT only through the named toQPointF(). So a site
// feeding the result to a Qt sink must move, and the compiler names
// each one.
// The sites the compiler named are fixed in this same commit -- a facade
// that leaves the tree red is not a landable step.
//
// ⚠ Deliberately absent:
// * boundingRect() -- 16 call sites, and contentBounds() has answered
// them since before b-1. Adding a second spelling of the item's own
// area is what §9 forbids. (The 16 sites move in b-3; the VIRTUAL
// override on ICoreGraphicsBoxedText is b-4's, not this row's.)
// * setZValue, sceneBounds, mapToScene/mapFromScene, setOpacity,
// setEnabled, setAcceptDrops -- on ICoreGraphicsObject because the
// scene tier calls them. This tier calls none of them. A forwarder
// exists because something asks for it.
// ------------------------------------------------------------------
void setPos(const ICorePoint& position);
void setPos(double x, double y);
[[nodiscard]] ICorePoint pos() const;
// A null parent detaches the item from the scene tree.
void setParentItem(ICoreNativeItem* parent);
// The ICore spelling of setTransformOriginPoint -- the name
// ICoreGraphicsObject already gave it. ⚠ A survey that matches on method
// NAMES reports this one missing from the scene tier's facade; the
// concept is there under a better name. Check concepts, not spellings.
void setTransformOrigin(const ICorePoint& origin);
void setRotation(double angle);
void setVisible(bool visible);
[[nodiscard]] bool isVisible() const;
void show();
void hide();
void update();
void prepareGeometryChange();
void setAcceptHoverEvents(bool accept);
// ⚠ The SCOPED enum, with no bitmask sibling -- copied deliberately,
// including the omission. P2.9a wrote the bitmask overload first and had
// to delete it: ICoreMouseButtons is a `using = unsigned int` and
// Qt::MouseButton is unscoped, so every call site spelling Qt::LeftButton
// bound to it silently and the tree stayed green with the raw Qt name
// alive inside a wrapper zone. The two sites in this tier still spelling
// Qt::LeftButton fail loudly under the scoped enum, which is the point.
void setAcceptedMouseButtons(ICoreMouseButton button);
// ------------------------------------------------------------------
// The QGraphicsItem flags this tier sets, as named booleans.
//
// ✅ P2.9a LEFT ItemIsFocusable TO THIS TASK BY NAME -- "they are P2.10's
// to name, and naming them here would put the vocabulary on the wrong
// base" (ICoreGraphicsObject.h). setFocusable is the answer, spelled to
// match ICoreWidget::setFocusable rather than invented.
//
// ⚠⚠ THE OTHER FLAG P2.9a DELEGATED, ItemUsesExtendedStyleOption, GETS NO
// NAME AT ALL -- it is dead, and its four sites should be DELETED (b-3).
// Three separate things say so:
// * Qt's docs: the flag governs only how finely exposedRect is filled
// in on QStyleOptionGraphicsItem. NOTHING in this entire tree reads
// exposedRect or levelOfDetailFromTransform, so it cannot have an
// effect either way.
// * The comment riding on every one of the four sites -- "This prevents
// Qt from drawing the dashed focus rect" -- is simply not what the
// flag does. What actually strips Qt's focus decoration is this
// class's Chrome (None/FocusRing), added by P2.10a's predecessor.
// * ICoreCanvasAreaViewTitleBarLabel already has both lines COMMENTED
// OUT and looks and behaves correctly, which is the experiment
// already having been run.
// Naming a flag whose only demonstrated property is a wrong comment
// would carry the cargo across the seam. Same reading P7.3 made when it
// declined to add toHexRgbString.
// ------------------------------------------------------------------
void setFocusable(bool focusable);
void setSelectable(bool selectable);
[[nodiscard]] bool isSelected() const;
// Focus. ⚠ `takeFocus` rather than `setFocus`, because that is what
// ICoreWidget already calls it (ICoreWidget.h) -- the scene tier has no
// focus vocabulary to copy, since scene items did not take keyboard focus
// and text items do. Same default reason as the widget tier.
void takeFocus(ICoreFocusReason reason = ICoreFocusReason::Mouse);
void clearFocus();
[[nodiscard]] bool hasFocus() const;
// ✅ "Am I on a scene?" -- and it is a BOOL, not P2.9d-4's reverse
// lookup. The whole text tier has exactly ONE scene() site and it is
// `if (!this->scene())`. P6.5's handle-keyed reverse lookup exists for a
// caller that wants the ICoreGraphicsScene wrapper back; this tier has
// none, so the expensive decision does not arise here.
[[nodiscard]] bool isInScene() const;
// Added by the flip for ICoreCanvasScanner, its single caller. On P0.7's
// precedent: one caller justifies a forwarder when the alternative is
// stranding a raw toolkit call that cannot survive the conversion.
[[nodiscard]] bool isUnderMouse() const;
// Which content token the text is drawn in.
enum class Ink { Primary, Secondary, Tertiary, Accent, OnAccent };
// What paint() does with Qt's own selection/focus decoration.
enum class Chrome {
Default, // leave it to Qt -- the default, and what a plain
// QGraphicsTextItem does
None, // strip Qt's selected/focused states, draw nothing extra
FocusRing // strip them, then draw this application's selection-border
// ring while the item has focus
};
// ⚠ Retyped off QGraphicsItem* by the flip. ICoreGraphicsBoxedText's
// constructor was already ICoreNativeItem* (P2.10b-3b) and had to unwrap
// with icoreNativeItem() to reach these two; that unwrap is now gone, which
// is the single line b-3b predicted would delete here.
explicit ICoreGraphicsText(ICoreNativeItem* parent = nullptr);
explicit ICoreGraphicsText(const ICoreString& text, ICoreNativeItem* parent = nullptr);
void setInk(Ink ink);
// Out of line since the flip: the state lives in Impl now.
[[nodiscard]] Ink ink() const;
void setChrome(Chrome chrome);
[[nodiscard]] Chrome chrome() const;
// Shadows QGraphicsTextItem::setDefaultTextColor -- see the header note.
void setDefaultTextColor(const ICoreColor& color);
// Hands the item back to the theme after a custom colour.
void clearCustomTextColor();
// Out of line: Impl is incomplete here, so the unique_ptr's deleter
// cannot be instantiated in this header.
~ICoreGraphicsText() override;
protected:
// Called BEFORE the text is drawn, for a subclass that wants a ground
// behind its label. Separate from paintContent below and not a substitute
// for it: anything drawn in paintContent lands ON TOP of the text, so a
// background painted there would hide the very label it is backing.
virtual void paintBackground(ICorePainter& painter);
// Called after the text (and any focus ring) has been drawn, for a subclass
// that decorates its label.
virtual void paintContent(ICorePainter& painter);
// The same hook surface ICoreGraphicsObject carries, for the text tier.
// Hover requires setAcceptHoverEvents(true) on the item, as in the toolkit.
virtual void pointerEntered(const ICoreMouseEvent& event);
virtual void pointerLeft();
// ------------------------------------------------------------------
// ⚠ A HOOK, NOT AN ICoreSignal, AND THE CALL SITES ARE WHY.
// Both tree-wide connections to QTextDocument::contentsChanged name
// `this` as the receiver (ICoreCanvasTextBoxViewLabel, twice) -- it is an
// object telling ITSELF its text changed, never a subscriber elsewhere.
// An ICoreSignal would be exactly the speculative surface P2.10a deleted
// from ICoreGraphicsBoxedText for having zero connections.
//
// Wired once here, in the constructor, so the connection is the base's
// business and a recycled subclass cannot forget it -- or double it.
// ⚠ ICoreCanvasTextBoxViewLabel::resetToInitialState currently re-connects
// on every recycle without disconnecting, so a recycled note re-lays-out
// once per previous life. Migrating it in P2.10b-3 removes that by
// construction; it is a real (if cheap) defect, recorded so the fix is
// not mistaken for a behaviour change.
// ------------------------------------------------------------------
virtual void textChanged();
// ------------------------------------------------------------------
// The gap P2.10 has to close, added additively ahead of the conversion
// exactly as P2.7 did for ICoreGraphicsObject: empty bodies, the toolkit
// handlers still virtual, so an unmigrated subclass keeps working.
//
// ⚠ THE RETURN CONVENTION IS ICoreGraphicsObject'S AND SO IS ITS TRAP.
// false forwards to the toolkit base; true accepts and skips it. For a
// PRESS that difference is not cosmetic: Qt accepts a reimplemented press
// by default and makes the item the mouse grabber, while the base ignores
// it for an item that is neither movable nor selectable -- so a handler
// that used to return without calling its base must return TRUE, and
// returning false silently costs it every later move and release. P2.8
// hit this across 25 classes; the rule is written up under that task.
// ------------------------------------------------------------------
virtual bool mousePressed(const ICoreMouseEvent& event);
virtual bool mouseMoved(const ICoreMouseEvent& event);
virtual bool mouseReleased(const ICoreMouseEvent& event);
virtual bool mouseDoubleClicked(const ICoreMouseEvent& event);
// Matches ICoreGraphicsObject's widened hook (P2.8 batch 11): an
// ICoreMouseEvent, not a bare point, because a context menu is opened at a
// screen position, tested at an item position, and may place what it
// creates at a scene position.
virtual bool contextMenuRequested(const ICoreMouseEvent& event);
// ------------------------------------------------------------------
// ⚠ FOCUS-OUT IS A PAIR HERE, AND IT IS THE ONE TIER WHERE IT HAS TO BE.
// Decided by the owner, 2026-08-11, after reading all four overriders.
//
// `focusLost` means "after the toolkit base" EVERYWHERE ELSE in the tree
// -- ICoreWidget::focusOutEvent calls QWidget's base and then the hook.
// But every one of this class's four overriders does its substantive work
// BEFORE the base: the three labels commit their text (setPlainText,
// applyDefaultStyle, updatePosition) and ICoreGraphicsBoxedText emits its
// signal, all ahead of QGraphicsTextItem::focusOutEvent. Folding that into
// a single after-the-base hook would move a document mutation across the
// toolkit's own focus-out handling.
//
// Reversing this class's forwarder instead was rejected: it would give one
// name two meanings across two tiers. So the slot splits, and each body
// maps mechanically with NO order change at all.
//
// ⚠ `guiTest`'s 30 cases are theme/shell/render and would NOT catch a
// focus-ordering regression, so this could not be settled by running the
// suites -- only by reading the bodies. Keep it that way: if you add a
// third hook here, read every overrider before you do.
//
// Most subclasses want only ONE of the pair. That is expected, not a smell.
// ------------------------------------------------------------------
// ⚠ FOCUS-IN IS A SINGLE VETOING HOOK, NOT A PAIR, AND THE ASYMMETRY WITH
// FOCUS-OUT ABOVE IS THE POINT (P2.10b-4). Its one overrider,
// ICorePortViewDescriptionLabel, DECLINES the base outright when the label
// is not user-editable -- so what it needs is a veto, which is exactly
// what focus-out's note says a focus LOSS can never have. Nothing in this
// tier does work after QGraphicsTextItem::focusInEvent, so there is no
// after-half to name and none is invented (§9).
//
// Return true to skip the toolkit base; call event.ignore() to also let
// the focus event propagate. Two axes, spelled as keyPressed spells them.
//
// ⚠ NOT named `focusGained`: ICoreWidget::focusGained is `void` and runs
// AFTER its base, so reusing that name for a before-the-base bool would be
// one name meaning two things across two tiers -- the trap P2.10a rejected
// when it named `focusLosing` and keyPressHandled dodged again below.
virtual bool focusGaining(const ICoreFocusEvent& event);
// Before QGraphicsTextItem::focusOutEvent -- commit or normalise the text
// here, which is what every overrider in this tree actually does.
virtual void focusLosing(const ICoreFocusEvent& event);
// After the toolkit base has handled the focus loss. Matches what
// `focusLost` means on ICoreWidget. In this tier the bodies that landed
// here are logging, which is why the split was needed rather than a
// reversal.
virtual void focusLost(const ICoreFocusEvent& event);
// ------------------------------------------------------------------
// KEYS, AND THEY ARE A PAIR FOR THE SAME REASON FOCUS-OUT IS (P2.10b-4).
//
// `keyPressed` is the before-the-base, vetoing half, spelled exactly as
// ICoreWidget::keyPressed so one concept keeps one name across tiers.
// Return true to skip the toolkit base; call event.ignore() to also let
// the key propagate to the item above. Two axes, as with the mouse.
//
// ⚠ `keyPressHandled` runs AFTER the toolkit base, and it exists because
// ICoreChartAxisLabel's body does. That class resizes itself to fit its
// text on every keystroke, and it measures the CURRENT text -- so running
// it before QGraphicsTextItem inserts the character sizes the label one
// keystroke behind, visibly, while typing. Its old override called its
// parent FIRST and then resized, and this pair is the only way to keep
// that sequence once the Qt virtual is gone.
//
// ⚠ It is NOT named `keyPressed` even though "after" is the past tense
// that would read best: ICoreWidget already uses `keyPressed` for the
// BEFORE half, and one name meaning two things in two tiers is precisely
// what P2.10a rejected when it named `focusLosing`.
//
// One caller is enough here, on P0.7's precedent (ICoreEasingSpec was
// added for a single site because the alternative was dropping the
// behaviour or stranding a raw Qt type). The alternative here is the same:
// strand a Qt override that cannot survive the flip, or change behaviour.
// ------------------------------------------------------------------
virtual bool keyPressed(const ICoreKeyEvent& event);
virtual void keyPressHandled(const ICoreKeyEvent& event);
// ⚠ THE 11 TOOLKIT VIRTUALS THAT STOOD HERE (hoverEnter/Leave, the four
// mouse events, contextMenu, focusIn/Out, keyPress, paint) MOVED INTO Impl
// WHOLESALE. They are what forwards the toolkit to the hooks above, and
// they had to move because Impl is the QGraphicsTextItem now. Their bodies
// are unchanged -- only `QGraphicsTextItem::x(e)` became
// `QGraphicsTextItem::x(e)` on Impl and `hook(...)` became
// `m_owner.hook(...)`.
};
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreGraphicsView.h#
src/ICoreEssentials/UI/Graphics/ICoreGraphicsView.h
ICoreGraphicsView#
ICoreGraphicsView.h:36 · class · bases public ICoreNativeWidget · pImpl · 42 declaration(s)
class ICoreGraphicsView : public ICoreNativeWidget {
public:
enum class Backdrop {
None, // brush untouched -- the default, see above
Canvas, // the block-diagram ground
Panel, // content raised above a panel (a chart's plot sheet)
Transparent // no brush, and a translucent viewport, so whatever the
// view floats over shows through
};
explicit ICoreGraphicsView(ICoreNativeWidget* parent = nullptr);
explicit ICoreGraphicsView(Backdrop backdrop, ICoreNativeWidget* parent = nullptr);
explicit ICoreGraphicsView(ICoreGraphicsScene* scene, Backdrop backdrop);
~ICoreGraphicsView() override;
ICoreGraphicsView(const ICoreGraphicsView&) = delete;
ICoreGraphicsView& operator=(const ICoreGraphicsView&) = delete;
void setScene(ICoreGraphicsScene* scene);
void setBackdrop(Backdrop backdrop);
Backdrop backdrop() const;
// The frame and both scroll bars, off together. Opt-in: a view that says
// nothing keeps the toolkit's frame and its automatic scroll bars.
void setChromeHidden(bool hidden);
bool isChromeHidden() const;
// Scroll bars only, leaving the frame alone -- what ICoreChartView wants,
// and the reason this is not folded into setChromeHidden().
void setScrollBarsVisible(bool visible);
// Zoom and pan keep the point under the pointer fixed, rather than the
// view centre. Both views that zoom want this; it is not the default.
void setZoomAnchoredUnderPointer(bool anchored);
void setAcceptsDrops(bool accepts);
void setAntialiased(bool antialiased);
void setFixedSize(double width, double height);
// --- Scroll position and viewport geometry.
//
// These replace 12 external reaches through `horizontalScrollBar()->value()`
// and its setter. Every one of them wanted a scroll POSITION; not one
// wanted a QScrollBar, so handing one out was exporting a toolkit widget to
// express a number. Doubles because every caller already computes in
// zoom-scaled doubles; the truncation to the toolkit's integer scrollbar
// now happens once, here, instead of at each call site.
double horizontalScroll() const;
double verticalScroll() const;
void setHorizontalScroll(double value);
void setVerticalScroll(double value);
// ⚠ viewWidth/viewHeight rather than width/height. The short names arrived
// from QWidget before the conversion, and a call site that kept using them
// would silently bind to something else rather than fail -- the quiet
// substitution R1 punishes elsewhere.
double viewWidth() const;
double viewHeight() const;
// The visible area in the view's own coordinates.
ICoreRect viewportBounds() const;
ICorePoint mapToScene(const ICorePoint& viewPoint) const;
ICoreRect mapToScene(const ICoreRect& viewRect) const;
ICorePoint mapFromScene(const ICorePoint& scenePoint) const;
// Position and margins within the parent's layout. Both arrive from QWidget
// today; a chart moves its view to the plot origin and zeroes its margins.
void setViewPosition(double x, double y);
void setViewMargins(double left, double top, double right, double bottom);
void centerViewOn(const ICorePoint& scenePosition);
// Centres on an ITEM rather than a point -- what "show me this block" means
// at the one call site, and it saves the caller reaching for the item's
// scene position through a second API.
void centerViewOn(ICoreNativeItem* item);
// Viewport-relative point to screen coordinates. Named on the view because
// the mapping is the VIEWPORT's, not the widget's, and a caller that used
// the widget's would be off by the frame.
ICorePoint mapViewportToGlobal(const ICorePoint& viewportPoint) const;
void scaleBy(double factor);
void requestRepaint();
ICoreNativeHandle nativeWidgetHandle() const override;
protected:
// ------------------------------------------------------------------
// The hook surface (P2.11b), mirroring ICoreGraphicsObject's. The names are
// deliberately the ones already in use one tier down (and ICoreChartBase's
// `wheelScrolled`), so a reader moving between the item tier and the view
// tier meets one vocabulary rather than two. Every bool answers "handled?";
// false forwards to the toolkit base so unhandled gestures behave as before.
// ------------------------------------------------------------------
virtual bool wheelScrolled(const ICoreWheelEvent& event);
virtual bool mousePressed(const ICoreMouseEvent& event);
virtual bool mouseMoved(const ICoreMouseEvent& event);
virtual bool mouseReleased(const ICoreMouseEvent& event);
// Drag and drop onto the view. Qt's contract applies unchanged: a drag not
// accepted on ENTER never produces the later two.
virtual bool dragEntered(const ICoreDragEvent& event);
virtual bool dragMovedOver(const ICoreDragEvent& event);
virtual bool payloadDropped(const ICoreDragEvent& event);
// ⚠ Hands over the VIEWPORT bounds, not the widget size, and not the
// old/new pair the P5.1 gap list sketches for ICoreWidget. Discovered from
// the call site rather than from what Qt offers (§9): the one overrider,
// ICoreChartView, ignores the event entirely and reads the viewport rect.
virtual void resized(const ICoreRect& viewportBounds);
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};