127 lines
3.4 KiB
C++
127 lines
3.4 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>
|
||
|
|
||
|
using namespace bwidgets;
|
||
|
|
||
|
widget::Caption::~Caption() noexcept
|
||
|
{
|
||
|
core::OpaqueStruct<core::Texture>::discard(_text_texture);
|
||
|
}
|
||
|
|
||
|
void widget::Caption::color_fg(const SDL_Color& c)
|
||
|
{
|
||
|
_color_fg = c;
|
||
|
core::OpaqueStruct<core::Texture>::discard(_text_texture);
|
||
|
}
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
void widget::Caption::text(const std::string& t)
|
||
|
{
|
||
|
_text = t;
|
||
|
core::OpaqueStruct<core::Texture>::discard(_text_texture);
|
||
|
}
|
||
|
|
||
|
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 = {margins.w, margins.h,
|
||
|
vp.w - 2 * margins.w, vp.h - 2 * margins.h};
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void widget::Caption::_handle_renderer_change(core::Renderer*)
|
||
|
{
|
||
|
core::OpaqueStruct<core::Texture>::discard(_text_texture);
|
||
|
}
|
||
|
|
||
|
void widget::Caption::_handle_rendering()
|
||
|
{
|
||
|
if (_text_texture == nullptr)
|
||
|
{
|
||
|
_handle_texture_update();
|
||
|
SDL_assert_release(_text_texture != nullptr);
|
||
|
}
|
||
|
|
||
|
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,
|
||
|
core::center_rect(_widget_area.h, size_dst.h) + margins.h,
|
||
|
size_dst.w,
|
||
|
size_dst.h
|
||
|
};
|
||
|
switch (alignment.h)
|
||
|
{
|
||
|
case AlignmentH::CENTER:
|
||
|
texture_dst.x = core::center_rect(_widget_area.w, texture_dst.w)
|
||
|
+ _widget_area.x;
|
||
|
break;
|
||
|
case AlignmentH::LEFT:
|
||
|
break;
|
||
|
case AlignmentH::RIGHT:
|
||
|
texture_dst.x = _widget_area.w - texture_dst.w - margins.w + _widget_area.x;
|
||
|
break;
|
||
|
}
|
||
|
switch (alignment.v)
|
||
|
{
|
||
|
case AlignmentV::BOTTOM:
|
||
|
texture_dst.y = _widget_area.h - texture_dst.h - margins.h + _widget_area.y;
|
||
|
break;
|
||
|
case AlignmentV::CENTER:
|
||
|
break;
|
||
|
case AlignmentV::TOP:
|
||
|
texture_dst.y = margins.h + _widget_area.y;
|
||
|
}
|
||
|
_renderer->copy(*_text_texture, NULL, texture_dst);
|
||
|
}
|
||
|
|
||
|
void widget::Caption::_handle_texture_update()
|
||
|
{
|
||
|
SDL_assert_release(_renderer != nullptr);
|
||
|
core::OpaqueStruct<core::Texture>::discard(_text_texture);
|
||
|
|
||
|
auto txt_surface = _font->render(core::Font::RenderMode::SHADED,
|
||
|
_text, _color_fg, _color_bg);
|
||
|
_text_texture = new core::Texture(_renderer, txt_surface);
|
||
|
}
|