Skip to content

Commit 40dfda7

Browse files
committed
draft: flickable list
1 parent 00ff110 commit 40dfda7

File tree

6 files changed

+146
-15
lines changed

6 files changed

+146
-15
lines changed

src/ruis/widget/base/touch/flickable.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,6 @@ ruis::event_status flickable::on_mouse_move(const mouse_move_event& event)
178178
.pointer_id = this->cur_pointer_id}
179179
);
180180
}
181-
182-
this->flickable_scroll_by(-delta);
183181
}
184182
}
185183
return event_status::consumed;

src/ruis/widget/group/list.cpp

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -353,77 +353,96 @@ void list::notify_scroll_pos_changed(size_t old_index, real old_offset)
353353
}
354354
}
355355

356-
void list::scroll_by(real delta)
356+
real list::scroll_by(real delta)
357357
{
358358
size_t old_index = this->pos_index;
359359
real old_offset = this->pos_offset;
360360

361+
// list's longitudinal direction index
361362
unsigned long_index = this->get_long_index();
362363

363-
// TRACE(<< "delta = " << delta << std::endl)
364+
real scrolled_by = 0;
364365

365366
if (delta >= 0) {
366367
for (auto& c : this->children()) {
367368
auto wd = c.get().rect().d[long_index] - this->pos_offset;
368369
if (wd > delta) {
369370
this->pos_offset += delta;
370371
delta -= wd;
372+
scrolled_by += delta;
371373
break;
372374
}
373375

374376
delta -= wd;
377+
scrolled_by += wd;
375378
this->pos_offset = 0;
376379
++this->pos_index;
377380
}
378381

379382
if (delta > 0) {
380-
ASSERT(this->pos_index > this->added_index + this->children().size(), [&](auto& o) {
381-
o << "this->pos_index = " << this->pos_index << " this->added_index = " << this->added_index
382-
<< " this->children().size() = " << this->children().size();
383-
})
383+
utki::assert(
384+
this->pos_index > this->added_index + this->children().size(),
385+
[&](auto& o) {
386+
o << "this->pos_index = " << this->pos_index << " this->added_index = " << this->added_index
387+
<< " this->children().size() = " << this->children().size();
388+
},
389+
SL
390+
);
384391
for (; this->pos_index < this->first_tail_item_index;) {
385392
auto w = this->get_provider().get_widget(this->pos_index);
386393
vec2 d = dims_for_widget(w.get(), this->rect().d);
387-
this->push_back(w); // this is just optimization, to avoid creating same widget twice
394+
395+
// this is just optimization, to avoid creating same widget twice
396+
this->push_back(std::move(w));
397+
388398
if (d[long_index] > delta) {
389399
this->pos_offset = delta;
390400
break;
391401
}
392402
delta -= d[long_index];
393-
ASSERT(this->pos_offset == 0)
403+
scrolled_by += d[long_index];
404+
utki::assert(this->pos_offset == 0, SL);
394405
++this->pos_index;
395406
}
396407
}
397408
} else {
398409
delta = -delta;
399410
if (delta <= this->pos_offset) {
400411
this->pos_offset -= delta;
412+
scrolled_by -= delta;
401413
} else {
402-
ASSERT(this->added_index == this->pos_index)
414+
utki::assert(this->added_index == this->pos_index, SL);
403415
delta -= this->pos_offset;
416+
scrolled_by -= this->pos_offset;
404417
this->pos_offset = 0;
405418
for (; this->pos_index > 0;) {
406-
ASSERT(this->added_index == this->pos_index)
419+
utki::assert(this->added_index == this->pos_index, SL);
407420
--this->pos_index;
408421
auto w = this->get_provider().get_widget(this->pos_index);
409422
vec2 d = dims_for_widget(w.get(), this->rect().d);
423+
424+
// this is just optimization, to avoid creating same widget twice
410425
this->insert(
411-
w,
426+
std::move(w), //
412427
this->children().begin()
413-
); // this is just optimization, to avoid creating same widget twice
428+
);
429+
414430
--this->added_index;
415431
if (d[long_index] > delta) {
416432
this->pos_offset = d[long_index] - delta;
417433
break;
418434
}
419435
delta -= d[long_index];
436+
scrolled_by -= d[long_index];
420437
}
421438
}
422439
}
423440

424441
this->update_children_list();
425442

426443
this->notify_scroll_pos_changed(old_index, old_offset);
444+
445+
return scrolled_by;
427446
}
428447

429448
ruis::vec2 list::measure(const ruis::vec2& quotum) const

src/ruis/widget/group/list.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,9 @@ class list :
126126
/**
127127
* @brief Scroll the list by given number of pixels.
128128
* @param delta - number of pixels to scroll, can be positive or negative.
129+
* @return number of pixels actually scrolled by.
129130
*/
130-
void scroll_by(real delta);
131+
real scroll_by(real delta);
131132

132133
/**
133134
* @brief Model change signal.
@@ -152,6 +153,10 @@ class list :
152153
return this->children();
153154
}
154155

156+
protected:
157+
using container::on_mouse_move;
158+
using container::on_mouse_button;
159+
155160
private:
156161
void update_children_list();
157162

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
ruis - GUI framework
3+
4+
Copyright (C) 2012-2026 Ivan Gagis <igagis@gmail.com>
5+
6+
This program is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
This program is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
/* ================ LICENSE END ================ */
21+
22+
#include "list.hpp"
23+
24+
using namespace ruis::touch;
25+
26+
ruis::event_status list::on_mouse_button(const mouse_button_event& event)
27+
{
28+
return this->flickable::on_mouse_button(event);
29+
}
30+
31+
ruis::event_status list::on_mouse_move(const mouse_move_event& event)
32+
{
33+
return this->flickable::on_mouse_move(event);
34+
}
35+
36+
ruis::event_status list::flickable_on_mouse_button(const mouse_button_event& event)
37+
{
38+
return this->ruis::list::on_mouse_button(event);
39+
}
40+
41+
ruis::event_status list::flickable_on_mouse_move(const mouse_move_event& event)
42+
{
43+
return this->ruis::list::on_mouse_move(event);
44+
}
45+
46+
ruis::vec2 list::flickable_scroll_by(const vec2& delta)
47+
{
48+
if (this->is_vertical()) {
49+
return vec2(0, this->scroll_by(delta.y()));
50+
} else {
51+
return vec2(this->scroll_by(delta.x()), 0);
52+
}
53+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
ruis - GUI framework
3+
4+
Copyright (C) 2012-2026 Ivan Gagis <igagis@gmail.com>
5+
6+
This program is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
This program is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
/* ================ LICENSE END ================ */
21+
22+
#pragma once
23+
24+
#include "../../base/touch/flickable.hpp"
25+
#include "../list.hpp"
26+
27+
namespace ruis::touch {
28+
29+
class list :
30+
public ruis::list, //
31+
private flickable
32+
{
33+
public:
34+
list(
35+
utki::shared_ref<ruis::context> context, //
36+
all_parameters params
37+
);
38+
39+
event_status on_mouse_button(const mouse_button_event& event) override;
40+
event_status on_mouse_move(const mouse_move_event& event) override;
41+
42+
private:
43+
event_status flickable_on_mouse_button(const mouse_button_event& event) override;
44+
event_status flickable_on_mouse_move(const mouse_move_event& event) override;
45+
vec2 flickable_scroll_by(const vec2& delta) override;
46+
};
47+
48+
namespace make {
49+
// TODO: add list() factory
50+
} // namespace make
51+
52+
} // namespace ruis::touch

src/ruis/widget/group/touch/scroll_area.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,8 @@ class scroll_area :
4646
vec2 flickable_scroll_by(const vec2& delta) override;
4747
};
4848

49+
namespace make {
50+
// TDOO: add scroll_area() factory
51+
} // namespace make
52+
4953
} // namespace ruis::touch

0 commit comments

Comments
 (0)