chainreaction/game_screen.cpp

119 lines
2.7 KiB
C++

#include <SDL2/SDL_render.h>
#include "game_screen.hpp"
using namespace bwidgets;
using namespace game;
using namespace game::data;
// TODO: Why don't I use a ptr to current caption?
static inline auto& cur_caption(ui::GameScreen* scr)
{
switch (scr->cur_player)
{
case Player::P1:
return scr->caption_p1;
case Player::P2:
return scr->caption_p2;
default:
return scr->caption_none;
}
}
ui::GameScreen::GameScreen()
: board(this), caption_none(this), caption_p1(this), caption_p2(this)
{
caption_p1.text("Player 1")->color_bg(board.color_outline);
caption_p2.text("Player 2")->color_bg(board.color_outline);
}
ui::GameScreen::~GameScreen()
{
for (auto l : _layers)
free(l.second);
}
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::_handle_rendering()
{
_renderer->draw_color(board.color_outline)
->fill_rect(_widget_area);
cur_caption(this).render();
board.render();
Layer::_handle_rendering();
}
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++)
{
for (auto* c : {&caption_none, &caption_p1, &caption_p2})
{
auto size = c->size();
if (step == 0)
{
if (size.h > heighest_caption)
heighest_caption = size.h;
}
else
{
c->viewport({
vp.x + (vp.w - size.w) / 2,
vp.y,
size.w,
heighest_caption
});
}
}
}
board.viewport({
vp.x,
vp.y + heighest_caption,
vp.w,
vp.h - heighest_caption
});
_viewport = vp;
}
void ui::GameScreen::_for_widgets(std::function<void (widget::Widget&)> f)
{
if (_cur_layer)
f(*_cur_layer);
}
void ui::GameScreen::_handle_font_change(core::Font* f)
{
for (auto l : _layers)
l.second->font(f);
for (auto* c : {&caption_none, &caption_p1, &caption_p2})
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);
}