Repository navigation
Expand file tree
/
Copy pathWidgetText.h
More file actions
112 lines (102 loc) · 2.74 KB
/
Copy pathWidgetText.h
File metadata and controls
112 lines (102 loc) · 2.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#pragma once
// Helpers for widget parts drawn by a TextComponent. Inline, so they come and
// go with the text feature.
#include <deki/Color.h>
#include <deki/Object.h>
#include "TextComponent.h"
#include "WidgetParts.h"
#include <string>
namespace Deki2D
{
namespace WidgetParts
{
/// The part's TextComponent, or nullptr.
inline TextComponent* Text(Deki::Object* part)
{
return part ? part->GetComponent<TextComponent>() : nullptr;
}
#ifdef DEKI_EDITOR
/// The first text with a font under `obj`, depth first, skipping `skip`.
inline TextComponent* FindFontedText(Deki::Object* obj, const Deki::Object* skip)
{
if (!obj || obj == skip)
{
return nullptr;
}
if (auto* tc = obj->GetComponent<TextComponent>())
{
if (!tc->font.guid.empty() || !tc->font.source.empty())
{
return tc;
}
}
for (Deki::Object* child : obj->GetChildren())
{
if (TextComponent* found = FindFontedText(child, skip))
{
return found;
}
}
return nullptr;
}
#endif
/// The text part `name`, made in the editor when missing: aligned `align`,
/// centred top to bottom, in `color`, with the font of the nearest text that
/// has one (first among the part's relatives, then further out), at
/// `fontSize` pixels.
inline Deki::Object* TextPart(Deki::Object* owner, const char* name, const Deki::Color& color,
TextAlign align = TextAlign::Center, int32_t fontSize = 16)
{
bool created = false;
Deki::Object* part = FindOrCreate<TextComponent>(owner, name, created);
TextComponent* tc = created ? Text(part) : nullptr;
if (!tc)
{
return part;
}
tc->color = color;
tc->align = align;
tc->verticalAlign = TextVerticalAlign::Middle;
#ifdef DEKI_EDITOR
tc->fontSize = fontSize;
Deki::Object* top = part;
while (top->GetParent())
{
top = top->GetParent();
if (TextComponent* found = FindFontedText(top, part))
{
tc->font = found->font;
break;
}
}
#else
(void)fontSize;
#endif
return part;
}
/// Sizes and places a text part, when there is one.
inline void PlaceText(Deki::Object* part, float x, float y, float width, float height)
{
if (!part)
{
return;
}
part->SetLocalPosition(x, y);
if (TextComponent* tc = Text(part))
{
tc->width = width;
tc->height = height;
}
}
/// Sets a text part's string, only when it changed, so the text is not baked
/// again for nothing.
inline void SetPartText(Deki::Object* part, const std::string& value)
{
TextComponent* tc = Text(part);
if (tc && tc->text != value)
{
tc->SetText(value);
}
}
} // namespace WidgetParts
} // namespace Deki2D