]> git.localhorst.tv Git - blank.git/blob - src/ui/widgets.cpp
533703fd84da47dea5e8d12f5c3df12d5c0e450f
[blank.git] / src / ui / widgets.cpp
1 #include "FixedText.hpp"
2 #include "MessageBox.hpp"
3 #include "Progress.hpp"
4 #include "Text.hpp"
5
6 #include "../graphics/Font.hpp"
7 #include "../graphics/Viewport.hpp"
8
9 #include <cstdio>
10
11
12 namespace blank {
13
14 MessageBox::MessageBox(const Font &f)
15 : font(f)
16 , lines()
17 , max_lines(10)
18 , pos(0.0f)
19 , adv(0.0f, font.LineSkip(), 0.0f)
20 , bg(1.0f, 1.0f, 1.0f, 0.0f)
21 , fg(1.0f, 1.0f, 1.0f, 1.0f)
22 , grav(Gravity::NORTH_WEST)
23 , dirty(true) {
24
25 }
26
27 void MessageBox::Position(const glm::vec3 &p, Gravity g) noexcept {
28         pos = p;
29         grav = g;
30         if (get_y(g) == Align::END) {
31                 adv.y = -font.LineSkip();
32         } else {
33                 adv.y = font.LineSkip();
34         }
35         for (Text &txt : lines) {
36                 txt.Pivot(g);
37         }
38         dirty = true;
39 }
40
41 void MessageBox::PushLine(const char *text) {
42         lines.emplace_front();
43         Text &txt = lines.front();
44         txt.Set(font, text);
45         txt.Pivot(grav);
46
47         while (lines.size() > max_lines) {
48                 lines.pop_back();
49         }
50         dirty = true;
51 }
52
53 namespace {
54
55 PrimitiveMesh::Buffer bg_buf;
56
57 }
58
59 void MessageBox::Recalc() {
60         size = glm::vec2(0.0f, 0.0f);
61         for (const Text &line : lines) {
62                 size.x = std::max(size.x, line.Size().x);
63                 size.y += line.Size().y;
64         }
65         bg_buf.FillRect(size.x, size.y, bg, align(grav, size));
66         bg_mesh.Update(bg_buf);
67         bg_buf.Clear();
68         dirty = false;
69 }
70
71 void MessageBox::Render(Viewport &viewport) noexcept {
72         viewport.SetCursor(pos, grav);
73         if (bg.a > std::numeric_limits<float>::epsilon()) {
74                 if (dirty) {
75                         Recalc();
76                 }
77                 PlainColor &prog = viewport.HUDColorProgram();
78                 prog.SetM(viewport.Cursor());
79                 bg_mesh.DrawTriangles();
80                 viewport.MoveCursor(glm::vec3(0.0f, 0.0f, -1.0f));
81         }
82         BlendedSprite &prog = viewport.SpriteProgram();
83         prog.SetBG(glm::vec4(0.0f));
84         prog.SetFG(fg);
85         for (Text &txt : lines) {
86                 prog.SetM(viewport.Cursor());
87                 txt.Render(viewport);
88                 viewport.MoveCursor(adv);
89         }
90 }
91
92
93 Progress::Progress(Font &font) noexcept
94 : font(font)
95 , text()
96 , tpl("%d/%d (%d%%)") {
97
98 }
99
100 namespace {
101
102 char buf[128] = { '\0' };
103
104 }
105
106 void Progress::Update(int current, int total) {
107         std::snprintf(buf, sizeof(buf), tpl, current, total, current * 100 / total);
108         text.Set(font, buf);
109 }
110
111 void Progress::Render(Viewport &viewport) noexcept {
112         text.Render(viewport);
113 }
114
115
116 Text::Text() noexcept
117 : tex()
118 , sprite()
119 , size(0.0f)
120 , pivot(Gravity::NORTH_WEST)
121 , dirty(false) {
122
123 }
124
125 FixedText::FixedText() noexcept
126 : Text()
127 , bg(1.0f, 1.0f, 1.0f, 0.0f)
128 , fg(1.0f, 1.0f, 1.0f, 1.0f)
129 , pos(0.0f)
130 , grav(Gravity::NORTH_WEST)
131 , visible(false) {
132
133 }
134
135 void Text::Set(const Font &font, const char *text) {
136         font.Render(text, tex);
137         size = font.TextSize(text);
138         dirty = true;
139 }
140
141 namespace {
142
143 SpriteMesh::Buffer sprite_buf;
144
145 }
146
147 void Text::Update() {
148         sprite_buf.LoadRect(size.x, size.y, align(pivot, size));
149         sprite.Update(sprite_buf);
150         dirty = false;
151 }
152
153 void FixedText::Render(Viewport &viewport) noexcept {
154         BlendedSprite &prog = viewport.SpriteProgram();
155         viewport.SetCursor(pos, grav);
156         prog.SetM(viewport.Cursor());
157         prog.SetBG(bg);
158         prog.SetFG(fg);
159         Text::Render(viewport);
160 }
161
162 void Text::Render(Viewport &viewport) noexcept {
163         if (dirty) {
164                 Update();
165         }
166         BlendedSprite &prog = viewport.SpriteProgram();
167         prog.SetTexture(tex);
168         sprite.Draw();
169 }
170
171 }