125 lines
3.4 KiB
C++
125 lines
3.4 KiB
C++
#include <basic_widgets/core/math.hpp>
|
|
#include <basic_widgets/core/texture.hpp>
|
|
#include <basic_widgets/w/caption_impl.hpp>
|
|
#include <basic_widgets/w/numeric_input.hpp>
|
|
|
|
using namespace bwidgets;
|
|
|
|
CaptionImpl::CaptionImpl(Widget* parent) noexcept : WidgetImpl {parent}
|
|
{
|
|
_font_color_bg = default_font_color_bg;
|
|
_font_color_fg = default_font_color_fg;
|
|
}
|
|
|
|
void CaptionImpl::render_mode(const Font::RenderMode m)
|
|
{
|
|
if (m != _render_mode) {
|
|
_text_texture.reset();
|
|
_render_mode = m;
|
|
}
|
|
}
|
|
|
|
auto CaptionImpl::size() const noexcept -> Size
|
|
{
|
|
if (!_font) return {0, 0};
|
|
|
|
const auto [w, h] = _font->text_size(_text);
|
|
return {w + 2 * margins.w, h + 2 * margins.h};
|
|
}
|
|
|
|
auto CaptionImpl::text() const noexcept -> std::string_view
|
|
{
|
|
return _text;
|
|
}
|
|
|
|
void CaptionImpl::text(std::string t)
|
|
{
|
|
if (t != _text) {
|
|
_text_texture.reset();
|
|
_text = std::move(t);
|
|
}
|
|
}
|
|
|
|
void CaptionImpl::_handle_font_change(const std::shared_ptr<Font>&)
|
|
{
|
|
_text_texture.reset();
|
|
}
|
|
|
|
void CaptionImpl::_handle_font_color_change(const Color fg, const Color bg)
|
|
{
|
|
if (fg != _font_color_fg) {
|
|
_text_texture.reset();
|
|
_font_color_fg = fg;
|
|
}
|
|
if (bg != _font_color_bg && _font_render_mode == Font::RenderMode::SHADED) {
|
|
_text_texture.reset();
|
|
_font_color_bg = fg;
|
|
}
|
|
}
|
|
|
|
void CaptionImpl::_handle_geometry_change(const SDL_Rect& vp)
|
|
{
|
|
if (vp.w != _viewport.w) {
|
|
_widget_area = rect_margin({0, 0, vp.w, vp.h}, margins);
|
|
}
|
|
else if (vp.h != _viewport.h) {
|
|
_widget_area = rect_margin({0, 0, vp.w, vp.h}, margins);
|
|
_text_texture.reset();
|
|
}
|
|
}
|
|
|
|
void CaptionImpl::_handle_renderer_change(const std::shared_ptr<Renderer>&)
|
|
{
|
|
_text_texture.reset();
|
|
}
|
|
|
|
void CaptionImpl::_handle_rendering()
|
|
{
|
|
if (!_text_texture) _handle_texture_update();
|
|
|
|
// fill caption viewport with background color when using
|
|
// shaded text rendering mode.
|
|
if (_render_mode == Font::RenderMode::SHADED) {
|
|
_renderer->draw_color(_font_color_bg)
|
|
->fill_rect({0, 0, _viewport.w, _viewport.h});
|
|
}
|
|
|
|
const Size size_dst {
|
|
(int)((float)_text_texture->attributes().w / (float)_text_texture->attributes().h
|
|
* (float)_widget_area.h),
|
|
_widget_area.h};
|
|
|
|
const auto texture_dst = [size_dst, this]() -> SDL_Rect {
|
|
switch (alignment) {
|
|
case Alignment::CENTER:
|
|
return {center_line(_widget_area.w, size_dst.w) + _widget_area.x,
|
|
margins.h, size_dst.w, size_dst.h};
|
|
case Alignment::LEFT:
|
|
return {margins.w, margins.h, size_dst.w, size_dst.h};
|
|
case Alignment::RIGHT:
|
|
return {_widget_area.w - size_dst.w - margins.w + _widget_area.x,
|
|
margins.h, size_dst.w, size_dst.h};
|
|
default:
|
|
throw std::logic_error("missing switch case.");
|
|
}
|
|
}();
|
|
_renderer->copy(*_text_texture, nullptr, texture_dst);
|
|
}
|
|
|
|
void CaptionImpl::_handle_texture_update()
|
|
{
|
|
if (!_font) return;
|
|
_text_texture.reset();
|
|
|
|
auto s = [this]() {
|
|
switch (_render_mode) {
|
|
case Font::RenderMode::SHADED:
|
|
return _font->render(_render_mode, _text, _font_color_fg,
|
|
_font_color_bg);
|
|
default:
|
|
return _font->render(_render_mode, _text, _font_color_fg);
|
|
}
|
|
}();
|
|
_text_texture = std::make_shared<Texture>(*_renderer, s.get());
|
|
}
|