Skip to content

Commit a79b638

Browse files
committed
Add new widgets: TUISpinBox, TUIDoubleSpinBox, TUIListView, and TUITableView
- Updated CMakeLists.txt to include new header and source files for TUISpinBox, TUIDoubleSpinBox, TUIListView, and TUITableView. - Enhanced README.md to document the new widgets and their functionalities. - Implemented TUISpinBox for integer value input with increment/decrement functionality. - Implemented TUIDoubleSpinBox for double value input with similar features. - Created TUIListView for displaying a list of selectable items. - Developed TUITableView for displaying tabular data with selection and editing capabilities. - Updated TUITextField and TUIMenu to support new onEnter callbacks. - Added connection methods for new widgets in TUIConnect.h.
1 parent fce5908 commit a79b638

17 files changed

Lines changed: 770 additions & 13 deletions

CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ set(TUIKIT_HEADERS
8282
include/tuikit/widgets/TUIForm.h
8383
include/tuikit/widgets/TUIStatusBar.h
8484
include/tuikit/widgets/TUIToolbar.h
85+
include/tuikit/widgets/TUISpinBox.h
86+
include/tuikit/widgets/TUIDoubleSpinBox.h
87+
include/tuikit/widgets/TUIListView.h
88+
include/tuikit/widgets/TUITableView.h
8589
# Add other headers as they are created
8690
)
8791

@@ -115,6 +119,10 @@ set(TUIKIT_SOURCES
115119
src/widgets/TUITreeView.cpp
116120
src/widgets/Notification.cpp
117121
src/core/TUIKLoader.cpp
122+
src/widgets/TUISpinBox.cpp
123+
src/widgets/TUIDoubleSpinBox.cpp
124+
src/widgets/TUIListView.cpp
125+
src/widgets/TUITableView.cpp
118126
# Add other source files as they are created
119127
)
120128

README.md

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,29 @@ The following core components are implemented and functional:
2323

2424
* `TUIApp`: The entry point for the application.
2525
* `TUIWidget`: Base class for all UI components.
26-
* `TUILabel`: Displays static text.
27-
* `TUITextField`: Editable single-line text input.
2826
* `TUIButton`: Interactive button with click events and icon support.
29-
* `TUIMenu`: Vertical list of selectable options.
3027
* `TUICheckBox`: Simple toggle checkbox.
31-
* `TUIRadioBox`: Group of exclusive radio buttons.
28+
* `TUICollapsible`: A collapsible container for widgets.
3229
* `TUIComboBox`: Dropdown list for selection.
33-
* `TUISlider`: Horizontal slider for continuous value selection.
34-
* `TUIToolbar`: A bar for action buttons.
30+
* `TUIDoubleSpinBox`: Spin box for double-precision floating-point values.
3531
* `TUIForm`: Organizes input fields with labels.
3632
* `TUIGroupBox`: Groups related widgets with an optional title and border.
37-
* `TUITabWidget`: Organizes content into multiple tabs.
38-
* `TUIStatusBar`: Displays status messages at the bottom of the application.
39-
* `TUITreeView`: Displays hierarchical data in a tree structure.
33+
* `TUILabel`: Displays static text.
34+
* `TUIListView`: A simple list of selectable string items.
35+
* `TUIMenu`: Vertical list of selectable options.
36+
* `TUIProgressBar`: A widget to show progress.
37+
* `TUIRadioBox`: Group of exclusive radio buttons.
4038
* `TUIResizableSplit`: Splitter for resizable panels (horizontal/vertical).
4139
* `TUIScrollableContainer`: Scrollable area for any widget (with scrollbar, keyboard and mouse support).
40+
* `TUISlider`: Horizontal slider for continuous value selection.
41+
* `TUISpinBox`: Spin box for integer values.
42+
* `TUIStatusBar`: Displays status messages at the bottom of the application.
43+
* `TUITableView`: A widget for displaying data in a table.
44+
* `TUITabWidget`: Organizes content into multiple tabs.
45+
* `TUITextArea`: A multi-line text editing widget.
46+
* `TUITextField`: Editable single-line text input.
47+
* `TUIToolbar`: A bar for action buttons.
48+
* `TUITreeView`: Displays hierarchical data in a tree structure.
4249

4350
## 🛠️ Getting Started
4451

examples/example_1.cpp

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
using namespace TUIKIT;
77

8+
// All comments and text are now in English.
9+
810
class AppSlots {
911
public:
1012
AppSlots(TUIApp& app, Label& button_label, Label& checkbox_label)
@@ -174,7 +176,46 @@ int main() {
174176
toolbar_tab_content->addWidget(groupbox("Application Toolbar", toolbar_widget));
175177

176178
// --- Advanced Widgets Tab Content ---
177-
auto advanced_widgets_content = vbox();
179+
// Left side: SpinBox, ListView, TreeView, Split, Scrollable, TUITableView, spinbox, doublespinbox
180+
// Vertical layout: left/right with stretch
181+
auto left_advanced_group = vbox();
182+
// Vertical layout: top/bottom with stretch
183+
auto right_advanced_group = vbox();
184+
// Horizontal layout: left/right with stretch
185+
auto advanced_widgets_content = hbox();
186+
187+
// SpinBox and DoubleSpinBox Example
188+
auto spin_box_group = vbox();
189+
auto spin_box_label = label("SpinBox Value: 50");
190+
auto spin_box = spinbox("Spin", 50, 0, 100, 1);
191+
spin_box->setValue(50);
192+
connect(spin_box, [&](int value) {
193+
spin_box_label->setText("SpinBox Value: " + std::to_string(value));
194+
});
195+
auto double_spin_box_label = label("DoubleSpinBox Value: 5.0");
196+
auto double_spin_box = doublespinbox("Double", 5.0, 0.0, 10.0, 0.5);
197+
connect(double_spin_box, [&](double value) {
198+
double_spin_box_label->setText("DoubleSpinBox Value: " + std::to_string(value));
199+
});
200+
spin_box_group->addWidget(spin_box);
201+
spin_box_group->addWidget(spin_box_label);
202+
spin_box_group->addWidget(double_spin_box);
203+
spin_box_group->addWidget(double_spin_box_label);
204+
right_advanced_group->addWidget(groupbox("Spin Boxes", spin_box_group));
205+
206+
// TUIListView Example
207+
auto list_view_group = vbox();
208+
std::vector<std::string> list_items = {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5"};
209+
auto list_view = listview(list_items);
210+
auto list_view_label = label("Selected List Item: None");
211+
connect(list_view, [&](int selected_index) {
212+
if (selected_index >= 0 && (size_t)selected_index < list_items.size()) {
213+
list_view_label->setText("Selected List Item: " + list_items[selected_index]);
214+
}
215+
});
216+
list_view_group->addWidget(list_view);
217+
list_view_group->addWidget(list_view_label);
218+
left_advanced_group->addWidget(groupbox("List View", list_view_group));
178219

179220
// TUITreeView Example
180221
TreeNode root_tree_node = {"Root", {
@@ -193,7 +234,7 @@ int main() {
193234
auto tree_view_group = vbox();
194235
tree_view_group->addWidget(tree_view);
195236
tree_view_group->addWidget(tree_view_label);
196-
advanced_widgets_content->addWidget(groupbox("Tree View", tree_view_group));
237+
left_advanced_group->addWidget(groupbox("Tree View", tree_view_group));
197238

198239
// TUIResizableSplit Example
199240
auto left_panel = label("Left Panel");
@@ -216,7 +257,29 @@ int main() {
216257
auto scrollable_group = vbox();
217258
scrollable_group->addWidget(scrollable_container_widget);
218259
scrollable_group->addWidget(scroll_selected_label);
219-
advanced_widgets_content->addWidget(groupbox("Scrollable Container", scrollable_group));
260+
left_advanced_group->addWidget(groupbox("Scrollable Container", scrollable_group));
261+
262+
// Right side: TableView
263+
auto table_view_group = vbox();
264+
std::vector<std::string> table_headers = {"Name", "Age ", "City "};
265+
std::vector<std::vector<std::string>> table_data = {
266+
{"John Doe", "30", "New York"},
267+
{"Jane Smith", "25", "London"},
268+
{"Sam Green", "35", "Paris"}
269+
};
270+
auto table_view = tableview(table_headers, table_data);
271+
auto table_view_label = label("Selected Table Cell: None");
272+
connect(table_view, [&](int row, int col) {
273+
if (row >= 0 && col >= 0) {
274+
table_view_label->setText("Selected Table Cell: (Row: " + std::to_string(row) + ", Col: " + std::to_string(col) + ")");
275+
}
276+
});
277+
table_view_group->addWidget(table_view);
278+
table_view_group->addWidget(table_view_label);
279+
right_advanced_group->addWidget(groupbox("Table View", table_view_group));
280+
281+
advanced_widgets_content->addWidget(left_advanced_group);
282+
advanced_widgets_content->addWidget(right_advanced_group);
220283

221284
// --- Tab Widget ---
222285
auto tab_widget = tabwidget();

include/tuikit.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@
2727
#include "tuikit/widgets/TUITextArea.h"
2828
#include "tuikit/widgets/TUIProgressBar.h"
2929
#include "tuikit/widgets/TUIScrollableContainer.h"
30+
#include "tuikit/widgets/TUIDoubleSpinBox.h"
31+
#include "tuikit/widgets/TUISpinBox.h"
32+
#include "tuikit/widgets/TUITableView.h"
33+
#include "tuikit/widgets/TUIListView.h"
3034
#include "tuikit/core/TUIConnect.h"
3135

3236
#include "tuikit/core/TUIIcons.h"
@@ -47,17 +51,21 @@ namespace TUIKIT {
4751
using CheckBox = std::shared_ptr<TUICheckBox>;
4852
using Collapsible = std::shared_ptr<TUICollapsible>;
4953
using ComboBox = std::shared_ptr<TUIComboBox>;
54+
using DoubleSpinBox = std::shared_ptr<TUIDoubleSpinBox>;
5055
using Form = std::shared_ptr<TUIForm>;
5156
using GroupBox = std::shared_ptr<TUIGroupBox>;
5257
using Label = std::shared_ptr<TUILabel>;
58+
using ListView = std::shared_ptr<TUIListView>;
5359
using Menu = std::shared_ptr<TUIMenu>;
5460
using ProgressBar = std::shared_ptr<TUIProgressBar>;
5561
using RadioBox = std::shared_ptr<TUIRadioBox>;
5662
using ResizableSplit = std::shared_ptr<TUIResizableSplit>;
5763
using ScrollableContainer = std::shared_ptr<TUIScrollableContainer>;
5864
using Slider = std::shared_ptr<TUISlider>;
65+
using SpinBox = std::shared_ptr<TUISpinBox>;
5966
using StatusBar = std::shared_ptr<TUIStatusBar>;
6067
using TabWidget = std::shared_ptr<TUITabWidget>;
68+
using TableView = std::shared_ptr<TUITableView>;
6169
using TextArea = std::shared_ptr<TUITextArea>;
6270
using TextField = std::shared_ptr<TUITextField>;
6371
using Toolbar = std::shared_ptr<TUIToolbar>;
@@ -85,6 +93,10 @@ namespace TUIKIT {
8593
return std::make_shared<TUIComboBox>(options, initial_selected);
8694
}
8795

96+
inline DoubleSpinBox doublespinbox(const std::string& label, double initial_value, double min_value, double max_value, double increment) {
97+
return std::make_shared<TUIDoubleSpinBox>(label, initial_value, min_value, max_value, increment);
98+
}
99+
88100
inline Form form() {
89101
return std::make_shared<TUIForm>();
90102
}
@@ -97,6 +109,10 @@ namespace TUIKIT {
97109
return std::make_shared<TUILabel>(text);
98110
}
99111

112+
inline ListView listview(const std::vector<std::string>& items) {
113+
return std::make_shared<TUIListView>(items);
114+
}
115+
100116
inline Menu menu(const std::vector<std::string>& options) {
101117
return std::make_shared<TUIMenu>(options);
102118
}
@@ -121,6 +137,10 @@ namespace TUIKIT {
121137
return std::make_shared<TUISlider>(label, initial_value, min_value, max_value, increment);
122138
}
123139

140+
inline SpinBox spinbox(const std::string& label, int initial_value, int min_value = 0, int max_value = 100, int increment = 1) {
141+
return std::make_shared<TUISpinBox>(label, initial_value, min_value, max_value, increment);
142+
}
143+
124144
inline StatusBar statusbar(const std::string& message = "") {
125145
return std::make_shared<TUIStatusBar>(message);
126146
}
@@ -129,6 +149,10 @@ namespace TUIKIT {
129149
return std::make_shared<TUITabWidget>();
130150
}
131151

152+
inline TableView tableview(const std::vector<std::string>& headers = {}, const std::vector<std::vector<std::string>>& data = {}) {
153+
return std::make_shared<TUITableView>(headers, data);
154+
}
155+
132156
inline TextArea textarea(const std::string& placeholder = "", const std::string& label = "", int height = 5) {
133157
return std::make_shared<TUITextArea>(placeholder, label, height);
134158
}

include/tuikit/core/TUIConnect.h

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
#include "tuikit/widgets/TUIComboBox.h"
1010
#include "tuikit/widgets/TUIRadioBox.h"
1111
#include "tuikit/widgets/TUIMenu.h"
12+
#include "tuikit/widgets/TUITreeView.h"
13+
#include "tuikit/widgets/TUISpinBox.h"
14+
#include "tuikit/widgets/TUIDoubleSpinBox.h"
15+
#include "tuikit/widgets/TUIListView.h"
16+
#include "tuikit/widgets/TUITableView.h"
1217

1318
namespace TUIKIT {
1419

@@ -52,6 +57,16 @@ void connect(std::shared_ptr<TUITextField> sender, Object* receiver, void (Objec
5257
sender->onChange([receiver, slot](const std::string& value) { (receiver->*slot)(value); });
5358
}
5459

60+
// TUITextField: onEnter() -> void()
61+
inline void connect(std::shared_ptr<TUITextField> sender, std::function<void()> slot) {
62+
sender->onEnter(std::move(slot));
63+
}
64+
65+
template <typename Object>
66+
void connect(std::shared_ptr<TUITextField> sender, Object* receiver, void (Object::*slot)()) {
67+
sender->onEnter([receiver, slot]() { (receiver->*slot)(); });
68+
}
69+
5570
// TUIComboBox: onSelect(int) -> void(int)
5671
inline void connect(std::shared_ptr<TUIComboBox> sender, std::function<void(int)> slot) {
5772
sender->onSelect(std::move(slot));
@@ -82,4 +97,104 @@ void connect(std::shared_ptr<TUIMenu> sender, Object* receiver, void (Object::*s
8297
sender->onSelect([receiver, slot](int value) { (receiver->*slot)(value); });
8398
}
8499

100+
// TUIMenu: onEnter(int) -> void(int)
101+
inline void connectOnEnter(std::shared_ptr<TUIMenu> sender, std::function<void(int)> slot) {
102+
sender->onEnter(std::move(slot));
103+
}
104+
105+
template <typename Object>
106+
void connectOnEnter(std::shared_ptr<TUIMenu> sender, Object* receiver, void (Object::*slot)(int)) {
107+
sender->onEnter([receiver, slot](int value) { (receiver->*slot)(value); });
108+
}
109+
110+
// TUITreeView: onSelect(const std::string&) -> void(const std::string&)
111+
inline void connect(std::shared_ptr<TUITreeView> sender, std::function<void(const std::string&)> slot) {
112+
sender->onSelect(std::move(slot));
113+
}
114+
115+
template <typename Object>
116+
void connect(std::shared_ptr<TUITreeView> sender, Object* receiver, void (Object::*slot)(const std::string&)) {
117+
sender->onSelect([receiver, slot](const std::string& value) { (receiver->*slot)(value); });
118+
}
119+
120+
// TUISpinBox: onChange(int) -> void(int)
121+
inline void connect(std::shared_ptr<TUISpinBox> sender, std::function<void(int)> slot) {
122+
sender->onChange(std::move(slot));
123+
}
124+
125+
template <typename Object>
126+
void connect(std::shared_ptr<TUISpinBox> sender, Object* receiver, void (Object::*slot)(int)) {
127+
sender->onChange([receiver, slot](int value) { (receiver->*slot)(value); });
128+
}
129+
130+
// TUISpinBox: onEnter() -> void()
131+
inline void connect(std::shared_ptr<TUISpinBox> sender, std::function<void()> slot) {
132+
sender->onEnter(std::move(slot));
133+
}
134+
135+
template <typename Object>
136+
void connect(std::shared_ptr<TUISpinBox> sender, Object* receiver, void (Object::*slot)()) {
137+
sender->onEnter([receiver, slot]() { (receiver->*slot)(); });
138+
}
139+
140+
// TUIDoubleSpinBox: onChange(double) -> void(double)
141+
inline void connect(std::shared_ptr<TUIDoubleSpinBox> sender, std::function<void(double)> slot) {
142+
sender->onChange(std::move(slot));
143+
}
144+
145+
template <typename Object>
146+
void connect(std::shared_ptr<TUIDoubleSpinBox> sender, Object* receiver, void (Object::*slot)(double)) {
147+
sender->onChange([receiver, slot](double value) { (receiver->*slot)(value); });
148+
}
149+
150+
// TUIDoubleSpinBox: onEnter() -> void()
151+
inline void connect(std::shared_ptr<TUIDoubleSpinBox> sender, std::function<void()> slot) {
152+
sender->onEnter(std::move(slot));
153+
}
154+
155+
template <typename Object>
156+
void connect(std::shared_ptr<TUIDoubleSpinBox> sender, Object* receiver, void (Object::*slot)()) {
157+
sender->onEnter([receiver, slot]() { (receiver->*slot)(); });
158+
}
159+
160+
// TUIListView: onSelect(int) -> void(int)
161+
inline void connect(std::shared_ptr<TUIListView> sender, std::function<void(int)> slot) {
162+
sender->onSelect(std::move(slot));
163+
}
164+
165+
template <typename Object>
166+
void connect(std::shared_ptr<TUIListView> sender, Object* receiver, void (Object::*slot)(int)) {
167+
sender->onSelect([receiver, slot](int value) { (receiver->*slot)(value); });
168+
}
169+
170+
// TUIListView: onEnter(int) -> void(int)
171+
inline void connectOnEnter(std::shared_ptr<TUIListView> sender, std::function<void(int)> slot) {
172+
sender->onEnter(std::move(slot));
173+
}
174+
175+
template <typename Object>
176+
void connectOnEnter(std::shared_ptr<TUIListView> sender, Object* receiver, void (Object::*slot)(int)) {
177+
sender->onEnter([receiver, slot](int value) { (receiver->*slot)(value); });
178+
}
179+
180+
// TUITableView: onSelect(int, int) -> void(int, int)
181+
inline void connect(std::shared_ptr<TUITableView> sender, std::function<void(int, int)> slot) {
182+
sender->onSelect(std::move(slot));
183+
}
184+
185+
template <typename Object>
186+
void connect(std::shared_ptr<TUITableView> sender, Object* receiver, void (Object::*slot)(int, int)) {
187+
sender->onSelect([receiver, slot](int row, int col) { (receiver->*slot)(row, col); });
188+
}
189+
190+
// TUITableView: onEnter(int, int) -> void(int, int)
191+
inline void connectOnEnter(std::shared_ptr<TUITableView> sender, std::function<void(int, int)> slot) {
192+
sender->onEnter(std::move(slot));
193+
}
194+
195+
template <typename Object>
196+
void connectOnEnter(std::shared_ptr<TUITableView> sender, Object* receiver, void (Object::*slot)(int, int)) {
197+
sender->onEnter([receiver, slot](int row, int col) { (receiver->*slot)(row, col); });
198+
}
199+
85200
} // namespace TUIKIT

0 commit comments

Comments
 (0)