bwidgets/src/w/caption.cpp

138 lines
3.5 KiB
C++

#include <SDL2/SDL_assert.h>
#include <basic_widgets/core/math.hpp>
#include <basic_widgets/core/texture.hpp>
#include <basic_widgets/w/caption.hpp>
#include <iostream>
using namespace bwidgets;
widget::Caption::~Caption() noexcept
{
core::OpaqueStruct<core::Texture>::discard(_text_texture);
}
widget::Caption* widget::Caption::color_bg(const SDL_Color& c)
{
_color_bg = c;
core::OpaqueStruct<core::Texture>::discard(_text_texture);
return this;
}
widget::Caption* widget::Caption::color_fg(const SDL_Color& c)
{
_color_fg = c;
core::OpaqueStruct<core::Texture>::discard(_text_texture);
return this;
}
widget::Caption* widget::Caption::render_mode(core::Font::RenderMode m) noexcept
{
_render_mode = m;
core::OpaqueStruct<core::Texture>::discard(_text_texture);
return this;
}
core::Size widget::Caption::size() const noexcept
{
if (_font == nullptr)
return {-1, -1};
core::Size size = _font->text_size(_text);
return {size.w + 2 * margins.w, size.h + 2 * margins.h};
}
const std::string& widget::Caption::text() const noexcept
{
return _text;
}
widget::Caption* widget::Caption::text(const std::string& t)
{
_text = t;
core::OpaqueStruct<core::Texture>::discard(_text_texture);
return this;
}
void widget::Caption::_handle_font_change(core::Font*)
{
core::OpaqueStruct<core::Texture>::discard(_text_texture);
}
static inline bool operator!=(const SDL_Color& a, const SDL_Color& b)
{
return a.r != b.r || a.g != b.g || a.b != b.b || a.a != b.a;
}
void widget::Caption::_handle_font_color_change(const SDL_Color& fg, const SDL_Color& bg)
{
if (fg != _font_color_fg || (bg != _font_color_bg &&
_font_render_mode == core::Font::RenderMode::SHADED))
{
core::OpaqueStruct<core::Texture>::discard(_text_texture);
}
}
void widget::Caption::_handle_geometry_change(const SDL_Rect& vp) noexcept
{
if (vp.w != _viewport.w || vp.h != _viewport.h)
{
_widget_area = core::rect_margin({0, 0, vp.w, vp.h}, margins);
}
}
void widget::Caption::_handle_renderer_change(core::Renderer*)
{
core::OpaqueStruct<core::Texture>::discard(_text_texture);
}
void widget::Caption::_handle_rendering()
{
_renderer->draw_color(_color_bg)->fill_rect({0, 0, _viewport.w, _viewport.h});
if (!_text_texture)
_handle_texture_update();
core::Size size_dst {
(int)((float)_text_texture->attributes().w
/ _text_texture->attributes().h * _widget_area.h),
_widget_area.h
};
SDL_Rect texture_dst {
margins.w,
margins.h,
size_dst.w,
size_dst.h
};
switch (alignment)
{
case Alignment::CENTER:
texture_dst.x = core::center_rect(_widget_area.w, texture_dst.w)
+ _widget_area.x;
break;
case Alignment::LEFT:
break;
case Alignment::RIGHT:
texture_dst.x = _widget_area.w - texture_dst.w - margins.w + _widget_area.x;
break;
}
_renderer->copy(_text_texture, NULL, texture_dst);
}
void widget::Caption::_handle_texture_update()
{
SDL_assert_release(_font);
core::OpaqueStruct<core::Texture>::discard(_text_texture);
SDL_Surface* s;
switch (_render_mode)
{
case core::Font::RenderMode::SHADED:
s = _font->render(_render_mode, _text, _color_fg, _color_bg);
break;
default:
s = _font->render(_render_mode, _text, _color_fg);
break;
}
_text_texture = new core::Texture(_renderer, s);
}