Skip to content

Commit

Permalink
borderless_movable: handle absolute or relative mouse position
Browse files Browse the repository at this point in the history
  • Loading branch information
pthom committed Jan 3, 2024
1 parent ba7570d commit 8448f4b
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 23 deletions.
8 changes: 1 addition & 7 deletions src/hello_imgui/internal/backend_impls/abstract_runner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -509,13 +509,7 @@ void AbstractRunner::RenderGui()
if (params.appWindowParams.borderless) // Need to add params.appWindowParams.borderlessResizable
{
#if !defined(HELLOIMGUI_MOBILEDEVICE) && !defined(__EMSCRIPTEN__)
bool shouldClose = HandleBorderlessMovable(mWindow,
mBackendWindowHelper.get(),
params.appWindowParams.borderlessMovable,
params.appWindowParams.borderlessResizable,
params.appWindowParams.borderlessClosable,
params.appWindowParams.borderlessHighlightColor
);
bool shouldClose = HandleBorderlessMovable(mWindow, mBackendWindowHelper.get(), params);
if (shouldClose)
params.appShallExit = true;
#endif
Expand Down
48 changes: 37 additions & 11 deletions src/hello_imgui/internal/borderless_movable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,23 @@ namespace HelloImGui
bool HandleBorderlessMovable(
BackendApi::WindowPointer window,
BackendApi::IBackendWindowHelper * backendWindowHelper,
bool borderlessMovable,
bool borderlessResizable,
bool borderlessClosable,
ImVec4 borderlessHighlightColor)
const HelloImGui::RunnerParams& runnerParams
)
{
// - If using viewports, the mouse position is absolute, and we can confidently move the window
// knowing that the mouse position will not be affected.
// - If not using viewports, the mouse position is relative to the window, and the window may
// jump from position to position when dragged: MouseDelta is not reliable in this case
// => in this case, we do not move the window
bool isMousePositionAbsolute = ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable;

bool shouldClose = false;

bool borderlessMovable = runnerParams.appWindowParams.borderlessMovable;
bool borderlessResizable = runnerParams.appWindowParams.borderlessResizable;
bool borderlessClosable = runnerParams.appWindowParams.borderlessClosable;
ImVec4 borderlessHighlightColor = runnerParams.appWindowParams.borderlessHighlightColor;

ImU32 highlightColorU32 = ImGui::GetColorU32(borderlessHighlightColor);
if (borderlessHighlightColor.w == 0.f)
highlightColorU32 = ImGui::GetColorU32(ImGuiCol_TitleBg, 0.6f);
Expand All @@ -29,9 +39,13 @@ namespace HelloImGui
// Update dragging state
ImVec2 mousePos = ImGui::GetMousePos();
static bool isDragging = false;

static ImVec2 mouseDragLastPos; // used to store DragDelta when isMousePositionAbsolute==false

if (dragArea.Contains(mousePos) && !isDragging && ImGui::IsMouseDown(ImGuiMouseButton_Left))
{
isDragging = true;
mouseDragLastPos = mousePos;
}
if (!ImGui::IsMouseDown(ImGuiMouseButton_Left) && isDragging)
isDragging = false;
Expand All @@ -49,13 +63,25 @@ namespace HelloImGui
// Move window if dragging
if (isDragging)
{
ImVec2 dragDelta = ImGui::GetMouseDragDelta(0);
ImGui::ResetMouseDragDelta(0);
ImVec2 dragDelta;
if (isMousePositionAbsolute)
{
dragDelta = ImGui::GetMouseDragDelta(0);
ImGui::ResetMouseDragDelta(0);
ImGui::ResetMouseDragDelta(ImGuiMouseButton_Left);
}
else
{
dragDelta = mousePos - mouseDragLastPos;
// take the window movement into account, since our future mouse position
// will be relative to the moved window!
mouseDragLastPos = mousePos - dragDelta;
}

auto windowBounds = backendWindowHelper->GetWindowBounds(window);
windowBounds.position[0] += (int)dragDelta.x;
windowBounds.position[1] += (int)dragDelta.y;
windowBounds.position[0] += (int)(dragDelta.x);
windowBounds.position[1] += (int)(dragDelta.y);
backendWindowHelper->SetWindowBounds(window, windowBounds);
ImGui::ResetMouseDragDelta(ImGuiMouseButton_Left);
}

// Set mouse cursor: probably not visible for moving (the cursor will be the classic arrow)
Expand All @@ -75,8 +101,8 @@ namespace HelloImGui
ImVec2 btnPos(topRight.x - btnSize.x, topRight.y);
ImRect btnArea(btnPos, btnPos + btnSize);

auto colorButton = ImGui::GetColorU32(ImGuiCol_Button, 0.95f);
colorButton = 0xFF0000BB;
//auto colorButton = ImGui::GetColorU32(ImGuiCol_Button, 0.95f);
ImU32 colorButton = 0xFF0000BB;
ImGui::GetForegroundDrawList()->AddCircleFilled(
btnArea.GetCenter(),
btnSize.x * 0.5f,
Expand Down
5 changes: 1 addition & 4 deletions src/hello_imgui/internal/borderless_movable.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ namespace HelloImGui
bool HandleBorderlessMovable(
BackendApi::WindowPointer window,
BackendApi::IBackendWindowHelper * backendWindowHelper,
bool borderlessMovable,
bool borderlessResizable,
bool borderlessClosable,
ImVec4 borderlessHighlightColor
const HelloImGui::RunnerParams& runnerParams
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@ int main(int, char**)
// First, tell HelloImGui that we want full screen dock space (this will create "MainDockSpace")
runnerParams.imGuiWindowParams.defaultImGuiWindowType = HelloImGui::DefaultImGuiWindowType::ProvideFullScreenDockSpace;
// In this demo, we also demonstrate multiple viewports: you can drag windows outside out the main window in order to put their content into new native windows
runnerParams.imGuiWindowParams.enableViewports = true;
runnerParams.imGuiWindowParams.enableViewports = false;
// Set the default layout
runnerParams.dockingParams = CreateDefaultLayout(appState);
// Add alternative layouts
Expand Down

0 comments on commit 8448f4b

Please sign in to comment.