Refactor ui::edit state & support focusing

This commit is contained in:
Nikita Lisitsa 2022-04-08 14:49:44 +03:00
parent bd6d0f9f93
commit e445b42724
2 changed files with 47 additions and 57 deletions

View file

@ -57,6 +57,9 @@ namespace psemek::ui
bool on_event(key_press const & e) override; bool on_event(key_press const & e) override;
bool on_event(text_input const & e) override; bool on_event(text_input const & e) override;
bool focused() const override;
virtual bool editing() const;
struct shape const & shape() const override { return shape_; } struct shape const & shape() const override { return shape_; }
void reshape(geom::box<float, 2> const & bbox) override; void reshape(geom::box<float, 2> const & bbox) override;
@ -70,15 +73,6 @@ namespace psemek::ui
protected: protected:
enum class state_t
{
normal,
mouseover,
editing,
};
state_t state() const { return state_; }
void set_text_shape(geom::box<float, 2> const & box); void set_text_shape(geom::box<float, 2> const & box);
private: private:
@ -87,6 +81,9 @@ namespace psemek::ui
halignment halign_ = halignment::left; halignment halign_ = halignment::left;
valignment valign_ = valignment::top; valignment valign_ = valignment::top;
bool editing_ = false;
bool mouseover_ = false;
std::size_t caret_ = 0; std::size_t caret_ = 0;
float caret_blink_period_ = 0.5f; float caret_blink_period_ = 0.5f;
float caret_blink_timer_ = 0.f; float caret_blink_timer_ = 0.f;
@ -95,8 +92,6 @@ namespace psemek::ui
box_shape shape_; box_shape shape_;
geom::box<float, 2> text_box_; geom::box<float, 2> text_box_;
state_t state_ = state_t::normal;
validator_type validator_; validator_type validator_;
callback_type on_text_entered_; callback_type on_text_entered_;

View file

@ -90,32 +90,13 @@ namespace psemek::ui
bool edit::on_event(mouse_move const & e) bool edit::on_event(mouse_move const & e)
{ {
bool const mouseover = shape_.contains(geom::cast<float>(e.position)); bool new_mouseover = shape_.contains(geom::cast<float>(e.position));
if (!mouseover_ && new_mouseover)
switch (state_) sdl2::set_cursor(sdl2::cursor_type::beam);
{ else if (mouseover_ && !new_mouseover)
case state_t::normal: sdl2::set_cursor(sdl2::cursor_type::arrow);
if (mouseover)
{
state_ = state_t::mouseover;
sdl2::set_cursor(sdl2::cursor_type::beam);
}
break;
case state_t::mouseover:
if (!mouseover)
{
state_ = state_t::normal;
sdl2::set_cursor(sdl2::cursor_type::arrow);
}
break;
case state_t::editing:
if (mouseover)
sdl2::set_cursor(sdl2::cursor_type::beam);
else
sdl2::set_cursor(sdl2::cursor_type::arrow);
break;
}
mouseover_ = new_mouseover;
return false; return false;
} }
@ -123,22 +104,25 @@ namespace psemek::ui
{ {
if (e.button == mouse_button::left && e.down) if (e.button == mouse_button::left && e.down)
{ {
switch (state_) if (mouseover_)
{ {
case state_t::normal: if (!editing_)
return false; {
case state_t::mouseover: editing_ = true;
state_ = state_t::editing;
if (!in_text_input())
start_text_input(); start_text_input();
reset_caret(); reset_caret();
}
return true; return true;
case state_t::editing: }
state_ = state_t::normal; else
if (in_text_input()) {
if (editing_)
{
editing_ = false;
stop_text_input(); stop_text_input();
reset_caret(); reset_caret();
return true; post_text_entered();
}
} }
} }
@ -147,7 +131,7 @@ namespace psemek::ui
bool edit::on_event(key_press const & e) bool edit::on_event(key_press const & e)
{ {
if (e.down && state_ == state_t::editing) if (e.down && editing_)
{ {
if (e.key == SDLK_LEFT) if (e.key == SDLK_LEFT)
{ {
@ -175,11 +159,13 @@ namespace psemek::ui
} }
else if (e.key == SDLK_RETURN || e.key == SDLK_ESCAPE) else if (e.key == SDLK_RETURN || e.key == SDLK_ESCAPE)
{ {
state_ = state_t::normal; if (editing_)
if (in_text_input()) {
editing_ = false;
stop_text_input(); stop_text_input();
reset_caret(); reset_caret();
post_text_entered(); post_text_entered();
}
} }
else if (e.key == SDLK_BACKSPACE) else if (e.key == SDLK_BACKSPACE)
{ {
@ -210,7 +196,7 @@ namespace psemek::ui
bool edit::on_event(text_input const & e) bool edit::on_event(text_input const & e)
{ {
if (state_ == state_t::editing) if (editing_)
{ {
auto new_text = text_; auto new_text = text_;
auto range = util::utf8_range(e.text); auto range = util::utf8_range(e.text);
@ -223,6 +209,16 @@ namespace psemek::ui
return false; return false;
} }
bool edit::focused() const
{
return editing_;
}
bool edit::editing() const
{
return editing_;
}
void edit::reshape(geom::box<float, 2> const & bbox) void edit::reshape(geom::box<float, 2> const & bbox)
{ {
shape_.box = bbox; shape_.box = bbox;
@ -235,7 +231,6 @@ namespace psemek::ui
static float const inf = std::numeric_limits<float>::infinity(); static float const inf = std::numeric_limits<float>::infinity();
auto st = merged_own_style(); auto st = merged_own_style();
return {{{0.f, inf}, {1.f * st->font->size()[1] * (*st->scale), inf}}}; return {{{0.f, inf}, {1.f * st->font->size()[1] * (*st->scale), inf}}};
} }
@ -247,7 +242,7 @@ namespace psemek::ui
void edit::update(float dt) void edit::update(float dt)
{ {
if (state_ == state_t::editing) if (editing_)
{ {
caret_blink_timer_ += dt; caret_blink_timer_ += dt;
if (caret_blink_timer_ >= caret_blink_period_) if (caret_blink_timer_ >= caret_blink_period_)
@ -359,7 +354,7 @@ namespace psemek::ui
void edit::reset_caret() void edit::reset_caret()
{ {
caret_visible_ = (state_ == state_t::editing); caret_visible_ = editing_;
caret_blink_timer_ = 0.f; caret_blink_timer_ = 0.f;
} }