mirror of https://github.com/ocornut/imgui
Internals: refactor: mouse input functions into their own section.
This commit is contained in:
parent
206b9ead8f
commit
28eabcb099
474
imgui.cpp
474
imgui.cpp
|
@ -70,6 +70,7 @@ CODE
|
|||
// [SECTION] STYLING
|
||||
// [SECTION] RENDER HELPERS
|
||||
// [SECTION] MAIN CODE (most of the code! lots of stuff, needs tidying up!)
|
||||
// [SECTION] INPUTS
|
||||
// [SECTION] ERROR CHECKING
|
||||
// [SECTION] LAYOUT
|
||||
// [SECTION] SCROLLING
|
||||
|
@ -4767,238 +4768,6 @@ static void FindHoveredWindow()
|
|||
g.HoveredWindowUnderMovingWindow = hovered_window_ignoring_moving_window;
|
||||
}
|
||||
|
||||
// Test if mouse cursor is hovering given rectangle
|
||||
// NB- Rectangle is clipped by our current clip setting
|
||||
// NB- Expand the rectangle to be generous on imprecise inputs systems (g.Style.TouchExtraPadding)
|
||||
bool ImGui::IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
// Clip
|
||||
ImRect rect_clipped(r_min, r_max);
|
||||
if (clip)
|
||||
rect_clipped.ClipWith(g.CurrentWindow->ClipRect);
|
||||
|
||||
// Expand for touch input
|
||||
const ImRect rect_for_touch(rect_clipped.Min - g.Style.TouchExtraPadding, rect_clipped.Max + g.Style.TouchExtraPadding);
|
||||
if (!rect_for_touch.Contains(g.IO.MousePos))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
int ImGui::GetKeyIndex(ImGuiKey imgui_key)
|
||||
{
|
||||
IM_ASSERT(imgui_key >= 0 && imgui_key < ImGuiKey_COUNT);
|
||||
ImGuiContext& g = *GImGui;
|
||||
return g.IO.KeyMap[imgui_key];
|
||||
}
|
||||
|
||||
// Note that dear imgui doesn't know the semantic of each entry of io.KeysDown[]!
|
||||
// Use your own indices/enums according to how your backend/engine stored them into io.KeysDown[]!
|
||||
bool ImGui::IsKeyDown(int user_key_index)
|
||||
{
|
||||
if (user_key_index < 0)
|
||||
return false;
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(user_key_index >= 0 && user_key_index < IM_ARRAYSIZE(g.IO.KeysDown));
|
||||
return g.IO.KeysDown[user_key_index];
|
||||
}
|
||||
|
||||
// t0 = previous time (e.g.: g.Time - g.IO.DeltaTime)
|
||||
// t1 = current time (e.g.: g.Time)
|
||||
// An event is triggered at:
|
||||
// t = 0.0f t = repeat_delay, t = repeat_delay + repeat_rate*N
|
||||
int ImGui::CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate)
|
||||
{
|
||||
if (t1 == 0.0f)
|
||||
return 1;
|
||||
if (t0 >= t1)
|
||||
return 0;
|
||||
if (repeat_rate <= 0.0f)
|
||||
return (t0 < repeat_delay) && (t1 >= repeat_delay);
|
||||
const int count_t0 = (t0 < repeat_delay) ? -1 : (int)((t0 - repeat_delay) / repeat_rate);
|
||||
const int count_t1 = (t1 < repeat_delay) ? -1 : (int)((t1 - repeat_delay) / repeat_rate);
|
||||
const int count = count_t1 - count_t0;
|
||||
return count;
|
||||
}
|
||||
|
||||
int ImGui::GetKeyPressedAmount(int key_index, float repeat_delay, float repeat_rate)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (key_index < 0)
|
||||
return 0;
|
||||
IM_ASSERT(key_index >= 0 && key_index < IM_ARRAYSIZE(g.IO.KeysDown));
|
||||
const float t = g.IO.KeysDownDuration[key_index];
|
||||
return CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, repeat_delay, repeat_rate);
|
||||
}
|
||||
|
||||
bool ImGui::IsKeyPressed(int user_key_index, bool repeat)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (user_key_index < 0)
|
||||
return false;
|
||||
IM_ASSERT(user_key_index >= 0 && user_key_index < IM_ARRAYSIZE(g.IO.KeysDown));
|
||||
const float t = g.IO.KeysDownDuration[user_key_index];
|
||||
if (t == 0.0f)
|
||||
return true;
|
||||
if (repeat && t > g.IO.KeyRepeatDelay)
|
||||
return GetKeyPressedAmount(user_key_index, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate) > 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ImGui::IsKeyReleased(int user_key_index)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (user_key_index < 0) return false;
|
||||
IM_ASSERT(user_key_index >= 0 && user_key_index < IM_ARRAYSIZE(g.IO.KeysDown));
|
||||
return g.IO.KeysDownDurationPrev[user_key_index] >= 0.0f && !g.IO.KeysDown[user_key_index];
|
||||
}
|
||||
|
||||
bool ImGui::IsMouseDown(ImGuiMouseButton button)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
|
||||
return g.IO.MouseDown[button];
|
||||
}
|
||||
|
||||
bool ImGui::IsMouseClicked(ImGuiMouseButton button, bool repeat)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
|
||||
const float t = g.IO.MouseDownDuration[button];
|
||||
if (t == 0.0f)
|
||||
return true;
|
||||
|
||||
if (repeat && t > g.IO.KeyRepeatDelay)
|
||||
{
|
||||
// FIXME: 2019/05/03: Our old repeat code was wrong here and led to doubling the repeat rate, which made it an ok rate for repeat on mouse hold.
|
||||
int amount = CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate * 0.50f);
|
||||
if (amount > 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ImGui::IsMouseReleased(ImGuiMouseButton button)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
|
||||
return g.IO.MouseReleased[button];
|
||||
}
|
||||
|
||||
bool ImGui::IsMouseDoubleClicked(ImGuiMouseButton button)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
|
||||
return g.IO.MouseClickedCount[button] == 2;
|
||||
}
|
||||
|
||||
int ImGui::GetMouseClickedCount(ImGuiMouseButton button)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
|
||||
return g.IO.MouseClickedCount[button];
|
||||
}
|
||||
|
||||
// Return if a mouse click/drag went past the given threshold. Valid to call during the MouseReleased frame.
|
||||
// [Internal] This doesn't test if the button is pressed
|
||||
bool ImGui::IsMouseDragPastThreshold(ImGuiMouseButton button, float lock_threshold)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
|
||||
if (lock_threshold < 0.0f)
|
||||
lock_threshold = g.IO.MouseDragThreshold;
|
||||
return g.IO.MouseDragMaxDistanceSqr[button] >= lock_threshold * lock_threshold;
|
||||
}
|
||||
|
||||
bool ImGui::IsMouseDragging(ImGuiMouseButton button, float lock_threshold)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
|
||||
if (!g.IO.MouseDown[button])
|
||||
return false;
|
||||
return IsMouseDragPastThreshold(button, lock_threshold);
|
||||
}
|
||||
|
||||
ImVec2 ImGui::GetMousePos()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
return g.IO.MousePos;
|
||||
}
|
||||
|
||||
// NB: prefer to call right after BeginPopup(). At the time Selectable/MenuItem is activated, the popup is already closed!
|
||||
ImVec2 ImGui::GetMousePosOnOpeningCurrentPopup()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (g.BeginPopupStack.Size > 0)
|
||||
return g.OpenPopupStack[g.BeginPopupStack.Size - 1].OpenMousePos;
|
||||
return g.IO.MousePos;
|
||||
}
|
||||
|
||||
// We typically use ImVec2(-FLT_MAX,-FLT_MAX) to denote an invalid mouse position.
|
||||
bool ImGui::IsMousePosValid(const ImVec2* mouse_pos)
|
||||
{
|
||||
// The assert is only to silence a false-positive in XCode Static Analysis.
|
||||
// Because GImGui is not dereferenced in every code path, the static analyzer assume that it may be NULL (which it doesn't for other functions).
|
||||
IM_ASSERT(GImGui != NULL);
|
||||
const float MOUSE_INVALID = -256000.0f;
|
||||
ImVec2 p = mouse_pos ? *mouse_pos : GImGui->IO.MousePos;
|
||||
return p.x >= MOUSE_INVALID && p.y >= MOUSE_INVALID;
|
||||
}
|
||||
|
||||
bool ImGui::IsAnyMouseDown()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
for (int n = 0; n < IM_ARRAYSIZE(g.IO.MouseDown); n++)
|
||||
if (g.IO.MouseDown[n])
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return the delta from the initial clicking position while the mouse button is clicked or was just released.
|
||||
// This is locked and return 0.0f until the mouse moves past a distance threshold at least once.
|
||||
// NB: This is only valid if IsMousePosValid(). backends in theory should always keep mouse position valid when dragging even outside the client window.
|
||||
ImVec2 ImGui::GetMouseDragDelta(ImGuiMouseButton button, float lock_threshold)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
|
||||
if (lock_threshold < 0.0f)
|
||||
lock_threshold = g.IO.MouseDragThreshold;
|
||||
if (g.IO.MouseDown[button] || g.IO.MouseReleased[button])
|
||||
if (g.IO.MouseDragMaxDistanceSqr[button] >= lock_threshold * lock_threshold)
|
||||
if (IsMousePosValid(&g.IO.MousePos) && IsMousePosValid(&g.IO.MouseClickedPos[button]))
|
||||
return g.IO.MousePos - g.IO.MouseClickedPos[button];
|
||||
return ImVec2(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
void ImGui::ResetMouseDragDelta(ImGuiMouseButton button)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
|
||||
// NB: We don't need to reset g.IO.MouseDragMaxDistanceSqr
|
||||
g.IO.MouseClickedPos[button] = g.IO.MousePos;
|
||||
}
|
||||
|
||||
ImGuiMouseCursor ImGui::GetMouseCursor()
|
||||
{
|
||||
return GImGui->MouseCursor;
|
||||
}
|
||||
|
||||
void ImGui::SetMouseCursor(ImGuiMouseCursor cursor_type)
|
||||
{
|
||||
GImGui->MouseCursor = cursor_type;
|
||||
}
|
||||
|
||||
void ImGui::CaptureKeyboardFromApp(bool capture)
|
||||
{
|
||||
GImGui->WantCaptureKeyboardNextFrame = capture ? 1 : 0;
|
||||
}
|
||||
|
||||
void ImGui::CaptureMouseFromApp(bool capture)
|
||||
{
|
||||
GImGui->WantCaptureMouseNextFrame = capture ? 1 : 0;
|
||||
}
|
||||
|
||||
bool ImGui::IsItemActive()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
@ -7460,6 +7229,247 @@ bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max)
|
|||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] INPUTS
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Test if mouse cursor is hovering given rectangle
|
||||
// NB- Rectangle is clipped by our current clip setting
|
||||
// NB- Expand the rectangle to be generous on imprecise inputs systems (g.Style.TouchExtraPadding)
|
||||
bool ImGui::IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
// Clip
|
||||
ImRect rect_clipped(r_min, r_max);
|
||||
if (clip)
|
||||
rect_clipped.ClipWith(g.CurrentWindow->ClipRect);
|
||||
|
||||
// Expand for touch input
|
||||
const ImRect rect_for_touch(rect_clipped.Min - g.Style.TouchExtraPadding, rect_clipped.Max + g.Style.TouchExtraPadding);
|
||||
if (!rect_for_touch.Contains(g.IO.MousePos))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
int ImGui::GetKeyIndex(ImGuiKey imgui_key)
|
||||
{
|
||||
IM_ASSERT(imgui_key >= 0 && imgui_key < ImGuiKey_COUNT);
|
||||
ImGuiContext& g = *GImGui;
|
||||
return g.IO.KeyMap[imgui_key];
|
||||
}
|
||||
|
||||
// Note that dear imgui doesn't know the semantic of each entry of io.KeysDown[]!
|
||||
// Use your own indices/enums according to how your backend/engine stored them into io.KeysDown[]!
|
||||
bool ImGui::IsKeyDown(int user_key_index)
|
||||
{
|
||||
if (user_key_index < 0)
|
||||
return false;
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(user_key_index >= 0 && user_key_index < IM_ARRAYSIZE(g.IO.KeysDown));
|
||||
return g.IO.KeysDown[user_key_index];
|
||||
}
|
||||
|
||||
// t0 = previous time (e.g.: g.Time - g.IO.DeltaTime)
|
||||
// t1 = current time (e.g.: g.Time)
|
||||
// An event is triggered at:
|
||||
// t = 0.0f t = repeat_delay, t = repeat_delay + repeat_rate*N
|
||||
int ImGui::CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate)
|
||||
{
|
||||
if (t1 == 0.0f)
|
||||
return 1;
|
||||
if (t0 >= t1)
|
||||
return 0;
|
||||
if (repeat_rate <= 0.0f)
|
||||
return (t0 < repeat_delay) && (t1 >= repeat_delay);
|
||||
const int count_t0 = (t0 < repeat_delay) ? -1 : (int)((t0 - repeat_delay) / repeat_rate);
|
||||
const int count_t1 = (t1 < repeat_delay) ? -1 : (int)((t1 - repeat_delay) / repeat_rate);
|
||||
const int count = count_t1 - count_t0;
|
||||
return count;
|
||||
}
|
||||
|
||||
int ImGui::GetKeyPressedAmount(int key_index, float repeat_delay, float repeat_rate)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (key_index < 0)
|
||||
return 0;
|
||||
IM_ASSERT(key_index >= 0 && key_index < IM_ARRAYSIZE(g.IO.KeysDown));
|
||||
const float t = g.IO.KeysDownDuration[key_index];
|
||||
return CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, repeat_delay, repeat_rate);
|
||||
}
|
||||
|
||||
bool ImGui::IsKeyPressed(int user_key_index, bool repeat)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (user_key_index < 0)
|
||||
return false;
|
||||
IM_ASSERT(user_key_index >= 0 && user_key_index < IM_ARRAYSIZE(g.IO.KeysDown));
|
||||
const float t = g.IO.KeysDownDuration[user_key_index];
|
||||
if (t == 0.0f)
|
||||
return true;
|
||||
if (repeat && t > g.IO.KeyRepeatDelay)
|
||||
return GetKeyPressedAmount(user_key_index, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate) > 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ImGui::IsKeyReleased(int user_key_index)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (user_key_index < 0) return false;
|
||||
IM_ASSERT(user_key_index >= 0 && user_key_index < IM_ARRAYSIZE(g.IO.KeysDown));
|
||||
return g.IO.KeysDownDurationPrev[user_key_index] >= 0.0f && !g.IO.KeysDown[user_key_index];
|
||||
}
|
||||
|
||||
bool ImGui::IsMouseDown(ImGuiMouseButton button)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
|
||||
return g.IO.MouseDown[button];
|
||||
}
|
||||
|
||||
bool ImGui::IsMouseClicked(ImGuiMouseButton button, bool repeat)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
|
||||
const float t = g.IO.MouseDownDuration[button];
|
||||
if (t == 0.0f)
|
||||
return true;
|
||||
|
||||
if (repeat && t > g.IO.KeyRepeatDelay)
|
||||
{
|
||||
// FIXME: 2019/05/03: Our old repeat code was wrong here and led to doubling the repeat rate, which made it an ok rate for repeat on mouse hold.
|
||||
int amount = CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate * 0.50f);
|
||||
if (amount > 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ImGui::IsMouseReleased(ImGuiMouseButton button)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
|
||||
return g.IO.MouseReleased[button];
|
||||
}
|
||||
|
||||
bool ImGui::IsMouseDoubleClicked(ImGuiMouseButton button)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
|
||||
return g.IO.MouseClickedCount[button] == 2;
|
||||
}
|
||||
|
||||
int ImGui::GetMouseClickedCount(ImGuiMouseButton button)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
|
||||
return g.IO.MouseClickedCount[button];
|
||||
}
|
||||
|
||||
// Return if a mouse click/drag went past the given threshold. Valid to call during the MouseReleased frame.
|
||||
// [Internal] This doesn't test if the button is pressed
|
||||
bool ImGui::IsMouseDragPastThreshold(ImGuiMouseButton button, float lock_threshold)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
|
||||
if (lock_threshold < 0.0f)
|
||||
lock_threshold = g.IO.MouseDragThreshold;
|
||||
return g.IO.MouseDragMaxDistanceSqr[button] >= lock_threshold * lock_threshold;
|
||||
}
|
||||
|
||||
bool ImGui::IsMouseDragging(ImGuiMouseButton button, float lock_threshold)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
|
||||
if (!g.IO.MouseDown[button])
|
||||
return false;
|
||||
return IsMouseDragPastThreshold(button, lock_threshold);
|
||||
}
|
||||
|
||||
ImVec2 ImGui::GetMousePos()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
return g.IO.MousePos;
|
||||
}
|
||||
|
||||
// NB: prefer to call right after BeginPopup(). At the time Selectable/MenuItem is activated, the popup is already closed!
|
||||
ImVec2 ImGui::GetMousePosOnOpeningCurrentPopup()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (g.BeginPopupStack.Size > 0)
|
||||
return g.OpenPopupStack[g.BeginPopupStack.Size - 1].OpenMousePos;
|
||||
return g.IO.MousePos;
|
||||
}
|
||||
|
||||
// We typically use ImVec2(-FLT_MAX,-FLT_MAX) to denote an invalid mouse position.
|
||||
bool ImGui::IsMousePosValid(const ImVec2* mouse_pos)
|
||||
{
|
||||
// The assert is only to silence a false-positive in XCode Static Analysis.
|
||||
// Because GImGui is not dereferenced in every code path, the static analyzer assume that it may be NULL (which it doesn't for other functions).
|
||||
IM_ASSERT(GImGui != NULL);
|
||||
const float MOUSE_INVALID = -256000.0f;
|
||||
ImVec2 p = mouse_pos ? *mouse_pos : GImGui->IO.MousePos;
|
||||
return p.x >= MOUSE_INVALID && p.y >= MOUSE_INVALID;
|
||||
}
|
||||
|
||||
bool ImGui::IsAnyMouseDown()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
for (int n = 0; n < IM_ARRAYSIZE(g.IO.MouseDown); n++)
|
||||
if (g.IO.MouseDown[n])
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return the delta from the initial clicking position while the mouse button is clicked or was just released.
|
||||
// This is locked and return 0.0f until the mouse moves past a distance threshold at least once.
|
||||
// NB: This is only valid if IsMousePosValid(). backends in theory should always keep mouse position valid when dragging even outside the client window.
|
||||
ImVec2 ImGui::GetMouseDragDelta(ImGuiMouseButton button, float lock_threshold)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
|
||||
if (lock_threshold < 0.0f)
|
||||
lock_threshold = g.IO.MouseDragThreshold;
|
||||
if (g.IO.MouseDown[button] || g.IO.MouseReleased[button])
|
||||
if (g.IO.MouseDragMaxDistanceSqr[button] >= lock_threshold * lock_threshold)
|
||||
if (IsMousePosValid(&g.IO.MousePos) && IsMousePosValid(&g.IO.MouseClickedPos[button]))
|
||||
return g.IO.MousePos - g.IO.MouseClickedPos[button];
|
||||
return ImVec2(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
void ImGui::ResetMouseDragDelta(ImGuiMouseButton button)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
|
||||
// NB: We don't need to reset g.IO.MouseDragMaxDistanceSqr
|
||||
g.IO.MouseClickedPos[button] = g.IO.MousePos;
|
||||
}
|
||||
|
||||
ImGuiMouseCursor ImGui::GetMouseCursor()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
return g.MouseCursor;
|
||||
}
|
||||
|
||||
void ImGui::SetMouseCursor(ImGuiMouseCursor cursor_type)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
g.MouseCursor = cursor_type;
|
||||
}
|
||||
|
||||
void ImGui::CaptureKeyboardFromApp(bool capture)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
g.WantCaptureKeyboardNextFrame = capture ? 1 : 0;
|
||||
}
|
||||
|
||||
void ImGui::CaptureMouseFromApp(bool capture)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
g.WantCaptureMouseNextFrame = capture ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] ERROR CHECKING
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue