Add default scroller implementation

This commit is contained in:
Nikita Lisitsa 2023-01-05 04:54:01 +03:00
parent 874d4bd5c8
commit 361ef9fd7a
2 changed files with 61 additions and 16 deletions

View file

@ -946,6 +946,58 @@ namespace psemek::ui
button * dec_button_;
};
struct scroller_impl
: scroller
{
void draw(struct painter & painter) const override
{
auto st = merged_own_style();
auto draw_box = [&](geom::box<float, 2> box, state_t state, float position, int dimension)
{
float h = height();
box[dimension].max -= h;
float origin = geom::lerp(box[dimension], position);
box[dimension] = {origin, origin + h};
gfx::color_rgba color;
if (state == state_t::normal)
color = *st->fg_color;
else if (state == state_t::mouseover)
color = *st->highlight_color;
else
{
color = *st->action_color;
box += geom::cast<float>(*st->action_offset);
}
if (*st->shadow_offset != geom::vector{0, 0})
painter.draw_rect(box + geom::cast<float>(*st->shadow_offset), *st->shadow_color);
painter.draw_rect(box, color);
};
if (horizontal_scroll())
draw_box(horizontal_box(), horizontal_state_, position(direction::horizontal), 0);
if (vertical_scroll())
draw_box(vertical_box(), vertical_state_, position(direction::vertical), 1);
scroller::draw(painter);
}
protected:
float width() const override
{
return 10.f;
}
float height() const
{
return 50.f;
}
};
struct selector_impl
: selector
{
@ -1083,7 +1135,7 @@ namespace psemek::ui
std::shared_ptr<scroller> default_element_factory::make_scroller()
{
return std::make_shared<scroller>();
return std::make_shared<scroller_impl>();
}
std::shared_ptr<selector> default_element_factory::make_selector()

View file

@ -48,15 +48,8 @@ namespace psemek::ui
if (!child_)
return false;
auto sc = child_->size_constraints();
float c = geom::unlerp<float>(box[0], e.position[0]);
c = geom::clamp(c, {0.f, 1.f});
auto old = shift_tgt_;
shift_tgt_[0] = shape_.box[0].length() / 2.f - c * sc[0].min;
clamp_shift();
on_scroll(shift_tgt_ - old);
set_position(direction::horizontal, geom::clamp(c, {0.f, 1.f}), true);
}
break;
}
@ -82,15 +75,9 @@ namespace psemek::ui
if (!child_)
return false;
auto sc = child_->size_constraints();
float c = geom::unlerp<float>(box[1], e.position[1]);
c = geom::clamp(c, {0.f, 1.f});
auto old = shift_tgt_;
shift_tgt_[1] = shape_.box[1].length() / 2.f - c * sc[1].min;
clamp_shift();
on_scroll(shift_tgt_ - old);
set_position(direction::vertical, geom::clamp(c, {0.f, 1.f}), true);
}
break;
}
@ -317,6 +304,8 @@ namespace psemek::ui
if (dir == direction::vertical && !vertical_scroll())
return;
auto old_shift = shift_tgt_;
int dim = (dir == direction::horizontal) ? 0 : 1;
auto child_box = child_->shape().bbox();
@ -329,8 +318,12 @@ namespace psemek::ui
child_area[0] -= width() * *st->scale;
shift_tgt_[dim] = position * (child_area[dim] - child_box[dim].length());
clamp_shift();
if (!animate)
shift_[dim] = shift_tgt_[dim];
on_scroll(shift_tgt_ - old_shift);
}
void scroller::update(float dt)