mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-22 11:57:00 +00:00
RangeSelect/MultiSelect: Fix for TreeNode following merge of 011d4755
. Demo: basic test for tree nodes.
This commit is contained in:
parent
dd52a2854c
commit
304270a99a
@ -1259,18 +1259,29 @@ static void ShowDemoWindowWidgets()
|
|||||||
"Cauliflower", "Celery", "Celery Root", "Celcuce", "Chayote", "Celtuce", "Chayote", "Chinese Broccoli", "Corn", "Cucumber"
|
"Cauliflower", "Celery", "Celery Root", "Celcuce", "Chayote", "Celtuce", "Chayote", "Chinese Broccoli", "Corn", "Cucumber"
|
||||||
};
|
};
|
||||||
|
|
||||||
int COUNT = 1000;
|
// Test both Selectable() and TreeNode() widgets
|
||||||
HelpMarker("Hold CTRL and click to select multiple items. Hold SHIFT to select a range. Keyboard is also supported.");
|
enum WidgetType { WidgetType_Selectable, WidgetType_TreeNode };
|
||||||
ImGui::CheckboxFlags("io.ConfigFlags: NavEnableKeyboard", (unsigned int *)&ImGui::GetIO().ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard);
|
static WidgetType widget_type = WidgetType_TreeNode;
|
||||||
|
if (ImGui::RadioButton("Selectables", widget_type == WidgetType_Selectable)) { widget_type = WidgetType_Selectable; }
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::RadioButton("Tree nodes", widget_type == WidgetType_TreeNode)) { widget_type = WidgetType_TreeNode; }
|
||||||
|
ImGui::CheckboxFlags("io.ConfigFlags: NavEnableKeyboard", (unsigned int*)&ImGui::GetIO().ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard);
|
||||||
|
ImGui::SameLine(); HelpMarker("Hold CTRL and click to select multiple items. Hold SHIFT to select a range. Keyboard is also supported.");
|
||||||
|
|
||||||
|
// Open a scrolling region
|
||||||
|
const int ITEMS_COUNT = 1000;
|
||||||
if (ImGui::BeginListBox("##Basket", ImVec2(-FLT_MIN, ImGui::GetFontSize() * 20)))
|
if (ImGui::BeginListBox("##Basket", ImVec2(-FLT_MIN, ImGui::GetFontSize() * 20)))
|
||||||
{
|
{
|
||||||
ImGuiMultiSelectData* multi_select_data = ImGui::BeginMultiSelect(ImGuiMultiSelectFlags_None, (void*)(intptr_t)selection_ref, selection.GetSelected((int)selection_ref));
|
|
||||||
if (multi_select_data->RequestClear) { selection.Clear(); }
|
|
||||||
if (multi_select_data->RequestSelectAll) { selection.SelectAll(COUNT); }
|
|
||||||
ImVec2 color_button_sz(ImGui::GetFontSize(), ImGui::GetFontSize());
|
ImVec2 color_button_sz(ImGui::GetFontSize(), ImGui::GetFontSize());
|
||||||
|
if (widget_type == WidgetType_TreeNode)
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(ImGui::GetStyle().ItemSpacing.x, 0.0f));
|
||||||
|
|
||||||
|
ImGuiMultiSelectData* multi_select_data = ImGui::BeginMultiSelect(ImGuiMultiSelectFlags_None, (void*)(intptr_t)selection_ref, selection.GetSelected(selection_ref));
|
||||||
|
if (multi_select_data->RequestClear) { selection.Clear(); }
|
||||||
|
if (multi_select_data->RequestSelectAll) { selection.SelectAll(ITEMS_COUNT); }
|
||||||
|
|
||||||
ImGuiListClipper clipper;
|
ImGuiListClipper clipper;
|
||||||
clipper.Begin(COUNT);
|
clipper.Begin(ITEMS_COUNT);
|
||||||
while (clipper.Step())
|
while (clipper.Step())
|
||||||
{
|
{
|
||||||
if (clipper.DisplayStart > (int)selection_ref)
|
if (clipper.DisplayStart > (int)selection_ref)
|
||||||
@ -1283,23 +1294,42 @@ static void ShowDemoWindowWidgets()
|
|||||||
bool item_is_selected = selection.GetSelected(n);
|
bool item_is_selected = selection.GetSelected(n);
|
||||||
|
|
||||||
// Emit a color button, to test that Shift+LeftArrow landing on an item that is not part
|
// Emit a color button, to test that Shift+LeftArrow landing on an item that is not part
|
||||||
// of the selection scope doesn't erroneously alter our selection.
|
// of the selection scope doesn't erroneously alter our selection (FIXME-TESTS: Add a test for that!).
|
||||||
ImVec4 dummy_col = ImColor((ImU32)ImGui::GetID(label));
|
ImU32 dummy_col = (ImU32)ImGui::GetID(label);
|
||||||
ImGui::ColorButton("##", dummy_col, ImGuiColorEditFlags_NoTooltip, color_button_sz);
|
ImGui::ColorButton("##", ImColor(dummy_col), ImGuiColorEditFlags_NoTooltip, color_button_sz);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
ImGui::SetNextItemSelectionData((void*)(intptr_t)n);
|
ImGui::SetNextItemSelectionData((void*)(intptr_t)n);
|
||||||
if (ImGui::Selectable(label, item_is_selected))
|
if (widget_type == WidgetType_Selectable)
|
||||||
selection.SetSelected(n, !item_is_selected);
|
{
|
||||||
|
if (ImGui::Selectable(label, item_is_selected))
|
||||||
|
selection.SetSelected(n, !item_is_selected);
|
||||||
|
}
|
||||||
|
else if (widget_type == WidgetType_TreeNode)
|
||||||
|
{
|
||||||
|
ImGuiTreeNodeFlags tree_node_flags = ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_OpenOnDoubleClick;
|
||||||
|
if (item_is_selected)
|
||||||
|
tree_node_flags |= ImGuiTreeNodeFlags_Selected;
|
||||||
|
ImGui::TreeNodeEx(label, tree_node_flags);
|
||||||
|
if (ImGui::IsItemToggledSelection())
|
||||||
|
selection.SetSelected(n, !item_is_selected);
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply multi-select requests
|
||||||
multi_select_data = ImGui::EndMultiSelect();
|
multi_select_data = ImGui::EndMultiSelect();
|
||||||
selection_ref = (int)(intptr_t)multi_select_data->RangeSrc;
|
selection_ref = (int)(intptr_t)multi_select_data->RangeSrc;
|
||||||
ImGui::EndListBox();
|
|
||||||
if (multi_select_data->RequestClear) { selection.Clear(); }
|
if (multi_select_data->RequestClear) { selection.Clear(); }
|
||||||
if (multi_select_data->RequestSelectAll) { selection.SelectAll(COUNT); }
|
if (multi_select_data->RequestSelectAll) { selection.SelectAll(ITEMS_COUNT); }
|
||||||
if (multi_select_data->RequestSetRange) { selection.SetRange((int)(intptr_t)multi_select_data->RangeSrc, (int)(intptr_t)multi_select_data->RangeDst, multi_select_data->RangeValue ? 1 : 0); }
|
if (multi_select_data->RequestSetRange) { selection.SetRange((int)(intptr_t)multi_select_data->RangeSrc, (int)(intptr_t)multi_select_data->RangeDst, multi_select_data->RangeValue ? 1 : 0); }
|
||||||
|
|
||||||
|
if (widget_type == WidgetType_TreeNode)
|
||||||
|
ImGui::PopStyleVar();
|
||||||
|
|
||||||
|
ImGui::EndListBox();
|
||||||
}
|
}
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
|
@ -5901,8 +5901,6 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
|||||||
const float arrow_hit_x1 = (text_pos.x - text_offset_x) - style.TouchExtraPadding.x;
|
const float arrow_hit_x1 = (text_pos.x - text_offset_x) - style.TouchExtraPadding.x;
|
||||||
const float arrow_hit_x2 = (text_pos.x - text_offset_x) + (g.FontSize + padding.x * 2.0f) + style.TouchExtraPadding.x;
|
const float arrow_hit_x2 = (text_pos.x - text_offset_x) + (g.FontSize + padding.x * 2.0f) + style.TouchExtraPadding.x;
|
||||||
const bool is_mouse_x_over_arrow = (g.IO.MousePos.x >= arrow_hit_x1 && g.IO.MousePos.x < arrow_hit_x2);
|
const bool is_mouse_x_over_arrow = (g.IO.MousePos.x >= arrow_hit_x1 && g.IO.MousePos.x < arrow_hit_x2);
|
||||||
if (window != g.HoveredWindow || !is_mouse_x_over_arrow)
|
|
||||||
button_flags |= ImGuiButtonFlags_NoKeyModifiers;
|
|
||||||
|
|
||||||
// Open behaviors can be altered with the _OpenOnArrow and _OnOnDoubleClick flags.
|
// Open behaviors can be altered with the _OpenOnArrow and _OnOnDoubleClick flags.
|
||||||
// Some alteration have subtle effects (e.g. toggle on MouseUp vs MouseDown events) due to requirements for multi-selection and drag and drop support.
|
// Some alteration have subtle effects (e.g. toggle on MouseUp vs MouseDown events) due to requirements for multi-selection and drag and drop support.
|
||||||
@ -5927,12 +5925,15 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
|||||||
const bool is_multi_select = g.MultiSelectEnabled;
|
const bool is_multi_select = g.MultiSelectEnabled;
|
||||||
if (is_multi_select)
|
if (is_multi_select)
|
||||||
{
|
{
|
||||||
flags |= ImGuiTreeNodeFlags_OpenOnArrow;
|
|
||||||
MultiSelectItemHeader(id, &selected);
|
MultiSelectItemHeader(id, &selected);
|
||||||
button_flags |= ImGuiButtonFlags_NoHoveredOnFocus;
|
button_flags |= ImGuiButtonFlags_NoHoveredOnFocus;
|
||||||
|
|
||||||
|
// We absolutely need to distinguish open vs select so this is the default when multi-select is enabled.
|
||||||
|
flags |= ImGuiTreeNodeFlags_OpenOnArrow;
|
||||||
|
|
||||||
// To handle drag and drop of multiple items we need to avoid clearing selection on click.
|
// To handle drag and drop of multiple items we need to avoid clearing selection on click.
|
||||||
// Enabling this test makes actions using CTRL+SHIFT delay their effect on the mouse release which is annoying, but it allows drag and drop of multiple items.
|
// Enabling this test makes actions using CTRL+SHIFT delay their effect on the mouse release which is annoying, but it allows drag and drop of multiple items.
|
||||||
|
// FIXME-MULTISELECT: Consider opt-in for drag and drop behavior in ImGuiMultiSelectFlags?
|
||||||
if (!selected || (g.ActiveId == id && g.ActiveIdHasBeenPressedBefore))
|
if (!selected || (g.ActiveId == id && g.ActiveIdHasBeenPressedBefore))
|
||||||
button_flags |= ImGuiButtonFlags_PressedOnClick;
|
button_flags |= ImGuiButtonFlags_PressedOnClick;
|
||||||
else
|
else
|
||||||
@ -5940,7 +5941,8 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
button_flags |= ImGuiButtonFlags_NoKeyModifiers;
|
if (window != g.HoveredWindow || !is_mouse_x_over_arrow)
|
||||||
|
button_flags |= ImGuiButtonFlags_NoKeyModifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hovered, held;
|
bool hovered, held;
|
||||||
|
Loading…
Reference in New Issue
Block a user