From 742fb4d8a69488577f51b7a3db27aa9ed4e19774 Mon Sep 17 00:00:00 2001 From: apio Date: Tue, 15 Aug 2023 15:10:13 +0200 Subject: [PATCH] libui: Handle other mouse events --- apps/gclient.cpp | 31 ++++++++++++---- libui/include/ui/Container.h | 5 ++- libui/include/ui/Image.h | 5 ++- libui/include/ui/Layout.h | 10 ++++-- libui/include/ui/Mouse.h | 21 +++++++++++ libui/include/ui/Widget.h | 5 ++- libui/include/ui/Window.h | 5 ++- libui/src/App.cpp | 2 +- libui/src/Container.cpp | 19 ++++++++-- libui/src/Image.cpp | 17 ++++++++- libui/src/Layout.cpp | 70 +++++++++++++++++++++++++++++++++--- libui/src/Window.cpp | 19 ++++++++-- 12 files changed, 187 insertions(+), 22 deletions(-) create mode 100644 libui/include/ui/Mouse.h diff --git a/apps/gclient.cpp b/apps/gclient.cpp index 23821081..404f6f8c 100644 --- a/apps/gclient.cpp +++ b/apps/gclient.cpp @@ -4,11 +4,28 @@ struct ColorWidget : public ui::Widget { public: - ColorWidget(ui::Color color) : m_color(color) + ColorWidget(ui::Color first, ui::Color second) : m_color(first), m_first_color(first), m_second_color(second) { } - Result handle_mousemove(ui::Point) override + Result handle_mouse_move(ui::Point) override + { + m_color = m_second_color; + return ui::EventResult::DidHandle; + } + + Result handle_mouse_leave(ui::Point) override + { + m_color = m_first_color; + return ui::EventResult::DidHandle; + } + + Result handle_mouse_down(ui::Point, int) override + { + return ui::EventResult::DidNotHandle; + } + + Result handle_mouse_up(ui::Point, int) override { return ui::EventResult::DidNotHandle; } @@ -21,6 +38,8 @@ struct ColorWidget : public ui::Widget private: ui::Color m_color; + ui::Color m_first_color; + ui::Color m_second_color; }; Result luna_main(int argc, char** argv) @@ -37,17 +56,17 @@ Result luna_main(int argc, char** argv) ui::HorizontalLayout layout; window->set_main_widget(layout); - ColorWidget green(ui::GREEN); + ColorWidget green(ui::GREEN, ui::WHITE); layout.add_widget(green); - ColorWidget blue(ui::BLUE); + ColorWidget blue(ui::BLUE, ui::GRAY); layout.add_widget(blue); ui::VerticalLayout sublayout; layout.add_widget(sublayout); - ColorWidget red(ui::RED); + ColorWidget red(ui::RED, ui::CYAN); sublayout.add_widget(red); - ColorWidget white(ui::WHITE); + ColorWidget white(ui::WHITE, ui::GREEN); sublayout.add_widget(white); window->draw(); diff --git a/libui/include/ui/Container.h b/libui/include/ui/Container.h index 6a4e565c..6bd703a2 100644 --- a/libui/include/ui/Container.h +++ b/libui/include/ui/Container.h @@ -20,7 +20,10 @@ namespace ui void set_widget(Widget& widget); - Result handle_mousemove(Point position) override; + Result handle_mouse_move(Point position) override; + Result handle_mouse_leave(Point position) override; + Result handle_mouse_down(Point position, int buttons) override; + Result handle_mouse_up(Point position, int buttons) override; Result draw(Canvas& canvas) override; private: diff --git a/libui/include/ui/Image.h b/libui/include/ui/Image.h index 6ad0bd13..2db7579f 100644 --- a/libui/include/ui/Image.h +++ b/libui/include/ui/Image.h @@ -84,7 +84,10 @@ namespace ui public: static Result> load(const os::Path& path); - Result handle_mousemove(Point position) override; + Result handle_mouse_move(Point position) override; + Result handle_mouse_leave(Point position) override; + Result handle_mouse_down(Point position, int buttons) override; + Result handle_mouse_up(Point position, int buttons) override; Result draw(Canvas& canvas) override; private: diff --git a/libui/include/ui/Layout.h b/libui/include/ui/Layout.h index 83cb0fef..47b54fda 100644 --- a/libui/include/ui/Layout.h +++ b/libui/include/ui/Layout.h @@ -30,7 +30,10 @@ namespace ui public: HorizontalLayout(AdjustHeight adjust_height = AdjustHeight::Yes, AdjustWidth adjust_width = AdjustWidth::Yes); - Result handle_mousemove(Point position) override; + Result handle_mouse_move(Point position) override; + Result handle_mouse_leave(Point position) override; + Result handle_mouse_down(Point position, int buttons) override; + Result handle_mouse_up(Point position, int buttons) override; Result draw(Canvas& canvas) override; @@ -48,7 +51,10 @@ namespace ui public: VerticalLayout(AdjustHeight adjust_height = AdjustHeight::Yes, AdjustWidth adjust_width = AdjustWidth::Yes); - Result handle_mousemove(Point position) override; + Result handle_mouse_move(Point position) override; + Result handle_mouse_leave(Point position) override; + Result handle_mouse_down(Point position, int buttons) override; + Result handle_mouse_up(Point position, int buttons) override; Result draw(Canvas& canvas) override; diff --git a/libui/include/ui/Mouse.h b/libui/include/ui/Mouse.h new file mode 100644 index 00000000..db28dda7 --- /dev/null +++ b/libui/include/ui/Mouse.h @@ -0,0 +1,21 @@ +/** + * @file Mouse.h + * @author apio (cloudapio.eu) + * @brief Mouse buttons. + * + * @copyright Copyright (c) 2023, the Luna authors. + * + */ + +#pragma once +#include + +namespace ui +{ + enum MouseButtons + { + LEFT = moon::Left, + MIDDLE = moon::Middle, + RIGHT = moon::Right, + }; +} diff --git a/libui/include/ui/Widget.h b/libui/include/ui/Widget.h index 24b1f31f..74ee1435 100644 --- a/libui/include/ui/Widget.h +++ b/libui/include/ui/Widget.h @@ -26,7 +26,10 @@ namespace ui class Widget { public: - virtual Result handle_mousemove(Point position); + virtual Result handle_mouse_move(Point position); + virtual Result handle_mouse_down(Point position, int buttons); + virtual Result handle_mouse_up(Point position, int buttons); + virtual Result handle_mouse_leave(Point position); virtual Result draw(Canvas& canvas); diff --git a/libui/include/ui/Window.h b/libui/include/ui/Window.h index 490cf3ec..9f440a36 100644 --- a/libui/include/ui/Window.h +++ b/libui/include/ui/Window.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -45,7 +46,8 @@ namespace ui void close(); Result draw(); - Result handle_mousemove(ui::Point position); + Result handle_mouse_move(ui::Point position); + Result handle_mouse_buttons(ui::Point position, int buttons); int id() const { @@ -59,5 +61,6 @@ namespace ui Canvas m_canvas; Widget* m_main_widget { nullptr }; Color m_background { ui::BLACK }; + Option m_old_mouse_buttons; }; } diff --git a/libui/src/App.cpp b/libui/src/App.cpp index 7a979206..035820d3 100644 --- a/libui/src/App.cpp +++ b/libui/src/App.cpp @@ -104,7 +104,7 @@ namespace ui MouseEventRequest request; TRY(m_client->recv_typed(request)); auto* window = find_window(request.window); - window->handle_mousemove(request.position); + window->handle_mouse_move(request.position); window->draw(); return {}; } diff --git a/libui/src/Container.cpp b/libui/src/Container.cpp index f6fe7abd..e40b1b55 100644 --- a/libui/src/Container.cpp +++ b/libui/src/Container.cpp @@ -23,9 +23,24 @@ namespace ui widget.rect() = ui::align(m_rect, widget.rect(), m_valign, m_halign); } - Result Container::handle_mousemove(Point position) + Result Container::handle_mouse_move(Point position) { - return m_widget->handle_mousemove(position); + return m_widget->handle_mouse_move(position); + } + + Result Container::handle_mouse_leave(Point position) + { + return m_widget->handle_mouse_leave(position); + } + + Result Container::handle_mouse_down(Point position, int buttons) + { + return m_widget->handle_mouse_down(position, buttons); + } + + Result Container::handle_mouse_up(Point position, int buttons) + { + return m_widget->handle_mouse_up(position, buttons); } Result Container::draw(Canvas& canvas) diff --git a/libui/src/Image.cpp b/libui/src/Image.cpp index e8f9b6ba..050bef2b 100644 --- a/libui/src/Image.cpp +++ b/libui/src/Image.cpp @@ -40,7 +40,22 @@ namespace ui return widget; } - Result ImageWidget::handle_mousemove(Point) + Result ImageWidget::handle_mouse_move(Point) + { + return EventResult::DidNotHandle; + } + + Result ImageWidget::handle_mouse_leave(Point) + { + return EventResult::DidNotHandle; + } + + Result ImageWidget::handle_mouse_up(Point, int) + { + return EventResult::DidNotHandle; + } + + Result ImageWidget::handle_mouse_down(Point, int) { return EventResult::DidNotHandle; } diff --git a/libui/src/Layout.cpp b/libui/src/Layout.cpp index 4eeca17f..4beeb1a4 100644 --- a/libui/src/Layout.cpp +++ b/libui/src/Layout.cpp @@ -17,11 +17,42 @@ namespace ui { } - Result HorizontalLayout::handle_mousemove(Point position) + Result HorizontalLayout::handle_mouse_move(Point position) + { + EventResult result = ui::EventResult::DidNotHandle; + + for (auto widget : m_widgets) + { + if (widget->rect().contains(position)) result = TRY(widget->handle_mouse_move(position)); + else + TRY(widget->handle_mouse_leave(position)); + } + + return result; + } + + Result HorizontalLayout::handle_mouse_leave(Point position) + { + for (auto widget : m_widgets) TRY(widget->handle_mouse_leave(position)); + + return ui::EventResult::DidNotHandle; + } + + Result HorizontalLayout::handle_mouse_up(Point position, int buttons) { for (auto widget : m_widgets) { - if (widget->rect().contains(position)) return widget->handle_mousemove(position); + if (widget->rect().contains(position)) return widget->handle_mouse_up(position, buttons); + } + + return ui::EventResult::DidNotHandle; + } + + Result HorizontalLayout::handle_mouse_down(Point position, int buttons) + { + for (auto widget : m_widgets) + { + if (widget->rect().contains(position)) return widget->handle_mouse_down(position, buttons); } return ui::EventResult::DidNotHandle; @@ -75,11 +106,42 @@ namespace ui { } - Result VerticalLayout::handle_mousemove(Point position) + Result VerticalLayout::handle_mouse_move(Point position) + { + EventResult result = ui::EventResult::DidNotHandle; + + for (auto widget : m_widgets) + { + if (widget->rect().contains(position)) result = TRY(widget->handle_mouse_move(position)); + else + TRY(widget->handle_mouse_leave(position)); + } + + return result; + } + + Result VerticalLayout::handle_mouse_leave(Point position) + { + for (auto widget : m_widgets) TRY(widget->handle_mouse_leave(position)); + + return ui::EventResult::DidNotHandle; + } + + Result VerticalLayout::handle_mouse_up(Point position, int buttons) { for (auto widget : m_widgets) { - if (widget->rect().contains(position)) return widget->handle_mousemove(position); + if (widget->rect().contains(position)) return widget->handle_mouse_up(position, buttons); + } + + return ui::EventResult::DidNotHandle; + } + + Result VerticalLayout::handle_mouse_down(Point position, int buttons) + { + for (auto widget : m_widgets) + { + if (widget->rect().contains(position)) return widget->handle_mouse_down(position, buttons); } return ui::EventResult::DidNotHandle; diff --git a/libui/src/Window.cpp b/libui/src/Window.cpp index 99d2e66d..cbbfc068 100644 --- a/libui/src/Window.cpp +++ b/libui/src/Window.cpp @@ -101,9 +101,24 @@ namespace ui return {}; } - Result Window::handle_mousemove(ui::Point position) + Result Window::handle_mouse_move(ui::Point position) { - if (m_main_widget) TRY(m_main_widget->handle_mousemove(position)); + if (!m_main_widget) return {}; + TRY(m_main_widget->handle_mouse_move(position)); + return {}; + } + + Result Window::handle_mouse_buttons(ui::Point position, int buttons) + { + if (!m_main_widget) return {}; + if (buttons) TRY(m_main_widget->handle_mouse_down(position, buttons)); + if (m_old_mouse_buttons.has_value()) + { + int old_buttons = m_old_mouse_buttons.value(); + int diff = old_buttons & ~buttons; + if (diff) TRY(m_main_widget->handle_mouse_up(position, diff)); + } + m_old_mouse_buttons = buttons; return {}; } }