SDOM - Simple SDL Document Object Model
A lightweight, extensible Document Object Model for SDL-based applications.
Loading...
Searching...
No Matches
SDOM_Label.hpp
Go to the documentation of this file.
1// SDOM_Label.hpp
2#pragma once
3
6
7/*
8
9Set the dirty flag when:
10- the Label bounds change (width, height, position).
11- the text changes.
12- the FontStyle changes.
13- the parent’s bounds change (if the Label is anchored or its layout depends on the parent).
14- the font resource changes (switching fonts or font size).
15- wordwrap or auto_resize flags change.
16- padding or margin changes.
17- visibility toggles (hidden/shown).
18- DPI or scaling factor changes (if supported).
19- the Label is moved between stages or layers (if rendering context changes).
20
21When to rebuild the cachedTexture_:
22- the Cores::getPixelFormat() changes (e.g. due to display mode change).
23- the Labels bounds change (width, height).
24
25When the dirty flag is set:
261) recreate the Labels texture (if needed)
272) render to the cachedTexture_
283) clear the dirty flag
29
30When the dirty flag is not set:
311) simply render the texture
32
33*/
34
35namespace SDOM
36{
37 class Label : public IDisplayObject
38 {
39 using SUPER = IDisplayObject;
40
41 public:
42 // --- Type Info --- //
43 static constexpr const char* TypeName = "Label";
44
45 // --- Initialization Struct --- //
47 {
49 {
50 // --- Default InitStruct values from IDisplayObject: --- //
51 name = TypeName;
52 type = TypeName;
53 x = 0.0f;
54 y = 0.0f;
55 width = 100.0f; // default width
56 height = 30.0f; // default height
57 color = {255, 0, 255, 255}; // magenta text
62 z_order = 0;
63 priority = 0;
64 isClickable = false; // Labels are not clickable by default
65 isEnabled = true;
66 isHidden = false;
67 tabPriority = 0;
68 tabEnabled = false; // Labels are not tabbable by default
69 }
70 // --- Label-specific properties --- //
71 std::string text = "Label";
72 std::string resourceName = "internal_font_8x8"; // default font
74 int fontSize = 8; // for TrueType fonts, or BitmapFont scaling
75 int fontWidth = 8; // for BitmapFont only (-1 to use fontSize)
76 int fontHeight = 8; // for BitmapFont only (-1 to use fontSize)
77 LabelAlign alignment = LabelAlign::TOP_LEFT; // Text alignment (default: top-left)
78
79 // SDL_Color foregroundColor = {255, 255, 255, 255}; // white
80 // SDL_Color backgroundColor = {255, 255, 255, 128}; // transparent
81 // SDL_Color borderColor = {0, 0, 0, 128}; // transparent
82 // SDL_Color outlineColor = {0, 0, 0, 255}; // black
83 // SDL_Color dropshadowColor = {0, 0, 0, 128}; // semi-transparent black
84
85 bool bold = false; // enable bold text
86 bool italic = false; // enable italic text
87 bool underline = false; // enable underline text
88 bool strikethrough = false; // enable strikethrough text
89 bool border = false; // enable border
90 bool background = false; // enable background
91 bool outline = false; // enable outline
92 bool dropshadow = false; // enable drop shadow
93 bool wordwrap = false; // enable word wrap
94 bool auto_resize = true; // enable auto resizing to fit text
95 int maxWidth = 0; // maximum allowable width for auto resizing (0 disables auto width)
96 int maxHeight = 0; // maximum allowable height for auto resizing (0 disables auto height)
97 int borderThickness = 1; // Border thickness (default: 0)
98 int outlineThickness = 1; // Outline thickness (default: 0)
99 int padding_horiz = 0; // Horizontal padding (left/right)
100 int padding_vert = 0; // Vertical padding (top/bottom)
101 int dropshadowOffsetX = 1; // Drop shadow offset (horizontal)
102 int dropshadowOffsetY = 1; // Drop shadow offset (vertical)
103 };
104
105 // -- NOTE: Be sure to utilize the utility functions in SDOM_Utils.hpp for color parsing/handling -- //
106 // std::string normalizeAnchorString(const std::string& s); // helper function to normalize anchor point strings
107 // bool validateAnchorPointString(const std::string& anchorString); // helper function to validate anchor point strings
108 // bool validateAnchorAssignments(const sol::table& config); // helper function to validate anchor point assignments in a config table
109
110 inline static const std::unordered_map<LabelAlign, std::string> labelAlignToString_ = {
111 { LabelAlign::DEFAULT, "default" },
112 { LabelAlign::LEFT, "left" },
113 { LabelAlign::CENTER, "center" },
114 { LabelAlign::RIGHT, "right" },
115 { LabelAlign::TOP, "top" },
116 { LabelAlign::TOP_LEFT, "top_left" },
117 { LabelAlign::TOP_CENTER, "top_center" },
118 { LabelAlign::TOP_RIGHT, "top_right" },
119 { LabelAlign::MIDDLE, "middle" },
120 { LabelAlign::MIDDLE_LEFT, "middle_left" },
121 { LabelAlign::MIDDLE_CENTER,"middle_center" },
122 { LabelAlign::MIDDLE_RIGHT, "middle_right" },
123 { LabelAlign::BOTTOM, "bottom" },
124 { LabelAlign::BOTTOM_LEFT, "bottom_left" },
125 { LabelAlign::BOTTOM_CENTER,"bottom_center" },
126 { LabelAlign::BOTTOM_RIGHT, "bottom_right" }
127 };
128
129 inline static const std::unordered_map<std::string, LabelAlign> stringToLabelAlign_ = {
130 { "default", LabelAlign::DEFAULT },
131 { "left", LabelAlign::LEFT },
132 { "center", LabelAlign::CENTER },
133 { "right", LabelAlign::RIGHT },
134 { "top", LabelAlign::TOP },
135 { "top_left", LabelAlign::TOP_LEFT },
136 { "top_center", LabelAlign::TOP_CENTER },
137 { "top_right", LabelAlign::TOP_RIGHT },
138 { "middle", LabelAlign::MIDDLE },
139 { "middle_left", LabelAlign::MIDDLE_LEFT },
140 { "middle_center", LabelAlign::MIDDLE_CENTER },
141 { "middle_right", LabelAlign::MIDDLE_RIGHT },
142 { "bottom", LabelAlign::BOTTOM },
143 { "bottom_left", LabelAlign::BOTTOM_LEFT },
144 { "bottom_center", LabelAlign::BOTTOM_CENTER },
145 { "bottom_right", LabelAlign::BOTTOM_RIGHT },
146 };
147
150 {
152 std::string text;
154 };
155
156 // PhraseToken: a run of tokens with identical style/alignment on the same line
157 struct PhraseToken {
158 std::string text; // Concatenated text of the phrase
159 FontStyle style; // Style for the entire phrase
160 int lineIndex; // Line number within the label
161 float startX; // X position for rendering
162 float lineY; // Y position for rendering
163 float width = 0.0f; // Width of the phrase (in pixels)
164 float height = 0.0f; // Height of the phrase (in pixels)
165 };
166
168
169 protected:
170 // --- Constructors --- //
171 Label(const InitStruct& init);
172 Label(const sol::table& config);
173
174 public:
175 // --- Static Factory Methods --- //
176 static std::unique_ptr<IDisplayObject> CreateFromLua(const sol::table& config) {
177 return std::unique_ptr<IDisplayObject>(new Label(config));
178 }
179 static std::unique_ptr<IDisplayObject> CreateFromInitStruct(const Label::InitStruct& baseInit) {
180 const auto& labelInit = static_cast<const Label::InitStruct&>(baseInit);
181 return std::unique_ptr<IDisplayObject>(new Label(labelInit));
182 }
183
184 Label() = default;
185 virtual ~Label() override;
186
187 // virtual methods
188 virtual bool onInit() override;
189 virtual void onQuit() override;
190 virtual void onUpdate(float fElapsedTime) override;
191 virtual void onEvent(const Event& event) override;
192 virtual void onRender() override;
193 virtual bool onUnitTest() override;
194
195 void setText(std::string p_text);
196 std::string getText() const { return text_; }
197 AssetHandle getFont() const { return fontAsset; }
199 int getGlyphHeight() const
200 {
201 if (fontAsset)
202 {
203 IFontObject* fontObj = fontAsset.as<IFontObject>();
204 if (fontObj)
205 {
206 return fontObj->getGlyphHeight('W');
207 }
208 }
209 return 0;
210 }
211
213 void setDefaultStyle(const FontStyle& style) { defaultStyle_ = style; setDirty(); }
214
215 bool isPunctuation(char c);
216 int tokenizeText(); // returns tokenList.size
217 void renderLabel();
218 void renderLabelPass(RenderPass pass);
219
220
221 protected:
222
223 friend Factory;
224 friend Core;
225
226 std::string text_;
227 std::string lastTokenizedText_ = ""; // To track changes for re-tokenization
228 int fontSize_; // truetype fonts
229 int fontWidth_; // bitmap font width
230 int fontHeight_; // bitmap font height
232 AssetHandle fontAsset; // Underlying font asset for the Label
233 FontStyle defaultStyle_; // default style for the label
234 std::string resourceName_; // Optional resource name for preloaded font
235
236 // Flags to indicate whether the user explicitly provided per-axis
237 // bitmap font metrics in the Lua config. If false, we will default
238 // to the backing SpriteSheet's spriteWidth/spriteHeight in onInit().
241
242 SDL_Texture* cachedTexture_ = nullptr;
243
244 // --- first pass token list --- //
245 std::vector<LabelToken> tokenList;
246
247 // --- second pass token alignment lists --- //
248 enum class AlignQueue : uint8_t
249 {
250 TOP_LEFT = 0b0000,
251 TOP_CENTER = 0b0001,
252 TOP_RIGHT = 0b0010,
253 MIDDLE_LEFT = 0b0011,
254 MIDDLE_CENTER = 0b0100,
255 MIDDLE_RIGHT = 0b0101,
256 BOTTOM_LEFT = 0b0110,
257 BOTTOM_CENTER = 0b0111,
258 BOTTOM_RIGHT = 0b1000,
259 DEFAULT = 0b0000, // default to top-left
260 LEFT = 0b0011, // default to middle-left
261 CENTER = 0b0100, // default to middle-center
262 RIGHT = 0b0101, // default to middle-right
263 TOP = 0b0001, // default to top-center
264 MIDDLE = 0b0100, // default to middle-center
265 BOTTOM = 0b0111 // default to bottom-center
266 };
286 std::map<AlignQueue, std::vector<LabelToken>> tokenAlignLists_;
287
288 // --- final pass phrase alignment lists --- //
289 std::map<AlignQueue, std::vector<PhraseToken>> phraseAlignLists_;
290
291 public:
292 // --- Accessors for unit tests / inspection --- //
293 const std::vector<LabelToken>& getTokenList() const { return tokenList; }
294 const std::string& getLastTokenizedText() const { return lastTokenizedText_; }
295 const std::map<AlignQueue, std::vector<LabelToken>>& getTokenAlignLists() const { return tokenAlignLists_; }
296 const std::map<AlignQueue, std::vector<PhraseToken>>& getPhraseAlignLists() const { return phraseAlignLists_; }
297
298 protected:
299 // --- Helpers to build alignment lists from tokenList --- //
300 void _buildTokenAlignLists(); // Helper to build alignment lists from tokenList
301 void _debugToken(const LabelToken& token); // Helper to print token info for debugging
302 void _maxSize(float& width, float& height); // Helper to calculate max size needed
303 void _buildPhraseAlignLists(); // Helper to build phrase groups from tokenAlignLists_
304
305 // --- Utility function to determine if cachedTexture_ needs to be rebuilt --- //
306 SDL_PixelFormat current_pixel_format = SDL_PIXELFORMAT_UNKNOWN;
311 bool needsTextureRebuild_(int width, int height, SDL_PixelFormat fmt) const;
312 bool rebuildTexture_(int width, int height, SDL_PixelFormat fmt = SDL_PIXELFORMAT_RGBA8888 );
313
314 // --- Lua Registration --- //
315 virtual void _registerLuaBindings(const std::string& typeName, sol::state_view lua);
316 };
317
318} // namespace SDOM
319
Definition SDOM_AssetHandle.hpp:13
T * as() const
Definition SDOM_AssetHandle.hpp:38
Definition SDOM_Event.hpp:55
Definition SDOM_IDisplayObject.hpp:153
IDisplayObject & setDirty()
Definition SDOM_IDisplayObject.hpp:237
Definition SDOM_IFontObject.hpp:170
FontType
Definition SDOM_IFontObject.hpp:177
virtual int getGlyphHeight(Uint32 ch) const =0
Definition SDOM_Label.hpp:38
const std::vector< LabelToken > & getTokenList() const
Definition SDOM_Label.hpp:293
void setText(std::string p_text)
Definition SDOM_Label.cpp:514
std::vector< LabelToken > tokenList
Definition SDOM_Label.hpp:245
int current_width
Definition SDOM_Label.hpp:307
virtual void onRender() override
Definition SDOM_Label.cpp:443
virtual bool onInit() override
Definition SDOM_Label.cpp:250
int parent_height_
Definition SDOM_Label.hpp:310
static std::unique_ptr< IDisplayObject > CreateFromLua(const sol::table &config)
Definition SDOM_Label.hpp:176
std::unordered_map< LabelAlign, AlignQueue > alignXRef_
Definition SDOM_Label.hpp:267
void _buildPhraseAlignLists()
Definition SDOM_Label.cpp:1412
void setDefaultStyle(const FontStyle &style)
Definition SDOM_Label.hpp:213
std::string getText() const
Definition SDOM_Label.hpp:196
int fontHeight_
Definition SDOM_Label.hpp:230
AssetHandle fontAsset
Definition SDOM_Label.hpp:232
static const std::unordered_map< LabelAlign, std::string > labelAlignToString_
Definition SDOM_Label.hpp:110
RenderPass
Definition SDOM_Label.hpp:167
FontStyle & getDefaultStyle()
Definition SDOM_Label.hpp:212
int current_height
Definition SDOM_Label.hpp:308
int getGlyphHeight() const
Definition SDOM_Label.hpp:199
virtual void onUpdate(float fElapsedTime) override
Definition SDOM_Label.cpp:371
TokenType
Definition SDOM_Label.hpp:148
int tokenizeText()
Definition SDOM_Label.cpp:530
std::string resourceName_
Definition SDOM_Label.hpp:234
void _maxSize(float &width, float &height)
Definition SDOM_Label.cpp:1297
static std::unique_ptr< IDisplayObject > CreateFromInitStruct(const Label::InitStruct &baseInit)
Definition SDOM_Label.hpp:179
friend Factory
Definition SDOM_Label.hpp:223
virtual ~Label() override
Definition SDOM_Label.cpp:244
IFontObject::FontType getFontType() const
Definition SDOM_Label.hpp:198
const std::map< AlignQueue, std::vector< PhraseToken > > & getPhraseAlignLists() const
Definition SDOM_Label.hpp:296
bool rebuildTexture_(int width, int height, SDL_PixelFormat fmt=SDL_PIXELFORMAT_RGBA8888)
Definition SDOM_Label.cpp:1663
void _debugToken(const LabelToken &token)
Definition SDOM_Label.cpp:1264
std::string lastTokenizedText_
Definition SDOM_Label.hpp:227
int parent_width_
Definition SDOM_Label.hpp:309
AssetHandle getFont() const
Definition SDOM_Label.hpp:197
FontStyle defaultStyle_
Definition SDOM_Label.hpp:233
virtual void _registerLuaBindings(const std::string &typeName, sol::state_view lua)
Definition SDOM_Label.cpp:1713
IFontObject::FontType fontType_
Definition SDOM_Label.hpp:231
bool userFontWidthSpecified_
Definition SDOM_Label.hpp:239
static const std::unordered_map< std::string, LabelAlign > stringToLabelAlign_
Definition SDOM_Label.hpp:129
virtual void onQuit() override
Definition SDOM_Label.cpp:351
bool userFontHeightSpecified_
Definition SDOM_Label.hpp:240
SDL_PixelFormat current_pixel_format
Definition SDOM_Label.hpp:306
std::map< AlignQueue, std::vector< LabelToken > > tokenAlignLists_
Definition SDOM_Label.hpp:286
int fontWidth_
Definition SDOM_Label.hpp:229
friend Core
Definition SDOM_Label.hpp:224
const std::string & getLastTokenizedText() const
Definition SDOM_Label.hpp:294
virtual bool onUnitTest() override
Runs unit tests for this object.
Definition SDOM_Label.cpp:509
AlignQueue
Definition SDOM_Label.hpp:249
Label()=default
virtual void onEvent(const Event &event) override
Definition SDOM_Label.cpp:437
SDL_Texture * cachedTexture_
Definition SDOM_Label.hpp:242
static constexpr const char * TypeName
Definition SDOM_Label.hpp:43
bool needsTextureRebuild_(int width, int height, SDL_PixelFormat fmt) const
Definition SDOM_Label.cpp:1655
bool isPunctuation(char c)
Definition SDOM_Label.cpp:525
void renderLabel()
Definition SDOM_Label.cpp:969
std::string text_
Definition SDOM_Label.hpp:226
void renderLabelPass(RenderPass pass)
Definition SDOM_Label.cpp:976
std::map< AlignQueue, std::vector< PhraseToken > > phraseAlignLists_
Definition SDOM_Label.hpp:289
const std::map< AlignQueue, std::vector< LabelToken > > & getTokenAlignLists() const
Definition SDOM_Label.hpp:295
void _buildTokenAlignLists()
Definition SDOM_Label.cpp:1157
int fontSize_
Definition SDOM_Label.hpp:228
Contains all core classes and utilities for the SDOM library.
Definition lua_BindHelpers.hpp:7
LabelAlign
Definition SDOM_IFontObject.hpp:14
@ TOP_LEFT
Top-left corner of the parent.
Definition SDOM_IFontObject.hpp:35
Definition SDOM_IDisplayObject.hpp:187
std::string type
Definition SDOM_IDisplayObject.hpp:189
AnchorPoint anchorLeft
Definition SDOM_IDisplayObject.hpp:203
float height
Definition SDOM_IDisplayObject.hpp:193
bool tabEnabled
Definition SDOM_IDisplayObject.hpp:212
std::string name
Definition SDOM_IDisplayObject.hpp:188
AnchorPoint anchorBottom
Definition SDOM_IDisplayObject.hpp:204
AnchorPoint anchorTop
Definition SDOM_IDisplayObject.hpp:202
float width
Definition SDOM_IDisplayObject.hpp:192
int z_order
Definition SDOM_IDisplayObject.hpp:206
SDL_Color color
Definition SDOM_IDisplayObject.hpp:194
float x
Definition SDOM_IDisplayObject.hpp:190
int priority
Definition SDOM_IDisplayObject.hpp:207
float y
Definition SDOM_IDisplayObject.hpp:191
int tabPriority
Definition SDOM_IDisplayObject.hpp:211
bool isClickable
Definition SDOM_IDisplayObject.hpp:208
bool isEnabled
Definition SDOM_IDisplayObject.hpp:209
AnchorPoint anchorRight
Definition SDOM_IDisplayObject.hpp:205
bool isHidden
Definition SDOM_IDisplayObject.hpp:210
Definition SDOM_Label.hpp:47
int dropshadowOffsetY
Definition SDOM_Label.hpp:102
int padding_vert
Definition SDOM_Label.hpp:100
std::string resourceName
Definition SDOM_Label.hpp:72
int borderThickness
Definition SDOM_Label.hpp:97
bool underline
Definition SDOM_Label.hpp:87
LabelAlign alignment
Definition SDOM_Label.hpp:77
int dropshadowOffsetX
Definition SDOM_Label.hpp:101
bool dropshadow
Definition SDOM_Label.hpp:92
IFontObject::FontType fontType
Definition SDOM_Label.hpp:73
int maxHeight
Definition SDOM_Label.hpp:96
bool auto_resize
Definition SDOM_Label.hpp:94
InitStruct()
Definition SDOM_Label.hpp:48
bool strikethrough
Definition SDOM_Label.hpp:88
bool wordwrap
Definition SDOM_Label.hpp:93
bool border
Definition SDOM_Label.hpp:89
bool outline
Definition SDOM_Label.hpp:91
int fontWidth
Definition SDOM_Label.hpp:75
int fontSize
Definition SDOM_Label.hpp:74
int fontHeight
Definition SDOM_Label.hpp:76
int padding_horiz
Definition SDOM_Label.hpp:99
int outlineThickness
Definition SDOM_Label.hpp:98
bool italic
Definition SDOM_Label.hpp:86
bool background
Definition SDOM_Label.hpp:90
std::string text
Definition SDOM_Label.hpp:71
bool bold
Definition SDOM_Label.hpp:85
int maxWidth
Definition SDOM_Label.hpp:95
Definition SDOM_Label.hpp:150
FontStyle style
Definition SDOM_Label.hpp:153
std::string text
Definition SDOM_Label.hpp:152
TokenType type
Definition SDOM_Label.hpp:151
Definition SDOM_Label.hpp:157
float height
Definition SDOM_Label.hpp:164
float startX
Definition SDOM_Label.hpp:161
std::string text
Definition SDOM_Label.hpp:158
int lineIndex
Definition SDOM_Label.hpp:160
float lineY
Definition SDOM_Label.hpp:162
FontStyle style
Definition SDOM_Label.hpp:159
float width
Definition SDOM_Label.hpp:163