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

API — ICoreEssentials/UI/Backends/Gtk4/Painting

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

ICoreGtk4PaintAccess.h#

ICoreEssentials/UI/Backends/Gtk4/Painting/ICoreGtk4PaintAccess.h

Backend-internal access to what an ICorePen, ICoreBrush or ICoreGradient actually says.

⚠ THIS HEADER IS WHY THE PAINTER CAN BE WRITTEN AT ALL. ICorePen and ICoreBrush have almost no getters -- their public surface is constructors, setters and nativeStorage() -- and on the Qt backend the state crosses the seam AS THE NATIVE OBJECT (icoreQt(pen) reinterprets the buffer as a QPen&). So a gtk4 ICorePainter::Impl handed an ICorePen could not ask it anything, and the only way in, nativeStorage(), holds a QPen -- naming which inside Backends/Gtk4/ is exactly what census row R2.4 exists to stop.

This backend therefore takes its own side of the seam, as the value tier did for ICoreFont: the buffer holds a pointer to a record THIS backend wrote, and this header is how the painter reads it back. The WinUI board reached the

ICoreGtk4PaintStop#

ICoreGtk4PaintAccess.h:36 · struct · 0 declaration(s)

One stop of a gradient.

struct ICoreGtk4PaintStop {
public:
    double position = 0.0;              // 0..1
    ICoreColor color;
};
};

ICoreGtk4BrushSpec#

ICoreGtk4PaintAccess.h:56 · struct · 0 declaration(s)

struct ICoreGtk4BrushSpec {
public:
    ICoreGtk4BrushKind kind = ICoreGtk4BrushKind::None;

    ICoreColor color;                   // Solid

    // LinearGradient: the two ends, in the CURRENT TRANSFORM SPACE at the
    // moment of the draw -- which is what QLinearGradient means and what
    // cairo_pattern_create_linear takes.
    double x1 = 0.0, y1 = 0.0, x2 = 0.0, y2 = 0.0;

    // RadialGradient: centre and radius. ⚠ ONE radius. `ICoreRadialGradient`
    // only ever states one, and cairo's radial pattern takes two CIRCLES (a
    // focus and an outer), so the seating passes a degenerate focus at the
    // centre rather than inventing an ellipse nothing asked for.
    double centerX = 0.0, centerY = 0.0, radius = 0.0;

    // ⚠ SORTED BY POSITION. `QGradient::stops()` answers sorted, and cairo
    // requires non-decreasing offsets; the order they were SET in is preserved
    // by neither.
    std::vector<ICoreGtk4PaintStop> stops;
};
};

ICoreGtk4PenSpec#

ICoreGtk4PaintAccess.h:85 · struct · 0 declaration(s)

⚠ A PEN CARRIES A BRUSH, NOT A COLOUR, and that is not over-modelling: ICorePen(const ICoreBrush&, double) exists and its one call site in this tree -- a notification panel's rim -- passes a grad...

struct ICoreGtk4PenSpec {
public:
    ICoreGtk4BrushSpec brush;
    double width = 0.0;
    ICorePenStyle style = ICorePenStyle::Solid;
    ICorePenCap cap = ICorePenCap::Square;
    ICorePenJoin join = ICorePenJoin::Bevel;
    bool cosmetic = false;
};
};

File-scope declarations#

// Which kind of cairo source this brush wants.
// 
// ⚠ `None` IS NOT `Solid` WITH ALPHA 0, and the difference is load-bearing:
// `ICoreBrush()` means "do not fill at all" -- fifteen call sites spell a bare
// `ICoreBrush()` to turn filling off before stroking an outline (ICoreBrush.h)
// -- so it means "skip the fill", not "fill with something invisible". A
enum class ICoreGtk4BrushKind {
    None = 0,
    Solid = 1,
    LinearGradient = 2,
    RadialGradient = 3,
};

ICoreGtk4PathAccess.h#

ICoreEssentials/UI/Backends/Gtk4/Painting/ICoreGtk4PathAccess.h

ICoreGtk4PathNode#

ICoreGtk4PathAccess.h:49 · struct · 0 declaration(s)

struct ICoreGtk4PathNode {
public:
    ICoreGtk4PathOp op = ICoreGtk4PathOp::Built;

    // op == Built
    std::vector<ICorePathBuilderElement> elements;

    // ⚠ THE FILL RULE TRAVELS WITH THE NODE, not with the path handle: a union
    // of two paths has a rule of its own, and the painter needs it at the node
    // it is filling rather than at the handle it was reached through.
    int fillRule = 1;   // matches ICoreFillRule: 0 NonZero, 1 EvenOdd

    // op == Union
    ICoreGtk4PathRef operandA;
    ICoreGtk4PathRef operandB;

    // op == StrokedRound (operandA is the path being stroked)
    double strokeWidth = 0.0;
};
};

File-scope declarations#

// Backend-internal access to what an ICorePainterPath actually contains.
// 
// The peer of `ICoreGtk4PaintAccess.h` next door.
// ⚠ NOTHING ABOVE THE BACKEND ZONE MAY INCLUDE THIS.
// 
// ⚠ A PATH IS A TREE HERE, NOT A CURVE LIST, and that is this file's one real
enum class ICoreGtk4PathOp {
    Built = 0,          // the element list is the whole answer
    Union = 1,          // operandA ∪ operandB
    StrokedRound = 2,   // the outline of operandA stroked `strokeWidth` across
};

using ICoreGtk4PathRef = std::shared_ptr<const ICoreGtk4PathNode>;

ICoreGtk4RichText.h#

ICoreEssentials/UI/Backends/Gtk4/Painting/ICoreGtk4RichText.h

Declares no class of its own — see the file.

ICoreGtk4TextSelection.h#

ICoreEssentials/UI/Backends/Gtk4/Painting/ICoreGtk4TextSelection.h

ICoreGtk4TextSelection#

ICoreGtk4TextSelection.h:70 · class · pImpl · 22 declaration(s)

Selecting, copying and right-clicking text that THIS TREE PAINTED.

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

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

    // ⚠ SET ONCE, BEFORE ANYTHING ELSE IS ASKED. Without it every member below
    // answers as though the surface were empty -- which is the correct answer
    // for a surface whose seat has not wired this up, and a silent one, so wire
    // it in the constructor beside installMenu().
    //
    // The provider must return a NEW layout (this class unrefs it) laid out
    // exactly as the surface's own text is -- same reader, same font, same
    // width, same alignment. Null means "nothing to select".
    void setLayoutProvider(std::function<PangoLayout*()> provider);

    // Where the surface shows that layout, in its own coordinates. Kept here so
    // that a scrolled document reports the byte the reader is pointing at without
    // every call site passing the same two numbers.
    void setOrigin(double x, double y);

    // Off means every member below is inert and the surface behaves exactly as
    // it did before this class existed. Turning it off drops any selection --
    // a highlight nobody can clear is worse than no highlight.
    void setEnabled(bool enabled);
    [[nodiscard]] bool isEnabled() const;

    // ⚠ CALLED FROM THE SEAT'S PAINT, BEFORE THE TEXT GOES DOWN. It returns the
    // rectangles to fill BEHIND the glyphs, in the widget's own coordinates, at
    // the origin setOrigin() last named.
    //
    // ⚠ ONE RECTANGLE PER LINE, NOT ONE PER RUN. A multi-line selection is a
    // band per line -- full width in the middle, partial at the two ends -- and
    // that is what Pango's own per-line x-ranges answer.
    [[nodiscard]] std::vector<ICoreRect> bands();

    // Whether anything is selected at all. Cheap; no layout needed.
    [[nodiscard]] bool hasSelection() const;

    // -- the pointer ---------------------------------------------------------
    //
    // Coordinates are the surface's own; the origin setOrigin() named is
    // subtracted here. Each returns true when the surface should repaint.

    // ⚠ THE PRESS ANCHORS AND DOES NOT SELECT. A single click in a document
    // clears the selection and puts the anchor down; the drag is what selects,
    // which is every text surface's behaviour and the reason a stray click does
    // not wipe out what the reader was about to copy by widening it.
    bool press(double x, double y);
    bool drag(double x, double y);
    void release();
    [[nodiscard]] bool isDragging() const;

    // Whole-word on a double click, the whole line on a triple -- the two
    // gestures every text surface answers and neither of which a drag can
    // express. `pressCount` is GtkGestureClick's n_press.
    bool multiClick(double x, double y, int pressCount);

    // -- the two commands ----------------------------------------------------

    void selectAll();
    void clearSelection();

    [[nodiscard]] std::string selectedText() const;

    // Puts selectedText() on the CLIPBOARD (not the primary selection), which
    // is what Ctrl+C and a Copy menu item both mean. A no-op with nothing
    // selected -- a copy that cleared the clipboard would lose whatever the
    // reader had put there.
    void copyToClipboard(GtkWidget* host) const;

    // ⚠ THE TWO SHORTCUTS, AND THEY ARE HANDLED HERE RATHER THAN BY A
    // GtkShortcutController. A painted surface has no toolkit control to carry
    // class bindings, so its seat's own key hook is the only route; answering
    // them here keeps the pair identical on every surface that uses this class.
    //
    // Returns true when the key was consumed. `state` is a GdkModifierType.
    bool keyPressed(GtkWidget* host, unsigned int keyval, unsigned int state);

    // -- the menu ------------------------------------------------------------

    // ⚠⚠ A REAL GtkPopoverMenu OVER A GMenu, WHICH IS WHAT "THE NATIVE CONTEXT
    // MENU" MEANS ON THIS TOOLKIT. GTK4 has no `gtk_menu_popup` and no
    // window-manager menu to borrow: a popover menu built from a GMenuModel IS
    // the platform's menu, and it is what GtkText and GtkLabel raise for their
    // own text. So a painted surface using this class gets the same widget, the
    // same theming and the same keyboard navigation as the hosted controls next
    // door -- rather than something this tree drew to look like one.
    //
    // Idempotent: the popover and its action group are built on the first call
    // and parented to `host`, so they die with it.
    void installMenu(GtkWidget* host);

    // Raise the menu at a point in `host`'s coordinates. A no-op if
    // installMenu() has not been called or selection is off. The Copy item is
    // insensitive with nothing selected, which is how a menu says "there is
    // nothing to copy" without leaving the reader to find out by pressing it.
    void popupAt(GtkWidget* host, double x, double y);

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