moar Button widget wip
This commit is contained in:
parent
282497cc61
commit
cc8b231623
92
button.cpp
92
button.cpp
|
@ -1,13 +1,15 @@
|
|||
#include <iostream>
|
||||
|
||||
#include "SDL_ttf.h"
|
||||
#include "button.hpp"
|
||||
#include "widget.hpp"
|
||||
|
||||
Button::Button(SDL_Renderer* r, SDL_Rect& vp, TTF_Font* f)
|
||||
: Widget(r, vp), _font(f)
|
||||
: Widget(r, vp), _font(f), _font_height(TTF_FontHeight(f))
|
||||
{
|
||||
set_caption("");
|
||||
_update_caption_area();
|
||||
set_viewport(vp);
|
||||
}
|
||||
|
||||
Button::~Button()
|
||||
|
@ -17,11 +19,7 @@ Button::~Button()
|
|||
|
||||
void Button::handle_event(const SDL_Event& ev)
|
||||
{
|
||||
}
|
||||
|
||||
SDL_Rect Button::minimal_size() const
|
||||
{
|
||||
return _caption_size;
|
||||
Widget::handle_event(ev);
|
||||
}
|
||||
|
||||
void Button::render()
|
||||
|
@ -31,26 +29,49 @@ void Button::render()
|
|||
SDL_RenderGetViewport(_renderer, &old_vp);
|
||||
SDL_RenderSetViewport(_renderer, &_viewport);
|
||||
|
||||
for (int i = border_width; i >= 0; i--)
|
||||
SDL_Color bg_color = _hovered ? color_background_hover : color_background;
|
||||
if (_pushed)
|
||||
{
|
||||
SDL_SetRenderDrawColor(
|
||||
_renderer,
|
||||
color_background.r * 10 / (i + 11),
|
||||
color_background.g * 10 / (i + 11),
|
||||
color_background.b * 10 / (i + 11),
|
||||
color_background.a
|
||||
);
|
||||
int margin = border_width - i;
|
||||
SDL_Rect rect = {
|
||||
margin,
|
||||
margin,
|
||||
_viewport.w - margin * 2,
|
||||
_viewport.h - margin * 2
|
||||
};
|
||||
SDL_RenderFillRect(_renderer, &rect);
|
||||
for (int i = 0; i < border_width; i++)
|
||||
{
|
||||
SDL_SetRenderDrawColor(
|
||||
_renderer,
|
||||
bg_color.r * (i + 10) / 10,
|
||||
bg_color.g * (i + 10) / 10,
|
||||
bg_color.b * (i + 10) / 10,
|
||||
bg_color.a
|
||||
);
|
||||
SDL_Rect rect = {
|
||||
_padding_h + i,
|
||||
_padding_v + i,
|
||||
_widget_area.w - i * 2,
|
||||
_widget_area.h - i * 2
|
||||
};
|
||||
SDL_RenderFillRect(_renderer, &rect);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = border_width; i >= 0; i--)
|
||||
{
|
||||
SDL_SetRenderDrawColor(
|
||||
_renderer,
|
||||
bg_color.r * (i + 10) / 10,
|
||||
bg_color.g * (i + 10) / 10,
|
||||
bg_color.b * (i + 10) / 10,
|
||||
bg_color.a
|
||||
);
|
||||
int margin = border_width - i;
|
||||
SDL_Rect rect = {
|
||||
_padding_h + margin,
|
||||
_padding_v + margin,
|
||||
_widget_area.w - margin * 2,
|
||||
_widget_area.h - margin * 2
|
||||
};
|
||||
SDL_RenderFillRect(_renderer, &rect);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_RenderSetViewport(_renderer, &_caption_viewport);
|
||||
SDL_RenderCopy(_renderer, _caption_texture, NULL, &_caption_area);
|
||||
|
||||
SDL_RenderSetViewport(_renderer, &old_vp);
|
||||
|
@ -59,6 +80,7 @@ void Button::render()
|
|||
void Button::set_caption(std::string text)
|
||||
{
|
||||
_caption_text = text;
|
||||
TTF_SizeUTF8(_font, _caption_text.c_str(), &_caption_size.w, &_caption_size.h);
|
||||
_render_caption_text();
|
||||
_update_caption_area();
|
||||
}
|
||||
|
@ -66,41 +88,39 @@ void Button::set_caption(std::string text)
|
|||
void Button::set_font(TTF_Font* font)
|
||||
{
|
||||
_font = font;
|
||||
_font_height = TTF_FontHeight(_font) + 2 * border_width;
|
||||
_render_caption_text();
|
||||
}
|
||||
|
||||
void Button::set_viewport(const SDL_Rect& vp)
|
||||
void Button::set_viewport(SDL_Rect& vp)
|
||||
{
|
||||
_padding_v = vp.h / 2.0 - (
|
||||
_font_height * _caption_height_multiplicator + 2 * border_width
|
||||
) / 2.0;
|
||||
Widget::set_viewport(vp);
|
||||
_caption_viewport = {
|
||||
_viewport.x + border_width,
|
||||
_viewport.y + border_width,
|
||||
_viewport.w - 2 * border_width,
|
||||
_viewport.h - 2 * border_width
|
||||
};
|
||||
_update_caption_area();
|
||||
}
|
||||
|
||||
void Button::_render_caption_text()
|
||||
{
|
||||
if (_font == NULL)
|
||||
return;
|
||||
|
||||
SDL_Surface* surface = TTF_RenderUTF8_Blended(
|
||||
_font,
|
||||
_caption_text.c_str(),
|
||||
color_foreground);
|
||||
_caption_texture = SDL_CreateTextureFromSurface(_renderer, surface);
|
||||
SDL_FreeSurface(surface);
|
||||
TTF_SizeUTF8(_font, _caption_text.c_str(), &_caption_size.w, &_caption_size.h);
|
||||
}
|
||||
|
||||
void Button::_update_caption_area()
|
||||
{
|
||||
if (_caption_text.length() < 1)
|
||||
return;
|
||||
_caption_area = {0, 0, 0, 0};
|
||||
|
||||
int y_offset = _caption_viewport.h / 2.0 - _caption_size.h / 2.0;
|
||||
int x_offset = _caption_viewport.w / 2.0 - _caption_size.w / 2.0;
|
||||
int y_offset = _widget_area.h / 2.0 - _caption_size.h / 2.0 + _padding_v;
|
||||
int x_offset = _widget_area.w / 2.0 - _caption_size.w / 2.0 + _padding_h;
|
||||
|
||||
_caption_area = {x_offset, y_offset, _caption_size.w, _caption_size.h};
|
||||
|
||||
TTF_SizeUTF8(_font, _caption_text.c_str(), &_caption_size.w, &_caption_size.h);
|
||||
}
|
||||
|
|
12
button.hpp
12
button.hpp
|
@ -12,13 +12,13 @@
|
|||
class Button : public Widget
|
||||
{
|
||||
protected:
|
||||
SDL_Rect _caption_area = {0, 0, 0, 0};
|
||||
SDL_Rect _caption_size = {0, 0, 0, 0};
|
||||
SDL_Rect _caption_area;
|
||||
SDL_Rect _caption_size;
|
||||
std::string _caption_text;
|
||||
SDL_Texture* _caption_texture = NULL;
|
||||
SDL_Rect _caption_viewport = {0, 0, 0, 0};
|
||||
TTF_Font* _font = NULL;
|
||||
SDL_Rect _minimal_size = {0, 0, 0, 0};
|
||||
int _font_height;
|
||||
float _caption_height_multiplicator = 1.2;
|
||||
|
||||
virtual void _render_caption_text();
|
||||
virtual void _update_caption_area();
|
||||
|
@ -26,16 +26,16 @@ protected:
|
|||
public:
|
||||
int border_width = 6;
|
||||
SDL_Color color_background = {175, 175, 175, SDL_ALPHA_OPAQUE};
|
||||
SDL_Color color_background_hover = {200, 200, 200, SDL_ALPHA_OPAQUE};
|
||||
SDL_Color color_foreground = {0, 0, 0, SDL_ALPHA_OPAQUE};
|
||||
|
||||
Button(SDL_Renderer*, SDL_Rect&, TTF_Font*);
|
||||
~Button();
|
||||
virtual void handle_event(const SDL_Event&);
|
||||
virtual SDL_Rect minimal_size() const;
|
||||
virtual void render();
|
||||
virtual void set_caption(std::string);
|
||||
virtual void set_font(TTF_Font*);
|
||||
virtual void set_viewport(const SDL_Rect&);
|
||||
virtual void set_viewport(SDL_Rect&);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
66
widget.hpp
66
widget.hpp
|
@ -1,21 +1,79 @@
|
|||
#ifndef WIDGET_HPP
|
||||
#define WIDGET_HPP
|
||||
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
class Widget
|
||||
{
|
||||
protected:
|
||||
bool _hovered = false;
|
||||
bool _pushed = false;
|
||||
SDL_Renderer* _renderer;
|
||||
SDL_Rect& _viewport;
|
||||
SDL_Rect _widget_area;
|
||||
int _padding_h = 0;
|
||||
int _padding_v = 0;
|
||||
|
||||
virtual void _on_release(const SDL_MouseButtonEvent& button)
|
||||
{
|
||||
if (_pushed && click_handler != NULL)
|
||||
{
|
||||
click_handler(button);
|
||||
}
|
||||
_pushed = false;
|
||||
}
|
||||
virtual void _on_push(const SDL_MouseButtonEvent& button)
|
||||
{
|
||||
SDL_Point position = {button.x - _viewport.x, button.y - _viewport.y};
|
||||
if (SDL_PointInRect(&position, &_widget_area) == SDL_TRUE)
|
||||
{
|
||||
_pushed = true;
|
||||
}
|
||||
}
|
||||
virtual void _update_hover_state(const SDL_MouseMotionEvent& mouse)
|
||||
{
|
||||
SDL_Point position = {mouse.x - _viewport.x, mouse.y - _viewport.y};
|
||||
_hovered = SDL_PointInRect(&position, &_widget_area) == SDL_TRUE;
|
||||
}
|
||||
|
||||
public:
|
||||
Widget(SDL_Renderer* r, SDL_Rect& vp) : _renderer(r), _viewport(vp) {}
|
||||
std::function<void (const SDL_MouseButtonEvent&)> click_handler = NULL;
|
||||
|
||||
Widget(SDL_Renderer* r, SDL_Rect& vp)
|
||||
: _renderer(r), _viewport(vp)
|
||||
{
|
||||
set_viewport(vp);
|
||||
}
|
||||
virtual ~Widget() {}
|
||||
virtual SDL_Rect minimal_size() const { return {0, 0, 0, 0}; }
|
||||
virtual void handle_event(const SDL_Event&) = 0;
|
||||
virtual void handle_event(const SDL_Event& ev)
|
||||
{
|
||||
switch (ev.type)
|
||||
{
|
||||
case SDL_MOUSEMOTION:
|
||||
_update_hover_state(ev.motion);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
_on_push(ev.button);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
_on_release(ev.button);
|
||||
break;
|
||||
}
|
||||
}
|
||||
virtual void render() = 0;
|
||||
virtual void set_viewport(const SDL_Rect& vp) { _viewport = vp; }
|
||||
virtual void set_viewport(SDL_Rect& vp)
|
||||
{
|
||||
_viewport = vp;
|
||||
_widget_area = {
|
||||
_padding_h,
|
||||
_padding_v,
|
||||
vp.w - 2 * _padding_h,
|
||||
vp.h - 2 * _padding_v
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <iostream>
|
||||
|
||||
#include "button.hpp"
|
||||
#include <SDL2/SDL_ttf.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
|
@ -23,7 +24,7 @@ int main()
|
|||
|
||||
SDL_Rect widget_vp = {50, 100, width - 100, height - 200};
|
||||
Button widget = Button(rend, widget_vp, font);
|
||||
widget.set_caption("H");
|
||||
widget.set_caption("Hrtdyjhguk yukvu");
|
||||
bool quit = false;
|
||||
while (!quit)
|
||||
{
|
||||
|
@ -48,6 +49,7 @@ int main()
|
|||
//_handle_click({ev.button.x, ev.button.y});
|
||||
break;
|
||||
}
|
||||
widget.handle_event(ev);
|
||||
}
|
||||
|
||||
SDL_SetRenderDrawColor(rend, 0, 0, 0, SDL_ALPHA_OPAQUE);
|
||||
|
|
Loading…
Reference in a new issue