diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index f85edf9..816e562 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -225,49 +225,66 @@ ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } -IMGUI_API LRESULT ImGui_ImplDX10_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index f85edf9..816e562 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -225,49 +225,66 @@ ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } -IMGUI_API LRESULT ImGui_ImplDX10_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index 4675a21..ea69074 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -74,10 +74,10 @@ if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } } -extern LRESULT ImGui_ImplDX10_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX10_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index f85edf9..816e562 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -225,49 +225,66 @@ ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } -IMGUI_API LRESULT ImGui_ImplDX10_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index 4675a21..ea69074 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -74,10 +74,10 @@ if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } } -extern LRESULT ImGui_ImplDX10_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX10_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 49a4aa4..7b3a3ba 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -232,49 +232,66 @@ ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } -IMGUI_API LRESULT ImGui_ImplDX11_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index f85edf9..816e562 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -225,49 +225,66 @@ ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } -IMGUI_API LRESULT ImGui_ImplDX10_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index 4675a21..ea69074 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -74,10 +74,10 @@ if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } } -extern LRESULT ImGui_ImplDX10_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX10_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 49a4aa4..7b3a3ba 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -232,49 +232,66 @@ ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } -IMGUI_API LRESULT ImGui_ImplDX11_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index 0432161..794503e 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -77,10 +77,10 @@ if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } } -extern LRESULT ImGui_ImplDX11_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX11_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index f85edf9..816e562 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -225,49 +225,66 @@ ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } -IMGUI_API LRESULT ImGui_ImplDX10_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index 4675a21..ea69074 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -74,10 +74,10 @@ if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } } -extern LRESULT ImGui_ImplDX10_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX10_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 49a4aa4..7b3a3ba 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -232,49 +232,66 @@ ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } -IMGUI_API LRESULT ImGui_ImplDX11_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index 0432161..794503e 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -77,10 +77,10 @@ if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } } -extern LRESULT ImGui_ImplDX11_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX11_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index 4901201..fc05c9c 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -171,49 +171,67 @@ d3d9_state_block->Release(); } -IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +// We use Win32 SetCapture/ReleaseCapture() API to enable reading the mouse outside our Windows bounds. +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index f85edf9..816e562 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -225,49 +225,66 @@ ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } -IMGUI_API LRESULT ImGui_ImplDX10_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index 4675a21..ea69074 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -74,10 +74,10 @@ if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } } -extern LRESULT ImGui_ImplDX10_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX10_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 49a4aa4..7b3a3ba 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -232,49 +232,66 @@ ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } -IMGUI_API LRESULT ImGui_ImplDX11_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index 0432161..794503e 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -77,10 +77,10 @@ if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } } -extern LRESULT ImGui_ImplDX11_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX11_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index 4901201..fc05c9c 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -171,49 +171,67 @@ d3d9_state_block->Release(); } -IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +// We use Win32 SetCapture/ReleaseCapture() API to enable reading the mouse outside our Windows bounds. +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index b8e5907..6a359c6 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -12,10 +12,10 @@ static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; static D3DPRESENT_PARAMETERS g_d3dpp; -extern LRESULT ImGui_ImplDX9_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX9_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index f85edf9..816e562 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -225,49 +225,66 @@ ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } -IMGUI_API LRESULT ImGui_ImplDX10_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index 4675a21..ea69074 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -74,10 +74,10 @@ if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } } -extern LRESULT ImGui_ImplDX10_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX10_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 49a4aa4..7b3a3ba 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -232,49 +232,66 @@ ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } -IMGUI_API LRESULT ImGui_ImplDX11_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index 0432161..794503e 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -77,10 +77,10 @@ if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } } -extern LRESULT ImGui_ImplDX11_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX11_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index 4901201..fc05c9c 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -171,49 +171,67 @@ d3d9_state_block->Release(); } -IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +// We use Win32 SetCapture/ReleaseCapture() API to enable reading the mouse outside our Windows bounds. +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index b8e5907..6a359c6 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -12,10 +12,10 @@ static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; static D3DPRESENT_PARAMETERS g_d3dpp; -extern LRESULT ImGui_ImplDX9_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX9_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp index 236a2d1..4aed20a 100644 --- a/examples/opengl2_example/imgui_impl_glfw.cpp +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -26,7 +26,7 @@ // Data static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; +static bool g_MouseJustPressed[3] = { false, false, false }; static float g_MouseWheel = 0.0f; static GLuint g_FontTexture = 0; @@ -129,7 +129,7 @@ void ImGui_ImplGlfwGL2_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) { if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; + g_MouseJustPressed[button] = true; } void ImGui_ImplGlfwGL2_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) @@ -287,8 +287,9 @@ for (int i = 0; i < 3; i++) { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. - g_MousePressed[i] = false; + // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. + io.MouseDown[i] = g_MouseJustPressed[i] || glfwGetMouseButton(g_Window, i) != 0; + g_MouseJustPressed[i] = false; } io.MouseWheel = g_MouseWheel; diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index f85edf9..816e562 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -225,49 +225,66 @@ ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } -IMGUI_API LRESULT ImGui_ImplDX10_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index 4675a21..ea69074 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -74,10 +74,10 @@ if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } } -extern LRESULT ImGui_ImplDX10_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX10_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 49a4aa4..7b3a3ba 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -232,49 +232,66 @@ ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } -IMGUI_API LRESULT ImGui_ImplDX11_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index 0432161..794503e 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -77,10 +77,10 @@ if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } } -extern LRESULT ImGui_ImplDX11_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX11_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index 4901201..fc05c9c 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -171,49 +171,67 @@ d3d9_state_block->Release(); } -IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +// We use Win32 SetCapture/ReleaseCapture() API to enable reading the mouse outside our Windows bounds. +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index b8e5907..6a359c6 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -12,10 +12,10 @@ static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; static D3DPRESENT_PARAMETERS g_d3dpp; -extern LRESULT ImGui_ImplDX9_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX9_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp index 236a2d1..4aed20a 100644 --- a/examples/opengl2_example/imgui_impl_glfw.cpp +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -26,7 +26,7 @@ // Data static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; +static bool g_MouseJustPressed[3] = { false, false, false }; static float g_MouseWheel = 0.0f; static GLuint g_FontTexture = 0; @@ -129,7 +129,7 @@ void ImGui_ImplGlfwGL2_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) { if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; + g_MouseJustPressed[button] = true; } void ImGui_ImplGlfwGL2_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) @@ -287,8 +287,9 @@ for (int i = 0; i < 3; i++) { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. - g_MousePressed[i] = false; + // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. + io.MouseDown[i] = g_MouseJustPressed[i] || glfwGetMouseButton(g_Window, i) != 0; + g_MouseJustPressed[i] = false; } io.MouseWheel = g_MouseWheel; diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index ac711b9..3611d6e 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -22,7 +22,7 @@ // Data static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; +static bool g_MouseJustPressed[3] = { false, false, false }; static float g_MouseWheel = 0.0f; static GLuint g_FontTexture = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; @@ -150,7 +150,7 @@ void ImGui_ImplGlfwGL3_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) { if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; + g_MouseJustPressed[button] = true; } void ImGui_ImplGlfwGL3_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) @@ -401,8 +401,9 @@ for (int i = 0; i < 3; i++) { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. - g_MousePressed[i] = false; + // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. + io.MouseDown[i] = g_MouseJustPressed[i] || glfwGetMouseButton(g_Window, i) != 0; + g_MouseJustPressed[i] = false; } io.MouseWheel = g_MouseWheel; diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index f85edf9..816e562 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -225,49 +225,66 @@ ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } -IMGUI_API LRESULT ImGui_ImplDX10_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index 4675a21..ea69074 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -74,10 +74,10 @@ if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } } -extern LRESULT ImGui_ImplDX10_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX10_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 49a4aa4..7b3a3ba 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -232,49 +232,66 @@ ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } -IMGUI_API LRESULT ImGui_ImplDX11_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index 0432161..794503e 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -77,10 +77,10 @@ if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } } -extern LRESULT ImGui_ImplDX11_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX11_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index 4901201..fc05c9c 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -171,49 +171,67 @@ d3d9_state_block->Release(); } -IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +// We use Win32 SetCapture/ReleaseCapture() API to enable reading the mouse outside our Windows bounds. +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index b8e5907..6a359c6 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -12,10 +12,10 @@ static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; static D3DPRESENT_PARAMETERS g_d3dpp; -extern LRESULT ImGui_ImplDX9_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX9_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp index 236a2d1..4aed20a 100644 --- a/examples/opengl2_example/imgui_impl_glfw.cpp +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -26,7 +26,7 @@ // Data static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; +static bool g_MouseJustPressed[3] = { false, false, false }; static float g_MouseWheel = 0.0f; static GLuint g_FontTexture = 0; @@ -129,7 +129,7 @@ void ImGui_ImplGlfwGL2_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) { if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; + g_MouseJustPressed[button] = true; } void ImGui_ImplGlfwGL2_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) @@ -287,8 +287,9 @@ for (int i = 0; i < 3; i++) { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. - g_MousePressed[i] = false; + // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. + io.MouseDown[i] = g_MouseJustPressed[i] || glfwGetMouseButton(g_Window, i) != 0; + g_MouseJustPressed[i] = false; } io.MouseWheel = g_MouseWheel; diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index ac711b9..3611d6e 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -22,7 +22,7 @@ // Data static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; +static bool g_MouseJustPressed[3] = { false, false, false }; static float g_MouseWheel = 0.0f; static GLuint g_FontTexture = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; @@ -150,7 +150,7 @@ void ImGui_ImplGlfwGL3_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) { if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; + g_MouseJustPressed[button] = true; } void ImGui_ImplGlfwGL3_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) @@ -401,8 +401,9 @@ for (int i = 0; i < 3; i++) { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. - g_MousePressed[i] = false; + // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. + io.MouseDown[i] = g_MouseJustPressed[i] || glfwGetMouseButton(g_Window, i) != 0; + g_MouseJustPressed[i] = false; } io.MouseWheel = g_MouseWheel; diff --git a/imgui.cpp b/imgui.cpp index 62d4e8f..8edb691 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10208,23 +10208,38 @@ return false; ImGuiContext& g = *GImGui; + ImGuiStyle& style = g.Style; ImVec2 pos = window->DC.CursorPos; ImVec2 label_size = CalcTextSize(label, NULL, true); - ImVec2 shortcut_size = shortcut ? CalcTextSize(shortcut, NULL) : ImVec2(0.0f, 0.0f); - float w = window->MenuColumns.DeclColumns(label_size.x, shortcut_size.x, (float)(int)(g.FontSize * 1.20f)); // Feedback for next frame - float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w); - bool pressed = Selectable(label, false, ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DrawFillAvailWidth | (enabled ? 0 : ImGuiSelectableFlags_Disabled), ImVec2(w, 0.0f)); - if (shortcut_size.x > 0.0f) + ImGuiSelectableFlags flags = ImGuiSelectableFlags_MenuItem | (enabled ? 0 : ImGuiSelectableFlags_Disabled); + bool pressed; + if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) { - PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); - RenderText(pos + ImVec2(window->MenuColumns.Pos[1] + extra_w, 0.0f), shortcut, NULL, false); - PopStyleColor(); + // Mimic the exact layout spacing of BeginMenu() to allow MenuItem() inside a menu bar, which is a little misleading but may be useful + // Note that in this situation we render neither the shortcut neither the selected tick mark + float w = label_size.x; + window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f); + PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing * 2.0f); + pressed = Selectable(label, false, flags, ImVec2(w, 0.0f)); + PopStyleVar(); + window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar(). } - - if (selected) - RenderCheckMark(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * (0.20f+0.200f), g.FontSize * 0.134f * 0.5f), GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled), g.FontSize * 0.866f); - + else + { + ImVec2 shortcut_size = shortcut ? CalcTextSize(shortcut, NULL) : ImVec2(0.0f, 0.0f); + float w = window->MenuColumns.DeclColumns(label_size.x, shortcut_size.x, (float)(int)(g.FontSize * 1.20f)); // Feedback for next frame + float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w); + pressed = Selectable(label, false, flags | ImGuiSelectableFlags_DrawFillAvailWidth, ImVec2(w, 0.0f)); + if (shortcut_size.x > 0.0f) + { + PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); + RenderText(pos + ImVec2(window->MenuColumns.Pos[1] + extra_w, 0.0f), shortcut, NULL, false); + PopStyleColor(); + } + if (selected) + RenderCheckMark(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * (0.20f+0.200f), g.FontSize * 0.134f * 0.5f), GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled), g.FontSize * 0.866f); + } return pressed; } diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index f85edf9..816e562 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -225,49 +225,66 @@ ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } -IMGUI_API LRESULT ImGui_ImplDX10_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index 4675a21..ea69074 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -74,10 +74,10 @@ if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } } -extern LRESULT ImGui_ImplDX10_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX10_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 49a4aa4..7b3a3ba 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -232,49 +232,66 @@ ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } -IMGUI_API LRESULT ImGui_ImplDX11_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index 0432161..794503e 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -77,10 +77,10 @@ if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } } -extern LRESULT ImGui_ImplDX11_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX11_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index 4901201..fc05c9c 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -171,49 +171,67 @@ d3d9_state_block->Release(); } -IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +// We use Win32 SetCapture/ReleaseCapture() API to enable reading the mouse outside our Windows bounds. +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index b8e5907..6a359c6 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -12,10 +12,10 @@ static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; static D3DPRESENT_PARAMETERS g_d3dpp; -extern LRESULT ImGui_ImplDX9_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX9_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp index 236a2d1..4aed20a 100644 --- a/examples/opengl2_example/imgui_impl_glfw.cpp +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -26,7 +26,7 @@ // Data static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; +static bool g_MouseJustPressed[3] = { false, false, false }; static float g_MouseWheel = 0.0f; static GLuint g_FontTexture = 0; @@ -129,7 +129,7 @@ void ImGui_ImplGlfwGL2_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) { if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; + g_MouseJustPressed[button] = true; } void ImGui_ImplGlfwGL2_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) @@ -287,8 +287,9 @@ for (int i = 0; i < 3; i++) { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. - g_MousePressed[i] = false; + // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. + io.MouseDown[i] = g_MouseJustPressed[i] || glfwGetMouseButton(g_Window, i) != 0; + g_MouseJustPressed[i] = false; } io.MouseWheel = g_MouseWheel; diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index ac711b9..3611d6e 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -22,7 +22,7 @@ // Data static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; +static bool g_MouseJustPressed[3] = { false, false, false }; static float g_MouseWheel = 0.0f; static GLuint g_FontTexture = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; @@ -150,7 +150,7 @@ void ImGui_ImplGlfwGL3_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) { if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; + g_MouseJustPressed[button] = true; } void ImGui_ImplGlfwGL3_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) @@ -401,8 +401,9 @@ for (int i = 0; i < 3; i++) { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. - g_MousePressed[i] = false; + // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. + io.MouseDown[i] = g_MouseJustPressed[i] || glfwGetMouseButton(g_Window, i) != 0; + g_MouseJustPressed[i] = false; } io.MouseWheel = g_MouseWheel; diff --git a/imgui.cpp b/imgui.cpp index 62d4e8f..8edb691 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10208,23 +10208,38 @@ return false; ImGuiContext& g = *GImGui; + ImGuiStyle& style = g.Style; ImVec2 pos = window->DC.CursorPos; ImVec2 label_size = CalcTextSize(label, NULL, true); - ImVec2 shortcut_size = shortcut ? CalcTextSize(shortcut, NULL) : ImVec2(0.0f, 0.0f); - float w = window->MenuColumns.DeclColumns(label_size.x, shortcut_size.x, (float)(int)(g.FontSize * 1.20f)); // Feedback for next frame - float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w); - bool pressed = Selectable(label, false, ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DrawFillAvailWidth | (enabled ? 0 : ImGuiSelectableFlags_Disabled), ImVec2(w, 0.0f)); - if (shortcut_size.x > 0.0f) + ImGuiSelectableFlags flags = ImGuiSelectableFlags_MenuItem | (enabled ? 0 : ImGuiSelectableFlags_Disabled); + bool pressed; + if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) { - PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); - RenderText(pos + ImVec2(window->MenuColumns.Pos[1] + extra_w, 0.0f), shortcut, NULL, false); - PopStyleColor(); + // Mimic the exact layout spacing of BeginMenu() to allow MenuItem() inside a menu bar, which is a little misleading but may be useful + // Note that in this situation we render neither the shortcut neither the selected tick mark + float w = label_size.x; + window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f); + PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing * 2.0f); + pressed = Selectable(label, false, flags, ImVec2(w, 0.0f)); + PopStyleVar(); + window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar(). } - - if (selected) - RenderCheckMark(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * (0.20f+0.200f), g.FontSize * 0.134f * 0.5f), GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled), g.FontSize * 0.866f); - + else + { + ImVec2 shortcut_size = shortcut ? CalcTextSize(shortcut, NULL) : ImVec2(0.0f, 0.0f); + float w = window->MenuColumns.DeclColumns(label_size.x, shortcut_size.x, (float)(int)(g.FontSize * 1.20f)); // Feedback for next frame + float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w); + pressed = Selectable(label, false, flags | ImGuiSelectableFlags_DrawFillAvailWidth, ImVec2(w, 0.0f)); + if (shortcut_size.x > 0.0f) + { + PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); + RenderText(pos + ImVec2(window->MenuColumns.Pos[1] + extra_w, 0.0f), shortcut, NULL, false); + PopStyleColor(); + } + if (selected) + RenderCheckMark(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * (0.20f+0.200f), g.FontSize * 0.134f * 0.5f), GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled), g.FontSize * 0.866f); + } return pressed; } diff --git a/imgui.h b/imgui.h index 3e2ab62..76d90e7 100644 --- a/imgui.h +++ b/imgui.h @@ -1548,7 +1548,7 @@ // Methods IMGUI_API ImFont(); IMGUI_API ~ImFont(); - IMGUI_API void Clear(); + IMGUI_API void ClearOutputData(); IMGUI_API void BuildLookupTable(); IMGUI_API const ImFontGlyph*FindGlyph(ImWchar c) const; IMGUI_API void SetFallbackChar(ImWchar c); diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index f85edf9..816e562 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -225,49 +225,66 @@ ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } -IMGUI_API LRESULT ImGui_ImplDX10_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index 4675a21..ea69074 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -74,10 +74,10 @@ if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } } -extern LRESULT ImGui_ImplDX10_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX10_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 49a4aa4..7b3a3ba 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -232,49 +232,66 @@ ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } -IMGUI_API LRESULT ImGui_ImplDX11_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index 0432161..794503e 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -77,10 +77,10 @@ if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } } -extern LRESULT ImGui_ImplDX11_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX11_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index 4901201..fc05c9c 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -171,49 +171,67 @@ d3d9_state_block->Release(); } -IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +// We use Win32 SetCapture/ReleaseCapture() API to enable reading the mouse outside our Windows bounds. +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index b8e5907..6a359c6 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -12,10 +12,10 @@ static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; static D3DPRESENT_PARAMETERS g_d3dpp; -extern LRESULT ImGui_ImplDX9_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX9_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp index 236a2d1..4aed20a 100644 --- a/examples/opengl2_example/imgui_impl_glfw.cpp +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -26,7 +26,7 @@ // Data static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; +static bool g_MouseJustPressed[3] = { false, false, false }; static float g_MouseWheel = 0.0f; static GLuint g_FontTexture = 0; @@ -129,7 +129,7 @@ void ImGui_ImplGlfwGL2_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) { if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; + g_MouseJustPressed[button] = true; } void ImGui_ImplGlfwGL2_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) @@ -287,8 +287,9 @@ for (int i = 0; i < 3; i++) { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. - g_MousePressed[i] = false; + // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. + io.MouseDown[i] = g_MouseJustPressed[i] || glfwGetMouseButton(g_Window, i) != 0; + g_MouseJustPressed[i] = false; } io.MouseWheel = g_MouseWheel; diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index ac711b9..3611d6e 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -22,7 +22,7 @@ // Data static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; +static bool g_MouseJustPressed[3] = { false, false, false }; static float g_MouseWheel = 0.0f; static GLuint g_FontTexture = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; @@ -150,7 +150,7 @@ void ImGui_ImplGlfwGL3_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) { if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; + g_MouseJustPressed[button] = true; } void ImGui_ImplGlfwGL3_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) @@ -401,8 +401,9 @@ for (int i = 0; i < 3; i++) { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. - g_MousePressed[i] = false; + // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. + io.MouseDown[i] = g_MouseJustPressed[i] || glfwGetMouseButton(g_Window, i) != 0; + g_MouseJustPressed[i] = false; } io.MouseWheel = g_MouseWheel; diff --git a/imgui.cpp b/imgui.cpp index 62d4e8f..8edb691 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10208,23 +10208,38 @@ return false; ImGuiContext& g = *GImGui; + ImGuiStyle& style = g.Style; ImVec2 pos = window->DC.CursorPos; ImVec2 label_size = CalcTextSize(label, NULL, true); - ImVec2 shortcut_size = shortcut ? CalcTextSize(shortcut, NULL) : ImVec2(0.0f, 0.0f); - float w = window->MenuColumns.DeclColumns(label_size.x, shortcut_size.x, (float)(int)(g.FontSize * 1.20f)); // Feedback for next frame - float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w); - bool pressed = Selectable(label, false, ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DrawFillAvailWidth | (enabled ? 0 : ImGuiSelectableFlags_Disabled), ImVec2(w, 0.0f)); - if (shortcut_size.x > 0.0f) + ImGuiSelectableFlags flags = ImGuiSelectableFlags_MenuItem | (enabled ? 0 : ImGuiSelectableFlags_Disabled); + bool pressed; + if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) { - PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); - RenderText(pos + ImVec2(window->MenuColumns.Pos[1] + extra_w, 0.0f), shortcut, NULL, false); - PopStyleColor(); + // Mimic the exact layout spacing of BeginMenu() to allow MenuItem() inside a menu bar, which is a little misleading but may be useful + // Note that in this situation we render neither the shortcut neither the selected tick mark + float w = label_size.x; + window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f); + PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing * 2.0f); + pressed = Selectable(label, false, flags, ImVec2(w, 0.0f)); + PopStyleVar(); + window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar(). } - - if (selected) - RenderCheckMark(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * (0.20f+0.200f), g.FontSize * 0.134f * 0.5f), GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled), g.FontSize * 0.866f); - + else + { + ImVec2 shortcut_size = shortcut ? CalcTextSize(shortcut, NULL) : ImVec2(0.0f, 0.0f); + float w = window->MenuColumns.DeclColumns(label_size.x, shortcut_size.x, (float)(int)(g.FontSize * 1.20f)); // Feedback for next frame + float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w); + pressed = Selectable(label, false, flags | ImGuiSelectableFlags_DrawFillAvailWidth, ImVec2(w, 0.0f)); + if (shortcut_size.x > 0.0f) + { + PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); + RenderText(pos + ImVec2(window->MenuColumns.Pos[1] + extra_w, 0.0f), shortcut, NULL, false); + PopStyleColor(); + } + if (selected) + RenderCheckMark(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * (0.20f+0.200f), g.FontSize * 0.134f * 0.5f), GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled), g.FontSize * 0.866f); + } return pressed; } diff --git a/imgui.h b/imgui.h index 3e2ab62..76d90e7 100644 --- a/imgui.h +++ b/imgui.h @@ -1548,7 +1548,7 @@ // Methods IMGUI_API ImFont(); IMGUI_API ~ImFont(); - IMGUI_API void Clear(); + IMGUI_API void ClearOutputData(); IMGUI_API void BuildLookupTable(); IMGUI_API const ImFontGlyph*FindGlyph(ImWchar c) const; IMGUI_API void SetFallbackChar(ImWchar c); diff --git a/imgui_demo.cpp b/imgui_demo.cpp index b8d643b..b464a35 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1989,6 +1989,7 @@ for (int i = 0; i < atlas->Fonts.Size; i++) { ImFont* font = atlas->Fonts[i]; + ImGui::PushID(font); bool font_details_opened = ImGui::TreeNode(font, "Font %d: \'%s\', %.2f px, %d glyphs", i, font->ConfigData ? font->ConfigData[0].Name : "", font->FontSize, font->Glyphs.Size); ImGui::SameLine(); if (ImGui::SmallButton("Set as default")) ImGui::GetIO().FontDefault = font; if (font_details_opened) @@ -2049,6 +2050,7 @@ } ImGui::TreePop(); } + ImGui::PopID(); } static float window_scale = 1.0f; ImGui::DragFloat("this window scale", &window_scale, 0.005f, 0.3f, 2.0f, "%.1f"); // scale only this window diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index f85edf9..816e562 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -225,49 +225,66 @@ ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } -IMGUI_API LRESULT ImGui_ImplDX10_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index 4675a21..ea69074 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -74,10 +74,10 @@ if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } } -extern LRESULT ImGui_ImplDX10_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX10_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 49a4aa4..7b3a3ba 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -232,49 +232,66 @@ ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } -IMGUI_API LRESULT ImGui_ImplDX11_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index 0432161..794503e 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -77,10 +77,10 @@ if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } } -extern LRESULT ImGui_ImplDX11_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX11_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index 4901201..fc05c9c 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -171,49 +171,67 @@ d3d9_state_block->Release(); } -IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +// We use Win32 SetCapture/ReleaseCapture() API to enable reading the mouse outside our Windows bounds. +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return 0; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; - return true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index b8e5907..6a359c6 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -12,10 +12,10 @@ static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; static D3DPRESENT_PARAMETERS g_d3dpp; -extern LRESULT ImGui_ImplDX9_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX9_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp index 236a2d1..4aed20a 100644 --- a/examples/opengl2_example/imgui_impl_glfw.cpp +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -26,7 +26,7 @@ // Data static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; +static bool g_MouseJustPressed[3] = { false, false, false }; static float g_MouseWheel = 0.0f; static GLuint g_FontTexture = 0; @@ -129,7 +129,7 @@ void ImGui_ImplGlfwGL2_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) { if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; + g_MouseJustPressed[button] = true; } void ImGui_ImplGlfwGL2_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) @@ -287,8 +287,9 @@ for (int i = 0; i < 3; i++) { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. - g_MousePressed[i] = false; + // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. + io.MouseDown[i] = g_MouseJustPressed[i] || glfwGetMouseButton(g_Window, i) != 0; + g_MouseJustPressed[i] = false; } io.MouseWheel = g_MouseWheel; diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index ac711b9..3611d6e 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -22,7 +22,7 @@ // Data static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; +static bool g_MouseJustPressed[3] = { false, false, false }; static float g_MouseWheel = 0.0f; static GLuint g_FontTexture = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; @@ -150,7 +150,7 @@ void ImGui_ImplGlfwGL3_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) { if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; + g_MouseJustPressed[button] = true; } void ImGui_ImplGlfwGL3_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) @@ -401,8 +401,9 @@ for (int i = 0; i < 3; i++) { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. - g_MousePressed[i] = false; + // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. + io.MouseDown[i] = g_MouseJustPressed[i] || glfwGetMouseButton(g_Window, i) != 0; + g_MouseJustPressed[i] = false; } io.MouseWheel = g_MouseWheel; diff --git a/imgui.cpp b/imgui.cpp index 62d4e8f..8edb691 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10208,23 +10208,38 @@ return false; ImGuiContext& g = *GImGui; + ImGuiStyle& style = g.Style; ImVec2 pos = window->DC.CursorPos; ImVec2 label_size = CalcTextSize(label, NULL, true); - ImVec2 shortcut_size = shortcut ? CalcTextSize(shortcut, NULL) : ImVec2(0.0f, 0.0f); - float w = window->MenuColumns.DeclColumns(label_size.x, shortcut_size.x, (float)(int)(g.FontSize * 1.20f)); // Feedback for next frame - float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w); - bool pressed = Selectable(label, false, ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DrawFillAvailWidth | (enabled ? 0 : ImGuiSelectableFlags_Disabled), ImVec2(w, 0.0f)); - if (shortcut_size.x > 0.0f) + ImGuiSelectableFlags flags = ImGuiSelectableFlags_MenuItem | (enabled ? 0 : ImGuiSelectableFlags_Disabled); + bool pressed; + if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) { - PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); - RenderText(pos + ImVec2(window->MenuColumns.Pos[1] + extra_w, 0.0f), shortcut, NULL, false); - PopStyleColor(); + // Mimic the exact layout spacing of BeginMenu() to allow MenuItem() inside a menu bar, which is a little misleading but may be useful + // Note that in this situation we render neither the shortcut neither the selected tick mark + float w = label_size.x; + window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f); + PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing * 2.0f); + pressed = Selectable(label, false, flags, ImVec2(w, 0.0f)); + PopStyleVar(); + window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar(). } - - if (selected) - RenderCheckMark(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * (0.20f+0.200f), g.FontSize * 0.134f * 0.5f), GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled), g.FontSize * 0.866f); - + else + { + ImVec2 shortcut_size = shortcut ? CalcTextSize(shortcut, NULL) : ImVec2(0.0f, 0.0f); + float w = window->MenuColumns.DeclColumns(label_size.x, shortcut_size.x, (float)(int)(g.FontSize * 1.20f)); // Feedback for next frame + float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w); + pressed = Selectable(label, false, flags | ImGuiSelectableFlags_DrawFillAvailWidth, ImVec2(w, 0.0f)); + if (shortcut_size.x > 0.0f) + { + PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); + RenderText(pos + ImVec2(window->MenuColumns.Pos[1] + extra_w, 0.0f), shortcut, NULL, false); + PopStyleColor(); + } + if (selected) + RenderCheckMark(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * (0.20f+0.200f), g.FontSize * 0.134f * 0.5f), GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled), g.FontSize * 0.866f); + } return pressed; } diff --git a/imgui.h b/imgui.h index 3e2ab62..76d90e7 100644 --- a/imgui.h +++ b/imgui.h @@ -1548,7 +1548,7 @@ // Methods IMGUI_API ImFont(); IMGUI_API ~ImFont(); - IMGUI_API void Clear(); + IMGUI_API void ClearOutputData(); IMGUI_API void BuildLookupTable(); IMGUI_API const ImFontGlyph*FindGlyph(ImWchar c) const; IMGUI_API void SetFallbackChar(ImWchar c); diff --git a/imgui_demo.cpp b/imgui_demo.cpp index b8d643b..b464a35 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1989,6 +1989,7 @@ for (int i = 0; i < atlas->Fonts.Size; i++) { ImFont* font = atlas->Fonts[i]; + ImGui::PushID(font); bool font_details_opened = ImGui::TreeNode(font, "Font %d: \'%s\', %.2f px, %d glyphs", i, font->ConfigData ? font->ConfigData[0].Name : "", font->FontSize, font->Glyphs.Size); ImGui::SameLine(); if (ImGui::SmallButton("Set as default")) ImGui::GetIO().FontDefault = font; if (font_details_opened) @@ -2049,6 +2050,7 @@ } ImGui::TreePop(); } + ImGui::PopID(); } static float window_scale = 1.0f; ImGui::DragFloat("this window scale", &window_scale, 0.005f, 0.3f, 2.0f, "%.1f"); // scale only this window diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 384da73..c3a5f3d 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1577,7 +1577,6 @@ const float off_x = cfg.GlyphOffset.x; const float off_y = cfg.GlyphOffset.y + (float)(int)(dst_font->Ascent + 0.5f); - dst_font->FallbackGlyph = NULL; // Always clear fallback so FindGlyph can return NULL. It will be set again in BuildLookupTable() for (int i = 0; i < tmp.RangesCount; i++) { stbtt_pack_range& range = tmp.Ranges[i]; @@ -1619,14 +1618,12 @@ { if (!font_config->MergeMode) { - font->ContainerAtlas = atlas; - font->ConfigData = font_config; - font->ConfigDataCount = 0; + font->ClearOutputData(); font->FontSize = font_config->SizePixels; + font->ConfigData = font_config; + font->ContainerAtlas = atlas; font->Ascent = ascent; font->Descent = descent; - font->Glyphs.resize(0); - font->MetricsTotalSurface = 0; } font->ConfigDataCount++; } @@ -1903,7 +1900,8 @@ { Scale = 1.0f; FallbackChar = (ImWchar)'?'; - Clear(); + DisplayOffset = ImVec2(0.0f, 1.0f); + ClearOutputData(); } ImFont::~ImFont() @@ -1916,13 +1914,12 @@ if (g.Font == this) g.Font = NULL; */ - Clear(); + ClearOutputData(); } -void ImFont::Clear() +void ImFont::ClearOutputData() { FontSize = 0.0f; - DisplayOffset = ImVec2(0.0f, 1.0f); Glyphs.clear(); IndexAdvanceX.clear(); IndexLookup.clear();