OXYGENHUB
◆ main openmsx / src / imgui / ImGuiLayer.cc
3.2 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
#include "ImGuiLayer.hh"
2
3
#include "ImGuiCpp.hh"
4
#include "ImGuiManager.hh"
5
6
#include "Keyboard.hh"
7
#include "MSXMotherBoard.hh"
8
#include "Reactor.hh"
9
10
#include <imgui.h>
11
#include <imgui_impl_opengl3.h>
12
#include <imgui_impl_sdl2.h>
13
#include <imgui_internal.h>
14
15
#include <SDL.h>
16
17
namespace openmsx {
18
19
ImGuiLayer::ImGuiLayer(ImGuiManager& manager_)
20
	: Layer(Layer::Coverage::PARTIAL, Layer::ZIndex::IMGUI)
21
	, manager(manager_)
22
{
23
}
24
25
void ImGuiLayer::paint(OutputSurface& /*surface*/)
26
{
27
	manager.preNewFrame();
28
29
	// Start the Dear ImGui frame
30
	ImGui_ImplOpenGL3_NewFrame();
31
	ImGui_ImplSDL2_NewFrame();
32
	ImGui::NewFrame();
33
34
	// Allow docking in main window
35
	auto* mainViewport = ImGui::GetMainViewport();
36
	auto dockspaceId = 0;
37
	im::StyleVar(ImGuiStyleVar_Alpha, /*transparent*/0.0f, [&]{
38
		dockspaceId = ImGui::DockSpaceOverViewport(0, mainViewport,
39
			ImGuiDockNodeFlags_NoDockingOverCentralNode |
40
			ImGuiDockNodeFlags_PassthruCentralNode |
41
			ImGuiDockNodeFlags_AutoHideTabBar);
42
	});
43
44
	// Main content window: focus target for the MSX display area.  Docked
45
	// into central node so it receives clicks there.  When focused, we
46
	// override WantCapture so input goes to the application (see
47
	// ImGuiManager).
48
	ImGui::SetNextWindowPos(mainViewport->Pos);
49
	ImGui::SetNextWindowSize(mainViewport->Size);
50
	auto flags = ImGuiWindowFlags_NoTitleBar |
51
			ImGuiWindowFlags_NoBackground |
52
			ImGuiWindowFlags_NoResize |
53
			ImGuiWindowFlags_NoMove |
54
			ImGuiWindowFlags_NoScrollbar |
55
			ImGuiWindowFlags_NoCollapse |
56
			ImGuiWindowFlags_NoBringToFrontOnFocus;
57
	bool focus = false;
58
	im::Window("MSX Display Area", nullptr, flags, [&]{
59
		// Ensure this window has focus on startup (after other windows are loaded)
60
		if (ImGui::GetFrameCount() == 1) {
61
			ImGui::SetWindowFocus();
62
		}
63
		// If no other window currently has focus, then take it ourselves.
64
		if (ImGui::GetCurrentContext()->NavWindow == nullptr) {
65
			ImGui::SetWindowFocus();
66
		}
67
68
		focus = ImGui::IsWindowFocused(ImGuiFocusedFlags_RootWindow);
69
		if (focus) {
70
			ImGui::SetNextFrameWantCaptureMouse(false);
71
			ImGui::SetNextFrameWantCaptureKeyboard(false);
72
		}
73
		if (auto* motherBoard = manager.getReactor().getMotherBoard()) {
74
			if (auto* keyb = motherBoard->getKeyboard()) {
75
				auto time = motherBoard->getCurrentTime();
76
				keyb->setFocus(focus, time);
77
			}
78
		}
79
	});
80
81
	manager.paintImGui(focus);
82
83
	// Rendering
84
	const ImGuiIO& io = ImGui::GetIO();
85
	ImGui::Render();
86
	ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
87
88
	// Update and Render additional Platform Windows
89
	// (Platform functions may change the current OpenGL context, so we
90
	// save/restore it to make it easier to paste this code elsewhere.
91
	if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) {
92
		SDL_Window* backup_current_window = SDL_GL_GetCurrentWindow();
93
		SDL_GLContext backup_current_context = SDL_GL_GetCurrentContext();
94
		ImGui::UpdatePlatformWindows();
95
		ImGui::RenderPlatformWindowsDefault();
96
		SDL_GL_MakeCurrent(backup_current_window, backup_current_context);
97
98
#ifdef __APPLE__
99
		if (ImGui::GetFrameCount() == 1) {
100
			// On startup, bring main openMSX window to front, which it doesn't
101
			// do it by itself due to creation of platform windows for viewports.
102
			SDL_RaiseWindow(SDL_GetWindowFromID(WindowEvent::getMainWindowId()));
103
		}
104
#endif
105
	}
106
}
107
108
} // namespace openmsx