[client,sdl] improve dialog button highlighting
move state to buttons or button list
This commit is contained in:
parent
e6384c06c2
commit
a8eaf2a38d
@ -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<SDL_Color> colors = { buttonbackgroundcolor, buttonmouseovercolor };
|
||||
if (!fill(renderer, colors))
|
||||
return false;
|
||||
return update_text(renderer, _name, buttonfontcolor);
|
||||
}
|
||||
|
||||
bool SdlButton::update(SDL_Renderer* renderer)
|
||||
{
|
||||
assert(renderer);
|
||||
|
@ -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;
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <assert.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "sdl_buttons.hpp"
|
||||
|
||||
@ -9,8 +10,8 @@ SdlButtonList::SdlButtonList()
|
||||
}
|
||||
|
||||
bool SdlButtonList::populate(SDL_Renderer* renderer, const std::vector<std::string>& labels,
|
||||
const std::vector<int>& ids, Sint32 offsetY, Sint32 width,
|
||||
Sint32 height)
|
||||
const std::vector<int>& 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<std::stri
|
||||
assert(labels.size() == ids.size());
|
||||
|
||||
_list.clear();
|
||||
size_t button_width = ids.size() * (width + hpadding) + hpadding;
|
||||
size_t offsetX = total_width - std::min<size_t>(total_width, button_width);
|
||||
for (size_t x = 0; x < ids.size(); x++)
|
||||
{
|
||||
const size_t offsetX = x * (static_cast<size_t>(width) + hpadding);
|
||||
const SDL_Rect rect = { static_cast<int>(offsetX), offsetY, width, height };
|
||||
const size_t curOffsetX = offsetX + x * (static_cast<size_t>(width) + hpadding);
|
||||
const SDL_Rect rect = { static_cast<int>(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;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "sdl_button.hpp"
|
||||
|
||||
@ -11,10 +12,16 @@ class SdlButtonList
|
||||
virtual ~SdlButtonList();
|
||||
|
||||
bool populate(SDL_Renderer* renderer, const std::vector<std::string>& labels,
|
||||
const std::vector<int>& ids, Sint32 offsetY, Sint32 width, Sint32 heigth);
|
||||
const std::vector<int>& 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<SdlButton> _list;
|
||||
SdlButton* _highlighted = nullptr;
|
||||
size_t _highlight_index = 0;
|
||||
SdlButton* _mouseover = nullptr;
|
||||
};
|
||||
|
@ -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<Sint32>(input_height),
|
||||
static_cast<Sint32>(widget_width),
|
||||
_buttons.populate(_renderer, buttonlabels, buttonids, total_width,
|
||||
static_cast<Sint32>(input_height), static_cast<Sint32>(widget_width),
|
||||
static_cast<Sint32>(widget_heigth));
|
||||
_buttons.set_highlight(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -234,12 +236,7 @@ int SdlInputWidgetList::run(std::vector<std::string>& 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:
|
||||
|
@ -10,7 +10,9 @@ SdlSelectList::SdlSelectList(const std::string& title, const std::vector<std::st
|
||||
|
||||
const size_t total_height = labels.size() * (widget_height + vpadding) + vpadding;
|
||||
_window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||
widget_width, total_height + widget_height, 0);
|
||||
widget_width, total_height + widget_height,
|
||||
SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_MOUSE_FOCUS |
|
||||
SDL_WINDOW_INPUT_FOCUS);
|
||||
if (_window == nullptr)
|
||||
{
|
||||
widget_log_error(-1, "SDL_CreateWindow");
|
||||
@ -33,9 +35,10 @@ SdlSelectList::SdlSelectList(const std::string& title, const std::vector<std::st
|
||||
|
||||
const std::vector<int> buttonids = { INPUT_BUTTON_ACCEPT, INPUT_BUTTON_CANCEL };
|
||||
const std::vector<std::string> buttonlabels = { "accept", "cancel" };
|
||||
_buttons.populate(_renderer, buttonlabels, buttonids, static_cast<Sint32>(total_height),
|
||||
static_cast<Sint32>(widget_width / 2),
|
||||
static_cast<Sint32>(widget_height));
|
||||
_buttons.populate(
|
||||
_renderer, buttonlabels, buttonids, widget_width, static_cast<Sint32>(total_height),
|
||||
static_cast<Sint32>(widget_width / 2), static_cast<Sint32>(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:
|
||||
|
Loading…
Reference in New Issue
Block a user