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
64static bool ImOsIsDebuggerPresent()
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
153static void ImGui_ImplOSPP_ForEachViewport(
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};
171 ImGui_ImplOSPP_ForEachViewport(
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};
189 ImGui_ImplOSPP_ForEachViewport(
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.
206static auto ImGui_ImplOSPP_GetBackendData() -> ImGui_ImplOSPP_Data*
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
241static void ImGui_ImplOSPP_UpdateMonitors();
242static void ImGui_ImplOSPP_InitPlatformInterface(unravel::render_window* window);
243static void ImGui_ImplOSPP_ShutdownPlatformInterface();
244
245// Functions
246static auto ImGui_ImplOSPP_GetClipboardText(ImGuiContext* ctx) -> const char*
247{
248 ImGui_ImplOSPP_Data* bd = ImGui_ImplOSPP_GetBackendData();
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
273static auto 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
491static void ImGui_ImplOSPP_UpdateKeyModifiers(os::key_event e)
492{
493 ImGuiIO& io = ImGui::GetIO();
494 io.AddKeyEvent(ImGuiMod_Ctrl, e.ctrl);
495 io.AddKeyEvent(ImGuiMod_Shift, e.shift);
496 io.AddKeyEvent(ImGuiMod_Alt, e.alt);
497 io.AddKeyEvent(ImGuiMod_Super, e.system);
498}
499
501{
502 if(ImGui::IsAnyItemActive())
503 {
504 bool is_window_move = false;
505 for(auto window : ImGui::GetCurrentContext()->Windows)
506 {
507 if(window->MoveId == ImGui::GetActiveID())
508 {
509 is_window_move = true;
510 }
511 }
512
513 if(!is_window_move)
514 {
515 return true;
516 }
517 }
518 return false;
519}
520
521// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your
522// inputs.
523// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or
524// clear/overwrite your copy of the mouse data.
525// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or
526// clear/overwrite your copy of the keyboard data. Generally you may always pass all inputs to dear imgui, and
527// hide them from your application based on those two flags. If you have multiple OSPP events and some of them
528// are not meant to be used by dear imgui, you may need to filter events based on their windowID field.
529auto ImGui_ImplOSPP_ProcessEvent(os::event& event) -> bool
530{
531 ImGuiIO& io = ImGui::GetIO();
532 ImGui_ImplOSPP_Data* bd = ImGui_ImplOSPP_GetBackendData();
533
534 switch(event.type)
535 {
536 case os::events::mouse_motion:
537 {
538 os::point mouse_pos(event.motion.x, event.motion.y);
539 if(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
540 {
541 auto viewport = ImGui_ImplOSPP_GetViewportFromWindowId(event.motion.window_id);
542 auto vd = ImGui_ImplOSPP_GetViewportData(viewport);
543 if(vd)
544 {
545 auto window_pos = vd->Window->get_window().get_position();
546 mouse_pos.x += window_pos.x;
547 mouse_pos.y += window_pos.y;
548 }
549 }
550 io.AddMouseSourceEvent(ImGuiMouseSource_Mouse);
551 io.AddMousePosEvent(float(mouse_pos.x), float(mouse_pos.y));
552
553 return true;
554 }
555 case os::events::mouse_wheel:
556 {
557 // IMGUI_DEBUG_LOG("wheel %.2f %.2f, precise %.2f %.2f\n", (float)event->wheel.x,
558 // (float)event->wheel.y, event->wheel.preciseX, event->wheel.preciseY);
559 float wheel_x = -float(event.wheel.x);
560 float wheel_y = float(event.wheel.y);
561#ifdef __EMSCRIPTEN__
562 wheel_x /= 100.0f;
563#endif
564 io.AddMouseSourceEvent(ImGuiMouseSource_Mouse);
565 io.AddMouseWheelEvent(wheel_x, wheel_y);
566 return true;
567 }
568 case os::events::mouse_button:
569 {
570 int mouse_button = int(uint8_t(event.button.button)) - 1;
571 if(mouse_button == -1)
572 break;
573
574 bool pressed = event.button.state_id == os::state::pressed;
575 io.AddMouseSourceEvent(ImGuiMouseSource_Mouse);
576 io.AddMouseButtonEvent(mouse_button, pressed);
577 bd->MouseButtonsDown =
578 pressed ? (bd->MouseButtonsDown | (1 << mouse_button)) : (bd->MouseButtonsDown & ~(1 << mouse_button));
579 return true;
580 }
581 case os::events::text_input:
582 {
583 io.AddInputCharactersUTF8(event.text.text.c_str());
585 {
586 event = {};
587 }
588 return true;
589 }
590 case os::events::key_up:
591 case os::events::key_down:
592 {
593 ImGui_ImplOSPP_UpdateKeyModifiers(event.key);
594 ImGuiKey key = ImGui_ImplOSPP_KeycodeToImGuiKey(event.key.code);
595 io.AddKeyEvent(key, (event.type == os::events::key_down));
596 io.SetKeyEventNativeData(key, event.key.code, event.key.code, event.key.code);
597
599 {
600 event = {};
601 }
602 return true;
603 }
604 case os::events::window:
605 {
606 switch(event.window.type)
607 {
608 case os::window_event_id::focus_gained:
609 {
610 io.AddFocusEvent(true);
611 return true;
612 }
613 case os::window_event_id::focus_lost:
614 {
615 io.AddFocusEvent(false);
616 return true;
617 }
618 case os::window_event_id::enter:
619 {
620 bd->MouseWindowID = event.window.window_id;
622
623 return true;
624 }
625
626 case os::window_event_id::leave:
627 {
628 if(bd->MouseWindowID == event.window.window_id)
629 {
630 bd->PendingMouseLeaveFrame = ImGui::GetFrameCount() + 1;
631 }
632 return true;
633 }
634
635 case os::window_event_id::close:
636 case os::window_event_id::moved:
637 case os::window_event_id::resized:
638 if(ImGuiViewport* viewport = ImGui_ImplOSPP_GetViewportFromWindowId(event.window.window_id))
639 {
640 if(event.window.type == os::window_event_id::close)
641 viewport->PlatformRequestClose = true;
642 if(event.window.type == os::window_event_id::moved)
643 viewport->PlatformRequestMove = true;
644 if(event.window.type == os::window_event_id::resized)
645 viewport->PlatformRequestResize = true;
646 return true;
647 }
648 return true;
649 default:
650 break;
651 }
652 return true;
653 }
654 case os::events::display_orientation:
655 case os::events::display_connected:
656 case os::events::display_disconnected:
657 case os::events::display_moved:
658 case os::events::display_content_scale_changed:
659 {
660 bd->WantUpdateMonitors = true;
661 return true;
662 }
663
664 default:
665 break;
666 }
667
668 return false;
669}
670
673 ImGui_ImplOSPP_SwapBuffers_Callback swap_callback) -> bool
674{
675 ImGuiIO& io = ImGui::GetIO();
676 IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
677
678 // Check and store if we are on a OSPP backend that supports global mouse position
679 // ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list)
680 bool mouse_can_use_global_state = false;
681#if OSPP_HAS_CAPTURE_AND_GLOBAL_MOUSE
682 // const char* OSPP_backend = OSPP_GetCurrentVideoDriver();
683 // const char* global_mouse_whitelist[] = { "windows", "cocoa", "x11", "DIVE", "VMAN" };
684 // for (int n = 0; n < IM_ARRAYSIZE(global_mouse_whitelist); n++)
685 // if (strncmp(OSPP_backend, global_mouse_whitelist[n], strlen(global_mouse_whitelist[n])) == 0)
686 mouse_can_use_global_state = true;
687#endif
688
689 // Setup backend capabilities flags
691 io.BackendPlatformUserData = bd;
692 io.BackendPlatformName = "imgui_impl_ospp";
693
694 // We can honor GetMouseCursor() values (optional)
695 io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors;
696
697
698
699 // We can honor io.WantSetMousePos requests (optional, rarely used)
700 io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos;
701 io.ConfigDebugHighlightIdConflicts = true;
702 // We can create multi-viewports on the
703 // Platform side (optional)
704 if(mouse_can_use_global_state)
705 io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports;
706
707 bd->RenderCallback = std::move(render_callback);
708 bd->SwapCallback = std::move(swap_callback);
709 bd->Window = window;
710
711 // OSPP on Linux/OSX doesn't report events for unfocused windows (see
712 // https://github.com/ocornut/imgui/issues/4960) We will use 'MouseCanReportHoveredViewport' to set
713 // 'ImGuiBackendFlags_HasMouseHoveredViewport' dynamically each frame.
714 bd->MouseCanUseGlobalState = mouse_can_use_global_state;
715#ifndef __APPLE__
717#else
719#endif
720 bd->WantUpdateMonitors = true;
721
722 ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
723 platform_io.Platform_SetClipboardTextFn = ImGui_ImplOSPP_SetClipboardText;
724 platform_io.Platform_GetClipboardTextFn = ImGui_ImplOSPP_GetClipboardText;
725 platform_io.Platform_OpenInShellFn = ImOsOpenInShell;
726 platform_io.Platform_ClipboardUserData = nullptr;
727 platform_io.Platform_SetImeDataFn = ImGui_ImplOSPP_SetPlatformImeData;
728
729
730 // Set platform dependent data in viewport
731 // Our mouse update function expect PlatformHandle to be filled for the main viewport
732 ImGuiViewport* main_viewport = ImGui::GetMainViewport();
733
734 main_viewport->PlatformHandle = ImGui_ImplOSPP_IdToHandle(window->get_window().get_id());
735 main_viewport->PlatformHandleRaw = window->get_window().get_native_handle();
736
737 // From 2.0.5: Set SDL hint to receive mouse click events on window focus, otherwise SDL doesn't emit the
738 // event. Without this, when clicking to gain focus, our widgets wouldn't activate even though they showed
739 // as hovered. (This is unfortunately a global SDL setting, so enabling it might have a side-effect on
740 // your application. It is unlikely to make a difference, but if your app absolutely needs to ignore the
741 // initial on-focus click: you can ignore OSPP_EVENT_MOUSE_BUTTON_DOWN events coming right after a
742 // OSPP_WINDOWEVENT_FOCUS_GAINED)
743 os::set_hint("HINT_MOUSE_FOCUS_CLICKTHROUGH", "1");
744
745 // From 2.0.22: Disable auto-capture, this is preventing drag and drop across multiple windows (see #5710)
746 os::set_hint("HINT_MOUSE_AUTO_CAPTURE", "0");
747
748 // SDL 3.x : see https://github.com/libSDL-org/SDL/issues/6659
749 os::set_hint("HINT_BORDERLESS_WINDOWED_STYLE", "0");
750
751 if((io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) &&
752 (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports))
753 ImGui_ImplOSPP_InitPlatformInterface(window);
754
755 return true;
756}
757
759{
760 ImGui_ImplOSPP_Data* bd = ImGui_ImplOSPP_GetBackendData();
761 IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
762 ImGuiIO& io = ImGui::GetIO();
763
764 ImGui_ImplOSPP_ShutdownPlatformInterface();
765
766 io.BackendPlatformName = nullptr;
767 io.BackendPlatformUserData = nullptr;
768 io.BackendFlags &=
769 ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad |
770 ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport);
771 IM_DELETE(bd);
772}
773
774// This code is incredibly messy because some of the functions we need for full viewport support are not
775// available in OSPP < 2.0.4.
776static void ImGui_ImplOSPP_UpdateMouseData()
777{
778 ImGui_ImplOSPP_Data* bd = ImGui_ImplOSPP_GetBackendData();
779 ImGuiIO& io = ImGui::GetIO();
780
781 if(bd->PendingMouseLeaveFrame && bd->PendingMouseLeaveFrame >= ImGui::GetFrameCount() && bd->MouseButtonsDown == 0)
782 {
783 bd->MouseWindowID = 0;
785 io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
786 }
787
788 // Our io.AddMouseViewportEvent() calls will only be valid when not capturing.
789 // Technically speaking testing for 'bd->MouseButtonsDown == 0' would be more rygorous, but testing for
790 // payload reduces noise and potential side-effects.
791 if(bd->MouseCanReportHoveredViewport && ImGui::GetDragDropPayload() == nullptr)
792 io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport;
793 else
794 io.BackendFlags &= ~ImGuiBackendFlags_HasMouseHoveredViewport;
795
796 // We forward mouse input when hovered or captured (via OSPP_EVENT_MOUSE_MOTION) or when focused (below)
797#if OSPP_HAS_CAPTURE_AND_GLOBAL_MOUSE
798 // OSPP_CaptureMouse() let the OS know e.g. that our imgui drag outside the OSPP window boundaries
799 // shouldn't
800 os::mouse::capture((bd->MouseButtonsDown != 0));
801
802 // e.g. trigger other operations outside
803 ImGuiViewport* focused_viewport = ImGui_ImplOSPP_GetFocusedViewport();
804
805 const bool is_app_focused = !!focused_viewport;
806#else
807 const bool is_app_focused =
808 bd->Window->get_window().has_focus(); // OSPP 2.0.3 and non-windowed systems: single-viewport only
809#endif
810 if(is_app_focused)
811 {
812 // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when
813 // ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
814 if(io.WantSetMousePos)
815 {
816 os::point mouse_pos(int32_t(io.MousePos.x), int32_t(io.MousePos.y));
817#if OSPP_HAS_CAPTURE_AND_GLOBAL_MOUSE
818 if(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
819 os::mouse::set_position(mouse_pos);
820 else
821#endif
822 os::mouse::set_position(mouse_pos, bd->Window->get_window());
823 }
824
825 // (Optional) Fallback to provide mouse position when focused (OSPP_EVENT_MOUSE_MOTION already
826 // provides this when hovered or captured)
827 if(bd->MouseCanUseGlobalState && bd->MouseButtonsDown == 0)
828 {
829 // Single-viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when
830 // the mouse is on the upper-left corner of the app window) Multi-viewport mode: mouse position in
831 // OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the
832 // primary monitor)
833 auto mouse_pos = os::mouse::get_position();
834 if(!(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable))
835 {
836 auto fvd = ImGui_ImplOSPP_GetViewportData(focused_viewport);
837 if(fvd)
838 {
839 mouse_pos = os::mouse::get_position(fvd->Window->get_window());
840 }
841 }
842 io.AddMouseSourceEvent(ImGuiMouseSource_Mouse);
843 io.AddMousePosEvent(float(mouse_pos.x), float(mouse_pos.y));
844 }
845 }
846
847 // (Optional) When using multiple viewports: call io.AddMouseViewportEvent() with the viewport the OS
848 // mouse cursor is hovering. If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, Dear
849 // imGui will ignore this field and infer the information using its flawed heuristic.
850 // - [!] OSPP backend does NOT correctly ignore viewports with the _NoInputs flag.
851 // Some backend are not able to handle that correctly. If a backend report an hovered viewport that
852 // has the _NoInputs flag (e.g. when dragging a window for docking, the viewport has the _NoInputs
853 // flag in order to allow us to find the viewport under), then Dear ImGui is forced to ignore the
854 // value reported by the backend, and use its flawed heuristic to guess the viewport behind.
855 // - [X] OSPP backend correctly reports this regardless of another viewport behind focused and dragged
856 // from (we need this to find a useful drag and drop target).
857 if(io.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport)
858 {
859 ImGuiID mouse_viewport_id = 0;
860 if(ImGuiViewport* mouse_viewport = ImGui_ImplOSPP_GetViewportFromWindowId(bd->MouseWindowID))
861 {
862 ImGui_ImplOSPP_ViewportData* vd = ImGui_ImplOSPP_GetViewportData(mouse_viewport);
863 mouse_viewport_id = mouse_viewport->ID;
864 }
865 io.AddMouseViewportEvent(mouse_viewport_id);
866 }
867}
868
869static void ImGui_ImplOSPP_UpdateMouseCursor()
870{
871 ImGuiIO& io = ImGui::GetIO();
872 if(io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
873 return;
874 ImGui_ImplOSPP_Data* bd = ImGui_ImplOSPP_GetBackendData();
875
876 ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
877 if(io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None)
878 {
879 // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
880 bd->Window->get_window().show_cursor(false);
881 }
882 else
883 {
884 if(bd->LastMouseCursor != imgui_cursor)
885 {
886 auto cursor = os::get_system_cursor(ImGui_ImplOSPP_MapCursor(imgui_cursor));
887 bd->Window->get_window().set_cursor(cursor);
888
889 bd->LastMouseCursor = imgui_cursor;
890 }
891 bd->Window->get_window().show_cursor(true);
892 }
893}
894
895static void ImGui_ImplOSPP_UpdateGamepads()
896{
897}
898
899static void ImGui_ImplOSPP_UpdateMonitors()
900{
901 ImGui_ImplOSPP_Data* bd = ImGui_ImplOSPP_GetBackendData();
902
903 ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
904
905 if(!bd->WantUpdateMonitors)
906 {
907 if(!platform_io.Monitors.empty())
908 {
909 if(!bd->NoMonitorDetected)
910 {
911 return;
912 }
913 }
914
915 }
916
917 bd->WantUpdateMonitors = false;
918
919 platform_io.Monitors.resize(0);
920 int display_count = os::display::get_available_displays_count();
921
922 if(display_count < 1)
923 {
924 ImGuiPlatformMonitor monitor;
925 monitor.MainPos = monitor.WorkPos = ImVec2();
926 monitor.MainSize = monitor.WorkSize = ImVec2(1920.f, 1080.f);
927 platform_io.Monitors.push_back(monitor);
928 bd->NoMonitorDetected = true;
929
930 return;
931 }
932
933 bd->NoMonitorDetected = false;
934
935 for(int n = 0; n < display_count; n++)
936 {
937 // Warning: the validity of monitor DPI information on Windows depends on the application DPI
938 // awareness settings, which generally needs to be set in the manifest or at runtime.
939 ImGuiPlatformMonitor monitor;
940 auto bounds = os::display::get_bounds(n);
941 auto mode = os::display::get_desktop_mode(n);
942 monitor.DpiScale = os::display::get_content_scale(n);
943 monitor.MainPos = monitor.WorkPos = ImVec2(float(bounds.x), float(bounds.y));
944 monitor.MainSize = monitor.WorkSize = ImVec2(float(bounds.w), float(bounds.h));
945 auto usable_bounds = os::display::get_usable_bounds(n);
946 monitor.WorkPos = ImVec2((float)usable_bounds.x, (float)usable_bounds.y);
947 monitor.WorkSize = ImVec2((float)usable_bounds.w, (float)usable_bounds.h);
948
949 monitor.PlatformHandle = (void*)(intptr_t)n;
950 if (monitor.DpiScale <= 0.0f)
951 continue; // Some accessibility applications are declaring virtual monitors with a DPI of 0, see #7902.
952 platform_io.Monitors.push_back(monitor);
953 }
954}
955
956static void ImGui_ImplOSPP_GetWindowSizeAndFramebufferScale(unravel::render_window* window, ImVec2* out_size, ImVec2* out_framebuffer_scale)
957{
958 int w, h;
959 int display_w, display_h;
960
961 auto size = window->get_window().get_size();
962 if(window->get_window().is_minimized())
963 {
964 w = h = 0;
965 }
966 else
967 {
968 w = size.w;
969 h = size.h;
970 }
971 auto surface_size = window->get_surface()->get_size();
972 if(surface_size.width != size.w || surface_size.height != size.h)
973 {
974 display_w = surface_size.width;
975 display_h = surface_size.height;
976 }
977 else
978 {
979 display_w = w;
980 display_h = h;
981 }
982 if (out_size != nullptr)
983 *out_size = ImVec2((float)w, (float)h);
984 if (out_framebuffer_scale != nullptr)
985 *out_framebuffer_scale = (w > 0 && h > 0) ? ImVec2((float)display_w / w, (float)display_h / h) : ImVec2(1.0f, 1.0f);
986}
987
988void ImGui_ImplOSPP_NewFrame(float delta_time)
989{
990 ImGui_ImplOSPP_Data* bd = ImGui_ImplOSPP_GetBackendData();
991 IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplOSPP_Init()?");
992 ImGuiIO& io = ImGui::GetIO();
993
994 ImGui_ImplOSPP_GetWindowSizeAndFramebufferScale(bd->Window, &io.DisplaySize, &io.DisplayFramebufferScale);
995
996 io.DeltaTime = delta_time;
997 if(io.DeltaTime <= 0.00001f)
998 io.DeltaTime = 1.0f / 60.0f;
999
1000
1001 // Update monitors
1002 if(bd->WantUpdateMonitors)
1003 ImGui_ImplOSPP_UpdateMonitors();
1004
1005 ImGui_ImplOSPP_UpdateMouseData();
1006 ImGui_ImplOSPP_UpdateMouseCursor();
1007
1008 // Update game controllers (if enabled and available)
1009 ImGui_ImplOSPP_UpdateGamepads();
1010}
1011
1013{
1014 ImGuiIO& io = ImGui::GetIO();
1015
1016 // Update and Render additional Platform Windows
1017 // (Platform functions may change the current OpenGL context, so we save/restore it to make it easier to
1018 // paste this code elsewhere.
1019 // For this specific demo app we could also call OSPP_GL_MakeCurrent(window, gl_context) directly)
1020 if(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
1021 {
1022 ImGui::UpdatePlatformWindows();
1023 ImGui::RenderPlatformWindowsDefault();
1024 }
1025}
1026//--------------------------------------------------------------------------------------------------------
1027// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
1028// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports
1029// simultaneously. If you are new to dear imgui or creating a new binding for dear imgui, it is recommended
1030// that you completely ignore this section first..
1031//--------------------------------------------------------------------------------------------------------
1032
1033static void ImGui_ImplOSPP_CreateWindow(ImGuiViewport* viewport)
1034{
1036 viewport->PlatformUserData = vd;
1037
1038 ImGuiViewport* main_viewport = ImGui::GetMainViewport();
1039 ImGui_ImplOSPP_ViewportData* main_viewport_data = ImGui_ImplOSPP_GetViewportData(main_viewport);
1040
1041 uint32_t win_flags = 0;
1042 win_flags |= os::window::hidden;
1043 win_flags |= os::window::resizable;
1044 win_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? os::window::borderless : 0;
1045 win_flags |= (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon) ? os::window::no_taskbar : 0;
1046 win_flags |= (viewport->Flags & ImGuiViewportFlags_TopMost) ? os::window::always_on_top : 0;
1047
1048 os::window os_win("No Title Yet",
1049 int32_t(viewport->Pos.x),
1050 int32_t(viewport->Pos.y),
1051 uint32_t(viewport->Size.x),
1052 uint32_t(viewport->Size.y),
1053 win_flags);
1054
1055 vd->Window = IM_NEW(unravel::render_window)(std::move(os_win));
1056 vd->WindowOwned = true;
1057
1058 viewport->PlatformHandle = ImGui_ImplOSPP_IdToHandle(vd->Window->get_window().get_id());
1059 viewport->PlatformHandleRaw = vd->Window->get_window().get_native_handle();
1060}
1061
1062static void ImGui_ImplOSPP_DestroyWindow(ImGuiViewport* viewport)
1063{
1064 if(ImGui_ImplOSPP_ViewportData* vd = ImGui_ImplOSPP_GetViewportData(viewport))
1065 {
1066 if(vd->Window && vd->WindowOwned)
1067 IM_DELETE(vd->Window);
1068
1069 vd->Window = nullptr;
1070 IM_DELETE(vd);
1071 }
1072 viewport->PlatformUserData = viewport->PlatformHandle = nullptr;
1073}
1074
1075static void ImGui_ImplOSPP_ShowWindow(ImGuiViewport* viewport)
1076{
1077 ImGui_ImplOSPP_ViewportData* vd = ImGui_ImplOSPP_GetViewportData(viewport);
1078
1079#if defined(_WIN32) && \
1080 !(defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP || WINAPI_FAMILY == WINAPI_FAMILY_GAMES))
1081 HWND hwnd = (HWND)viewport->PlatformHandleRaw;
1082
1083 // SDL hack: Show icon in task bar (#7989)
1084 // Note: SDL_WINDOW_UTILITY can be used to control task bar visibility, but on Windows, it does not affect child
1085 // windows.
1086 if(!(viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon))
1087 {
1088 LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
1089 ex_style |= WS_EX_APPWINDOW;
1090 ex_style &= ~WS_EX_TOOLWINDOW;
1091 ::ShowWindow(hwnd, SW_HIDE);
1092 ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style);
1093 }
1094#endif
1095
1096 os::set_hint("HINT_WINDOW_ACTIVATE_WHEN_SHOWN",
1097 (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing) ? "0" : "1");
1098
1099
1100
1101 vd->Window->get_window().show();
1102
1103 if(!vd->WindowShownAtLeastOnce)
1104 {
1105 vd->WindowShownAtLeastOnce = true;
1106 vd->Window->get_window().set_opacity(vd->WindowOpacity);
1107 }
1108}
1109
1110static auto ImGui_ImplOSPP_GetWindowPos(ImGuiViewport* viewport) -> ImVec2
1111{
1112 ImGui_ImplOSPP_ViewportData* vd = ImGui_ImplOSPP_GetViewportData(viewport);
1113 auto pos = vd->Window->get_window().get_position();
1114 return {float(pos.x), float(pos.y)};
1115}
1116
1117static void ImGui_ImplOSPP_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
1118{
1119 ImGui_ImplOSPP_ViewportData* vd = ImGui_ImplOSPP_GetViewportData(viewport);
1120 vd->Window->get_window().set_position(int32_t(pos.x), int32_t(pos.y));
1121}
1122
1123static auto ImGui_ImplOSPP_GetWindowSize(ImGuiViewport* viewport) -> ImVec2
1124{
1125 ImGui_ImplOSPP_ViewportData* vd = ImGui_ImplOSPP_GetViewportData(viewport);
1126 auto size = vd->Window->get_window().get_size();
1127 return {float(size.w), float(size.h)};
1128}
1129
1130static void ImGui_ImplOSPP_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
1131{
1132 ImGui_ImplOSPP_ViewportData* vd = ImGui_ImplOSPP_GetViewportData(viewport);
1133 vd->Window->resize(uint32_t(size.x), uint32_t(size.y));
1134}
1135
1136static ImVec2 ImGui_ImplOSPP_GetWindowFramebufferScale(ImGuiViewport* viewport)
1137{
1138 ImGui_ImplOSPP_ViewportData* vd = ImGui_ImplOSPP_GetViewportData(viewport);
1139 ImVec2 framebuffer_scale;
1140 ImGui_ImplOSPP_GetWindowSizeAndFramebufferScale(vd->Window, nullptr, &framebuffer_scale);
1141 return framebuffer_scale;
1142}
1143
1144
1145static void ImGui_ImplOSPP_SetWindowTitle(ImGuiViewport* viewport, const char* title)
1146{
1147 ImGui_ImplOSPP_ViewportData* vd = ImGui_ImplOSPP_GetViewportData(viewport);
1148 vd->Window->get_window().set_title(title);
1149}
1150
1151static void ImGui_ImplOSPP_SetWindowAlpha(ImGuiViewport* viewport, float alpha)
1152{
1153 ImGui_ImplOSPP_ViewportData* vd = ImGui_ImplOSPP_GetViewportData(viewport);
1155 vd->Window->get_window().set_opacity(alpha);
1156 else
1157 vd->WindowOpacity = alpha;
1158}
1159
1160static void ImGui_ImplOSPP_SetWindowFocus(ImGuiViewport* viewport)
1161{
1162 ImGui_ImplOSPP_ViewportData* vd = ImGui_ImplOSPP_GetViewportData(viewport);
1163 vd->Window->get_window().request_focus();
1164}
1165
1166static auto ImGui_ImplOSPP_GetWindowFocus(ImGuiViewport* viewport) -> bool
1167{
1168 ImGui_ImplOSPP_ViewportData* vd = ImGui_ImplOSPP_GetViewportData(viewport);
1169 return vd->Window->get_window().has_focus();
1170}
1171
1172static auto ImGui_ImplOSPP_GetWindowMinimized(ImGuiViewport* viewport) -> bool
1173{
1174 ImGui_ImplOSPP_ViewportData* vd = ImGui_ImplOSPP_GetViewportData(viewport);
1175 return vd->Window->get_window().is_minimized();
1176}
1177
1178void ImGui_ImplOSPP_RenderWindow(ImGuiViewport* viewport, void* rend_args)
1179{
1180 ImGui_ImplOSPP_Data* bd = ImGui_ImplOSPP_GetBackendData();
1181 ImGui_ImplOSPP_ViewportData* vd = ImGui_ImplOSPP_GetViewportData(viewport);
1182
1183 bd->RenderCallback(vd->Window, viewport, rend_args);
1184}
1185
1186void ImGui_ImplOSPP_SwapBuffers(ImGuiViewport* viewport, void* rend_args)
1187{
1188 ImGui_ImplOSPP_Data* bd = ImGui_ImplOSPP_GetBackendData();
1189 ImGui_ImplOSPP_ViewportData* vd = ImGui_ImplOSPP_GetViewportData(viewport);
1190
1191 bd->SwapCallback(vd->Window, viewport, rend_args);
1192}
1193
1194static void ImGui_ImplOSPP_InitPlatformInterface(unravel::render_window* window)
1195{
1196 // Register platform interface (will be coupled with a renderer interface)
1197 ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
1198 platform_io.Platform_CreateWindow = ImGui_ImplOSPP_CreateWindow;
1199 platform_io.Platform_DestroyWindow = ImGui_ImplOSPP_DestroyWindow;
1200 platform_io.Platform_ShowWindow = ImGui_ImplOSPP_ShowWindow;
1201 platform_io.Platform_SetWindowPos = ImGui_ImplOSPP_SetWindowPos;
1202 platform_io.Platform_GetWindowPos = ImGui_ImplOSPP_GetWindowPos;
1203 platform_io.Platform_SetWindowSize = ImGui_ImplOSPP_SetWindowSize;
1204 platform_io.Platform_GetWindowSize = ImGui_ImplOSPP_GetWindowSize;
1205 platform_io.Platform_GetWindowFramebufferScale = ImGui_ImplOSPP_GetWindowFramebufferScale;
1206 platform_io.Platform_SetWindowFocus = ImGui_ImplOSPP_SetWindowFocus;
1207 platform_io.Platform_GetWindowFocus = ImGui_ImplOSPP_GetWindowFocus;
1208 platform_io.Platform_GetWindowMinimized = ImGui_ImplOSPP_GetWindowMinimized;
1209 platform_io.Platform_SetWindowTitle = ImGui_ImplOSPP_SetWindowTitle;
1210 platform_io.Platform_RenderWindow = ImGui_ImplOSPP_RenderWindow;
1211 platform_io.Platform_SwapBuffers = ImGui_ImplOSPP_SwapBuffers;
1212 platform_io.Platform_SetWindowAlpha = ImGui_ImplOSPP_SetWindowAlpha;
1213
1214 // Register main window handle (which is owned by the main application, not by us)
1215 // This is mostly for simplicity and consistency, so that our code (e.g. mouse handling etc.) can use same
1216 // logic for main and secondary viewports.
1217 ImGuiViewport* main_viewport = ImGui::GetMainViewport();
1219 vd->Window = window;
1220 vd->WindowOwned = false;
1221
1222 main_viewport->PlatformUserData = vd;
1223 main_viewport->PlatformHandle = ImGui_ImplOSPP_IdToHandle(window->get_window().get_id());
1224 main_viewport->PlatformHandleRaw = window->get_window().get_native_handle();
1225}
1226
1227static void ImGui_ImplOSPP_ShutdownPlatformInterface()
1228{
1229 ImGui::DestroyPlatformWindows();
1230}
1231
1232#if defined(__clang__)
1233#pragma clang diagnostic pop
1234#endif
event_type event
void ImGui_ImplOSPP_Shutdown()
auto ImGui_ImplOSPP_MapCursor(ImGuiMouseCursor cursor) -> os::cursor::type
void ImGui_ImplOSPP_RenderWindow(ImGuiViewport *viewport, void *rend_args)
void ImGui_ImplOSPP_SwapBuffers(ImGuiViewport *viewport, void *rend_args)
auto ImGui_ImplOSPP_IdToHandle(uint32_t id) -> void *
void ImGui_ImplOSPP_EndFrame()
auto ImGui_ImplOSPP_Init(unravel::render_window *window, ImGui_ImplOSPP_RenderWindow_Callback render_callback, ImGui_ImplOSPP_SwapBuffers_Callback swap_callback) -> bool
auto ImGui_IsAnyRealItemActive() -> bool
void ImGui_ImplOSPP_NewFrame(float delta_time)
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.