Visual Computing Library  devel
Loading...
Searching...
No Matches
window_manager.h
1/*****************************************************************************
2 * VCLib *
3 * Visual Computing Library *
4 * *
5 * Copyright(C) 2021-2025 *
6 * Visual Computing Lab *
7 * ISTI - Italian National Research Council *
8 * *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the Mozilla Public License Version 2.0 as published *
13 * by the Mozilla Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * Mozilla Public License Version 2.0 *
20 * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. *
21 ****************************************************************************/
22
23#ifndef VCL_QT_WINDOW_MANAGER_H
24#define VCL_QT_WINDOW_MANAGER_H
25
26#include "input.h"
27
28#include <vclib/render/concepts/render_app.h>
29#include <vclib/render/window_managers.h>
30#include <vclib/space/core/point.h>
31
32#include <QGuiApplication>
33#include <QMouseEvent>
34#include <QWindow>
35
36namespace vcl::qt {
37
38template<typename DerivedRenderApp>
39class WindowManager : public QWindow
40{
41 std::string mTitle;
42
43public:
44 using ParentType = QWindow;
45
46 static const uint WINDOW_MANAGER_ID = WindowManagerId::QT_WINDOW;
47
48 explicit WindowManager(QWindow* parent = nullptr) : QWindow(parent)
49 {
50 static_assert(
52 "The DerivedRenderApp must satisfy the RenderAppConcept.");
53 setSurfaceType(QSurface::OpenGLSurface);
54 }
55
56 explicit WindowManager(
57 const std::string& windowTitle,
58 uint width = 1024,
59 uint height = 768,
60 QWindow* parent = nullptr) : WindowManager(parent)
61 {
62 setGeometry(100, 100, width, height);
63 setTitle(QString::fromStdString(windowTitle));
64 }
65
66 ~WindowManager() override = default;
67
68 bool isMinimized() const
69 {
70 return QWindow::visibility() == QWindow::Minimized;
71 }
72
73 const std::string& windowTitle() const { return mTitle; }
74
75 void setWindowTitle(const std::string& title)
76 {
77 mTitle = title;
78 setTitle(QString::fromStdString(title));
79 }
80
81 Point2f dpiScale() const
82 {
83 auto* screen = this->screen();
84 return Point2f(
85 screen ? screen->devicePixelRatio() : 1.0,
86 screen ? screen->devicePixelRatio() : 1.0);
87 }
88
89 void* displayId() const
90 {
91 void* displayID = nullptr;
92#ifdef Q_OS_LINUX
93 QNativeInterface::QX11Application* x11AppInfo =
94 qApp->nativeInterface<QNativeInterface::QX11Application>();
95 if (x11AppInfo) {
96 displayID = x11AppInfo->display();
97 }
98 else {
99 QNativeInterface::QWaylandApplication* wayAppInfo =
100 qApp->nativeInterface<QNativeInterface::QWaylandApplication>();
101 if (wayAppInfo) {
102 displayID = wayAppInfo->display();
103 }
104 else {
105 exit(-1);
106 }
107 }
108#endif
109 return displayID;
110 }
111
112 void* windowPtr() { return reinterpret_cast<void*>(winId()); }
113
114 void update() { QWindow::requestUpdate(); }
115
116protected:
117 bool event(QEvent* event)
118 {
119 if (event->type() == QEvent::UpdateRequest) {
120 DerivedRenderApp::WM::paint(derived());
121 return true;
122 }
123 return QWindow::event(event);
124 }
125
126 void resizeEvent(QResizeEvent* event) override
127 {
128 DerivedRenderApp::WM::resize(
129 derived(), width() * dpiScale().x(), height() * dpiScale().y());
130 QWindow::resizeEvent(event);
131 update();
132 }
133
134 void exposeEvent(QExposeEvent* event) override
135 {
136 if (isExposed()) {
137 DerivedRenderApp::WM::init(derived());
138 }
139 QWindow::exposeEvent(event);
140 update();
141 }
142
143 void keyPressEvent(QKeyEvent* event) override
144 {
145 DerivedRenderApp::WM::setModifiers(
146 derived(), vcl::qt::fromQt(event->modifiers()));
147
148 DerivedRenderApp::WM::keyPress(
149 derived(),
150 vcl::qt::fromQt((Qt::Key) event->key(), event->modifiers()));
151 QWindow::keyPressEvent(event);
152 update();
153 }
154
155 void keyReleaseEvent(QKeyEvent* event) override
156 {
157 DerivedRenderApp::WM::setModifiers(
158 derived(), vcl::qt::fromQt(event->modifiers()));
159
160 DerivedRenderApp::WM::keyRelease(
161 derived(),
162 vcl::qt::fromQt((Qt::Key) event->key(), event->modifiers()));
163 QWindow::keyReleaseEvent(event);
164 update();
165 }
166
167 void mouseMoveEvent(QMouseEvent* event) override
168 {
169 DerivedRenderApp::WM::mouseMove(
170 derived(),
171 event->pos().x() * dpiScale().x(),
172 event->pos().y() * dpiScale().y());
173 QWindow::mouseMoveEvent(event);
174 update();
175 }
176
177 void mousePressEvent(QMouseEvent* event) override
178 {
179 DerivedRenderApp::WM::mousePress(
180 derived(),
181 vcl::qt::fromQt(event->button()),
182 event->pos().x() * dpiScale().x(),
183 event->pos().y() * dpiScale().y());
184 QWindow::mousePressEvent(event);
185 update();
186 }
187
188 void mouseReleaseEvent(QMouseEvent* event) override
189 {
190 DerivedRenderApp::WM::mouseRelease(
191 derived(),
192 vcl::qt::fromQt(event->button()),
193 event->pos().x() * dpiScale().x(),
194 event->pos().y() * dpiScale().y());
195 QWindow::mouseReleaseEvent(event);
196 update();
197 }
198
199 void mouseDoubleClickEvent(QMouseEvent* event) override
200 {
201 DerivedRenderApp::WM::mouseDoubleClick(
202 derived(),
203 vcl::qt::fromQt(event->button()),
204 event->pos().x() * dpiScale().x(),
205 event->pos().y() * dpiScale().y());
206 QWindow::mouseDoubleClickEvent(event);
207 update();
208 }
209
210 void wheelEvent(QWheelEvent* event) override
211 {
212 if (!event->pixelDelta().isNull())
213 DerivedRenderApp::WM::mouseScroll(
214 derived(), event->pixelDelta().x(), event->pixelDelta().y());
215 else
216 DerivedRenderApp::WM::mouseScroll(
217 derived(), event->angleDelta().x(), event->angleDelta().y());
218
219 QWindow::wheelEvent(event);
220 update();
221 }
222
223private:
224 void paintEvent(QPaintEvent* event) override
225 {
226 DerivedRenderApp::WM::paint(derived());
227 QWindow::paintEvent(event);
228 }
229
230 auto* derived() { return static_cast<DerivedRenderApp*>(this); }
231
232 const auto* derived() const
233 {
234 return static_cast<const DerivedRenderApp*>(this);
235 }
236};
237
238} // namespace vcl::qt
239
240#endif // VCL_QT_WINDOW_MANAGER_H
A class representing a box in N-dimensional space.
Definition box.h:46
bool isNull() const
Checks whether the box is null or not.
Definition box.h:133
The Point class represents an N-dimensional point containing N scalar values.
Definition point.h:55
Definition window_manager.h:40
Definition render_app.h:31
Point2< float > Point2f
A convenience alias for a 2-dimensional Point with floating-point components.
Definition point.h:718