adapt to latest bwidgets changes

This commit is contained in:
Andrea Blankenstijn 2021-07-20 23:59:21 +02:00
parent c5cb53ebc7
commit 897c863fdd
7 changed files with 174 additions and 175 deletions

View File

@ -1,10 +1,14 @@
#include <basic_widgets/abstract/widget.hpp>
#include <basic_widgets/utils/render.hpp>
#include <SDL2/SDL_assert.h>
#include <SDL2/SDL_events.h>
#include <basic_widgets/core/draw.hpp>
#include <basic_widgets/core/renderer.hpp>
#include <basic_widgets/core/texture.hpp>
#include "board_widget.hpp"
#include "game.hpp"
using namespace bwidgets::utils;
using namespace bwidgets;
using namespace game;
using namespace game::data;
@ -16,7 +20,7 @@ ui::BoardWidget::BoardWidget(Widget* p)
[this]
(const SDL_MouseButtonEvent& p) -> void
{
if (_board != nullptr)
if (board != nullptr)
{
auto coord = new SDL_Point(this->board_coord_from_input({p.x, p.y}));
SDL_Event play_ev;
@ -30,44 +34,36 @@ ui::BoardWidget::BoardWidget(Widget* p)
};
}
void ui::BoardWidget::board(Board* b)
ui::BoardWidget::~BoardWidget()
{
_board = b;
delete _circle_blue;
delete _circle_red;
}
SDL_Point ui::BoardWidget::board_coord_from_input(const SDL_Point& p) const
{
if (_board == nullptr)
if (board == nullptr)
return {-1, -1};
return {
(p.x - _viewport.x - _widget_area.x) / (_widget_area.w / _board->width),
(p.y - _viewport.y - _widget_area.y) / (_widget_area.h / _board->height)
(p.x - _viewport.x - _widget_area.x) / (_widget_area.w / board->width),
(p.y - _viewport.y - _widget_area.y) / (_widget_area.h / board->height)
};
}
void ui::BoardWidget::render(SDL_Renderer* r)
void ui::BoardWidget::_handle_rendering()
{
Widget::render(r);
if (_renderer == nullptr || _renderer != r)
{
_renderer = r;
_update_textures();
}
SDL_RenderSetViewport(r, &_viewport);
SDL_SetRenderDrawColor(r, color_bg.r, color_bg.g, color_bg.b, color_bg.a);
SDL_RenderFillRect(r, &_widget_area);
if (!_circle_blue || !_circle_red)
_handle_texture_update();
_renderer->draw_color(color_bg)->fill_rect(_widget_area);
_render_empty_board();
_render_square_content();
}
void ui::BoardWidget::viewport(const SDL_Rect& vp)
void ui::BoardWidget::_handle_geometry_change(const SDL_Rect& vp) noexcept
{
Widget::viewport(vp);
_widget_area = {0, 0, vp.w, vp.h};
auto smallest_size {
_widget_area.w < _widget_area.h
? _widget_area.w
@ -85,10 +81,9 @@ void ui::BoardWidget::viewport(const SDL_Rect& vp)
_widget_area.w - 2 * (_border_area.w),
_widget_area.h - 2 * (_border_area.w)
};
_update_textures();
}
void ui::BoardWidget::_draw_atoms(const SDL_Rect& area, int atoms, SDL_Texture* texture)
void ui::BoardWidget::_draw_atoms(const SDL_Rect& area, int atoms, core::Texture* texture)
{
const auto radius = area.w < area.h ? area.w / 8 : area.h / 8;
const auto diameter = radius * 2;
@ -145,86 +140,81 @@ void ui::BoardWidget::_draw_atoms(const SDL_Rect& area, int atoms, SDL_Texture*
{
const int size {o.x == disabled ? 0 : diameter};
render::render_copy(_renderer, texture, {area.x + o.x, area.y + o.y, size, size});
_renderer->copy(texture, NULL, {area.x + o.x, area.y + o.y, size, size});
}
}
void ui::BoardWidget::_handle_renderer_change(core::Renderer*)
{
core::OpaqueStruct<core::Texture>::discard(_circle_blue);
core::OpaqueStruct<core::Texture>::discard(_circle_red);
}
void ui::BoardWidget::_render_empty_board()
{
SDL_SetRenderDrawColor(_renderer,
color_outline.r,
color_outline.g,
color_outline.b,
color_outline.a);
_renderer->draw_color(color_outline);
if (_board != nullptr)
if (board)
{
for (int col = 0; col <= _board->width; col++)
for (int col = 0; col <= board->width; col++)
{
int x = col * _widget_area.w / _board->width;
SDL_RenderDrawLine(_renderer,
_widget_area.x + x, _widget_area.y,
_widget_area.x + x, _widget_area.y + _widget_area.h);
int x = col * _widget_area.w / board->width;
_renderer->draw_line({_widget_area.x + x, _widget_area.y},
{_widget_area.x + x, _widget_area.y + _widget_area.h});
}
for (int row = 0; row <= _board->height; row++)
for (int row = 0; row <= board->height; row++)
{
int y = row * _widget_area.h / _board->height;
SDL_RenderDrawLine(_renderer,
_widget_area.x, _widget_area.y + y,
_widget_area.x + _widget_area.w, _widget_area.y + y);
int y = row * _widget_area.h / board->height;
_renderer->draw_line({_widget_area.x, _widget_area.y + y},
{_widget_area.x + _widget_area.w, _widget_area.y + y});
}
}
for (int xy = 0; xy < _border_area.w; xy++)
{
const float color_factor = 1 - (float)xy / _border_area.w / 3;
SDL_SetRenderDrawColor(_renderer,
color_outline.r * color_factor,
color_outline.g * color_factor,
color_outline.b * color_factor,
color_outline.a);
SDL_Rect border {
_border_area.x + xy,
_border_area.y + xy,
_widget_area.w + 2 * (_widget_area.x - _border_area.x - xy) + 1,
_widget_area.h + 2 * (_widget_area.y - _border_area.y - xy) + 1
};
SDL_RenderDrawRect(_renderer, &border);
_renderer->draw_color({
(uint8_t)(color_outline.r * color_factor),
(uint8_t)(color_outline.g * color_factor),
(uint8_t)(color_outline.b * color_factor),
color_outline.a})->draw_rect({
_border_area.x + xy,
_border_area.y + xy,
_widget_area.w + 2 * (_widget_area.x - _border_area.x - xy) + 1,
_widget_area.h + 2 * (_widget_area.y - _border_area.y - xy) + 1
});
}
}
void ui::BoardWidget::_render_square_content()
{
if (_board == nullptr)
if (!board)
return;
for (int y = 0; y < _board->height; y++)
for (int y = 0; y < board->height; y++)
{
for (int x = 0; x < _board->width; x++)
for (int x = 0; x < board->width; x++)
{
SDL_Rect sqr_area {
_widget_area.x
+ x * _widget_area.w / _board->width + 1,
+ x * _widget_area.w / board->width + 1,
_widget_area.y
+ y * _widget_area.h / _board->height + 1,
_widget_area.w / _board->width - 2,
_widget_area.h / _board->height - 2
+ y * _widget_area.h / board->height + 1,
_widget_area.w / board->width - 2,
_widget_area.h / board->height - 2
};
const auto& sqr = Board::square(*_board, {x, y});
auto capacity = logic::square_capacity(*_board, {x, y});
const auto& sqr = Board::square(*board, {x, y});
auto capacity = logic::square_capacity(*board, {x, y});
if (sqr.value > capacity)
{
SDL_SetRenderDrawColor(_renderer, 255, 0, 0, 255/16);
SDL_RenderFillRect(_renderer, &sqr_area);
_renderer->draw_color(color_hl1)->fill_rect(sqr_area);
}
else if (sqr.value == capacity)
{
SDL_SetRenderDrawColor(_renderer, 255, 255, 0, 255/16);
SDL_RenderFillRect(_renderer, &sqr_area);
_renderer->draw_color(color_hl2)->fill_rect(sqr_area);
}
_draw_atoms(sqr_area, sqr.value,
sqr.owner == game::data::Player::P1
@ -234,20 +224,18 @@ void ui::BoardWidget::_render_square_content()
}
}
void ui::BoardWidget::_update_textures()
void ui::BoardWidget::_handle_texture_update()
{
if (_board == nullptr || _renderer == nullptr)
SDL_assert_release(!_circle_blue && !_circle_red);
if (!board)
return;
int circle_size = _widget_area.w > _widget_area.h
? _widget_area.h / _board->height / 4
: _widget_area.w / _board->width / 4;
auto circle_size = _widget_area.w > _widget_area.h
? _widget_area.h / board->height / 4
: _widget_area.w / board->width / 4;
for (SDL_Texture** t : {&_circle_blue, &_circle_red})
{
SDL_DestroyTexture(*t);
*t = nullptr;
}
_circle_blue = render::filled_circle({0, 0, 255, 255}, circle_size, _renderer);
_circle_red = render::filled_circle({255, 0, 0, 255}, circle_size, _renderer);
auto aa = circle_size > 16 ? 3 : 0;
_circle_blue = core::filled_circle({0, 0, 255, 255}, circle_size, _renderer, aa);
_circle_red = core::filled_circle({255, 0, 0, 255}, circle_size, _renderer, aa);
}

View File

@ -4,12 +4,11 @@
#include <SDL2/SDL_rect.h>
#include <SDL2/SDL_stdinc.h>
#include <basic_widgets/abstract/mouse_handler.hpp>
#include <basic_widgets/abstract/widget.hpp>
#include <basic_widgets/w/feat/mouse_handler.hpp>
#include <basic_widgets/w/feat/texture_handler.hpp>
#include <basic_widgets/w/base/widget.hpp>
extern Uint32 SDL_RegisterEvents(int);
struct SDL_Renderer;
struct SDL_Texture;
extern "C" { Uint32 SDL_RegisterEvents(int); }
namespace game::data
{
@ -18,24 +17,27 @@ namespace game::data
namespace game::ui
{
class BoardWidget : public bwidgets::abstract::Widget,
public bwidgets::abstract::MouseHandler
class BoardWidget : public bwidgets::widget::Widget,
public bwidgets::widget::MouseHandler,
public bwidgets::widget::TextureHandler
{
protected:
static const
int _border_ratio {30};
int _border_ratio {30};
const data::Board* _board {nullptr};
SDL_Rect _border_area;
SDL_Texture* _circle_blue {nullptr};
SDL_Texture* _circle_red {nullptr};
SDL_Renderer* _renderer {nullptr};
SDL_Rect _border_area;
bwidgets::core::Texture* _circle_blue {nullptr};
bwidgets::core::Texture* _circle_red {nullptr};
virtual void _draw_atoms(const SDL_Rect&, int, SDL_Texture*);
virtual void _draw_atoms(const SDL_Rect&, int, bwidgets::core::Texture*);
virtual void _handle_focus_change(bool) override {}
virtual void _handle_geometry_change(const SDL_Rect&) noexcept override;
virtual void _handle_renderer_change(bwidgets::core::Renderer*) override;
virtual void _handle_rendering() override;
virtual void _handle_texture_update() override;
virtual void _render_empty_board();
virtual void _render_square_content();
virtual void _update_textures();
public:
enum struct event_code : Sint32 {
@ -43,17 +45,18 @@ namespace game::ui
};
const Uint32 event_type {SDL_RegisterEvents(1)};
SDL_Color color_bg {50, 50, 50, SDL_ALPHA_OPAQUE};
SDL_Color color_outline {175, 175, 175, SDL_ALPHA_OPAQUE};
SDL_Color color_p1 {255, 0, 0, SDL_ALPHA_OPAQUE};
SDL_Color color_p2 {0, 0, 255, SDL_ALPHA_OPAQUE};
const data::Board* board {nullptr};
SDL_Color color_bg {50, 50, 50, SDL_ALPHA_OPAQUE};
SDL_Color color_hl1 {255, 0, 0, SDL_ALPHA_OPAQUE/16};
SDL_Color color_hl2 {255, 255, 0, SDL_ALPHA_OPAQUE/16};
SDL_Color color_outline {175, 175, 175, SDL_ALPHA_OPAQUE};
SDL_Color color_p1 {255, 0, 0, SDL_ALPHA_OPAQUE};
SDL_Color color_p2 {0, 0, 255, SDL_ALPHA_OPAQUE};
BoardWidget(Widget* parent=nullptr);
virtual ~BoardWidget();
void board(data::Board*);
SDL_Point board_coord_from_input(const SDL_Point&) const;
void render(SDL_Renderer*);
void viewport(const SDL_Rect&);
};
}
#endif

View File

@ -23,8 +23,8 @@ static inline auto& cur_caption(ui::GameScreen* scr)
ui::GameScreen::GameScreen()
: board(this), caption_none(this), caption_p1(this), caption_p2(this)
{
caption_p1.text("Player 1");
caption_p2.text("Player 2");
caption_p1.text("Player 1")->color_bg(board.color_outline);
caption_p2.text("Player 2")->color_bg(board.color_outline);
}
ui::GameScreen::~GameScreen()
@ -33,34 +33,30 @@ ui::GameScreen::~GameScreen()
free(l.second);
}
void ui::GameScreen::handle_event(const SDL_Event& e)
ui::GameScreen* ui::GameScreen::handle_event(const SDL_Event& e)
{
if (_cur_layer == nullptr)
board.handle_event(e);
else
Layer::handle_event(e);
return this;
}
void ui::GameScreen::render(SDL_Renderer* r)
void ui::GameScreen::_handle_rendering()
{
SDL_RenderSetViewport(r, &_viewport);
_renderer->draw_color(board.color_outline)
->fill_rect(_widget_area);
SDL_SetRenderDrawColor(r,
board.color_outline.r,
board.color_outline.g,
board.color_outline.b,
board.color_outline.a
);
SDL_RenderFillRect(r, NULL);
cur_caption(this).render();
board.render();
cur_caption(this).render(r);
board.render(r);
Layer::render(r);
Layer::_handle_rendering();
}
void ui::GameScreen::viewport(const SDL_Rect& vp)
void ui::GameScreen::_handle_geometry_change(const SDL_Rect& vp) noexcept
{
_widget_area = {0, 0, vp.w, vp.h};
int heighest_caption = 0;
for (auto step = 0; step < 2; step++)
@ -94,15 +90,29 @@ void ui::GameScreen::viewport(const SDL_Rect& vp)
_viewport = vp;
}
void ui::GameScreen::_for_widgets(std::function<void (abstract::Widget&)> f)
void ui::GameScreen::_for_widgets(std::function<void (widget::Widget&)> f)
{
if (_cur_layer != nullptr)
if (_cur_layer)
f(*_cur_layer);
}
void ui::GameScreen::_handle_font_change()
void ui::GameScreen::_handle_font_change(core::Font* f)
{
Layer::_handle_font_change();
for (auto l : _layers)
l.second->font(f);
for (auto* c : {&caption_none, &caption_p1, &caption_p2})
c->font(_font);
c->font(f);
}
void ui::GameScreen::_handle_renderer_change(core::Renderer* r)
{
for (auto l : _layers)
l.second->renderer(r);
for (auto* c : {(Widget*)&board,
(Widget*)&caption_none,
(Widget*)&caption_p1,
(Widget*)&caption_p2})
c->renderer(r);
}

View File

@ -3,7 +3,7 @@
#include <unordered_map>
#include <basic_widgets/caption.hpp>
#include <basic_widgets/w/caption.hpp>
#include "board_widget.hpp"
#include "data.hpp"
@ -13,7 +13,7 @@ struct SDL_Renderer;
namespace game::ui
{
class GameScreen : public Layer
class GameScreen final : public Layer
{
enum LayerId {
MENU
@ -24,8 +24,12 @@ namespace game::ui
Layers _layers;
SDL_Rect _viewport {};
void _for_widgets(std::function<void (bwidgets::abstract::Widget&)>) override;
void _handle_font_change() override;
void _for_widgets(std::function<void (bwidgets::widget::Widget&)>) override;
void _handle_font_change(bwidgets::core::Font*) override;
void _handle_font_color_change(const SDL_Color&, const SDL_Color&) override {}
void _handle_geometry_change(const SDL_Rect&) noexcept override;
void _handle_renderer_change(bwidgets::core::Renderer*) override;
void _handle_rendering() override;
public:
BoardWidget board;
@ -37,9 +41,7 @@ namespace game::ui
GameScreen();
~GameScreen();
void handle_event(const SDL_Event&) override;
void render(SDL_Renderer*) override;
void viewport(const SDL_Rect&) override;
virtual GameScreen* handle_event(const SDL_Event&) override;
};
}

View File

@ -5,16 +5,15 @@
using namespace game;
using namespace std;
using namespace bwidgets::abstract;
using namespace bwidgets;
ui::Layer::Layer(Widget* parent)
ui::Layer::Layer(widget::Widget* parent)
: Widget(parent)
{
}
void ui::Layer::_handle_font_change()
void ui::Layer::_handle_font_change(core::Font* f)
{
auto f = _font;
_for_widgets([f](Widget& w) {
try {
auto& handler = dynamic_cast<FontHandler&>(w);
@ -23,23 +22,24 @@ void ui::Layer::_handle_font_change()
});
}
void ui::Layer::handle_event(const SDL_Event& e)
ui::Layer* ui::Layer::handle_event(const SDL_Event& e)
{
_for_widgets([e](Widget& w) {
w.handle_event(e);
});
return this;
}
void ui::Layer::render(SDL_Renderer* r)
void ui::Layer::_handle_renderer_change(core::Renderer* r)
{
_for_widgets([r](Widget& w) {
w.render(r);
w.renderer(r);
});
}
void ui::Layer::viewport(const SDL_Rect& vp)
void ui::Layer::_handle_rendering()
{
_for_widgets([vp](Widget& w) {
w.viewport(vp);
_for_widgets([](Widget& w) {
w.render();
});
}

View File

@ -3,32 +3,28 @@
#include <functional>
#include <basic_widgets/abstract/font_handler.hpp>
#include <basic_widgets/abstract/widget.hpp>
#include <basic_widgets/w/feat/font_handler.hpp>
#include <basic_widgets/w/base/widget.hpp>
union SDL_Event;
struct SDL_Rect;
struct SDL_Renderer;
namespace bwidgets::abstract {
class Widget;
}
namespace game::ui
{
class Layer : public bwidgets::abstract::Widget,
public bwidgets::abstract::FontHandler
class Layer : public bwidgets::widget::Widget,
public bwidgets::widget::FontHandler
{
protected:
virtual void _for_widgets(std::function<void (bwidgets::abstract::Widget&)>) = 0;
virtual void _handle_font_change() override;
protected:
virtual void _for_widgets(std::function<void (bwidgets::widget::Widget&)>) = 0;
virtual void _handle_font_change(bwidgets::core::Font*) override;
virtual void _handle_renderer_change(bwidgets::core::Renderer*) override;
virtual void _handle_rendering() override;
public:
Layer(Widget* parent=nullptr);
public:
Layer(Widget* parent=nullptr);
void handle_event(const SDL_Event&) override;
void render(SDL_Renderer*) override;
void viewport(const SDL_Rect&) override;
virtual Layer* handle_event(const SDL_Event&) override;
};
}

View File

@ -2,11 +2,12 @@
#include <SDL2/SDL_ttf.h>
#include <basic_widgets/utils/font.hpp>
#include <basic_widgets/core/font.hpp>
#include "game_screen.hpp"
#include "game.hpp"
using namespace bwidgets;
using namespace game;
int main()
@ -23,21 +24,21 @@ int main()
height,
SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE
);
SDL_Renderer* rend = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);
SDL_SetRenderDrawBlendMode(rend, SDL_BLENDMODE_BLEND);
auto* rend = new core::Renderer(win, -1, SDL_RENDERER_ACCELERATED);
rend->blend_mode(SDL_BLENDMODE_BLEND);
SDL_Rect viewport {2, 2, width - 4, height - 4};
TTF_Init();
std::string font_file = bwidgets::utils::font::find("Monospace");
TTF_Font* font = TTF_OpenFont(font_file.c_str(), 20);
auto* font = new core::Font(core::Font::find("Monospace"), 20);
data::Board board(4, 3);
data::Board transition_board(board);
ui::GameScreen game_screen;
game_screen.board.board(&board);
game_screen.board.board = &board;
game_screen.font(font);
game_screen.renderer(rend);
game_screen.viewport(viewport);
bool quit = false;
@ -63,9 +64,9 @@ int main()
if (ev.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
{
SDL_GetRendererOutputSize(rend, &width, &height);
viewport.w = width - 4;
viewport.h = height - 4;
auto s = rend->output_size();
viewport.w = s.w - 4;
viewport.h = s.h - 4;
game_screen.viewport(viewport);
}
@ -104,33 +105,32 @@ int main()
}
SDL_SetRenderDrawColor(rend, 0, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderClear(rend);
rend->draw_color({0, 0, 0, SDL_ALPHA_OPAQUE})->clear();
if (transitions_iterator < transitions.size())
{
if (auto t = SDL_GetTicks(); t - transitions_timer > 750)
{
game_screen.board.board(&transitions[transitions_iterator]);
game_screen.board.board = &transitions[transitions_iterator];
transitions_iterator++;
transitions_timer = t;
}
}
else if (transitions_iterator > 0 && transitions_iterator == transitions.size())
{
game_screen.board.board(&board);
game_screen.board.board = &board;
transitions_iterator = 0;
transitions.clear();
}
game_screen.render(rend);
game_screen.render();
SDL_RenderPresent(rend);
rend->present();
}
TTF_CloseFont(font);
delete font;
delete rend;
TTF_Quit();
SDL_DestroyRenderer(rend);
SDL_DestroyWindow(win);
SDL_Quit();
return 0;