make window respond to events and lay more groundwork
This commit is contained in:
parent
2cc5e1c1e0
commit
b4cfe309f3
10 changed files with 135 additions and 37 deletions
|
@ -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]
|
||||
|
|
|
@ -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"; }
|
||||
};
|
||||
|
||||
}
|
|
@ -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; }
|
||||
};
|
||||
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Raven {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ int main() {
|
|||
Raven::Window window {};
|
||||
|
||||
window.spawn_window();
|
||||
for(;;){}
|
||||
window.run(true);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue