|
@@ -1,4 +1,4 @@
|
|
|
-// dear imgui, v1.90.5 WIP
|
|
|
+// dear imgui, v1.90.5
|
|
|
// (main code and documentation)
|
|
|
|
|
|
// Help:
|
|
@@ -77,6 +77,7 @@ CODE
|
|
|
// [SECTION] RENDER HELPERS
|
|
|
// [SECTION] INITIALIZATION, SHUTDOWN
|
|
|
// [SECTION] MAIN CODE (most of the code! lots of stuff, needs tidying up!)
|
|
|
+// [SECTION] ID STACK
|
|
|
// [SECTION] INPUTS
|
|
|
// [SECTION] ERROR CHECKING
|
|
|
// [SECTION] ITEM SUBMISSION
|
|
@@ -1225,7 +1226,7 @@ ImGuiStyle::ImGuiStyle()
|
|
|
FrameBorderSize = 0.0f; // Thickness of border around frames. Generally set to 0.0f or 1.0f. Other values not well tested.
|
|
|
ItemSpacing = ImVec2(8,4); // Horizontal and vertical spacing between widgets/lines
|
|
|
ItemInnerSpacing = ImVec2(4,4); // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label)
|
|
|
- CellPadding = ImVec2(4,2); // Padding within a table cell. CellPadding.y may be altered between different rows.
|
|
|
+ CellPadding = ImVec2(4,2); // Padding within a table cell. Cellpadding.x is locked for entire table. CellPadding.y may be altered between different rows.
|
|
|
TouchExtraPadding = ImVec2(0,0); // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much!
|
|
|
IndentSpacing = 21.0f; // Horizontal spacing when e.g. entering a tree node. Generally == (FontSize + FramePadding.x*2).
|
|
|
ColumnsMinSpacing = 6.0f; // Minimum horizontal spacing between two columns. Preferably > (FramePadding.x + 1).
|
|
@@ -3193,7 +3194,9 @@ static const ImGuiDataVarInfo GStyleVarInfo[] =
|
|
|
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, GrabMinSize) }, // ImGuiStyleVar_GrabMinSize
|
|
|
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, GrabRounding) }, // ImGuiStyleVar_GrabRounding
|
|
|
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabRounding) }, // ImGuiStyleVar_TabRounding
|
|
|
+ { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabBorderSize) }, // ImGuiStyleVar_TabBorderSize
|
|
|
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabBarBorderSize) }, // ImGuiStyleVar_TabBarBorderSize
|
|
|
+ { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TableAngledHeadersAngle)},// ImGuiStyleVar_TableAngledHeadersAngle
|
|
|
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign
|
|
|
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, SelectableTextAlign) }, // ImGuiStyleVar_SelectableTextAlign
|
|
|
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, SeparatorTextBorderSize) },// ImGuiStyleVar_SeparatorTextBorderSize
|
|
@@ -3868,45 +3871,6 @@ ImGuiWindow::~ImGuiWindow()
|
|
|
ColumnsStorage.clear_destruct();
|
|
|
}
|
|
|
|
|
|
-ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end)
|
|
|
-{
|
|
|
- ImGuiID seed = IDStack.back();
|
|
|
- ImGuiID id = ImHashStr(str, str_end ? (str_end - str) : 0, seed);
|
|
|
- ImGuiContext& g = *Ctx;
|
|
|
- if (g.DebugHookIdInfo == id)
|
|
|
- ImGui::DebugHookIdInfo(id, ImGuiDataType_String, str, str_end);
|
|
|
- return id;
|
|
|
-}
|
|
|
-
|
|
|
-ImGuiID ImGuiWindow::GetID(const void* ptr)
|
|
|
-{
|
|
|
- ImGuiID seed = IDStack.back();
|
|
|
- ImGuiID id = ImHashData(&ptr, sizeof(void*), seed);
|
|
|
- ImGuiContext& g = *Ctx;
|
|
|
- if (g.DebugHookIdInfo == id)
|
|
|
- ImGui::DebugHookIdInfo(id, ImGuiDataType_Pointer, ptr, NULL);
|
|
|
- return id;
|
|
|
-}
|
|
|
-
|
|
|
-ImGuiID ImGuiWindow::GetID(int n)
|
|
|
-{
|
|
|
- ImGuiID seed = IDStack.back();
|
|
|
- ImGuiID id = ImHashData(&n, sizeof(n), seed);
|
|
|
- ImGuiContext& g = *Ctx;
|
|
|
- if (g.DebugHookIdInfo == id)
|
|
|
- ImGui::DebugHookIdInfo(id, ImGuiDataType_S32, (void*)(intptr_t)n, NULL);
|
|
|
- return id;
|
|
|
-}
|
|
|
-
|
|
|
-// This is only used in rare/specific situations to manufacture an ID out of nowhere.
|
|
|
-ImGuiID ImGuiWindow::GetIDFromRectangle(const ImRect& r_abs)
|
|
|
-{
|
|
|
- ImGuiID seed = IDStack.back();
|
|
|
- ImRect r_rel = ImGui::WindowRectAbsToRel(this, r_abs);
|
|
|
- ImGuiID id = ImHashData(&r_rel, sizeof(r_rel), seed);
|
|
|
- return id;
|
|
|
-}
|
|
|
-
|
|
|
static void SetCurrentWindow(ImGuiWindow* window)
|
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
@@ -6195,7 +6159,7 @@ static int ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& si
|
|
|
|
|
|
int ret_auto_fit_mask = 0x00;
|
|
|
const float grip_draw_size = IM_TRUNC(ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
|
|
|
- const float grip_hover_inner_size = IM_TRUNC(grip_draw_size * 0.75f);
|
|
|
+ const float grip_hover_inner_size = (resize_grip_count > 0) ? IM_TRUNC(grip_draw_size * 0.75f) : 0.0f;
|
|
|
const float grip_hover_outer_size = g.IO.ConfigWindowsResizeFromEdges ? WINDOWS_HOVER_PADDING : 0.0f;
|
|
|
|
|
|
ImRect clamp_rect = visibility_rect;
|
|
@@ -6333,10 +6297,13 @@ static int ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& si
|
|
|
border_target = ImClamp(border_target, clamp_min, clamp_max);
|
|
|
if (flags & ImGuiWindowFlags_ChildWindow) // Clamp resizing of childs within parent
|
|
|
{
|
|
|
- if ((flags & (ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar)) == 0 || (flags & ImGuiWindowFlags_NoScrollbar))
|
|
|
- border_target.x = ImClamp(border_target.x, window->ParentWindow->InnerClipRect.Min.x, window->ParentWindow->InnerClipRect.Max.x);
|
|
|
- if (flags & ImGuiWindowFlags_NoScrollbar)
|
|
|
- border_target.y = ImClamp(border_target.y, window->ParentWindow->InnerClipRect.Min.y, window->ParentWindow->InnerClipRect.Max.y);
|
|
|
+ ImGuiWindowFlags parent_flags = window->ParentWindow->Flags;
|
|
|
+ ImRect border_limit_rect = window->ParentWindow->InnerRect;
|
|
|
+ border_limit_rect.Expand(ImVec2(-ImMax(window->WindowPadding.x, window->WindowBorderSize), -ImMax(window->WindowPadding.y, window->WindowBorderSize)));
|
|
|
+ if ((parent_flags & (ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar)) == 0 || (parent_flags & ImGuiWindowFlags_NoScrollbar))
|
|
|
+ border_target.x = ImClamp(border_target.x, border_limit_rect.Min.x, border_limit_rect.Max.x);
|
|
|
+ if (parent_flags & ImGuiWindowFlags_NoScrollbar)
|
|
|
+ border_target.y = ImClamp(border_target.y, border_limit_rect.Min.y, border_limit_rect.Max.y);
|
|
|
}
|
|
|
if (!ignore_resize)
|
|
|
CalcResizePosSizeFromAnyCorner(window, border_target, ImMin(def.SegmentN1, def.SegmentN2), &pos_target, &size_target);
|
|
@@ -8599,6 +8566,69 @@ ImGuiStorage* ImGui::GetStateStorage()
|
|
|
return window->DC.StateStorage;
|
|
|
}
|
|
|
|
|
|
+bool ImGui::IsRectVisible(const ImVec2& size)
|
|
|
+{
|
|
|
+ ImGuiWindow* window = GImGui->CurrentWindow;
|
|
|
+ return window->ClipRect.Overlaps(ImRect(window->DC.CursorPos, window->DC.CursorPos + size));
|
|
|
+}
|
|
|
+
|
|
|
+bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max)
|
|
|
+{
|
|
|
+ ImGuiWindow* window = GImGui->CurrentWindow;
|
|
|
+ return window->ClipRect.Overlaps(ImRect(rect_min, rect_max));
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+// [SECTION] ID STACK
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+
|
|
|
+// This is one of the very rare legacy case where we use ImGuiWindow methods,
|
|
|
+// it should ideally be flattened at some point but it's been used a lots by widgets.
|
|
|
+ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end)
|
|
|
+{
|
|
|
+ ImGuiID seed = IDStack.back();
|
|
|
+ ImGuiID id = ImHashStr(str, str_end ? (str_end - str) : 0, seed);
|
|
|
+#ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
|
|
+ ImGuiContext& g = *Ctx;
|
|
|
+ if (g.DebugHookIdInfo == id)
|
|
|
+ ImGui::DebugHookIdInfo(id, ImGuiDataType_String, str, str_end);
|
|
|
+#endif
|
|
|
+ return id;
|
|
|
+}
|
|
|
+
|
|
|
+ImGuiID ImGuiWindow::GetID(const void* ptr)
|
|
|
+{
|
|
|
+ ImGuiID seed = IDStack.back();
|
|
|
+ ImGuiID id = ImHashData(&ptr, sizeof(void*), seed);
|
|
|
+#ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
|
|
+ ImGuiContext& g = *Ctx;
|
|
|
+ if (g.DebugHookIdInfo == id)
|
|
|
+ ImGui::DebugHookIdInfo(id, ImGuiDataType_Pointer, ptr, NULL);
|
|
|
+#endif
|
|
|
+ return id;
|
|
|
+}
|
|
|
+
|
|
|
+ImGuiID ImGuiWindow::GetID(int n)
|
|
|
+{
|
|
|
+ ImGuiID seed = IDStack.back();
|
|
|
+ ImGuiID id = ImHashData(&n, sizeof(n), seed);
|
|
|
+#ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
|
|
+ ImGuiContext& g = *Ctx;
|
|
|
+ if (g.DebugHookIdInfo == id)
|
|
|
+ ImGui::DebugHookIdInfo(id, ImGuiDataType_S32, (void*)(intptr_t)n, NULL);
|
|
|
+#endif
|
|
|
+ return id;
|
|
|
+}
|
|
|
+
|
|
|
+// This is only used in rare/specific situations to manufacture an ID out of nowhere.
|
|
|
+ImGuiID ImGuiWindow::GetIDFromRectangle(const ImRect& r_abs)
|
|
|
+{
|
|
|
+ ImGuiID seed = IDStack.back();
|
|
|
+ ImRect r_rel = ImGui::WindowRectAbsToRel(this, r_abs);
|
|
|
+ ImGuiID id = ImHashData(&r_rel, sizeof(r_rel), seed);
|
|
|
+ return id;
|
|
|
+}
|
|
|
+
|
|
|
void ImGui::PushID(const char* str_id)
|
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
@@ -8636,8 +8666,10 @@ void ImGui::PushOverrideID(ImGuiID id)
|
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
ImGuiWindow* window = g.CurrentWindow;
|
|
|
+#ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
|
|
if (g.DebugHookIdInfo == id)
|
|
|
DebugHookIdInfo(id, ImGuiDataType_ID, NULL, NULL);
|
|
|
+#endif
|
|
|
window->IDStack.push_back(id);
|
|
|
}
|
|
|
|
|
@@ -8647,18 +8679,22 @@ void ImGui::PushOverrideID(ImGuiID id)
|
|
|
ImGuiID ImGui::GetIDWithSeed(const char* str, const char* str_end, ImGuiID seed)
|
|
|
{
|
|
|
ImGuiID id = ImHashStr(str, str_end ? (str_end - str) : 0, seed);
|
|
|
+#ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
if (g.DebugHookIdInfo == id)
|
|
|
DebugHookIdInfo(id, ImGuiDataType_String, str, str_end);
|
|
|
+#endif
|
|
|
return id;
|
|
|
}
|
|
|
|
|
|
ImGuiID ImGui::GetIDWithSeed(int n, ImGuiID seed)
|
|
|
{
|
|
|
ImGuiID id = ImHashData(&n, sizeof(n), seed);
|
|
|
+#ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
if (g.DebugHookIdInfo == id)
|
|
|
DebugHookIdInfo(id, ImGuiDataType_S32, (void*)(intptr_t)n, NULL);
|
|
|
+#endif
|
|
|
return id;
|
|
|
}
|
|
|
|
|
@@ -8687,19 +8723,6 @@ ImGuiID ImGui::GetID(const void* ptr_id)
|
|
|
return window->GetID(ptr_id);
|
|
|
}
|
|
|
|
|
|
-bool ImGui::IsRectVisible(const ImVec2& size)
|
|
|
-{
|
|
|
- ImGuiWindow* window = GImGui->CurrentWindow;
|
|
|
- return window->ClipRect.Overlaps(ImRect(window->DC.CursorPos, window->DC.CursorPos + size));
|
|
|
-}
|
|
|
-
|
|
|
-bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max)
|
|
|
-{
|
|
|
- ImGuiWindow* window = GImGui->CurrentWindow;
|
|
|
- return window->ClipRect.Overlaps(ImRect(rect_min, rect_max));
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
//-----------------------------------------------------------------------------
|
|
|
// [SECTION] INPUTS
|
|
|
//-----------------------------------------------------------------------------
|
|
@@ -12983,8 +13006,10 @@ void ImGui::NavMoveRequestApplyResult()
|
|
|
g.NavLastValidSelectionUserData = ImGuiSelectionUserData_Invalid;
|
|
|
}
|
|
|
|
|
|
- // FIXME: Could become optional e.g. ImGuiNavMoveFlags_NoClearActiveId if we later want to apply navigation requests without altering active input.
|
|
|
- if (g.ActiveId != result->ID)
|
|
|
+ // Clear active id unless requested not to
|
|
|
+ // FIXME: ImGuiNavMoveFlags_NoClearActiveId is currently unused as we don't have a clear strategy to preserve active id after interaction,
|
|
|
+ // so this is mostly provided as a gateway for further experiments (see #1418, #2890)
|
|
|
+ if (g.ActiveId != result->ID && (g.NavMoveFlags & ImGuiNavMoveFlags_NoClearActiveId) == 0)
|
|
|
ClearActiveID();
|
|
|
|
|
|
// Don't set NavJustMovedToId if just landed on the same spot (which may happen with ImGuiNavMoveFlags_AllowCurrentNavId)
|