|
@@ -7105,6 +7105,7 @@ void ImGui::DebugNodeTypingSelectState(ImGuiTypingSelectState* data)
|
|
//-------------------------------------------------------------------------
|
|
//-------------------------------------------------------------------------
|
|
// - DebugLogMultiSelectRequests() [Internal]
|
|
// - DebugLogMultiSelectRequests() [Internal]
|
|
// - BoxSelectStart() [Internal]
|
|
// - BoxSelectStart() [Internal]
|
|
|
|
+// - BoxSelectScrollWithMouseDrag() [Internal]
|
|
// - BeginMultiSelect()
|
|
// - BeginMultiSelect()
|
|
// - EndMultiSelect()
|
|
// - EndMultiSelect()
|
|
// - SetNextItemSelectionUserData()
|
|
// - SetNextItemSelectionUserData()
|
|
@@ -7133,6 +7134,23 @@ static void BoxSelectStart(ImGuiMultiSelectState* storage, ImGuiSelectionUserDat
|
|
storage->BoxSelectStartPosRel = storage->BoxSelectEndPosRel = ImGui::WindowPosAbsToRel(g.CurrentWindow, g.IO.MousePos);
|
|
storage->BoxSelectStartPosRel = storage->BoxSelectEndPosRel = ImGui::WindowPosAbsToRel(g.CurrentWindow, g.IO.MousePos);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void BoxSelectScrollWithMouseDrag(ImGuiWindow* window, const ImRect& r)
|
|
|
|
+{
|
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
|
+ for (int n = 0; n < 2; n++)
|
|
|
|
+ {
|
|
|
|
+ float dist = (g.IO.MousePos[n] > r.Max[n]) ? g.IO.MousePos[n] - r.Max[n] : (g.IO.MousePos[n] < r.Min[n]) ? g.IO.MousePos[n] - r.Min[n] : 0.0f;
|
|
|
|
+ if (dist == 0.0f || (dist < 0.0f && window->Scroll[n] < 0.0f) || (dist > 0.0f && window->Scroll[n] >= window->ScrollMax[n]))
|
|
|
|
+ continue;
|
|
|
|
+ float speed_multiplier = ImLinearRemapClamp(g.FontSize, g.FontSize * 5.0f, 1.0f, 4.0f, ImAbs(dist)); // x1 to x4 depending on distance
|
|
|
|
+ float scroll_step = IM_ROUND(g.FontSize * 35.0f * speed_multiplier * ImSign(dist) * g.IO.DeltaTime);
|
|
|
|
+ if (n == 0)
|
|
|
|
+ ImGui::SetScrollX(window, window->Scroll[n] + scroll_step);
|
|
|
|
+ else
|
|
|
|
+ ImGui::SetScrollY(window, window->Scroll[n] + scroll_step);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
// Return ImGuiMultiSelectIO structure. Lifetime: valid until corresponding call to EndMultiSelect().
|
|
// Return ImGuiMultiSelectIO structure. Lifetime: valid until corresponding call to EndMultiSelect().
|
|
ImGuiMultiSelectIO* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags)
|
|
ImGuiMultiSelectIO* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags)
|
|
{
|
|
{
|
|
@@ -7142,6 +7160,8 @@ ImGuiMultiSelectIO* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags)
|
|
IM_ASSERT(g.CurrentMultiSelect == NULL); // No recursion allowed yet (we could allow it if we deem it useful)
|
|
IM_ASSERT(g.CurrentMultiSelect == NULL); // No recursion allowed yet (we could allow it if we deem it useful)
|
|
IM_STATIC_ASSERT(offsetof(ImGuiMultiSelectTempData, IO) == 0); // Clear() relies on that.
|
|
IM_STATIC_ASSERT(offsetof(ImGuiMultiSelectTempData, IO) == 0); // Clear() relies on that.
|
|
g.CurrentMultiSelect = ms;
|
|
g.CurrentMultiSelect = ms;
|
|
|
|
+ if ((flags & (ImGuiMultiSelectFlags_ScopeWindow | ImGuiMultiSelectFlags_ScopeRect)) == 0)
|
|
|
|
+ flags |= ImGuiMultiSelectFlags_ScopeWindow;
|
|
|
|
|
|
// FIXME: BeginFocusScope()
|
|
// FIXME: BeginFocusScope()
|
|
const ImGuiID id = window->IDStack.back();
|
|
const ImGuiID id = window->IDStack.back();
|
|
@@ -7257,6 +7277,7 @@ ImGuiMultiSelectIO* ImGui::EndMultiSelect()
|
|
IM_ASSERT(ms->FocusScopeId == g.CurrentFocusScopeId);
|
|
IM_ASSERT(ms->FocusScopeId == g.CurrentFocusScopeId);
|
|
IM_ASSERT(g.CurrentMultiSelect != NULL && storage->Window == g.CurrentWindow);
|
|
IM_ASSERT(g.CurrentMultiSelect != NULL && storage->Window == g.CurrentWindow);
|
|
|
|
|
|
|
|
+ const ImRect scope_rect = (ms->Flags & ImGuiMultiSelectFlags_ScopeRect) ? ImRect(ms->ScopeRectMin, ImMax(window->DC.CursorMaxPos, ms->ScopeRectMin)) : window->InnerClipRect;
|
|
if (ms->IsFocused)
|
|
if (ms->IsFocused)
|
|
{
|
|
{
|
|
// We currently don't allow user code to modify RangeSrcItem by writing to BeginIO's version, but that would be an easy change here.
|
|
// We currently don't allow user code to modify RangeSrcItem by writing to BeginIO's version, but that would be an easy change here.
|
|
@@ -7272,25 +7293,30 @@ ImGuiMultiSelectIO* ImGui::EndMultiSelect()
|
|
storage->NavIdSelected = -1;
|
|
storage->NavIdSelected = -1;
|
|
}
|
|
}
|
|
|
|
|
|
- // Box-select: render selection rectangle
|
|
|
|
- // FIXME-MULTISELECT: Scroll on box-select
|
|
|
|
if ((ms->Flags & ImGuiMultiSelectFlags_BoxSelect) && storage->BoxSelectActive)
|
|
if ((ms->Flags & ImGuiMultiSelectFlags_BoxSelect) && storage->BoxSelectActive)
|
|
{
|
|
{
|
|
|
|
+ // Box-select: render selection rectangle
|
|
ms->Storage->BoxSelectEndPosRel = WindowPosAbsToRel(window, g.IO.MousePos);
|
|
ms->Storage->BoxSelectEndPosRel = WindowPosAbsToRel(window, g.IO.MousePos);
|
|
- window->DrawList->AddRectFilled(ms->BoxSelectRectCurr.Min, ms->BoxSelectRectCurr.Max, GetColorU32(ImGuiCol_SeparatorHovered, 0.30f)); // FIXME-MULTISELECT: Styling
|
|
|
|
- window->DrawList->AddRect(ms->BoxSelectRectCurr.Min, ms->BoxSelectRectCurr.Max, GetColorU32(ImGuiCol_NavHighlight)); // FIXME-MULTISELECT: Styling
|
|
|
|
|
|
+ ImRect box_select_r = ms->BoxSelectRectCurr;
|
|
|
|
+ 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
|
|
|
|
+ window->DrawList->AddRect(box_select_r.Min, box_select_r.Max, GetColorU32(ImGuiCol_NavHighlight)); // FIXME-MULTISELECT: Styling
|
|
|
|
+
|
|
|
|
+ // Box-select: scroll
|
|
|
|
+ ImRect scroll_r = scope_rect;
|
|
|
|
+ scroll_r.Expand(g.Style.FramePadding);
|
|
|
|
+ if ((ms->Flags & ImGuiMultiSelectFlags_ScopeWindow) && (ms->Flags & ImGuiMultiSelectFlags_NoBoxSelectScroll) == 0 && !scroll_r.Contains(g.IO.MousePos))
|
|
|
|
+ BoxSelectScrollWithMouseDrag(window, scroll_r);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (ms->IsEndIO == false)
|
|
if (ms->IsEndIO == false)
|
|
ms->IO.Requests.resize(0);
|
|
ms->IO.Requests.resize(0);
|
|
|
|
|
|
- const ImRect scope_rect(ms->ScopeRectMin, ImMax(window->DC.CursorMaxPos, ms->ScopeRectMin));
|
|
|
|
- const bool scope_hovered = (ms->Flags & ImGuiMultiSelectFlags_ScopeRect) ? IsMouseHoveringRect(scope_rect.Min, scope_rect.Max) : IsWindowHovered();
|
|
|
|
-
|
|
|
|
// 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!
|
|
- if (scope_hovered && g.HoveredId == 0)
|
|
|
|
|
|
+ const bool scope_hovered = (ms->Flags & ImGuiMultiSelectFlags_ScopeRect) ? scope_rect.Contains(g.IO.MousePos) : IsWindowHovered();
|
|
|
|
+ if (scope_hovered && g.HoveredId == 0 && g.ActiveId == 0)
|
|
{
|
|
{
|
|
if (ms->Flags & ImGuiMultiSelectFlags_BoxSelect)
|
|
if (ms->Flags & ImGuiMultiSelectFlags_BoxSelect)
|
|
if (!storage->BoxSelectActive && !storage->BoxSelectStarting && g.IO.MouseClickedCount[0] == 1)
|
|
if (!storage->BoxSelectActive && !storage->BoxSelectStarting && g.IO.MouseClickedCount[0] == 1)
|