jGL
Loading...
Searching...
No Matches
desktopDisplay.h
Go to the documentation of this file.
1#ifndef DesktopDisplay_H
2#define DesktopDisplay_H
3
4#ifndef ANDROID
5
6#include <cstdlib>
7#include <vector>
8#include <map>
9
10#include <vulkan/vulkan.h>
11#define GLFW_INCLUDE_NONE
12#include <GLFW/glfw3.h>
13
14#include <jGL/Display/event.h>
15#include <jGL/Display/display.h>
16
17#include <jGL/common.h>
18#include <stb_image.h>
19#include <algorithm>
20
21#ifdef WINDOWS
22#include <windows.h>
23#include <mmsystem.h>
24#endif
25
26namespace jGL
27{
28
30 (
31 GLFWwindow * window,
32 int key,
33 int scancode,
34 int action,
35 int mods
36 );
37
39 (
40 GLFWwindow * window,
41 int button,
42 int action,
43 int mods
44 );
45
47 (
48 GLFWwindow * window,
49 double x,
50 double y
51 );
52
53 void parseAction
54 (
55 GLFWwindow * window,
56 int code,
57 int action
58 );
59
60 class DesktopDisplay : public Display
61 {
62 public:
63
64 struct Config
65 {
67 : VULKAN(false),
68 COCOA_RETINA(false),
69 CLIP_TO_MONITOR(true),
71 {}
72
74 (
75 bool vulkan,
76 bool cocoa,
77 bool clipMonitor,
78 bool clipWorkArea
79 )
80 : VULKAN(vulkan),
81 COCOA_RETINA(cocoa),
82 CLIP_TO_MONITOR(clipMonitor),
83 CLIP_TO_WORK_AREA(clipWorkArea)
84 {}
85
92
93 bool VULKAN;
95 // if screen size bigger than monitor clip
97 // if screen size too big to fit with taskbars, cip
99 };
100
102 (
103 glm::ivec2 res,
104 const char * title,
105 GLFWkeyfun keyCallback,
106 GLFWmousebuttonfun mouseButtonCallback,
107 GLFWscrollfun mouseScrollCallback,
108 const Config conf
109 );
110
112 (
113 glm::ivec2 res,
114 const char * title,
115 const Config conf
116 );
117
119 {
120 for (auto icon : logo)
121 {
122 stbi_image_free(icon.pixels);
123 }
124 logo.clear();
125
126 glfwTerminate();
127 #ifdef WINDOWS
128 timeEndPeriod(1);
129 #endif
130 }
131
132 GLFWwindow * getWindow() const { return glfwWindow; }
133
134 bool isOpen(){ if (glfwWindow != NULL) { return !glfwWindow ? false : true; } return false; }
135 bool closing(){ return glfwWindowShouldClose(glfwWindow); }
136
137 void open(){
138 #ifdef WINDOWS
139 timeBeginPeriod(1);
140 #endif
141 if (glfwWindow == NULL)
142 {
143 // required for MacOS
144 // https://www.glfw.org/faq.html#41__how_do_i_create_an_opengl_30_context
145 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
146 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
147 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, true);
148 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
149 glfwWindowHint(GLFW_COCOA_RETINA_FRAMEBUFFER, windowConfig.COCOA_RETINA);
150 glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
151
152 // get work area (i.e. without taskbars)
153 int wxpos, wypos, wwidth, wheight;
154 glfwGetMonitorWorkarea(glfwGetPrimaryMonitor(), &wxpos, &wypos, &wwidth, &wheight);
155
156 // hack to obtain decoration size
157 GLFWwindow * temporaryWindow = glfwCreateWindow(1, 1, "", NULL, NULL);
158 int fleft, ftop, fright, fbottom;
159 glfwGetWindowFrameSize(temporaryWindow, &fleft, &ftop, &fright, &fbottom);
160 glfwWindowShouldClose(temporaryWindow);
161 glfwDestroyWindow(temporaryWindow);
162
163 #ifdef WINDOWS
164 // windows pos includes decoration...
165 glm::ivec2 pos(wxpos, wypos+ftop);
166 #else
167 glm::ivec2 pos(wxpos, wypos);
168 #endif
169
170 if (windowConfig.CLIP_TO_MONITOR)
171 {
172 const GLFWvidmode * mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
173 resolution.x = std::min(resolution.x, mode->width);
174 resolution.y = std::min(resolution.y, mode->height);
175 }
176
177 if (windowConfig.CLIP_TO_WORK_AREA)
178 {
179 if (resolution.y+ftop > wheight)
180 {
181 resolution.y = wheight-ftop;
182 }
183
184 if (resolution.x > wwidth)
185 {
186 resolution.x = wwidth;
187 }
188 }
189
190 glfwWindow = glfwCreateWindow(getResX(), getResY(),title,NULL,NULL);
191 glfwSwapInterval(1);
193 }
194 }
195
196 void close(){ if (glfwWindow != NULL) { glfwDestroyWindow(glfwWindow); glfwWindow = NULL; } }
197
198 void setAsFocus(){ if (glfwWindow != NULL) { glfwMakeContextCurrent(glfwWindow); } }
199
201 (
202 GLFWwindow * window,
203 int key,
204 int scancode,
205 int action,
206 int mods
207 );
208
209 void mousePosition(double & x, double & y){ if (glfwWindow != NULL){ glfwGetCursorPos(glfwWindow,&x,&y); } }
210
211 void setMousePosition(double x, double y)
212 {
213 if (glfwWindow != NULL)
214 {
215 glfwSetCursorPos(glfwWindow, x, y);
216 }
217 }
218
219 int getKeyLastState(int key) { return glfwGetKey(glfwWindow, key); }
220
221 void loop()
222 {
223 data.clear();
224 handleEvents();
225 if (glfwWindowShouldClose(glfwWindow)){ close(); }
226 throttle();
227 swap();
228 }
229
230 std::vector<Event> getEvents(int code)
231 {
232 if (data.events.find(code) == data.events.cend())
233 {
234 return {Event()};
235 }
236 else
237 {
238 return data.events[code];
239 }
240 }
241
242 bool keyHasEvent(int key, EventType action)
243 {
244 if (data.events.find(key) == data.events.cend())
245 {
246 return false;
247 }
248 else
249 {
250 auto ts = getEventTypes(key);
251 return std::find(ts.cbegin(), ts.cend(), action) != ts.cend();
252 }
253 }
254
255 bool keyHasAnyEvents(int key, std::vector<EventType> actions)
256 {
257 if (data.events.find(key) == data.events.cend())
258 {
259 return false;
260 }
261 else
262 {
263 auto ts = getEventTypes(key);
264 for (const auto & action : actions)
265 {
266 if (std::find(ts.cbegin(), ts.cend(), action) != ts.cend())
267 {
268 return true;
269 }
270 }
271 }
272 return false;
273 }
274
275 std::vector<EventType> getEventTypes(int code)
276 {
277 std::vector<EventType> e;
278 if (data.events.find(code) == data.events.cend())
279 {
280 return {EventType::NONE};
281 }
282 else
283 {
284 for (auto evt : data.events[code])
285 {
286 e.push_back(evt.type);
287 }
288 return e;
289 }
290 }
291
292 Event getEvent(int code)
293 {
294 if (data.events.find(code) == data.events.cend())
295 {
296 return Event();
297 }
298 else
299 {
300 return data.events[code][0];
301 }
302 }
303
305 {
306 std::map<int, std::vector<Event>> events;
307 double scrollX = 0.0;
308 double scrollY = 0.0;
309 bool scrolled = false;
310
311 void clear()
312 {
313 scrollX = 0.0;
314 scrollY = 0.0;
315 scrolled = false;
316 events.clear();
317 }
318 };
319
320 void setIcon(const std::vector<std::vector<std::byte>> & icons)
321 {
322 glfwSetWindowIcon(glfwWindow, 0, NULL);
323 logo.clear();
324 for (auto icon : icons)
325 {
326 GLFWimage image;
327 unsigned char * chData = reinterpret_cast<unsigned char*>(icon.data());
328 image.pixels = stbi_load_from_memory
329 (
330 chData,
331 icon.size(),
332 &image.width,
333 &image.height,
334 0,
335 4
336 );
337 logo.push_back(image);
338 }
339
340 glfwSetWindowIcon(glfwWindow,logo.size(),logo.data());
341 }
342
343 glm::ivec2 frameBufferSize() const
344 {
345 glm::ivec2 s;
346 if (glfwWindow != NULL)
347 {
348 glfwGetFramebufferSize(glfwWindow, &s.x, &s.y);
349 }
350 return s;
351 }
352
353 glm::ivec2 windowSize() const
354 {
355 glm::ivec2 s;
356 if (glfwWindow != NULL)
357 {
358 glfwGetWindowSize(glfwWindow, &s.x, &s.y);
359 }
360 return s;
361 }
362
363 glm::vec2 contentScale() const
364 {
365 glm::vec2 s;
366 if (glfwWindow != NULL)
367 {
368 glfwGetWindowContentScale(glfwWindow, &s.x, &s.y);
369 }
370 return s;
371 }
372
373 glm::ivec4 windowFrameSize() const
374 {
375 glm::ivec4 s;
376 if (glfwWindow != NULL)
377 {
378 glfwGetWindowFrameSize(glfwWindow, &s.x, &s.y, &s.z, &s.w);
379 }
380 return s;
381 }
382
383 glm::ivec2 windowPosition() const
384 {
385 glm::ivec2 s;
386 if (glfwWindow != NULL)
387 {
388 glfwGetWindowPos(glfwWindow, &s.x, &s.y);
389 }
390 return s;
391 }
392
393 void setWindowPosition(glm::ivec2 s)
394 {
395 if (glfwWindow != NULL)
396 {
397 glfwSetWindowPos(glfwWindow, s.x, s.y);
398 }
399 }
400
401 private:
402
403 const char * title;
404
405 std::vector<GLFWimage> logo;
406
407 GLFWwindow * glfwWindow;
408
409 WindowData data;
410
411 Config windowConfig;
412
413 void swap(){ if (glfwWindow != NULL) { glfwSwapBuffers(glfwWindow); } }
414
415 void handleEvents(){ if (glfwWindow != NULL){ glfwPollEvents(); } }
416
417 };
418}
419
420#endif /* ANDROID */
421#endif /* DesktopDisplay_H */
Definition desktopDisplay.h:61
void setMousePosition(double x, double y)
Definition desktopDisplay.h:211
glm::ivec4 windowFrameSize() const
Definition desktopDisplay.h:373
void setWindowPosition(glm::ivec2 s)
Definition desktopDisplay.h:393
void loop()
Definition desktopDisplay.h:221
void keyCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
void setAsFocus()
Definition desktopDisplay.h:198
std::vector< Event > getEvents(int code)
Definition desktopDisplay.h:230
bool isOpen()
Definition desktopDisplay.h:134
std::vector< EventType > getEventTypes(int code)
Definition desktopDisplay.h:275
void mousePosition(double &x, double &y)
Definition desktopDisplay.h:209
~DesktopDisplay()
Definition desktopDisplay.h:118
glm::ivec2 windowSize() const
Definition desktopDisplay.h:353
void setIcon(const std::vector< std::vector< std::byte > > &icons)
Definition desktopDisplay.h:320
int getKeyLastState(int key)
Definition desktopDisplay.h:219
bool keyHasAnyEvents(int key, std::vector< EventType > actions)
Definition desktopDisplay.h:255
bool keyHasEvent(int key, EventType action)
Definition desktopDisplay.h:242
GLFWwindow * getWindow() const
Definition desktopDisplay.h:132
bool closing()
Definition desktopDisplay.h:135
Event getEvent(int code)
Definition desktopDisplay.h:292
glm::vec2 contentScale() const
Definition desktopDisplay.h:363
void open()
Definition desktopDisplay.h:137
void close()
Definition desktopDisplay.h:196
glm::ivec2 windowPosition() const
Definition desktopDisplay.h:383
glm::ivec2 frameBufferSize() const
Definition desktopDisplay.h:343
Definition display.h:12
unsigned getResY() const
Definition display.h:26
virtual void throttle()
Definition display.h:49
glm::ivec2 resolution
Definition display.h:43
unsigned getResX() const
Definition display.h:25
A drawable graphic.
Definition id.h:10
void defaultScrollCallback(GLFWwindow *window, double x, double y)
Definition desktopDisplay.cpp:61
EventType
Definition event.h:9
void parseAction(GLFWwindow *window, int code, int action)
Definition desktopDisplay.cpp:8
void defaultMouseButtonCallback(GLFWwindow *window, int button, int action, int mods)
Definition desktopDisplay.cpp:50
void defaultKeyEventCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
Definition desktopDisplay.cpp:32
Definition desktopDisplay.h:65
bool CLIP_TO_WORK_AREA
Definition desktopDisplay.h:98
bool VULKAN
Definition desktopDisplay.h:93
bool CLIP_TO_MONITOR
Definition desktopDisplay.h:96
bool COCOA_RETINA
Definition desktopDisplay.h:94
Config(const Config &c)
Definition desktopDisplay.h:86
Config(bool vulkan, bool cocoa, bool clipMonitor, bool clipWorkArea)
Definition desktopDisplay.h:74
Config()
Definition desktopDisplay.h:66
Definition desktopDisplay.h:305
double scrollY
Definition desktopDisplay.h:308
void clear()
Definition desktopDisplay.h:311
std::map< int, std::vector< Event > > events
Definition desktopDisplay.h:306
double scrollX
Definition desktopDisplay.h:307
bool scrolled
Definition desktopDisplay.h:309
Definition event.h:14