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_move const & e) override;
|
||||||
bool on_event(mouse_click 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()>;
|
using on_click_callback = std::function<void()>;
|
||||||
|
|
||||||
void on_click(on_click_callback callback)
|
void on_click(on_click_callback callback)
|
||||||
|
|
@ -22,6 +27,9 @@ namespace psemek::ui
|
||||||
callback_ = std::move(callback);
|
callback_ = std::move(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void set_repeat(float wait, float period);
|
||||||
|
virtual void set_no_repeat();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
enum class state_t
|
enum class state_t
|
||||||
{
|
{
|
||||||
|
|
@ -33,11 +41,29 @@ namespace psemek::ui
|
||||||
virtual state_t state() const { return state_; }
|
virtual state_t state() const { return state_; }
|
||||||
|
|
||||||
virtual void on_state_changed(state_t old);
|
virtual void on_state_changed(state_t old);
|
||||||
|
virtual void post_on_click();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
state_t state_ = state_t::normal;
|
state_t state_ = state_t::normal;
|
||||||
|
|
||||||
on_click_callback callback_;
|
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)
|
if (e.down)
|
||||||
{
|
{
|
||||||
state_ = state_t::mousedown;
|
state_ = state_t::mousedown;
|
||||||
if (callback_)
|
post_on_click();
|
||||||
post(callback_);
|
|
||||||
on_state_changed(state_t::mouseover);
|
on_state_changed(state_t::mouseover);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -60,12 +59,85 @@ namespace psemek::ui
|
||||||
return false;
|
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)
|
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)
|
if (state() == state_t::mousedown || old == state_t::mousedown)
|
||||||
{
|
{
|
||||||
post_reshape();
|
post_reshape();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void button::post_on_click()
|
||||||
|
{
|
||||||
|
if (callback_)
|
||||||
|
post(callback_);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue