diff --git a/client/SDL/dialogs/sdl_button.cpp b/client/SDL/dialogs/sdl_button.cpp index a3c5e529b..9c253e6c0 100644 --- a/client/SDL/dialogs/sdl_button.cpp +++ b/client/SDL/dialogs/sdl_button.cpp @@ -24,6 +24,7 @@ static const SDL_Color buttonbackgroundcolor = { 0x69, 0x66, 0x63, 0xff }; static const SDL_Color buttonhighlightcolor = { 0xcd, 0xca, 0x35, 0x60 }; +static const SDL_Color buttonmouseovercolor = { 0x66, 0xff, 0x66, 0x60 }; static const SDL_Color buttonfontcolor = { 0xd1, 0xcf, 0xcd, 0xff }; SdlButton::SdlButton(SDL_Renderer* renderer, const std::string& label, int id, const SDL_Rect& rect) @@ -53,6 +54,14 @@ bool SdlButton::highlight(SDL_Renderer* renderer) return update_text(renderer, _name, buttonfontcolor); } +bool SdlButton::mouseover(SDL_Renderer* renderer) +{ + std::vector colors = { buttonbackgroundcolor, buttonmouseovercolor }; + if (!fill(renderer, colors)) + return false; + return update_text(renderer, _name, buttonfontcolor); +} + bool SdlButton::update(SDL_Renderer* renderer) { assert(renderer); diff --git a/client/SDL/dialogs/sdl_button.hpp b/client/SDL/dialogs/sdl_button.hpp index e96bce955..4b97ecf25 100644 --- a/client/SDL/dialogs/sdl_button.hpp +++ b/client/SDL/dialogs/sdl_button.hpp @@ -12,6 +12,7 @@ class SdlButton : public SdlWidget virtual ~SdlButton() override; bool highlight(SDL_Renderer* renderer); + bool mouseover(SDL_Renderer* renderer); bool update(SDL_Renderer* renderer); int id() const; diff --git a/client/SDL/dialogs/sdl_buttons.cpp b/client/SDL/dialogs/sdl_buttons.cpp index 124ab72bb..77d89e583 100644 --- a/client/SDL/dialogs/sdl_buttons.cpp +++ b/client/SDL/dialogs/sdl_buttons.cpp @@ -1,4 +1,5 @@ #include +#include #include "sdl_buttons.hpp" @@ -9,8 +10,8 @@ SdlButtonList::SdlButtonList() } bool SdlButtonList::populate(SDL_Renderer* renderer, const std::vector& labels, - const std::vector& ids, Sint32 offsetY, Sint32 width, - Sint32 height) + const std::vector& ids, Sint32 total_width, Sint32 offsetY, + Sint32 width, Sint32 height) { assert(renderer); assert(width >= 0); @@ -18,10 +19,12 @@ bool SdlButtonList::populate(SDL_Renderer* renderer, const std::vector(total_width, button_width); for (size_t x = 0; x < ids.size(); x++) { - const size_t offsetX = x * (static_cast(width) + hpadding); - const SDL_Rect rect = { static_cast(offsetX), offsetY, width, height }; + const size_t curOffsetX = offsetX + x * (static_cast(width) + hpadding); + const SDL_Rect rect = { static_cast(curOffsetX), offsetY, width, height }; _list.push_back({ renderer, labels[x], ids[x], rect }); } return true; @@ -36,6 +39,11 @@ SdlButton* SdlButtonList::get_selected(const SDL_MouseButtonEvent& button) const Sint32 x = button.x; const Sint32 y = button.y; + return get_selected(x, y); +} + +SdlButton* SdlButtonList::get_selected(Sint32 x, Sint32 y) +{ for (auto& btn : _list) { auto r = btn.rect(); @@ -45,9 +53,45 @@ SdlButton* SdlButtonList::get_selected(const SDL_MouseButtonEvent& button) return nullptr; } +bool SdlButtonList::set_highlight_next(bool reset) +{ + if (reset) + _highlighted = nullptr; + else + { + auto next = _highlight_index++; + _highlight_index %= _list.size(); + auto& element = _list[next]; + _highlighted = &element; + } + return true; +} + +bool SdlButtonList::set_highlight(size_t index) +{ + if (index >= _list.size()) + { + _highlighted = nullptr; + return false; + } + auto& element = _list[index]; + _highlighted = &element; + _highlight_index = ++index % _list.size(); + return true; +} + +bool SdlButtonList::set_mouseover(Sint32 x, Sint32 y) +{ + _mouseover = get_selected(x, y); + return _mouseover != nullptr; +} + void SdlButtonList::clear() { _list.clear(); + _mouseover = nullptr; + _highlighted = nullptr; + _highlight_index = 0; } bool SdlButtonList::update(SDL_Renderer* renderer) @@ -59,5 +103,11 @@ bool SdlButtonList::update(SDL_Renderer* renderer) if (!btn.update(renderer)) return false; } + + if (_highlighted) + _highlighted->highlight(renderer); + + if (_mouseover) + _mouseover->mouseover(renderer); return true; } diff --git a/client/SDL/dialogs/sdl_buttons.hpp b/client/SDL/dialogs/sdl_buttons.hpp index 6f48f36e5..271b6f884 100644 --- a/client/SDL/dialogs/sdl_buttons.hpp +++ b/client/SDL/dialogs/sdl_buttons.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include "sdl_button.hpp" @@ -11,10 +12,16 @@ class SdlButtonList virtual ~SdlButtonList(); bool populate(SDL_Renderer* renderer, const std::vector& labels, - const std::vector& ids, Sint32 offsetY, Sint32 width, Sint32 heigth); + const std::vector& ids, Sint32 total_width, Sint32 offsetY, Sint32 width, + Sint32 heigth); bool update(SDL_Renderer* renderer); SdlButton* get_selected(const SDL_MouseButtonEvent& button); + SdlButton* get_selected(Sint32 x, Sint32 y); + + bool set_highlight_next(bool reset = false); + bool set_highlight(size_t index); + bool set_mouseover(Sint32 x, Sint32 y); void clear(); @@ -24,4 +31,7 @@ class SdlButtonList private: std::vector _list; + SdlButton* _highlighted = nullptr; + size_t _highlight_index = 0; + SdlButton* _mouseover = nullptr; }; diff --git a/client/SDL/dialogs/sdl_input_widgets.cpp b/client/SDL/dialogs/sdl_input_widgets.cpp index 0ec81bf3b..ac9b3bdca 100644 --- a/client/SDL/dialogs/sdl_input_widgets.cpp +++ b/client/SDL/dialogs/sdl_input_widgets.cpp @@ -22,8 +22,9 @@ SdlInputWidgetList::SdlInputWidgetList(const std::string& title, const size_t total_width = widget_width + widget_width; const size_t input_height = labels.size() * (widget_heigth + vpadding) + vpadding; const size_t total_height = input_height + widget_heigth; - _window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, - total_width, total_height, 0); + _window = SDL_CreateWindow( + title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, total_width, total_height, + SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_INPUT_FOCUS); if (_window == nullptr) { widget_log_error(-1, "SDL_CreateWindow"); @@ -42,9 +43,10 @@ SdlInputWidgetList::SdlInputWidgetList(const std::string& title, _list.push_back( { _renderer, labels[x], initial[x], flags[x], x, widget_width, widget_heigth }); - _buttons.populate(_renderer, buttonlabels, buttonids, static_cast(input_height), - static_cast(widget_width), + _buttons.populate(_renderer, buttonlabels, buttonids, total_width, + static_cast(input_height), static_cast(widget_width), static_cast(widget_heigth)); + _buttons.set_highlight(0); } } } @@ -234,12 +236,7 @@ int SdlInputWidgetList::run(std::vector& result) throw; } - auto button = _buttons.get_selected(event.button); - if (button) - { - if (!button->highlight(_renderer)) - throw; - } + _buttons.set_mouseover(event.button.x, event.button.y); } break; case SDL_MOUSEBUTTONDOWN: diff --git a/client/SDL/dialogs/sdl_selectlist.cpp b/client/SDL/dialogs/sdl_selectlist.cpp index 34643dd2c..e27d7f3c5 100644 --- a/client/SDL/dialogs/sdl_selectlist.cpp +++ b/client/SDL/dialogs/sdl_selectlist.cpp @@ -10,7 +10,9 @@ SdlSelectList::SdlSelectList(const std::string& title, const std::vector buttonids = { INPUT_BUTTON_ACCEPT, INPUT_BUTTON_CANCEL }; const std::vector buttonlabels = { "accept", "cancel" }; - _buttons.populate(_renderer, buttonlabels, buttonids, static_cast(total_height), - static_cast(widget_width / 2), - static_cast(widget_height)); + _buttons.populate( + _renderer, buttonlabels, buttonids, widget_width, static_cast(total_height), + static_cast(widget_width / 2), static_cast(widget_height)); + _buttons.set_highlight(0); } } } @@ -116,12 +119,7 @@ int SdlSelectList::run() throw; } - auto button = _buttons.get_selected(event.button); - if (button) - { - if (!button->highlight(_renderer)) - throw; - } + _buttons.set_mouseover(event.button.x, event.button.y); } break; case SDL_MOUSEBUTTONDOWN: