[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 buttonbackgroundcolor = { 0x69, 0x66, 0x63, 0xff };
|
||||||
static const SDL_Color buttonhighlightcolor = { 0xcd, 0xca, 0x35, 0x60 };
|
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 };
|
static const SDL_Color buttonfontcolor = { 0xd1, 0xcf, 0xcd, 0xff };
|
||||||
|
|
||||||
SdlButton::SdlButton(SDL_Renderer* renderer, const std::string& label, int id, const SDL_Rect& rect)
|
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);
|
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)
|
bool SdlButton::update(SDL_Renderer* renderer)
|
||||||
{
|
{
|
||||||
assert(renderer);
|
assert(renderer);
|
||||||
|
@ -12,6 +12,7 @@ class SdlButton : public SdlWidget
|
|||||||
virtual ~SdlButton() override;
|
virtual ~SdlButton() override;
|
||||||
|
|
||||||
bool highlight(SDL_Renderer* renderer);
|
bool highlight(SDL_Renderer* renderer);
|
||||||
|
bool mouseover(SDL_Renderer* renderer);
|
||||||
bool update(SDL_Renderer* renderer);
|
bool update(SDL_Renderer* renderer);
|
||||||
|
|
||||||
int id() const;
|
int id() const;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "sdl_buttons.hpp"
|
#include "sdl_buttons.hpp"
|
||||||
|
|
||||||
@ -9,8 +10,8 @@ SdlButtonList::SdlButtonList()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool SdlButtonList::populate(SDL_Renderer* renderer, const std::vector<std::string>& labels,
|
bool SdlButtonList::populate(SDL_Renderer* renderer, const std::vector<std::string>& labels,
|
||||||
const std::vector<int>& ids, Sint32 offsetY, Sint32 width,
|
const std::vector<int>& ids, Sint32 total_width, Sint32 offsetY,
|
||||||
Sint32 height)
|
Sint32 width, Sint32 height)
|
||||||
{
|
{
|
||||||
assert(renderer);
|
assert(renderer);
|
||||||
assert(width >= 0);
|
assert(width >= 0);
|
||||||
@ -18,10 +19,12 @@ bool SdlButtonList::populate(SDL_Renderer* renderer, const std::vector<std::stri
|
|||||||
assert(labels.size() == ids.size());
|
assert(labels.size() == ids.size());
|
||||||
|
|
||||||
_list.clear();
|
_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++)
|
for (size_t x = 0; x < ids.size(); x++)
|
||||||
{
|
{
|
||||||
const size_t offsetX = x * (static_cast<size_t>(width) + hpadding);
|
const size_t curOffsetX = offsetX + x * (static_cast<size_t>(width) + hpadding);
|
||||||
const SDL_Rect rect = { static_cast<int>(offsetX), offsetY, width, height };
|
const SDL_Rect rect = { static_cast<int>(curOffsetX), offsetY, width, height };
|
||||||
_list.push_back({ renderer, labels[x], ids[x], rect });
|
_list.push_back({ renderer, labels[x], ids[x], rect });
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -36,6 +39,11 @@ SdlButton* SdlButtonList::get_selected(const SDL_MouseButtonEvent& button)
|
|||||||
const Sint32 x = button.x;
|
const Sint32 x = button.x;
|
||||||
const Sint32 y = button.y;
|
const Sint32 y = button.y;
|
||||||
|
|
||||||
|
return get_selected(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
SdlButton* SdlButtonList::get_selected(Sint32 x, Sint32 y)
|
||||||
|
{
|
||||||
for (auto& btn : _list)
|
for (auto& btn : _list)
|
||||||
{
|
{
|
||||||
auto r = btn.rect();
|
auto r = btn.rect();
|
||||||
@ -45,9 +53,45 @@ SdlButton* SdlButtonList::get_selected(const SDL_MouseButtonEvent& button)
|
|||||||
return nullptr;
|
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()
|
void SdlButtonList::clear()
|
||||||
{
|
{
|
||||||
_list.clear();
|
_list.clear();
|
||||||
|
_mouseover = nullptr;
|
||||||
|
_highlighted = nullptr;
|
||||||
|
_highlight_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SdlButtonList::update(SDL_Renderer* renderer)
|
bool SdlButtonList::update(SDL_Renderer* renderer)
|
||||||
@ -59,5 +103,11 @@ bool SdlButtonList::update(SDL_Renderer* renderer)
|
|||||||
if (!btn.update(renderer))
|
if (!btn.update(renderer))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_highlighted)
|
||||||
|
_highlighted->highlight(renderer);
|
||||||
|
|
||||||
|
if (_mouseover)
|
||||||
|
_mouseover->mouseover(renderer);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "sdl_button.hpp"
|
#include "sdl_button.hpp"
|
||||||
|
|
||||||
@ -11,10 +12,16 @@ class SdlButtonList
|
|||||||
virtual ~SdlButtonList();
|
virtual ~SdlButtonList();
|
||||||
|
|
||||||
bool populate(SDL_Renderer* renderer, const std::vector<std::string>& labels,
|
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);
|
bool update(SDL_Renderer* renderer);
|
||||||
SdlButton* get_selected(const SDL_MouseButtonEvent& button);
|
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();
|
void clear();
|
||||||
|
|
||||||
@ -24,4 +31,7 @@ class SdlButtonList
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<SdlButton> _list;
|
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 total_width = widget_width + widget_width;
|
||||||
const size_t input_height = labels.size() * (widget_heigth + vpadding) + vpadding;
|
const size_t input_height = labels.size() * (widget_heigth + vpadding) + vpadding;
|
||||||
const size_t total_height = input_height + widget_heigth;
|
const size_t total_height = input_height + widget_heigth;
|
||||||
_window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
_window = SDL_CreateWindow(
|
||||||
total_width, total_height, 0);
|
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)
|
if (_window == nullptr)
|
||||||
{
|
{
|
||||||
widget_log_error(-1, "SDL_CreateWindow");
|
widget_log_error(-1, "SDL_CreateWindow");
|
||||||
@ -42,9 +43,10 @@ SdlInputWidgetList::SdlInputWidgetList(const std::string& title,
|
|||||||
_list.push_back(
|
_list.push_back(
|
||||||
{ _renderer, labels[x], initial[x], flags[x], x, widget_width, widget_heigth });
|
{ _renderer, labels[x], initial[x], flags[x], x, widget_width, widget_heigth });
|
||||||
|
|
||||||
_buttons.populate(_renderer, buttonlabels, buttonids, static_cast<Sint32>(input_height),
|
_buttons.populate(_renderer, buttonlabels, buttonids, total_width,
|
||||||
static_cast<Sint32>(widget_width),
|
static_cast<Sint32>(input_height), static_cast<Sint32>(widget_width),
|
||||||
static_cast<Sint32>(widget_heigth));
|
static_cast<Sint32>(widget_heigth));
|
||||||
|
_buttons.set_highlight(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -234,12 +236,7 @@ int SdlInputWidgetList::run(std::vector<std::string>& result)
|
|||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto button = _buttons.get_selected(event.button);
|
_buttons.set_mouseover(event.button.x, event.button.y);
|
||||||
if (button)
|
|
||||||
{
|
|
||||||
if (!button->highlight(_renderer))
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_MOUSEBUTTONDOWN:
|
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;
|
const size_t total_height = labels.size() * (widget_height + vpadding) + vpadding;
|
||||||
_window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
_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)
|
if (_window == nullptr)
|
||||||
{
|
{
|
||||||
widget_log_error(-1, "SDL_CreateWindow");
|
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<int> buttonids = { INPUT_BUTTON_ACCEPT, INPUT_BUTTON_CANCEL };
|
||||||
const std::vector<std::string> buttonlabels = { "accept", "cancel" };
|
const std::vector<std::string> buttonlabels = { "accept", "cancel" };
|
||||||
_buttons.populate(_renderer, buttonlabels, buttonids, static_cast<Sint32>(total_height),
|
_buttons.populate(
|
||||||
static_cast<Sint32>(widget_width / 2),
|
_renderer, buttonlabels, buttonids, widget_width, static_cast<Sint32>(total_height),
|
||||||
static_cast<Sint32>(widget_height));
|
static_cast<Sint32>(widget_width / 2), static_cast<Sint32>(widget_height));
|
||||||
|
_buttons.set_highlight(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,12 +119,7 @@ int SdlSelectList::run()
|
|||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto button = _buttons.get_selected(event.button);
|
_buttons.set_mouseover(event.button.x, event.button.y);
|
||||||
if (button)
|
|
||||||
{
|
|
||||||
if (!button->highlight(_renderer))
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_MOUSEBUTTONDOWN:
|
case SDL_MOUSEBUTTONDOWN:
|
||||||
|
Loading…
Reference in New Issue
Block a user