Unravel Engine C++ Reference
Loading...
Searching...
No Matches
imgui_impl_ospp.cpp
Go to the documentation of this file.
1#include "imgui_impl_ospp.h"
2#include "imgui/imgui_internal.h"
4#include <imgui_widgets/utils.h>
5#include <ospp/clipboard.h>
6#include <ospp/display_mode.h>
7#include <ospp/hints.h>
9#include <utility>
10
11#if defined(_WIN32)
12#if !defined(_WINDOWS_)
13#define WIN32_LEAN_AND_MEAN
14#include <windows.h>
15#endif
16#include <shellapi.h> // ShellExecuteA()
17#include <stdio.h>
18#else
19#include <errno.h>
20#include <unistd.h>
21#endif
22#ifndef _MSC_VER
23#include <sys/stat.h> // stat()
24#include <sys/types.h>
25#endif
26#ifdef __APPLE__
27#include <sys/sysctl.h>
28#endif
29
30// Clang warnings with -Weverything
31#if defined(__clang__)
32#pragma clang diagnostic push
33#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx'
34 // to 'float' may lose precision
35#endif
36
37#if !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) && \
38 !defined(__amigaos4__)
39#define OSPP_HAS_CAPTURE_AND_GLOBAL_MOUSE 1
40#else
41#define OSPP_HAS_CAPTURE_AND_GLOBAL_MOUSE 0
42#endif
43
44// OSPP Data
46{
48 uint32_t MouseWindowID{};
50 ImGuiMouseCursor LastMouseCursor{ImGuiMouseCursor_COUNT};
52 std::string ClipboardTextData{};
54 bool MouseCanReportHoveredViewport{}; // This is hard to use/unreliable on OSPP so we'll set
55 // ImGuiBackendFlags_HasMouseHoveredViewport dynamically based on
56 // state.
59
62};
63
65{
66#ifdef _WIN32
67 return ::IsDebuggerPresent() != 0;
68#elif defined(__linux__)
69 int debugger_pid = 0;
70 char buf[2048]; // TracerPid is located near the start of the file. If end of the buffer gets cut off thats fine.
71 FILE* fp = fopen("/proc/self/status",
72 "rb"); // Can not use ImFileLoadToMemory because size detection of /proc/self/status would fail.
73 if(fp == NULL)
74 return false;
75 fread(buf, 1, IM_ARRAYSIZE(buf), fp);
76 fclose(fp);
77 buf[IM_ARRAYSIZE(buf) - 1] = 0;
78 if(char* tracer_pid = strstr(buf, "TracerPid:"))
79 {
80 tracer_pid += 10; // Skip label
81 while(isspace(*tracer_pid))
82 tracer_pid++;
83 debugger_pid = atoi(tracer_pid);
84 }
85 return debugger_pid != 0;
86#elif defined(__APPLE__)
87 // https://stackoverflow.com/questions/2200277/detecting-debugger-on-mac-os-x
88 int junk;
89 int mib[4];
90 struct kinfo_proc info;
91 size_t size;
92
93 // Initialize mib, which tells sysctl the info we want, in this case
94 // we're looking for information about a specific process ID.
95 info.kp_proc.p_flag = 0;
96 mib[0] = CTL_KERN;
97 mib[1] = KERN_PROC;
98 mib[2] = KERN_PROC_PID;
99 mib[3] = getpid();
100
101 size = sizeof(info);
102 junk = sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0);
103 IM_ASSERT(junk == 0);
104
105 // We're being debugged if the P_TRACED flag is set.
106 return (info.kp_proc.p_flag & P_TRACED) != 0;
107#else
108 // FIXME
109 return false;
110#endif
111}
112
113static bool ImOsOpenInShell(ImGuiContext* ctx, const char* path)
114{
115 fs::path p(path);
116 fs::show_in_graphical_env(p);
117 return true;
118}
119
120// Helper structure we store in the void* RendererUserData field of each ImGuiViewport to easily retrieve our
121// backend data.
123{
128
130 {
131 Window = nullptr;
132 WindowOwned = false;
134 WindowOpacity = 1.0f;
135 }
137 {
138 IM_ASSERT(Window == nullptr);
139 }
140};
141
142static auto ImGui_ImplOSPP_GetViewportData(ImGuiViewport* viewport) -> ImGui_ImplOSPP_ViewportData*
143{
144 if(viewport && viewport->PlatformUserData)
145 {
146 auto data = (ImGui_ImplOSPP_ViewportData*)viewport->PlatformUserData;
147 return data;
148 }
149
150 return nullptr;
151}
152
154 const std::function<void(ImGuiViewport* viewport, ImGui_ImplOSPP_ViewportData* data)>& callback)
155{
156 ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
157
158 for(int i = 0; i != platform_io.Viewports.Size; i++)
159 {
160 auto data = ImGui_ImplOSPP_GetViewportData(platform_io.Viewports[i]);
161 if(data)
162 {
163 callback(platform_io.Viewports[i], data);
164 }
165 }
166}
167
168static auto ImGui_ImplOSPP_GetViewportFromWindowId(uint32_t id) -> ImGuiViewport*
169{
170 ImGuiViewport* result{nullptr};
172 [&](ImGuiViewport* viewport, ImGui_ImplOSPP_ViewportData* data)
173 {
174 if(!result)
175 {
176 if(data->Window && data->Window->get_window().get_id() == id)
177 {
178 result = viewport;
179 }
180 }
181 });
182
183 return result;
184}
185
186static auto ImGui_ImplOSPP_GetFocusedViewport() -> ImGuiViewport*
187{
188 ImGuiViewport* result{nullptr};
190 [&](ImGuiViewport* viewport, ImGui_ImplOSPP_ViewportData* data)
191 {
192 if(!result && data->Window->get_window().has_focus())
193 {
194 result = viewport;
195 }
196 });
197
198 return result;
199}
200
201// Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts
202// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context +
203// multiple windows) instead of multiple Dear ImGui contexts.
204// FIXME: multi-context support is not well tested and probably dysfunctional in this backend.
205// FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context.
207{
208 return ImGui::GetCurrentContext() ? (ImGui_ImplOSPP_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr;
209}
210
211auto ImGui_ImplOSPP_IdToHandle(uint32_t id) -> void*
212{
213 return reinterpret_cast<void*>(uintptr_t(id));
214}
215
216auto ImGui_ImplOSPP_MapCursor(ImGuiMouseCursor cursor) -> os::cursor::type
217{
218 static const std::map<ImGuiMouseCursor, os::cursor::type> cursor_map = {
219 {ImGuiMouseCursor_Arrow, os::cursor::type::arrow},
220 {ImGuiMouseCursor_TextInput, os::cursor::type::ibeam},
221 {ImGuiMouseCursor_ResizeNS, os::cursor::type::size_ns},
222 {ImGuiMouseCursor_ResizeEW, os::cursor::type::size_we},
223 {ImGuiMouseCursor_ResizeNESW, os::cursor::type::size_nesw},
224 {ImGuiMouseCursor_ResizeNWSE, os::cursor::type::size_nwse},
225 {ImGuiMouseCursor_ResizeAll, os::cursor::type::size_all},
226 {ImGuiMouseCursor_Hand, os::cursor::type::hand},
227 {ImGuiMouseCursor_Wait, os::cursor::type::wait},
228 {ImGuiMouseCursor_Progress, os::cursor::type::arrow_wait},
229 {ImGuiMouseCursor_Help, os::cursor::type::hand},
230 {ImGuiMouseCursor_Cross, os::cursor::type::crosshair},
231 {ImGuiMouseCursor_NotAllowed, os::cursor::type::not_allowed}};
232 auto it = cursor_map.find(cursor);
233 if(it != cursor_map.end())
234 {
235 return it->second;
236 }
237 return os::cursor::type::arrow;
238}
239
240// Forward Declarations
244
245// Functions
246static auto ImGui_ImplOSPP_GetClipboardText(ImGuiContext* ctx) -> const char*
247{
249
250 bd->ClipboardTextData = os::clipboard::get_text();
251 return bd->ClipboardTextData.c_str();
252}
253
254static void ImGui_ImplOSPP_SetClipboardText(ImGuiContext* ctx, const char* text)
255{
256 auto unwrapped_text = string_utils::replace(text, "\n\r", "");
257 os::clipboard::set_text(unwrapped_text);
258}
259
260static void ImGui_ImplOSPP_SetPlatformImeData(ImGuiContext* ctx, ImGuiViewport* viewport, ImGuiPlatformImeData* data)
261{
262 if(data->WantVisible)
263 {
264 // OSPP_Rect r;
265 // r.x = (int)(data->InputPos.x - viewport->Pos.x);
266 // r.y = (int)(data->InputPos.y - viewport->Pos.y + data->InputLineHeight);
267 // r.w = 1;
268 // r.h = (int)data->InputLineHeight;
269 // OSPP_SetTextInputRect(&r);
270 }
271}
272
273auto ImGui_ImplOSPP_KeycodeToImGuiKey(os::key::code keycode) -> ImGuiKey
274{
275 switch(keycode)
276 {
277 case os::key::code::tab:
278 return ImGuiKey_Tab;
279 case os::key::code::left:
280 return ImGuiKey_LeftArrow;
281 case os::key::code::right:
282 return ImGuiKey_RightArrow;
283 case os::key::code::up:
284 return ImGuiKey_UpArrow;
285 case os::key::code::down:
286 return ImGuiKey_DownArrow;
287 case os::key::code::pageup:
288 return ImGuiKey_PageUp;
289 case os::key::code::pagedown:
290 return ImGuiKey_PageDown;
291 case os::key::code::home:
292 return ImGuiKey_Home;
293 case os::key::code::end:
294 return ImGuiKey_End;
295 case os::key::code::insert:
296 return ImGuiKey_Insert;
297 case os::key::code::del:
298 return ImGuiKey_Delete;
299 case os::key::code::backspace:
300 return ImGuiKey_Backspace;
301 case os::key::code::space:
302 return ImGuiKey_Space;
303 case os::key::code::enter:
304 return ImGuiKey_Enter;
305 case os::key::code::escape:
306 return ImGuiKey_Escape;
307 case os::key::code::apostrophe:
308 return ImGuiKey_Apostrophe;
309 case os::key::code::comma:
310 return ImGuiKey_Comma;
311 case os::key::code::minus:
312 return ImGuiKey_Minus;
313 case os::key::code::period:
314 return ImGuiKey_Period;
315 case os::key::code::slash:
316 return ImGuiKey_Slash;
317 case os::key::code::semicolon:
318 return ImGuiKey_Semicolon;
319 case os::key::code::equals:
320 return ImGuiKey_Equal;
321 case os::key::code::leftbracket:
322 return ImGuiKey_LeftBracket;
323 case os::key::code::backslash:
324 return ImGuiKey_Backslash;
325 case os::key::code::rightbracket:
326 return ImGuiKey_RightBracket;
327 // case os::key::code::BACKQUOTE: return ImGuiKey_GraveAccent;
328 case os::key::code::capslock:
329 return ImGuiKey_CapsLock;
330 case os::key::code::scrolllock:
331 return ImGuiKey_ScrollLock;
332 case os::key::code::numlockclear:
333 return ImGuiKey_NumLock;
334 case os::key::code::printscreen:
335 return ImGuiKey_PrintScreen;
336 case os::key::code::pause:
337 return ImGuiKey_Pause;
338 case os::key::code::kp_digit0:
339 return ImGuiKey_Keypad0;
340 case os::key::code::kp_digit1:
341 return ImGuiKey_Keypad1;
342 case os::key::code::kp_digit2:
343 return ImGuiKey_Keypad2;
344 case os::key::code::kp_digit3:
345 return ImGuiKey_Keypad3;
346 case os::key::code::kp_digit4:
347 return ImGuiKey_Keypad4;
348 case os::key::code::kp_digit5:
349 return ImGuiKey_Keypad5;
350 case os::key::code::kp_digit6:
351 return ImGuiKey_Keypad6;
352 case os::key::code::kp_digit7:
353 return ImGuiKey_Keypad7;
354 case os::key::code::kp_digit8:
355 return ImGuiKey_Keypad8;
356 case os::key::code::kp_digit9:
357 return ImGuiKey_Keypad9;
358 case os::key::code::kp_period:
359 return ImGuiKey_KeypadDecimal;
360 case os::key::code::kp_divide:
361 return ImGuiKey_KeypadDivide;
362 case os::key::code::kp_multiply:
363 return ImGuiKey_KeypadMultiply;
364 case os::key::code::kp_minus:
365 return ImGuiKey_KeypadSubtract;
366 case os::key::code::kp_plus:
367 return ImGuiKey_KeypadAdd;
368 case os::key::code::kp_enter:
369 return ImGuiKey_KeypadEnter;
370 case os::key::code::kp_equals:
371 return ImGuiKey_KeypadEqual;
372 case os::key::code::lctrl:
373 return ImGuiKey_LeftCtrl;
374 case os::key::code::lshift:
375 return ImGuiKey_LeftShift;
376 case os::key::code::lalt:
377 return ImGuiKey_LeftAlt;
378 case os::key::code::lgui:
379 return ImGuiKey_LeftSuper;
380 case os::key::code::rctrl:
381 return ImGuiKey_RightCtrl;
382 case os::key::code::rshift:
383 return ImGuiKey_RightShift;
384 case os::key::code::ralt:
385 return ImGuiKey_RightAlt;
386 case os::key::code::rgui:
387 return ImGuiKey_RightSuper;
388 case os::key::code::application:
389 return ImGuiKey_Menu;
390 case os::key::code::digit0:
391 return ImGuiKey_0;
392 case os::key::code::digit1:
393 return ImGuiKey_1;
394 case os::key::code::digit2:
395 return ImGuiKey_2;
396 case os::key::code::digit3:
397 return ImGuiKey_3;
398 case os::key::code::digit4:
399 return ImGuiKey_4;
400 case os::key::code::digit5:
401 return ImGuiKey_5;
402 case os::key::code::digit6:
403 return ImGuiKey_6;
404 case os::key::code::digit7:
405 return ImGuiKey_7;
406 case os::key::code::digit8:
407 return ImGuiKey_8;
408 case os::key::code::digit9:
409 return ImGuiKey_9;
410 case os::key::code::a:
411 return ImGuiKey_A;
412 case os::key::code::b:
413 return ImGuiKey_B;
414 case os::key::code::c:
415 return ImGuiKey_C;
416 case os::key::code::d:
417 return ImGuiKey_D;
418 case os::key::code::e:
419 return ImGuiKey_E;
420 case os::key::code::f:
421 return ImGuiKey_F;
422 case os::key::code::g:
423 return ImGuiKey_G;
424 case os::key::code::h:
425 return ImGuiKey_H;
426 case os::key::code::i:
427 return ImGuiKey_I;
428 case os::key::code::j:
429 return ImGuiKey_J;
430 case os::key::code::k:
431 return ImGuiKey_K;
432 case os::key::code::l:
433 return ImGuiKey_L;
434 case os::key::code::m:
435 return ImGuiKey_M;
436 case os::key::code::n:
437 return ImGuiKey_N;
438 case os::key::code::o:
439 return ImGuiKey_O;
440 case os::key::code::p:
441 return ImGuiKey_P;
442 case os::key::code::q:
443 return ImGuiKey_Q;
444 case os::key::code::r:
445 return ImGuiKey_R;
446 case os::key::code::s:
447 return ImGuiKey_S;
448 case os::key::code::t:
449 return ImGuiKey_T;
450 case os::key::code::u:
451 return ImGuiKey_U;
452 case os::key::code::v:
453 return ImGuiKey_V;
454 case os::key::code::w:
455 return ImGuiKey_W;
456 case os::key::code::x:
457 return ImGuiKey_X;
458 case os::key::code::y:
459 return ImGuiKey_Y;
460 case os::key::code::z:
461 return ImGuiKey_Z;
462 case os::key::code::f1:
463 return ImGuiKey_F1;
464 case os::key::code::f2:
465 return ImGuiKey_F2;
466 case os::key::code::f3:
467 return ImGuiKey_F3;
468 case os::key::code::f4:
469 return ImGuiKey_F4;
470 case os::key::code::f5:
471 return ImGuiKey_F5;
472 case os::key::code::f6:
473 return ImGuiKey_F6;
474 case os::key::code::f7:
475 return ImGuiKey_F7;
476 case os::key::code::f8:
477 return ImGuiKey_F8;
478 case os::key::code::f9:
479 return ImGuiKey_F9;
480 case os::key::code::f10:
481 return ImGuiKey_F10;
482 case os::key::code::f11:
483 return ImGuiKey_F11;
484 case os::key::code::f12:
485 return ImGuiKey_F12;
486 default:
487 return ImGuiKey_None;
488 }
489}
490
491auto ImGui_ImplOSPP_ImGuiKeyToKeycode(ImGuiKey key) -> os::key::code
492{
493 switch(key)
494 {
495 case ImGuiKey_Tab:
496 return os::key::code::tab;
497 case ImGuiKey_LeftArrow:
498 return os::key::code::left;
499 case ImGuiKey_RightArrow:
500 return os::key::code::right;
501 case ImGuiKey_UpArrow:
502 return os::key::code::up;
503 case ImGuiKey_DownArrow:
504 return os::key::code::down;
505 case ImGuiKey_PageUp:
506 return os::key::code::pageup;
507 case ImGuiKey_PageDown:
508 return os::key::code::pagedown;
509 case ImGuiKey_Home:
510 return os::key::code::home;
511 case ImGuiKey_End:
512 return os::key::code::end;
513 case ImGuiKey_Insert:
514 return os::key::code::insert;
515 case ImGuiKey_Delete:
516 return os::key::code::del;
517 case ImGuiKey_Backspace:
518 return os::key::code::backspace;
519 case ImGuiKey_Space:
520 return os::key::code::space;
521 case ImGuiKey_Enter:
522 return os::key::code::enter;
523 case ImGuiKey_Escape:
524 return os::key::code::escape;
525 case ImGuiKey_Apostrophe:
526 return os::key::code::apostrophe;
527 case ImGuiKey_Comma:
528 return os::key::code::comma;
529 case ImGuiKey_Minus:
530 return os::key::code::minus;
531 case ImGuiKey_Period:
532 return os::key::code::period;
533 case ImGuiKey_Slash:
534 return os::key::code::slash;
535 case ImGuiKey_Semicolon:
536 return os::key::code::semicolon;
537 case ImGuiKey_Equal:
538 return os::key::code::equals;
539 case ImGuiKey_LeftBracket:
540 return os::key::code::leftbracket;
541 case ImGuiKey_Backslash:
542 return os::key::code::backslash;
543 case ImGuiKey_RightBracket:
544 return os::key::code::rightbracket;
545 case ImGuiKey_CapsLock:
546 return os::key::code::capslock;
547 case ImGuiKey_ScrollLock:
548 return os::key::code::scrolllock;
549 case ImGuiKey_NumLock:
550 return os::key::code::numlockclear;
551 case ImGuiKey_PrintScreen:
552 return os::key::code::printscreen;
553 case ImGuiKey_Pause:
554 return os::key::code::pause;
555 case ImGuiKey_Keypad0:
556 return os::key::code::kp_digit0;
557 case ImGuiKey_Keypad1:
558 return os::key::code::kp_digit1;
559 case ImGuiKey_Keypad2:
560 return os::key::code::kp_digit2;
561 case ImGuiKey_Keypad3:
562 return os::key::code::kp_digit3;
563 case ImGuiKey_Keypad4:
564 return os::key::code::kp_digit4;
565 case ImGuiKey_Keypad5:
566 return os::key::code::kp_digit5;
567 case ImGuiKey_Keypad6:
568 return os::key::code::kp_digit6;
569 case ImGuiKey_Keypad7:
570 return os::key::code::kp_digit7;
571 case ImGuiKey_Keypad8:
572 return os::key::code::kp_digit8;
573 case ImGuiKey_Keypad9:
574 return os::key::code::kp_digit9;
575 case ImGuiKey_KeypadDecimal:
576 return os::key::code::kp_period;
577 case ImGuiKey_KeypadDivide:
578 return os::key::code::kp_divide;
579 case ImGuiKey_KeypadMultiply:
580 return os::key::code::kp_multiply;
581 case ImGuiKey_KeypadSubtract:
582 return os::key::code::kp_minus;
583 case ImGuiKey_KeypadAdd:
584 return os::key::code::kp_plus;
585 case ImGuiKey_KeypadEnter:
586 return os::key::code::kp_enter;
587 case ImGuiKey_KeypadEqual:
588 return os::key::code::kp_equals;
589 case ImGuiKey_LeftCtrl:
590 return os::key::code::lctrl;
591 case ImGuiKey_LeftShift:
592 return os::key::code::lshift;
593 case ImGuiKey_LeftAlt:
594 return os::key::code::lalt;
595 case ImGuiKey_LeftSuper:
596 return os::key::code::lgui;
597 case ImGuiKey_RightCtrl:
598 return os::key::code::rctrl;
599 case ImGuiKey_RightShift:
600 return os::key::code::rshift;
601 case ImGuiKey_RightAlt:
602 return os::key::code::ralt;
603 case ImGuiKey_RightSuper:
604 return os::key::code::rgui;
605 case ImGuiKey_Menu:
606 return os::key::code::application;
607 case ImGuiKey_0:
608 return os::key::code::digit0;
609 case ImGuiKey_1:
610 return os::key::code::digit1;
611 case ImGuiKey_2:
612 return os::key::code::digit2;
613 case ImGuiKey_3:
614 return os::key::code::digit3;
615 case ImGuiKey_4:
616 return os::key::code::digit4;
617 case ImGuiKey_5:
618 return os::key::code::digit5;
619 case ImGuiKey_6:
620 return os::key::code::digit6;
621 case ImGuiKey_7:
622 return os::key::code::digit7;
623 case ImGuiKey_8:
624 return os::key::code::digit8;
625 case ImGuiKey_9:
626 return os::key::code::digit9;
627 case ImGuiKey_A:
628 return os::key::code::a;
629 case ImGuiKey_B:
630 return os::key::code::b;
631 case ImGuiKey_C:
632 return os::key::code::c;
633 case ImGuiKey_D:
634 return os::key::code::d;
635 case ImGuiKey_E:
636 return os::key::code::e;
637 case ImGuiKey_F:
638 return os::key::code::f;
639 case ImGuiKey_G:
640 return os::key::code::g;
641 case ImGuiKey_H:
642 return os::key::code::h;
643 case ImGuiKey_I:
644 return os::key::code::i;
645 case ImGuiKey_J:
646 return os::key::code::j;
647 case ImGuiKey_K:
648 return os::key::code::k;
649 case ImGuiKey_L:
650 return os::key::code::l;
651 case ImGuiKey_M:
652 return os::key::code::m;
653 case ImGuiKey_N:
654 return os::key::code::n;
655 case ImGuiKey_O:
656 return os::key::code::o;
657 case ImGuiKey_P:
658 return os::key::code::p;
659 case ImGuiKey_Q:
660 return os::key::code::q;
661 case ImGuiKey_R:
662 return os::key::code::r;
663 case ImGuiKey_S:
664 return os::key::code::s;
665 case ImGuiKey_T:
666 return os::key::code::t;
667 case ImGuiKey_U:
668 return os::key::code::u;
669 case ImGuiKey_V:
670 return os::key::code::v;
671 case ImGuiKey_W:
672 return os::key::code::w;
673 case ImGuiKey_X:
674 return os::key::code::x;
675 case ImGuiKey_Y:
676 return os::key::code::y;
677 case ImGuiKey_Z:
678 return os::key::code::z;
679 case ImGuiKey_F1:
680 return os::key::code::f1;
681 case ImGuiKey_F2:
682 return os::key::code::f2;
683 case ImGuiKey_F3:
684 return os::key::code::f3;
685 case ImGuiKey_F4:
686 return os::key::code::f4;
687 case ImGuiKey_F5:
688 return os::key::code::f5;
689 case ImGuiKey_F6:
690 return os::key::code::f6;
691 case ImGuiKey_F7:
692 return os::key::code::f7;
693 case ImGuiKey_F8:
694 return os::key::code::f8;
695 case ImGuiKey_F9:
696 return os::key::code::f9;
697 case ImGuiKey_F10:
698 return os::key::code::f10;
699 case ImGuiKey_F11:
700 return os::key::code::f11;
701 case ImGuiKey_F12:
702 return os::key::code::f12;
703 default:
704 return os::key::code::unknown;
705 }
706}
707
708static void ImGui_ImplOSPP_UpdateKeyModifiers(os::key_event e)
709{
710 ImGuiIO& io = ImGui::GetIO();
711 io.AddKeyEvent(ImGuiMod_Ctrl, e.ctrl);
712 io.AddKeyEvent(ImGuiMod_Shift, e.shift);
713 io.AddKeyEvent(ImGuiMod_Alt, e.alt);
714 io.AddKeyEvent(ImGuiMod_Super, e.system);
715}
716
718{
719 if(ImGui::IsAnyItemActive())
720 {
721 bool is_window_move = false;
722 for(auto window : ImGui::GetCurrentContext()->Windows)
723 {
724 if(window->MoveId == ImGui::GetActiveID())
725 {
726 is_window_move = true;
727 }
728 }
729
730 if(!is_window_move)
731 {
732 return true;
733 }
734 }
735 return false;
736}
737
738// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your
739// inputs.
740// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or
741// clear/overwrite your copy of the mouse data.
742// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or
743// clear/overwrite your copy of the keyboard data. Generally you may always pass all inputs to dear imgui, and
744// hide them from your application based on those two flags. If you have multiple OSPP events and some of them
745// are not meant to be used by dear imgui, you may need to filter events based on their windowID field.
746auto ImGui_ImplOSPP_ProcessEvent(os::event& event) -> bool
747{
748 ImGuiIO& io = ImGui::GetIO();
750
751 switch(event.type)
752 {
753 case os::events::mouse_motion:
754 {
755 os::point mouse_pos(event.motion.x, event.motion.y);
756 if(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
757 {
758 auto viewport = ImGui_ImplOSPP_GetViewportFromWindowId(event.motion.window_id);
759 auto vd = ImGui_ImplOSPP_GetViewportData(viewport);
760 if(vd)
761 {
762 auto window_pos = vd->Window->get_window().get_position();
763 mouse_pos.x += window_pos.x;
764 mouse_pos.y += window_pos.y;
765 }
766 }
767 io.AddMouseSourceEvent(ImGuiMouseSource_Mouse);
768 io.AddMousePosEvent(float(mouse_pos.x), float(mouse_pos.y));
769
770 return true;
771 }
772 case os::events::mouse_wheel:
773 {
774 // IMGUI_DEBUG_LOG("wheel %.2f %.2f, precise %.2f %.2f\n", (float)event->wheel.x,
775 // (float)event->wheel.y, event->wheel.preciseX, event->wheel.preciseY);
776 float wheel_x = -float(event.wheel.x);
777 float wheel_y = float(event.wheel.y);
778#ifdef __EMSCRIPTEN__
779 wheel_x /= 100.0f;
780#endif
781 io.AddMouseSourceEvent(ImGuiMouseSource_Mouse);
782 io.AddMouseWheelEvent(wheel_x, wheel_y);
783 return true;
784 }
785 case os::events::mouse_button:
786 {
787 int mouse_button = int(uint8_t(event.button.button)) - 1;
788 if(mouse_button == -1)
789 break;
790
791 bool pressed = event.button.state_id == os::state::pressed;
792 io.AddMouseSourceEvent(ImGuiMouseSource_Mouse);
793 io.AddMouseButtonEvent(mouse_button, pressed);
794 bd->MouseButtonsDown =
795 pressed ? (bd->MouseButtonsDown | (1 << mouse_button)) : (bd->MouseButtonsDown & ~(1 << mouse_button));
796 return true;
797 }
798 case os::events::text_input:
799 {
800 io.AddInputCharactersUTF8(event.text.text.c_str());
802 {
803 event = {};
804 }
805 return true;
806 }
807 case os::events::key_up:
808 case os::events::key_down:
809 {
811 ImGuiKey key = ImGui_ImplOSPP_KeycodeToImGuiKey(event.key.code);
812 io.AddKeyEvent(key, (event.type == os::events::key_down));
813 io.SetKeyEventNativeData(key, event.key.code, event.key.code, event.key.code);
814
816 {
817 event = {};
818 }
819 return true;
820 }
821 case os::events::window:
822 {
823 switch(event.window.type)
824 {
825 case os::window_event_id::focus_gained:
826 {
827 io.AddFocusEvent(true);
828 return true;
829 }
830 case os::window_event_id::focus_lost:
831 {
832 io.AddFocusEvent(false);
833 return true;
834 }
835 case os::window_event_id::enter:
836 {
837 bd->MouseWindowID = event.window.window_id;
839
840 return true;
841 }
842
843 case os::window_event_id::leave:
844 {
845 if(bd->MouseWindowID == event.window.window_id)
846 {
847 bd->PendingMouseLeaveFrame = ImGui::GetFrameCount() + 1;
848 }
849 return true;
850 }
851
852 case os::window_event_id::close:
853 case os::window_event_id::moved:
854 case os::window_event_id::resized:
855 if(ImGuiViewport* viewport = ImGui_ImplOSPP_GetViewportFromWindowId(event.window.window_id))
856 {
857 if(event.window.type == os::window_event_id::close)
858 viewport->PlatformRequestClose = true;
859 if(event.window.type == os::window_event_id::moved)
860 viewport->PlatformRequestMove = true;
861 if(event.window.type == os::window_event_id::resized)
862 viewport->PlatformRequestResize = true;
863 return true;
864 }
865 return true;
866 default:
867 break;
868 }
869 return true;
870 }
871 case os::events::display_orientation:
872 case os::events::display_connected:
873 case os::events::display_disconnected:
874 case os::events::display_moved:
875 case os::events::display_content_scale_changed:
876 {
877 bd->WantUpdateMonitors = true;
878 return true;
879 }
880
881 default:
882 break;
883 }
884
885 return false;
886}
887
890 ImGui_ImplOSPP_SwapBuffers_Callback swap_callback) -> bool
891{
892 ImGuiIO& io = ImGui::GetIO();
893 IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
894
895 // Check and store if we are on a OSPP backend that supports global mouse position
896 // ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list)
897 bool mouse_can_use_global_state = false;
898#if OSPP_HAS_CAPTURE_AND_GLOBAL_MOUSE
899 // const char* OSPP_backend = OSPP_GetCurrentVideoDriver();
900 // const char* global_mouse_whitelist[] = { "windows", "cocoa", "x11", "DIVE", "VMAN" };
901 // for (int n = 0; n < IM_ARRAYSIZE(global_mouse_whitelist); n++)
902 // if (strncmp(OSPP_backend, global_mouse_whitelist[n], strlen(global_mouse_whitelist[n])) == 0)
903 mouse_can_use_global_state = true;
904#endif
905
906 // Setup backend capabilities flags
908 io.BackendPlatformUserData = bd;
909 io.BackendPlatformName = "imgui_impl_ospp";
910
911 // We can honor GetMouseCursor() values (optional)
912 io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors;
913
914
915
916 // We can honor io.WantSetMousePos requests (optional, rarely used)
917 io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos;
918 io.ConfigDebugHighlightIdConflicts = true;
919 // We can create multi-viewports on the
920 // Platform side (optional)
921 if(mouse_can_use_global_state)
922 io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports;
923
924 bd->RenderCallback = std::move(render_callback);
925 bd->SwapCallback = std::move(swap_callback);
926 bd->Window = window;
927
928 // OSPP on Linux/OSX doesn't report events for unfocused windows (see
929 // https://github.com/ocornut/imgui/issues/4960) We will use 'MouseCanReportHoveredViewport' to set
930 // 'ImGuiBackendFlags_HasMouseHoveredViewport' dynamically each frame.
931 bd->MouseCanUseGlobalState = mouse_can_use_global_state;
932#ifndef __APPLE__
934#else
936#endif
937 bd->WantUpdateMonitors = true;
938
939 ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
940 platform_io.Platform_SetClipboardTextFn = ImGui_ImplOSPP_SetClipboardText;
941 platform_io.Platform_GetClipboardTextFn = ImGui_ImplOSPP_GetClipboardText;
942 platform_io.Platform_OpenInShellFn = ImOsOpenInShell;
943 platform_io.Platform_ClipboardUserData = nullptr;
944 platform_io.Platform_SetImeDataFn = ImGui_ImplOSPP_SetPlatformImeData;
945
946
947 // Set platform dependent data in viewport
948 // Our mouse update function expect PlatformHandle to be filled for the main viewport
949 ImGuiViewport* main_viewport = ImGui::GetMainViewport();
950
951 main_viewport->PlatformHandle = ImGui_ImplOSPP_IdToHandle(window->get_window().get_id());
952 main_viewport->PlatformHandleRaw = window->get_window().get_native_handle();
953
954 // From 2.0.5: Set SDL hint to receive mouse click events on window focus, otherwise SDL doesn't emit the
955 // event. Without this, when clicking to gain focus, our widgets wouldn't activate even though they showed
956 // as hovered. (This is unfortunately a global SDL setting, so enabling it might have a side-effect on
957 // your application. It is unlikely to make a difference, but if your app absolutely needs to ignore the
958 // initial on-focus click: you can ignore OSPP_EVENT_MOUSE_BUTTON_DOWN events coming right after a
959 // OSPP_WINDOWEVENT_FOCUS_GAINED)
960 os::set_hint("HINT_MOUSE_FOCUS_CLICKTHROUGH", "1");
961
962 // From 2.0.22: Disable auto-capture, this is preventing drag and drop across multiple windows (see #5710)
963 os::set_hint("HINT_MOUSE_AUTO_CAPTURE", "0");
964
965 // SDL 3.x : see https://github.com/libSDL-org/SDL/issues/6659
966 os::set_hint("HINT_BORDERLESS_WINDOWED_STYLE", "0");
967
968 if((io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) &&
969 (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports))
971
972 return true;
973}
974
976{
978 IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
979 ImGuiIO& io = ImGui::GetIO();
980
982
983 io.BackendPlatformName = nullptr;
984 io.BackendPlatformUserData = nullptr;
985 io.BackendFlags &=
986 ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad |
987 ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport);
988 IM_DELETE(bd);
989}
990
991// This code is incredibly messy because some of the functions we need for full viewport support are not
992// available in OSPP < 2.0.4.
994{
996 ImGuiIO& io = ImGui::GetIO();
997
998 if(bd->PendingMouseLeaveFrame && bd->PendingMouseLeaveFrame >= ImGui::GetFrameCount() && bd->MouseButtonsDown == 0)
999 {
1000 bd->MouseWindowID = 0;
1001 bd->PendingMouseLeaveFrame = 0;
1002 io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
1003 }
1004
1005 // Our io.AddMouseViewportEvent() calls will only be valid when not capturing.
1006 // Technically speaking testing for 'bd->MouseButtonsDown == 0' would be more rygorous, but testing for
1007 // payload reduces noise and potential side-effects.
1008 if(bd->MouseCanReportHoveredViewport && ImGui::GetDragDropPayload() == nullptr)
1009 io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport;
1010 else
1011 io.BackendFlags &= ~ImGuiBackendFlags_HasMouseHoveredViewport;
1012
1013 // We forward mouse input when hovered or captured (via OSPP_EVENT_MOUSE_MOTION) or when focused (below)
1014#if OSPP_HAS_CAPTURE_AND_GLOBAL_MOUSE
1015 // OSPP_CaptureMouse() let the OS know e.g. that our imgui drag outside the OSPP window boundaries
1016 // shouldn't
1017 os::mouse::capture((bd->MouseButtonsDown != 0));
1018
1019 // e.g. trigger other operations outside
1020 ImGuiViewport* focused_viewport = ImGui_ImplOSPP_GetFocusedViewport();
1021
1022 const bool is_app_focused = !!focused_viewport;
1023#else
1024 const bool is_app_focused =
1025 bd->Window->get_window().has_focus(); // OSPP 2.0.3 and non-windowed systems: single-viewport only
1026#endif
1027 if(is_app_focused)
1028 {
1029 // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when
1030 // ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
1031 if(io.WantSetMousePos)
1032 {
1033 os::point mouse_pos(int32_t(io.MousePos.x), int32_t(io.MousePos.y));
1034#if OSPP_HAS_CAPTURE_AND_GLOBAL_MOUSE
1035 if(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
1036 os::mouse::set_position(mouse_pos);
1037 else
1038#endif
1039 os::mouse::set_position(mouse_pos, bd->Window->get_window());
1040 }
1041
1042 // (Optional) Fallback to provide mouse position when focused (OSPP_EVENT_MOUSE_MOTION already
1043 // provides this when hovered or captured)
1044 if(bd->MouseCanUseGlobalState && bd->MouseButtonsDown == 0)
1045 {
1046 // Single-viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when
1047 // the mouse is on the upper-left corner of the app window) Multi-viewport mode: mouse position in
1048 // OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the
1049 // primary monitor)
1050 auto mouse_pos = os::mouse::get_position();
1051 if(!(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable))
1052 {
1053 auto fvd = ImGui_ImplOSPP_GetViewportData(focused_viewport);
1054 if(fvd)
1055 {
1056 mouse_pos = os::mouse::get_position(fvd->Window->get_window());
1057 }
1058 }
1059 io.AddMouseSourceEvent(ImGuiMouseSource_Mouse);
1060 io.AddMousePosEvent(float(mouse_pos.x), float(mouse_pos.y));
1061 }
1062 }
1063
1064 // (Optional) When using multiple viewports: call io.AddMouseViewportEvent() with the viewport the OS
1065 // mouse cursor is hovering. If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, Dear
1066 // imGui will ignore this field and infer the information using its flawed heuristic.
1067 // - [!] OSPP backend does NOT correctly ignore viewports with the _NoInputs flag.
1068 // Some backend are not able to handle that correctly. If a backend report an hovered viewport that
1069 // has the _NoInputs flag (e.g. when dragging a window for docking, the viewport has the _NoInputs
1070 // flag in order to allow us to find the viewport under), then Dear ImGui is forced to ignore the
1071 // value reported by the backend, and use its flawed heuristic to guess the viewport behind.
1072 // - [X] OSPP backend correctly reports this regardless of another viewport behind focused and dragged
1073 // from (we need this to find a useful drag and drop target).
1074 if(io.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport)
1075 {
1076 ImGuiID mouse_viewport_id = 0;
1077 if(ImGuiViewport* mouse_viewport = ImGui_ImplOSPP_GetViewportFromWindowId(bd->MouseWindowID))
1078 {
1080 mouse_viewport_id = mouse_viewport->ID;
1081 }
1082 io.AddMouseViewportEvent(mouse_viewport_id);
1083 }
1084}
1085
1087{
1088 ImGuiIO& io = ImGui::GetIO();
1089 if(io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
1090 return;
1092
1093 ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
1094 if(io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None)
1095 {
1096 // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
1097 bd->Window->get_window().show_cursor(false);
1098 }
1099 else
1100 {
1101 if(bd->LastMouseCursor != imgui_cursor)
1102 {
1103 auto cursor = os::get_system_cursor(ImGui_ImplOSPP_MapCursor(imgui_cursor));
1104 bd->Window->get_window().set_cursor(cursor);
1105
1106 bd->LastMouseCursor = imgui_cursor;
1107 }
1108 bd->Window->get_window().show_cursor(true);
1109 }
1110}
1111
1113{
1114}
1115
1117{
1119
1120 ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
1121
1122 if(!bd->WantUpdateMonitors)
1123 {
1124 if(!platform_io.Monitors.empty())
1125 {
1126 if(!bd->NoMonitorDetected)
1127 {
1128 return;
1129 }
1130 }
1131
1132 }
1133
1134 bd->WantUpdateMonitors = false;
1135
1136 platform_io.Monitors.resize(0);
1137 int display_count = os::display::get_available_displays_count();
1138
1139 if(display_count < 1)
1140 {
1141 ImGuiPlatformMonitor monitor;
1142 monitor.MainPos = monitor.WorkPos = ImVec2();
1143 monitor.MainSize = monitor.WorkSize = ImVec2(1920.f, 1080.f);
1144 platform_io.Monitors.push_back(monitor);
1145 bd->NoMonitorDetected = true;
1146
1147 return;
1148 }
1149
1150 bd->NoMonitorDetected = false;
1151
1152 for(int n = 0; n < display_count; n++)
1153 {
1154 // Warning: the validity of monitor DPI information on Windows depends on the application DPI
1155 // awareness settings, which generally needs to be set in the manifest or at runtime.
1156 ImGuiPlatformMonitor monitor;
1157 auto bounds = os::display::get_bounds(n);
1158 auto mode = os::display::get_desktop_mode(n);
1159 monitor.DpiScale = os::display::get_content_scale(n);
1160 monitor.MainPos = monitor.WorkPos = ImVec2(float(bounds.x), float(bounds.y));
1161 monitor.MainSize = monitor.WorkSize = ImVec2(float(bounds.w), float(bounds.h));
1162 auto usable_bounds = os::display::get_usable_bounds(n);
1163 monitor.WorkPos = ImVec2((float)usable_bounds.x, (float)usable_bounds.y);
1164 monitor.WorkSize = ImVec2((float)usable_bounds.w, (float)usable_bounds.h);
1165
1166 monitor.PlatformHandle = (void*)(intptr_t)n;
1167 if (monitor.DpiScale <= 0.0f)
1168 continue; // Some accessibility applications are declaring virtual monitors with a DPI of 0, see #7902.
1169 platform_io.Monitors.push_back(monitor);
1170 }
1171}
1172
1173static void ImGui_ImplOSPP_GetWindowSizeAndFramebufferScale(unravel::render_window* window, ImVec2* out_size, ImVec2* out_framebuffer_scale)
1174{
1175 int w, h;
1176 int display_w, display_h;
1177
1178 auto size = window->get_window().get_size();
1179 if(window->get_window().is_minimized())
1180 {
1181 w = h = 0;
1182 }
1183 else
1184 {
1185 w = size.w;
1186 h = size.h;
1187 }
1188 auto surface_size = window->get_surface()->get_size();
1189 if(surface_size.width != size.w || surface_size.height != size.h)
1190 {
1191 display_w = surface_size.width;
1192 display_h = surface_size.height;
1193 }
1194 else
1195 {
1196 display_w = w;
1197 display_h = h;
1198 }
1199 if (out_size != nullptr)
1200 *out_size = ImVec2((float)w, (float)h);
1201 if (out_framebuffer_scale != nullptr)
1202 *out_framebuffer_scale = (w > 0 && h > 0) ? ImVec2((float)display_w / w, (float)display_h / h) : ImVec2(1.0f, 1.0f);
1203}
1204
1205void ImGui_ImplOSPP_NewFrame(float delta_time)
1206{
1208 IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplOSPP_Init()?");
1209 ImGuiIO& io = ImGui::GetIO();
1210
1211 ImGui_ImplOSPP_GetWindowSizeAndFramebufferScale(bd->Window, &io.DisplaySize, &io.DisplayFramebufferScale);
1212
1213 io.DeltaTime = delta_time;
1214 if(io.DeltaTime <= 0.00001f)
1215 io.DeltaTime = 1.0f / 60.0f;
1216
1217
1218 // Update monitors
1219 if(bd->WantUpdateMonitors)
1221
1224
1225 // Update game controllers (if enabled and available)
1227}
1228
1230{
1231 ImGuiIO& io = ImGui::GetIO();
1232
1233 // Update and Render additional Platform Windows
1234 // (Platform functions may change the current OpenGL context, so we save/restore it to make it easier to
1235 // paste this code elsewhere.
1236 // For this specific demo app we could also call OSPP_GL_MakeCurrent(window, gl_context) directly)
1237 if(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
1238 {
1239 ImGui::UpdatePlatformWindows();
1240 ImGui::RenderPlatformWindowsDefault();
1241 }
1242}
1243//--------------------------------------------------------------------------------------------------------
1244// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
1245// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports
1246// simultaneously. If you are new to dear imgui or creating a new binding for dear imgui, it is recommended
1247// that you completely ignore this section first..
1248//--------------------------------------------------------------------------------------------------------
1249
1250static void ImGui_ImplOSPP_CreateWindow(ImGuiViewport* viewport)
1251{
1253 viewport->PlatformUserData = vd;
1254
1255 ImGuiViewport* main_viewport = ImGui::GetMainViewport();
1256 ImGui_ImplOSPP_ViewportData* main_viewport_data = ImGui_ImplOSPP_GetViewportData(main_viewport);
1257
1258 uint32_t win_flags = 0;
1259 win_flags |= os::window::hidden;
1260 win_flags |= os::window::resizable;
1261 win_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? os::window::borderless : 0;
1262 win_flags |= (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon) ? os::window::no_taskbar : 0;
1263 win_flags |= (viewport->Flags & ImGuiViewportFlags_TopMost) ? os::window::always_on_top : 0;
1264
1265 os::window os_win("No Title Yet",
1266 int32_t(viewport->Pos.x),
1267 int32_t(viewport->Pos.y),
1268 uint32_t(viewport->Size.x),
1269 uint32_t(viewport->Size.y),
1270 win_flags);
1271
1272 vd->Window = IM_NEW(unravel::render_window)(std::move(os_win));
1273 vd->WindowOwned = true;
1274
1275 viewport->PlatformHandle = ImGui_ImplOSPP_IdToHandle(vd->Window->get_window().get_id());
1276 viewport->PlatformHandleRaw = vd->Window->get_window().get_native_handle();
1277}
1278
1279static void ImGui_ImplOSPP_DestroyWindow(ImGuiViewport* viewport)
1280{
1282 {
1283 if(vd->Window && vd->WindowOwned)
1284 IM_DELETE(vd->Window);
1285
1286 vd->Window = nullptr;
1287 IM_DELETE(vd);
1288 }
1289 viewport->PlatformUserData = viewport->PlatformHandle = nullptr;
1290}
1291
1292static void ImGui_ImplOSPP_ShowWindow(ImGuiViewport* viewport)
1293{
1295
1296#if defined(_WIN32) && \
1297 !(defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP || WINAPI_FAMILY == WINAPI_FAMILY_GAMES))
1298 HWND hwnd = (HWND)viewport->PlatformHandleRaw;
1299
1300 // SDL hack: Show icon in task bar (#7989)
1301 // Note: SDL_WINDOW_UTILITY can be used to control task bar visibility, but on Windows, it does not affect child
1302 // windows.
1303 if(!(viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon))
1304 {
1305 LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
1306 ex_style |= WS_EX_APPWINDOW;
1307 ex_style &= ~WS_EX_TOOLWINDOW;
1308 ::ShowWindow(hwnd, SW_HIDE);
1309 ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style);
1310 }
1311#endif
1312
1313 os::set_hint("HINT_WINDOW_ACTIVATE_WHEN_SHOWN",
1314 (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing) ? "0" : "1");
1315
1316
1317
1318 vd->Window->get_window().show();
1319
1320 if(!vd->WindowShownAtLeastOnce)
1321 {
1322 vd->WindowShownAtLeastOnce = true;
1323 vd->Window->get_window().set_opacity(vd->WindowOpacity);
1324 }
1325}
1326
1327static auto ImGui_ImplOSPP_GetWindowPos(ImGuiViewport* viewport) -> ImVec2
1328{
1330 auto pos = vd->Window->get_window().get_position();
1331 return {float(pos.x), float(pos.y)};
1332}
1333
1334static void ImGui_ImplOSPP_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
1335{
1337 vd->Window->get_window().set_position(int32_t(pos.x), int32_t(pos.y));
1338}
1339
1340static auto ImGui_ImplOSPP_GetWindowSize(ImGuiViewport* viewport) -> ImVec2
1341{
1343 auto size = vd->Window->get_window().get_size();
1344 return {float(size.w), float(size.h)};
1345}
1346
1347static void ImGui_ImplOSPP_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
1348{
1350 vd->Window->resize(uint32_t(size.x), uint32_t(size.y));
1351}
1352
1353static ImVec2 ImGui_ImplOSPP_GetWindowFramebufferScale(ImGuiViewport* viewport)
1354{
1356 ImVec2 framebuffer_scale;
1357 ImGui_ImplOSPP_GetWindowSizeAndFramebufferScale(vd->Window, nullptr, &framebuffer_scale);
1358 return framebuffer_scale;
1359}
1360
1361
1362static void ImGui_ImplOSPP_SetWindowTitle(ImGuiViewport* viewport, const char* title)
1363{
1365 vd->Window->get_window().set_title(title);
1366}
1367
1368static void ImGui_ImplOSPP_SetWindowAlpha(ImGuiViewport* viewport, float alpha)
1369{
1372 vd->Window->get_window().set_opacity(alpha);
1373 else
1374 vd->WindowOpacity = alpha;
1375}
1376
1377static void ImGui_ImplOSPP_SetWindowFocus(ImGuiViewport* viewport)
1378{
1380 vd->Window->get_window().request_focus();
1381}
1382
1383static auto ImGui_ImplOSPP_GetWindowFocus(ImGuiViewport* viewport) -> bool
1384{
1386 return vd->Window->get_window().has_focus();
1387}
1388
1389static auto ImGui_ImplOSPP_GetWindowMinimized(ImGuiViewport* viewport) -> bool
1390{
1392 return vd->Window->get_window().is_minimized();
1393}
1394
1395void ImGui_ImplOSPP_RenderWindow(ImGuiViewport* viewport, void* rend_args)
1396{
1399
1400 bd->RenderCallback(vd->Window, viewport, rend_args);
1401}
1402
1403void ImGui_ImplOSPP_SwapBuffers(ImGuiViewport* viewport, void* rend_args)
1404{
1407
1408 bd->SwapCallback(vd->Window, viewport, rend_args);
1409}
1410
1412{
1413 // Register platform interface (will be coupled with a renderer interface)
1414 ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
1415 platform_io.Platform_CreateWindow = ImGui_ImplOSPP_CreateWindow;
1416 platform_io.Platform_DestroyWindow = ImGui_ImplOSPP_DestroyWindow;
1417 platform_io.Platform_ShowWindow = ImGui_ImplOSPP_ShowWindow;
1418 platform_io.Platform_SetWindowPos = ImGui_ImplOSPP_SetWindowPos;
1419 platform_io.Platform_GetWindowPos = ImGui_ImplOSPP_GetWindowPos;
1420 platform_io.Platform_SetWindowSize = ImGui_ImplOSPP_SetWindowSize;
1421 platform_io.Platform_GetWindowSize = ImGui_ImplOSPP_GetWindowSize;
1422 platform_io.Platform_GetWindowFramebufferScale = ImGui_ImplOSPP_GetWindowFramebufferScale;
1423 platform_io.Platform_SetWindowFocus = ImGui_ImplOSPP_SetWindowFocus;
1424 platform_io.Platform_GetWindowFocus = ImGui_ImplOSPP_GetWindowFocus;
1425 platform_io.Platform_GetWindowMinimized = ImGui_ImplOSPP_GetWindowMinimized;
1426 platform_io.Platform_SetWindowTitle = ImGui_ImplOSPP_SetWindowTitle;
1427 platform_io.Platform_RenderWindow = ImGui_ImplOSPP_RenderWindow;
1428 platform_io.Platform_SwapBuffers = ImGui_ImplOSPP_SwapBuffers;
1429 platform_io.Platform_SetWindowAlpha = ImGui_ImplOSPP_SetWindowAlpha;
1430
1431 // Register main window handle (which is owned by the main application, not by us)
1432 // This is mostly for simplicity and consistency, so that our code (e.g. mouse handling etc.) can use same
1433 // logic for main and secondary viewports.
1434 ImGuiViewport* main_viewport = ImGui::GetMainViewport();
1436 vd->Window = window;
1437 vd->WindowOwned = false;
1438
1439 main_viewport->PlatformUserData = vd;
1440 main_viewport->PlatformHandle = ImGui_ImplOSPP_IdToHandle(window->get_window().get_id());
1441 main_viewport->PlatformHandleRaw = window->get_window().get_native_handle();
1442}
1443
1445{
1446 ImGui::DestroyPlatformWindows();
1447}
1448
1449#if defined(__clang__)
1450#pragma clang diagnostic pop
1451#endif
event_type event
const char * title
void ImGui_ImplOSPP_Shutdown()
static ImVec2 ImGui_ImplOSPP_GetWindowFramebufferScale(ImGuiViewport *viewport)
static auto ImGui_ImplOSPP_GetViewportFromWindowId(uint32_t id) -> ImGuiViewport *
static void ImGui_ImplOSPP_ShowWindow(ImGuiViewport *viewport)
auto ImGui_ImplOSPP_MapCursor(ImGuiMouseCursor cursor) -> os::cursor::type
static void ImGui_ImplOSPP_GetWindowSizeAndFramebufferScale(unravel::render_window *window, ImVec2 *out_size, ImVec2 *out_framebuffer_scale)
static void ImGui_ImplOSPP_SetWindowAlpha(ImGuiViewport *viewport, float alpha)
void ImGui_ImplOSPP_RenderWindow(ImGuiViewport *viewport, void *rend_args)
static void ImGui_ImplOSPP_ForEachViewport(const std::function< void(ImGuiViewport *viewport, ImGui_ImplOSPP_ViewportData *data)> &callback)
static auto ImGui_ImplOSPP_GetWindowMinimized(ImGuiViewport *viewport) -> bool
void ImGui_ImplOSPP_SwapBuffers(ImGuiViewport *viewport, void *rend_args)
static void ImGui_ImplOSPP_UpdateMouseData()
static auto ImGui_ImplOSPP_GetWindowSize(ImGuiViewport *viewport) -> ImVec2
static void ImGui_ImplOSPP_UpdateMouseCursor()
static void ImGui_ImplOSPP_CreateWindow(ImGuiViewport *viewport)
static void ImGui_ImplOSPP_UpdateMonitors()
auto ImGui_ImplOSPP_IdToHandle(uint32_t id) -> void *
auto ImGui_ImplOSPP_KeycodeToImGuiKey(os::key::code keycode) -> ImGuiKey
static auto ImGui_ImplOSPP_GetFocusedViewport() -> ImGuiViewport *
static void ImGui_ImplOSPP_SetPlatformImeData(ImGuiContext *ctx, ImGuiViewport *viewport, ImGuiPlatformImeData *data)
void ImGui_ImplOSPP_EndFrame()
static void ImGui_ImplOSPP_SetWindowSize(ImGuiViewport *viewport, ImVec2 size)
static void ImGui_ImplOSPP_UpdateKeyModifiers(os::key_event e)
auto ImGui_ImplOSPP_Init(unravel::render_window *window, ImGui_ImplOSPP_RenderWindow_Callback render_callback, ImGui_ImplOSPP_SwapBuffers_Callback swap_callback) -> bool
static void ImGui_ImplOSPP_InitPlatformInterface(unravel::render_window *window)
static auto ImGui_ImplOSPP_GetViewportData(ImGuiViewport *viewport) -> ImGui_ImplOSPP_ViewportData *
static auto ImGui_ImplOSPP_GetClipboardText(ImGuiContext *ctx) -> const char *
static void ImGui_ImplOSPP_SetWindowTitle(ImGuiViewport *viewport, const char *title)
static void ImGui_ImplOSPP_SetWindowFocus(ImGuiViewport *viewport)
static auto ImGui_ImplOSPP_GetWindowPos(ImGuiViewport *viewport) -> ImVec2
static void ImGui_ImplOSPP_UpdateGamepads()
static bool ImOsOpenInShell(ImGuiContext *ctx, const char *path)
static void ImGui_ImplOSPP_SetWindowPos(ImGuiViewport *viewport, ImVec2 pos)
auto ImGui_IsAnyRealItemActive() -> bool
static void ImGui_ImplOSPP_ShutdownPlatformInterface()
static void ImGui_ImplOSPP_SetClipboardText(ImGuiContext *ctx, const char *text)
auto ImGui_ImplOSPP_ImGuiKeyToKeycode(ImGuiKey key) -> os::key::code
void ImGui_ImplOSPP_NewFrame(float delta_time)
static auto ImGui_ImplOSPP_GetBackendData() -> ImGui_ImplOSPP_Data *
static void ImGui_ImplOSPP_DestroyWindow(ImGuiViewport *viewport)
static auto ImGui_ImplOSPP_GetWindowFocus(ImGuiViewport *viewport) -> bool
static bool ImOsIsDebuggerPresent()
auto ImGui_ImplOSPP_ProcessEvent(os::event &event) -> bool
std::function< void(unravel::render_window *window, ImGuiViewport *viewport, void *)> ImGui_ImplOSPP_RenderWindow_Callback
std::function< void(unravel::render_window *window, ImGuiViewport *viewport, void *)> ImGui_ImplOSPP_SwapBuffers_Callback
auto replace(const std::string &str, const std::string &search, const std::string &replace) -> std::string
Definition utils.cpp:28
ImGui_ImplOSPP_RenderWindow_Callback RenderCallback
unravel::render_window * Window
std::string ClipboardTextData
ImGuiMouseCursor LastMouseCursor
ImGui_ImplOSPP_SwapBuffers_Callback SwapCallback
unravel::render_window * Window
T height
Definition basetypes.hpp:56
Struct representing a render window.
auto get_surface() -> graphics_surface_t &
Gets the rendering surface.
void resize(uint32_t w, uint32_t h)
Resizes the render window to the specified width and height.
auto get_window() -> os::window &
Gets the associated OS window.
float size