Skip to content

Commit 03f9bbc

Browse files
committed
add scroll bar to table_list test app
1 parent 27d36fe commit 03f9bbc

File tree

5 files changed

+192
-46
lines changed

5 files changed

+192
-46
lines changed

src/ruis/widget/base/fraction_widget.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
2323

2424
using namespace ruis;
2525

26-
void fraction_widget::set_fraction(real fraction, bool notify_change)
26+
void fraction_widget::set_fraction(
27+
real fraction, //
28+
bool notify_change
29+
)
2730
{
2831
using std::min;
2932
using std::max;

src/ruis/widget/group/list.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ class list :
8282

8383
ruis::vector2 measure(const ruis::vector2& quotum) const override;
8484

85+
void on_reload() override;
86+
8587
/**
8688
* @brief Set scroll position as factor from [0:1].
8789
* @param factor - factor of the scroll position to set.
@@ -131,8 +133,6 @@ class list :
131133
*/
132134
void scroll_by(real delta);
133135

134-
void on_reload() override;
135-
136136
/**
137137
* @brief Model change signal.
138138
* Emitted when list widget contents have actually been updated due to change in provider's model data set.

src/ruis/widget/group/table_list.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ table_list::table_list(
102102
.dims = {ruis::dim::fill, ruis::dim::fill},
103103
.weight = 1
104104
},
105+
.widget_params{
106+
.clip = true
107+
},
105108
.list_providable_params{
106109
.provider = [&]() -> utki::shared_ref<list_provider> {
107110
return utki::make_shared<internal::provider>(
@@ -151,6 +154,28 @@ table_list::table_list(
151154
this->arrange_list_item_cells(c->children());
152155
}
153156
};
157+
158+
this->table_rows_list.get().model_change_handler = [this](auto& l) {
159+
this->notify_model_changed();
160+
};
161+
162+
this->table_rows_list.get().scroll_change_handler = [this](auto& l) {
163+
this->notify_scroll_changed();
164+
};
165+
}
166+
167+
void table_list::notify_model_changed()
168+
{
169+
if (this->model_change_handler) {
170+
this->model_change_handler(*this);
171+
}
172+
}
173+
174+
void table_list::notify_scroll_changed()
175+
{
176+
if (this->scroll_change_handler) {
177+
this->scroll_change_handler(*this);
178+
}
154179
}
155180

156181
void table_list::arrange_list_item_cells(ruis::semiconst_widget_list& cells)

src/ruis/widget/group/table_list.hpp

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,82 @@ class table_list :
9595
all_parameters params
9696
);
9797

98+
/**
99+
* @brief Set scroll position as factor from [0:1].
100+
* @param factor - factor of the scroll position to set.
101+
* @param notify_change - whether to invoke the scroll change handler.
102+
*/
103+
void set_scroll_factor(
104+
real factor, //
105+
bool notify_scroll_change = true
106+
)
107+
{
108+
this->table_rows_list.get().set_scroll_factor(
109+
factor, //
110+
notify_scroll_change
111+
);
112+
}
113+
114+
/**
115+
* @brief Get scroll factor.
116+
* @return Current scroll position as factor from [0:1].
117+
*/
118+
real get_scroll_factor() const noexcept
119+
{
120+
return this->table_rows_list.get().get_scroll_factor();
121+
}
122+
123+
/**
124+
* @brief Get scroll band.
125+
* Returns scroll band as a fraction of 1. This is basically the number of visible elements divided by total number
126+
* of elements in the list.
127+
* @return scroll band.
128+
*/
129+
real get_scroll_band() const noexcept
130+
{
131+
return this->table_rows_list.get().get_scroll_band();
132+
}
133+
134+
/**
135+
* @brief Get index of the first visible item.
136+
* @return index of the first visible item.
137+
*/
138+
size_t get_pos_index() const noexcept
139+
{
140+
return this->table_rows_list.get().get_pos_index();
141+
}
142+
143+
/**
144+
* @brief Get offset of the first visible item.
145+
* The value is positive, though the item coordinate is <= 0.
146+
* @return offset in pixels of the first visible item.
147+
*/
148+
real get_pos_offset() const noexcept
149+
{
150+
return this->table_rows_list.get().get_pos_offset();
151+
}
152+
153+
/**
154+
* @brief Scroll the list by given number of pixels.
155+
* @param delta - number of pixels to scroll, can be positive or negative.
156+
*/
157+
void scroll_by(real delta)
158+
{
159+
this->table_rows_list.get().scroll_by(delta);
160+
}
161+
162+
/**
163+
* @brief Model change signal.
164+
* Emitted when list widget contents have actually been updated due to change in provider's model data set.
165+
*/
166+
std::function<void(table_list&)> model_change_handler;
167+
168+
/**
169+
* @brief Scroll position changed signal.
170+
* Emitted when list's scroll position has changed.
171+
*/
172+
std::function<void(table_list&)> scroll_change_handler;
173+
98174
private:
99175
table_list(
100176
utki::shared_ref<tiling_area> ta, //
@@ -104,6 +180,10 @@ class table_list :
104180

105181
void arrange_list_item_cells(ruis::semiconst_widget_list& cells);
106182

183+
void notify_model_changed();
184+
185+
void notify_scroll_changed();
186+
107187
utki::shared_ref<tiling_area> headers_tiling_area;
108188
utki::shared_ref<list> table_rows_list;
109189
};

tests/app2/src/table_list_window.cpp

Lines changed: 81 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <ruis/widget/group/table_list.hpp>
44
#include <ruis/widget/group/window.hpp>
55
#include <ruis/widget/label/rectangle.hpp>
6+
#include <ruis/widget/slider/scroll_bar.hpp>
67

78
#include "table_tree_view_window.hpp"
89

@@ -75,6 +76,83 @@ utki::shared_ref<ruis::widget> make_table_list_window(
7576
)
7677
{
7778
// clang-format off
79+
auto table_list = m::table_list(c,
80+
{
81+
.layout_params{
82+
.dims = {ruis::dim::fill, ruis::dim::fill},
83+
.weight = 1
84+
},
85+
.table_list_params{
86+
.column_headers = {
87+
make_table_list_header(c, U"col 1"s),
88+
make_table_list_header(c, U"col 2"s),
89+
make_table_list_header(c, U"col 3"s)
90+
},
91+
.provider = [&](){
92+
class provider : public ruis::table_list::provider{
93+
public:
94+
provider(utki::shared_ref<ruis::context> context) :
95+
ruis::table_list::provider(std::move(context))
96+
{}
97+
98+
size_t count() const noexcept override{
99+
return list_data.size();
100+
}
101+
102+
ruis::widget_list get_row_widgets(size_t index) override{
103+
ruis::widget_list ret;
104+
105+
for(auto i = 0; i != 3; ++i){
106+
ret.emplace_back(
107+
m::text(
108+
this->context,//
109+
{.widget_params{.clip = true}},
110+
utki::to_utf32(list_data[index].children[i].value.string)
111+
)
112+
);
113+
}
114+
return ret;
115+
}
116+
};
117+
return utki::make_shared<provider>(c);
118+
}()
119+
}
120+
}
121+
);
122+
123+
auto scroll_bar = m::scroll_bar(c,
124+
{
125+
.layout_params{
126+
.dims = {ruis::dim::min, ruis::dim::fill}
127+
}
128+
}
129+
);
130+
131+
scroll_bar.get().fraction_change_handler =
132+
[table_list_weak = utki::make_weak(table_list)]
133+
(ruis::fraction_widget& sb)
134+
{
135+
if(auto l = table_list_weak.lock()){
136+
l->set_scroll_factor(
137+
sb.get_fraction(),
138+
false // no notify
139+
);
140+
}
141+
};
142+
143+
table_list.get().scroll_change_handler =
144+
[scroll_bar_weak = utki::make_weak(scroll_bar)]
145+
(ruis::table_list& tl)
146+
{
147+
if(auto sb = scroll_bar_weak.lock()){
148+
sb->set_fraction(
149+
tl.get_scroll_factor(),
150+
false // no notify
151+
);
152+
sb->set_band_fraction(tl.get_scroll_band());
153+
}
154+
};
155+
78156
return m::window(c,
79157
{
80158
.widget_params = {
@@ -90,53 +168,13 @@ utki::shared_ref<ruis::widget> make_table_list_window(
90168
}
91169
},
92170
.container_params = {
93-
.layout = ruis::layout::pile
171+
.layout = ruis::layout::row
94172
},
95173
.title = c.get().localization.get().get("table_list"sv)
96174
},
97175
{
98-
m::table_list(c,
99-
{
100-
.layout_params{
101-
.dims = {ruis::dim::fill, ruis::dim::fill}
102-
},
103-
.table_list_params{
104-
.column_headers = {
105-
make_table_list_header(c, U"col 1"s),
106-
make_table_list_header(c, U"col 2"s),
107-
make_table_list_header(c, U"col 3"s)
108-
},
109-
.provider = [&](){
110-
class provider : public ruis::table_list::provider{
111-
public:
112-
provider(utki::shared_ref<ruis::context> context) :
113-
ruis::table_list::provider(std::move(context))
114-
{}
115-
116-
size_t count() const noexcept override{
117-
return list_data.size();
118-
}
119-
120-
ruis::widget_list get_row_widgets(size_t index) override{
121-
ruis::widget_list ret;
122-
123-
for(auto i = 0; i != 3; ++i){
124-
ret.emplace_back(
125-
m::text(
126-
this->context,//
127-
{.widget_params{.clip = true}},
128-
utki::to_utf32(list_data[index].children[i].value.string)
129-
)
130-
);
131-
}
132-
return ret;
133-
}
134-
};
135-
return utki::make_shared<provider>(c);
136-
}()
137-
}
138-
}
139-
)
176+
std::move(table_list),
177+
std::move(scroll_bar)
140178
}
141179
);
142180
// clang-format on

0 commit comments

Comments
 (0)