32 #include <unordered_map>
35 #include "eng3d/ui/widget.hpp"
36 #include "eng3d/ui/div.hpp"
37 #include "eng3d/ui/scrollbar.hpp"
38 #include "eng3d/utils.hpp"
53 void set_key(
const std::string& key);
55 void set_key(
float key,
const std::string_view format);
64 std::string key_string;
65 UI::TableElement::KeyType key_type = UI::TableElement::KeyType::NONE;
79 std::vector<UI::TableElement*> elements;
80 std::vector<int>& columns_width;
89 Table(
int _x,
int _y,
unsigned _h,
int _row_height, std::vector<int> _widths, std::vector<std::string> _header_labels,
UI::Widget* _parent =
nullptr)
91 row_height{ _row_height }, columns_width{ _widths }
93 assert(_widths.size() == _header_labels.size());
94 this->
width = std::accumulate(_widths.begin(), _widths.end(), 35);
95 auto& header = this->
template make_widget<UI::TableRow>(this->
width - 35, _row_height, this->columns_width);
96 for(
size_t i = 0; i < _header_labels.size(); i++) {
97 auto& label = _header_labels[i];
98 auto* column = header.get_element(i);
99 column->set_text(label);
100 column->set_on_click([
this, i](
Widget&) {
101 this->sorting_ascending = (this->sorting_row == (int)i) ? !this->sorting_ascending :
true;
102 this->sorting_row = i;
103 this->
sort(i, this->sorting_ascending);
106 auto& wrapper = this->
template make_widget<UI::Div>(0, _row_height, this->
width, this->
height - row_height);
107 wrapper.is_scroll =
true;
108 this->column_wrapper = &wrapper.template make_widget<UI::Div>(0, 0, this->
width - 25, 0);
111 this->scrollbar = &wrapper.template make_widget<UI::Scrollbar>(this->
width - 20, 0, wrapper.height - 40);
113 int total_height = this->row_height * this->rows.size();
114 this->column_wrapper->
height = total_height;
120 this->rows.reserve(_size);
124 if(!this->rows.count(_row_id)) {
125 auto& row = this->column_wrapper->template make_widget<UI::TableRow>(this->
width - 25, this->row_height, this->columns_width);
126 this->rows.insert({ _row_id, &row });
128 auto* row = this->rows[_row_id];
129 row->is_active =
true;
134 if(this->rows.count(_row_id)) {
135 this->rows[_row_id]->kill();
136 this->rows.erase(_row_id);
141 for(
auto it = rows.begin(); it != rows.end(); it++) {
142 it->second->is_active =
false;
147 for(
auto it = rows.begin(); it != rows.end(); ) {
148 if(!it->second->is_active) {
157 void sort(
size_t _column_index,
bool ascending) {
158 this->column_wrapper->
sort_children([_column_index, ascending](
const auto& a,
const auto& b) {
160 auto &element_a = *(row_a.
get_element(_column_index));
162 auto &element_b = *(row_b.
get_element(_column_index));
163 return ascending ? (element_a < element_b) : (element_b < element_a);
167 std::unordered_map<T, UI::TableRow*> rows;
168 int sorting_row = -1;
169 bool sorting_ascending =
true;
173 std::vector<int> columns_width;
An element on a table, operates on a k=v fashion where the key is used for sorting the table.
void set_key(const std::string &key)
TableElement(int width, int height, UI::Widget *_parent)
virtual ~TableElement() override
bool operator<(const UI::TableElement &right) const
A dynamic/smart table that can sort elements by ascending/descending order.
void make_rows_unactive()
virtual ~Table() override
void remove_row(T _row_id)
void reserve(size_t _size)
UI::TableRow & get_row(T _row_id)
Table(int _x, int _y, unsigned _h, int _row_height, std::vector< int > _widths, std::vector< std::string > _header_labels, UI::Widget *_parent=nullptr)
void sort(size_t _column_index, bool ascending)
void clear_unactive_rows()
A row of a table, contains table elements and specifies the width of the entire row.
virtual ~TableRow() override
UI::TableElement * get_element(size_t index)
TableRow(int width, int height, std::vector< int > &columns_width, UI::Widget *_parent)
WidgetType
The type of the widget, some widgets share types between them to keep simplicity.
A basic widget without any presets.