107 lines
2 KiB
C++
107 lines
2 KiB
C++
#include <psemek/ui/button.hpp>
|
|
|
|
namespace psemek::ui
|
|
{
|
|
|
|
element::children_range button::children() const
|
|
{
|
|
return children_range{children_};
|
|
}
|
|
|
|
bool button::on_event(mouse_move const & e)
|
|
{
|
|
bool const over = shape().contains(geom::cast<float>(e.position));
|
|
|
|
switch (state_) {
|
|
case state_t::normal:
|
|
if (over)
|
|
{
|
|
state_ = state_t::mouseover;
|
|
on_state_changed(state_t::normal);
|
|
}
|
|
break;
|
|
case state_t::mouseover:
|
|
case state_t::mousedown:
|
|
if (!over)
|
|
{
|
|
auto old = state_;
|
|
state_ = state_t::normal;
|
|
on_state_changed(old);
|
|
}
|
|
break;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool button::on_event(mouse_click const & e)
|
|
{
|
|
if (e.button != mouse_button::left) return false;
|
|
|
|
switch (state_) {
|
|
case state_t::normal:
|
|
break;
|
|
case state_t::mouseover:
|
|
if (e.down)
|
|
{
|
|
state_ = state_t::mousedown;
|
|
if (callback_)
|
|
post(callback_);
|
|
on_state_changed(state_t::mouseover);
|
|
return true;
|
|
}
|
|
break;
|
|
case state_t::mousedown:
|
|
if (!e.down)
|
|
{
|
|
state_ = state_t::mouseover;
|
|
on_state_changed(state_t::mousedown);
|
|
return true;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void button::on_state_changed(state_t old)
|
|
{
|
|
auto s = merged_style();
|
|
|
|
if (state() == state_t::mousedown)
|
|
{
|
|
for (auto c : children())
|
|
if (c) c->reshape(c->shape().bbox() + geom::cast<float>(*s->action_offset));
|
|
}
|
|
else if (old == state_t::mousedown)
|
|
{
|
|
for (auto c : children())
|
|
if (c) c->reshape(c->shape().bbox() - geom::cast<float>(*s->action_offset));
|
|
}
|
|
}
|
|
|
|
void button::set_label(std::shared_ptr<struct label> label)
|
|
{
|
|
if (icon())
|
|
set_icon(nullptr);
|
|
|
|
if (label_) label_->set_parent(nullptr);
|
|
|
|
label_ = std::move(label);
|
|
children_[0] = label_.get();
|
|
if (label_) label_->set_parent(this);
|
|
}
|
|
|
|
void button::set_icon(std::shared_ptr<image_view> icon)
|
|
{
|
|
if (label())
|
|
set_label(nullptr);
|
|
|
|
if (icon_) icon_->set_parent(nullptr);
|
|
|
|
icon_ = std::move(icon);
|
|
children_[0] = icon_.get();
|
|
if (icon_) icon_->set_parent(this);
|
|
}
|
|
|
|
}
|