1 #include "FixedText.hpp"
2 #include "MessageBox.hpp"
4 #include "TextInput.hpp"
6 #include "../graphics/Font.hpp"
7 #include "../graphics/Viewport.hpp"
19 MessageBox::MessageBox(const graphics::Font &f)
24 , adv(0.0f, font.LineSkip(), 0.0f)
25 , bg(1.0f, 1.0f, 1.0f, 0.0f)
26 , fg(1.0f, 1.0f, 1.0f, 1.0f)
27 , grav(graphics::Gravity::NORTH_WEST)
32 void MessageBox::Position(const glm::vec3 &p, graphics::Gravity g) noexcept {
35 if (get_y(g) == graphics::Align::END) {
36 adv.y = -font.LineSkip();
38 adv.y = font.LineSkip();
40 for (Text &txt : lines) {
46 void MessageBox::PushLine(const char *text) {
47 lines.emplace_front();
48 Text &txt = lines.front();
52 while (lines.size() > max_lines) {
60 graphics::PrimitiveMesh::Buffer bg_buf;
64 void MessageBox::Recalc() {
65 size = glm::vec2(0.0f, 0.0f);
66 for (const Text &line : lines) {
67 size.x = max(size.x, line.Size().x);
68 size.y += line.Size().y;
70 bg_buf.FillRect(size.x, size.y, bg, align(grav, size));
71 bg_mesh.Update(bg_buf);
76 void MessageBox::Render(graphics::Viewport &viewport) noexcept {
77 viewport.SetCursor(pos, grav);
78 if (bg.a > numeric_limits<float>::epsilon()) {
82 graphics::PlainColor &prog = viewport.HUDColorProgram();
83 prog.SetM(viewport.Cursor());
84 bg_mesh.DrawTriangles();
85 viewport.MoveCursor(glm::vec3(0.0f, 0.0f, -1.0f));
87 graphics::BlendedSprite &prog = viewport.SpriteProgram();
88 prog.SetBG(glm::vec4(0.0f));
89 prog.SetFG(glm::vec4(fg) * (1.0f / 255.0f));
90 for (Text &txt : lines) {
91 prog.SetM(viewport.Cursor());
93 viewport.MoveCursor(adv);
102 , pivot(graphics::Gravity::NORTH_WEST)
107 FixedText::FixedText() noexcept
109 , bg(1.0f, 1.0f, 1.0f, 0.0f)
110 , fg(1.0f, 1.0f, 1.0f, 1.0f)
112 , grav(graphics::Gravity::NORTH_WEST)
117 void Text::Set(const graphics::Font &font, const char *text) {
118 font.Render(text, tex);
119 size = font.TextSize(text);
125 graphics::SpriteMesh::Buffer sprite_buf;
129 void Text::Update() {
130 sprite_buf.LoadRect(size.x, size.y, align(pivot, size));
131 sprite.Update(sprite_buf);
135 void FixedText::Render(graphics::Viewport &viewport) noexcept {
136 graphics::BlendedSprite &prog = viewport.SpriteProgram();
137 viewport.SetCursor(pos, grav);
138 prog.SetM(viewport.Cursor());
141 Text::Render(viewport);
144 void Text::Render(graphics::Viewport &viewport) noexcept {
148 graphics::BlendedSprite &prog = viewport.SpriteProgram();
149 prog.SetTexture(tex);
154 TextInput::TextInput(const graphics::Font &font)
161 , bg(1.0f, 1.0f, 1.0f, 0.0f)
162 , fg(1.0f, 1.0f, 1.0f, 1.0f)
164 , size(font.LineSkip())
165 , gravity(graphics::Gravity::NORTH_WEST)
173 void TextInput::Focus(graphics::Viewport &viewport) noexcept {
174 SDL_StartTextInput();
177 glm::vec2 p(viewport.GetPosition(glm::vec2(position), gravity));
183 SDL_SetTextInputRect(&rect);
186 void TextInput::Blur() noexcept {
191 void TextInput::Clear() noexcept {
197 void TextInput::Backspace() noexcept {
198 string::size_type previous(cursor);
200 input.erase(cursor, previous - cursor);
204 void TextInput::Delete() noexcept {
205 string::size_type previous(cursor);
207 input.erase(previous, cursor - previous);
212 void TextInput::MoveBegin() noexcept {
216 void TextInput::MoveBackward() noexcept {
217 if (AtBegin()) return;
219 while (cursor > 0 && (input[cursor] & 0xC0) == 0x80) {
224 void TextInput::MoveForward() noexcept {
227 while (cursor <= input.size() && (input[cursor] & 0xC0) == 0x80) {
232 void TextInput::MoveEnd() noexcept {
233 cursor = input.size();
236 void TextInput::Insert(const char *str) {
237 size_t len = strlen(str);
238 input.insert(cursor, str, len);
243 bool TextInput::AtBegin() const noexcept {
247 bool TextInput::AtEnd() const noexcept {
248 return cursor == input.size();
251 void TextInput::Position(const glm::vec3 &p, graphics::Gravity g, graphics::Gravity pv) noexcept {
258 void TextInput::Width(float w) noexcept {
263 void TextInput::Handle(const SDL_TextInputEvent &e) {
267 void TextInput::Handle(const SDL_TextEditingEvent &) {
271 void TextInput::Refresh() {
273 bg_buf.FillRect(size.x, size.y, bg, align(gravity, size));
274 bg_mesh.Update(bg_buf);
279 bg_buf.Reserve(2, 2);
280 bg_buf.vertices.emplace_back(0.0f, 0.0f, 0.0f);
281 bg_buf.vertices.emplace_back(0.0f, float(font.LineSkip()), 0.0f);
282 bg_buf.colors.resize(2, fg);
283 bg_buf.indices.push_back(0);
284 bg_buf.indices.push_back(1);
285 cursor_mesh.Update(bg_buf);
287 dirty_cursor = false;
290 if (!input.empty()) {
291 text.Set(font, input.c_str());
297 void TextInput::Render(graphics::Viewport &viewport) {
299 viewport.SetCursor(position, gravity);
300 if (bg.a > numeric_limits<float>::epsilon()) {
301 viewport.EnableAlphaBlending();
302 graphics::PlainColor &prog = viewport.HUDColorProgram();
303 prog.SetM(viewport.Cursor());
304 bg_mesh.DrawTriangles();
305 viewport.MoveCursor(glm::vec3(0.0f, 0.0f, -1.0f));
307 if (!input.empty()) {
308 graphics::BlendedSprite &prog = viewport.SpriteProgram();
309 prog.SetBG(glm::vec4(0.0f));
310 prog.SetFG(glm::vec4(fg) * (1.0f / 255.0f));
311 prog.SetM(viewport.Cursor());
312 text.Render(viewport);
315 glm::vec2 offset(0.0f);
316 if (input.empty() || AtBegin()) {
318 offset = -align(text.Pivot(), glm::vec2(0.0f, font.LineSkip()));
319 } else if (AtEnd()) {
320 offset = -align(text.Pivot(), text.Size(), glm::vec2(-text.Size().x, 0.0f));
322 offset = -align(text.Pivot(), text.Size(), glm::vec2(-font.TextSize(input.substr(0, cursor).c_str()).x, 0.0f));
324 viewport.MoveCursor(glm::vec3(offset, -1.0f));
325 graphics::PlainColor &prog = viewport.HUDColorProgram();
326 prog.SetM(viewport.Cursor());
327 cursor_mesh.DrawLines();