From b4cfe309f32cf4876e60a651824367e7a94fc3ff Mon Sep 17 00:00:00 2001 From: hippoz <10706925-hippoz@users.noreply.gitlab.com> Date: Wed, 9 Mar 2022 03:46:27 +0200 Subject: [PATCH] make window respond to events and lay more groundwork --- meson.build | 7 +++---- src/Events.hpp | 31 +++++++++++++++++++-------- src/Painter.hpp | 14 ++++++++++--- src/Point.cpp | 0 src/Point.hpp | 2 ++ src/Widget.cpp | 31 +++++++++++++++++++++++++++ src/Widget.hpp | 11 ++++++++++ src/Window.cpp | 56 ++++++++++++++++++++++++++++++++++++------------- src/Window.hpp | 16 ++++++++++---- src/main.cpp | 4 ++-- 10 files changed, 135 insertions(+), 37 deletions(-) delete mode 100644 src/Point.cpp diff --git a/meson.build b/meson.build index bbf25d7..464d4d5 100644 --- a/meson.build +++ b/meson.build @@ -1,16 +1,15 @@ -project('blit', 'cpp') - +project('raven', 'cpp') cairomm_dep = dependency('cairomm-1.0') pangocairo_dep = dependency('pangocairo') xlib_dep = dependency('x11') executable( - 'blit_app', + 'ravenapp', './src/Box.cpp', - './src/Point.cpp', './src/Events.cpp', './src/Widget.cpp', + './src/Painter.cpp', './src/Window.cpp', './src/main.cpp', dependencies : [cairomm_dep, xlib_dep, pangocairo_dep] diff --git a/src/Events.hpp b/src/Events.hpp index ba63f5a..81b60d4 100644 --- a/src/Events.hpp +++ b/src/Events.hpp @@ -1,13 +1,16 @@ +#pragma once + #include #include "Point.hpp" namespace Raven { enum class EventType { - None, + NoneEvent, MouseButton, - MouseMove + MouseMove, + WidgetRepaintRequested }; class Event { @@ -18,8 +21,10 @@ public: void accept() { m_accepted = true; } bool is_accepted() { return m_accepted; } - virtual EventType get_event_type() { return EventType::None; } - virtual const char *get_event_name() { return "None"; } + virtual EventType get_type() { return EventType::NoneEvent; } + virtual const char *get_name() { return "NoneEvent"; } + + virtual ~Event() = default; }; class MouseButtonEvent : public Event { @@ -31,8 +36,8 @@ public: : m_was_left_button_pressed(was_left_button_pressed) , m_was_right_button_pressed(was_right_button_pressed) {} - EventType get_event_type() { return EventType::MouseButton; } - const char *get_event_name() { return "MouseButton"; } + EventType get_type() { return EventType::MouseButton; } + const char *get_name() { return "MouseButton"; } bool get_was_left_button_pressed() { return m_was_left_button_pressed; } bool get_was_right_button_pressed() { return m_was_right_button_pressed; } @@ -45,10 +50,18 @@ public: MouseMoveEvent(Point point) : m_point(point) {} - EventType get_event_type() { return EventType::MouseMove; } - const char *get_event_name() { return "MouseMove"; } + EventType get_type() { return EventType::MouseMove; } + const char *get_name() { return "MouseMove"; } Point &get_point() { return m_point; } }; -} \ No newline at end of file +class WidgetRepaintRequestedEvent : public Event { +public: + WidgetRepaintRequestedEvent() {} + + EventType get_type() { return EventType::WidgetRepaintRequested; } + const char *get_name() { return "WidgetRepaintRequested"; } +}; + +} diff --git a/src/Painter.hpp b/src/Painter.hpp index 2173cea..b3446d1 100644 --- a/src/Painter.hpp +++ b/src/Painter.hpp @@ -1,9 +1,17 @@ +#pragma once + +#include + namespace Raven { class Painter { - Painter() { +private: + Cairo::RefPtr m_cairo; +public: + Painter() {} - } + Cairo::RefPtr get_cairo() { return m_cairo; } + void set_cairo(Cairo::RefPtr cairo) { m_cairo = cairo; } }; -} \ No newline at end of file +} diff --git a/src/Point.cpp b/src/Point.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/src/Point.hpp b/src/Point.hpp index 7cda038..336cbf0 100644 --- a/src/Point.hpp +++ b/src/Point.hpp @@ -1,3 +1,5 @@ +#pragma once + #include namespace Raven { diff --git a/src/Widget.cpp b/src/Widget.cpp index e69de29..f762550 100644 --- a/src/Widget.cpp +++ b/src/Widget.cpp @@ -0,0 +1,31 @@ +#include +#include "Widget.hpp" +#include "Events.hpp" + +namespace Raven { + +void Widget::dispatch_event(Event &event) { + process_event(event); +} + +void Widget::process_event(Event &event) { + switch (event.get_type()) { + case EventType::MouseMove: { + on_mouse_move(reinterpret_cast(event)); + break; + } + case EventType::MouseButton: { + on_mouse_button(reinterpret_cast(event)); + break; + } + case EventType::WidgetRepaintRequested: { + on_paint(); + break; + } + case EventType::NoneEvent: { + break; + } + } +} + +} \ No newline at end of file diff --git a/src/Widget.hpp b/src/Widget.hpp index 0c4e4ac..151f7bc 100644 --- a/src/Widget.hpp +++ b/src/Widget.hpp @@ -1,6 +1,7 @@ #pragma once #include "Box.hpp" +#include "Events.hpp" namespace Raven { @@ -13,6 +14,16 @@ public: } const Box &get_current_geometry() const { return m_current_geometry; } + + void dispatch_event(Event &event); + + virtual void on_mouse_button(MouseButtonEvent &event) = 0; + virtual void on_mouse_move(MouseMoveEvent &event) = 0; + virtual void on_paint() = 0; + + virtual ~Widget() = default; +private: + void process_event(Event &event); }; } \ No newline at end of file diff --git a/src/Window.cpp b/src/Window.cpp index 83eb78b..2ab0cae 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -1,37 +1,63 @@ +#include #include #include "Window.hpp" #include -#include -#include -#include -#include +#include +#include +#include +#include +#include namespace Raven { bool Window::spawn_window() { - Display *dsp; - Drawable da; - int screen; - - if ((dsp = XOpenDisplay(NULL)) == NULL) { + Display *dsp = XOpenDisplay(NULL); + if (dsp == NULL) { std::cout << "error: XOpenDisplay(NULL)" << "\n"; return false; } + m_x_display = dsp; - screen = DefaultScreen(dsp); - da = XCreateSimpleWindow(dsp, DefaultRootWindow(dsp), 0, 0, get_current_geometry().get_width(), get_current_geometry().get_height(), 0, 0, 0); - XSelectInput(dsp, da, ButtonPressMask | ButtonReleaseMask | KeyPressMask | PointerMotionMask); + int screen = DefaultScreen(dsp); + Drawable da = XCreateSimpleWindow(dsp, DefaultRootWindow(dsp), 0, 0, m_current_geometry.get_width(), m_current_geometry.get_height(), 0, 0, 0); + + XSelectInput(dsp, da, ButtonPressMask | ButtonReleaseMask | KeyPressMask | PointerMotionMask | StructureNotifyMask | ExposureMask); XMapWindow(dsp, da); - auto x_surface = Cairo::XlibSurface::create( + + auto cairo_xlib_surface = Cairo::XlibSurface::create( dsp, da, DefaultVisual(dsp, screen), get_current_geometry().get_width(), get_current_geometry().get_height() ); - Cairo::Context::create(x_surface); + auto cairo_context = Cairo::Context::create(cairo_xlib_surface); + + m_painter.set_cairo(cairo_context); return true; } -} \ No newline at end of file +void Window::run(bool block) { + XEvent e; + + for (;;) { + if (block || XPending(m_x_display)) + XNextEvent(m_x_display, &e); + else + break; + + switch (e.type) { + case MapNotify: { + std::cout << "MapNotify\n"; + break; + } + case Expose: { + std::cout << "we'd probably repaint the window right now\n"; + break; + } + } + } +} + +} diff --git a/src/Window.hpp b/src/Window.hpp index 294863e..b450cc6 100644 --- a/src/Window.hpp +++ b/src/Window.hpp @@ -1,4 +1,8 @@ +#pragma once + #include "Widget.hpp" +#include "Painter.hpp" +#include namespace Raven { @@ -6,17 +10,21 @@ class Window { private: Widget *m_active_widget { nullptr }; Box m_current_geometry { 0, 0, 800, 600 }; -public: - Window() { + Painter m_painter {}; - } + Display *m_x_display { nullptr }; +public: + Window() {} + + Painter &get_painter() { return m_painter; } Widget *get_active_widget() { return m_active_widget; } void set_active_widget(Widget *active_widget) { m_active_widget = active_widget; } + Box &get_current_geometry() { return m_current_geometry; } bool spawn_window(); - void window_event_loop(); + void run(bool block); }; } diff --git a/src/main.cpp b/src/main.cpp index f086965..befbfae 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,10 +2,10 @@ #include "Window.hpp" int main() { - Raven::Window window{}; + Raven::Window window {}; window.spawn_window(); - for(;;){} + window.run(true); return 0; } \ No newline at end of file