mirror of
https://github.com/ocornut/imgui.git
synced 2026-05-28 12:06:39 +08:00
Merge branch 'master' into docking
build / Build - Windows (push) Has been cancelled
build / Build - Linux (push) Has been cancelled
build / Build - MacOS (push) Has been cancelled
build / Build - iOS (push) Has been cancelled
build / Build - Emscripten (push) Has been cancelled
build / Build - Android (push) Has been cancelled
build / Test - Windows (push) Has been cancelled
build / Test - Linux (push) Has been cancelled
build / Build - Windows (push) Has been cancelled
build / Build - Linux (push) Has been cancelled
build / Build - MacOS (push) Has been cancelled
build / Build - iOS (push) Has been cancelled
build / Build - Emscripten (push) Has been cancelled
build / Build - Android (push) Has been cancelled
build / Test - Windows (push) Has been cancelled
build / Test - Linux (push) Has been cancelled
This commit is contained in:
+13
-1
@@ -61,6 +61,12 @@ Other Changes:
|
|||||||
- Multi-Select:
|
- Multi-Select:
|
||||||
- Fixed an issue using Multi-Select within a Table causing column width measurement to
|
- Fixed an issue using Multi-Select within a Table causing column width measurement to
|
||||||
be invalid when trailing column contents is not submitted in the last row. (#9341, #8250)
|
be invalid when trailing column contents is not submitted in the last row. (#9341, #8250)
|
||||||
|
- Fixed an issue using Multi-Select within a Table with the right-most column visible,
|
||||||
|
which could lead to an extra vertical offset in the Header row. (#8250)
|
||||||
|
- Box-Select: fixed an issue using ImGuiMultiSelectFlags_BoxSelect1d mode while scrolling.
|
||||||
|
Notably, using mouse wheel while holding a box-selection could lead items close to windows
|
||||||
|
edges from not being correctly unselected. (#7994, #8250, #7821, #7850, #7970)
|
||||||
|
- Box-Select: improved dirty/unclip rectangle logic for ImGuiMultiSelectFlags_BoxSelect2d.
|
||||||
- Box-Select: fixed an issue using ImGuiMultiSelectFlags_BoxSelect2d mode, where
|
- Box-Select: fixed an issue using ImGuiMultiSelectFlags_BoxSelect2d mode, where
|
||||||
items out of view wouldn't be properly selected while scrolling while mouse cursor
|
items out of view wouldn't be properly selected while scrolling while mouse cursor
|
||||||
is hovering outside of selection scope. (#7994, #1861, #6518)
|
is hovering outside of selection scope. (#7994, #1861, #6518)
|
||||||
@@ -74,7 +80,12 @@ Other Changes:
|
|||||||
and ImGuiSelectionUserData is technically opaque storage. (#7994, #1861)
|
and ImGuiSelectionUserData is technically opaque storage. (#7994, #1861)
|
||||||
(we will probably bring this back as a minor optimization if we have a way to for
|
(we will probably bring this back as a minor optimization if we have a way to for
|
||||||
user to tell us ImGuiSelectionUserData are indices)
|
user to tell us ImGuiSelectionUserData are indices)
|
||||||
- Box-Select, Tables: fixed an issue when calling `BeginMultiSelect()` in a table
|
- Box-Select: fixes for using accross nested child windows. (#8364)
|
||||||
|
- Box-Select + Clipper: fixed an issue selecting items while scrolling while a clipper
|
||||||
|
active. (#7994, #8250, #7821, #7850, #7970)
|
||||||
|
- Box-Select + Tables: fixed an issue using box-selection in a tables with
|
||||||
|
items straying out of columns boundaries. (#7994, #2221)
|
||||||
|
- Box-Select + Tables: fixed an issue when calling `BeginMultiSelect()` in a table
|
||||||
before layout has been locked (first row or headers row submitted). (#8250)
|
before layout has been locked (first row or headers row submitted). (#8250)
|
||||||
- Style:
|
- Style:
|
||||||
- Fixed vertical scrollbar top coordinates when using thick borders on windows
|
- Fixed vertical scrollbar top coordinates when using thick borders on windows
|
||||||
@@ -90,6 +101,7 @@ Other Changes:
|
|||||||
a better recoverable error. (#9350)
|
a better recoverable error. (#9350)
|
||||||
- Misc:
|
- Misc:
|
||||||
- Minor optimization: reduce redudant label scanning in common widgets.
|
- Minor optimization: reduce redudant label scanning in common widgets.
|
||||||
|
- Added missing Test Engine hooks for PlotXXX(), VSliderXXX(), TableHeader().
|
||||||
- Backends:
|
- Backends:
|
||||||
- Metal: avoid redundant vertex buffer bind in `SetupRenderState()`, which leads
|
- Metal: avoid redundant vertex buffer bind in `SetupRenderState()`, which leads
|
||||||
to validation issue. (#9343) [@Hunam6]
|
to validation issue. (#9343) [@Hunam6]
|
||||||
|
|||||||
@@ -3521,12 +3521,14 @@ static bool ImGuiListClipper_StepInternal(ImGuiListClipper* clipper)
|
|||||||
// FIXME: Selectable() use of half-ItemSpacing isn't consistent in matter of layout, as ItemAdd(bb) stray above ItemSize()'s CursorPos.
|
// FIXME: Selectable() use of half-ItemSpacing isn't consistent in matter of layout, as ItemAdd(bb) stray above ItemSize()'s CursorPos.
|
||||||
// RangeSelect's BoxSelect relies on comparing overlap of previous and current rectangle and is sensitive to that.
|
// RangeSelect's BoxSelect relies on comparing overlap of previous and current rectangle and is sensitive to that.
|
||||||
// As a workaround we currently half ItemSpacing worth on each side.
|
// As a workaround we currently half ItemSpacing worth on each side.
|
||||||
min_y -= g.Style.ItemSpacing.y;
|
float pad_y = g.Style.ItemSpacing.y;
|
||||||
max_y += g.Style.ItemSpacing.y;
|
min_y -= pad_y;
|
||||||
|
max_y += pad_y;
|
||||||
|
|
||||||
// Box-select on 2D area requires different clipping.
|
// Box-select on 2D area requires different clipping.
|
||||||
|
// (best adding pad_y here than in BeginBoxSelect() as we are closer to current state)
|
||||||
if (bs->UnclipMode)
|
if (bs->UnclipMode)
|
||||||
data->Ranges.push_back(ImGuiListClipperRange::FromPositions(bs->UnclipRect.Min.y, bs->UnclipRect.Max.y, 0, 0));
|
data->Ranges.push_back(ImGuiListClipperRange::FromPositions(bs->UnclipRect.Min.y - pad_y, bs->UnclipRect.Max.y + pad_y, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add main visible range
|
// Add main visible range
|
||||||
@@ -6095,14 +6097,6 @@ void ImGui::PopClipRect()
|
|||||||
window->ClipRect = window->DrawList->_ClipRectStack.back();
|
window->ClipRect = window->DrawList->_ClipRectStack.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
static ImGuiWindow* FindFrontMostVisibleChildWindow(ImGuiWindow* window)
|
|
||||||
{
|
|
||||||
for (int n = window->DC.ChildWindows.Size - 1; n >= 0; n--)
|
|
||||||
if (IsWindowActiveAndVisible(window->DC.ChildWindows[n]))
|
|
||||||
return FindFrontMostVisibleChildWindow(window->DC.ChildWindows[n]);
|
|
||||||
return window;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui::RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32 col)
|
static void ImGui::RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32 col)
|
||||||
{
|
{
|
||||||
if ((col & IM_COL32_A_MASK) == 0)
|
if ((col & IM_COL32_A_MASK) == 0)
|
||||||
@@ -6871,6 +6865,14 @@ void ImGui::EndChild()
|
|||||||
g.LogLinePosY = -FLT_MAX; // To enforce a carriage return
|
g.LogLinePosY = -FLT_MAX; // To enforce a carriage return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGuiWindow* ImGui::FindFrontMostVisibleChildWindow(ImGuiWindow* window)
|
||||||
|
{
|
||||||
|
for (int n = window->DC.ChildWindows.Size - 1; n >= 0; n--)
|
||||||
|
if (IsWindowActiveAndVisible(window->DC.ChildWindows[n]))
|
||||||
|
return FindFrontMostVisibleChildWindow(window->DC.ChildWindows[n]);
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
|
||||||
static void SetWindowConditionAllowFlags(ImGuiWindow* window, ImGuiCond flags, bool enabled)
|
static void SetWindowConditionAllowFlags(ImGuiWindow* window, ImGuiCond flags, bool enabled)
|
||||||
{
|
{
|
||||||
window->SetWindowPosAllowFlags = enabled ? (window->SetWindowPosAllowFlags | flags) : (window->SetWindowPosAllowFlags & ~flags);
|
window->SetWindowPosAllowFlags = enabled ? (window->SetWindowPosAllowFlags | flags) : (window->SetWindowPosAllowFlags & ~flags);
|
||||||
@@ -9381,6 +9383,17 @@ void ImGui::PopFocusScope()
|
|||||||
g.CurrentFocusScopeId = g.FocusScopeStack.Size ? g.FocusScopeStack.back().ID : 0;
|
g.CurrentFocusScopeId = g.FocusScopeStack.Size ? g.FocusScopeStack.back().ID : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ImGui::IsInNavFocusRoute(ImGuiID focus_scope_id)
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
if (g.NavFocusScopeId == focus_scope_id)
|
||||||
|
return true;
|
||||||
|
for (const ImGuiFocusScopeData& focus_scope : g.NavFocusRoute)
|
||||||
|
if (focus_scope.ID == focus_scope_id)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void ImGui::SetNavFocusScope(ImGuiID focus_scope_id)
|
void ImGui::SetNavFocusScope(ImGuiID focus_scope_id)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
@@ -11457,7 +11470,8 @@ bool ImGui::DebugCheckVersionAndDataLayout(const char* version, size_t sz_io, si
|
|||||||
// to extend contents size of our parent container (e.g. window contents size, which is used for auto-resizing
|
// to extend contents size of our parent container (e.g. window contents size, which is used for auto-resizing
|
||||||
// windows, table column contents size used for auto-resizing columns, group size).
|
// windows, table column contents size used for auto-resizing columns, group size).
|
||||||
// This was causing issues and ambiguities and we needed to retire that.
|
// This was causing issues and ambiguities and we needed to retire that.
|
||||||
// From 1.89, extending contents size boundaries REQUIRES AN ITEM TO BE SUBMITTED.
|
// 2022/08/05 (1.89): extending contents size boundaries REQUIRES AN ITEM TO BE SUBMITTED. However we gated the new logic behind a '#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS' block.
|
||||||
|
// 2025/06/25 (1.92): removed the legacy path and turned into an assert. It was a mistake that there was a #ifndef before: our obsolescence schedule gets pushed back a bit more :(
|
||||||
//
|
//
|
||||||
// Previously this would make the window content size ~200x200:
|
// Previously this would make the window content size ~200x200:
|
||||||
// Begin(...) + SetCursorScreenPos(GetCursorScreenPos() + ImVec2(200,200)) + End(); // NOT OK ANYMORE
|
// Begin(...) + SetCursorScreenPos(GetCursorScreenPos() + ImVec2(200,200)) + End(); // NOT OK ANYMORE
|
||||||
@@ -14042,7 +14056,7 @@ static void ImGui::NavProcessItem()
|
|||||||
const ImGuiID id = g.LastItemData.ID;
|
const ImGuiID id = g.LastItemData.ID;
|
||||||
const ImGuiItemFlags item_flags = g.LastItemData.ItemFlags;
|
const ImGuiItemFlags item_flags = g.LastItemData.ItemFlags;
|
||||||
|
|
||||||
// When inside a container that isn't scrollable with Left<>Right, clip NavRect accordingly (#2221, #8816)
|
// When inside a container that isn't scrollable with Left<>Right, clip NavRect accordingly (#2221, #8816, #7994)
|
||||||
ImRect nav_bb = g.LastItemData.NavRect;
|
ImRect nav_bb = g.LastItemData.NavRect;
|
||||||
if (window->DC.NavIsScrollPushableX == false)
|
if (window->DC.NavIsScrollPushableX == false)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
// Library Version
|
// Library Version
|
||||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
||||||
#define IMGUI_VERSION "1.92.8 WIP"
|
#define IMGUI_VERSION "1.92.8 WIP"
|
||||||
#define IMGUI_VERSION_NUM 19272
|
#define IMGUI_VERSION_NUM 19273
|
||||||
#define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000
|
#define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000
|
||||||
#define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198
|
#define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198
|
||||||
#define IMGUI_HAS_VIEWPORT // In 'docking' WIP branch.
|
#define IMGUI_HAS_VIEWPORT // In 'docking' WIP branch.
|
||||||
|
|||||||
+10
-3
@@ -11069,8 +11069,9 @@ struct ExampleAssetsBrowser
|
|||||||
bool AllowDragUnselected = false; // Will set ImGuiMultiSelectFlags_SelectOnClickRelease
|
bool AllowDragUnselected = false; // Will set ImGuiMultiSelectFlags_SelectOnClickRelease
|
||||||
float IconSize = 0;
|
float IconSize = 0;
|
||||||
int IconSpacing = 10;
|
int IconSpacing = 10;
|
||||||
int IconHitSpacing = 4; // Increase hit-spacing if you want to make it possible to clear or box-select from gaps. Some spacing is required to able to amend with Shift+box-select. Value is small in Explorer.
|
int IconHitSpacing = 4; // Increase hit-spacing if you want to make it possible to clear or box-select from gaps. Some spacing is required to able to amend with Shift+box-select. Value is small in Explorer.
|
||||||
bool StretchSpacing = true;
|
bool StretchSpacing = true;
|
||||||
|
bool UseScrollX = false; // Debug: submit twice the number of items per line (overflow horizontally to exercise ScrollX + box-select)
|
||||||
|
|
||||||
// State
|
// State
|
||||||
ImVector<ExampleAsset> Items; // Our items
|
ImVector<ExampleAsset> Items; // Our items
|
||||||
@@ -11121,12 +11122,15 @@ struct ExampleAssetsBrowser
|
|||||||
// Layout: calculate number of icon per line and number of lines
|
// Layout: calculate number of icon per line and number of lines
|
||||||
LayoutItemSize = ImVec2(floorf(IconSize), floorf(IconSize));
|
LayoutItemSize = ImVec2(floorf(IconSize), floorf(IconSize));
|
||||||
LayoutColumnCount = IM_MAX((int)(avail_width / (LayoutItemSize.x + LayoutItemSpacing)), 1);
|
LayoutColumnCount = IM_MAX((int)(avail_width / (LayoutItemSize.x + LayoutItemSpacing)), 1);
|
||||||
LayoutLineCount = (Items.Size + LayoutColumnCount - 1) / LayoutColumnCount;
|
|
||||||
|
|
||||||
// Layout: when stretching: allocate remaining space to more spacing. Round before division, so item_spacing may be non-integer.
|
// Layout: when stretching: allocate remaining space to more spacing. Round before division, so item_spacing may be non-integer.
|
||||||
if (StretchSpacing && LayoutColumnCount > 1)
|
if (StretchSpacing && LayoutColumnCount > 1)
|
||||||
LayoutItemSpacing = floorf(avail_width - LayoutItemSize.x * LayoutColumnCount) / LayoutColumnCount;
|
LayoutItemSpacing = floorf(avail_width - LayoutItemSize.x * LayoutColumnCount) / LayoutColumnCount;
|
||||||
|
|
||||||
|
if (UseScrollX)
|
||||||
|
LayoutColumnCount *= 2;
|
||||||
|
LayoutLineCount = (Items.Size + LayoutColumnCount - 1) / LayoutColumnCount;
|
||||||
|
|
||||||
LayoutItemStep = ImVec2(LayoutItemSize.x + LayoutItemSpacing, LayoutItemSize.y + LayoutItemSpacing);
|
LayoutItemStep = ImVec2(LayoutItemSize.x + LayoutItemSpacing, LayoutItemSize.y + LayoutItemSpacing);
|
||||||
LayoutSelectableSpacing = IM_MAX(floorf(LayoutItemSpacing) - IconHitSpacing, 0.0f);
|
LayoutSelectableSpacing = IM_MAX(floorf(LayoutItemSpacing) - IconHitSpacing, 0.0f);
|
||||||
LayoutOuterPadding = floorf(LayoutItemSpacing * 0.5f);
|
LayoutOuterPadding = floorf(LayoutItemSpacing * 0.5f);
|
||||||
@@ -11186,6 +11190,7 @@ struct ExampleAssetsBrowser
|
|||||||
ImGui::SliderInt("Icon Spacing", &IconSpacing, 0, 32);
|
ImGui::SliderInt("Icon Spacing", &IconSpacing, 0, 32);
|
||||||
ImGui::SliderInt("Icon Hit Spacing", &IconHitSpacing, 0, 32);
|
ImGui::SliderInt("Icon Hit Spacing", &IconHitSpacing, 0, 32);
|
||||||
ImGui::Checkbox("Stretch Spacing", &StretchSpacing);
|
ImGui::Checkbox("Stretch Spacing", &StretchSpacing);
|
||||||
|
ImGui::Checkbox("Use ScrollX", &UseScrollX);
|
||||||
ImGui::PopItemWidth();
|
ImGui::PopItemWidth();
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
@@ -11215,7 +11220,7 @@ struct ExampleAssetsBrowser
|
|||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImGui::SetNextWindowContentSize(ImVec2(0.0f, LayoutOuterPadding + LayoutLineCount * (LayoutItemSize.y + LayoutItemSpacing)));
|
ImGui::SetNextWindowContentSize(ImVec2(0.0f, LayoutOuterPadding + LayoutLineCount * (LayoutItemSize.y + LayoutItemSpacing)));
|
||||||
if (ImGui::BeginChild("Assets", ImVec2(0.0f, -ImGui::GetTextLineHeightWithSpacing()), ImGuiChildFlags_Borders, ImGuiWindowFlags_NoMove))
|
if (ImGui::BeginChild("Assets", ImVec2(0.0f, -ImGui::GetTextLineHeightWithSpacing()), ImGuiChildFlags_Borders, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_HorizontalScrollbar))
|
||||||
{
|
{
|
||||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||||
|
|
||||||
@@ -11359,6 +11364,8 @@ struct ExampleAssetsBrowser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
clipper.End();
|
clipper.End();
|
||||||
|
if (Items.Size == 0)
|
||||||
|
ImGui::Dummy(ImVec2(0, 0));
|
||||||
ImGui::PopStyleVar(); // ImGuiStyleVar_ItemSpacing
|
ImGui::PopStyleVar(); // ImGuiStyleVar_ItemSpacing
|
||||||
|
|
||||||
// Context menu
|
// Context menu
|
||||||
|
|||||||
@@ -617,6 +617,8 @@ struct IMGUI_API ImRect
|
|||||||
bool Overlaps(const ImRect& r) const { return r.Min.y < Max.y && r.Max.y > Min.y && r.Min.x < Max.x && r.Max.x > Min.x; }
|
bool Overlaps(const ImRect& r) const { return r.Min.y < Max.y && r.Max.y > Min.y && r.Min.x < Max.x && r.Max.x > Min.x; }
|
||||||
void Add(const ImVec2& p) { if (Min.x > p.x) Min.x = p.x; if (Min.y > p.y) Min.y = p.y; if (Max.x < p.x) Max.x = p.x; if (Max.y < p.y) Max.y = p.y; }
|
void Add(const ImVec2& p) { if (Min.x > p.x) Min.x = p.x; if (Min.y > p.y) Min.y = p.y; if (Max.x < p.x) Max.x = p.x; if (Max.y < p.y) Max.y = p.y; }
|
||||||
void Add(const ImRect& r) { if (Min.x > r.Min.x) Min.x = r.Min.x; if (Min.y > r.Min.y) Min.y = r.Min.y; if (Max.x < r.Max.x) Max.x = r.Max.x; if (Max.y < r.Max.y) Max.y = r.Max.y; }
|
void Add(const ImRect& r) { if (Min.x > r.Min.x) Min.x = r.Min.x; if (Min.y > r.Min.y) Min.y = r.Min.y; if (Max.x < r.Max.x) Max.x = r.Max.x; if (Max.y < r.Max.y) Max.y = r.Max.y; }
|
||||||
|
void AddX(float x) { if (Min.x > x) Min.x = x; if (Max.x < x) Max.x = x; }
|
||||||
|
void AddY(float y) { if (Min.y > y) Min.y = y; if (Max.y < y) Max.y = y; }
|
||||||
void Expand(const float amount) { Min.x -= amount; Min.y -= amount; Max.x += amount; Max.y += amount; }
|
void Expand(const float amount) { Min.x -= amount; Min.y -= amount; Max.x += amount; Max.y += amount; }
|
||||||
void Expand(const ImVec2& amount) { Min.x -= amount.x; Min.y -= amount.y; Max.x += amount.x; Max.y += amount.y; }
|
void Expand(const ImVec2& amount) { Min.x -= amount.x; Min.y -= amount.y; Max.x += amount.x; Max.y += amount.y; }
|
||||||
void Translate(const ImVec2& d) { Min.x += d.x; Min.y += d.y; Max.x += d.x; Max.y += d.y; }
|
void Translate(const ImVec2& d) { Min.x += d.x; Min.y += d.y; Max.x += d.x; Max.y += d.y; }
|
||||||
@@ -1915,6 +1917,7 @@ struct ImGuiBoxSelectState
|
|||||||
// Temporary/Transient data
|
// Temporary/Transient data
|
||||||
bool UnclipMode; // (Temp/Transient, here in hot area). Set/cleared by the BeginMultiSelect()/EndMultiSelect() owning active box-select.
|
bool UnclipMode; // (Temp/Transient, here in hot area). Set/cleared by the BeginMultiSelect()/EndMultiSelect() owning active box-select.
|
||||||
ImRect UnclipRect; // Rectangle where ItemAdd() clipping may be temporarily disabled. Need support by multi-select supporting widgets.
|
ImRect UnclipRect; // Rectangle where ItemAdd() clipping may be temporarily disabled. Need support by multi-select supporting widgets.
|
||||||
|
ImRect UnclipRects[2]; // Per-axis versions.
|
||||||
ImRect BoxSelectRectPrev; // Selection rectangle in absolute coordinates (derived every frame from BoxSelectStartPosRel and MousePos)
|
ImRect BoxSelectRectPrev; // Selection rectangle in absolute coordinates (derived every frame from BoxSelectStartPosRel and MousePos)
|
||||||
ImRect BoxSelectRectCurr;
|
ImRect BoxSelectRectCurr;
|
||||||
|
|
||||||
@@ -3562,6 +3565,7 @@ namespace ImGui
|
|||||||
|
|
||||||
// Childs
|
// Childs
|
||||||
IMGUI_API bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, ImGuiChildFlags child_flags, ImGuiWindowFlags window_flags);
|
IMGUI_API bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, ImGuiChildFlags child_flags, ImGuiWindowFlags window_flags);
|
||||||
|
IMGUI_API ImGuiWindow* FindFrontMostVisibleChildWindow(ImGuiWindow* window);
|
||||||
|
|
||||||
// Popups, Modals
|
// Popups, Modals
|
||||||
IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_window_flags);
|
IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_window_flags);
|
||||||
@@ -3770,6 +3774,7 @@ namespace ImGui
|
|||||||
// We don't use the ID Stack for this as it is common to want them separate.
|
// We don't use the ID Stack for this as it is common to want them separate.
|
||||||
IMGUI_API void PushFocusScope(ImGuiID id);
|
IMGUI_API void PushFocusScope(ImGuiID id);
|
||||||
IMGUI_API void PopFocusScope();
|
IMGUI_API void PopFocusScope();
|
||||||
|
IMGUI_API bool IsInNavFocusRoute(ImGuiID focus_scope_id);
|
||||||
inline ImGuiID GetCurrentFocusScope() { ImGuiContext& g = *GImGui; return g.CurrentFocusScopeId; } // Focus scope we are outputting into, set by PushFocusScope()
|
inline ImGuiID GetCurrentFocusScope() { ImGuiContext& g = *GImGui; return g.CurrentFocusScopeId; } // Focus scope we are outputting into, set by PushFocusScope()
|
||||||
|
|
||||||
// Drag and Drop
|
// Drag and Drop
|
||||||
|
|||||||
@@ -1330,6 +1330,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
// When starting a BeginMultiSelect() after table has been layout we update IsRequestOutput fields.
|
// When starting a BeginMultiSelect() after table has been layout we update IsRequestOutput fields.
|
||||||
void ImGui::TableApplyExternalUnclipRect(ImGuiTable* table, ImRect& rect)
|
void ImGui::TableApplyExternalUnclipRect(ImGuiTable* table, ImRect& rect)
|
||||||
{
|
{
|
||||||
|
if (rect.IsInverted())
|
||||||
|
return;
|
||||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||||
{
|
{
|
||||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||||
@@ -3311,6 +3313,8 @@ void ImGui::TableHeader(const char* label)
|
|||||||
// We don't use BeginPopupContextItem() because we want the popup to stay up even after the column is hidden
|
// We don't use BeginPopupContextItem() because we want the popup to stay up even after the column is hidden
|
||||||
if (IsPopupOpenRequestForItem(ImGuiPopupFlags_None, id))
|
if (IsPopupOpenRequestForItem(ImGuiPopupFlags_None, id))
|
||||||
TableOpenContextMenu(column_n);
|
TableOpenContextMenu(column_n);
|
||||||
|
|
||||||
|
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unlike TableHeadersRow() it is not expected that you can reimplement or customize this with custom widgets.
|
// Unlike TableHeadersRow() it is not expected that you can reimplement or customize this with custom widgets.
|
||||||
|
|||||||
+83
-27
@@ -1565,7 +1565,7 @@ bool ImGui::TextLink(const char* label)
|
|||||||
window->DrawList->AddLine(ImVec2(bb.Min.x, line_y), ImVec2(bb.Max.x, line_y), GetColorU32(line_colf), 1.0f * (float)(int)g.Style._MainScale); // FIXME-TEXT: Underline mode // FIXME-DPI
|
window->DrawList->AddLine(ImVec2(bb.Min.x, line_y), ImVec2(bb.Max.x, line_y), GetColorU32(line_colf), 1.0f * (float)(int)g.Style._MainScale); // FIXME-TEXT: Underline mode // FIXME-DPI
|
||||||
|
|
||||||
PushStyleColor(ImGuiCol_Text, GetColorU32(text_colf));
|
PushStyleColor(ImGuiCol_Text, GetColorU32(text_colf));
|
||||||
RenderText(bb.Min, label, label_end);
|
RenderText(bb.Min, label, label_end, false);
|
||||||
PopStyleColor();
|
PopStyleColor();
|
||||||
|
|
||||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
|
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
|
||||||
@@ -1957,7 +1957,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
|
|||||||
const float arrow_size = (flags & ImGuiComboFlags_NoArrowButton) ? 0.0f : GetFrameHeight();
|
const float arrow_size = (flags & ImGuiComboFlags_NoArrowButton) ? 0.0f : GetFrameHeight();
|
||||||
const char* label_end = FindRenderedTextEnd(label);
|
const char* label_end = FindRenderedTextEnd(label);
|
||||||
const ImVec2 label_size = CalcTextSize(label, label_end, false);
|
const ImVec2 label_size = CalcTextSize(label, label_end, false);
|
||||||
const float preview_width = ((flags & ImGuiComboFlags_WidthFitPreview) && (preview_value != NULL)) ? CalcTextSize(preview_value, NULL, true).x : 0.0f;
|
const float preview_width = ((flags & ImGuiComboFlags_WidthFitPreview) && (preview_value != NULL)) ? CalcTextSize(preview_value, NULL, false).x : 0.0f;
|
||||||
const float w = (flags & ImGuiComboFlags_NoPreview) ? arrow_size : ((flags & ImGuiComboFlags_WidthFitPreview) ? (arrow_size + preview_width + style.FramePadding.x * 2.0f) : CalcItemWidth());
|
const float w = (flags & ImGuiComboFlags_NoPreview) ? arrow_size : ((flags & ImGuiComboFlags_WidthFitPreview) ? (arrow_size + preview_width + style.FramePadding.x * 2.0f) : CalcItemWidth());
|
||||||
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f));
|
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f));
|
||||||
const ImRect total_bb(bb.Min, bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
const ImRect total_bb(bb.Min, bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
||||||
@@ -3549,6 +3549,7 @@ bool ImGui::VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType d
|
|||||||
if (label_size.x > 0.0f)
|
if (label_size.x > 0.0f)
|
||||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label, label_end, false);
|
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label, label_end, false);
|
||||||
|
|
||||||
|
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
|
||||||
return value_changed;
|
return value_changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7514,8 +7515,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
|||||||
RenderTextClipped(pos, ImVec2(ImMin(pos.x + size.x, window->WorkRect.Max.x), pos.y + size.y), label, label_end, &label_size, style.SelectableTextAlign, &bb);
|
RenderTextClipped(pos, ImVec2(ImMin(pos.x + size.x, window->WorkRect.Max.x), pos.y + size.y), label, label_end, &label_size, style.SelectableTextAlign, &bb);
|
||||||
|
|
||||||
#ifdef IMGUI_DEBUG_BOXSELECT
|
#ifdef IMGUI_DEBUG_BOXSELECT
|
||||||
if (g.BoxSelectState.UnclipMode)
|
if (g.BoxSelectState.UnclipMode) { GetForegroundDrawList()->AddText(pos, IM_COL32(255,255,0,200), label, label_end); }
|
||||||
GetForegroundDrawList()->AddText(pos, IM_COL32(255,255,0,200), label);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Automatically close popups
|
// Automatically close popups
|
||||||
@@ -7833,7 +7833,7 @@ bool ImGui::BeginBoxSelect(const ImRect& scope_rect, ImGuiWindow* window, ImGuiI
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Current frame absolute prev/current rectangles are used to toggle selection.
|
// Current frame absolute prev/current rectangles are used to toggle selection.
|
||||||
// They are derived from positions relative to scrolling space.
|
// They are derived from positions relative to scrolling space, so "previous" rectangle is reprojected for current frame coordinates.
|
||||||
ImVec2 start_pos_abs = WindowPosRelToAbs(window, bs->StartPosRel);
|
ImVec2 start_pos_abs = WindowPosRelToAbs(window, bs->StartPosRel);
|
||||||
ImVec2 prev_end_pos_abs = WindowPosRelToAbs(window, bs->EndPosRel); // Clamped already
|
ImVec2 prev_end_pos_abs = WindowPosRelToAbs(window, bs->EndPosRel); // Clamped already
|
||||||
ImVec2 curr_end_pos_abs = g.IO.MousePos;
|
ImVec2 curr_end_pos_abs = g.IO.MousePos;
|
||||||
@@ -7843,26 +7843,68 @@ bool ImGui::BeginBoxSelect(const ImRect& scope_rect, ImGuiWindow* window, ImGuiI
|
|||||||
bs->BoxSelectRectPrev.Max = ImMax(start_pos_abs, prev_end_pos_abs);
|
bs->BoxSelectRectPrev.Max = ImMax(start_pos_abs, prev_end_pos_abs);
|
||||||
bs->BoxSelectRectCurr.Min = ImMin(start_pos_abs, curr_end_pos_abs);
|
bs->BoxSelectRectCurr.Min = ImMin(start_pos_abs, curr_end_pos_abs);
|
||||||
bs->BoxSelectRectCurr.Max = ImMax(start_pos_abs, curr_end_pos_abs);
|
bs->BoxSelectRectCurr.Max = ImMax(start_pos_abs, curr_end_pos_abs);
|
||||||
|
//IMGUI_DEBUG_LOG("StartPosRel (%.2f,%.2f) EndPosRel (%.2f,%.2f) -> (%.2f,%.2f)\n", bs->StartPosRel.x, bs->StartPosRel.y, bs->EndPosRel.x, bs->EndPosRel.y, WindowPosAbsToRel(window, g.IO.MousePos).x, WindowPosAbsToRel(window, g.IO.MousePos).y);
|
||||||
|
|
||||||
// Box-select 2D mode detects change of the rectangle.
|
// Box-select 2D mode detects change of the rectangle.
|
||||||
// Storing unclip rect used by widgets supporting box-select.
|
// Storing unclip rects which will be tested by widgets supporting box-select. Always update rectangles when active (even if we don't use them).
|
||||||
if (ms_flags & ImGuiMultiSelectFlags_BoxSelect2d)
|
// To facilitate understanding this: enable IMGUI_DEBUG_BOXSELECT and visualize all geometry.
|
||||||
|
if (ms_flags & (ImGuiMultiSelectFlags_BoxSelect1d | ImGuiMultiSelectFlags_BoxSelect2d))
|
||||||
{
|
{
|
||||||
if (bs->BoxSelectRectPrev.Min != bs->BoxSelectRectCurr.Min || bs->BoxSelectRectPrev.Max != bs->BoxSelectRectCurr.Max)
|
// For both sides, compute the area differing between Prev and Curr rectangles.
|
||||||
bs->UnclipMode = true;
|
bs->UnclipRects[0] = bs->UnclipRects[1] = ImRect(+FLT_MAX, +FLT_MAX, -FLT_MAX, -FLT_MAX);
|
||||||
|
for (int side = 0; side < 2; side++)
|
||||||
|
{
|
||||||
|
ImVec2 d_min = (side == 0) ? ImMin(bs->BoxSelectRectCurr.Min, bs->BoxSelectRectPrev.Min) : ImMin(bs->BoxSelectRectCurr.Max, bs->BoxSelectRectPrev.Max);
|
||||||
|
ImVec2 d_max = (side == 0) ? ImMax(bs->BoxSelectRectCurr.Min, bs->BoxSelectRectPrev.Min) : ImMax(bs->BoxSelectRectCurr.Max, bs->BoxSelectRectPrev.Max);
|
||||||
|
if (d_min.x != d_max.x)
|
||||||
|
{
|
||||||
|
bs->UnclipRects[0].AddX(d_min.x);
|
||||||
|
bs->UnclipRects[0].AddX(d_max.x);
|
||||||
|
}
|
||||||
|
if (d_min.y != d_max.y)
|
||||||
|
{
|
||||||
|
bs->UnclipRects[1].AddY(d_min.y);
|
||||||
|
bs->UnclipRects[1].AddY(d_max.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Always update rect even if we don't use it.
|
ImRect box_select_intersection = bs->BoxSelectRectPrev;
|
||||||
bs->UnclipRect = bs->BoxSelectRectPrev; // FIXME-OPT: UnclipRect X coordinates could be intersection of Prev and Curr rect on X axis.
|
box_select_intersection.Add(bs->BoxSelectRectCurr);
|
||||||
bs->UnclipRect.Add(bs->BoxSelectRectCurr);
|
if (ms_flags & ImGuiMultiSelectFlags_BoxSelect2d)
|
||||||
|
if (bs->BoxSelectRectPrev.Min.x != bs->BoxSelectRectCurr.Min.x || bs->BoxSelectRectPrev.Max.x != bs->BoxSelectRectCurr.Max.x)
|
||||||
|
{
|
||||||
|
bs->UnclipRects[0].AddY(box_select_intersection.Min.y);
|
||||||
|
bs->UnclipRects[0].AddY(box_select_intersection.Max.y);
|
||||||
|
}
|
||||||
|
if (ms_flags & (ImGuiMultiSelectFlags_BoxSelect1d | ImGuiMultiSelectFlags_BoxSelect2d))
|
||||||
|
if (bs->BoxSelectRectPrev.Min.y != bs->BoxSelectRectCurr.Min.y || bs->BoxSelectRectPrev.Max.y != bs->BoxSelectRectCurr.Max.y)
|
||||||
|
{
|
||||||
|
bs->UnclipRects[1].AddX(box_select_intersection.Min.x);
|
||||||
|
bs->UnclipRects[1].AddX(box_select_intersection.Max.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge both rectangles into one.
|
||||||
|
// FIXME-OPT: When UnclipRect.Area() is much larger than the sum of UnclipRects[0]/[1] Areas, widgets should
|
||||||
|
// ideally first use UnclipRect as a first coarse cull layer + the individual ones as a second validation.
|
||||||
|
bs->UnclipRect = bs->UnclipRects[0];
|
||||||
|
bs->UnclipRect.Add(bs->UnclipRects[1]);
|
||||||
|
if (!bs->UnclipRect.IsInverted() && (!window->ClipRect.Contains(bs->UnclipRect.Min) || !window->ClipRect.Contains(bs->UnclipRect.Max))) // !! Don't use Contains(ImRect)
|
||||||
|
bs->UnclipMode = true;
|
||||||
|
if (bs->UnclipMode && g.CurrentTable != NULL)
|
||||||
|
TableApplyExternalUnclipRect(g.CurrentTable, bs->UnclipRect); // No need submitting both
|
||||||
}
|
}
|
||||||
if (bs->UnclipMode && g.CurrentTable != NULL)
|
|
||||||
TableApplyExternalUnclipRect(g.CurrentTable, bs->UnclipRect);
|
|
||||||
|
|
||||||
#ifdef IMGUI_DEBUG_BOXSELECT
|
#ifdef IMGUI_DEBUG_BOXSELECT
|
||||||
if (ms_flags & ImGuiMultiSelectFlags_BoxSelect2d)
|
//GetForegroundDrawList()->AddRect(scope_rect.Min, scope_rect.Max, IM_COL32(0, 255, 0, 200), 0.0f, 0, 4.0f);
|
||||||
GetForegroundDrawList()->AddRect(bs->UnclipRect.Min, bs->UnclipRect.Max, bs->UnclipMode ? IM_COL32(255,255,0,200) : IM_COL32(255,0,0,200), 0.0f, 0, 4.0f);
|
|
||||||
//GetForegroundDrawList()->AddRect(bs->BoxSelectRectPrev.Min, bs->BoxSelectRectPrev.Max, IM_COL32(255,0,0,200), 0.0f, 0, 3.0f);
|
//GetForegroundDrawList()->AddRect(bs->BoxSelectRectPrev.Min, bs->BoxSelectRectPrev.Max, IM_COL32(255,0,0,200), 0.0f, 0, 3.0f);
|
||||||
//GetForegroundDrawList()->AddRect(bs->BoxSelectRectCurr.Min, bs->BoxSelectRectCurr.Max, IM_COL32(0,255,0,200), 0.0f, 0, 1.0f);
|
//GetForegroundDrawList()->AddRect(bs->BoxSelectRectCurr.Min, bs->BoxSelectRectCurr.Max, IM_COL32(0,255,0,200), 0.0f, 0, 1.0f);
|
||||||
|
if (ms_flags & (ImGuiMultiSelectFlags_BoxSelect1d | ImGuiMultiSelectFlags_BoxSelect2d))
|
||||||
|
{
|
||||||
|
for (ImRect& unclip_r : bs->UnclipRects)
|
||||||
|
if (!unclip_r.IsInverted())
|
||||||
|
GetForegroundDrawList()->AddRect(unclip_r.Min, unclip_r.Max, bs->UnclipMode ? IM_COL32(255, 255, 0, 200) : IM_COL32(255, 0, 0, 200), 0.0f, 0, 4.0f);
|
||||||
|
GetForegroundDrawList()->AddRect(bs->UnclipRect.Min, bs->UnclipRect.Max, bs->UnclipMode ? IM_COL32(255, 255, 0, 200) : IM_COL32(255, 0, 0, 200), 0.0f, 0, 2.0f);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -7879,8 +7921,9 @@ void ImGui::EndBoxSelect(const ImRect& scope_rect, ImGuiMultiSelectFlags ms_flag
|
|||||||
bs->EndPosRel = WindowPosAbsToRel(window, ImClamp(g.IO.MousePos, scope_rect.Min, scope_rect.Max)); // Clamp stored position according to current scrolling view
|
bs->EndPosRel = WindowPosAbsToRel(window, ImClamp(g.IO.MousePos, scope_rect.Min, scope_rect.Max)); // Clamp stored position according to current scrolling view
|
||||||
ImRect box_select_r = bs->BoxSelectRectCurr;
|
ImRect box_select_r = bs->BoxSelectRectCurr;
|
||||||
box_select_r.ClipWith(scope_rect);
|
box_select_r.ClipWith(scope_rect);
|
||||||
window->DrawList->AddRectFilled(box_select_r.Min, box_select_r.Max, GetColorU32(ImGuiCol_SeparatorHovered, 0.30f)); // FIXME-MULTISELECT: Styling
|
ImGuiWindow* draw_window = FindFrontMostVisibleChildWindow(window);
|
||||||
window->DrawList->AddRect(box_select_r.Min, box_select_r.Max, GetColorU32(ImGuiCol_NavCursor)); // FIXME-MULTISELECT FIXME-DPI: Styling
|
draw_window->DrawList->AddRectFilled(box_select_r.Min, box_select_r.Max, GetColorU32(ImGuiCol_SeparatorHovered, 0.30f)); // FIXME-MULTISELECT: Styling
|
||||||
|
draw_window->DrawList->AddRect(box_select_r.Min, box_select_r.Max, GetColorU32(ImGuiCol_NavCursor)); // FIXME-MULTISELECT FIXME-DPI: Styling
|
||||||
|
|
||||||
// Scroll
|
// Scroll
|
||||||
const bool enable_scroll = (ms_flags & ImGuiMultiSelectFlags_ScopeWindow) && (ms_flags & ImGuiMultiSelectFlags_BoxSelectNoScroll) == 0;
|
const bool enable_scroll = (ms_flags & ImGuiMultiSelectFlags_ScopeWindow) && (ms_flags & ImGuiMultiSelectFlags_BoxSelectNoScroll) == 0;
|
||||||
@@ -7920,7 +7963,6 @@ static void DebugLogMultiSelectRequests(const char* function, const ImGuiMultiSe
|
|||||||
|
|
||||||
static ImRect CalcScopeRect(ImGuiMultiSelectTempData* ms, ImGuiWindow* window)
|
static ImRect CalcScopeRect(ImGuiMultiSelectTempData* ms, ImGuiWindow* window)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
|
||||||
if (ms->Flags & ImGuiMultiSelectFlags_ScopeRect)
|
if (ms->Flags & ImGuiMultiSelectFlags_ScopeRect)
|
||||||
{
|
{
|
||||||
// Warning: this depends on CursorMaxPos so it means to be called by EndMultiSelect() only
|
// Warning: this depends on CursorMaxPos so it means to be called by EndMultiSelect() only
|
||||||
@@ -7929,10 +7971,10 @@ static ImRect CalcScopeRect(ImGuiMultiSelectTempData* ms, ImGuiWindow* window)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// When a table, pull HostClipRect, which allows us to predict ClipRect before first row/layout is performed. (#7970)
|
//// When a table, pull HostClipRect, which allows us to predict ClipRect before first row/layout is performed. (#7970)
|
||||||
ImRect scope_rect = window->InnerClipRect;
|
ImRect scope_rect = window->InnerClipRect;
|
||||||
if (g.CurrentTable != NULL)
|
//if (g.CurrentTable != NULL)
|
||||||
scope_rect = g.CurrentTable->HostClipRect;
|
// scope_rect = g.CurrentTable->HostClipRect;
|
||||||
|
|
||||||
// Add inner table decoration (#7821) // FIXME: Why not baking in InnerClipRect?
|
// Add inner table decoration (#7821) // FIXME: Why not baking in InnerClipRect?
|
||||||
scope_rect.Min = ImMin(scope_rect.Min + ImVec2(window->DecoInnerSizeX1, window->DecoInnerSizeY1), scope_rect.Max);
|
scope_rect.Min = ImMin(scope_rect.Min + ImVec2(window->DecoInnerSizeX1, window->DecoInnerSizeY1), scope_rect.Max);
|
||||||
@@ -7980,10 +8022,12 @@ ImGuiMultiSelectIO* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, int sel
|
|||||||
ms->Clear();
|
ms->Clear();
|
||||||
ms->FocusScopeId = id;
|
ms->FocusScopeId = id;
|
||||||
ms->Flags = flags;
|
ms->Flags = flags;
|
||||||
ms->IsFocused = (ms->FocusScopeId == g.NavFocusScopeId);
|
|
||||||
ms->BackupCursorMaxPos = window->DC.CursorMaxPos;
|
ms->BackupCursorMaxPos = window->DC.CursorMaxPos;
|
||||||
ms->ScopeRectMin = window->DC.CursorMaxPos = window->DC.CursorPos; // CalcScopeRect() for ImGuiMultiSelectFlags_ScopeRect will measure in EndMultiSelect().
|
ms->ScopeRectMin = window->DC.CursorPos;
|
||||||
|
if (flags & ImGuiMultiSelectFlags_ScopeRect)
|
||||||
|
window->DC.CursorMaxPos = ms->ScopeRectMin; // CalcScopeRect() for ImGuiMultiSelectFlags_ScopeRect will measure in EndMultiSelect().
|
||||||
PushFocusScope(ms->FocusScopeId);
|
PushFocusScope(ms->FocusScopeId);
|
||||||
|
ms->IsFocused = IsInNavFocusRoute(g.CurrentFocusScopeId);
|
||||||
if (flags & ImGuiMultiSelectFlags_ScopeWindow) // Mark parent child window as navigable into, with highlight. Assume user will always submit interactive items.
|
if (flags & ImGuiMultiSelectFlags_ScopeWindow) // Mark parent child window as navigable into, with highlight. Assume user will always submit interactive items.
|
||||||
window->DC.NavLayersActiveMask |= 1 << ImGuiNavLayer_Main;
|
window->DC.NavLayersActiveMask |= 1 << ImGuiNavLayer_Main;
|
||||||
|
|
||||||
@@ -8111,7 +8155,7 @@ ImGuiMultiSelectIO* ImGui::EndMultiSelect()
|
|||||||
// Clear selection when clicking void?
|
// Clear selection when clicking void?
|
||||||
// We specifically test for IsMouseDragPastThreshold(0) == false to allow box-selection!
|
// We specifically test for IsMouseDragPastThreshold(0) == false to allow box-selection!
|
||||||
// The InnerRect test is necessary for non-child/decorated windows.
|
// The InnerRect test is necessary for non-child/decorated windows.
|
||||||
bool scope_hovered = IsWindowHovered() && window->InnerRect.Contains(g.IO.MousePos);
|
bool scope_hovered = window->InnerRect.Contains(g.IO.MousePos) && IsWindowHovered(ImGuiHoveredFlags_ChildWindows);
|
||||||
if (scope_hovered && (ms->Flags & ImGuiMultiSelectFlags_ScopeRect))
|
if (scope_hovered && (ms->Flags & ImGuiMultiSelectFlags_ScopeRect))
|
||||||
scope_hovered &= scope_rect.Contains(g.IO.MousePos);
|
scope_hovered &= scope_rect.Contains(g.IO.MousePos);
|
||||||
if (scope_hovered && g.HoveredId == 0 && g.ActiveId == 0)
|
if (scope_hovered && g.HoveredId == 0 && g.ActiveId == 0)
|
||||||
@@ -8321,8 +8365,19 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed)
|
|||||||
if (ms->BoxSelectId != 0)
|
if (ms->BoxSelectId != 0)
|
||||||
if (ImGuiBoxSelectState* bs = GetBoxSelectState(ms->BoxSelectId))
|
if (ImGuiBoxSelectState* bs = GetBoxSelectState(ms->BoxSelectId))
|
||||||
{
|
{
|
||||||
const bool rect_overlap_curr = bs->BoxSelectRectCurr.Overlaps(g.LastItemData.Rect);
|
ImRect item_rect = g.LastItemData.Rect;
|
||||||
const bool rect_overlap_prev = bs->BoxSelectRectPrev.Overlaps(g.LastItemData.Rect);
|
if (!window->DC.NavIsScrollPushableX) // FIXME: Rename to be more generic.
|
||||||
|
if (ImGuiTable* table = g.CurrentTable)
|
||||||
|
if (table->CurrentColumn != -1)
|
||||||
|
{
|
||||||
|
// FIXME: We cannot use current ClipRect as it includes HostClipRect.
|
||||||
|
// A more generic version would be nice, but window->WorkRect.Min/Max exclude CellPadding. (#7994)
|
||||||
|
ImGuiTableColumn* column = &table->Columns[table->CurrentColumn];
|
||||||
|
item_rect.Min.x = ImMax(item_rect.Min.x, column->MinX);
|
||||||
|
item_rect.Max.x = ImMin(item_rect.Max.x, column->MaxX);
|
||||||
|
}
|
||||||
|
const bool rect_overlap_curr = bs->BoxSelectRectCurr.Overlaps(item_rect);
|
||||||
|
const bool rect_overlap_prev = bs->BoxSelectRectPrev.Overlaps(item_rect);
|
||||||
if ((rect_overlap_curr && !rect_overlap_prev && !selected) || (rect_overlap_prev && !rect_overlap_curr))
|
if ((rect_overlap_curr && !rect_overlap_prev && !selected) || (rect_overlap_prev && !rect_overlap_curr))
|
||||||
{
|
{
|
||||||
if (storage->LastSelectionSize <= 0 && bs->IsStartedSetNavIdOnce)
|
if (storage->LastSelectionSize <= 0 && bs->IsStartedSetNavIdOnce)
|
||||||
@@ -8940,6 +8995,7 @@ int ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_get
|
|||||||
|
|
||||||
// Return hovered index or -1 if none are hovered.
|
// Return hovered index or -1 if none are hovered.
|
||||||
// This is currently not exposed in the public API because we need a larger redesign of the whole thing, but in the short-term we are making it available in PlotEx().
|
// This is currently not exposed in the public API because we need a larger redesign of the whole thing, but in the short-term we are making it available in PlotEx().
|
||||||
|
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
|
||||||
return idx_hovered;
|
return idx_hovered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user