make window respond to events and lay more groundwork

This commit is contained in:
hippoz 2022-03-09 03:46:27 +02:00
parent 2cc5e1c1e0
commit b4cfe309f3
No known key found for this signature in database
GPG key ID: 7C52899193467641
10 changed files with 135 additions and 37 deletions

View file

@ -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]

View file

@ -1,13 +1,16 @@
#pragma once
#include <stdint.h>
#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; }
};
class WidgetRepaintRequestedEvent : public Event {
public:
WidgetRepaintRequestedEvent() {}
EventType get_type() { return EventType::WidgetRepaintRequested; }
const char *get_name() { return "WidgetRepaintRequested"; }
};
}

View file

@ -1,9 +1,17 @@
#pragma once
#include <cairomm/cairomm.h>
namespace Raven {
class Painter {
Painter() {
private:
Cairo::RefPtr<Cairo::Context> m_cairo;
public:
Painter() {}
}
Cairo::RefPtr<Cairo::Context> get_cairo() { return m_cairo; }
void set_cairo(Cairo::RefPtr<Cairo::Context> cairo) { m_cairo = cairo; }
};
}

View file

View file

@ -1,3 +1,5 @@
#pragma once
#include <stdint.h>
namespace Raven {

View file

@ -0,0 +1,31 @@
#include <iostream>
#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<MouseMoveEvent&>(event));
break;
}
case EventType::MouseButton: {
on_mouse_button(reinterpret_cast<MouseButtonEvent&>(event));
break;
}
case EventType::WidgetRepaintRequested: {
on_paint();
break;
}
case EventType::NoneEvent: {
break;
}
}
}
}

View file

@ -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);
};
}

View file

@ -1,37 +1,63 @@
#include <X11/X.h>
#include <iostream>
#include "Window.hpp"
#include <X11/Xlib.h>
#include <cairomm-1.0/cairomm/cairomm.h>
#include <cairomm-1.0/cairomm/context.h>
#include <cairomm-1.0/cairomm/surface.h>
#include <cairomm-1.0/cairomm/xlib_surface.h>
#include <X11/Xutil.h>
#include <cairomm/cairomm.h>
#include <cairomm/context.h>
#include <cairomm/surface.h>
#include <cairomm/xlib_surface.h>
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;
}
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;
}
}
}
}
}

View file

@ -1,4 +1,8 @@
#pragma once
#include "Widget.hpp"
#include "Painter.hpp"
#include <X11/Xlib.h>
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);
};
}

View file

@ -2,10 +2,10 @@
#include "Window.hpp"
int main() {
Raven::Window window{};
Raven::Window window {};
window.spawn_window();
for(;;){}
window.run(true);
return 0;
}