Generated reference › API — ICoreEssentials/UI/Painting
kind: generated#api#icoreessentials-ui-painting

API — ICoreEssentials/UI/Painting

The public contract of 10 header(s) under src/ICoreEssentials/UI/Painting — 8 class/struct definition(s), 119 declaration(s). Each section shows the header's banner and its public (and protected-virtual) surface exactly as the file writes it.

ICoreBrush.h#

src/ICoreEssentials/UI/Painting/ICoreBrush.h

ICoreBrush#

ICoreBrush.h:27 · class · 10 declaration(s)

class ICoreBrush {
public:
    // Default is Qt::NoBrush -- "no fill". Fifteen call sites spell it as a
    // bare ICoreBrush() to turn filling off before stroking an outline, so it
    // is the single most-used constructor here.
    ICoreBrush();

    ICoreBrush(const ICoreColor& color);
    ICoreBrush(const ICoreLinearGradient& gradient);
    ICoreBrush(const ICoreRadialGradient& gradient);

    ICoreBrush(const ICoreBrush& other);
    ICoreBrush(ICoreBrush&& other) noexcept;
    ICoreBrush& operator=(const ICoreBrush& other);
    ICoreBrush& operator=(ICoreBrush&& other) noexcept;
    ~ICoreBrush();

    // The seam, per §1. Call icoreQt() from a .cpp rather than reaching in.
    const void* nativeStorage() const;

    // Public so the .cpp can pin them; §7 measured QBrush at 8 bytes (plain
    // d-pointer) against this tree's Qt 6.10.2 on macOS arm64.
    static constexpr std::size_t kNativeStorageSize = 8;
    static constexpr std::size_t kNativeStorageAlign = 8;

};

ICoreGradient.h#

src/ICoreEssentials/UI/Painting/ICoreGradient.h

ICoreLinearGradient#

ICoreGradient.h:29 · class · 10 declaration(s)

The two gradient shapes the app paints with.

class ICoreLinearGradient {
public:
    ICoreLinearGradient();

    ICoreLinearGradient(const ICorePoint& start, const ICorePoint& stop);
    ICoreLinearGradient(double x1, double y1, double x2, double y2);

    ICoreLinearGradient(const ICoreLinearGradient& other);
    ICoreLinearGradient(ICoreLinearGradient&& other) noexcept;
    ICoreLinearGradient& operator=(const ICoreLinearGradient& other);
    ICoreLinearGradient& operator=(ICoreLinearGradient&& other) noexcept;
    ~ICoreLinearGradient();

    // ⚠ setStop is the ONLY spelling. The inherited QGradient::setColorAt used
    // to be reachable through the old base and three sites had drifted onto it;
    // they are migrated. Adding a setColorAt forwarder would have given the
    // tree two names for one operation -- the addition P0.5, P3.4, P7.3 and
    // P7.6's painter decision each refused.
    void setStop(double position, const ICoreColor& color);

    // The seam, per §1. Call icoreQt() from a .cpp rather than reaching in.
    const void* nativeStorage() const;

    // Public so the .cpp can pin them. See the buffer note above: 88, not 8.
    static constexpr std::size_t kNativeStorageSize = 88;
    static constexpr std::size_t kNativeStorageAlign = 8;

};

ICoreRadialGradient#

ICoreGradient.h:60 · class · 10 declaration(s)

class ICoreRadialGradient {
public:
    ICoreRadialGradient();

    ICoreRadialGradient(const ICorePoint& center, double radius);
    ICoreRadialGradient(double cx, double cy, double radius);

    ICoreRadialGradient(const ICoreRadialGradient& other);
    ICoreRadialGradient(ICoreRadialGradient&& other) noexcept;
    ICoreRadialGradient& operator=(const ICoreRadialGradient& other);
    ICoreRadialGradient& operator=(ICoreRadialGradient&& other) noexcept;
    ~ICoreRadialGradient();

    void setStop(double position, const ICoreColor& color);

    const void* nativeStorage() const;

    static constexpr std::size_t kNativeStorageSize = 88;
    static constexpr std::size_t kNativeStorageAlign = 8;

};

ICoreGradientDirection.h#

src/ICoreEssentials/UI/Painting/ICoreGradientDirection.h

File-scope declarations#

// Which way a surface gradient runs, named START corner first: the lit end is
// always the one named first, and the surface deepens toward the second.
// 
// ⚠ A HEADER OF ITS OWN, and deliberately so. ICoreWidget and ICoreToolBar both
// take this in a setter, and ICoreWidget.h is named by ~150 headers in this
// tree -- so it may not reach ICoreSurfaceGradient.h, whose return type drags
enum class ICoreGradientDirection {
    TopToBottom,
    BottomLeftToTopRight,
    BottomRightToTopLeft,
};

ICoreIconRenderer.h#

src/ICoreEssentials/UI/Painting/ICoreIconRenderer.h

ICoreIconRenderer#

ICoreIconRenderer.h:34 · class · pImpl · 6 declaration(s)

An icon drawn at the resolution it will REALLY be shown at, in one place.

class ICoreIconRenderer {
public:
    ICoreIconRenderer();
    ~ICoreIconRenderer();

    // Replaces the art, dropping any rasterization of the old.
    void setIcon(const ICoreIcon& icon);

    // Whether there is art to draw -- the same question ICoreIcon::isNull
    // answers, so an owner does not have to keep the icon around beside this.
    [[nodiscard]] bool isNull() const;

    // Drop the cache. Not needed for a theme switch or a change of art (both
    // are handled), only for an owner recycling this for something new.
    void invalidate();

    // Rasterize at the scale `painter` really lands on, then draw the art
    // fitted to its own aspect and centred inside `box`, in the painter's
    // coordinates. A no-op for null art or an empty box.
    void draw(ICorePainter& painter, const ICoreRect& box);

private:
    class Impl;                    // the two-line residue; state lives here
    std::unique_ptr<Impl> impl;
};

ICoreNavItemStyle.h#

src/ICoreEssentials/UI/Painting/ICoreNavItemStyle.h

The app's nav-row hover/selection treatment, in one place.

A row lit by this reads the same wherever it lives: an accent wash over the resting surface, an accent hairline around it, and an accent edge growing out of the left side. It started on the left fixed panel's menu buttons (ICoreHBoxButton) and is now what every list-of-things-you-can-open wears — the settings panel's menu chooser included — so the two cannot drift apart by someone tuning one copy of the numbers.

progress is 0 at rest and 1 fully lit; a caller animating a hover passes the in-between values and the whole treatment fades with it. Nothing is drawn at 0, which is the point: a nav row stays invisible until the pointer reaches it.

Declares no class of its own — see the file.

ICorePainter.h#

src/ICoreEssentials/UI/Painting/ICorePainter.h

The brush a paintContent() hook is handed. Composition, not subclass: it BORROWS the QPainter the wrapper base class opened on the widget, so client code can never construct one against nothing or keep one past the paint call -- the reference member makes it unassignable and the wrapper controls its lifetime. Every method is a typed pass-through; the Qt name appears only in the .cpp and in the constructor parameter, which no client can spell.

ICorePainter#

ICorePainter.h:29 · class · pImpl · 44 declaration(s)

class ICorePainter {
public:
    explicit ICorePainter(QPainter& painter);
    ~ICorePainter();

    ICorePainter(const ICorePainter&) = delete;
    ICorePainter& operator=(const ICorePainter&) = delete;

    void save();
    void restore();

    void setAntialiasing(bool on);

    // Whether TEXT is antialiased -- separate from setAntialiasing because
    // the toolkit tracks it as its own hint (on by default there, so most
    // callers never touch this; the print path sets it explicitly). Note
    // setAntialiasing already carries SmoothPixmapTransform with it, so
    // there is no separate pixmap-smoothing verb.
    void setTextAntialiasing(bool on);

    void setPen(const ICorePen& pen);
    void setPenColor(const ICoreColor& color);
    void setNoPen();

    void setBrush(const ICoreBrush& brush);
    void setNoBrush();

    void setOpacity(double opacity);
    double opacity() const;

    void setFont(const ICoreFont& font);
    ICoreFont font() const;
    // The scale at which this painter's output actually lands on screen, per
    // axis -- the view's zoom and any item transform folded together with the
    // device pixel ratio.
    //
    // Exists so a renderer can rasterize vector art at the size it will REALLY
    // be shown at, instead of a fixed guess that is blurry when zoomed in and
    // wasteful when zoomed out. It replaces reaching for worldTransform() and
    // device()->devicePixelRatioF() at the call site, which were the only two
    // toolkit escapes left in the scene tier's painting code.
    [[nodiscard]] ICoreSizeF deviceScale() const;

    ICoreFontMetrics fontMetrics() const;

    void drawRect(const ICoreRect& rect);
    void drawRoundedRect(const ICoreRect& rect, double radiusX, double radiusY);
    void fillRect(const ICoreRect& rect, const ICoreBrush& brush);

    // Replace the ink already drawn in `box` with `tint`, keeping its alpha --
    // the "tint a glyph" operation. What is on the device keeps its shape and
    // its soft edges; only its colour changes.
    //
    // ⚠ THIS IS DELIBERATELY A NAMED OPERATION AND NOT A COMPOSITION-MODE
    // SETTER (P7.1, decided by the owner 2026-08-11). Underneath it is
    // CompositionMode_SourceIn + fillRect, which was written out by hand at
    // three sites; the toolkit publishes ~30 composition modes and this tree
    // uses exactly ONE, so an ICoreCompositionMode enum would put 30 knobs
    // across the boundary to serve one idiom. §9's rule -- name the operation,
    // not the toolkit knob -- and the same reading that rejected
    // ICorePointerShape (P0.5) and runOnce() (P3.4).
    //
    // ⚠ It leaves the composition mode where it found it. The three call sites
    // all ended their painter immediately afterwards, so none of them observed
    // the mode again -- but a caller that keeps painting must not inherit
    // SourceIn from a call that reads like a fill.
    void floodKeepingAlpha(const ICoreRect& box, const ICoreColor& tint);
    void drawEllipse(const ICoreRect& rect);
    void drawEllipse(const ICorePoint& center, double radiusX, double radiusY);

    void drawLine(const ICoreLine& line);
    void drawLine(const ICorePoint& p1, const ICorePoint& p2);
    void drawPolyline(const std::vector<ICorePoint>& points);
    void drawPolygon(const std::vector<ICorePoint>& points);

    void drawPath(const ICorePainterPath& path);
    void fillPath(const ICorePainterPath& path, const ICoreBrush& brush);
    void strokePath(const ICorePainterPath& path, const ICorePen& pen);

    // Text at a baseline point, or laid out in a rect under ICoreAlignment
    // flags (or-able, e.g. Left | VCenter).
    void drawText(const ICorePoint& baseline, const ICoreString& text);
    void drawText(const ICoreRect& rect, ICoreAlignment alignment, const ICoreString& text);

    // Same, but breaking the text across lines at word boundaries to fit the
    // rect's width. A separate method rather than a flag on drawText because
    // wrapping is the whole difference: the single-line form deliberately
    // clips, and a caller that wants one behaviour never wants the other by
    // accident.
    void drawWrappedText(const ICoreRect& rect, ICoreAlignment alignment, const ICoreString& text);

    void drawPixmap(const ICorePoint& topLeft, const ICorePixmap& pixmap);
    void drawPixmap(const ICoreRect& target, const ICorePixmap& pixmap);

    void translate(double dx, double dy);
    void rotate(double degrees);
    void scale(double sx, double sy);

    void setClipRect(const ICoreRect& rect);
    void setClipPath(const ICorePainterPath& path);
    void clearClip();

    // For wrapper-zone code composing with Qt APIs; unnameable by clients.
    QPainter& qt();

private:
    class Impl;                    // the two-line residue; state lives here
    std::unique_ptr<Impl> impl;
};

ICorePainterPath.h#

src/ICoreEssentials/UI/Painting/ICorePainterPath.h

ICorePainterPath#

ICorePainterPath.h:22 · class · 17 declaration(s)

An outline to fill, stroke or clip by.

class ICorePainterPath {
public:
    ICorePainterPath();

    ICorePainterPath(const ICorePainterPath& other);
    ICorePainterPath(ICorePainterPath&& other) noexcept;
    ICorePainterPath& operator=(const ICorePainterPath& other);
    ICorePainterPath& operator=(ICorePainterPath&& other) noexcept;
    ~ICorePainterPath();

    void moveTo(const ICorePoint& p);
    void lineTo(const ICorePoint& p);
    void cubicTo(const ICorePoint& c1, const ICorePoint& c2, const ICorePoint& end);

    void addRect(const ICoreRect& rect);
    void addRoundedRect(const ICoreRect& rect, double radiusX, double radiusY);
    void addEllipse(const ICoreRect& rect);
    void arcTo(const ICoreRect& rect, double startAngle, double sweepLength);

    void closeSubpath();

    // The union of this path and `other`, as a separate subpath -- which is
    // what keeps rounded corners intact where the two join. Returns an
    // ICorePainterPath rather than the toolkit's type on purpose: its one
    // caller writes `shape = shape.united(tail)`, and before the conversion
    // that assignment only compiled because a QPainterPath converted back
    // implicitly through a constructor this class no longer has.
    ICorePainterPath united(const ICorePainterPath& other) const;

    // This path widened into a fillable outline `width` units across, with
    // ROUND caps and joins. Added for P2.8's last blocked site:
    // ICoreLinkBranchSegment::contentShape() widens its one-pixel line so a
    // thin link stays clickable as the canvas zooms, and after this class
    // converted there was no way to express that -- no QPainterPath in, and
    // no stroking operation out.
    //
    // ⚠ Deliberately NOT strokedCopy(width, cap, join). Cap and join would
    // have to cross this boundary as enums, and the single caller in the tree
    // wants round for both. §9's rule -- the API is what the call sites use
    // and nothing else. Add the general form when a second caller needs a
    // second shape, not before.
    [[nodiscard]] ICorePainterPath strokedRound(double width) const;

    // The seam, per §1 -- void* rather than a forward-declared QPainterPath*,
    // which would put the toolkit name back in this header. Call icoreQt()
    // from a .cpp rather than reaching in here.
    const void* nativeStorage() const;

    // Public so the .cpp can pin them; §7 measured QPainterPath at 8 bytes
    // (plain d-pointer) against this tree's Qt 6.10.2 on macOS arm64.
    static constexpr std::size_t kNativeStorageSize = 8;
    static constexpr std::size_t kNativeStorageAlign = 8;

};

ICorePen.h#

src/ICoreEssentials/UI/Painting/ICorePen.h

ICorePen#

ICorePen.h:28 · class · 16 declaration(s)

class ICorePen {
public:
    // Qt's default pen: black, solid, width 0 (cosmetic hairline).
    ICorePen();

    ICorePen(const ICoreColor& color);
    ICorePen(const ICoreColor& color, double width);

    // Added by P7.4 when ICoreBrush converted; its one call site is
    // ICoreNotificationCenterMessageBox's rim.
    ICorePen(const ICoreBrush& brush, double width);

    ICorePen(const ICorePen& other);
    ICorePen(ICorePen&& other) noexcept;
    ICorePen& operator=(const ICorePen& other);
    ICorePen& operator=(ICorePen&& other) noexcept;
    ~ICorePen();

    void setStyle(ICorePenStyle style);
    void setCap(ICorePenCap cap);

    // Surfaced by the conversion, like setCosmetic below: the link/port paint
    // code re-colours and re-widths a pen it built once, and used to reach
    // QPen::setColor / setWidthF through the base. Width is a double and maps
    // to the toolkit's floating setWidthF -- the integer setWidth truncates.
    void setColor(const ICoreColor& color);
    void setWidth(double width);

    // Added by P5.3 because a call site needed it -- ICoreComboBoxArrows'
    // round join. All 9 join sites now resolve here; the Qt-base route they
    // used to take no longer exists.
    void setJoin(ICorePenJoin join);

    // A cosmetic pen keeps its width under view transforms -- the canvas
    // origin anchor's crosshair is the consumer. Surfaced by the conversion:
    // its 3 sites used to reach QPen::setCosmetic through the base.
    void setCosmetic(bool cosmetic);

    // The seam, per §1. Call icoreQt() from a .cpp rather than reaching in.
    const void* nativeStorage() const;

    // QPen is a plain d-pointer on this tree's Qt 6.10.2, macOS arm64 --
    // same measurement §7 recorded for QBrush.
    static constexpr std::size_t kNativeStorageSize = 8;
    static constexpr std::size_t kNativeStorageAlign = 8;

};

ICorePixmapPainter.h#

src/ICoreEssentials/UI/Painting/ICorePixmapPainter.h

ICorePixmapPainter#

ICorePixmapPainter.h:14 · class · pImpl · 6 declaration(s)

Draws onto a pixmap instead of onto a widget.

class ICorePixmapPainter {
public:
    explicit ICorePixmapPainter(ICorePixmap& target);
    ~ICorePixmapPainter();

    ICorePixmapPainter(const ICorePixmapPainter&) = delete;
    ICorePixmapPainter& operator=(const ICorePixmapPainter&) = delete;

    ICorePainter& painter();

    // Finish early. Idempotent; the destructor calls it too.
    void end();

private:
    class Impl;                    // the two-line residue; state lives here
    std::unique_ptr<Impl> impl;
};

ICoreSurfaceGradient.h#

src/ICoreEssentials/UI/Painting/ICoreSurfaceGradient.h

The app's large-surface treatment, in one place -- the gradient half of what ICoreNavItemStyle is for rows.

A surface dressed by this is lit at one end and deepens toward the other, along whichever axis the caller names -- so the left rail, the top bar and the floating time line read as the same material even where they do not run the same way. It is derived from the surface's own RESTING colour, so it follows the theme with no work at the call site and needs no second set of tokens -- on a dark ground the lift is the brand's bright royal and the fall is toward black; on a light one it is toward white and the fall is a royal tint.

⚠ THE RAMP IS SAMPLED, NOT A TWO-STOP LINE, and that is the whole reason this is shared code rather than three call sites each writing setStop twice. A

Declares no class of its own — see the file.