Skip to content

Commit

Permalink
Add SetWindowHitTest/SetNextWindowHitTest pair to allow clicking trou…
Browse files Browse the repository at this point in the history
…gh windows.
  • Loading branch information
thedmd committed Jul 22, 2020
1 parent a4501e7 commit 292afdc
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 0 deletions.
26 changes: 26 additions & 0 deletions imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,7 @@ static const float WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER = 2.00f; // Lock
//-------------------------------------------------------------------------

static void SetCurrentWindow(ImGuiWindow* window);
static void SetWindowHitTest(ImGuiWindow* window, ImGuiHitTestData hitTest);
static void FindHoveredWindow();
static ImGuiWindow* CreateNewWindow(const char* name, ImGuiWindowFlags flags);
static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window, bool snap_on_edges);
Expand Down Expand Up @@ -2760,6 +2761,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name)
HiddenFramesCanSkipItems = HiddenFramesCannotSkipItems = 0;
SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing;
SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX);
WindowHitTest = ImGuiHitTestData();

InnerRect = ImRect(0.0f, 0.0f, 0.0f, 0.0f); // Clear so the InnerRect.GetSize() code in Begin() doesn't lead to overflow even if the result isn't used.

Expand Down Expand Up @@ -4295,6 +4297,9 @@ static void FindHoveredWindow()
if (!bb.Contains(g.IO.MousePos))
continue;

if (window->WindowHitTest.Callback && !window->WindowHitTest.Callback(g.IO.MousePos, window->Pos, window->Size, window->WindowHitTest.UserData))
continue;

// Those seemingly unnecessary extra tests are because the code here is a little different in viewport/docking branches.
if (hovered_window == NULL)
hovered_window = window;
Expand Down Expand Up @@ -4323,6 +4328,7 @@ bool ImGui::IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool c
const ImRect rect_for_touch(rect_clipped.Min - g.Style.TouchExtraPadding, rect_clipped.Max + g.Style.TouchExtraPadding);
bool result = rect_for_touch.Contains(g.IO.MousePos);

ImGuiWindow* window = g.CurrentWindow;
if (result && window->DC.HitTest.Callback)
return window->DC.HitTest.Callback(g.IO.MousePos, r_min, r_max, window->DC.HitTest.UserData);
else
Expand Down Expand Up @@ -5509,6 +5515,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->ContentSizeExplicit = ImVec2(0.0f, 0.0f);
if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasCollapsed)
SetWindowCollapsed(window, g.NextWindowData.CollapsedVal, g.NextWindowData.CollapsedCond);
if (g.NextWindowData.WindowHitTest)
SetWindowHitTest(window, g.NextWindowData.WindowHitTestVal);
if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasFocus)
FocusWindow(window);
if (window->Appearing)
Expand Down Expand Up @@ -6489,6 +6497,17 @@ void ImGui::SetWindowFocus(const char* name)
}
}

static void SetWindowHitTest(ImGuiWindow* window, ImGuiHitTestData hitTest)
{
window->WindowHitTest = hitTest;
}

void ImGui::SetWindowHitTest(const char* name, ImGuiHitTestCallback callback, void* user_data)
{
if (ImGuiWindow* window = FindWindowByName(name))
SetWindowHitTest(window, ImGuiHitTestData(callback, user_data));
}

void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiCond cond, const ImVec2& pivot)
{
ImGuiContext& g = *GImGui;
Expand Down Expand Up @@ -6555,6 +6574,13 @@ void ImGui::SetNextWindowBgAlpha(float alpha)
g.NextWindowData.BgAlphaVal = alpha;
}

void ImGui::SetNextWindowHitTest(ImGuiHitTestCallback callback, void* user_data)
{
ImGuiContext& g = *GImGui;
g.NextWindowData.WindowHitTest = true;
g.NextWindowData.WindowHitTestVal = ImGuiHitTestData(callback, user_data);
}

ImDrawList* ImGui::GetWindowDrawList()
{
ImGuiWindow* window = GetCurrentWindow();
Expand Down
2 changes: 2 additions & 0 deletions imgui.h
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ namespace ImGui
IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiCond cond = 0); // set next window collapsed state. call before Begin()
IMGUI_API void SetNextWindowFocus(); // set next window to be focused / top-most. call before Begin()
IMGUI_API void SetNextWindowBgAlpha(float alpha); // set next window background color alpha. helper to easily override the Alpha component of ImGuiCol_WindowBg/ChildBg/PopupBg. you may also use ImGuiWindowFlags_NoBackground.
IMGUI_API void SetNextWindowHitTest(ImGuiHitTestCallback callback, void* user_data = NULL);
IMGUI_API void SetWindowPos(const ImVec2& pos, ImGuiCond cond = 0); // (not recommended) set current window position - call within Begin()/End(). prefer using SetNextWindowPos(), as this may incur tearing and side-effects.
IMGUI_API void SetWindowSize(const ImVec2& size, ImGuiCond cond = 0); // (not recommended) set current window size - call within Begin()/End(). set to ImVec2(0, 0) to force an auto-fit. prefer using SetNextWindowSize(), as this may incur tearing and minor side-effects.
IMGUI_API void SetWindowCollapsed(bool collapsed, ImGuiCond cond = 0); // (not recommended) set current window collapsed state. prefer using SetNextWindowCollapsed().
Expand All @@ -322,6 +323,7 @@ namespace ImGui
IMGUI_API void SetWindowSize(const char* name, const ImVec2& size, ImGuiCond cond = 0); // set named window size. set axis to 0.0f to force an auto-fit on this axis.
IMGUI_API void SetWindowCollapsed(const char* name, bool collapsed, ImGuiCond cond = 0); // set named window collapsed state
IMGUI_API void SetWindowFocus(const char* name); // set named window to be focused / top-most. use NULL to remove focus.
IMGUI_API void SetWindowHitTest(const char* name, ImGuiHitTestCallback callback, void* user_data = NULL);

// Content region
// - Those functions are bound to be redesigned soon (they are confusing, incomplete and return values in local window coordinates which increases confusion)
Expand Down
3 changes: 3 additions & 0 deletions imgui_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -938,6 +938,7 @@ struct ImGuiNextWindowData
ImGuiCond PosCond;
ImGuiCond SizeCond;
ImGuiCond CollapsedCond;
bool WindowHitTest;
ImVec2 PosVal;
ImVec2 PosPivotVal;
ImVec2 SizeVal;
Expand All @@ -949,6 +950,7 @@ struct ImGuiNextWindowData
void* SizeCallbackUserData;
float BgAlphaVal; // Override background alpha
ImVec2 MenuBarOffsetMinVal; // *Always on* This is not exposed publicly, so we don't clear it.
ImGuiHitTestData WindowHitTestVal;

ImGuiNextWindowData() { memset(this, 0, sizeof(*this)); }
inline void ClearFlags() { Flags = ImGuiNextWindowDataFlags_None; }
Expand Down Expand Up @@ -1617,6 +1619,7 @@ struct IMGUI_API ImGuiWindow
ImGuiCond SetWindowCollapsedAllowFlags; // store acceptable condition flags for SetNextWindowCollapsed() use.
ImVec2 SetWindowPosVal; // store window position when using a non-zero Pivot (position set needs to be processed when we know the window size)
ImVec2 SetWindowPosPivot; // store window pivot for positioning. ImVec2(0, 0) when positioning from top-left corner; ImVec2(0.5f, 0.5f) for centering; ImVec2(1, 1) for bottom right.
ImGuiHitTestData WindowHitTest;

ImVector<ImGuiID> IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack. (In theory this should be in the TempData structure)
ImGuiWindowTempData DC; // Temporary per-window data, reset at the beginning of the frame. This used to be called ImGuiDrawContext, hence the "DC" variable name.
Expand Down

0 comments on commit 292afdc

Please sign in to comment.