TreeNode: Made clicking on arrow with _OpenOnArrow toggle the open state on the Mouse Down event rather than the Mouse Down+Up sequence (this is rather standard behavior).

This commit is contained in:
omar 2020-03-31 19:29:46 +02:00
parent 68c5d030cd
commit 05420ea2cf
2 changed files with 26 additions and 15 deletions

View File

@ -47,6 +47,8 @@ Other Changes:
glyph. (#2149, #515) glyph. (#2149, #515)
- Selectable: Fixed honoring style.SelectableTextAlign with unspecified size. (#2347, #2601) - Selectable: Fixed honoring style.SelectableTextAlign with unspecified size. (#2347, #2601)
- Selectable: Allow using ImGuiSelectableFlags_SpanAllColumns in other columns than first. (#125) - Selectable: Allow using ImGuiSelectableFlags_SpanAllColumns in other columns than first. (#125)
- TreeNode: Made clicking on arrow with _OpenOnArrow toggle the open state on the Mouse Down
event rather than the Mouse Down+Up sequence (this is rather standard behavior).
- Scrolling: Fixed scrolling centering API leading to non-integer scrolling values and initial - Scrolling: Fixed scrolling centering API leading to non-integer scrolling values and initial
cursor position. This would often get fixed after the fix item submission, but using the cursor position. This would often get fixed after the fix item submission, but using the
ImGuiListClipper as the first thing after Begin() could largely break size calculations. (#3073) ImGuiListClipper as the first thing after Begin() could largely break size calculations. (#3073)

View File

@ -5319,30 +5319,39 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
return is_open; return is_open;
} }
// Flags that affects opening behavior: ImGuiButtonFlags button_flags = ImGuiTreeNodeFlags_None;
// - 0 (default) .................... single-click anywhere to open
// - OpenOnDoubleClick .............. double-click anywhere to open
// - OpenOnArrow .................... single-click on arrow to open
// - OpenOnDoubleClick|OpenOnArrow .. single-click on arrow or double-click anywhere to open
ImGuiButtonFlags button_flags = 0;
if (flags & ImGuiTreeNodeFlags_AllowItemOverlap) if (flags & ImGuiTreeNodeFlags_AllowItemOverlap)
button_flags |= ImGuiButtonFlags_AllowItemOverlap; button_flags |= ImGuiButtonFlags_AllowItemOverlap;
if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick)
button_flags |= ImGuiButtonFlags_PressedOnDoubleClick | ((flags & ImGuiTreeNodeFlags_OpenOnArrow) ? ImGuiButtonFlags_PressedOnClickRelease : 0);
else
button_flags |= ImGuiButtonFlags_PressedOnClickRelease;
if (!is_leaf) if (!is_leaf)
button_flags |= ImGuiButtonFlags_PressedOnDragDropHold; button_flags |= ImGuiButtonFlags_PressedOnDragDropHold;
// We allow clicking on the arrow section with keyboard modifiers held, in order to easily // We allow clicking on the arrow section with keyboard modifiers held, in order to easily
// allow browsing a tree while preserving selection with code implementing multi-selection patterns. // allow browsing a tree while preserving selection with code implementing multi-selection patterns.
// When clicking on the rest of the tree node we always disallow keyboard modifiers. // When clicking on the rest of the tree node we always disallow keyboard modifiers.
const float hit_padding_x = style.TouchExtraPadding.x; 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) - hit_padding_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) + hit_padding_x; 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 || !(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; button_flags |= ImGuiButtonFlags_NoKeyModifiers;
// 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.
// - Single-click on label = Toggle on MouseUp (default)
// - Single-click on arrow = Toggle on MouseUp (when _OpenOnArrow=0)
// - Single-click on arrow = Toggle on MouseDown (when _OpenOnArrow=1)
// - Double-click on label = Toggle on MouseDoubleClick (when _OpenOnDoubleClick=1)
// - Double-click on arrow = Toggle on MouseDoubleClick (when _OpenOnDoubleClick=1 and _OpenOnArrow=0)
// This makes _OpenOnArrow have a subtle effect on _OpenOnDoubleClick: arrow click reacts on Down rather than Up.
// It is rather standard that arrow click react on Down rather than Up and we'd be tempted to make it the default
// (by removing the _OpenOnArrow test below), however this would have a perhaps surprising effect on CollapsingHeader()?
// So right now we are making this optional. May evolve later.
if (is_mouse_x_over_arrow && (flags & ImGuiTreeNodeFlags_OpenOnArrow))
button_flags |= ImGuiButtonFlags_PressedOnClick;
else if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick)
button_flags |= ImGuiButtonFlags_PressedOnDoubleClick;
else
button_flags |= ImGuiButtonFlags_PressedOnClickRelease;
bool selected = (flags & ImGuiTreeNodeFlags_Selected) != 0; bool selected = (flags & ImGuiTreeNodeFlags_Selected) != 0;
const bool was_selected = selected; const bool was_selected = selected;
@ -5356,7 +5365,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
if ((flags & (ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick)) == 0 || (g.NavActivateId == id)) if ((flags & (ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick)) == 0 || (g.NavActivateId == id))
toggled = true; toggled = true;
if (flags & ImGuiTreeNodeFlags_OpenOnArrow) if (flags & ImGuiTreeNodeFlags_OpenOnArrow)
toggled |= (g.IO.MousePos.x >= arrow_hit_x1 && g.IO.MousePos.x < arrow_hit_x2) && (!g.NavDisableMouseHover); // Lightweight equivalent of IsMouseHoveringRect() since ButtonBehavior() already did the job toggled |= is_mouse_x_over_arrow && !g.NavDisableMouseHover; // Lightweight equivalent of IsMouseHoveringRect() since ButtonBehavior() already did the job
if ((flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) && g.IO.MouseDoubleClicked[0]) if ((flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) && g.IO.MouseDoubleClicked[0])
toggled = true; toggled = true;
if (g.DragDropActive && is_open) // When using Drag and Drop "hold to open" we keep the node highlighted after opening, but never close it again. if (g.DragDropActive && is_open) // When using Drag and Drop "hold to open" we keep the node highlighted after opening, but never close it again.