add basic multi-window support
This commit is contained in:
parent
035522591f
commit
e6be3bb378
7 changed files with 111 additions and 13 deletions
|
@ -26,6 +26,7 @@ raven_source_files = [
|
|||
'./src/Box.cpp',
|
||||
'./src/Styles.cpp',
|
||||
'./src/Painter.cpp',
|
||||
'./src/Application.cpp',
|
||||
'./src/Window.cpp',
|
||||
'./src/Widget.cpp',
|
||||
'./src/SvgWidget.cpp',
|
||||
|
@ -61,6 +62,7 @@ raven_header_files = [
|
|||
'./src/Styles.hpp',
|
||||
'./src/Widget.hpp',
|
||||
'./src/SvgWidget.hpp',
|
||||
'./src/Application.hpp',
|
||||
'./src/Window.hpp'
|
||||
]
|
||||
|
||||
|
|
55
src/Application.cpp
Normal file
55
src/Application.cpp
Normal file
|
@ -0,0 +1,55 @@
|
|||
#include "Application.hpp"
|
||||
#include <poll.h>
|
||||
|
||||
namespace Raven {
|
||||
|
||||
void Application::add_window(std::shared_ptr<Window> window) {
|
||||
m_windows.push_back(window);
|
||||
update_fds();
|
||||
}
|
||||
|
||||
void Application::update_fds() {
|
||||
for (int i = 0; i < RAVEN_APPLICATION_MAX_WINDOWS; i++) {
|
||||
m_fds[i].fd = -1;
|
||||
m_fds[i].events = 0;
|
||||
m_fds[i].revents = 0;
|
||||
}
|
||||
for (size_t i = 0; i < m_windows.size(); i++) {
|
||||
m_fds[i].fd = m_windows[i]->file_descriptor();
|
||||
m_fds[i].events = POLL_IN;
|
||||
}
|
||||
}
|
||||
|
||||
int Application::turn() {
|
||||
if (m_fds_need_update) {
|
||||
update_fds();
|
||||
m_fds_need_update = false;
|
||||
}
|
||||
if (poll(m_fds, m_windows.size(), -1) > 0) {
|
||||
for (size_t i = 0; i < m_windows.size(); i++) {
|
||||
if (m_fds[i].revents & POLLIN) {
|
||||
m_windows[i]->run(false);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Application::run() {
|
||||
// Make sure any pending events are dealt with before starting the loop
|
||||
for (size_t i = 0; i < m_windows.size(); i++) {
|
||||
m_windows[i]->run(false);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
int ret = turn();
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
34
src/Application.hpp
Normal file
34
src/Application.hpp
Normal file
|
@ -0,0 +1,34 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <poll.h>
|
||||
#include "Window.hpp"
|
||||
|
||||
namespace Raven {
|
||||
|
||||
#define RAVEN_APPLICATION_MAX_WINDOWS 1023
|
||||
|
||||
class Application {
|
||||
public:
|
||||
Application() {}
|
||||
|
||||
void add_window(std::shared_ptr<Window>);
|
||||
int turn();
|
||||
int run();
|
||||
|
||||
template<class... Args>
|
||||
std::shared_ptr<Window> add_window(Args&&... args) {
|
||||
std::shared_ptr<Window> child = std::make_shared<Window>(std::forward<Args>(args)...);
|
||||
add_window(child);
|
||||
return child;
|
||||
}
|
||||
private:
|
||||
void update_fds();
|
||||
|
||||
std::vector<std::shared_ptr<Window>> m_windows;
|
||||
struct pollfd m_fds[RAVEN_APPLICATION_MAX_WINDOWS];
|
||||
bool m_fds_need_update { true };
|
||||
};
|
||||
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
#include "cairomm/enums.h"
|
||||
#include "cairomm/refptr.h"
|
||||
#include "cairomm/surface.h"
|
||||
#include "raven/Widget.hpp"
|
||||
#include "Widget.hpp"
|
||||
#include "librsvg/rsvg.h"
|
||||
|
||||
namespace Raven {
|
||||
|
|
|
@ -69,6 +69,10 @@ bool Window::spawn_window() {
|
|||
return true;
|
||||
}
|
||||
|
||||
int Window::file_descriptor() {
|
||||
return m_x_display ? XConnectionNumber(m_x_display) : -1;
|
||||
}
|
||||
|
||||
bool Window::dispatch_to_main_widget(Event &event) {
|
||||
if (!m_main_widget)
|
||||
return false;
|
||||
|
@ -157,7 +161,6 @@ void Window::swallow_batches() {
|
|||
|
||||
void Window::run(bool block) {
|
||||
XEvent e;
|
||||
bool is_loop_batch_started = false;
|
||||
|
||||
swallow_batches();
|
||||
|
||||
|
@ -167,9 +170,9 @@ void Window::run(bool block) {
|
|||
else
|
||||
break;
|
||||
|
||||
if (!is_loop_batch_started) {
|
||||
if (!m_is_loop_batch_started) {
|
||||
start_batch();
|
||||
is_loop_batch_started = true;
|
||||
m_is_loop_batch_started = true;
|
||||
}
|
||||
switch (e.type) {
|
||||
case MapNotify: {
|
||||
|
@ -254,9 +257,9 @@ void Window::run(bool block) {
|
|||
callback();
|
||||
m_microtasks.pop();
|
||||
}
|
||||
if (is_loop_batch_started) {
|
||||
if (m_is_loop_batch_started) {
|
||||
end_batch();
|
||||
is_loop_batch_started = false;
|
||||
m_is_loop_batch_started = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ public:
|
|||
bool spawn_window();
|
||||
void run(bool block);
|
||||
|
||||
int file_descriptor();
|
||||
|
||||
void start_batch();
|
||||
void end_batch();
|
||||
void swallow_batches();
|
||||
|
@ -64,6 +66,7 @@ private:
|
|||
Box m_invalidated_area {0, 0, 0, 0};
|
||||
bool m_did_relayout_during_batch { false };
|
||||
std::queue<std::function<void()>> m_microtasks;
|
||||
bool m_is_loop_batch_started { false };
|
||||
|
||||
Display *m_x_display { nullptr };
|
||||
XIM m_xim { nullptr };
|
||||
|
|
15
src/main.cpp
15
src/main.cpp
|
@ -1,4 +1,5 @@
|
|||
#include "Label.hpp"
|
||||
#include "Application.hpp"
|
||||
#include "ColumnLayout.hpp"
|
||||
#include "ListView.hpp"
|
||||
#include "TextInput.hpp"
|
||||
|
@ -20,10 +21,13 @@
|
|||
#include <string>
|
||||
|
||||
int main() {
|
||||
Raven::Window window {};
|
||||
window.spawn_window();
|
||||
Raven::Application application {};
|
||||
|
||||
auto window = application.add_window();
|
||||
|
||||
auto main_widget = window.set_main_widget<Raven::Widget>();
|
||||
window->spawn_window();
|
||||
|
||||
auto main_widget = window->set_main_widget<Raven::Widget>();
|
||||
auto main_widget_layout = main_widget->set_layout<Raven::BoxLayout>(Raven::Direction::Horizontal);
|
||||
main_widget_layout->set_margin(8);
|
||||
main_widget_layout->set_spacing(8);
|
||||
|
@ -54,8 +58,6 @@ int main() {
|
|||
delete_button->set_style(&Raven::raised_button_style);
|
||||
delete_button->set_grows(true);
|
||||
|
||||
content->add<Raven::Label>("Edit an item");
|
||||
|
||||
auto edit_row = content->add<Raven::Widget>();
|
||||
edit_row->set_style(&Raven::raised_widget_style);
|
||||
auto edit_row_layout = edit_row->set_layout<Raven::BoxLayout>(Raven::Direction::Horizontal);
|
||||
|
@ -96,6 +98,5 @@ int main() {
|
|||
}
|
||||
list_view->elements_updated();
|
||||
|
||||
window.run(true);
|
||||
return 0;
|
||||
return application.run();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue