Add default scroller implementation
This commit is contained in:
parent
874d4bd5c8
commit
361ef9fd7a
2 changed files with 61 additions and 16 deletions
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue