API — ICoreEssentials/UI/Backends/Web/Text
The public contract of 3 header(s) under ICoreEssentials/UI/Backends/Web/Text — 7 class/struct definition(s), 73 declaration(s). Each section shows the header's banner and its public (and protected-virtual) surface exactly as the file writes it.
ICoreWebSyntaxHighlighter.h#
ICoreEssentials/UI/Backends/Web/Text/ICoreWebSyntaxHighlighter.h
ICoreWebSyntaxHighlighter#
ICoreWebSyntaxHighlighter.h:30 · class · pImpl · 18 declaration(s)
The web text tier's syntax-highlighting engine (web backend, WB5.2): the per-paragraph callback, the block-state machine that lets a construct span paragraphs, and the run formatting a highlighter ...
class ICoreWebSyntaxHighlighter {
public:
ICoreWebSyntaxHighlighter();
virtual ~ICoreWebSyntaxHighlighter();
ICoreWebSyntaxHighlighter(const ICoreWebSyntaxHighlighter&) = delete;
ICoreWebSyntaxHighlighter& operator=(const ICoreWebSyntaxHighlighter&) = delete;
// A document from icoreWebMakeTextDocument(); nullptr detaches, and
// detaching removes this engine's overlay from the document it leaves.
void setDocument(void* document);
[[nodiscard]] void* document() const;
// Reapply the highlighting to every paragraph.
void rehighlight();
// Reapply it to one paragraph, and to as many after it as the block state
// requires: a paragraph whose END STATE changed forces the next one to be
// re-read, which is what carries a block comment down the file.
void rehighlightBlock(int blockNumber);
// Paragraphs in the attached document; an empty document still has one.
[[nodiscard]] int blockCount() const;
// ⚠ SUBSCRIBED, NOT DRIVEN, like the GTK engine and unlike the WinUI one
// (TOM has no change notification). An edit re-highlights the paragraphs it
// touched and then cascades while their end states change -- Qt's
// QSyntaxHighlighter::_q_reformatBlocks shape. Painting writes only the
// overlay, which emits no change, so a pass cannot re-enter itself.
//
// The public seam one layer up publishes rehighlight() and nothing
// narrower, so without this an editor wanting live highlighting could only
// re-run the whole file per keystroke. Off for a batch pass or a test.
void setAutoRehighlight(bool on);
[[nodiscard]] bool autoRehighlight() const;
// =========================
// THE RUN SURFACE -- public, not protected: these are what a highlighter
// CALLS, and the header surface rule bans protected non-virtual helpers.
// =========================
// Paint a run of the paragraph being highlighted; `start` is relative to
// it. Clipped to the paragraph, never paints the separator, and REPLACES
// what this engine had there -- it does not merge. Outside a pass, a no-op.
void setFormat(int start, int count, const ICoreWebTextRunFormat& format);
// What this engine has painted at `position` of the current paragraph,
// including this pass's own runs.
//
// ⚠ PASS-SCOPED: outside a highlight pass it answers an empty format,
// because the Qt seat does -- QSyntaxHighlighter::format() reads the block
// being highlighted and there is none once the pass returns. The overlay
// could answer at any time; answering would let a caller write code that
// works here and silently reads defaults elsewhere.
[[nodiscard]] ICoreWebTextRunFormat formatAt(int position) const;
// The end state of the previous paragraph, or -1 for the first and for one
// whose predecessor never set a state.
[[nodiscard]] int previousBlockState() const;
// The current paragraph's state: -1 until set, and a state set in an
// earlier pass survives into this one.
[[nodiscard]] int currentBlockState() const;
void setCurrentBlockState(int state);
// The paragraph being highlighted, or -1 outside a pass.
[[nodiscard]] int currentBlockNumber() const;
protected:
// One paragraph WITHOUT its separator -- what QTextBlock::text() hands over.
virtual void highlightBlock(const std::u16string& text) = 0;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreWebTextDocument.h#
ICoreEssentials/UI/Backends/Web/Text/ICoreWebTextDocument.h
The web text tier's document model and its in-zone seam (web backend, WB5.1). The peer of ../../Gtk4/Text/ICoreGtk4TextDocument.h, and deliberately the same vocabulary.
⚠⚠ THIS BACKEND HAS NO TOOLKIT BUFFER, SO THE MODEL IS WRITTEN HERE. The three desktop seats each sit on a document their toolkit already owns -- a QTextDocument, an NSTextStorage, a GtkTextBuffer, a TOM document. A browser has none a canvas-painted editor can use: a DOM <textarea> is a VIEW with a string in it, and WB2.3 uses one only as the IME/keyboard seat. So the document is a plain C++ object, owned by whoever made it, and every other file in this directory is a view over it.
⚠ IT NAMES NO BROWSER API AND NEEDS NONE. Nothing in this directory includes <emscripten/...>, so the whole tier compiles and runs on a host compiler as
ICoreWebTextChange#
ICoreWebTextDocument.h:152 · struct · 0 declaration(s)
What one edit did, in BLOCKS.
struct ICoreWebTextChange {
public:
int position = 0;
int charsRemoved = 0;
int charsAdded = 0;
int firstBlock = 0;
int oldBlockCount = 1;
int newBlockCount = 1;
};
};
ICoreWebTextRunFormat#
ICoreWebTextDocument.h:180 · struct · 3 declaration(s)
One run's worth of formatting: the vocabulary ICoreTextCharFormat carries.
struct ICoreWebTextRunFormat {
public:
bool hasForeground = false;
int foregroundRed = 0;
int foregroundGreen = 0;
int foregroundBlue = 0;
int foregroundAlpha = 255;
bool bold = false;
bool italic = false;
bool underline = false;
bool hasUnderlineColor = false;
int underlineRed = 0;
int underlineGreen = 0;
int underlineBlue = 0;
int underlineAlpha = 255;
// Asks for nothing. Painting one CLEARS the run.
[[nodiscard]] bool isEmpty() const;
[[nodiscard]] bool operator==(const ICoreWebTextRunFormat& other) const;
[[nodiscard]] bool operator!=(const ICoreWebTextRunFormat& other) const;
};
};
ICoreWebTextRun#
ICoreWebTextDocument.h:204 · struct · 0 declaration(s)
A painted span of one block: start, start + length), block-relative.
struct ICoreWebTextRun {
public:
int start = 0;
int length = 0;
ICoreWebTextRunFormat format;
};
};
ICoreWebTextView.h#
[ICoreEssentials/UI/Backends/Web/Text/ICoreWebTextView.h
The web backend's text VIEW (WB5.3): what GtkTextView, NSTextView and the WinUI painted engine are to their seats -- layout, wrapping, hit-testing, caret and selection, keyboard editing, undo and scrolling -- over the WB5.1 document model (ICoreWebTextDocument.h).
⚠⚠ WHY IT IS PAINTED AND NOT A <textarea>. The script editor paints syntax runs (the WB5.2 overlay), a gutter, folds, decorations and a completion popup over its text; a <textarea> can show none of that -- one colour, one font, no per-run anything. So the view is painted on the canvas from the model, and a hidden DOM element is only ever the keyboard/IME sink (the CodeMirror 6 / Monaco shape). This class is the painted half; it does not paint either -- the seats walk visibleLines() with the Canvas2D painter.
⚠ IT NAMES NO BROWSER, NO NODE AND NO PAINTER. Text is measured through a
ICoreWebTextLine#
ICoreWebTextView.h:36 · struct · 1 declaration(s)
One visual line: a block's run of text as laid out on one row.
struct ICoreWebTextLine {
public:
int block = 0; // document block number
int start = 0; // block-relative unit where the line starts
int length = 0; // units on this line, without the separator
double top = 0.0; // content-space y of the row's top
double height = 0.0; // the row's height (line spacing x the block's line height)
double baseline = 0.0; // content-space y of the text baseline
std::vector<double> xs; // x of each unit boundary on the line, size length + 1
};
};
ICoreWebTextKeyOutcome#
ICoreWebTextView.h:48 · struct · 1 declaration(s)
What a key did, for the seat to finish: the clipboard is the seat's, so the engine asks rather than touching it.
struct ICoreWebTextKeyOutcome {
public:
bool consumed = false;
bool writeClipboard = false; // copy/cut: put clipboardText on the clipboard
bool readClipboard = false; // paste: the seat calls insertText(clipboard)
std::u16string clipboardText;
};
};
ICoreWebTextView#
ICoreWebTextView.h:55 · class · pImpl · 50 declaration(s)
class ICoreWebTextView {
public:
using Measure = std::function<double(const std::u16string& text)>;
ICoreWebTextView();
~ICoreWebTextView();
ICoreWebTextView(const ICoreWebTextView&) = delete;
ICoreWebTextView& operator=(const ICoreWebTextView&) = delete;
// ---- the model -------------------------------------------------------------
// The view makes and OWNS its document (one reference), as a GtkTextView
// owns its buffer; documentHandle() hands out borrowed views of it.
[[nodiscard]] void* document() const;
void setPlainText(const std::u16string& text); // resets undo, caret to 0
[[nodiscard]] std::u16string plainText() const;
// ---- metrics and geometry ---------------------------------------------------
// `measure` answers the advance of a run with no tabs in it. `ascent` and
// `lineSpacing` are the font's. Changing any of them relays out everything.
void setMetrics(Measure measure, double ascent, double lineSpacing);
void setTabStopDistance(double pixels); // 0 = 8 spaces' worth
void setWrap(bool wrapAtViewportWidth);
void setDocumentMargin(double margin); // around the text, all four sides
void setViewportSize(double width, double height);
[[nodiscard]] double viewportWidth() const;
[[nodiscard]] double viewportHeight() const;
// ⚠ Block visibility (folding) and a block's line height are document
// properties that change WITHOUT a change notice -- they are not text. The
// seat that changes one calls this, or the view keeps the old layout.
void invalidateLayout();
[[nodiscard]] double contentHeight() const; // including both margins
[[nodiscard]] double contentWidth() const; // the widest line, with margins
// The caret rectangle at a position (content space): the unit's left edge,
// one line tall, zero wide. A position at a wrap point belongs to the line
// it STARTS, as on every desktop toolkit.
[[nodiscard]] ICoreRect rectForPosition(int position) const;
// The position nearest a content-space point (above the text is 0, below
// is the end, past a line's end is the line's end).
[[nodiscard]] int positionAt(double x, double y) const;
// A block's rows, content space; empty for a hidden or invalid block.
[[nodiscard]] ICoreRect blockBounds(int block) const;
// The visual lines that intersect the viewport, in order -- what a seat
// paints. Content space: subtract the scroll offsets to paint.
[[nodiscard]] std::vector<ICoreWebTextLine> visibleLines() const;
// ---- scrolling --------------------------------------------------------------
[[nodiscard]] double scrollY() const;
[[nodiscard]] double scrollX() const;
void setScrollY(double y); // clamped to the content
void setScrollX(double x);
enum class ScrollHint { Visible, Top, Center };
void scrollToBlock(int block, ScrollHint hint);
void ensureCaretVisible();
// ---- caret and selection ----------------------------------------------------
[[nodiscard]] int position() const;
[[nodiscard]] int anchor() const;
[[nodiscard]] bool hasSelection() const;
[[nodiscard]] int selectionStart() const;
[[nodiscard]] int selectionEnd() const;
[[nodiscard]] std::u16string selectedText() const;
// Clamped. `reveal` scrolls the caret into view; the widget seats pass
// false, because ICoreRichTextEdit::setTextCursor/setSelection do not
// scroll on GTK4 or AppKit -- ensureCursorVisible() is its own call, and
// the Script IDE's goToLine() centres a line only if it is off screen
// AFTER placing the caret (scriptide/go_to_line_centres_a_line_off_screen).
void setSelection(int anchor, int position, bool reveal = true);
void setCaret(int position);
// ---- editing ----------------------------------------------------------------
void setReadOnly(bool readOnly);
[[nodiscard]] bool isReadOnly() const;
// Replace the selection with `text` (typing, paste, IME commit). One undo
// step, except that consecutive single typed characters with no caret move
// in between coalesce into one, as every desktop editor does.
void insertText(const std::u16string& text);
// An editing/navigation key. `typed` is the character(s) a printable key
// produced (empty for a non-printing key). Chords are Control on Windows
// and Linux, Meta (Cmd) on macOS -- both are accepted, as the portable text
// item core does, because a page cannot trust what platform it is on.
ICoreWebTextKeyOutcome key(int icoreKey, unsigned int modifiers, const std::u16string& typed);
void undo();
void redo();
[[nodiscard]] bool isUndoAvailable() const;
[[nodiscard]] bool isRedoAvailable() const;
// Keep only the last `blocks` blocks (0 = unlimited), trimming from the top
// after an append -- a console's scrollback.
void setMaximumBlockCount(int blocks);
// Append at the end of the document without moving the caret or recording
// undo (output, not typing); returns the position the text started at.
int append(const std::u16string& text);
// ---- pointer -----------------------------------------------------------------
// Viewport-space coordinates. clickCount 2 selects a word, 3 a block.
void pointerPressed(double x, double y, int clickCount, bool extend);
void pointerDragged(double x, double y);
void pointerReleased();
// Wheel: pixels to scroll (positive = down/right). Returns whether it moved.
bool scrolled(double dx, double dy);
// ---- notifications (all on the main thread, after the state changed) --------
void setContentsChangedHook(std::function<void()> hook);
void setBlockCountChangedHook(std::function<void(int)> hook);
void setCursorChangedHook(std::function<void()> hook);
void setScrollChangedHook(std::function<void()> hook);
void setUndoAvailableHook(std::function<void(bool)> hook);
void setRedoAvailableHook(std::function<void(bool)> hook);
// Anything the seat must repaint for: text, caret, selection, scroll, layout.
void setRepaintHook(std::function<void()> hook);
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};