Symphony Of Empires
text.cpp
Go to the documentation of this file.
1 // Symphony of Empires
2 // Copyright (C) 2021, Symphony of Empires contributors
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <https://www.gnu.org/licenses/>.
16 //
17 // ----------------------------------------------------------------------------
18 // Name:
19 // eng3d/ui/text.cpp
20 //
21 // Abstract:
22 // A text widget with support for multiple lines.
23 // ----------------------------------------------------------------------------
24 
25 #include "eng3d/ui/text.hpp"
26 #include "eng3d/ui/label.hpp"
27 
28 using namespace UI;
29 
30 UI::Text::Text(int _x, int _y, unsigned w, unsigned h, UI::Widget* _parent)
31  : UI::Widget(_parent, _x, _y, w, h, UI::WidgetType::GROUP)
32 {
33  this->text_color = this->parent->text_color;
34  this->flex = UI::Flex::COLUMN;
35 }
36 
42 UI::Text::Text(int _x, int _y, const std::string& _text, UI::Widget* _parent)
43  : UI::Widget(_parent, _x, _y, 0, 0, UI::WidgetType::GROUP)
44 {
45  this->text_color = this->parent->text_color;
46  this->auto_adjust = true;
47  this->width = this->parent->width;
48  this->flex = UI::Flex::COLUMN;
49  this->set_text(_text);
50 }
51 
53 
54 }
55 
56 void UI::Text::set_text(const std::string& text) {
57  this->kill_children();
58  if(text.empty()) return;
59 
60  // Separate the text in multiple labels and break on space
62  size_t pos = 0;
63  size_t max_width = 0, max_height = 0;
64  size_t line_width = glm::max(this->width / 12, static_cast<size_t>(1));
65  while(pos < text.length()) {
66  size_t remaining_chars = text.length() - pos;
67  size_t end_pos = text.length();
68  if(remaining_chars > line_width)
69  end_pos = pos + line_width;
70 
71  bool break_line = false;
72  for(size_t i = pos; i <= end_pos; i++) {
73  if(text[i] == '\n') {
74  end_pos = i;
75  break_line = true;
76  break;
77  }
78  }
79 
80  if(!break_line && remaining_chars > line_width) {
81  for(size_t i = end_pos; i > pos; i--) {
82  if(text[i] == ' ') {
83  end_pos = i;
84  break;
85  }
86  }
87  }
88 
89  std::string buf = text.substr(pos, end_pos - pos);
90  pos = end_pos;
91  if(break_line) pos++;
92  auto& lab = this->make_widget<UI::Label>(4, 4, buf);
93  max_width = glm::max(max_width, lab.width);
94  max_height += lab.height;
95  }
96 
97  if(this->auto_adjust) {
98  this->width = max_width + 4;
99  this->height = max_height + 4;
100  }
101 }
The UI context that handles all the ui widgets.
Definition: ui.hpp:63
virtual void on_render(Context &ctx, Eng3D::Rect viewport)
Definition: text.cpp:52
virtual void set_text(const std::string &text)
Generates text for the widget and overrides the current text texture.
Definition: text.cpp:56
Text(int x, int y, unsigned w, unsigned h, UI::Widget *parent)
Definition: text.cpp:30
bool auto_adjust
Whetever to auto adjust the widget depending on the text.
Definition: text.hpp:51
The master widget all the other widgets inherit from, do not use directly instead use one of the many...
Definition: widget.hpp:176
size_t width
Definition: widget.hpp:325
UI::Flex flex
Definition: widget.hpp:337
Eng3D::Color text_color
Definition: widget.hpp:332
UI::Widget * parent
Definition: widget.hpp:314
WidgetType
The type of the widget, some widgets share types between them to keep simplicity.
Definition: widget.hpp:76