Loading...
Searching...
No Matches
TextInput.h
Go to the documentation of this file.
1//
2// TextInput.h
3//
4
5#ifndef MALENA_TEXTINPUT_H
6#define MALENA_TEXTINPUT_H
7
8#pragma once
9
21#include <SFML/Graphics.hpp>
22#include <functional>
23#include <string>
24#include <type_traits>
25
26namespace ml
27{
29 {
30 public:
31 enum class Flag { READONLY };
32 enum class State { IDLE, FOCUSED, ERROR }; // disabled derived from ml::Flag::ENABLED
33 };
34
44 class MALENA_API TextInput : public ComponentWith<TextInputManifest>,
45 public TextInputSettings,
46 public TextInputTheme,
47 public Themeable
48 {
49 public:
52
53 protected:
57
59 sf::Vector2f _position = {0.f, 0.f};
60 float _scrollX = 0.f;
61
64 bool _showPlaceholder = true;
66 const sf::Font* _monoFont = nullptr; // alternate font for rich-text round-trip
67
69 mutable bool _cursorVisible = false;
70
71 bool _dragging = false;
72 bool _prevMouseDown = false;
73 std::size_t _dragAnchor = 0;
76 bool _waitingDouble = false;
77
78 std::function<void(const std::string&)> _onChange;
79 std::function<void(const std::string&)> _onSubmit;
80
81 void rebuild();
82 virtual void onRebuildComplete() {}
83 virtual void reflow();
84 virtual void rebuildAndScroll();
85 void syncColors();
86 virtual void syncPlaceholder();
87 virtual std::size_t hitTest(const sf::Vector2f& worldPos) const;
88
89 virtual void handleKey(const sf::Event::KeyPressed& kp);
91
92 void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
93 void onEnabledChanged(bool enabled) override; // refresh colors
94 void onThemeApplied(const Theme& theme) override;
95
96 public:
98
99 // ── Apply ─────────────────────────────────────────────────────────────
100
101 template<typename S>
102 void applySettings(const S& s)
103 {
104 static_assert(std::is_base_of_v<TextInputSettings, S>,
105 "applySettings() requires a type derived from TextInputSettings");
106 static_cast<TextInputSettings&>(*this) = s;
107 syncColors();
109 rebuild();
110 }
111
112 template<typename T>
113 void applyTheme(const T& t)
114 {
115 static_assert(std::is_base_of_v<TextInputTheme, T>,
116 "applyTheme() requires a type derived from TextInputTheme");
117 static_cast<TextInputTheme&>(*this) = t;
118 syncColors();
119 }
120
121 template<typename St>
122 void applyStyle(const St& s)
123 {
124 static_assert(std::is_base_of_v<TextInputSettings, St> &&
125 std::is_base_of_v<TextInputTheme, St>,
126 "applyStyle() requires TextInputSettings and TextInputTheme");
127 static_cast<TextInputSettings&>(*this) = s;
128 static_cast<TextInputTheme&>(*this) = s;
129 syncColors();
131 rebuild();
132 }
133
134 // ── Value ─────────────────────────────────────────────────────────────
135
136 void setValue(const std::string& value);
137 [[nodiscard]] std::string getValue() const;
138 void clear();
139
140 // ── Rich content (JSON spans) ─────────────────────────────────────────
141 // Serialize/restore the text AND its styling as a portable JSON string:
142 // {"text":"...","spans":[{"start":,"end":,"bold":,"italic":,
143 // "underline":,"size":,"color":{"r","g","b","a"}}]}
144 // Lossless round-trip of the rich-text buffer; ideal for storage/transport.
145 [[nodiscard]] std::string getRichText() const;
146 void setRichText(const std::string& json);
147
148 // ── Selection styling ─────────────────────────────────────────────────
149
151 void setSelectionCharSize(unsigned int size);
152 void setSelectionColor(const sf::Color& color);
153 void setSelectionBold(bool bold);
154 void setSelectionItalic(bool italic);
155 void setSelectionUnderline(bool underline);
156 void setSelectionAlign(int align); // 0 left, 1 center, 2 right (paragraph)
157 void setSelectionListType(int listType); // 0 none, 1 bullet, 2 numbered (paragraph)
158 void changeSelectionIndent(int delta); // +1 indent / -1 outdent (paragraph)
159
160 void selectAll();
161 void setSelection(std::size_t start, std::size_t end);
162 [[nodiscard]] std::string getSelectedText() const;
163 [[nodiscard]] std::size_t getSelectionStart() const;
164 [[nodiscard]] std::size_t getSelectionEnd() const;
165 [[nodiscard]] std::size_t getCursor() const;
166
174
176 [[nodiscard]] const sf::Font* getFontAt(std::size_t index) const;
178 [[nodiscard]] sf::Color getColorAt(std::size_t index) const;
180 [[nodiscard]] unsigned int getCharSizeAt(std::size_t index) const;
181
188 [[nodiscard]] TextAttribute getActiveStyle() const;
189
191 [[nodiscard]] bool isFocused() const { return checkFlag(ml::Flag::FOCUSED); }
193 [[nodiscard]] sf::Color getTextColor() const;
194
195 // ── Options ───────────────────────────────────────────────────────────
196
197 void setPlaceholder(const std::string& text);
198 [[nodiscard]] std::string getPlaceholder() const;
199
200 void setReadOnly(bool readonly);
201 [[nodiscard]] bool isReadOnly() const;
202
206 void setClearSelectionOnBlur(bool enabled);
207
208 void setError(bool error);
209 [[nodiscard]] bool hasError() const;
210
211 // ── Size / font ───────────────────────────────────────────────────────
212
213 virtual void setSize(const sf::Vector2f& size);
214 [[nodiscard]] sf::Vector2f getSize() const;
215
216 virtual void setFont(const sf::Font& font);
217 void setFont(const sf::Font&&) = delete;
218 virtual void setCharacterSize(unsigned int size);
219 [[nodiscard]] unsigned int getCharacterSize() const;
220
221 // ── Callbacks ─────────────────────────────────────────────────────────
222
223 void onChange(std::function<void(const std::string&)> callback);
224 void onSubmit(std::function<void(const std::string&)> callback);
225
226 // ── Positionable ──────────────────────────────────────────────────────
227
228 virtual void setPosition(const sf::Vector2f& position) override;
229 sf::Vector2f getPosition() const override;
231 };
232
233 template<typename MANIFEST>
234 class TextInputWith : public TextInput, public Customizable<MANIFEST>
235 { public: using TextInput::TextInput; };
236
237} // namespace ml
238
239#endif // MALENA_TEXTINPUT_H
static const sf::Font & getDefault()
Return the built-in Arial font.
Base class for all Malena manifests.
Definition Manifest.h:51
Pure data layer for rich text editing.
Rendering layer for RichTextBuffer.
void setSelectionFont(const sf::Font &font)
const sf::Font * _monoFont
Definition TextInput.h:66
unsigned int getCharSizeAt(std::size_t index) const
std::size_t _dragAnchor
Definition TextInput.h:73
std::string getValue() const
void applyStyle(const St &s)
Definition TextInput.h:122
void changeSelectionIndent(int delta)
std::size_t getSelectionEnd() const
virtual void onRebuildComplete()
Definition TextInput.h:82
bool isReadOnly() const
void setError(bool error)
void setSelection(std::size_t start, std::size_t end)
virtual void reflow()
void setSelectionBold(bool bold)
void selectAll()
RichTextBuffer _buffer
Definition TextInput.h:54
std::size_t getCursor() const
void handleChar(const sf::Event::TextEntered &te)
bool _waitingDouble
Definition TextInput.h:76
std::function< void(const std::string &)> _onSubmit
Definition TextInput.h:79
void setSelectionAlign(int align)
TextAttribute getActiveStyle() const
The style that applies to text typed/selected at the caret right now — selection start if a selection...
bool _showPlaceholder
Definition TextInput.h:64
void setReadOnly(bool readonly)
void setSelectionItalic(bool italic)
bool _prevMouseDown
Definition TextInput.h:72
sf::Vector2f getSize() const
void onSubmit(std::function< void(const std::string &)> callback)
void setValue(const std::string &value)
void applyTheme(const T &t)
Definition TextInput.h:113
sf::Vector2f _position
Definition TextInput.h:59
bool hasError() const
virtual void rebuildAndScroll()
RichTextRenderer _renderer
Definition TextInput.h:55
void onChange(std::function< void(const std::string &)> callback)
void setSelectionColor(const sf::Color &color)
virtual void setFont(const sf::Font &font)
std::string getPlaceholder() const
void syncColors()
std::function< void(const std::string &)> _onChange
Definition TextInput.h:78
virtual void handleKey(const sf::Event::KeyPressed &kp)
bool _cursorVisible
Definition TextInput.h:69
std::size_t getSelectionStart() const
sf::Vector2f getPosition() const override
virtual void setSize(const sf::Vector2f &size)
void setMonospaceFont(const sf::Font *font)
Register an alternate "monospace" font so it survives rich-text round-trips. Spans using this exact f...
Definition TextInput.h:173
void setFont(const sf::Font &&)=delete
sf::RectangleShape _background
Definition TextInput.h:58
TextInputManifest::State State
Definition TextInput.h:51
void onEnabledChanged(bool enabled) override
void setPlaceholder(const std::string &text)
void onThemeApplied(const Theme &theme) override
Called by ThemeManager when the active theme changes.
TextInputManifest::Flag Flag
Definition TextInput.h:50
sf::RenderTexture _canvas
Definition TextInput.h:56
virtual void setPosition(const sf::Vector2f &position) override
sf::Vector2f _lastClick
Definition TextInput.h:75
sf::Clock _cursorClock
Definition TextInput.h:68
TextInput(const sf::Font &font=FontManager<>::getDefault())
sf::Text _maskDisplay
Definition TextInput.h:63
sf::Color getColorAt(std::size_t index) const
virtual void syncPlaceholder()
float _scrollX
Definition TextInput.h:60
sf::Text _placeholder
Definition TextInput.h:62
void setRichText(const std::string &json)
void setClearSelectionOnBlur(bool enabled)
std::string getSelectedText() const
void draw(sf::RenderTarget &target, sf::RenderStates states) const override
const sf::Font * getFontAt(std::size_t index) const
unsigned int getCharacterSize() const
void setSelectionCharSize(unsigned int size)
sf::Color getTextColor() const
void applySettings(const S &s)
Definition TextInput.h:102
virtual void setCharacterSize(unsigned int size)
void setSelectionListType(int listType)
sf::FloatRect getGlobalBounds() const override
sf::Clock _clickClock
Definition TextInput.h:74
std::string getRichText() const
bool _clearSelectionOnBlur
Definition TextInput.h:65
virtual std::size_t hitTest(const sf::Vector2f &worldPos) const
bool isFocused() const
Definition TextInput.h:191
void setSelectionUnderline(bool underline)
Shared manifest for TextInput and TextArea.
Definition TextInput.h:29
TextInput(const sf::Font &font=FontManager<>::getDefault())
Component< M, Traits... > ComponentWith
Alias for Component<M, Traits...>.
Definition Component.h:316
nlohmann::json json
Alias for nlohmann::json.
Definition Json.h:32
@ FOCUSED
Component has keyboard focus (set by ClickableDispatcher).
Definition Flag.h:70
#define MALENA_API
Definition Component.h:22
Rect< float > FloatRect
Vector2< float > Vector2f
const sf::Font * font
sf::Vector2f size
A styled attribute range applied to a span of characters.
Layout and behaviour settings for TextInput and TextArea.
Color tokens for TextInput and TextArea.
Universal design token set applied across all Themeable components.
Definition Theme.h:70