Compare commits

..

3 Commits

Author SHA1 Message Date
e85dc97e91
libui: Add default handlers for events in Widget
All checks were successful
continuous-integration/drone/pr Build is passing
2023-08-29 15:32:33 +02:00
2c7ae3c61b
libui: Propagate Container events only if they are in the child widget's rect 2023-08-29 15:29:17 +02:00
f0f1a9c46c
libui+wind: Handle mouse leave events when the mouse leaves a window 2023-08-29 15:26:34 +02:00
16 changed files with 84 additions and 56 deletions

View File

@ -14,22 +14,12 @@ struct ColorWidget : public ui::Widget
return ui::EventResult::DidHandle; return ui::EventResult::DidHandle;
} }
Result<ui::EventResult> handle_mouse_leave(ui::Point) override Result<ui::EventResult> handle_mouse_leave() override
{ {
m_color = m_first_color; m_color = m_first_color;
return ui::EventResult::DidHandle; return ui::EventResult::DidHandle;
} }
Result<ui::EventResult> handle_mouse_down(ui::Point, int) override
{
return ui::EventResult::DidNotHandle;
}
Result<ui::EventResult> handle_mouse_up(ui::Point, int) override
{
return ui::EventResult::DidNotHandle;
}
Result<void> draw(ui::Canvas& canvas) override Result<void> draw(ui::Canvas& canvas) override
{ {
canvas.fill(m_color); canvas.fill(m_color);

View File

@ -21,7 +21,7 @@ namespace ui
void set_action(void (*action)(void)); void set_action(void (*action)(void));
Result<EventResult> handle_mouse_move(Point position) override; Result<EventResult> handle_mouse_move(Point position) override;
Result<EventResult> handle_mouse_leave(Point position) override; Result<EventResult> handle_mouse_leave() override;
Result<EventResult> handle_mouse_down(Point position, int buttons) override; Result<EventResult> handle_mouse_down(Point position, int buttons) override;
Result<EventResult> handle_mouse_up(Point position, int buttons) override; Result<EventResult> handle_mouse_up(Point position, int buttons) override;
Result<void> draw(Canvas& canvas) override; Result<void> draw(Canvas& canvas) override;

View File

@ -21,7 +21,7 @@ namespace ui
void set_widget(Widget& widget); void set_widget(Widget& widget);
Result<EventResult> handle_mouse_move(Point position) override; Result<EventResult> handle_mouse_move(Point position) override;
Result<EventResult> handle_mouse_leave(Point position) override; Result<EventResult> handle_mouse_leave() override;
Result<EventResult> handle_mouse_down(Point position, int buttons) override; Result<EventResult> handle_mouse_down(Point position, int buttons) override;
Result<EventResult> handle_mouse_up(Point position, int buttons) override; Result<EventResult> handle_mouse_up(Point position, int buttons) override;
Result<void> draw(Canvas& canvas) override; Result<void> draw(Canvas& canvas) override;

View File

@ -84,10 +84,6 @@ namespace ui
public: public:
static Result<OwnedPtr<ImageWidget>> load(const os::Path& path); static Result<OwnedPtr<ImageWidget>> load(const os::Path& path);
Result<EventResult> handle_mouse_move(Point position) override;
Result<EventResult> handle_mouse_leave(Point position) override;
Result<EventResult> handle_mouse_down(Point position, int buttons) override;
Result<EventResult> handle_mouse_up(Point position, int buttons) override;
Result<void> draw(Canvas& canvas) override; Result<void> draw(Canvas& canvas) override;
private: private:

View File

@ -31,7 +31,7 @@ namespace ui
HorizontalLayout(AdjustHeight adjust_height = AdjustHeight::Yes, AdjustWidth adjust_width = AdjustWidth::Yes); HorizontalLayout(AdjustHeight adjust_height = AdjustHeight::Yes, AdjustWidth adjust_width = AdjustWidth::Yes);
Result<EventResult> handle_mouse_move(Point position) override; Result<EventResult> handle_mouse_move(Point position) override;
Result<EventResult> handle_mouse_leave(Point position) override; Result<EventResult> handle_mouse_leave() override;
Result<EventResult> handle_mouse_down(Point position, int buttons) override; Result<EventResult> handle_mouse_down(Point position, int buttons) override;
Result<EventResult> handle_mouse_up(Point position, int buttons) override; Result<EventResult> handle_mouse_up(Point position, int buttons) override;
@ -52,7 +52,7 @@ namespace ui
VerticalLayout(AdjustHeight adjust_height = AdjustHeight::Yes, AdjustWidth adjust_width = AdjustWidth::Yes); VerticalLayout(AdjustHeight adjust_height = AdjustHeight::Yes, AdjustWidth adjust_width = AdjustWidth::Yes);
Result<EventResult> handle_mouse_move(Point position) override; Result<EventResult> handle_mouse_move(Point position) override;
Result<EventResult> handle_mouse_leave(Point position) override; Result<EventResult> handle_mouse_leave() override;
Result<EventResult> handle_mouse_down(Point position, int buttons) override; Result<EventResult> handle_mouse_down(Point position, int buttons) override;
Result<EventResult> handle_mouse_up(Point position, int buttons) override; Result<EventResult> handle_mouse_up(Point position, int buttons) override;

View File

@ -8,6 +8,7 @@
*/ */
#pragma once #pragma once
#include <luna/Ignore.h>
#include <luna/Result.h> #include <luna/Result.h>
#include <ui/Canvas.h> #include <ui/Canvas.h>
#include <ui/Point.h> #include <ui/Point.h>
@ -26,10 +27,28 @@ namespace ui
class Widget class Widget
{ {
public: public:
virtual Result<EventResult> handle_mouse_move(Point position); virtual Result<EventResult> handle_mouse_move(Point position)
virtual Result<EventResult> handle_mouse_down(Point position, int buttons); {
virtual Result<EventResult> handle_mouse_up(Point position, int buttons); ignore(position);
virtual Result<EventResult> handle_mouse_leave(Point position); return EventResult::DidNotHandle;
}
virtual Result<EventResult> handle_mouse_down(Point position, int buttons)
{
ignore(position, buttons);
return EventResult::DidNotHandle;
}
virtual Result<EventResult> handle_mouse_up(Point position, int buttons)
{
ignore(position, buttons);
return EventResult::DidNotHandle;
}
virtual Result<EventResult> handle_mouse_leave()
{
return EventResult::DidNotHandle;
}
virtual Result<void> draw(Canvas& canvas); virtual Result<void> draw(Canvas& canvas);

View File

@ -46,6 +46,7 @@ namespace ui
void close(); void close();
Result<void> draw(); Result<void> draw();
Result<void> handle_mouse_leave();
Result<void> handle_mouse_move(ui::Point position); Result<void> handle_mouse_move(ui::Point position);
Result<void> handle_mouse_buttons(ui::Point position, int buttons); Result<void> handle_mouse_buttons(ui::Point position, int buttons);

View File

@ -19,6 +19,7 @@ namespace ui
CREATE_WINDOW_RESPONSE_ID, CREATE_WINDOW_RESPONSE_ID,
WINDOW_CLOSE_REQUEST_ID, WINDOW_CLOSE_REQUEST_ID,
MOUSE_EVENT_REQUEST_ID, MOUSE_EVENT_REQUEST_ID,
MOUSE_LEAVE_REQUEST_ID,
GET_SCREEN_RECT_RESPONSE_ID GET_SCREEN_RECT_RESPONSE_ID
}; };
@ -46,6 +47,13 @@ namespace ui
int buttons; int buttons;
}; };
struct MouseLeaveRequest
{
static constexpr u8 ID = MOUSE_LEAVE_REQUEST_ID;
int window;
};
struct GetScreenRectResponse struct GetScreenRectResponse
{ {
static constexpr u8 ID = GET_SCREEN_RECT_RESPONSE_ID; static constexpr u8 ID = GET_SCREEN_RECT_RESPONSE_ID;

View File

@ -122,6 +122,14 @@ namespace ui
window->draw(); window->draw();
return {}; return {};
} }
case MOUSE_LEAVE_REQUEST_ID: {
MouseLeaveRequest request;
READ_MESSAGE(request);
auto* window = find_window(request.window);
window->handle_mouse_leave();
window->draw();
return {};
}
default: fail("Unexpected IPC request from server!"); default: fail("Unexpected IPC request from server!");
} }
} }

View File

@ -35,10 +35,10 @@ namespace ui
return m_child->handle_mouse_move(position); return m_child->handle_mouse_move(position);
} }
Result<EventResult> Button::handle_mouse_leave(Point position) Result<EventResult> Button::handle_mouse_leave()
{ {
m_hovered = m_clicked = false; m_hovered = m_clicked = false;
return m_child->handle_mouse_leave(position); return m_child->handle_mouse_leave();
} }
Result<EventResult> Button::handle_mouse_down(Point position, int buttons) Result<EventResult> Button::handle_mouse_down(Point position, int buttons)

View File

@ -26,22 +26,25 @@ namespace ui
Result<EventResult> Container::handle_mouse_move(Point position) Result<EventResult> Container::handle_mouse_move(Point position)
{ {
return m_widget->handle_mouse_move(position); if (m_widget->rect().contains(position)) return m_widget->handle_mouse_move(position);
return ui::EventResult::DidNotHandle;
} }
Result<EventResult> Container::handle_mouse_leave(Point position) Result<EventResult> Container::handle_mouse_leave()
{ {
return m_widget->handle_mouse_leave(position); return m_widget->handle_mouse_leave();
} }
Result<EventResult> Container::handle_mouse_down(Point position, int buttons) Result<EventResult> Container::handle_mouse_down(Point position, int buttons)
{ {
return m_widget->handle_mouse_down(position, buttons); if (m_widget->rect().contains(position)) return m_widget->handle_mouse_down(position, buttons);
return ui::EventResult::DidNotHandle;
} }
Result<EventResult> Container::handle_mouse_up(Point position, int buttons) Result<EventResult> Container::handle_mouse_up(Point position, int buttons)
{ {
return m_widget->handle_mouse_up(position, buttons); if (m_widget->rect().contains(position)) return m_widget->handle_mouse_up(position, buttons);
return ui::EventResult::DidNotHandle;
} }
Result<void> Container::draw(Canvas& canvas) Result<void> Container::draw(Canvas& canvas)

View File

@ -40,26 +40,6 @@ namespace ui
return widget; return widget;
} }
Result<EventResult> ImageWidget::handle_mouse_move(Point)
{
return EventResult::DidNotHandle;
}
Result<EventResult> ImageWidget::handle_mouse_leave(Point)
{
return EventResult::DidNotHandle;
}
Result<EventResult> ImageWidget::handle_mouse_up(Point, int)
{
return EventResult::DidNotHandle;
}
Result<EventResult> ImageWidget::handle_mouse_down(Point, int)
{
return EventResult::DidNotHandle;
}
Result<void> ImageWidget::draw(Canvas& canvas) Result<void> ImageWidget::draw(Canvas& canvas)
{ {
canvas.subcanvas({ 0, 0, m_image->width(), m_image->height() }).fill(m_image->pixels(), m_image->width()); canvas.subcanvas({ 0, 0, m_image->width(), m_image->height() }).fill(m_image->pixels(), m_image->width());

View File

@ -25,15 +25,15 @@ namespace ui
{ {
if (widget->rect().contains(position)) result = TRY(widget->handle_mouse_move(position)); if (widget->rect().contains(position)) result = TRY(widget->handle_mouse_move(position));
else else
TRY(widget->handle_mouse_leave(position)); TRY(widget->handle_mouse_leave());
} }
return result; return result;
} }
Result<EventResult> HorizontalLayout::handle_mouse_leave(Point position) Result<EventResult> HorizontalLayout::handle_mouse_leave()
{ {
for (auto widget : m_widgets) TRY(widget->handle_mouse_leave(position)); for (auto widget : m_widgets) TRY(widget->handle_mouse_leave());
return ui::EventResult::DidNotHandle; return ui::EventResult::DidNotHandle;
} }
@ -114,15 +114,15 @@ namespace ui
{ {
if (widget->rect().contains(position)) result = TRY(widget->handle_mouse_move(position)); if (widget->rect().contains(position)) result = TRY(widget->handle_mouse_move(position));
else else
TRY(widget->handle_mouse_leave(position)); TRY(widget->handle_mouse_leave());
} }
return result; return result;
} }
Result<EventResult> VerticalLayout::handle_mouse_leave(Point position) Result<EventResult> VerticalLayout::handle_mouse_leave()
{ {
for (auto widget : m_widgets) TRY(widget->handle_mouse_leave(position)); for (auto widget : m_widgets) TRY(widget->handle_mouse_leave());
return ui::EventResult::DidNotHandle; return ui::EventResult::DidNotHandle;
} }

View File

@ -101,6 +101,13 @@ namespace ui
return {}; return {};
} }
Result<void> Window::handle_mouse_leave()
{
if (!m_main_widget) return {};
TRY(m_main_widget->handle_mouse_leave());
return {};
}
Result<void> Window::handle_mouse_move(ui::Point position) Result<void> Window::handle_mouse_move(ui::Point position)
{ {
if (!m_main_widget) return {}; if (!m_main_widget) return {};

View File

@ -79,6 +79,8 @@ void Mouse::update(const moon::MousePacket& packet)
} }
} }
Window* new_active_window = nullptr;
for (Window* window = g_windows.last().value_or(nullptr); window; for (Window* window = g_windows.last().value_or(nullptr); window;
window = g_windows.previous(window).value_or(nullptr)) window = g_windows.previous(window).value_or(nullptr))
{ {
@ -92,7 +94,19 @@ void Mouse::update(const moon::MousePacket& packet)
request.position = contents.relative(m_position); request.position = contents.relative(m_position);
request.buttons = packet.buttons; request.buttons = packet.buttons;
os::IPC::send_async(window->client->conn, request); os::IPC::send_async(window->client->conn, request);
new_active_window = window;
break; break;
} }
} }
if (m_active_window != new_active_window)
{
if (m_active_window)
{
ui::MouseLeaveRequest request;
request.window = m_active_window->id;
os::IPC::send_async(m_active_window->client->conn, request);
}
m_active_window = new_active_window;
}
} }

View File

@ -19,4 +19,6 @@ class Mouse
Window* m_dragging_window = nullptr; Window* m_dragging_window = nullptr;
ui::Point m_initial_drag_position; ui::Point m_initial_drag_position;
Window* m_active_window = nullptr;
}; };