mirror of
https://github.com/ocornut/imgui.git
synced 2024-11-27 16:29:02 +08:00
NewFrame: Extract some code into a NewFrameUpdateHoveredWindowAndCaptureFlags() which can be of use with touch-based inputs systems.
This commit is contained in:
parent
c1bdab6d5b
commit
e88fb10d7c
108
imgui.cpp
108
imgui.cpp
@ -3344,6 +3344,62 @@ static void ImGui::NewFrameUpdateMouseInputs()
|
||||
}
|
||||
}
|
||||
|
||||
// The reason this is exposed in imgui_internal.h is: on touch-based system that don't have hovering, we want to dispatch inputs to the right target (imgui vs imgui+app)
|
||||
void ImGui::NewFrameUpdateHoveredWindowAndCaptureFlags()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
// Find the window hovered by mouse:
|
||||
// - Child windows can extend beyond the limit of their parent so we need to derive HoveredRootWindow from HoveredWindow.
|
||||
// - When moving a window we can skip the search, which also conveniently bypasses the fact that window->WindowRectClipped is lagging as this point of the frame.
|
||||
// - We also support the moved window toggling the NoInputs flag after moving has started in order to be able to detect windows below it, which is useful for e.g. docking mechanisms.
|
||||
g.HoveredWindow = (g.MovingWindow && !(g.MovingWindow->Flags & ImGuiWindowFlags_NoInputs)) ? g.MovingWindow : FindHoveredWindow();
|
||||
g.HoveredRootWindow = g.HoveredWindow ? g.HoveredWindow->RootWindow : NULL;
|
||||
|
||||
// Modal windows prevents cursor from hovering behind them.
|
||||
ImGuiWindow* modal_window = GetFrontMostModalRootWindow();
|
||||
if (modal_window)
|
||||
if (g.HoveredRootWindow && !IsWindowChildOf(g.HoveredRootWindow, modal_window))
|
||||
g.HoveredRootWindow = g.HoveredWindow = NULL;
|
||||
|
||||
// We track click ownership. When clicked outside of a window the click is owned by the application and won't report hovering nor request capture even while dragging over our windows afterward.
|
||||
int mouse_earliest_button_down = -1;
|
||||
bool mouse_any_down = false;
|
||||
for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++)
|
||||
{
|
||||
if (g.IO.MouseClicked[i])
|
||||
g.IO.MouseDownOwned[i] = (g.HoveredWindow != NULL) || (!g.OpenPopupStack.empty());
|
||||
mouse_any_down |= g.IO.MouseDown[i];
|
||||
if (g.IO.MouseDown[i])
|
||||
if (mouse_earliest_button_down == -1 || g.IO.MouseClickedTime[i] < g.IO.MouseClickedTime[mouse_earliest_button_down])
|
||||
mouse_earliest_button_down = i;
|
||||
}
|
||||
const bool mouse_avail_to_imgui = (mouse_earliest_button_down == -1) || g.IO.MouseDownOwned[mouse_earliest_button_down];
|
||||
|
||||
// If mouse was first clicked outside of ImGui bounds we also cancel out hovering.
|
||||
// FIXME: For patterns of drag and drop across OS windows, we may need to rework/remove this test (first committed 311c0ca9 on 2015/02)
|
||||
const bool mouse_dragging_extern_payload = g.DragDropActive && (g.DragDropSourceFlags & ImGuiDragDropFlags_SourceExtern) != 0;
|
||||
if (!mouse_avail_to_imgui && !mouse_dragging_extern_payload)
|
||||
g.HoveredWindow = g.HoveredRootWindow = NULL;
|
||||
|
||||
// Update io.WantCaptureMouse for the user application (true = dispatch mouse info to imgui, false = dispatch mouse info to imgui + app)
|
||||
if (g.WantCaptureMouseNextFrame != -1)
|
||||
g.IO.WantCaptureMouse = (g.WantCaptureMouseNextFrame != 0);
|
||||
else
|
||||
g.IO.WantCaptureMouse = (mouse_avail_to_imgui && (g.HoveredWindow != NULL || mouse_any_down)) || (!g.OpenPopupStack.empty());
|
||||
|
||||
// Update io.WantCaptureKeyboard for the user application (true = dispatch keyboard info to imgui, false = dispatch keyboard info to imgui + app)
|
||||
if (g.WantCaptureKeyboardNextFrame != -1)
|
||||
g.IO.WantCaptureKeyboard = (g.WantCaptureKeyboardNextFrame != 0);
|
||||
else
|
||||
g.IO.WantCaptureKeyboard = (g.ActiveId != 0) || (modal_window != NULL);
|
||||
if (g.IO.NavActive && (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) && !(g.IO.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard))
|
||||
g.IO.WantCaptureKeyboard = true;
|
||||
|
||||
// Update io.WantTextInput flag, this is to allow systems without a keyboard (e.g. mobile, hand-held) to show a software keyboard if possible
|
||||
g.IO.WantTextInput = (g.WantTextInputNextFrame != -1) ? (g.WantTextInputNextFrame != 0) : 0;
|
||||
}
|
||||
|
||||
void ImGui::NewFrame()
|
||||
{
|
||||
IM_ASSERT(GImGui != NULL && "No current context. Did you call ImGui::CreateContext() or ImGui::SetCurrentContext()?");
|
||||
@ -3446,63 +3502,17 @@ void ImGui::NewFrame()
|
||||
|
||||
// Handle user moving window with mouse (at the beginning of the frame to avoid input lag or sheering)
|
||||
NewFrameUpdateMovingWindow();
|
||||
|
||||
// Find the window we are hovering
|
||||
// - Child windows can extend beyond the limit of their parent so we need to derive HoveredRootWindow from HoveredWindow.
|
||||
// - When moving a window we can skip the search, which also conveniently bypasses the fact that window->WindowRectClipped is lagging as this point.
|
||||
// - We also support the moved window toggling the NoInputs flag after moving has started in order to be able to detect windows below it, which is useful for e.g. docking mechanisms.
|
||||
g.HoveredWindow = (g.MovingWindow && !(g.MovingWindow->Flags & ImGuiWindowFlags_NoInputs)) ? g.MovingWindow : FindHoveredWindow();
|
||||
g.HoveredRootWindow = g.HoveredWindow ? g.HoveredWindow->RootWindow : NULL;
|
||||
|
||||
ImGuiWindow* modal_window = GetFrontMostModalRootWindow();
|
||||
if (modal_window != NULL)
|
||||
{
|
||||
NewFrameUpdateHoveredWindowAndCaptureFlags();
|
||||
|
||||
if (ImGuiWindow* modal_window = GetFrontMostModalRootWindow())
|
||||
g.ModalWindowDarkeningRatio = ImMin(g.ModalWindowDarkeningRatio + g.IO.DeltaTime * 6.0f, 1.0f);
|
||||
if (g.HoveredRootWindow && !IsWindowChildOf(g.HoveredRootWindow, modal_window))
|
||||
g.HoveredRootWindow = g.HoveredWindow = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
g.ModalWindowDarkeningRatio = 0.0f;
|
||||
}
|
||||
|
||||
// Update the WantCaptureMouse/WantCaptureKeyboard flags, so user can capture/discard the inputs away from the rest of their application.
|
||||
// When clicking outside of a window we assume the click is owned by the application and won't request capture. We need to track click ownership.
|
||||
int mouse_earliest_button_down = -1;
|
||||
bool mouse_any_down = false;
|
||||
for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++)
|
||||
{
|
||||
if (g.IO.MouseClicked[i])
|
||||
g.IO.MouseDownOwned[i] = (g.HoveredWindow != NULL) || (!g.OpenPopupStack.empty());
|
||||
mouse_any_down |= g.IO.MouseDown[i];
|
||||
if (g.IO.MouseDown[i])
|
||||
if (mouse_earliest_button_down == -1 || g.IO.MouseClickedTime[i] < g.IO.MouseClickedTime[mouse_earliest_button_down])
|
||||
mouse_earliest_button_down = i;
|
||||
}
|
||||
bool mouse_avail_to_imgui = (mouse_earliest_button_down == -1) || g.IO.MouseDownOwned[mouse_earliest_button_down];
|
||||
if (g.WantCaptureMouseNextFrame != -1)
|
||||
g.IO.WantCaptureMouse = (g.WantCaptureMouseNextFrame != 0);
|
||||
else
|
||||
g.IO.WantCaptureMouse = (mouse_avail_to_imgui && (g.HoveredWindow != NULL || mouse_any_down)) || (!g.OpenPopupStack.empty());
|
||||
|
||||
if (g.WantCaptureKeyboardNextFrame != -1)
|
||||
g.IO.WantCaptureKeyboard = (g.WantCaptureKeyboardNextFrame != 0);
|
||||
else
|
||||
g.IO.WantCaptureKeyboard = (g.ActiveId != 0) || (modal_window != NULL);
|
||||
if (g.IO.NavActive && (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) && !(g.IO.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard))
|
||||
g.IO.WantCaptureKeyboard = true;
|
||||
|
||||
g.IO.WantTextInput = (g.WantTextInputNextFrame != -1) ? (g.WantTextInputNextFrame != 0) : 0;
|
||||
g.MouseCursor = ImGuiMouseCursor_Arrow;
|
||||
g.WantCaptureMouseNextFrame = g.WantCaptureKeyboardNextFrame = g.WantTextInputNextFrame = -1;
|
||||
g.OsImePosRequest = ImVec2(1.0f, 1.0f); // OS Input Method Editor showing on top-left of our window by default
|
||||
|
||||
// If mouse was first clicked outside of ImGui bounds we also cancel out hovering.
|
||||
// FIXME: For patterns of drag and drop across OS windows, we may need to rework/remove this test (first committed 311c0ca9 on 2015/02)
|
||||
bool mouse_dragging_extern_payload = g.DragDropActive && (g.DragDropSourceFlags & ImGuiDragDropFlags_SourceExtern) != 0;
|
||||
if (!mouse_avail_to_imgui && !mouse_dragging_extern_payload)
|
||||
g.HoveredWindow = g.HoveredRootWindow = NULL;
|
||||
|
||||
// Mouse wheel scrolling, scale
|
||||
if (g.HoveredWindow && !g.HoveredWindow->Collapsed && (g.IO.MouseWheel != 0.0f || g.IO.MouseWheelH != 0.0f))
|
||||
{
|
||||
|
@ -1017,6 +1017,8 @@ namespace ImGui
|
||||
IMGUI_API void Initialize(ImGuiContext* context);
|
||||
IMGUI_API void Shutdown(ImGuiContext* context); // Since 1.60 this is a _private_ function. You can call DestroyContext() to destroy the context created by CreateContext().
|
||||
|
||||
IMGUI_API void NewFrameUpdateHoveredWindowAndCaptureFlags();
|
||||
|
||||
IMGUI_API void MarkIniSettingsDirty();
|
||||
IMGUI_API ImGuiSettingsHandler* FindSettingsHandler(const char* type_name);
|
||||
IMGUI_API ImGuiWindowSettings* FindWindowSettings(ImGuiID id);
|
||||
|
Loading…
Reference in New Issue
Block a user