From 6149c486647ed4f78842cab87676fadfe872396f Mon Sep 17 00:00:00 2001 From: Andrea Blankenstijn Date: Tue, 1 Feb 2022 19:07:24 +0100 Subject: [PATCH] default fonts in theme, custom with FontHandler. fix input highlight. render multiline text. remove default theme singleton. scrollable area texture alignment. --- examples/input_example.cpp | 1 - examples/run.hpp | 6 ++ examples/scrollable_area_example.cpp | 5 +- examples/scrollbar_example.cpp | 1 - inc/basic_widgets/core/draw.hpp | 5 ++ inc/basic_widgets/w/base/input.hpp | 2 - inc/basic_widgets/w/base/input_impl.hpp | 34 ++++----- inc/basic_widgets/w/base/theme.hpp | 28 ++++++- inc/basic_widgets/w/base/widget.hpp | 1 - inc/basic_widgets/w/button_impl.hpp | 1 + inc/basic_widgets/w/default_theme.hpp | 22 ++++-- inc/basic_widgets/w/feat/font_handler.hpp | 6 +- .../w/feat/font_handler_impl.hpp | 2 +- inc/basic_widgets/w/numeric_input.hpp | 3 - inc/basic_widgets/w/numeric_input_impl.hpp | 23 ++---- inc/basic_widgets/w/scrollable_area.hpp | 23 ++++-- inc/basic_widgets/w/scrollable_area_impl.hpp | 16 ++-- inc/basic_widgets/w/scrollbar.hpp | 2 - inc/basic_widgets/w/scrollbar_impl.hpp | 4 - src/core/draw.cpp | 34 +++++++++ src/w/base/widget_impl.cpp | 2 +- src/w/button_impl.cpp | 6 ++ src/w/caption_impl.cpp | 8 +- src/w/default_theme.cpp | 74 ++++++++++++++++--- src/w/scrollable_area_impl.cpp | 64 ++++++++++++---- src/w/scrollbar_impl.cpp | 20 +---- 26 files changed, 266 insertions(+), 127 deletions(-) diff --git a/examples/input_example.cpp b/examples/input_example.cpp index 07f0a3b..84dddda 100644 --- a/examples/input_example.cpp +++ b/examples/input_example.cpp @@ -7,7 +7,6 @@ auto main() -> int run_example>( []() { return bwidgets::create_input_float(); }, [](auto w, auto f, auto, auto, auto) { - w->font(f); w->button_step = 0.5; // NOLINT(readability-magic-numbers) w->value_range(-3.14, 8.5); // NOLINT(readability-magic-numbers) }); diff --git a/examples/run.hpp b/examples/run.hpp index f89d32a..92759a4 100644 --- a/examples/run.hpp +++ b/examples/run.hpp @@ -5,6 +5,7 @@ #include #include +#include #include template @@ -39,11 +40,16 @@ void run_example(std::function()> factory, std::make_shared(win.get(), -1, SDL_RENDERER_ACCELERATED); renderer->blend_mode(SDL_BLENDMODE_BLEND); + auto theme = std::make_shared(); + auto layout = bwidgets::create_horizontal_layout(); + layout->theme(theme); for (auto x = 0; x < w; x++) { auto col = bwidgets::create_vertical_layout(); + col->theme(theme); for (auto y = 0; y < h; y++) { auto widget = factory(); + widget->theme(theme); setup(widget.get(), font, x, y, renderer); col->add_widget(std::move(widget)); } diff --git a/examples/scrollable_area_example.cpp b/examples/scrollable_area_example.cpp index 19bda1d..b2f00b5 100644 --- a/examples/scrollable_area_example.cpp +++ b/examples/scrollable_area_example.cpp @@ -8,8 +8,9 @@ auto main() -> int run_example( []() { return bwidgets::create_scrollable_area(); }, [](auto w, auto f, auto x, auto y, auto r) { - w->font(f); - w->texture(bwidgets::filled_circle({255, 0, 0, 255}, 300, *r)); + w->texture(bwidgets::render_text({"h", "e", "l", "l", "o", ", World!"}, + w->theme()->color_font_fg(), + *w->theme()->font_default_biggest(), *r)); }); return 0; } diff --git a/examples/scrollbar_example.cpp b/examples/scrollbar_example.cpp index eacce47..7f64129 100644 --- a/examples/scrollbar_example.cpp +++ b/examples/scrollbar_example.cpp @@ -8,7 +8,6 @@ auto main() -> int { run_example([]() { return bwidgets::create_scrollbar(); }, [](auto w, auto f, auto x, auto y, auto) { - w->font(f); w->on_scroll([x, y](const float v) { std::cout << "Scroll(" << x << "," << y << "): " << v * 100 << "%" diff --git a/inc/basic_widgets/core/draw.hpp b/inc/basic_widgets/core/draw.hpp index 2991204..b2f0e44 100644 --- a/inc/basic_widgets/core/draw.hpp +++ b/inc/basic_widgets/core/draw.hpp @@ -3,6 +3,8 @@ #include #include +#include +#include struct SDL_PixelFormat; struct SDL_Point; @@ -11,6 +13,7 @@ struct SDL_Rect; namespace bwidgets { class Color; + class Font; class Renderer; class Texture; @@ -26,6 +29,8 @@ namespace bwidgets // aa_pixels used for antialiasing. [[nodiscard]] auto filled_circle(Color c, int resolution, const Renderer&, int aa_pixels = 3) -> std::shared_ptr; + [[nodiscard]] auto render_text(const std::vector&, const Color&, Font&, + const Renderer&) -> std::shared_ptr; // Set the color of every pixels of a Texture using the passed function to compute // pixel color. void diff --git a/inc/basic_widgets/w/base/input.hpp b/inc/basic_widgets/w/base/input.hpp index c2779bf..df64353 100644 --- a/inc/basic_widgets/w/base/input.hpp +++ b/inc/basic_widgets/w/base/input.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include @@ -12,7 +11,6 @@ namespace bwidgets template class Input : public virtual Widget, - public virtual FontHandler, public virtual KeyboardHandler, public virtual MouseHandler { diff --git a/inc/basic_widgets/w/base/input_impl.hpp b/inc/basic_widgets/w/base/input_impl.hpp index 6b12505..d9e0489 100644 --- a/inc/basic_widgets/w/base/input_impl.hpp +++ b/inc/basic_widgets/w/base/input_impl.hpp @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -18,7 +17,6 @@ namespace bwidgets { template class InputImpl : public virtual Input, - public virtual FontHandlerImpl, public virtual KeyboardHandlerImpl, public virtual MouseHandlerImpl, public virtual WidgetImpl @@ -52,15 +50,17 @@ namespace bwidgets [[nodiscard]] auto size() const noexcept -> Size override { - if (!_font) return {0, 0}; + if (!theme()) return {0, 0}; return { - _font + theme() + ->font_default() ->text_size( std::string(InputImpl::input_min_width, InputImpl::input_width_unit)) .w + 2 * theme()->size_widget_border(), - _font->line_skip + 4 * theme()->size_widget_border() // _why_ 4 and not 2?… + theme()->font_default()->line_skip + + 4 * theme()->size_widget_border() // _why_ 4 and not 2?… }; } @@ -182,20 +182,6 @@ namespace bwidgets _input_caption->font_color_bg(theme()->color_input_bg()); }); enable_mouse_handler(_text_area, viewport()); - - _input_caption->font_color_bg(theme()->color_input_bg()); - } - - void _handle_font_change(const std::shared_ptr& f) override - { - _input_caption->font(f); - _handle_geometry_change(viewport()); - } - - void _handle_font_color_change(const Color fg, const Color bg) override - { - _input_caption->font_color_bg(bg); - _input_caption->font_color_fg(fg); } void _handle_geometry_change(const SDL_Rect& vp) override @@ -218,12 +204,20 @@ namespace bwidgets void _handle_rendering() override { const auto& color_end = - focus() ? theme()->color_input_bg_active() : theme()->color_input_bg(); + focus() || hovered() ? theme()->color_input_bg_active() : theme()->color_input_bg(); fill_rect_gradient(*renderer(), _text_area, theme()->color_widget_border(), color_end, theme()->size_widget_border()); _input_caption->render(); } + + void _handle_theme_change(const std::shared_ptr& t) override + { + _input_caption->theme(t); + _input_caption->font(t->font_default()); + _input_caption->font_color_bg(t->color_input_bg()); + _input_caption->font_color_fg(t->color_input_fg()); + } }; } diff --git a/inc/basic_widgets/w/base/theme.hpp b/inc/basic_widgets/w/base/theme.hpp index 18fba64..1a0b0e2 100644 --- a/inc/basic_widgets/w/base/theme.hpp +++ b/inc/basic_widgets/w/base/theme.hpp @@ -1,6 +1,7 @@ #ifndef BWIDGETS_THEME_HPP #define BWIDGETS_THEME_HPP +#include #include #include @@ -9,6 +10,17 @@ namespace bwidgets class Theme { public: + enum class FontEnum + { + MONO, + MONO_BIG, + MONO_BIGGER, + MONO_BIGGEST, + MONO_SMALL, + MONO_SMALLER, + MONO_SMALLEST + }; + virtual ~Theme() = default; [[nodiscard]] virtual auto color_font_bg() const -> const Color& = 0; @@ -21,7 +33,21 @@ namespace bwidgets [[nodiscard]] virtual auto color_widget_bg_hl() const -> const Color& = 0; [[nodiscard]] virtual auto color_widget_border() const -> const Color& = 0; [[nodiscard]] virtual auto color_widget_border_pushed() const - -> const Color& = 0; + -> const Color& = 0; + [[nodiscard]] virtual auto font(FontEnum) -> const std::shared_ptr& = 0; + [[nodiscard]] virtual auto font_default() -> const std::shared_ptr& = 0; + [[nodiscard]] virtual auto font_default_big() + -> const std::shared_ptr& = 0; + [[nodiscard]] virtual auto font_default_bigger() + -> const std::shared_ptr& = 0; + [[nodiscard]] virtual auto font_default_biggest() + -> const std::shared_ptr& = 0; + [[nodiscard]] virtual auto font_default_small() + -> const std::shared_ptr& = 0; + [[nodiscard]] virtual auto font_default_smaller() + -> const std::shared_ptr& = 0; + [[nodiscard]] virtual auto font_default_smallest() + -> const std::shared_ptr& = 0; [[nodiscard]] virtual auto size_layout_margin() const -> const Size& = 0; [[nodiscard]] virtual auto size_widget_border() const -> int = 0; }; diff --git a/inc/basic_widgets/w/base/widget.hpp b/inc/basic_widgets/w/base/widget.hpp index d4794f6..9dcbe5a 100644 --- a/inc/basic_widgets/w/base/widget.hpp +++ b/inc/basic_widgets/w/base/widget.hpp @@ -17,7 +17,6 @@ namespace bwidgets class Widget : public virtual EventHandler { public: - explicit Widget(Widget* p = nullptr) {}; [[nodiscard]] virtual auto parent() -> Widget* = 0; virtual void parent(Widget*) = 0; // Render widget on current renderer target. diff --git a/inc/basic_widgets/w/button_impl.hpp b/inc/basic_widgets/w/button_impl.hpp index 60f82a0..5d200ee 100644 --- a/inc/basic_widgets/w/button_impl.hpp +++ b/inc/basic_widgets/w/button_impl.hpp @@ -32,6 +32,7 @@ namespace bwidgets void _handle_geometry_change(const SDL_Rect&) override; void _handle_renderer_change(const std::shared_ptr&) override; void _handle_rendering() override; + void _handle_theme_change(const std::shared_ptr&) override; void _on_push(bool) override; }; } diff --git a/inc/basic_widgets/w/default_theme.hpp b/inc/basic_widgets/w/default_theme.hpp index 4d84c76..b8d31ab 100644 --- a/inc/basic_widgets/w/default_theme.hpp +++ b/inc/basic_widgets/w/default_theme.hpp @@ -1,6 +1,7 @@ #ifndef BWIDGETS_DEFAULT_THEME_HPP #define BWIDGETS_DEFAULT_THEME_HPP +#include #include #include @@ -20,6 +21,18 @@ namespace bwidgets [[nodiscard]] auto color_widget_bg_hl() const -> const Color& override; [[nodiscard]] auto color_widget_border() const -> const Color& override; [[nodiscard]] auto color_widget_border_pushed() const -> const Color& override; + [[nodiscard]] auto font(FontEnum) -> const std::shared_ptr& override; + [[nodiscard]] auto font_default() -> const std::shared_ptr& override; + [[nodiscard]] auto font_default_big() -> const std::shared_ptr& override; + [[nodiscard]] auto font_default_bigger() + -> const std::shared_ptr& override; + [[nodiscard]] auto font_default_biggest() + -> const std::shared_ptr& override; + [[nodiscard]] auto font_default_small() -> const std::shared_ptr& override; + [[nodiscard]] auto font_default_smaller() + -> const std::shared_ptr& override; + [[nodiscard]] auto font_default_smallest() + -> const std::shared_ptr& override; [[nodiscard]] auto size_layout_margin() const -> const Size& override; [[nodiscard]] auto size_widget_border() const -> int override; @@ -36,15 +49,8 @@ namespace bwidgets static const Color _color_widget_border_pushed; static const Size _size_layout_margin; static const int _size_widget_border; - }; - class DefaultThemeInstance final - { - public: - [[nodiscard]] static auto get() -> std::shared_ptr; - - private: - static std::shared_ptr _instance; + std::map> _fonts; }; } diff --git a/inc/basic_widgets/w/feat/font_handler.hpp b/inc/basic_widgets/w/feat/font_handler.hpp index c65a5b8..5e934fb 100644 --- a/inc/basic_widgets/w/feat/font_handler.hpp +++ b/inc/basic_widgets/w/feat/font_handler.hpp @@ -19,12 +19,12 @@ namespace bwidgets virtual ~FontHandler() noexcept = default; // Set the used font. - virtual void font(std::shared_ptr f) = 0; + virtual void font(const std::shared_ptr& f) = 0; // Set background color used for shaded text rendering // mode. - virtual void font_color_bg(Color c) = 0; + virtual void font_color_bg(Color c) = 0; // Set foreground (glyphs) color. - virtual void font_color_fg(Color c) = 0; + virtual void font_color_fg(Color c) = 0; protected: FontHandler() noexcept = default; diff --git a/inc/basic_widgets/w/feat/font_handler_impl.hpp b/inc/basic_widgets/w/feat/font_handler_impl.hpp index 28f2e3d..79613a5 100644 --- a/inc/basic_widgets/w/feat/font_handler_impl.hpp +++ b/inc/basic_widgets/w/feat/font_handler_impl.hpp @@ -8,7 +8,7 @@ namespace bwidgets class FontHandlerImpl : public virtual FontHandler { public: - void font(const std::shared_ptr f) final + void font(const std::shared_ptr& f) final { if (f && (f != _font || f->family_name != _font->family_name diff --git a/inc/basic_widgets/w/numeric_input.hpp b/inc/basic_widgets/w/numeric_input.hpp index 1cb5b3b..7f5c5c9 100644 --- a/inc/basic_widgets/w/numeric_input.hpp +++ b/inc/basic_widgets/w/numeric_input.hpp @@ -9,9 +9,6 @@ namespace bwidgets template class NumericInput : public virtual Input { - protected: - using Input::Input; - public: // Button increment/decrement step. T button_step = 1; diff --git a/inc/basic_widgets/w/numeric_input_impl.hpp b/inc/basic_widgets/w/numeric_input_impl.hpp index afc9a25..86f811d 100644 --- a/inc/basic_widgets/w/numeric_input_impl.hpp +++ b/inc/basic_widgets/w/numeric_input_impl.hpp @@ -132,22 +132,6 @@ namespace bwidgets std::pair _value_range {std::numeric_limits::lowest(), std::numeric_limits::max()}; - void _handle_font_change(const std::shared_ptr& f) override - { - _decrement_button->font(f); - _increment_button->font(f); - InputImpl::_handle_font_change(f); - } - - void _handle_font_color_change(const Color fg, const Color bg) override - { - InputImpl::_handle_font_color_change(fg, bg); - _decrement_button->font_color_bg(bg); - _decrement_button->font_color_fg(fg); - _increment_button->font_color_bg(bg); - _increment_button->font_color_fg(fg); - } - void _handle_geometry_change(const SDL_Rect& vp) override { InputImpl::_handle_geometry_change(vp); @@ -192,6 +176,13 @@ namespace bwidgets _increment_button->render(); _decrement_button->render(); } + + void _handle_theme_change(const std::shared_ptr& t) override + { + InputImpl::_handle_theme_change(t); + _increment_button->theme(t); + _decrement_button->theme(t); + } }; } diff --git a/inc/basic_widgets/w/scrollable_area.hpp b/inc/basic_widgets/w/scrollable_area.hpp index c9e9923..c541237 100644 --- a/inc/basic_widgets/w/scrollable_area.hpp +++ b/inc/basic_widgets/w/scrollable_area.hpp @@ -2,18 +2,31 @@ #define BWIDGETS_SCROLLABLE_AREA_HPP #include -#include #include "basic_widgets/core/texture.hpp" namespace bwidgets { - class ScrollableArea : public virtual Widget, - public virtual FontHandler + class ScrollableArea : public virtual Widget { public: - virtual auto texture() -> const std::shared_ptr& = 0; - virtual void texture(std::shared_ptr) = 0; + enum class Alignment + { + BOTTOM_CENTER, + BOTTOM_LEFT, + BOTTOM_RIGHT, + CENTER_CENTER, + CENTER_LEFT, + CENTER_RIGHT, + TOP_CENTER, + TOP_LEFT, + TOP_RIGHT + }; + + [[nodiscard]] virtual auto alignment() -> Alignment = 0; + virtual void alignment(Alignment) = 0; + [[nodiscard]] virtual auto texture() -> const std::shared_ptr& = 0; + virtual void texture(std::shared_ptr) = 0; }; } diff --git a/inc/basic_widgets/w/scrollable_area_impl.hpp b/inc/basic_widgets/w/scrollable_area_impl.hpp index 4e6c650..6b41748 100644 --- a/inc/basic_widgets/w/scrollable_area_impl.hpp +++ b/inc/basic_widgets/w/scrollable_area_impl.hpp @@ -2,32 +2,32 @@ #define BWIDGETS_SCROLLABLE_AREA_IMPL_HPP #include -#include #include #include namespace bwidgets { class ScrollableAreaImpl : public virtual ScrollableArea, - public virtual WidgetImpl, - public virtual FontHandlerImpl + public virtual WidgetImpl { public: ScrollableAreaImpl(Widget* parent = nullptr); - void handle_event(const SDL_Event&) override; - auto size() const noexcept -> Size override; - auto texture() -> const std::shared_ptr& override; - void texture(std::shared_ptr) override; + [[nodiscard]] auto alignment() -> Alignment override; + void alignment(Alignment) override; + void handle_event(const SDL_Event&) override; + [[nodiscard]] auto size() const noexcept -> Size override; + [[nodiscard]] auto texture() -> const std::shared_ptr& override; + void texture(std::shared_ptr) override; protected: - void _handle_font_change(const std::shared_ptr&) override; void _handle_geometry_change(const SDL_Rect&) override; void _handle_renderer_change(const std::shared_ptr&) override; void _handle_rendering() override; void _handle_theme_change(const std::shared_ptr&) override; private: + Alignment _alignment; std::unique_ptr _scrollbar_h; std::unique_ptr _scrollbar_v; std::shared_ptr _texture; diff --git a/inc/basic_widgets/w/scrollbar.hpp b/inc/basic_widgets/w/scrollbar.hpp index fb09c72..dc2647f 100644 --- a/inc/basic_widgets/w/scrollbar.hpp +++ b/inc/basic_widgets/w/scrollbar.hpp @@ -4,13 +4,11 @@ #include #include -#include #include namespace bwidgets { class ScrollBar : public virtual Widget, - public virtual FontHandler, public virtual MouseHandler { public: diff --git a/inc/basic_widgets/w/scrollbar_impl.hpp b/inc/basic_widgets/w/scrollbar_impl.hpp index cf1d8c3..81a66cd 100644 --- a/inc/basic_widgets/w/scrollbar_impl.hpp +++ b/inc/basic_widgets/w/scrollbar_impl.hpp @@ -6,7 +6,6 @@ #include #include -#include #include #include @@ -14,7 +13,6 @@ namespace bwidgets { class ScrollBarImpl : public virtual ScrollBar, public virtual WidgetImpl, - public virtual FontHandlerImpl, public virtual MouseHandlerImpl { public: @@ -42,8 +40,6 @@ namespace bwidgets float _step; float _value {0}; - void _handle_font_change(const std::shared_ptr&) override; - void _handle_font_color_change(Color, Color) override; void _handle_geometry_change(const SDL_Rect&) override; void _handle_renderer_change(const std::shared_ptr&) override; void _handle_rendering() override; diff --git a/src/core/draw.cpp b/src/core/draw.cpp index ad00f4d..d12543a 100644 --- a/src/core/draw.cpp +++ b/src/core/draw.cpp @@ -1,12 +1,19 @@ #include #include +#include #include +#include + #include +#include #include #include #include +#include "basic_widgets/core/type/sdl_error.hpp" +#include "SDL_surface.h" + namespace bwidgets { auto aa(const Color base_color, const int aa_pixels, const float d) noexcept -> Color @@ -66,6 +73,33 @@ namespace bwidgets return texture; } + auto render_text(const std::vector& lines, const Color& c, Font& f, + const Renderer& r) -> std::shared_ptr + { + int width {0}; + std::queue> surfaces {}; + for (const auto& l : lines) { + auto s = f.render(Font::RenderMode::BLENDED, l, c); + if (s->w > width) width = s->w; + surfaces.emplace(std::move(s)); + } + + std::unique_ptr text_surface { + SDL_CreateRGBSurfaceWithFormat(0, width, surfaces.size() * f.height, 32, + SDL_PIXELFORMAT_RGBA32)}; + int y {0}; + int i {0}; + while (!surfaces.empty()) { + auto& s {surfaces.front()}; + SDL_Rect dst {0, y, s->w, s->h}; + SDL_BlitSurface(s.get(), nullptr, text_surface.get(), &dst); + surfaces.pop(); + y += f.height; + } + + return std::make_shared(r, text_surface.get()); + } + void set_pixels_color( Texture* t, const std::function& pixel_color) diff --git a/src/w/base/widget_impl.cpp b/src/w/base/widget_impl.cpp index b3041ac..7b5b25c 100644 --- a/src/w/base/widget_impl.cpp +++ b/src/w/base/widget_impl.cpp @@ -3,7 +3,7 @@ using namespace bwidgets; -WidgetImpl::WidgetImpl(Widget* p) : _parent {p}, _theme {DefaultThemeInstance::get()} {} +WidgetImpl::WidgetImpl(Widget* p) : _parent {p}, _theme {nullptr} {} auto WidgetImpl::parent() -> Widget* { diff --git a/src/w/button_impl.cpp b/src/w/button_impl.cpp index 39fc0bf..fb701a5 100644 --- a/src/w/button_impl.cpp +++ b/src/w/button_impl.cpp @@ -59,6 +59,12 @@ void ButtonImpl::_handle_renderer_change(const std::shared_ptr& r) _caption->renderer(r); } +void ButtonImpl::_handle_theme_change(const std::shared_ptr& t) +{ + _caption->theme(t); + _caption->font(t->font_default()); +} + void ButtonImpl::_handle_rendering() { const Color& c = diff --git a/src/w/caption_impl.cpp b/src/w/caption_impl.cpp index b9283f5..ad4b2a9 100644 --- a/src/w/caption_impl.cpp +++ b/src/w/caption_impl.cpp @@ -5,11 +5,7 @@ using namespace bwidgets; -CaptionImpl::CaptionImpl(Widget* parent) noexcept : WidgetImpl {parent} -{ - _font_color_bg = theme()->color_font_bg(); - _font_color_fg = theme()->color_font_fg(); -} +CaptionImpl::CaptionImpl(Widget* parent) noexcept : WidgetImpl {parent} {} auto CaptionImpl::alignment() const -> Alignment { @@ -82,7 +78,7 @@ void CaptionImpl::_handle_renderer_change(const std::shared_ptr&) void CaptionImpl::_handle_rendering() { if (!_text_texture) _handle_texture_update(); - // TODO: what if texture can't be loaded? + if (!_text_texture) throw std::runtime_error("can't render text"); // fill caption viewport with background color when using // shaded text rendering mode. diff --git a/src/w/default_theme.cpp b/src/w/default_theme.cpp index 0a4784e..a4d2205 100644 --- a/src/w/default_theme.cpp +++ b/src/w/default_theme.cpp @@ -3,11 +3,9 @@ using namespace bwidgets; using namespace std; -// DefaultTheme - const Color DefaultTheme::_color_font_bg = {200, 200, 200, SDL_ALPHA_OPAQUE}; const Color DefaultTheme::_color_font_fg = {60, 60, 60, SDL_ALPHA_OPAQUE}; -const Color DefaultTheme::_color_input_bg = {180, 180, 180, SDL_ALPHA_OPAQUE}; +const Color DefaultTheme::_color_input_bg = {170, 170, 170, SDL_ALPHA_OPAQUE}; const Color DefaultTheme::_color_input_bg_active = _color_font_bg; const Color DefaultTheme::_color_input_fg = _color_font_fg; const Color DefaultTheme::_color_widget_bg = {160, 160, 160, SDL_ALPHA_OPAQUE}; @@ -68,6 +66,67 @@ auto DefaultTheme::color_widget_border_pushed() const -> const Color& return _color_widget_border_pushed; } +auto DefaultTheme::font(FontEnum f) -> const shared_ptr& +{ + if (!_fonts.contains(f) || !_fonts[f]) { + _fonts.insert_or_assign(f, [f]() { + switch (f) { + case FontEnum::MONO: + return make_shared(Font::find("Monospace"), 14); + case FontEnum::MONO_BIG: + return make_shared(Font::find("Monospace"), 18); + case FontEnum::MONO_BIGGER: + return make_shared(Font::find("Monospace"), 24); + case FontEnum::MONO_BIGGEST: + return make_shared(Font::find("Monospace"), 32); + case FontEnum::MONO_SMALL: + return make_shared(Font::find("Monospace"), 12); + case FontEnum::MONO_SMALLER: + return make_shared(Font::find("Monospace"), 10); + case FontEnum::MONO_SMALLEST: + return make_shared(Font::find("Monospace"), 8); + } + }()); + } + + return _fonts[f]; +} + +auto DefaultTheme::font_default() -> const shared_ptr& +{ + return font(FontEnum::MONO); +} + +auto DefaultTheme::font_default_big() -> const shared_ptr& +{ + return font(FontEnum::MONO_BIG); +} + +auto DefaultTheme::font_default_bigger() -> const shared_ptr& +{ + return font(FontEnum::MONO_BIGGER); +} + +auto DefaultTheme::font_default_biggest() -> const shared_ptr& +{ + return font(FontEnum::MONO_BIGGEST); +} + +auto DefaultTheme::font_default_small() -> const shared_ptr& +{ + return font(FontEnum::MONO_SMALL); +} + +auto DefaultTheme::font_default_smaller() -> const shared_ptr& +{ + return font(FontEnum::MONO_SMALLER); +} + +auto DefaultTheme::font_default_smallest() -> const shared_ptr& +{ + return font(FontEnum::MONO_SMALLEST); +} + auto DefaultTheme::size_layout_margin() const -> const Size& { return _size_layout_margin; @@ -78,12 +137,3 @@ auto DefaultTheme::size_widget_border() const -> int return _size_widget_border; } -// DefaultThemeInstance - -std::shared_ptr DefaultThemeInstance::_instance = nullptr; - -auto DefaultThemeInstance::get() -> std::shared_ptr -{ - if (!_instance) _instance = make_shared(); - return _instance; -} diff --git a/src/w/scrollable_area_impl.cpp b/src/w/scrollable_area_impl.cpp index 3c3fee1..026b21f 100644 --- a/src/w/scrollable_area_impl.cpp +++ b/src/w/scrollable_area_impl.cpp @@ -10,6 +10,7 @@ using namespace std; ScrollableAreaImpl::ScrollableAreaImpl(Widget* p) : WidgetImpl {p}, + _alignment {Alignment::CENTER_CENTER}, _scrollbar_h {create_scrollbar(this)}, _scrollbar_v {create_scrollbar(this)}, _texture {nullptr}, @@ -19,6 +20,16 @@ ScrollableAreaImpl::ScrollableAreaImpl(Widget* p) _scrollbar_v->orientation(ScrollBar::Orientation::VERTICAL); } +auto ScrollableAreaImpl::alignment() -> Alignment +{ + return _alignment; +} + +void ScrollableAreaImpl::alignment(Alignment a) +{ + _alignment = a; +} + void ScrollableAreaImpl::handle_event(const SDL_Event& ev) { WidgetImpl::handle_event(ev); @@ -38,15 +49,12 @@ auto ScrollableAreaImpl::texture() -> const shared_ptr& void ScrollableAreaImpl::texture(shared_ptr t) { + const auto& attr {t->attributes()}; + _scrollbar_h->step(1.0F / attr.w * 20.F); + _scrollbar_v->step(1.0F / attr.h * 20.F); _texture = move(t); } -void ScrollableAreaImpl::_handle_font_change(const shared_ptr& f) -{ - _scrollbar_h->font(f); - _scrollbar_v->font(f); -} - void ScrollableAreaImpl::_handle_geometry_change(const SDL_Rect& vp) { const auto reserved_h = _scrollbar_h->size().w; @@ -71,15 +79,45 @@ void ScrollableAreaImpl::_handle_rendering() theme()->color_widget_bg(), theme()->size_widget_border()); const auto texture_attr = _texture->attributes(); - const auto copy_dst = [this, &texture_attr]() { + const auto dst_rect = [this, &texture_attr]() { auto dst = rect_margin( _texture_area, {theme()->size_widget_border(), theme()->size_widget_border()}); if (dst.w > texture_attr.w) { - dst.x += center_line(dst.w, texture_attr.w); + switch (alignment()) { + case Alignment::BOTTOM_CENTER: + case Alignment::CENTER_CENTER: + case Alignment::TOP_CENTER: + dst.x += center_line(dst.w, texture_attr.w); + break; + case Alignment::BOTTOM_LEFT: + case Alignment::CENTER_LEFT: + case Alignment::TOP_LEFT: + break; + case Alignment::BOTTOM_RIGHT: + case Alignment::CENTER_RIGHT: + case Alignment::TOP_RIGHT: + dst.x += dst.w - texture_attr.w; + break; + } dst.w = texture_attr.w; } if (dst.h > texture_attr.h) { - dst.y += center_line(dst.h, texture_attr.h); + switch (alignment()) { + case Alignment::BOTTOM_CENTER: + case Alignment::BOTTOM_LEFT: + case Alignment::BOTTOM_RIGHT: + dst.y += dst.h - texture_attr.h; + break; + case Alignment::CENTER_CENTER: + case Alignment::CENTER_LEFT: + case Alignment::CENTER_RIGHT: + dst.y += center_line(dst.h, texture_attr.h); + break; + case Alignment::TOP_CENTER: + case Alignment::TOP_LEFT: + case Alignment::TOP_RIGHT: + break; + } dst.h = texture_attr.h; } return dst; @@ -87,11 +125,11 @@ void ScrollableAreaImpl::_handle_rendering() renderer()->copy( *_texture, {static_cast(_scrollbar_h->value() - * std::clamp(texture_attr.w - copy_dst.w, 0, texture_attr.w)), + * clamp(texture_attr.w - dst_rect.w, 0, texture_attr.w)), static_cast(_scrollbar_v->value() - * std::clamp(texture_attr.h - copy_dst.h, 0, texture_attr.h)), - copy_dst.w, copy_dst.h}, - copy_dst); + * clamp(texture_attr.h - dst_rect.h, 0, texture_attr.h)), + dst_rect.w, dst_rect.h}, + dst_rect); _scrollbar_h->render(); _scrollbar_v->render(); diff --git a/src/w/scrollbar_impl.cpp b/src/w/scrollbar_impl.cpp index 4a5630d..37aa8f2 100644 --- a/src/w/scrollbar_impl.cpp +++ b/src/w/scrollbar_impl.cpp @@ -129,11 +129,7 @@ auto ScrollBarImpl::size() const noexcept -> Size return {width, button_size + button_size + 3 * _cursor_size.h}; } - const auto height = [this, button_size]() { - const auto button_max_height = - button_size > button_size ? button_size : button_size; - return button_max_height > _cursor_size.w ? button_max_height : _cursor_size.w; - }(); + const auto height = button_size > _cursor_size.w ? button_size : _cursor_size.w; return {height, button_size + button_size + 3 * _cursor_size.h}; } @@ -161,18 +157,6 @@ void ScrollBarImpl::value(const float v) } } -void ScrollBarImpl::_handle_font_change(const shared_ptr& f) -{ - _button_minus->font(f); - _button_plus->font(f); -} - -void ScrollBarImpl::_handle_font_color_change(const Color fg, Color) -{ - _button_minus->font_color_fg(fg); - _button_plus->font_color_fg(fg); -} - void ScrollBarImpl::_handle_geometry_change(const SDL_Rect& vp) { const auto button_size = @@ -213,5 +197,7 @@ void ScrollBarImpl::_handle_rendering() void ScrollBarImpl::_handle_theme_change(const shared_ptr& t) { _button_minus->theme(t); + _button_minus->font(t->font_default_smaller()); _button_plus->theme(t); + _button_plus->font(t->font_default_smaller()); }