default fonts in theme, custom with FontHandler.

fix input highlight.
render multiline text.
remove default theme singleton.
scrollable area texture alignment.
This commit is contained in:
Andrea Blankenstijn 2022-02-01 19:07:24 +01:00
parent 3f15d1d857
commit 6149c48664
26 changed files with 266 additions and 127 deletions

View file

@ -7,7 +7,6 @@ auto main() -> int
run_example<bwidgets::NumericInput<float>>(
[]() { 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)
});

View file

@ -5,6 +5,7 @@
#include <iostream>
#include <basic_widgets/core/type/deleter.hpp>
#include <basic_widgets/w/default_theme.hpp>
#include <basic_widgets/w/widget_factory.hpp>
template<typename T>
@ -39,11 +40,16 @@ void run_example(std::function<std::unique_ptr<W>()> factory,
std::make_shared<bwidgets::Renderer>(win.get(), -1, SDL_RENDERER_ACCELERATED);
renderer->blend_mode(SDL_BLENDMODE_BLEND);
auto theme = std::make_shared<bwidgets::DefaultTheme>();
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));
}

View file

@ -8,8 +8,9 @@ auto main() -> int
run_example<bwidgets::ScrollableArea>(
[]() { 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;
}

View file

@ -8,7 +8,6 @@ auto main() -> int
{
run_example<bwidgets::ScrollBar>([]() { 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 << "%"

View file

@ -3,6 +3,8 @@
#include <functional>
#include <memory>
#include <string>
#include <vector>
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<Texture>;
[[nodiscard]] auto render_text(const std::vector<std::string>&, const Color&, Font&,
const Renderer&) -> std::shared_ptr<Texture>;
// Set the color of every pixels of a Texture using the passed function to compute
// pixel color.
void

View file

@ -3,7 +3,6 @@
#include <basic_widgets/core/type/concepts.hpp>
#include <basic_widgets/w/base/widget.hpp>
#include <basic_widgets/w/feat/font_handler.hpp>
#include <basic_widgets/w/feat/keyboard_handler.hpp>
#include <basic_widgets/w/feat/mouse_handler.hpp>
@ -12,7 +11,6 @@ namespace bwidgets
template<typename T>
class Input : public virtual Widget,
public virtual FontHandler,
public virtual KeyboardHandler,
public virtual MouseHandler
{

View file

@ -9,7 +9,6 @@
#include <basic_widgets/w/base/input.hpp>
#include <basic_widgets/w/base/widget_impl.hpp>
#include <basic_widgets/w/caption.hpp>
#include <basic_widgets/w/feat/font_handler_impl.hpp>
#include <basic_widgets/w/feat/keyboard_handler_impl.hpp>
#include <basic_widgets/w/feat/mouse_handler_impl.hpp>
#include <basic_widgets/w/widget_factory.hpp>
@ -18,7 +17,6 @@ namespace bwidgets
{
template<typename T>
class InputImpl : public virtual Input<T>,
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<Font>& 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<Theme>& 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());
}
};
}

View file

@ -1,6 +1,7 @@
#ifndef BWIDGETS_THEME_HPP
#define BWIDGETS_THEME_HPP
#include <basic_widgets/core/font.hpp>
#include <basic_widgets/core/type/color.hpp>
#include <basic_widgets/core/type/size.hpp>
@ -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<Font>& = 0;
[[nodiscard]] virtual auto font_default() -> const std::shared_ptr<Font>& = 0;
[[nodiscard]] virtual auto font_default_big()
-> const std::shared_ptr<Font>& = 0;
[[nodiscard]] virtual auto font_default_bigger()
-> const std::shared_ptr<Font>& = 0;
[[nodiscard]] virtual auto font_default_biggest()
-> const std::shared_ptr<Font>& = 0;
[[nodiscard]] virtual auto font_default_small()
-> const std::shared_ptr<Font>& = 0;
[[nodiscard]] virtual auto font_default_smaller()
-> const std::shared_ptr<Font>& = 0;
[[nodiscard]] virtual auto font_default_smallest()
-> const std::shared_ptr<Font>& = 0;
[[nodiscard]] virtual auto size_layout_margin() const -> const Size& = 0;
[[nodiscard]] virtual auto size_widget_border() const -> int = 0;
};

View file

@ -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.

View file

@ -32,6 +32,7 @@ namespace bwidgets
void _handle_geometry_change(const SDL_Rect&) override;
void _handle_renderer_change(const std::shared_ptr<Renderer>&) override;
void _handle_rendering() override;
void _handle_theme_change(const std::shared_ptr<Theme>&) override;
void _on_push(bool) override;
};
}

View file

@ -1,6 +1,7 @@
#ifndef BWIDGETS_DEFAULT_THEME_HPP
#define BWIDGETS_DEFAULT_THEME_HPP
#include <map>
#include <memory>
#include <basic_widgets/w/base/theme.hpp>
@ -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<Font>& override;
[[nodiscard]] auto font_default() -> const std::shared_ptr<Font>& override;
[[nodiscard]] auto font_default_big() -> const std::shared_ptr<Font>& override;
[[nodiscard]] auto font_default_bigger()
-> const std::shared_ptr<Font>& override;
[[nodiscard]] auto font_default_biggest()
-> const std::shared_ptr<Font>& override;
[[nodiscard]] auto font_default_small() -> const std::shared_ptr<Font>& override;
[[nodiscard]] auto font_default_smaller()
-> const std::shared_ptr<Font>& override;
[[nodiscard]] auto font_default_smallest()
-> const std::shared_ptr<Font>& 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<DefaultTheme>;
private:
static std::shared_ptr<DefaultTheme> _instance;
std::map<FontEnum, std::shared_ptr<Font>> _fonts;
};
}

View file

@ -19,12 +19,12 @@ namespace bwidgets
virtual ~FontHandler() noexcept = default;
// Set the used font.
virtual void font(std::shared_ptr<Font> f) = 0;
virtual void font(const std::shared_ptr<Font>& 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;

View file

@ -8,7 +8,7 @@ namespace bwidgets
class FontHandlerImpl : public virtual FontHandler
{
public:
void font(const std::shared_ptr<Font> f) final
void font(const std::shared_ptr<Font>& f) final
{
if (f
&& (f != _font || f->family_name != _font->family_name

View file

@ -9,9 +9,6 @@ namespace bwidgets
template<Numeric T>
class NumericInput : public virtual Input<T>
{
protected:
using Input<T>::Input;
public:
// Button increment/decrement step.
T button_step = 1;

View file

@ -132,22 +132,6 @@ namespace bwidgets
std::pair<T, T> _value_range {std::numeric_limits<T>::lowest(),
std::numeric_limits<T>::max()};
void _handle_font_change(const std::shared_ptr<Font>& f) override
{
_decrement_button->font(f);
_increment_button->font(f);
InputImpl<T>::_handle_font_change(f);
}
void _handle_font_color_change(const Color fg, const Color bg) override
{
InputImpl<T>::_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<T>::_handle_geometry_change(vp);
@ -192,6 +176,13 @@ namespace bwidgets
_increment_button->render();
_decrement_button->render();
}
void _handle_theme_change(const std::shared_ptr<Theme>& t) override
{
InputImpl<T>::_handle_theme_change(t);
_increment_button->theme(t);
_decrement_button->theme(t);
}
};
}

View file

@ -2,18 +2,31 @@
#define BWIDGETS_SCROLLABLE_AREA_HPP
#include <basic_widgets/w/base/widget.hpp>
#include <basic_widgets/w/feat/font_handler.hpp>
#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<Texture>& = 0;
virtual void texture(std::shared_ptr<Texture>) = 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<Texture>& = 0;
virtual void texture(std::shared_ptr<Texture>) = 0;
};
}

View file

@ -2,32 +2,32 @@
#define BWIDGETS_SCROLLABLE_AREA_IMPL_HPP
#include <basic_widgets/w/base/widget_impl.hpp>
#include <basic_widgets/w/feat/font_handler_impl.hpp>
#include <basic_widgets/w/scrollable_area.hpp>
#include <basic_widgets/w/scrollbar.hpp>
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<Texture>& override;
void texture(std::shared_ptr<Texture>) 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<Texture>& override;
void texture(std::shared_ptr<Texture>) override;
protected:
void _handle_font_change(const std::shared_ptr<Font>&) override;
void _handle_geometry_change(const SDL_Rect&) override;
void _handle_renderer_change(const std::shared_ptr<Renderer>&) override;
void _handle_rendering() override;
void _handle_theme_change(const std::shared_ptr<Theme>&) override;
private:
Alignment _alignment;
std::unique_ptr<ScrollBar> _scrollbar_h;
std::unique_ptr<ScrollBar> _scrollbar_v;
std::shared_ptr<Texture> _texture;

View file

@ -4,13 +4,11 @@
#include <functional>
#include <basic_widgets/w/base/widget.hpp>
#include <basic_widgets/w/feat/font_handler.hpp>
#include <basic_widgets/w/feat/mouse_handler.hpp>
namespace bwidgets
{
class ScrollBar : public virtual Widget,
public virtual FontHandler,
public virtual MouseHandler
{
public:

View file

@ -6,7 +6,6 @@
#include <basic_widgets/w/base/widget_impl.hpp>
#include <basic_widgets/w/button.hpp>
#include <basic_widgets/w/feat/font_handler_impl.hpp>
#include <basic_widgets/w/feat/mouse_handler_impl.hpp>
#include <basic_widgets/w/scrollbar.hpp>
@ -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<Font>&) 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<Renderer>&) override;
void _handle_rendering() override;

View file

@ -1,12 +1,19 @@
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <SDL_pixels.h>
#include <basic_widgets/core/draw.hpp>
#include <basic_widgets/core/font.hpp>
#include <basic_widgets/core/math.hpp>
#include <basic_widgets/core/renderer.hpp>
#include <basic_widgets/core/texture.hpp>
#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<std::string>& lines, const Color& c, Font& f,
const Renderer& r) -> std::shared_ptr<Texture>
{
int width {0};
std::queue<std::unique_ptr<SDL_Surface, Deleter>> 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<SDL_Surface, Deleter> 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<Texture>(r, text_surface.get());
}
void set_pixels_color(
Texture* t,
const std::function<uint32_t(SDL_Point, const SDL_PixelFormat&)>& pixel_color)

View file

@ -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*
{

View file

@ -59,6 +59,12 @@ void ButtonImpl::_handle_renderer_change(const std::shared_ptr<Renderer>& r)
_caption->renderer(r);
}
void ButtonImpl::_handle_theme_change(const std::shared_ptr<Theme>& t)
{
_caption->theme(t);
_caption->font(t->font_default());
}
void ButtonImpl::_handle_rendering()
{
const Color& c =

View file

@ -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<Renderer>&)
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.

View file

@ -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<Font>&
{
if (!_fonts.contains(f) || !_fonts[f]) {
_fonts.insert_or_assign(f, [f]() {
switch (f) {
case FontEnum::MONO:
return make_shared<Font>(Font::find("Monospace"), 14);
case FontEnum::MONO_BIG:
return make_shared<Font>(Font::find("Monospace"), 18);
case FontEnum::MONO_BIGGER:
return make_shared<Font>(Font::find("Monospace"), 24);
case FontEnum::MONO_BIGGEST:
return make_shared<Font>(Font::find("Monospace"), 32);
case FontEnum::MONO_SMALL:
return make_shared<Font>(Font::find("Monospace"), 12);
case FontEnum::MONO_SMALLER:
return make_shared<Font>(Font::find("Monospace"), 10);
case FontEnum::MONO_SMALLEST:
return make_shared<Font>(Font::find("Monospace"), 8);
}
}());
}
return _fonts[f];
}
auto DefaultTheme::font_default() -> const shared_ptr<Font>&
{
return font(FontEnum::MONO);
}
auto DefaultTheme::font_default_big() -> const shared_ptr<Font>&
{
return font(FontEnum::MONO_BIG);
}
auto DefaultTheme::font_default_bigger() -> const shared_ptr<Font>&
{
return font(FontEnum::MONO_BIGGER);
}
auto DefaultTheme::font_default_biggest() -> const shared_ptr<Font>&
{
return font(FontEnum::MONO_BIGGEST);
}
auto DefaultTheme::font_default_small() -> const shared_ptr<Font>&
{
return font(FontEnum::MONO_SMALL);
}
auto DefaultTheme::font_default_smaller() -> const shared_ptr<Font>&
{
return font(FontEnum::MONO_SMALLER);
}
auto DefaultTheme::font_default_smallest() -> const shared_ptr<Font>&
{
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<DefaultTheme> DefaultThemeInstance::_instance = nullptr;
auto DefaultThemeInstance::get() -> std::shared_ptr<DefaultTheme>
{
if (!_instance) _instance = make_shared<DefaultTheme>();
return _instance;
}

View file

@ -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<Texture>&
void ScrollableAreaImpl::texture(shared_ptr<Texture> 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<Font>& 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<int>(_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<int>(_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();

View file

@ -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<Font>& 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<Theme>& t)
{
_button_minus->theme(t);
_button_minus->font(t->font_default_smaller());
_button_plus->theme(t);
_button_plus->font(t->font_default_smaller());
}