Support ui::button repeating callback when kept pressed
This commit is contained in:
parent
35c26f1167
commit
e8a5ecfa3b
2 changed files with 100 additions and 2 deletions
|
|
@ -15,6 +15,11 @@ namespace psemek::ui
|
|||
bool on_event(mouse_move const & e) override;
|
||||
bool on_event(mouse_click const & e) override;
|
||||
|
||||
void update(float dt) override;
|
||||
|
||||
void set_enabled(bool value);
|
||||
void set_hidden(bool value);
|
||||
|
||||
using on_click_callback = std::function<void()>;
|
||||
|
||||
void on_click(on_click_callback callback)
|
||||
|
|
@ -22,6 +27,9 @@ namespace psemek::ui
|
|||
callback_ = std::move(callback);
|
||||
}
|
||||
|
||||
virtual void set_repeat(float wait, float period);
|
||||
virtual void set_no_repeat();
|
||||
|
||||
protected:
|
||||
enum class state_t
|
||||
{
|
||||
|
|
@ -33,11 +41,29 @@ namespace psemek::ui
|
|||
virtual state_t state() const { return state_; }
|
||||
|
||||
virtual void on_state_changed(state_t old);
|
||||
virtual void post_on_click();
|
||||
|
||||
private:
|
||||
state_t state_ = state_t::normal;
|
||||
|
||||
on_click_callback callback_;
|
||||
|
||||
struct repeat
|
||||
{
|
||||
float wait;
|
||||
float period;
|
||||
|
||||
enum class state_t
|
||||
{
|
||||
idle,
|
||||
wait,
|
||||
repeat,
|
||||
} state = state_t::idle;
|
||||
|
||||
float timer = 0.f;
|
||||
};
|
||||
|
||||
std::optional<repeat> repeat_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,8 +41,7 @@ namespace psemek::ui
|
|||
if (e.down)
|
||||
{
|
||||
state_ = state_t::mousedown;
|
||||
if (callback_)
|
||||
post(callback_);
|
||||
post_on_click();
|
||||
on_state_changed(state_t::mouseover);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -60,12 +59,85 @@ namespace psemek::ui
|
|||
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_);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue