| 
									
										
										
										
											2019-07-30 14:58:24 +08:00
										 |  |  | // Copyright (C) 2019 Nomango
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-17 16:55:47 +08:00
										 |  |  | #include <kiwano/core/Common.h>
 | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | #include <kiwano/core/event/KeyEvent.h>
 | 
					
						
							|  |  |  | #include <kiwano/core/event/MouseEvent.h>
 | 
					
						
							| 
									
										
										
										
											2019-11-13 14:33:15 +08:00
										 |  |  | #include <kiwano/platform/Window.h>
 | 
					
						
							|  |  |  | #include <kiwano/platform/Input.h>
 | 
					
						
							| 
									
										
										
										
											2020-01-17 16:55:47 +08:00
										 |  |  | #include <kiwano/render/Renderer.h>
 | 
					
						
							| 
									
										
										
										
											2019-10-11 21:55:29 +08:00
										 |  |  | #include <kiwano-imgui/ImGuiModule.h>
 | 
					
						
							|  |  |  | #include <kiwano-imgui/imgui_impl.h>
 | 
					
						
							| 
									
										
										
										
											2019-07-30 14:58:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace kiwano | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	namespace imgui | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		ImGuiModule::ImGuiModule() | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 			: target_window_(nullptr) | 
					
						
							| 
									
										
										
										
											2019-07-30 14:58:24 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-12 14:51:54 +08:00
										 |  |  | 		void ImGuiModule::SetupComponent() | 
					
						
							| 
									
										
										
										
											2019-07-30 14:58:24 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			// Setup Dear ImGui context
 | 
					
						
							|  |  |  | 			IMGUI_CHECKVERSION(); | 
					
						
							|  |  |  | 			ImGui::CreateContext(); | 
					
						
							|  |  |  | 			ImGuiIO& io = ImGui::GetIO(); (void)io; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// Setup Dear ImGui style
 | 
					
						
							|  |  |  | 			ImGui::StyleColorsDark(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// Setup Platform/Renderer bindings
 | 
					
						
							| 
									
										
										
										
											2020-01-17 11:24:24 +08:00
										 |  |  | 			target_window_ = Renderer::Instance().GetTargetWindow(); | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors;         // We can honor GetMouseCursor() values (optional)
 | 
					
						
							|  |  |  | 			io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos;          // We can honor io.WantSetMousePos requests (optional, rarely used)
 | 
					
						
							|  |  |  | 			io.BackendPlatformName = "imgui_impl_win32"; | 
					
						
							|  |  |  | 			io.ImeWindowHandle = target_window_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array that we will update during the application lifetime.
 | 
					
						
							| 
									
										
										
										
											2020-01-17 16:46:17 +08:00
										 |  |  | 			io.KeyMap[ImGuiKey_Tab] = (int)KeyCode::Tab; | 
					
						
							|  |  |  | 			io.KeyMap[ImGuiKey_LeftArrow] = (int)KeyCode::Left; | 
					
						
							|  |  |  | 			io.KeyMap[ImGuiKey_RightArrow] = (int)KeyCode::Right; | 
					
						
							|  |  |  | 			io.KeyMap[ImGuiKey_UpArrow] = (int)KeyCode::Up; | 
					
						
							|  |  |  | 			io.KeyMap[ImGuiKey_DownArrow] = (int)KeyCode::Down; | 
					
						
							|  |  |  | 			io.KeyMap[ImGuiKey_Delete] = (int)KeyCode::Delete; | 
					
						
							|  |  |  | 			io.KeyMap[ImGuiKey_Backspace] = (int)KeyCode::Back; | 
					
						
							|  |  |  | 			io.KeyMap[ImGuiKey_Space] = (int)KeyCode::Space; | 
					
						
							|  |  |  | 			io.KeyMap[ImGuiKey_Enter] = (int)KeyCode::Enter; | 
					
						
							|  |  |  | 			io.KeyMap[ImGuiKey_Escape] = (int)KeyCode::Esc; | 
					
						
							|  |  |  | 			io.KeyMap[ImGuiKey_A] = (int)KeyCode::A; | 
					
						
							|  |  |  | 			io.KeyMap[ImGuiKey_C] = (int)KeyCode::C; | 
					
						
							|  |  |  | 			io.KeyMap[ImGuiKey_V] = (int)KeyCode::V; | 
					
						
							|  |  |  | 			io.KeyMap[ImGuiKey_X] = (int)KeyCode::X; | 
					
						
							|  |  |  | 			io.KeyMap[ImGuiKey_Y] = (int)KeyCode::Y; | 
					
						
							|  |  |  | 			io.KeyMap[ImGuiKey_Z] = (int)KeyCode::Z; | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-17 11:24:24 +08:00
										 |  |  | 			ImGui_Impl_Init(Renderer::Instance()); | 
					
						
							| 
									
										
										
										
											2019-07-30 14:58:24 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		void ImGuiModule::DestroyComponent() | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			ImGui_Impl_Shutdown(); | 
					
						
							|  |  |  | 			ImGui::DestroyContext(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-12 14:51:54 +08:00
										 |  |  | 		void ImGuiModule::OnUpdate(Duration dt) | 
					
						
							| 
									
										
										
										
											2019-07-30 14:58:24 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			ImGuiIO& io = ImGui::GetIO(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// Setup time step
 | 
					
						
							| 
									
										
										
										
											2019-08-12 14:51:54 +08:00
										 |  |  | 			io.DeltaTime = dt.Seconds(); | 
					
						
							| 
									
										
										
										
											2019-07-30 14:58:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// Read keyboard modifiers inputs
 | 
					
						
							| 
									
										
										
										
											2020-01-17 11:24:24 +08:00
										 |  |  | 			io.KeyCtrl = Input::Instance().IsDown(KeyCode::Ctrl); | 
					
						
							|  |  |  | 			io.KeyShift = Input::Instance().IsDown(KeyCode::Shift); | 
					
						
							|  |  |  | 			io.KeyAlt = Input::Instance().IsDown(KeyCode::Alt); | 
					
						
							|  |  |  | 			io.KeySuper = Input::Instance().IsDown(KeyCode::Super); | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 			// io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the HandleEvent function below.
 | 
					
						
							| 
									
										
										
										
											2019-07-30 14:58:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// Update OS mouse position
 | 
					
						
							|  |  |  | 			UpdateMousePos(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// Update OS mouse cursor with the cursor requested by imgui
 | 
					
						
							|  |  |  | 			UpdateMouseCursor(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		void ImGuiModule::BeforeRender() | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			NewFrame(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		void ImGuiModule::AfterRender() | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			Render(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 		void ImGuiModule::HandleEvent(Event* evt) | 
					
						
							| 
									
										
										
										
											2019-07-30 14:58:24 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			if (ImGui::GetCurrentContext() == NULL) | 
					
						
							|  |  |  | 				return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			ImGuiIO& io = ImGui::GetIO(); | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 			if (evt->IsType<MouseEvent>()) | 
					
						
							| 
									
										
										
										
											2019-07-30 14:58:24 +08:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 				if (evt->IsType<MouseDownEvent>()) | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2020-01-17 16:46:17 +08:00
										 |  |  | 					MouseButton button = dynamic_cast<MouseDownEvent*>(evt)->button; | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 					int index = 0; | 
					
						
							|  |  |  | 					if		(button == MouseButton::Left) index = 0; | 
					
						
							|  |  |  | 					else if (button == MouseButton::Right) index = 1; | 
					
						
							|  |  |  | 					else if (button == MouseButton::Middle) index = 2; | 
					
						
							|  |  |  | 					io.MouseDown[index] = true; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else if (evt->IsType<MouseUpEvent>()) | 
					
						
							| 
									
										
										
										
											2019-07-30 14:58:24 +08:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2020-01-17 16:46:17 +08:00
										 |  |  | 					MouseButton button = dynamic_cast<MouseUpEvent*>(evt)->button; | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 					int index = 0; | 
					
						
							|  |  |  | 					if		(button == MouseButton::Left) index = 0; | 
					
						
							|  |  |  | 					else if (button == MouseButton::Right) index = 1; | 
					
						
							|  |  |  | 					else if (button == MouseButton::Middle) index = 2; | 
					
						
							|  |  |  | 					io.MouseDown[index] = false; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else if (evt->IsType<MouseWheelEvent>()) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					float wheel = dynamic_cast<MouseWheelEvent*>(evt)->wheel; | 
					
						
							|  |  |  | 					io.MouseWheel += wheel; | 
					
						
							| 
									
										
										
										
											2019-07-30 14:58:24 +08:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 			else if (evt->IsType<KeyEvent>()) | 
					
						
							| 
									
										
										
										
											2019-07-30 14:58:24 +08:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 				if (evt->IsType<KeyDownEvent>()) | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2020-01-17 16:46:17 +08:00
										 |  |  | 					KeyCode key = dynamic_cast<KeyDownEvent*>(evt)->code; | 
					
						
							|  |  |  | 					io.KeysDown[(int)key] = true; | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				else if (evt->IsType<KeyUpEvent>()) | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2020-01-17 16:46:17 +08:00
										 |  |  | 					KeyCode key = dynamic_cast<KeyUpEvent*>(evt)->code; | 
					
						
							|  |  |  | 					io.KeysDown[(int)key] = false; | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				else if (evt->IsType<KeyCharEvent>()) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					// You can also use ToAscii()+GetKeyboardState() to retrieve characters.
 | 
					
						
							|  |  |  | 					char ch = dynamic_cast<KeyCharEvent*>(evt)->value; | 
					
						
							|  |  |  | 					io.AddInputCharacter(static_cast<ImWchar>(ch)); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-07-30 14:58:24 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		void ImGuiModule::NewFrame() | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			ImGui_Impl_NewFrame(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			ImGuiIO& io = ImGui::GetIO(); | 
					
						
							|  |  |  | 			KGE_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built!"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// Setup display size (every frame to accommodate for window resizing)
 | 
					
						
							| 
									
										
										
										
											2020-01-17 11:24:24 +08:00
										 |  |  | 			Size display_size = Renderer::Instance().GetOutputSize(); | 
					
						
							| 
									
										
										
										
											2019-07-30 14:58:24 +08:00
										 |  |  | 			io.DisplaySize = ImVec2(display_size.x, display_size.y); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			ImGui::NewFrame(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		void ImGuiModule::Render() | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			ImGui::Render(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			ImGui_Impl_RenderDrawData(ImGui::GetDrawData()); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		void ImGuiModule::UpdateMousePos() | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			ImGuiIO& io = ImGui::GetIO(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
 | 
					
						
							|  |  |  | 			if (io.WantSetMousePos) | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2019-09-29 22:23:13 +08:00
										 |  |  | 				POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y }; | 
					
						
							| 
									
										
										
										
											2019-07-30 14:58:24 +08:00
										 |  |  | 				::ClientToScreen(target_window_, &pos); | 
					
						
							|  |  |  | 				::SetCursorPos(pos.x, pos.y); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-17 11:24:24 +08:00
										 |  |  | 			Point pos = Input::Instance().GetMousePos(); | 
					
						
							| 
									
										
										
										
											2019-07-30 14:58:24 +08:00
										 |  |  | 			io.MousePos = ImVec2(pos.x, pos.y); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		void ImGuiModule::UpdateMouseCursor() | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) | 
					
						
							|  |  |  | 				return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-21 16:33:41 +08:00
										 |  |  | 			CursorType cursor = CursorType::Arrow; | 
					
						
							| 
									
										
										
										
											2019-07-30 14:58:24 +08:00
										 |  |  | 			switch (ImGui::GetMouseCursor()) | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2019-08-21 16:33:41 +08:00
										 |  |  | 			case ImGuiMouseCursor_Arrow:        cursor = CursorType::Arrow; break; | 
					
						
							|  |  |  | 			case ImGuiMouseCursor_TextInput:    cursor = CursorType::TextInput; break; | 
					
						
							|  |  |  | 			case ImGuiMouseCursor_ResizeAll:    cursor = CursorType::SizeAll; break; | 
					
						
							|  |  |  | 			case ImGuiMouseCursor_ResizeEW:     cursor = CursorType::SizeWE; break; | 
					
						
							|  |  |  | 			case ImGuiMouseCursor_ResizeNS:     cursor = CursorType::SizeNS; break; | 
					
						
							|  |  |  | 			case ImGuiMouseCursor_ResizeNESW:   cursor = CursorType::SizeNESW; break; | 
					
						
							|  |  |  | 			case ImGuiMouseCursor_ResizeNWSE:   cursor = CursorType::SizeNWSE; break; | 
					
						
							|  |  |  | 			case ImGuiMouseCursor_Hand:         cursor = CursorType::Hand; break; | 
					
						
							| 
									
										
										
										
											2019-07-30 14:58:24 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-17 11:24:24 +08:00
										 |  |  | 			Window::Instance().SetCursor(cursor); | 
					
						
							| 
									
										
										
										
											2019-07-30 14:58:24 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-08-06 01:08:09 +08:00
										 |  |  | } |