more wip on api and also on a scrollable thing widget
This commit is contained in:
parent
860b656bf7
commit
af7b9803d2
|
@ -26,7 +26,7 @@ void run_example(
|
|||
const bwidgets::Size size_init {854, 480};
|
||||
auto font =
|
||||
std::make_shared<bwidgets::Font>(bwidgets::Font::find("Monospace"),
|
||||
18); // NOLINT(readability-magic-numbers)
|
||||
14); // NOLINT(readability-magic-numbers)
|
||||
|
||||
auto win = std::unique_ptr<SDL_Window, bwidgets::Deleter>(
|
||||
bwidgets::ptr_or_throw<bwidgets::SDLError>(SDL_CreateWindow(
|
||||
|
|
11
examples/scrollable_area_example.cpp
Normal file
11
examples/scrollable_area_example.cpp
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include <basic_widgets/w/widget_factory.hpp>
|
||||
|
||||
#include "run.hpp"
|
||||
|
||||
auto main() -> int
|
||||
{
|
||||
run_example<bwidgets::ScrollableArea>(
|
||||
[]() { return bwidgets::create_scrollable_area(); },
|
||||
[](auto w, auto f, auto x, auto y) { w->font(f); });
|
||||
return 0;
|
||||
}
|
|
@ -1,20 +1,11 @@
|
|||
#include <iostream>
|
||||
|
||||
#include <basic_widgets/w/widget_factory.hpp>
|
||||
|
||||
#include "run.hpp"
|
||||
|
||||
auto main() -> int
|
||||
{
|
||||
run_example<bwidgets::ScrollBar>(
|
||||
[]() { return bwidgets::create_scrollbar(); },
|
||||
[](auto w, auto f, auto x, auto y) {
|
||||
w->font(f);
|
||||
w->orientation(bwidgets::ScrollBar::Orientation::HORIZONTAL);
|
||||
w->on_scroll([x, y](const int value) {
|
||||
std::cout << "scrollbar(" << x << ',' << y << "): " << value << '%'
|
||||
<< std::endl;
|
||||
});
|
||||
});
|
||||
run_example<bwidgets::ScrollableArea>(
|
||||
[]() { return bwidgets::create_scrollable_area(); },
|
||||
[](auto w, auto f, auto x, auto y) {});
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ namespace bwidgets
|
|||
public:
|
||||
using WidgetImpl::WidgetImpl;
|
||||
|
||||
// TODO: remove widget
|
||||
void handle_event(const SDL_Event&) override;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -17,6 +17,7 @@ namespace bwidgets
|
|||
[[nodiscard]] virtual auto color_input_bg_active() const -> const Color& = 0;
|
||||
[[nodiscard]] virtual auto color_input_fg() const -> const Color& = 0;
|
||||
[[nodiscard]] virtual auto color_widget_bg() const -> const Color& = 0;
|
||||
[[nodiscard]] virtual auto color_widget_bg_dark() const -> const Color& = 0;
|
||||
[[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
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace bwidgets
|
|||
virtual void _handle_renderer_change(const std::shared_ptr<Renderer>&) {}
|
||||
// Called on rendering.
|
||||
virtual void _handle_rendering() = 0;
|
||||
virtual void _handle_theme_change(const std::shared_ptr<Theme>&) {} // = 0;
|
||||
virtual void _handle_theme_change(const std::shared_ptr<Theme>&) {}
|
||||
|
||||
private:
|
||||
Widget* _parent;
|
||||
|
|
|
@ -16,6 +16,7 @@ namespace bwidgets
|
|||
[[nodiscard]] auto color_input_bg_active() const -> const Color& override;
|
||||
[[nodiscard]] auto color_input_fg() const -> const Color& override;
|
||||
[[nodiscard]] auto color_widget_bg() const -> const Color& override;
|
||||
[[nodiscard]] auto color_widget_bg_dark() const -> const Color& override;
|
||||
[[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;
|
||||
|
@ -29,6 +30,7 @@ namespace bwidgets
|
|||
static const Color _color_input_bg_active;
|
||||
static const Color _color_input_fg;
|
||||
static const Color _color_widget_bg;
|
||||
static const Color _color_widget_bg_dark;
|
||||
static const Color _color_widget_bg_hl;
|
||||
static const Color _color_widget_border;
|
||||
static const Color _color_widget_border_pushed;
|
||||
|
|
|
@ -46,8 +46,8 @@ namespace bwidgets
|
|||
|
||||
// Called on font changes.
|
||||
virtual void _handle_font_change(const std::shared_ptr<Font>&) = 0;
|
||||
// Called on font color changes.
|
||||
virtual void _handle_font_color_change(Color, Color) = 0;
|
||||
// Called on font color changes. TODO: remove that, use theme
|
||||
virtual void _handle_font_color_change(Color, Color) {}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -29,8 +29,10 @@ namespace bwidgets
|
|||
// Set mouse motion handler.
|
||||
virtual void
|
||||
mouse_motion_handler(std::function<void(const SDL_MouseMotionEvent&)>) = 0;
|
||||
virtual void
|
||||
mouse_wheel_handler(std::function<void(const SDL_MouseWheelEvent&)>) = 0;
|
||||
// Get current push state (mouse button down)
|
||||
[[nodiscard]] virtual bool pushed() const = 0;
|
||||
[[nodiscard]] virtual bool pushed() const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -14,9 +14,10 @@ namespace bwidgets
|
|||
bool _hovered {false};
|
||||
bool _pushed {false};
|
||||
|
||||
std::function<void(const SDL_MouseButtonEvent&)> _click_handler {[](auto) {}};
|
||||
std::function<void(bool)> _hover_handler {[](auto) {}};
|
||||
std::function<void(const SDL_MouseMotionEvent&)> _motion_handler {[](auto) {}};
|
||||
std::function<void(const SDL_MouseButtonEvent&)> _click_handler {nullptr};
|
||||
std::function<void(bool)> _hover_handler {nullptr};
|
||||
std::function<void(const SDL_MouseMotionEvent&)> _motion_handler {nullptr};
|
||||
std::function<void(const SDL_MouseWheelEvent&)> _wheel_handler {nullptr};
|
||||
|
||||
public:
|
||||
void click_handler(decltype(_click_handler) handler) override
|
||||
|
@ -28,7 +29,10 @@ namespace bwidgets
|
|||
|
||||
void enable_mouse_handler(const SDL_Rect&, const SDL_Rect&) override;
|
||||
|
||||
[[nodiscard]] bool hovered() const override { return _hovered; }
|
||||
[[nodiscard]] bool hovered() const override
|
||||
{
|
||||
return _hovered;
|
||||
}
|
||||
|
||||
void hover_handler(decltype(_hover_handler) handler) override
|
||||
{
|
||||
|
@ -40,7 +44,12 @@ namespace bwidgets
|
|||
_motion_handler = std::move(handler);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool pushed() const override { return _pushed; }
|
||||
void mouse_wheel_handler(decltype(_wheel_handler)) override;
|
||||
|
||||
[[nodiscard]] bool pushed() const override
|
||||
{
|
||||
return _pushed;
|
||||
}
|
||||
|
||||
protected:
|
||||
using MouseHandler::MouseHandler;
|
||||
|
|
20
inc/basic_widgets/w/scrollable_area.hpp
Normal file
20
inc/basic_widgets/w/scrollable_area.hpp
Normal file
|
@ -0,0 +1,20 @@
|
|||
#ifndef BWIDGETS_SCROLLABLE_AREA_HPP
|
||||
#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
|
||||
{
|
||||
public:
|
||||
virtual auto texture() -> const std::shared_ptr<Texture>& = 0;
|
||||
virtual void texture(std::shared_ptr<Texture>) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
38
inc/basic_widgets/w/scrollable_area_impl.hpp
Normal file
38
inc/basic_widgets/w/scrollable_area_impl.hpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
#ifndef BWIDGETS_SCROLLABLE_AREA_IMPL_HPP
|
||||
#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:
|
||||
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;
|
||||
|
||||
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:
|
||||
std::unique_ptr<ScrollBar> _scrollbar_h;
|
||||
std::unique_ptr<ScrollBar> _scrollbar_v;
|
||||
std::shared_ptr<Texture> _texture;
|
||||
SDL_Rect _texture_area;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -20,8 +20,6 @@ namespace bwidgets
|
|||
VERTICAL
|
||||
};
|
||||
|
||||
using Widget::Widget;
|
||||
|
||||
virtual void on_scroll(std::function<void(int)>) = 0;
|
||||
[[nodiscard]] virtual auto orientation() const -> Orientation = 0;
|
||||
virtual void orientation(Orientation) = 0;
|
||||
|
|
|
@ -44,6 +44,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;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <basic_widgets/w/button.hpp>
|
||||
#include <basic_widgets/w/caption.hpp>
|
||||
#include <basic_widgets/w/numeric_input.hpp>
|
||||
#include <basic_widgets/w/scrollable_area.hpp>
|
||||
#include <basic_widgets/w/scrollbar.hpp>
|
||||
|
||||
namespace bwidgets
|
||||
|
@ -14,6 +15,7 @@ namespace bwidgets
|
|||
auto create_horizontal_layout(Widget* p = nullptr) -> std::unique_ptr<AlignedLayout>;
|
||||
auto create_input_float(Widget* p = nullptr) -> std::unique_ptr<NumericInput<float>>;
|
||||
auto create_input_int(Widget* p = nullptr) -> std::unique_ptr<NumericInput<int>>;
|
||||
auto create_scrollable_area(Widget* p = nullptr) -> std::unique_ptr<ScrollableArea>;
|
||||
auto create_scrollbar(Widget* p = nullptr) -> std::unique_ptr<ScrollBar>;
|
||||
auto create_vertical_layout(Widget* p = nullptr) -> std::unique_ptr<AlignedLayout>;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ libbasic_widgets = static_library('basic_widgets',
|
|||
'src/w/feat/event_handler_impl.cpp',
|
||||
'src/w/feat/keyboard_handler_impl.cpp',
|
||||
'src/w/feat/mouse_handler_impl.cpp',
|
||||
'src/w/scrollable_area_impl.cpp',
|
||||
'src/w/scrollbar_impl.cpp',
|
||||
'src/w/widget_factory.cpp',
|
||||
dependencies : [sdl, fontconfig],
|
||||
|
@ -75,6 +76,13 @@ executable('input_demo',
|
|||
link_with : libbasic_widgets,
|
||||
install : false)
|
||||
|
||||
executable('scrollable_area_demo',
|
||||
'examples/scrollable_area_example.cpp',
|
||||
dependencies : [sdl],
|
||||
include_directories : pub_api,
|
||||
link_with : libbasic_widgets,
|
||||
install : false)
|
||||
|
||||
executable('scrollbar_demo',
|
||||
'examples/scrollbar_example.cpp',
|
||||
dependencies : [sdl],
|
||||
|
|
|
@ -82,6 +82,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?
|
||||
|
||||
// fill caption viewport with background color when using
|
||||
// shaded text rendering mode.
|
||||
|
|
|
@ -11,6 +11,7 @@ const Color DefaultTheme::_color_input_bg = {180, 180, 180, SDL_ALPHA_OPA
|
|||
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};
|
||||
const Color DefaultTheme::_color_widget_bg_dark = {100, 100, 100, SDL_ALPHA_OPAQUE};
|
||||
const Color DefaultTheme::_color_widget_bg_hl = {180, 180, 180, SDL_ALPHA_OPAQUE};
|
||||
const Color DefaultTheme::_color_widget_border = {130, 130, 130, SDL_ALPHA_OPAQUE};
|
||||
const Color DefaultTheme::_color_widget_border_pushed = {90, 90, 90, SDL_ALPHA_OPAQUE};
|
||||
|
@ -42,6 +43,11 @@ auto DefaultTheme::color_input_fg() const -> const Color&
|
|||
return _color_input_fg;
|
||||
}
|
||||
|
||||
auto DefaultTheme::color_widget_bg_dark() const -> const Color&
|
||||
{
|
||||
return _color_widget_bg_dark;
|
||||
}
|
||||
|
||||
auto DefaultTheme::color_widget_bg() const -> const Color&
|
||||
{
|
||||
return _color_widget_bg;
|
||||
|
|
|
@ -33,16 +33,31 @@ void MouseHandlerImpl::enable_mouse_handler(const SDL_Rect& rel_area,
|
|||
// has been pushed and released over the widget.
|
||||
if (mouse_in_rect({ev.button.x, ev.button.y})) {
|
||||
focus(true);
|
||||
_click_handler(ev.button);
|
||||
if (_click_handler) _click_handler(ev.button);
|
||||
}
|
||||
}
|
||||
}});
|
||||
_add_event_handler({SDL_MOUSEMOTION, [this, mouse_in_rect](const SDL_Event& ev) {
|
||||
if (!mouse_in_rect({ev.motion.x, ev.motion.y})) {
|
||||
if (_hovered) _hover_handler(_hovered = false);
|
||||
if (_hovered) {
|
||||
_hovered = false;
|
||||
if (_hover_handler) _hover_handler(_hovered);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!_hovered) _hover_handler(_hovered = true);
|
||||
_motion_handler(ev.motion);
|
||||
if (!_hovered) {
|
||||
_hovered = true;
|
||||
if (_hover_handler) _hover_handler(_hovered);
|
||||
}
|
||||
if (_motion_handler) _motion_handler(ev.motion);
|
||||
}});
|
||||
_add_event_handler({SDL_MOUSEWHEEL, [this](const SDL_Event& ev) {
|
||||
if (hovered() && _wheel_handler) _wheel_handler(ev.wheel);
|
||||
}});
|
||||
}
|
||||
|
||||
void MouseHandlerImpl::mouse_wheel_handler(
|
||||
std::function<void(const SDL_MouseWheelEvent&)> handler)
|
||||
{
|
||||
_wheel_handler = std::move(handler);
|
||||
}
|
||||
|
|
79
src/w/scrollable_area_impl.cpp
Normal file
79
src/w/scrollable_area_impl.cpp
Normal file
|
@ -0,0 +1,79 @@
|
|||
#include <utility>
|
||||
|
||||
#include <basic_widgets/core/draw.hpp>
|
||||
#include <basic_widgets/w/scrollable_area_impl.hpp>
|
||||
#include <basic_widgets/w/widget_factory.hpp>
|
||||
|
||||
using namespace bwidgets;
|
||||
using namespace std;
|
||||
|
||||
ScrollableAreaImpl::ScrollableAreaImpl(Widget* p)
|
||||
: WidgetImpl {p},
|
||||
_scrollbar_h {create_scrollbar(this)},
|
||||
_scrollbar_v {create_scrollbar(this)},
|
||||
_texture {nullptr},
|
||||
_texture_area {}
|
||||
{
|
||||
_scrollbar_h->orientation(ScrollBar::Orientation::HORIZONTAL);
|
||||
_scrollbar_v->orientation(ScrollBar::Orientation::VERTICAL);
|
||||
}
|
||||
|
||||
void ScrollableAreaImpl::handle_event(const SDL_Event& ev)
|
||||
{
|
||||
WidgetImpl::handle_event(ev);
|
||||
_scrollbar_h->handle_event(ev);
|
||||
_scrollbar_v->handle_event(ev);
|
||||
}
|
||||
|
||||
auto ScrollableAreaImpl::size() const noexcept -> Size
|
||||
{
|
||||
return {100, 100};
|
||||
}
|
||||
|
||||
auto ScrollableAreaImpl::texture() -> const shared_ptr<Texture>&
|
||||
{
|
||||
return _texture;
|
||||
}
|
||||
|
||||
void ScrollableAreaImpl::texture(shared_ptr<Texture> t)
|
||||
{
|
||||
_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;
|
||||
const auto reserved_w = _scrollbar_v->size().w;
|
||||
|
||||
_texture_area = {0, 0, vp.w - reserved_w, vp.h - reserved_h};
|
||||
|
||||
_scrollbar_h->viewport({vp.x, vp.y + _texture_area.h, vp.w, reserved_h});
|
||||
_scrollbar_v->viewport(
|
||||
{vp.x + _texture_area.w, vp.y, reserved_w, vp.h - reserved_h});
|
||||
}
|
||||
|
||||
void ScrollableAreaImpl::_handle_renderer_change(const shared_ptr<Renderer>& r)
|
||||
{
|
||||
_scrollbar_h->renderer(r);
|
||||
_scrollbar_v->renderer(r);
|
||||
}
|
||||
|
||||
void ScrollableAreaImpl::_handle_rendering()
|
||||
{
|
||||
fill_rect_gradient(*renderer(), _texture_area, theme()->color_widget_border(),
|
||||
theme()->color_widget_bg(), theme()->size_widget_border());
|
||||
_scrollbar_h->render();
|
||||
_scrollbar_v->render();
|
||||
}
|
||||
|
||||
void ScrollableAreaImpl::_handle_theme_change(const shared_ptr<Theme>& t)
|
||||
{
|
||||
_scrollbar_h->theme(t);
|
||||
_scrollbar_v->theme(t);
|
||||
}
|
|
@ -12,6 +12,20 @@
|
|||
using namespace bwidgets;
|
||||
using namespace std;
|
||||
|
||||
auto common_size(const Widget* w1, const Widget* w2) -> Size
|
||||
{
|
||||
const auto size1 = w1->size();
|
||||
const auto size2 = w2->size();
|
||||
|
||||
return {size1.w > size2.w ? size1.w : size2.w,
|
||||
size1.h > size2.h ? size1.h : size2.h};
|
||||
}
|
||||
|
||||
auto square_size(Size s) -> int
|
||||
{
|
||||
return s.w > s.h ? s.w : s.h;
|
||||
}
|
||||
|
||||
ScrollBarImpl::ScrollBarImpl(Widget* parent)
|
||||
: WidgetImpl {parent},
|
||||
_button_minus {create_button(this)},
|
||||
|
@ -38,10 +52,20 @@ ScrollBarImpl::ScrollBarImpl(Widget* parent)
|
|||
SDL_Point p = {ev.x - viewport().x - _bar_area.x,
|
||||
ev.y - viewport().y - _bar_area.y};
|
||||
if (_orientation == Orientation::VERTICAL) {
|
||||
value(std::clamp(p.y, 0, _bar_area.h) * 100 / _bar_area.h);
|
||||
value(clamp(p.y, 0, _bar_area.h) * 100 / _bar_area.h);
|
||||
}
|
||||
else {
|
||||
value(std::clamp(p.x, 0, _bar_area.w) * 100 / _bar_area.w);
|
||||
value(clamp(p.x, 0, _bar_area.w) * 100 / _bar_area.w);
|
||||
}
|
||||
});
|
||||
mouse_wheel_handler([this](SDL_MouseWheelEvent ev) {
|
||||
if (orientation() == ScrollBar::Orientation::VERTICAL) {
|
||||
if (ev.y < 0) value(value() + 5);
|
||||
else if (ev.y > 0) value(value() - 5);
|
||||
}
|
||||
else {
|
||||
if (ev.x > 0) value(value() + 5);
|
||||
else if (ev.x < 0) value(value() - 5);
|
||||
}
|
||||
});
|
||||
enable_mouse_handler(_bar_area, viewport());
|
||||
|
@ -66,9 +90,9 @@ void ScrollBarImpl::handle_event(const SDL_Event& ev)
|
|||
_button_plus->handle_event(ev);
|
||||
}
|
||||
|
||||
void ScrollBarImpl::on_scroll(std::function<void(int)> cb)
|
||||
void ScrollBarImpl::on_scroll(function<void(int)> cb)
|
||||
{
|
||||
_on_scroll = std::move(cb);
|
||||
_on_scroll = move(cb);
|
||||
}
|
||||
|
||||
auto ScrollBarImpl::orientation() const -> Orientation
|
||||
|
@ -93,23 +117,23 @@ void ScrollBarImpl::orientation(const Orientation o)
|
|||
|
||||
auto ScrollBarImpl::size() const noexcept -> Size
|
||||
{
|
||||
const auto minus_size = _button_minus->size();
|
||||
const auto plus_size = _button_plus->size();
|
||||
const auto button_size =
|
||||
square_size(common_size(_button_minus.get(), _button_plus.get()));
|
||||
if (_orientation == Orientation::VERTICAL) {
|
||||
const auto width = [this, minus_size, plus_size]() {
|
||||
const auto width = [this, button_size]() {
|
||||
const auto button_max_width =
|
||||
minus_size.w > plus_size.w ? minus_size.w : plus_size.w;
|
||||
button_size > button_size ? button_size : button_size;
|
||||
return button_max_width > _cursor_size.w ? button_max_width : _cursor_size.w;
|
||||
}();
|
||||
return {width, minus_size.h + plus_size.h + 3 * _cursor_size.h};
|
||||
return {width, button_size + button_size + 3 * _cursor_size.h};
|
||||
}
|
||||
|
||||
const auto height = [this, minus_size, plus_size]() {
|
||||
const auto height = [this, button_size]() {
|
||||
const auto button_max_height =
|
||||
minus_size.h > plus_size.h ? minus_size.h : plus_size.h;
|
||||
button_size > button_size ? button_size : button_size;
|
||||
return button_max_height > _cursor_size.w ? button_max_height : _cursor_size.w;
|
||||
}();
|
||||
return {height, minus_size.w + plus_size.w + 3 * _cursor_size.h};
|
||||
return {height, button_size + button_size + 3 * _cursor_size.h};
|
||||
}
|
||||
|
||||
auto ScrollBarImpl::value() const -> int
|
||||
|
@ -119,14 +143,14 @@ auto ScrollBarImpl::value() const -> int
|
|||
|
||||
void ScrollBarImpl::value(const int v)
|
||||
{
|
||||
const auto new_value = std::clamp(v, 0, 100);
|
||||
const auto new_value = clamp(v, 0, 100);
|
||||
if (new_value != _value) {
|
||||
_value = new_value;
|
||||
_on_scroll(new_value);
|
||||
if (_on_scroll) _on_scroll(new_value);
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollBarImpl::_handle_font_change(const std::shared_ptr<Font>& f)
|
||||
void ScrollBarImpl::_handle_font_change(const shared_ptr<Font>& f)
|
||||
{
|
||||
_button_minus->font(f);
|
||||
_button_plus->font(f);
|
||||
|
@ -140,23 +164,24 @@ void ScrollBarImpl::_handle_font_color_change(const Color fg, Color)
|
|||
|
||||
void ScrollBarImpl::_handle_geometry_change(const SDL_Rect& vp)
|
||||
{
|
||||
const auto minus_size = _button_minus->size();
|
||||
const auto plus_size = _button_plus->size();
|
||||
const auto button_size =
|
||||
square_size(common_size(_button_minus.get(), _button_plus.get()));
|
||||
|
||||
if (_orientation == Orientation::VERTICAL) {
|
||||
_bar_area = {0, minus_size.h, vp.w, vp.h - minus_size.h - plus_size.h};
|
||||
_button_minus->viewport(rect_offset({0, 0, vp.w, minus_size.h}, vp));
|
||||
_bar_area = {0, button_size, vp.w, vp.h - 2 * button_size};
|
||||
_button_minus->viewport(rect_offset({0, 0, vp.w, button_size}, vp));
|
||||
_button_plus->viewport(
|
||||
rect_offset({0, _bar_area.y + _bar_area.h, vp.w, plus_size.h}, vp));
|
||||
rect_offset({0, _bar_area.y + _bar_area.h, vp.w, button_size}, vp));
|
||||
}
|
||||
else {
|
||||
_bar_area = {minus_size.w, 0, vp.w - minus_size.w - plus_size.w, vp.h};
|
||||
_button_minus->viewport(rect_offset({0, 0, minus_size.w, vp.h}, vp));
|
||||
_bar_area = {button_size, 0, vp.w - 2 * button_size, vp.h};
|
||||
_button_minus->viewport(rect_offset({0, 0, button_size, vp.h}, vp));
|
||||
_button_plus->viewport(
|
||||
rect_offset({_bar_area.x + _bar_area.w, 0, plus_size.w, vp.h}, vp));
|
||||
rect_offset({_bar_area.x + _bar_area.w, 0, button_size, vp.h}, vp));
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollBarImpl::_handle_renderer_change(const std::shared_ptr<Renderer>& r)
|
||||
void ScrollBarImpl::_handle_renderer_change(const shared_ptr<Renderer>& r)
|
||||
{
|
||||
_button_minus->renderer(r);
|
||||
_button_plus->renderer(r);
|
||||
|
@ -164,9 +189,8 @@ void ScrollBarImpl::_handle_renderer_change(const std::shared_ptr<Renderer>& r)
|
|||
|
||||
void ScrollBarImpl::_handle_rendering()
|
||||
{
|
||||
renderer()->draw_color(theme()->color_widget_border());
|
||||
fill_rect_gradient(*renderer(), _bar_area, theme()->color_widget_bg(),
|
||||
theme()->color_widget_border());
|
||||
fill_rect_gradient(*renderer(), _bar_area, theme()->color_widget_border(),
|
||||
theme()->color_widget_bg_dark());
|
||||
|
||||
auto c = hovered() ? theme()->color_widget_bg_hl() : theme()->color_widget_bg();
|
||||
fill_rect_gradient(*renderer(), cursor_area(), theme()->color_widget_border(), c);
|
||||
|
@ -174,3 +198,9 @@ void ScrollBarImpl::_handle_rendering()
|
|||
_button_minus->render();
|
||||
_button_plus->render();
|
||||
}
|
||||
|
||||
void ScrollBarImpl::_handle_theme_change(const shared_ptr<Theme>& t)
|
||||
{
|
||||
_button_minus->theme(t);
|
||||
_button_plus->theme(t);
|
||||
}
|
||||
|
|
|
@ -2,40 +2,51 @@
|
|||
#include <basic_widgets/w/button_impl.hpp>
|
||||
#include <basic_widgets/w/caption_impl.hpp>
|
||||
#include <basic_widgets/w/numeric_input_impl.hpp>
|
||||
#include <basic_widgets/w/scrollable_area_impl.hpp>
|
||||
#include <basic_widgets/w/scrollbar_impl.hpp>
|
||||
#include <basic_widgets/w/widget_factory.hpp>
|
||||
|
||||
auto bwidgets::create_horizontal_layout(Widget* parent) -> std::unique_ptr<AlignedLayout>
|
||||
{
|
||||
return std::make_unique<AlignedLayoutImpl<LayoutAlignment::HORIZONTAL>>(parent);
|
||||
}
|
||||
using namespace std;
|
||||
|
||||
auto bwidgets::create_vertical_layout(Widget* parent) -> std::unique_ptr<AlignedLayout>
|
||||
namespace bwidgets
|
||||
{
|
||||
return std::make_unique<AlignedLayoutImpl<LayoutAlignment::VERTICAL>>(parent);
|
||||
}
|
||||
auto create_horizontal_layout(Widget* parent) -> unique_ptr<AlignedLayout>
|
||||
{
|
||||
return make_unique<AlignedLayoutImpl<LayoutAlignment::HORIZONTAL>>(parent);
|
||||
}
|
||||
|
||||
auto bwidgets::create_button(Widget* parent) -> std::unique_ptr<Button>
|
||||
{
|
||||
return std::make_unique<ButtonImpl>(parent);
|
||||
}
|
||||
auto create_vertical_layout(Widget* parent) -> unique_ptr<AlignedLayout>
|
||||
{
|
||||
return make_unique<AlignedLayoutImpl<LayoutAlignment::VERTICAL>>(parent);
|
||||
}
|
||||
|
||||
auto bwidgets::create_caption(Widget* parent) -> std::unique_ptr<Caption>
|
||||
{
|
||||
return std::make_unique<CaptionImpl>(parent);
|
||||
}
|
||||
auto create_button(Widget* parent) -> unique_ptr<Button>
|
||||
{
|
||||
return make_unique<ButtonImpl>(parent);
|
||||
}
|
||||
|
||||
auto bwidgets::create_input_float(Widget* parent) -> std::unique_ptr<NumericInput<float>>
|
||||
{
|
||||
return std::make_unique<NumericInputImpl<float>>(parent);
|
||||
}
|
||||
auto create_caption(Widget* parent) -> unique_ptr<Caption>
|
||||
{
|
||||
return make_unique<CaptionImpl>(parent);
|
||||
}
|
||||
|
||||
auto bwidgets::create_scrollbar(Widget* parent) -> std::unique_ptr<ScrollBar>
|
||||
{
|
||||
return std::make_unique<ScrollBarImpl>(parent);
|
||||
}
|
||||
auto create_input_float(Widget* parent) -> unique_ptr<NumericInput<float>>
|
||||
{
|
||||
return make_unique<NumericInputImpl<float>>(parent);
|
||||
}
|
||||
|
||||
auto bwidgets::create_input_int(Widget* parent) -> std::unique_ptr<NumericInput<int>>
|
||||
{
|
||||
return std::make_unique<NumericInputImpl<int>>(parent);
|
||||
auto create_scrollable_area(Widget* parent) -> unique_ptr<ScrollableArea>
|
||||
{
|
||||
return make_unique<ScrollableAreaImpl>(parent);
|
||||
}
|
||||
|
||||
auto create_scrollbar(Widget* parent) -> unique_ptr<ScrollBar>
|
||||
{
|
||||
return make_unique<ScrollBarImpl>(parent);
|
||||
}
|
||||
|
||||
auto create_input_int(Widget* parent) -> unique_ptr<NumericInput<int>>
|
||||
{
|
||||
return make_unique<NumericInputImpl<int>>(parent);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue