Loading...
Searching...
No Matches
RichTextEditor.h
Go to the documentation of this file.
1// Copyright (c) 2025 Dave R. Smith.
2// Malena Framework — Licensed under PolyForm Noncommercial 1.0.0; commercial use requires a paid license. See LICENSE.
3
4#ifndef MALENA_RICHTEXTEDITOR_H
5#define MALENA_RICHTEXTEDITOR_H
6
7#pragma once
8
12#include <Malena/Graphics/Text/TextInput.h> // type-in font size box
16#include <Malena/Graphics/Controls/ContextMenu.h> // hamburger pop-up when narrow
18#include <Malena/Graphics/Text/CodeEditor.h> // monospaceFont() for the Code heading
19#include <Malena/Resources/IconFont.h> // iconFont() + Icon glyph codepoints
20#include <cstddef>
21#include <functional>
22#include <string>
23
24namespace ml
25{
38 {
39 public:
41
42 // ── Content ───────────────────────────────────────────────────────────
43 void setValue(const std::string& text);
44 [[nodiscard]] std::string getValue() const;
45 void setRichText(const std::string& json);
46 [[nodiscard]] std::string getRichText() const;
47
48 void onChange(std::function<void(const std::string&)> cb);
49
56 void setAutoHideToolbar(bool enabled);
57
58 // ── Layout ────────────────────────────────────────────────────────────
59 void setPosition(const sf::Vector2f& pos) override;
60 void setSize(const sf::Vector2f& size);
61 // Hiding the editor closes its color/style pop-ups and collapses it, so a
62 // pop-up left open can't linger (e.g. when a parent swaps editors).
63 void setVisible(bool visible) override;
64
67
68 private:
69 void layout();
70 void updateActiveState(); // poll clicks to toggle _active (auto-hide)
71 bool _autoHideToolbar = false;
72 bool _active = false;
73 bool _prevMouseDown = false;
74 void rehighlightCode(); // re-color all code paragraphs
75 void highlightCodeRange(std::size_t a, std::size_t b,
76 const std::string& text); // one paragraph
77 bool _inCodeHl = false; // re-entrancy guard
78
79 Toolbar _bar{ iconFont() }; // B/I/U rendered as icon glyphs
80 ColorButton _colorBtn; // color swatch (shows last-chosen color)
81 TextArea _area;
82 ColorChooser _color;
83 TextInput _sizeInput; // type-in font size (mirrors caret)
84 Select _headingSelect;
85 ContextMenu _alignMenu; // align + list when collapsed (hamburger)
86
87 static constexpr unsigned int kMinFontSize = 6;
88 static constexpr unsigned int kMaxFontSize = 200; // sane cap (see notes)
89 static constexpr float kCompactBelow = 520.f; // collapse align/list below this width
90
91 std::size_t _iBold = 0, _iItalic = 0, _iUnderline = 0;
92 std::size_t _iAlignL = 0, _iAlignC = 0, _iAlignR = 0;
93 std::size_t _iListBullet = 0, _iListNum = 0;
94 std::size_t _iMenu = 0;
95 bool _b = false, _i = false, _u = false;
96 bool _compact = false; // align/list collapsed into the hamburger
97 bool _syncing = false; // mirroring caret → suppress control callbacks
98 int _curAlign = 0; // 0 left / 1 center / 2 right
99 int _curList = 0; // 0 none / 1 bullet / 2 numbered
100 std::string _curStyle = "Paragraph"; // last style shown in the dropdown
101
102 // Apply a paragraph-level change: expand to the cursor's paragraph, run
103 // the styling callback, then restore the caret where the user was typing.
104 void applyToParagraph(const std::function<void()>& fn);
105 void setParagraphAlign(int align);
106 void toggleList(int listType);
107
108 void buildBar(bool compact); // (re)populate the toolbar for the mode
109 void openAlignListMenu(); // show the hamburger pop-up
110
111 // Mirror every toolbar control to the style at the caret.
112 void syncControlsToCursor();
113
114 // Selection captured when a pop-up/dropdown opens, re-applied before each1
115 // change (overlays drop the live selection otherwise).
116 std::size_t _colorSelStart = 0, _colorSelEnd = 0;
117 std::size_t _hdSelStart = 0, _hdSelEnd = 0;
118
119 std::function<void(const std::string&)> _onChange;
120 };
121
122} // namespace ml
123
124#endif // MALENA_RICHTEXTEDITOR_H
A small clickable swatch filled with a color — e.g. a toolbar "text color" button that shows the last...
Definition ColorButton.h:25
Combined color chooser: a "Color" (HSV gradient + RGB/Hex entry + Save/Done) tab and a "Swatches" tab...
A reusable right-click / pop-up menu: a small list of labeled items shown at a point that runs an act...
Definition ContextMenu.h:35
void setRichText(const std::string &json)
void setVisible(bool visible) override
void setAutoHideToolbar(bool enabled)
When enabled, the formatting toolbar is hidden until the editor is "active" (the user clicks inside i...
void setSize(const sf::Vector2f &size)
std::string getValue() const
std::string getRichText() const
void setValue(const std::string &text)
void setPosition(const sf::Vector2f &pos) override
Move the panel and shift all children by the same delta.
void onChange(std::function< void(const std::string &)> cb)
A dropdown select control with rich per-item content.
Definition Select.h:86
A multi-line rich text input field with vertical scrolling.
Definition TextArea.h:36
Single-line rich text input with horizontal scrolling.
Definition TextInput.h:48
A horizontal or vertical strip of buttons, separators, and components.
Definition Toolbar.h:83
nlohmann::json json
Alias for nlohmann::json.
Definition Json.h:32
#define MALENA_API
Definition Component.h:22
MALENA_API const sf::Font & iconFont()
The bundled Material Icons font (Apache-2.0). Use with Icon codepoints to render crisp UI glyphs.
Vector2< float > Vector2f