Horizontal and vertical layouts.
This commit is contained in:
parent
cc8b231623
commit
51fa4f53a3
12
button.cpp
12
button.cpp
|
@ -1,15 +1,12 @@
|
|||
#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), _font_height(TTF_FontHeight(f))
|
||||
Button::Button(SDL_Renderer* r, TTF_Font* f)
|
||||
: Widget(r), _font(f), _font_height(TTF_FontHeight(f))
|
||||
{
|
||||
set_caption("");
|
||||
_update_caption_area();
|
||||
set_viewport(vp);
|
||||
}
|
||||
|
||||
Button::~Button()
|
||||
|
@ -24,6 +21,8 @@ void Button::handle_event(const SDL_Event& ev)
|
|||
|
||||
void Button::render()
|
||||
{
|
||||
Widget::render();
|
||||
|
||||
SDL_Rect old_vp;
|
||||
|
||||
SDL_RenderGetViewport(_renderer, &old_vp);
|
||||
|
@ -92,7 +91,7 @@ void Button::set_font(TTF_Font* font)
|
|||
_render_caption_text();
|
||||
}
|
||||
|
||||
void Button::set_viewport(SDL_Rect& vp)
|
||||
void Button::set_viewport(SDL_Rect vp)
|
||||
{
|
||||
_padding_v = vp.h / 2.0 - (
|
||||
_font_height * _caption_height_multiplicator + 2 * border_width
|
||||
|
@ -110,6 +109,7 @@ void Button::_render_caption_text()
|
|||
_font,
|
||||
_caption_text.c_str(),
|
||||
color_foreground);
|
||||
SDL_DestroyTexture(_caption_texture);
|
||||
_caption_texture = SDL_CreateTextureFromSurface(_renderer, surface);
|
||||
SDL_FreeSurface(surface);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#ifndef BUTTON_HPP
|
||||
#define BUTTON_HPP
|
||||
|
||||
#include <SDL2/SDL_pixels.h>
|
||||
#include <SDL2/SDL_rect.h>
|
||||
#include <string>
|
||||
|
||||
#include <SDL2/SDL_ttf.h>
|
||||
|
@ -13,12 +11,12 @@ class Button : public Widget
|
|||
{
|
||||
protected:
|
||||
SDL_Rect _caption_area;
|
||||
float _caption_height_multiplicator = 1.2;
|
||||
SDL_Rect _caption_size;
|
||||
std::string _caption_text;
|
||||
SDL_Texture* _caption_texture = NULL;
|
||||
TTF_Font* _font = NULL;
|
||||
int _font_height;
|
||||
float _caption_height_multiplicator = 1.2;
|
||||
|
||||
virtual void _render_caption_text();
|
||||
virtual void _update_caption_area();
|
||||
|
@ -29,13 +27,13 @@ public:
|
|||
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(SDL_Renderer*, TTF_Font*);
|
||||
~Button();
|
||||
virtual void handle_event(const SDL_Event&);
|
||||
virtual void render();
|
||||
virtual void set_caption(std::string);
|
||||
virtual void set_font(TTF_Font*);
|
||||
virtual void set_viewport(SDL_Rect&);
|
||||
virtual void set_viewport(SDL_Rect);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
26
horizontal_layout.cpp
Normal file
26
horizontal_layout.cpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
#include "iostream"
|
||||
|
||||
#include "horizontal_layout.hpp"
|
||||
|
||||
Horizontal_Layout::Horizontal_Layout(SDL_Renderer* r)
|
||||
: Layout::Layout(r)
|
||||
{
|
||||
}
|
||||
|
||||
void Horizontal_Layout::_update_layout()
|
||||
{
|
||||
float widget_size = (float)_viewport.w / _widgets.size();
|
||||
|
||||
for (std::vector<Widget*>::size_type i = 0; i < _widgets.size(); i++)
|
||||
{
|
||||
SDL_Rect widget_vp = {
|
||||
_viewport.x + (int)(i * (widget_size + _interspace / 2)),
|
||||
_viewport.y,
|
||||
(int)(widget_size - _interspace),
|
||||
_viewport.h
|
||||
};
|
||||
_widgets.at(i)->set_viewport(widget_vp);
|
||||
std::cerr << "h-layout:widget:" << i << " " << widget_vp.x << ","
|
||||
<< widget_vp.y << "," << widget_vp.w << "," << widget_vp.h << std::endl;
|
||||
}
|
||||
}
|
15
horizontal_layout.hpp
Normal file
15
horizontal_layout.hpp
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef HORIZONTAL_LAYOUT_HPP
|
||||
#define HORIZONTAL_LAYOUT_HPP
|
||||
|
||||
#include "layout.hpp"
|
||||
|
||||
class Horizontal_Layout : public Layout
|
||||
{
|
||||
protected:
|
||||
void _update_layout();
|
||||
|
||||
public:
|
||||
Horizontal_Layout(SDL_Renderer*);
|
||||
};
|
||||
|
||||
#endif
|
47
layout.cpp
Normal file
47
layout.cpp
Normal file
|
@ -0,0 +1,47 @@
|
|||
#include <iostream>
|
||||
|
||||
#include "layout.hpp"
|
||||
|
||||
Layout::Layout(SDL_Renderer* r)
|
||||
: Widget(r)
|
||||
{
|
||||
}
|
||||
|
||||
Layout::~Layout()
|
||||
{
|
||||
for (Widget* widget_ptr : _widgets)
|
||||
delete widget_ptr;
|
||||
}
|
||||
|
||||
void Layout::add_widget(Widget *widget_ptr)
|
||||
{
|
||||
_widgets.push_back(widget_ptr);
|
||||
}
|
||||
|
||||
void Layout::handle_event(const SDL_Event& ev)
|
||||
{
|
||||
for (Widget* widget_ptr : _widgets)
|
||||
widget_ptr->handle_event(ev);
|
||||
}
|
||||
|
||||
void Layout::render()
|
||||
{
|
||||
SDL_Rect old_vp;
|
||||
|
||||
SDL_RenderGetViewport(_renderer, &old_vp);
|
||||
SDL_RenderSetViewport(_renderer, &_viewport);
|
||||
|
||||
SDL_SetRenderDrawColor(_renderer, 255, 0, 0, SDL_ALPHA_OPAQUE);
|
||||
SDL_RenderDrawRect(_renderer, NULL);
|
||||
|
||||
for (Widget* widget_ptr : _widgets)
|
||||
widget_ptr->render();
|
||||
|
||||
SDL_RenderSetViewport(_renderer, &old_vp);
|
||||
}
|
||||
|
||||
void Layout::set_viewport(SDL_Rect vp)
|
||||
{
|
||||
Widget::set_viewport(vp);
|
||||
_update_layout();
|
||||
}
|
25
layout.hpp
Normal file
25
layout.hpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
#ifndef LAYOUT_HPP
|
||||
#define LAYOUT_HPP
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "widget.hpp"
|
||||
|
||||
class Layout : public Widget
|
||||
{
|
||||
protected:
|
||||
float _interspace = 16;
|
||||
std::vector<Widget*> _widgets;
|
||||
|
||||
virtual void _update_layout() = 0;
|
||||
|
||||
public:
|
||||
Layout(SDL_Renderer*);
|
||||
virtual ~Layout();
|
||||
virtual void add_widget(Widget*);
|
||||
virtual void handle_event(const SDL_Event&);
|
||||
virtual void render();
|
||||
virtual void set_viewport(SDL_Rect);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -3,8 +3,12 @@ project('sdl2_basic_widgets', 'cpp',
|
|||
default_options : ['warning_level=3', 'cpp_std=c++14'])
|
||||
|
||||
executable('sdl2_basic_widgets',
|
||||
'widget_test.cpp',
|
||||
'horizontal_layout.cpp',
|
||||
'layout.cpp',
|
||||
'button.cpp',
|
||||
'vertical_layout.cpp',
|
||||
'widget.cpp',
|
||||
'widget_test.cpp',
|
||||
dependencies : [
|
||||
dependency('sdl2'),
|
||||
dependency('SDL2_ttf')
|
||||
|
|
26
vertical_layout.cpp
Normal file
26
vertical_layout.cpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
#include <iostream>
|
||||
|
||||
#include "vertical_layout.hpp"
|
||||
|
||||
Vertical_Layout::Vertical_Layout(SDL_Renderer* r)
|
||||
: Layout(r)
|
||||
{
|
||||
}
|
||||
|
||||
void Vertical_Layout::_update_layout()
|
||||
{
|
||||
float widget_size = (float)_viewport.h / _widgets.size();
|
||||
|
||||
for (std::vector<Widget*>::size_type i = 0; i < _widgets.size(); i++)
|
||||
{
|
||||
SDL_Rect widget_vp = {
|
||||
_viewport.x,
|
||||
_viewport.y + (int)(i * (widget_size + _interspace / 2)),
|
||||
_viewport.w,
|
||||
(int)(widget_size - _interspace),
|
||||
};
|
||||
_widgets.at(i)->set_viewport(widget_vp);
|
||||
std::cerr << "v-layout:widget:" << i << " " << widget_vp.x << ","
|
||||
<< widget_vp.y << "," << widget_vp.w << "," << widget_vp.h << std::endl;
|
||||
}
|
||||
}
|
15
vertical_layout.hpp
Normal file
15
vertical_layout.hpp
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef VERTICAL_LAYOUT_HPP
|
||||
#define VERTICAL_LAYOUT_HPP
|
||||
|
||||
#include "layout.hpp"
|
||||
|
||||
class Vertical_Layout : public Layout
|
||||
{
|
||||
protected:
|
||||
void _update_layout();
|
||||
|
||||
public:
|
||||
Vertical_Layout(SDL_Renderer*);
|
||||
};
|
||||
|
||||
#endif
|
78
widget.cpp
Normal file
78
widget.cpp
Normal file
|
@ -0,0 +1,78 @@
|
|||
#include <iostream>
|
||||
|
||||
#include "widget.hpp"
|
||||
|
||||
Widget::Widget(SDL_Renderer* r)
|
||||
: _renderer(r)
|
||||
{
|
||||
}
|
||||
|
||||
Widget::~Widget()
|
||||
{
|
||||
}
|
||||
|
||||
void Widget::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;
|
||||
}
|
||||
}
|
||||
|
||||
void Widget::render()
|
||||
{
|
||||
SDL_Rect old_vp;
|
||||
|
||||
SDL_RenderGetViewport(_renderer, &old_vp);
|
||||
SDL_RenderSetViewport(_renderer, &_viewport);
|
||||
|
||||
SDL_SetRenderDrawColor(_renderer, 0, 255, 0, SDL_ALPHA_OPAQUE);
|
||||
SDL_RenderDrawRect(_renderer, NULL);
|
||||
|
||||
SDL_RenderSetViewport(_renderer, &old_vp);
|
||||
}
|
||||
|
||||
void Widget::set_viewport(SDL_Rect vp)
|
||||
{
|
||||
_viewport = vp;
|
||||
_widget_area = {
|
||||
_padding_h,
|
||||
_padding_v,
|
||||
vp.w - 2 * _padding_h,
|
||||
vp.h - 2 * _padding_v
|
||||
};
|
||||
}
|
||||
|
||||
void Widget::_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;
|
||||
}
|
||||
}
|
||||
|
||||
void Widget::_on_release(const SDL_MouseButtonEvent& button)
|
||||
{
|
||||
if (_pushed)
|
||||
{
|
||||
if (click_handler != NULL)
|
||||
click_handler(button);
|
||||
}
|
||||
_pushed = false;
|
||||
}
|
||||
|
||||
void Widget::_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;
|
||||
}
|
||||
|
70
widget.hpp
70
widget.hpp
|
@ -2,7 +2,6 @@
|
|||
#define WIDGET_HPP
|
||||
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
|
@ -10,70 +9,25 @@ 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;
|
||||
bool _pushed = false;
|
||||
SDL_Renderer* _renderer;
|
||||
SDL_Rect _viewport;
|
||||
SDL_Rect _widget_area;
|
||||
|
||||
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;
|
||||
}
|
||||
virtual void _on_push(const SDL_MouseButtonEvent&);
|
||||
virtual void _on_release(const SDL_MouseButtonEvent&);
|
||||
virtual void _update_hover_state(const SDL_MouseMotionEvent&);
|
||||
|
||||
public:
|
||||
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 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(SDL_Rect& vp)
|
||||
{
|
||||
_viewport = vp;
|
||||
_widget_area = {
|
||||
_padding_h,
|
||||
_padding_v,
|
||||
vp.w - 2 * _padding_h,
|
||||
vp.h - 2 * _padding_v
|
||||
};
|
||||
}
|
||||
Widget(SDL_Renderer*);
|
||||
virtual ~Widget();
|
||||
virtual void handle_event(const SDL_Event&);
|
||||
virtual void render();
|
||||
virtual void set_viewport(SDL_Rect);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include <iostream>
|
||||
|
||||
#include "button.hpp"
|
||||
#include "horizontal_layout.hpp"
|
||||
#include "vertical_layout.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
|
@ -22,9 +24,27 @@ int main()
|
|||
SDL_Renderer* rend = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);
|
||||
SDL_SetRenderDrawBlendMode(rend, SDL_BLENDMODE_BLEND);
|
||||
|
||||
SDL_Rect widget_vp = {50, 100, width - 100, height - 200};
|
||||
Button widget = Button(rend, widget_vp, font);
|
||||
widget.set_caption("Hrtdyjhguk yukvu");
|
||||
SDL_Rect layout_vp = {0, 0, width, height};
|
||||
Layout* layout = new Vertical_Layout(rend);
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
std::cerr << "Layout " << i << " Widget:";
|
||||
Layout* column = new Horizontal_Layout(rend);
|
||||
layout->add_widget(column);
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
Button* widget = new Button(rend, font);
|
||||
column->add_widget(widget);
|
||||
std::cerr << " " << j << "@" << widget;
|
||||
widget->set_caption("Hi!");
|
||||
widget->click_handler = [i, j] (const SDL_MouseButtonEvent&) {
|
||||
std::cerr << "click row:" << i
|
||||
<< ":col:" << j << std::endl;
|
||||
};
|
||||
}
|
||||
std::cerr << std::endl << "Append v-layout" << std::endl;
|
||||
}
|
||||
layout->set_viewport(layout_vp);
|
||||
bool quit = false;
|
||||
while (!quit)
|
||||
{
|
||||
|
@ -40,25 +60,27 @@ int main()
|
|||
if (ev.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
|
||||
{
|
||||
SDL_GetRendererOutputSize(rend, &width, &height);
|
||||
widget_vp.w = width - 100;
|
||||
widget_vp.h = height - 200;
|
||||
widget.set_viewport(widget_vp);
|
||||
layout_vp.w = width;
|
||||
layout_vp.h = height;
|
||||
std::cerr << "Screen resized " << width << "x" << height << std::endl;
|
||||
layout->set_viewport(layout_vp);
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
//_handle_click({ev.button.x, ev.button.y});
|
||||
break;
|
||||
}
|
||||
widget.handle_event(ev);
|
||||
layout->handle_event(ev);
|
||||
}
|
||||
|
||||
SDL_SetRenderDrawColor(rend, 0, 0, 0, SDL_ALPHA_OPAQUE);
|
||||
SDL_RenderClear(rend);
|
||||
|
||||
widget.render();
|
||||
layout->render();
|
||||
SDL_RenderPresent(rend);
|
||||
}
|
||||
|
||||
delete layout;
|
||||
SDL_DestroyRenderer(rend);
|
||||
SDL_DestroyWindow(win);
|
||||
SDL_Quit();
|
||||
|
|
Loading…
Reference in a new issue