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')
|
cairomm_dep = dependency('cairomm-1.0')
|
||||||
pangocairo_dep = dependency('pangocairo')
|
pangocairo_dep = dependency('pangocairo')
|
||||||
xlib_dep = dependency('x11')
|
xlib_dep = dependency('x11')
|
||||||
|
|
||||||
executable(
|
executable(
|
||||||
'blit_app',
|
'ravenapp',
|
||||||
'./src/Box.cpp',
|
'./src/Box.cpp',
|
||||||
'./src/Point.cpp',
|
|
||||||
'./src/Events.cpp',
|
'./src/Events.cpp',
|
||||||
'./src/Widget.cpp',
|
'./src/Widget.cpp',
|
||||||
|
'./src/Painter.cpp',
|
||||||
'./src/Window.cpp',
|
'./src/Window.cpp',
|
||||||
'./src/main.cpp',
|
'./src/main.cpp',
|
||||||
dependencies : [cairomm_dep, xlib_dep, pangocairo_dep]
|
dependencies : [cairomm_dep, xlib_dep, pangocairo_dep]
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "Point.hpp"
|
#include "Point.hpp"
|
||||||
|
|
||||||
namespace Raven {
|
namespace Raven {
|
||||||
|
|
||||||
enum class EventType {
|
enum class EventType {
|
||||||
None,
|
NoneEvent,
|
||||||
|
|
||||||
MouseButton,
|
MouseButton,
|
||||||
MouseMove
|
MouseMove,
|
||||||
|
WidgetRepaintRequested
|
||||||
};
|
};
|
||||||
|
|
||||||
class Event {
|
class Event {
|
||||||
|
@ -18,8 +21,10 @@ public:
|
||||||
|
|
||||||
void accept() { m_accepted = true; }
|
void accept() { m_accepted = true; }
|
||||||
bool is_accepted() { return m_accepted; }
|
bool is_accepted() { return m_accepted; }
|
||||||
virtual EventType get_event_type() { return EventType::None; }
|
virtual EventType get_type() { return EventType::NoneEvent; }
|
||||||
virtual const char *get_event_name() { return "None"; }
|
virtual const char *get_name() { return "NoneEvent"; }
|
||||||
|
|
||||||
|
virtual ~Event() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MouseButtonEvent : public Event {
|
class MouseButtonEvent : public Event {
|
||||||
|
@ -31,8 +36,8 @@ public:
|
||||||
: m_was_left_button_pressed(was_left_button_pressed)
|
: m_was_left_button_pressed(was_left_button_pressed)
|
||||||
, m_was_right_button_pressed(was_right_button_pressed) {}
|
, m_was_right_button_pressed(was_right_button_pressed) {}
|
||||||
|
|
||||||
EventType get_event_type() { return EventType::MouseButton; }
|
EventType get_type() { return EventType::MouseButton; }
|
||||||
const char *get_event_name() { return "MouseButton"; }
|
const char *get_name() { return "MouseButton"; }
|
||||||
|
|
||||||
bool get_was_left_button_pressed() { return m_was_left_button_pressed; }
|
bool get_was_left_button_pressed() { return m_was_left_button_pressed; }
|
||||||
bool get_was_right_button_pressed() { return m_was_right_button_pressed; }
|
bool get_was_right_button_pressed() { return m_was_right_button_pressed; }
|
||||||
|
@ -45,10 +50,18 @@ public:
|
||||||
MouseMoveEvent(Point point)
|
MouseMoveEvent(Point point)
|
||||||
: m_point(point) {}
|
: m_point(point) {}
|
||||||
|
|
||||||
EventType get_event_type() { return EventType::MouseMove; }
|
EventType get_type() { return EventType::MouseMove; }
|
||||||
const char *get_event_name() { return "MouseMove"; }
|
const char *get_name() { return "MouseMove"; }
|
||||||
|
|
||||||
Point &get_point() { return m_point; }
|
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 {
|
namespace Raven {
|
||||||
|
|
||||||
class Painter {
|
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>
|
#include <stdint.h>
|
||||||
|
|
||||||
namespace Raven {
|
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
|
#pragma once
|
||||||
|
|
||||||
#include "Box.hpp"
|
#include "Box.hpp"
|
||||||
|
#include "Events.hpp"
|
||||||
|
|
||||||
namespace Raven {
|
namespace Raven {
|
||||||
|
|
||||||
|
@ -13,6 +14,16 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
const Box &get_current_geometry() const { return m_current_geometry; }
|
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 <iostream>
|
||||||
#include "Window.hpp"
|
#include "Window.hpp"
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <cairomm-1.0/cairomm/cairomm.h>
|
#include <X11/Xutil.h>
|
||||||
#include <cairomm-1.0/cairomm/context.h>
|
#include <cairomm/cairomm.h>
|
||||||
#include <cairomm-1.0/cairomm/surface.h>
|
#include <cairomm/context.h>
|
||||||
#include <cairomm-1.0/cairomm/xlib_surface.h>
|
#include <cairomm/surface.h>
|
||||||
|
#include <cairomm/xlib_surface.h>
|
||||||
|
|
||||||
namespace Raven {
|
namespace Raven {
|
||||||
|
|
||||||
bool Window::spawn_window() {
|
bool Window::spawn_window() {
|
||||||
Display *dsp;
|
Display *dsp = XOpenDisplay(NULL);
|
||||||
Drawable da;
|
if (dsp == NULL) {
|
||||||
int screen;
|
|
||||||
|
|
||||||
if ((dsp = XOpenDisplay(NULL)) == NULL) {
|
|
||||||
std::cout << "error: XOpenDisplay(NULL)" << "\n";
|
std::cout << "error: XOpenDisplay(NULL)" << "\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
m_x_display = dsp;
|
||||||
|
|
||||||
screen = DefaultScreen(dsp);
|
int screen = DefaultScreen(dsp);
|
||||||
da = XCreateSimpleWindow(dsp, DefaultRootWindow(dsp), 0, 0, get_current_geometry().get_width(), get_current_geometry().get_height(), 0, 0, 0);
|
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);
|
|
||||||
|
XSelectInput(dsp, da, ButtonPressMask | ButtonReleaseMask | KeyPressMask | PointerMotionMask | StructureNotifyMask | ExposureMask);
|
||||||
XMapWindow(dsp, da);
|
XMapWindow(dsp, da);
|
||||||
auto x_surface = Cairo::XlibSurface::create(
|
|
||||||
|
auto cairo_xlib_surface = Cairo::XlibSurface::create(
|
||||||
dsp,
|
dsp,
|
||||||
da,
|
da,
|
||||||
DefaultVisual(dsp, screen),
|
DefaultVisual(dsp, screen),
|
||||||
get_current_geometry().get_width(),
|
get_current_geometry().get_width(),
|
||||||
get_current_geometry().get_height()
|
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;
|
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 "Widget.hpp"
|
||||||
|
#include "Painter.hpp"
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
namespace Raven {
|
namespace Raven {
|
||||||
|
|
||||||
|
@ -6,17 +10,21 @@ class Window {
|
||||||
private:
|
private:
|
||||||
Widget *m_active_widget { nullptr };
|
Widget *m_active_widget { nullptr };
|
||||||
Box m_current_geometry { 0, 0, 800, 600 };
|
Box m_current_geometry { 0, 0, 800, 600 };
|
||||||
public:
|
Painter m_painter {};
|
||||||
Window() {
|
|
||||||
|
|
||||||
}
|
Display *m_x_display { nullptr };
|
||||||
|
public:
|
||||||
|
Window() {}
|
||||||
|
|
||||||
|
Painter &get_painter() { return m_painter; }
|
||||||
|
|
||||||
Widget *get_active_widget() { return m_active_widget; }
|
Widget *get_active_widget() { return m_active_widget; }
|
||||||
void set_active_widget(Widget *active_widget) { m_active_widget = active_widget; }
|
void set_active_widget(Widget *active_widget) { m_active_widget = active_widget; }
|
||||||
|
|
||||||
Box &get_current_geometry() { return m_current_geometry; }
|
Box &get_current_geometry() { return m_current_geometry; }
|
||||||
|
|
||||||
bool spawn_window();
|
bool spawn_window();
|
||||||
void window_event_loop();
|
void run(bool block);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ int main() {
|
||||||
Raven::Window window {};
|
Raven::Window window {};
|
||||||
|
|
||||||
window.spawn_window();
|
window.spawn_window();
|
||||||
for(;;){}
|
window.run(true);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
Loading…
Reference in a new issue