rewrite how events are held
This commit is contained in:
parent
07f7061c20
commit
c07dbfe8ff
24 changed files with 441 additions and 248 deletions
|
@ -34,11 +34,11 @@ EmptyLineBeforeAccessModifier: Always
|
||||||
FixNamespaceComments: false
|
FixNamespaceComments: false
|
||||||
IncludeBlocks: Regroup
|
IncludeBlocks: Regroup
|
||||||
IncludeCategories:
|
IncludeCategories:
|
||||||
- Regex: '<[[:alnum:].]+>'
|
- Regex: '<[[:alnum:]._]+>'
|
||||||
Priority: -10
|
Priority: -10
|
||||||
- Regex: '^<fontconfig/'
|
- Regex: '^<fontconfig'
|
||||||
Priority: -5
|
Priority: -5
|
||||||
- Regex: '^<SDL2/'
|
- Regex: '^<SDL'
|
||||||
Priority: -5
|
Priority: -5
|
||||||
- Regex: '^<basic_widgets/'
|
- Regex: '^<basic_widgets/'
|
||||||
Priority: 0
|
Priority: 0
|
||||||
|
|
|
@ -9,9 +9,9 @@ using bwidgets::Button;
|
||||||
auto main() -> int
|
auto main() -> int
|
||||||
{
|
{
|
||||||
run_example<Button>([](auto w, auto f, auto x, auto y) {
|
run_example<Button>([](auto w, auto f, auto x, auto y) {
|
||||||
w->click_handler = [x, y](const SDL_MouseButtonEvent&) {
|
w->click_handler([x, y](const SDL_MouseButtonEvent&) {
|
||||||
std::cout << "button(" << x << ',' << y << "):click!" << std::endl;
|
std::cout << "button(" << x << ',' << y << "):click!" << std::endl;
|
||||||
};
|
});
|
||||||
w->font(f);
|
w->font(f);
|
||||||
w->text("+");
|
w->text("+");
|
||||||
});
|
});
|
||||||
|
|
45
inc/basic_widgets/impl/mouse_handler_impl.hpp
Normal file
45
inc/basic_widgets/impl/mouse_handler_impl.hpp
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#ifndef BWIDGETS_MOUSE_HANDLER_IMPL_HPP
|
||||||
|
#define BWIDGETS_MOUSE_HANDLER_IMPL_HPP
|
||||||
|
|
||||||
|
#include <basic_widgets/w/feat/mouse_handler.hpp>
|
||||||
|
|
||||||
|
namespace bwidgets
|
||||||
|
{
|
||||||
|
class MouseHandlerImpl : public MouseHandler
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const SDL_Rect* _area {nullptr};
|
||||||
|
bool _hovered {false};
|
||||||
|
bool _pushed {false};
|
||||||
|
|
||||||
|
std::function<void(const SDL_MouseButtonEvent&)> _click_handler;
|
||||||
|
std::function<void(const SDL_MouseMotionEvent&)> _motion_handler;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MouseHandlerImpl() = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void
|
||||||
|
click_handler(std::function<void(const SDL_MouseButtonEvent&)> handler) override
|
||||||
|
{
|
||||||
|
_click_handler = std::move(handler);
|
||||||
|
}
|
||||||
|
void disable_mouse_handler() override;
|
||||||
|
void enable_mouse_handler(const SDL_Rect*) override;
|
||||||
|
[[nodiscard]] bool hovered() const override
|
||||||
|
{
|
||||||
|
return _hovered;
|
||||||
|
}
|
||||||
|
void mouse_motion_handler(
|
||||||
|
std::function<void(const SDL_MouseMotionEvent&)> handler) override
|
||||||
|
{
|
||||||
|
_motion_handler = std::move(handler);
|
||||||
|
}
|
||||||
|
[[nodiscard]] bool pushed() const override
|
||||||
|
{
|
||||||
|
return _pushed;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -13,8 +13,8 @@
|
||||||
#include <basic_widgets/core/math.hpp>
|
#include <basic_widgets/core/math.hpp>
|
||||||
#include <basic_widgets/core/type/concepts.hpp>
|
#include <basic_widgets/core/type/concepts.hpp>
|
||||||
#include <basic_widgets/w/caption.hpp>
|
#include <basic_widgets/w/caption.hpp>
|
||||||
#include <basic_widgets/w/feat/keyboard_handler.hpp>
|
#include <basic_widgets/w/feat/keyboard_handler_impl.hpp>
|
||||||
#include <basic_widgets/w/feat/mouse_handler.hpp>
|
#include <basic_widgets/w/feat/mouse_handler_impl.hpp>
|
||||||
|
|
||||||
namespace bwidgets
|
namespace bwidgets
|
||||||
{
|
{
|
||||||
|
@ -22,29 +22,57 @@ namespace bwidgets
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class Input : public Widget,
|
class Input : public Widget,
|
||||||
public FontHandler,
|
public FontHandler,
|
||||||
public KeyboardHandler,
|
public KeyboardHandlerImpl,
|
||||||
public MouseHandler
|
public MouseHandlerImpl
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
Caption _input_caption;
|
Caption _input_caption;
|
||||||
|
|
||||||
Input(Widget* parent = nullptr) : Widget {parent}, _input_caption {this}
|
Input(Widget* parent = nullptr) : Widget {parent}, _input_caption {this}
|
||||||
{
|
{
|
||||||
FocusHandler::_focus_area = &_widget_area;
|
FocusHandlerImpl::focus_handler([this](bool focus) {
|
||||||
MouseHandler::_click_area = &_widget_area;
|
if (focus) {
|
||||||
_input_caption.text(value_to_string(value));
|
SDL_StartTextInput();
|
||||||
}
|
}
|
||||||
|
// focus loss.
|
||||||
|
else if (FocusHandlerImpl::focus()) {
|
||||||
|
value = value_from_string(input_text());
|
||||||
|
input_text(value_to_string(value));
|
||||||
|
SDL_StopTextInput();
|
||||||
|
_input_caption.text(value_to_string(value));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
void _handle_focus_change(bool focus) override
|
KeyboardHandlerImpl::key_handler([this](const SDL_KeyboardEvent& key) {
|
||||||
{
|
if (key.type == SDL_KEYDOWN) {
|
||||||
if (focus) {
|
switch (key.keysym.sym) {
|
||||||
SDL_StartTextInput();
|
case SDLK_BACKSPACE: {
|
||||||
}
|
std::string txt = input_text();
|
||||||
else {
|
if (txt.length() > 0) {
|
||||||
value = value_from_string(input_text());
|
txt.pop_back();
|
||||||
input_text(value_to_string(value));
|
input_text(txt);
|
||||||
SDL_StopTextInput();
|
}
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
|
case SDLK_RETURN:
|
||||||
|
case SDLK_RETURN2: // what is return2 btw?
|
||||||
|
case SDLK_KP_ENTER:
|
||||||
|
value = value_from_string(input_text());
|
||||||
|
FocusHandlerImpl::focus(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
KeyboardHandlerImpl::text_input_handler(
|
||||||
|
[this](const SDL_TextInputEvent& input) {
|
||||||
|
if (is_valid_input(input.text)) {
|
||||||
|
input_text(input_text() + input.text);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
KeyboardHandlerImpl::enable_keyboard_handler();
|
||||||
|
|
||||||
|
MouseHandlerImpl::enable_mouse_handler(&(Input::_widget_area),
|
||||||
|
&(Input::_viewport));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handle_font_change(const std::shared_ptr<Font>& f) override
|
void _handle_font_change(const std::shared_ptr<Font>& f) override
|
||||||
|
@ -67,28 +95,6 @@ namespace bwidgets
|
||||||
{rect_margin(_widget_area, {border_width, border_width})}, vp));
|
{rect_margin(_widget_area, {border_width, border_width})}, vp));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handle_key(const SDL_KeyboardEvent& key) override
|
|
||||||
{
|
|
||||||
if (key.type == SDL_KEYDOWN) {
|
|
||||||
switch (key.keysym.sym) {
|
|
||||||
case SDLK_BACKSPACE: {
|
|
||||||
std::string txt = input_text();
|
|
||||||
if (txt.length() > 0) {
|
|
||||||
txt.pop_back();
|
|
||||||
input_text(txt);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SDLK_RETURN:
|
|
||||||
case SDLK_RETURN2: // what is return2 btw?
|
|
||||||
case SDLK_KP_ENTER:
|
|
||||||
value = value_from_string(input_text());
|
|
||||||
focus(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _handle_renderer_change(const std::shared_ptr<Renderer>& r) override
|
void _handle_renderer_change(const std::shared_ptr<Renderer>& r) override
|
||||||
{
|
{
|
||||||
_input_caption.renderer(r);
|
_input_caption.renderer(r);
|
||||||
|
@ -97,27 +103,21 @@ namespace bwidgets
|
||||||
void _handle_rendering() override
|
void _handle_rendering() override
|
||||||
{
|
{
|
||||||
for (int i = border_width - 1; i >= 0; i--) {
|
for (int i = border_width - 1; i >= 0; i--) {
|
||||||
const auto factor = linear(i, 0, border_width);
|
const auto factor = linear(i, 0, border_width);
|
||||||
const auto& color_end = _has_focus ? color_bg_focused : color_bg;
|
const auto& color_end =
|
||||||
const auto color_start = color_end / 2;
|
FocusHandlerImpl::focus() ? color_bg_focused : color_bg;
|
||||||
|
const auto color_start = color_end / 2;
|
||||||
_renderer->draw_color(lerp(color_start, color_end, factor))
|
_renderer->draw_color(lerp(color_start, color_end, factor))
|
||||||
->draw_rect(rect_margin(_widget_area, {i, i}));
|
->draw_rect(rect_margin(_widget_area, {i, i}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MouseHandler::_is_hovered || FocusHandler::_has_focus)
|
if (hovered() || FocusHandlerImpl::focus())
|
||||||
_input_caption.font_color_bg(color_bg_focused);
|
_input_caption.font_color_bg(color_bg_focused);
|
||||||
else _input_caption.font_color_bg(color_bg);
|
else _input_caption.font_color_bg(color_bg);
|
||||||
|
|
||||||
_input_caption.render();
|
_input_caption.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handle_text_input(const SDL_TextInputEvent& input) override
|
|
||||||
{
|
|
||||||
if (is_valid_input(input.text)) {
|
|
||||||
input_text(input_text() + input.text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const int default_border_width = 3;
|
static const int default_border_width = 3;
|
||||||
inline static const Color default_color_bg = {200, 200, 200, SDL_ALPHA_OPAQUE};
|
inline static const Color default_color_bg = {200, 200, 200, SDL_ALPHA_OPAQUE};
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace bwidgets
|
||||||
auto operator=(const Layout&) = delete;
|
auto operator=(const Layout&) = delete;
|
||||||
auto operator=(Layout&&) = delete;
|
auto operator=(Layout&&) = delete;
|
||||||
|
|
||||||
auto handle_event(const SDL_Event&) -> Layout* override;
|
void handle_event(const SDL_Event&) override;
|
||||||
[[nodiscard]] auto size() const noexcept -> Size override = 0;
|
[[nodiscard]] auto size() const noexcept -> Size override = 0;
|
||||||
|
|
||||||
virtual auto add_widget(std::unique_ptr<Widget>) -> Layout*;
|
virtual auto add_widget(std::unique_ptr<Widget>) -> Layout*;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include <basic_widgets/core/renderer.hpp>
|
#include <basic_widgets/core/renderer.hpp>
|
||||||
#include <basic_widgets/core/type/size.hpp>
|
#include <basic_widgets/core/type/size.hpp>
|
||||||
|
#include <basic_widgets/w/feat/event_handler_impl.hpp>
|
||||||
|
|
||||||
union SDL_Event;
|
union SDL_Event;
|
||||||
|
|
||||||
|
@ -12,15 +13,13 @@ struct SDL_Renderer;
|
||||||
|
|
||||||
namespace bwidgets
|
namespace bwidgets
|
||||||
{
|
{
|
||||||
class Widget
|
class Widget : public virtual EventHandlerImpl
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<Renderer> _renderer;
|
std::shared_ptr<Renderer> _renderer;
|
||||||
SDL_Rect _viewport {0, 0, 0, 0};
|
SDL_Rect _viewport {0, 0, 0, 0};
|
||||||
SDL_Rect _widget_area {0, 0, 0, 0};
|
SDL_Rect _widget_area {0, 0, 0, 0};
|
||||||
|
|
||||||
explicit Widget(Widget* p = nullptr) noexcept : parent {p} {}
|
|
||||||
|
|
||||||
virtual void _handle_geometry_change(const SDL_Rect&) = 0;
|
virtual void _handle_geometry_change(const SDL_Rect&) = 0;
|
||||||
virtual void _handle_renderer_change(const std::shared_ptr<Renderer>&) {}
|
virtual void _handle_renderer_change(const std::shared_ptr<Renderer>&) {}
|
||||||
virtual void _handle_rendering() = 0;
|
virtual void _handle_rendering() = 0;
|
||||||
|
@ -28,14 +27,8 @@ namespace bwidgets
|
||||||
public:
|
public:
|
||||||
Widget* parent;
|
Widget* parent;
|
||||||
|
|
||||||
Widget(const Widget&) noexcept = default;
|
explicit Widget(Widget* p = nullptr) noexcept : parent {p} {}
|
||||||
Widget(Widget&&) noexcept = default;
|
|
||||||
virtual ~Widget() noexcept = default;
|
|
||||||
|
|
||||||
auto operator=(const Widget&) = delete;
|
|
||||||
auto operator=(Widget&&) = delete;
|
|
||||||
|
|
||||||
virtual auto handle_event(const SDL_Event&) -> Widget*;
|
|
||||||
[[nodiscard]] virtual auto size() const noexcept -> Size = 0;
|
[[nodiscard]] virtual auto size() const noexcept -> Size = 0;
|
||||||
|
|
||||||
virtual auto render() -> Widget* final;
|
virtual auto render() -> Widget* final;
|
||||||
|
|
|
@ -6,20 +6,19 @@
|
||||||
|
|
||||||
#include <basic_widgets/core/type/color.hpp>
|
#include <basic_widgets/core/type/color.hpp>
|
||||||
#include <basic_widgets/w/caption.hpp>
|
#include <basic_widgets/w/caption.hpp>
|
||||||
#include <basic_widgets/w/feat/mouse_handler.hpp>
|
#include <basic_widgets/w/feat/mouse_handler_impl.hpp>
|
||||||
|
|
||||||
namespace bwidgets
|
namespace bwidgets
|
||||||
{
|
{
|
||||||
class Button : public Widget,
|
class Button : public virtual Widget,
|
||||||
public FontHandler,
|
public virtual FontHandler,
|
||||||
public MouseHandler
|
public virtual MouseHandlerImpl
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
Caption _caption;
|
Caption _caption;
|
||||||
SDL_Rect _caption_area {};
|
SDL_Rect _caption_area {};
|
||||||
Color _color_foreground = default_color_fg;
|
Color _color_foreground = default_color_fg;
|
||||||
|
|
||||||
void _handle_focus_change(bool) override {}
|
|
||||||
void _handle_font_change(const std::shared_ptr<Font>&) override;
|
void _handle_font_change(const std::shared_ptr<Font>&) override;
|
||||||
void _handle_font_color_change(Color, Color)
|
void _handle_font_color_change(Color, Color)
|
||||||
override;
|
override;
|
||||||
|
@ -38,6 +37,10 @@ namespace bwidgets
|
||||||
Color color_bg = default_color_bg;
|
Color color_bg = default_color_bg;
|
||||||
Color color_bg_hover = default_color_bg_hover;
|
Color color_bg_hover = default_color_bg_hover;
|
||||||
|
|
||||||
|
using EventHandlerImpl::handle_event;
|
||||||
|
using FocusHandlerImpl::focus;
|
||||||
|
using FocusHandlerImpl::focus_handler;
|
||||||
|
|
||||||
Button(Widget* parent = nullptr) noexcept;
|
Button(Widget* parent = nullptr) noexcept;
|
||||||
Button(const Button&) = delete;
|
Button(const Button&) = delete;
|
||||||
Button(Button&&) = delete;
|
Button(Button&&) = delete;
|
||||||
|
|
32
inc/basic_widgets/w/feat/event_handler.hpp
Normal file
32
inc/basic_widgets/w/feat/event_handler.hpp
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef BWIDGETS_EVENT_HANDLER_HPP
|
||||||
|
#define BWIDGETS_EVENT_HANDLER_HPP
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include <SDL_events.h>
|
||||||
|
|
||||||
|
namespace bwidgets
|
||||||
|
{
|
||||||
|
class EventHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using handler_t =
|
||||||
|
std::pair<SDL_EventType, std::function<void(const SDL_Event&)>>;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
EventHandler() = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
EventHandler(const EventHandler&) = delete;
|
||||||
|
EventHandler(EventHandler&&) = delete;
|
||||||
|
auto operator=(const EventHandler&) -> EventHandler& = delete;
|
||||||
|
auto operator=(EventHandler&&) -> EventHandler& = delete;
|
||||||
|
|
||||||
|
virtual ~EventHandler() = default;
|
||||||
|
|
||||||
|
virtual void handle_event(const SDL_Event&) = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
24
inc/basic_widgets/w/feat/event_handler_impl.hpp
Normal file
24
inc/basic_widgets/w/feat/event_handler_impl.hpp
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef BWIDGETS_EVENT_HANDLER_IMPL_HPP
|
||||||
|
#define BWIDGETS_EVENT_HANDLER_IMPL_HPP
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include <basic_widgets/w/feat/event_handler.hpp>
|
||||||
|
|
||||||
|
namespace bwidgets
|
||||||
|
{
|
||||||
|
class EventHandlerImpl : public virtual EventHandler
|
||||||
|
{
|
||||||
|
std::unordered_map<SDL_EventType, std::function<void(const SDL_Event&)>>
|
||||||
|
_event_handlers {};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
auto _add_event_handler(handler_t) -> bool;
|
||||||
|
auto _remove_event_handler(SDL_EventType) -> std::pair<handler_t, bool>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void handle_event(const SDL_Event&) override;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,32 +1,25 @@
|
||||||
#ifndef BWIDGETS_FOCUS_HANDLER_HPP
|
#ifndef BWIDGETS_FOCUS_HANDLER_HPP
|
||||||
#define BWIDGETS_FOCUS_HANDLER_HPP
|
#define BWIDGETS_FOCUS_HANDLER_HPP
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
struct SDL_Rect;
|
struct SDL_Rect;
|
||||||
|
|
||||||
namespace bwidgets
|
namespace bwidgets
|
||||||
{
|
{
|
||||||
class FocusHandler
|
class FocusHandler
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
const SDL_Rect* _focus_area = nullptr;
|
|
||||||
bool _has_focus = false;
|
|
||||||
|
|
||||||
virtual void _handle_focus_change(bool) = 0;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FocusHandler() = default;
|
FocusHandler() = default;
|
||||||
FocusHandler(const FocusHandler&) = delete;
|
FocusHandler(const FocusHandler&) = delete;
|
||||||
FocusHandler(FocusHandler&&) = delete;
|
FocusHandler(FocusHandler&&) = delete;
|
||||||
virtual ~FocusHandler() = default;
|
|
||||||
|
|
||||||
auto operator=(FocusHandler&&) = delete;
|
auto operator=(FocusHandler&&) = delete;
|
||||||
auto operator=(const FocusHandler&) = delete;
|
auto operator=(const FocusHandler&) = delete;
|
||||||
|
|
||||||
virtual void focus(bool focus) final
|
virtual ~FocusHandler() = default;
|
||||||
{
|
virtual void focus(bool focus) = 0;
|
||||||
_handle_focus_change(focus);
|
virtual bool focus() = 0;
|
||||||
_has_focus = focus;
|
virtual void focus_handler(std::function<void(bool)>) = 0;
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
32
inc/basic_widgets/w/feat/focus_handler_impl.hpp
Normal file
32
inc/basic_widgets/w/feat/focus_handler_impl.hpp
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef BWIDGETS_FOCUS_HANDLER_IMPL_HPP
|
||||||
|
#define BWIDGETS_FOCUS_HANDLER_IMPL_HPP
|
||||||
|
|
||||||
|
#include <basic_widgets/w/feat/focus_handler.hpp>
|
||||||
|
|
||||||
|
namespace bwidgets
|
||||||
|
{
|
||||||
|
class FocusHandlerImpl : public virtual FocusHandler
|
||||||
|
{
|
||||||
|
bool _has_focus {false};
|
||||||
|
std::function<void(bool)> _focus_handler {[](auto) {}};
|
||||||
|
|
||||||
|
public:
|
||||||
|
void focus(bool focus_) override
|
||||||
|
{
|
||||||
|
_focus_handler(focus_);
|
||||||
|
_has_focus = focus_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool focus() override
|
||||||
|
{
|
||||||
|
return _has_focus;
|
||||||
|
}
|
||||||
|
|
||||||
|
void focus_handler(decltype(_focus_handler) handler) final
|
||||||
|
{
|
||||||
|
_focus_handler = std::move(handler);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef BWIDGETS_KEYBOARD_HANDLER
|
#ifndef BWIDGETS_KEYBOARD_HANDLER_HPP
|
||||||
#define BWIDGETS_KEYBOARD_HANDLER
|
#define BWIDGETS_KEYBOARD_HANDLER_HPP
|
||||||
|
|
||||||
|
#include <basic_widgets/w/feat/event_handler.hpp>
|
||||||
#include <basic_widgets/w/feat/focus_handler.hpp>
|
#include <basic_widgets/w/feat/focus_handler.hpp>
|
||||||
|
|
||||||
struct SDL_KeyboardEvent;
|
struct SDL_KeyboardEvent;
|
||||||
|
@ -8,34 +9,18 @@ struct SDL_TextInputEvent;
|
||||||
|
|
||||||
namespace bwidgets
|
namespace bwidgets
|
||||||
{
|
{
|
||||||
class KeyboardHandler : public virtual FocusHandler
|
class KeyboardHandler : public virtual EventHandler,
|
||||||
|
public virtual FocusHandler
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
virtual void _handle_key(const SDL_KeyboardEvent&) = 0;
|
using EventHandler::EventHandler;
|
||||||
virtual void _handle_text_input(const SDL_TextInputEvent&) = 0;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using FocusHandler::FocusHandler;
|
virtual void disable_keyboard_handler() = 0;
|
||||||
|
virtual void enable_keyboard_handler() = 0;
|
||||||
KeyboardHandler(const KeyboardHandler&) = delete;
|
virtual void key_handler(std::function<void(const SDL_KeyboardEvent&)>) = 0;
|
||||||
KeyboardHandler(KeyboardHandler&&) = delete;
|
virtual void
|
||||||
~KeyboardHandler() override = default;
|
text_input_handler(std::function<void(const SDL_TextInputEvent&)>) = 0;
|
||||||
auto operator=(const KeyboardHandler&) = delete;
|
|
||||||
auto operator=(KeyboardHandler&&) = delete;
|
|
||||||
|
|
||||||
virtual auto handle_keyboard(const SDL_KeyboardEvent& ev)
|
|
||||||
-> KeyboardHandler* final
|
|
||||||
{
|
|
||||||
if (_has_focus) _handle_key(ev);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual auto handle_keyboard(const SDL_TextInputEvent& ev)
|
|
||||||
-> KeyboardHandler* final
|
|
||||||
{
|
|
||||||
if (_has_focus) _handle_text_input(ev);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
31
inc/basic_widgets/w/feat/keyboard_handler_impl.hpp
Normal file
31
inc/basic_widgets/w/feat/keyboard_handler_impl.hpp
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef BWIDGETS_KEYBOARD_HANDLER_IMPL_HPP
|
||||||
|
#define BWIDGETS_KEYBOARD_HANDLER_IMPL_HPP
|
||||||
|
|
||||||
|
#include <basic_widgets/w/feat/event_handler_impl.hpp>
|
||||||
|
#include <basic_widgets/w/feat/focus_handler_impl.hpp>
|
||||||
|
#include <basic_widgets/w/feat/keyboard_handler.hpp>
|
||||||
|
|
||||||
|
namespace bwidgets
|
||||||
|
{
|
||||||
|
class KeyboardHandlerImpl : public KeyboardHandler,
|
||||||
|
virtual public EventHandlerImpl,
|
||||||
|
virtual public FocusHandlerImpl
|
||||||
|
{
|
||||||
|
std::function<void(const SDL_KeyboardEvent&)> _key_handler {[](auto) {}};
|
||||||
|
std::function<void(const SDL_TextInputEvent&)> _input_handler {[](auto) {}};
|
||||||
|
|
||||||
|
public:
|
||||||
|
void disable_keyboard_handler() override;
|
||||||
|
void enable_keyboard_handler() override;
|
||||||
|
void key_handler(decltype(_key_handler) handler) override
|
||||||
|
{
|
||||||
|
_key_handler = std::move(handler);
|
||||||
|
}
|
||||||
|
void text_input_handler(decltype(_input_handler) handler) override
|
||||||
|
{
|
||||||
|
_input_handler = std::move(handler);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,8 +1,7 @@
|
||||||
#ifndef BWIDGETS_MOUSE_HANDLER_HPP
|
#ifndef BWIDGETS_MOUSE_HANDLER_HPP
|
||||||
#define BWIDGETS_MOUSE_HANDLER_HPP
|
#define BWIDGETS_MOUSE_HANDLER_HPP
|
||||||
|
|
||||||
#include <functional>
|
#include <basic_widgets/w/feat/event_handler.hpp>
|
||||||
|
|
||||||
#include <basic_widgets/w/feat/focus_handler.hpp>
|
#include <basic_widgets/w/feat/focus_handler.hpp>
|
||||||
|
|
||||||
struct SDL_MouseButtonEvent;
|
struct SDL_MouseButtonEvent;
|
||||||
|
@ -10,35 +9,22 @@ struct SDL_MouseMotionEvent;
|
||||||
|
|
||||||
namespace bwidgets
|
namespace bwidgets
|
||||||
{
|
{
|
||||||
class MouseHandler : public virtual FocusHandler
|
class MouseHandler : virtual public FocusHandler,
|
||||||
|
virtual public EventHandler
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
const SDL_Rect* _click_area = nullptr;
|
using EventHandler::EventHandler;
|
||||||
bool _is_hovered = false;
|
|
||||||
bool _is_pushed = false;
|
|
||||||
|
|
||||||
virtual void _handle_mouse_button(const SDL_MouseButtonEvent&,
|
virtual void _on_push(bool) = 0;
|
||||||
const SDL_Rect&) {};
|
|
||||||
virtual void _handle_mouse_motion(const SDL_MouseMotionEvent&,
|
|
||||||
const SDL_Rect&) {};
|
|
||||||
virtual void _on_push(bool) {};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::function<void(const SDL_MouseButtonEvent&)> click_handler = nullptr;
|
virtual void click_handler(std::function<void(const SDL_MouseButtonEvent&)>) = 0;
|
||||||
|
virtual void disable_mouse_handler() = 0;
|
||||||
using FocusHandler::FocusHandler;
|
virtual void enable_mouse_handler(const SDL_Rect*, const SDL_Rect*) = 0;
|
||||||
|
[[nodiscard]] virtual bool hovered() const = 0;
|
||||||
MouseHandler(const MouseHandler&) = delete;
|
virtual void
|
||||||
MouseHandler(MouseHandler&&) = delete;
|
mouse_motion_handler(std::function<void(const SDL_MouseMotionEvent&)>) = 0;
|
||||||
~MouseHandler() override = default;
|
[[nodiscard]] virtual bool pushed() const = 0;
|
||||||
auto operator=(const MouseHandler&) = delete;
|
|
||||||
auto operator=(MouseHandler&&) = delete;
|
|
||||||
|
|
||||||
virtual auto handle_mouse(const SDL_MouseButtonEvent&, const SDL_Rect&)
|
|
||||||
-> MouseHandler* final;
|
|
||||||
virtual auto handle_mouse(const SDL_MouseMotionEvent&, const SDL_Rect&)
|
|
||||||
-> MouseHandler* final;
|
|
||||||
virtual auto push(bool) -> MouseHandler* final;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
54
inc/basic_widgets/w/feat/mouse_handler_impl.hpp
Normal file
54
inc/basic_widgets/w/feat/mouse_handler_impl.hpp
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#ifndef BWIDGETS_MOUSE_HANDLER_IMPL_HPP
|
||||||
|
#define BWIDGETS_MOUSE_HANDLER_IMPL_HPP
|
||||||
|
|
||||||
|
#include <basic_widgets/w/feat/event_handler_impl.hpp>
|
||||||
|
#include <basic_widgets/w/feat/focus_handler_impl.hpp>
|
||||||
|
#include <basic_widgets/w/feat/mouse_handler.hpp>
|
||||||
|
|
||||||
|
namespace bwidgets
|
||||||
|
{
|
||||||
|
class MouseHandlerImpl : public MouseHandler,
|
||||||
|
virtual public EventHandlerImpl,
|
||||||
|
virtual public FocusHandlerImpl
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
bool _hovered {false};
|
||||||
|
bool _pushed {false};
|
||||||
|
|
||||||
|
std::function<void(const SDL_MouseButtonEvent&)> _click_handler {[](auto) {}};
|
||||||
|
std::function<void(const SDL_MouseMotionEvent&)> _motion_handler {[](auto) {}};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
using MouseHandler::MouseHandler;
|
||||||
|
|
||||||
|
void _on_push(bool) override {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
void
|
||||||
|
click_handler(std::function<void(const SDL_MouseButtonEvent&)> handler) override
|
||||||
|
{
|
||||||
|
_click_handler = std::move(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disable_mouse_handler() override;
|
||||||
|
|
||||||
|
void enable_mouse_handler(const SDL_Rect*, const SDL_Rect*) override;
|
||||||
|
[[nodiscard]] bool hovered() const override
|
||||||
|
{
|
||||||
|
return _hovered;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mouse_motion_handler(
|
||||||
|
std::function<void(const SDL_MouseMotionEvent&)> handler) override
|
||||||
|
{
|
||||||
|
_motion_handler = std::move(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool pushed() const override
|
||||||
|
{
|
||||||
|
return _pushed;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -2,14 +2,13 @@
|
||||||
#define BWIDGETS_NUMERIC_INPUT_HPP
|
#define BWIDGETS_NUMERIC_INPUT_HPP
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#include <basic_widgets/core/math.hpp>
|
#include <basic_widgets/core/math.hpp>
|
||||||
#include <basic_widgets/core/type/concepts.hpp>
|
#include <basic_widgets/core/type/concepts.hpp>
|
||||||
#include <basic_widgets/w/base/input.hpp>
|
#include <basic_widgets/w/base/input.hpp>
|
||||||
#include <basic_widgets/w/button.hpp>
|
#include <basic_widgets/w/button.hpp>
|
||||||
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
namespace bwidgets
|
namespace bwidgets
|
||||||
{
|
{
|
||||||
template<Numeric T>
|
template<Numeric T>
|
||||||
|
@ -94,25 +93,25 @@ namespace bwidgets
|
||||||
|
|
||||||
_increment_button.text("+");
|
_increment_button.text("+");
|
||||||
|
|
||||||
_increment_button.click_handler = [this](const SDL_MouseButtonEvent&) {
|
_increment_button.click_handler([this](const SDL_MouseButtonEvent&) {
|
||||||
T new_value = this->value + button_step;
|
T new_value = this->value + button_step;
|
||||||
if (_value_range.second - this->value < button_step)
|
if (_value_range.second - this->value < button_step)
|
||||||
new_value = _value_range.second;
|
new_value = _value_range.second;
|
||||||
|
|
||||||
this->value = new_value;
|
this->value = new_value;
|
||||||
this->input_text(this->value_to_string(new_value));
|
this->input_text(this->value_to_string(new_value));
|
||||||
};
|
});
|
||||||
|
|
||||||
_decrement_button.text("-");
|
_decrement_button.text("-");
|
||||||
|
|
||||||
_decrement_button.click_handler = [this](const SDL_MouseButtonEvent&) {
|
_decrement_button.click_handler([this](const SDL_MouseButtonEvent&) {
|
||||||
T new_value = this->value - button_step;
|
T new_value = this->value - button_step;
|
||||||
if (this->value - _value_range.first < button_step)
|
if (this->value - _value_range.first < button_step)
|
||||||
new_value = _value_range.first;
|
new_value = _value_range.first;
|
||||||
|
|
||||||
this->value = new_value;
|
this->value = new_value;
|
||||||
this->input_text(this->value_to_string(new_value));
|
this->input_text(this->value_to_string(new_value));
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
NumericInput(const NumericInput&) = delete;
|
NumericInput(const NumericInput&) = delete;
|
||||||
|
@ -121,12 +120,11 @@ namespace bwidgets
|
||||||
auto operator=(const NumericInput&) = delete;
|
auto operator=(const NumericInput&) = delete;
|
||||||
auto operator=(NumericInput&&) = delete;
|
auto operator=(NumericInput&&) = delete;
|
||||||
|
|
||||||
auto handle_event(const SDL_Event& ev) -> Widget* override
|
void handle_event(const SDL_Event& ev) override
|
||||||
{
|
{
|
||||||
Input<T>::handle_event(ev);
|
Input<T>::handle_event(ev);
|
||||||
_increment_button.handle_event(ev);
|
_increment_button.handle_event(ev);
|
||||||
_decrement_button.handle_event(ev);
|
_decrement_button.handle_event(ev);
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] auto is_valid_input(const std::string& input) const noexcept
|
[[nodiscard]] auto is_valid_input(const std::string& input) const noexcept
|
||||||
|
|
10
meson.build
10
meson.build
|
@ -9,7 +9,7 @@ project('sdl2_basic_widgets', 'cpp',
|
||||||
],
|
],
|
||||||
license: 'EUPL-1.2')
|
license: 'EUPL-1.2')
|
||||||
|
|
||||||
add_project_arguments('-pedantic', '-Winline', language: 'cpp')
|
add_project_arguments('-pedantic', language: 'cpp')
|
||||||
|
|
||||||
if (get_option('buildtype').startswith('debug'))
|
if (get_option('buildtype').startswith('debug'))
|
||||||
add_project_arguments('-DBWIDGETS_DEBUG', language: 'cpp')
|
add_project_arguments('-DBWIDGETS_DEBUG', language: 'cpp')
|
||||||
|
@ -32,7 +32,9 @@ libbasic_widgets = static_library('basic_widgets',
|
||||||
'src/w/base/widget.cpp',
|
'src/w/base/widget.cpp',
|
||||||
'src/w/button.cpp',
|
'src/w/button.cpp',
|
||||||
'src/w/caption.cpp',
|
'src/w/caption.cpp',
|
||||||
'src/w/feat/mouse_handler.cpp',
|
'src/w/feat/event_handler_impl.cpp',
|
||||||
|
'src/w/feat/keyboard_handler_impl.cpp',
|
||||||
|
'src/w/feat/mouse_handler_impl.cpp',
|
||||||
dependencies : [sdl, fontconfig],
|
dependencies : [sdl, fontconfig],
|
||||||
include_directories : pub_api,
|
include_directories : pub_api,
|
||||||
install : true)
|
install : true)
|
||||||
|
@ -44,24 +46,28 @@ libbasic_widgets_dep = declare_dependency(
|
||||||
|
|
||||||
executable('button_demo',
|
executable('button_demo',
|
||||||
'examples/button_example.cpp',
|
'examples/button_example.cpp',
|
||||||
|
dependencies: [sdl],
|
||||||
include_directories : pub_api,
|
include_directories : pub_api,
|
||||||
link_with : libbasic_widgets,
|
link_with : libbasic_widgets,
|
||||||
install : false)
|
install : false)
|
||||||
|
|
||||||
executable('caption_demo',
|
executable('caption_demo',
|
||||||
'examples/caption_example.cpp',
|
'examples/caption_example.cpp',
|
||||||
|
dependencies: [sdl],
|
||||||
include_directories : pub_api,
|
include_directories : pub_api,
|
||||||
link_with : libbasic_widgets,
|
link_with : libbasic_widgets,
|
||||||
install : false)
|
install : false)
|
||||||
|
|
||||||
executable('example_demo',
|
executable('example_demo',
|
||||||
'examples/example_example.cpp',
|
'examples/example_example.cpp',
|
||||||
|
dependencies: [sdl],
|
||||||
include_directories : pub_api,
|
include_directories : pub_api,
|
||||||
link_with : libbasic_widgets,
|
link_with : libbasic_widgets,
|
||||||
install : false)
|
install : false)
|
||||||
|
|
||||||
executable('input_demo',
|
executable('input_demo',
|
||||||
'examples/input_example.cpp',
|
'examples/input_example.cpp',
|
||||||
|
dependencies: [sdl],
|
||||||
include_directories : pub_api,
|
include_directories : pub_api,
|
||||||
link_with : libbasic_widgets,
|
link_with : libbasic_widgets,
|
||||||
install : false)
|
install : false)
|
||||||
|
|
|
@ -17,10 +17,10 @@ void Layout::for_widgets(const std::function<void(Widget*)>& f)
|
||||||
for (const auto& w : _widgets) f(w.get());
|
for (const auto& w : _widgets) f(w.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Layout::handle_event(const SDL_Event& ev) -> Layout*
|
void Layout::handle_event(const SDL_Event& ev)
|
||||||
{
|
{
|
||||||
|
EventHandlerImpl::handle_event(ev);
|
||||||
for (const auto& w : _widgets) w->handle_event(ev);
|
for (const auto& w : _widgets) w->handle_event(ev);
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Layout::_handle_geometry_change(const SDL_Rect& vp)
|
void Layout::_handle_geometry_change(const SDL_Rect& vp)
|
||||||
|
|
|
@ -1,41 +1,7 @@
|
||||||
#include <SDL2/SDL_assert.h>
|
|
||||||
#include <SDL2/SDL_events.h>
|
|
||||||
|
|
||||||
#include <basic_widgets/w/base/widget.hpp>
|
#include <basic_widgets/w/base/widget.hpp>
|
||||||
#include <basic_widgets/w/feat/keyboard_handler.hpp>
|
|
||||||
#include <basic_widgets/w/feat/mouse_handler.hpp>
|
|
||||||
|
|
||||||
using namespace bwidgets;
|
using namespace bwidgets;
|
||||||
|
|
||||||
auto Widget::handle_event(const SDL_Event& ev) -> Widget*
|
|
||||||
{
|
|
||||||
if (auto* handler = dynamic_cast<KeyboardHandler*>(this); handler) {
|
|
||||||
switch (ev.type) {
|
|
||||||
case SDL_KEYDOWN:
|
|
||||||
case SDL_KEYUP:
|
|
||||||
handler->handle_keyboard(ev.key);
|
|
||||||
break;
|
|
||||||
case SDL_TEXTINPUT:
|
|
||||||
handler->handle_keyboard(ev.text);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (auto* handler = dynamic_cast<MouseHandler*>(this); handler) {
|
|
||||||
switch (ev.type) {
|
|
||||||
case SDL_MOUSEBUTTONDOWN:
|
|
||||||
case SDL_MOUSEBUTTONUP:
|
|
||||||
handler->handle_mouse(ev.button, _viewport);
|
|
||||||
break;
|
|
||||||
case SDL_MOUSEMOTION:
|
|
||||||
handler->handle_mouse(ev.motion, _viewport);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Widget::render() -> Widget*
|
auto Widget::render() -> Widget*
|
||||||
{
|
{
|
||||||
if (_renderer == nullptr) return this;
|
if (_renderer == nullptr) return this;
|
||||||
|
|
|
@ -13,13 +13,13 @@ const Color Button::default_color_fg {0, 0, 0, SDL_ALPHA_OPAQUE};
|
||||||
|
|
||||||
Button::Button(Widget* parent) noexcept : Widget {parent}, _caption {this}
|
Button::Button(Widget* parent) noexcept : Widget {parent}, _caption {this}
|
||||||
{
|
{
|
||||||
_focus_area = _click_area = &_widget_area;
|
enable_mouse_handler(&_widget_area, &_viewport);
|
||||||
_caption.alignment = Caption::Alignment::CENTER;
|
_caption.alignment = Caption::Alignment::CENTER;
|
||||||
|
|
||||||
_caption.render_mode(Font::RenderMode::BLENDED);
|
_caption.render_mode(Font::RenderMode::BLENDED);
|
||||||
|
|
||||||
border_gradient = [this](int len, int pos, float divider) -> Color {
|
border_gradient = [this](int len, int pos, float divider) -> Color {
|
||||||
const auto& end_color = _is_hovered ? color_bg_hover : color_bg;
|
const auto& end_color = hovered() ? color_bg_hover : color_bg;
|
||||||
const auto start_color = end_color / divider;
|
const auto start_color = end_color / divider;
|
||||||
const auto factor = linear(pos, 0, len);
|
const auto factor = linear(pos, 0, len);
|
||||||
return lerp(start_color, end_color, factor);
|
return lerp(start_color, end_color, factor);
|
||||||
|
@ -74,8 +74,8 @@ void Button::_handle_renderer_change(const std::shared_ptr<Renderer>& r)
|
||||||
|
|
||||||
void Button::_handle_rendering()
|
void Button::_handle_rendering()
|
||||||
{
|
{
|
||||||
Color c = _is_hovered ? color_bg_hover : color_bg;
|
Color c = hovered() ? color_bg_hover : color_bg;
|
||||||
const auto divider = _is_pushed ? 1.5 : 2;
|
const auto divider = pushed() ? 1.5 : 2;
|
||||||
auto x = 0;
|
auto x = 0;
|
||||||
auto y = 0;
|
auto y = 0;
|
||||||
const auto biggest = border_size.w > border_size.h ? border_size.w : border_size.h;
|
const auto biggest = border_size.w > border_size.h ? border_size.w : border_size.h;
|
||||||
|
|
32
src/w/feat/event_handler_impl.cpp
Normal file
32
src/w/feat/event_handler_impl.cpp
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#include <basic_widgets/w/feat/event_handler_impl.hpp>
|
||||||
|
|
||||||
|
using namespace bwidgets;
|
||||||
|
|
||||||
|
void EventHandlerImpl::handle_event(const SDL_Event& ev)
|
||||||
|
{
|
||||||
|
auto type = static_cast<SDL_EventType>(ev.type);
|
||||||
|
if (!_event_handlers.contains(type)) return;
|
||||||
|
|
||||||
|
_event_handlers[type](ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto EventHandlerImpl::_add_event_handler(handler_t event_handler) -> bool
|
||||||
|
{
|
||||||
|
if (_event_handlers.contains(event_handler.first)) return false;
|
||||||
|
|
||||||
|
_event_handlers.emplace(event_handler);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto EventHandlerImpl::_remove_event_handler(SDL_EventType ev_type)
|
||||||
|
-> std::pair<handler_t, bool>
|
||||||
|
{
|
||||||
|
handler_t handler;
|
||||||
|
auto pos = _event_handlers.find(ev_type);
|
||||||
|
if (pos == _event_handlers.end()) return {handler, false};
|
||||||
|
|
||||||
|
handler = {ev_type, _event_handlers[ev_type]};
|
||||||
|
_event_handlers.erase(pos);
|
||||||
|
|
||||||
|
return {handler, true};
|
||||||
|
}
|
23
src/w/feat/keyboard_handler_impl.cpp
Normal file
23
src/w/feat/keyboard_handler_impl.cpp
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#include <basic_widgets/w/feat/keyboard_handler_impl.hpp>
|
||||||
|
|
||||||
|
using namespace bwidgets;
|
||||||
|
|
||||||
|
void KeyboardHandlerImpl::disable_keyboard_handler()
|
||||||
|
{
|
||||||
|
_remove_event_handler(SDL_KEYDOWN);
|
||||||
|
_remove_event_handler(SDL_KEYUP);
|
||||||
|
_remove_event_handler(SDL_TEXTINPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardHandlerImpl::enable_keyboard_handler()
|
||||||
|
{
|
||||||
|
const auto keyboard_handler = [this](const SDL_Event& ev) {
|
||||||
|
if (FocusHandlerImpl::focus()) _key_handler(ev.key);
|
||||||
|
};
|
||||||
|
|
||||||
|
_add_event_handler({SDL_KEYDOWN, keyboard_handler});
|
||||||
|
_add_event_handler({SDL_KEYUP, keyboard_handler});
|
||||||
|
_add_event_handler({SDL_TEXTINPUT, [this](const SDL_Event& ev) {
|
||||||
|
if (FocusHandlerImpl::focus()) _input_handler(ev.text);
|
||||||
|
}});
|
||||||
|
}
|
|
@ -1,60 +0,0 @@
|
||||||
#include <SDL2/SDL_events.h>
|
|
||||||
#include <SDL2/SDL_rect.h>
|
|
||||||
|
|
||||||
#include <basic_widgets/core/math.hpp>
|
|
||||||
#include <basic_widgets/w/feat/mouse_handler.hpp>
|
|
||||||
|
|
||||||
using namespace bwidgets;
|
|
||||||
|
|
||||||
auto MouseHandler::handle_mouse(const SDL_MouseButtonEvent& ev, const SDL_Rect& orig)
|
|
||||||
-> MouseHandler*
|
|
||||||
{
|
|
||||||
if (_click_area == nullptr) return this;
|
|
||||||
|
|
||||||
const SDL_Point p {ev.x, ev.y};
|
|
||||||
const SDL_Rect vp {rect_offset(*_click_area, orig)};
|
|
||||||
|
|
||||||
if (ev.type == SDL_MOUSEBUTTONDOWN) {
|
|
||||||
if (SDL_PointInRect(&p, &vp) == SDL_TRUE) {
|
|
||||||
push(true);
|
|
||||||
_handle_mouse_button(ev, vp);
|
|
||||||
}
|
|
||||||
else focus(false);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (_is_pushed) {
|
|
||||||
if (SDL_PointInRect(&p, &vp) == SDL_TRUE) {
|
|
||||||
focus(true);
|
|
||||||
|
|
||||||
if (click_handler != nullptr) click_handler(ev);
|
|
||||||
}
|
|
||||||
push(false);
|
|
||||||
_handle_mouse_button(ev, vp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto MouseHandler::handle_mouse(const SDL_MouseMotionEvent& ev, const SDL_Rect& orig)
|
|
||||||
-> MouseHandler*
|
|
||||||
{
|
|
||||||
if (_click_area == nullptr) return this;
|
|
||||||
|
|
||||||
const SDL_Point p {ev.x, ev.y};
|
|
||||||
const SDL_Rect vp {rect_offset(*_click_area, orig)};
|
|
||||||
|
|
||||||
_is_hovered = SDL_PointInRect(&p, &vp) != 0;
|
|
||||||
|
|
||||||
if (_is_hovered) _handle_mouse_motion(ev, orig);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto MouseHandler::push(bool state) -> MouseHandler*
|
|
||||||
{
|
|
||||||
_on_push(state);
|
|
||||||
_is_pushed = state;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
50
src/w/feat/mouse_handler_impl.cpp
Normal file
50
src/w/feat/mouse_handler_impl.cpp
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#include <basic_widgets/core/math.hpp>
|
||||||
|
#include <basic_widgets/w/feat/mouse_handler_impl.hpp>
|
||||||
|
|
||||||
|
using namespace bwidgets;
|
||||||
|
|
||||||
|
void MouseHandlerImpl::disable_mouse_handler()
|
||||||
|
{
|
||||||
|
EventHandlerImpl::_remove_event_handler(SDL_MOUSEBUTTONDOWN);
|
||||||
|
EventHandlerImpl::_remove_event_handler(SDL_MOUSEBUTTONUP);
|
||||||
|
_remove_event_handler(SDL_MOUSEMOTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
|
||||||
|
void MouseHandlerImpl::enable_mouse_handler(const SDL_Rect* area, const SDL_Rect* vp)
|
||||||
|
{
|
||||||
|
if (!area || !vp) throw std::logic_error("ptr parameters cannot be null.");
|
||||||
|
|
||||||
|
_add_event_handler({SDL_MOUSEBUTTONDOWN, [this, area, vp](const SDL_Event& ev) {
|
||||||
|
auto absolute_area = rect_offset(*area, *vp);
|
||||||
|
SDL_Point p = {ev.button.x, ev.button.y};
|
||||||
|
if (SDL_PointInRect(&p, &absolute_area) == SDL_FALSE) {
|
||||||
|
FocusHandlerImpl::focus(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_on_push(true);
|
||||||
|
_pushed = true;
|
||||||
|
}});
|
||||||
|
_add_event_handler({SDL_MOUSEBUTTONUP, [this, area, vp](const SDL_Event& ev) {
|
||||||
|
auto absolute_area = rect_offset(*area, *vp);
|
||||||
|
SDL_Point p = {ev.button.x, ev.button.y};
|
||||||
|
if (_pushed) {
|
||||||
|
_on_push(false);
|
||||||
|
_pushed = false;
|
||||||
|
}
|
||||||
|
if (SDL_PointInRect(&p, &absolute_area) == SDL_FALSE) return;
|
||||||
|
|
||||||
|
FocusHandlerImpl::focus(true);
|
||||||
|
_click_handler(ev.button);
|
||||||
|
}});
|
||||||
|
_add_event_handler({SDL_MOUSEMOTION, [this, area, vp](const SDL_Event& ev) {
|
||||||
|
auto absolute_area = rect_offset(*area, *vp);
|
||||||
|
SDL_Point p = {ev.motion.x, ev.motion.y};
|
||||||
|
if (SDL_PointInRect(&p, &absolute_area) == SDL_FALSE) {
|
||||||
|
_hovered = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_hovered = true;
|
||||||
|
_motion_handler(ev.motion);
|
||||||
|
}});
|
||||||
|
}
|
Loading…
Reference in a new issue