152 lines
2.6 KiB
C++
152 lines
2.6 KiB
C++
#include <psemek/ui/button.hpp>
|
|
|
|
namespace psemek::ui
|
|
{
|
|
|
|
label * button::label() const
|
|
{
|
|
return dynamic_cast<struct label *>(child().get());
|
|
}
|
|
|
|
image_view * button::icon() const
|
|
{
|
|
return dynamic_cast<struct image_view *>(child().get());
|
|
}
|
|
|
|
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;
|
|
post_on_click();
|
|
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::update(float dt)
|
|
{
|
|
if (repeat_)
|
|
{
|
|
repeat_->timer += dt;
|
|
|
|
switch (repeat_->state)
|
|
{
|
|
case repeat::state_t::idle:
|
|
break;
|
|
case repeat::state_t::wait:
|
|
if (repeat_->timer >= repeat_->wait)
|
|
{
|
|
repeat_->timer -= repeat_->wait;
|
|
repeat_->state = repeat::state_t::repeat;
|
|
post_on_click();
|
|
}
|
|
break;
|
|
case repeat::state_t::repeat:
|
|
if (repeat_->timer >= repeat_->period)
|
|
{
|
|
repeat_->timer -= repeat_->period;
|
|
repeat_->state = repeat::state_t::repeat;
|
|
post_on_click();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void button::set_enabled(bool value)
|
|
{
|
|
element::set_enabled(value);
|
|
if (!value && repeat_)
|
|
repeat_->state = repeat::state_t::idle;
|
|
}
|
|
|
|
void button::set_hidden(bool value)
|
|
{
|
|
element::set_hidden(value);
|
|
if (value && repeat_)
|
|
repeat_->state = repeat::state_t::idle;
|
|
}
|
|
|
|
void button::set_repeat(float wait, float period)
|
|
{
|
|
repeat_ = repeat{wait, period};
|
|
}
|
|
|
|
void button::set_no_repeat()
|
|
{
|
|
repeat_ = std::nullopt;
|
|
}
|
|
|
|
void button::on_state_changed(state_t old)
|
|
{
|
|
if (repeat_)
|
|
{
|
|
if (state() == state_t::mousedown)
|
|
{
|
|
repeat_->timer = 0.f;
|
|
repeat_->state = repeat::state_t::wait;
|
|
}
|
|
else
|
|
{
|
|
repeat_->state = repeat::state_t::idle;
|
|
}
|
|
}
|
|
|
|
if (state() == state_t::mousedown || old == state_t::mousedown)
|
|
{
|
|
post_reshape();
|
|
}
|
|
}
|
|
|
|
void button::post_on_click()
|
|
{
|
|
if (callback_)
|
|
post(callback_);
|
|
}
|
|
|
|
}
|