ソースを参照

Viewport, Platform, Examples: Added support for transparent window via PlatformIO Platform_SetWindowAlpha (#1542) + fixes for GLFW 3.3

omar 7 年 前
コミット
72899318e6
4 ファイル変更41 行追加3 行削除
  1. 14 2
      examples/imgui_impl_glfw.cpp
  2. 19 0
      examples/imgui_impl_win32.cpp
  3. 5 0
      imgui.cpp
  4. 3 1
      imgui_internal.h

+ 14 - 2
examples/imgui_impl_glfw.cpp

@@ -39,6 +39,7 @@
 #else
 #define GLFW_HAS_GLFW_HOVERED   0
 #endif
+#define GLFW_HAS_WINDOW_ALPHA   (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+
 #define GLFW_HAS_VULKAN         (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+
 
 // Data
@@ -235,8 +236,8 @@ static void ImGui_ImplGlfw_UpdateMouse()
         }
 
 #if GLFW_HAS_GLFW_HOVERED
-        io.ConfigFlags |= ImGuiConfigFlags_PlatformHasMouseHoveredViewport;
-        if (glfwGetWindowAttrib(data->Window, GLFW_HOVERED) && !(viewport->Flags & ImGuiViewportFlags_NoInputs))
+        io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport;
+        if (glfwGetWindowAttrib(window, GLFW_HOVERED) && !(viewport->Flags & ImGuiViewportFlags_NoInputs))
             io.MouseHoveredViewport = viewport->ID;
 #endif
     }
@@ -469,6 +470,14 @@ static void ImGui_ImplGlfw_SetWindowTitle(ImGuiViewport* viewport, const char* t
     glfwSetWindowTitle(data->Window, title);
 }
 
+#if GLFW_HAS_WINDOW_ALPHA
+static void ImGui_ImplGlfw_SetWindowAlpha(ImGuiViewport* viewport, float alpha)
+{
+    ImGuiViewportDataGlfw* data = (ImGuiViewportDataGlfw*)viewport->PlatformUserData;
+    glfwSetWindowOpacity(data->Window, alpha);
+}
+#endif
+
 static void ImGui_ImplGlfw_RenderWindow(ImGuiViewport* viewport, void*)
 {
     ImGuiViewportDataGlfw* data = (ImGuiViewportDataGlfw*)viewport->PlatformUserData;
@@ -522,6 +531,9 @@ static void ImGui_ImplGlfw_InitPlatformInterface()
     platform_io.Platform_SetWindowTitle = ImGui_ImplGlfw_SetWindowTitle;
     platform_io.Platform_RenderWindow = ImGui_ImplGlfw_RenderWindow;
     platform_io.Platform_SwapBuffers = ImGui_ImplGlfw_SwapBuffers;
+#if GLFW_HAS_WINDOW_ALPHA
+    platform_io.Platform_SetWindowAlpha = ImGui_ImplGlfw_SetWindowAlpha;
+#endif
 #if GLFW_HAS_VULKAN
     platform_io.Platform_CreateVkSurface = ImGui_ImplGlfw_CreateVkSurface;
 #endif

+ 19 - 0
examples/imgui_impl_win32.cpp

@@ -472,6 +472,24 @@ static void ImGui_ImplWin32_SetWindowTitle(ImGuiViewport* viewport, const char*
     ::SetWindowTextA(data->Hwnd, title);
 }
 
+static void ImGui_ImplWin32_SetWindowAlpha(ImGuiViewport* viewport, float alpha)
+{
+    ImGuiViewportDataWin32* data = (ImGuiViewportDataWin32*)viewport->PlatformUserData;
+    IM_ASSERT(data->Hwnd != 0);
+    IM_ASSERT(alpha >= 0.0f && alpha <= 1.0f);
+    if (alpha < 1.0f)
+    {
+        DWORD style = ::GetWindowLongW(data->Hwnd, GWL_EXSTYLE) | WS_EX_LAYERED;
+        ::SetWindowLongW(data->Hwnd, GWL_EXSTYLE, style);
+        ::SetLayeredWindowAttributes(data->Hwnd, 0, (BYTE)(255 * alpha), LWA_ALPHA);
+    }
+    else
+    {
+        DWORD style = ::GetWindowLongW(data->Hwnd, GWL_EXSTYLE) & ~WS_EX_LAYERED;
+        ::SetWindowLongW(data->Hwnd, GWL_EXSTYLE, style);
+    }
+}
+
 static float ImGui_ImplWin32_GetWindowDpiScale(ImGuiViewport* viewport)
 {
     ImGuiViewportDataWin32* data = (ImGuiViewportDataWin32*)viewport->PlatformUserData;
@@ -543,6 +561,7 @@ static void ImGui_ImplWin32_InitPlatformInterface()
     platform_io.Platform_SetWindowSize = ImGui_ImplWin32_SetWindowSize;
     platform_io.Platform_GetWindowSize = ImGui_ImplWin32_GetWindowSize;
     platform_io.Platform_SetWindowTitle = ImGui_ImplWin32_SetWindowTitle;
+    platform_io.Platform_SetWindowAlpha = ImGui_ImplWin32_SetWindowAlpha;
     platform_io.Platform_GetWindowDpiScale = ImGui_ImplWin32_GetWindowDpiScale;
 
     // Register main window handle

+ 5 - 0
imgui.cpp

@@ -3578,6 +3578,11 @@ void ImGui::UpdatePlatformWindows()
             ImGui::MemFree(title_displayed);
         }
 
+        // Update alpha
+        if (viewport->LastAlpha != viewport->Alpha && g.PlatformIO.Platform_SetWindowAlpha)
+            g.PlatformIO.Platform_SetWindowAlpha(viewport, viewport->Alpha);
+        viewport->LastAlpha = viewport->Alpha;
+
         // Show window. On startup ensure platform window don't get focus.
         if (is_new_window)
         {

+ 3 - 1
imgui_internal.h

@@ -517,13 +517,15 @@ struct ImGuiViewportP : public ImGuiViewport
     int                 LastFrameActive;          // Last frame number this viewport was activated by a window
     int                 LastFrameAsRefViewport;   // Last frame number this viewport was io.MouseViewportRef
     ImGuiID             LastNameHash;
+    float               Alpha;                    // Window opacity (when dragging dockable windows/viewports we make them transparent)
+    float               LastAlpha;
     ImGuiWindow*        Window;
     ImDrawList*         OverlayDrawList;          // For convenience, a draw list we can render to that's always rendered last (we use it to draw software mouse cursor when io.MouseDrawCursor is set)
     ImDrawData          DrawDataP;
     ImDrawDataBuilder   DrawDataBuilder;
     ImVec2              RendererLastSize;
 
-    ImGuiViewportP(ImDrawListSharedData* draw_list_shared_data) { Idx = 1; LastFrameActive = LastFrameAsRefViewport = -1; LastNameHash = 0; Window = NULL; OverlayDrawList = IM_NEW(ImDrawList)(draw_list_shared_data); OverlayDrawList->_OwnerName = "##Overlay"; RendererLastSize = ImVec2(-1.0f,-1.0f); }
+    ImGuiViewportP(ImDrawListSharedData* draw_list_shared_data) { Idx = 1; LastFrameActive = LastFrameAsRefViewport = -1; LastNameHash = 0; Alpha = LastAlpha = 1.0f; Window = NULL; OverlayDrawList = IM_NEW(ImDrawList)(draw_list_shared_data); OverlayDrawList->_OwnerName = "##Overlay"; RendererLastSize = ImVec2(-1.0f,-1.0f); }
     ~ImGuiViewportP()        { IM_DELETE(OverlayDrawList); }
     ImRect  GetRect() const  { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); }
     float   GetNextX() const { const float SPACING = 4.0f; return Pos.x + Size.x + SPACING; }