|
@@ -488,14 +488,6 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
ImGuiWindow* window = GetCurrentWindow();
|
|
|
|
|
|
- if (flags & ImGuiButtonFlags_Disabled)
|
|
|
- {
|
|
|
- if (out_hovered) *out_hovered = false;
|
|
|
- if (out_held) *out_held = false;
|
|
|
- if (g.ActiveId == id) ClearActiveID();
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
// Default only reacts to left mouse button
|
|
|
if ((flags & ImGuiButtonFlags_MouseButtonMask_) == 0)
|
|
|
flags |= ImGuiButtonFlags_MouseButtonDefault_;
|
|
@@ -527,7 +519,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
|
|
{
|
|
|
hovered = true;
|
|
|
SetHoveredID(id);
|
|
|
- if (CalcTypematicRepeatAmount(g.HoveredIdTimer + 0.0001f - g.IO.DeltaTime, g.HoveredIdTimer + 0.0001f, DRAGDROP_HOLD_TO_OPEN_TIMER, 0.00f))
|
|
|
+ if (g.HoveredIdTimer - g.IO.DeltaTime <= DRAGDROP_HOLD_TO_OPEN_TIMER && g.HoveredIdTimer >= DRAGDROP_HOLD_TO_OPEN_TIMER)
|
|
|
{
|
|
|
pressed = true;
|
|
|
g.DragDropHoldJustPressedId = id;
|
|
@@ -619,6 +611,10 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // Release active id if turning disabled
|
|
|
+ if (g.ActiveId == id && (g.CurrentItemFlags & ImGuiItemFlags_Disabled))
|
|
|
+ ClearActiveID();
|
|
|
+
|
|
|
// Process while held
|
|
|
bool held = false;
|
|
|
if (g.ActiveId == id)
|
|
@@ -1455,7 +1451,7 @@ bool ImGui::SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float
|
|
|
if (g.ActiveId != id)
|
|
|
SetItemAllowOverlap();
|
|
|
|
|
|
- if (held || (g.HoveredId == id && g.HoveredIdPreviousFrame == id && g.HoveredIdTimer >= hover_visibility_delay))
|
|
|
+ if (held || (hovered && g.HoveredIdPreviousFrame == id && g.HoveredIdTimer >= hover_visibility_delay))
|
|
|
SetMouseCursor(axis == ImGuiAxis_Y ? ImGuiMouseCursor_ResizeNS : ImGuiMouseCursor_ResizeEW);
|
|
|
|
|
|
ImRect bb_render = bb;
|
|
@@ -2441,7 +2437,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
|
|
|
}
|
|
|
|
|
|
// Draw frame
|
|
|
- const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
|
|
|
+ const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
|
|
|
RenderNavHighlight(frame_bb, id);
|
|
|
RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, style.FrameRounding);
|
|
|
|
|
@@ -3047,7 +3043,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
|
|
|
}
|
|
|
|
|
|
// Draw frame
|
|
|
- const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
|
|
|
+ const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
|
|
|
RenderNavHighlight(frame_bb, id);
|
|
|
RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, g.Style.FrameRounding);
|
|
|
|
|
@@ -3195,7 +3191,7 @@ bool ImGui::VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType d
|
|
|
}
|
|
|
|
|
|
// Draw frame
|
|
|
- const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
|
|
|
+ const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
|
|
|
RenderNavHighlight(frame_bb, id);
|
|
|
RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, g.Style.FrameRounding);
|
|
|
|
|
@@ -3450,7 +3446,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data
|
|
|
style.FramePadding.x = style.FramePadding.y;
|
|
|
ImGuiButtonFlags button_flags = ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups;
|
|
|
if (flags & ImGuiInputTextFlags_ReadOnly)
|
|
|
- button_flags |= ImGuiButtonFlags_Disabled;
|
|
|
+ PushDisabled(true);
|
|
|
SameLine(0, style.ItemInnerSpacing.x);
|
|
|
if (ButtonEx("-", ImVec2(button_size, button_size), button_flags))
|
|
|
{
|
|
@@ -3463,6 +3459,8 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data
|
|
|
DataTypeApplyOp(data_type, '+', p_data, p_data, g.IO.KeyCtrl && p_step_fast ? p_step_fast : p_step);
|
|
|
value_changed = true;
|
|
|
}
|
|
|
+ if (flags & ImGuiInputTextFlags_ReadOnly)
|
|
|
+ PopDisabled();
|
|
|
|
|
|
const char* label_end = FindRenderedTextEnd(label);
|
|
|
if (label != label_end)
|
|
@@ -6146,10 +6144,11 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
|
|
}
|
|
|
|
|
|
bool item_add;
|
|
|
- if (flags & ImGuiSelectableFlags_Disabled)
|
|
|
+ const bool disabled_item = (flags & ImGuiSelectableFlags_Disabled) != 0;
|
|
|
+ if (disabled_item)
|
|
|
{
|
|
|
ImGuiItemFlags backup_item_flags = g.CurrentItemFlags;
|
|
|
- g.CurrentItemFlags |= ImGuiItemFlags_Disabled | ImGuiItemFlags_NoNavDefaultFocus;
|
|
|
+ g.CurrentItemFlags |= ImGuiItemFlags_Disabled;
|
|
|
item_add = ItemAdd(bb, id);
|
|
|
g.CurrentItemFlags = backup_item_flags;
|
|
|
}
|
|
@@ -6167,6 +6166,10 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
|
|
if (!item_add)
|
|
|
return false;
|
|
|
|
|
|
+ const bool disabled_global = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0;
|
|
|
+ if (disabled_item && !disabled_global)
|
|
|
+ PushDisabled(true);
|
|
|
+
|
|
|
// FIXME: We can standardize the behavior of those two, we could also keep the fast path of override ClipRect + full push on render only,
|
|
|
// which would be advantageous since most selectable are not selected.
|
|
|
if (span_all_columns && window->DC.CurrentColumns)
|
|
@@ -6179,13 +6182,9 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
|
|
if (flags & ImGuiSelectableFlags_NoHoldingActiveID) { button_flags |= ImGuiButtonFlags_NoHoldingActiveId; }
|
|
|
if (flags & ImGuiSelectableFlags_SelectOnClick) { button_flags |= ImGuiButtonFlags_PressedOnClick; }
|
|
|
if (flags & ImGuiSelectableFlags_SelectOnRelease) { button_flags |= ImGuiButtonFlags_PressedOnRelease; }
|
|
|
- if (flags & ImGuiSelectableFlags_Disabled) { button_flags |= ImGuiButtonFlags_Disabled; }
|
|
|
if (flags & ImGuiSelectableFlags_AllowDoubleClick) { button_flags |= ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnDoubleClick; }
|
|
|
if (flags & ImGuiSelectableFlags_AllowItemOverlap) { button_flags |= ImGuiButtonFlags_AllowItemOverlap; }
|
|
|
|
|
|
- if (flags & ImGuiSelectableFlags_Disabled)
|
|
|
- selected = false;
|
|
|
-
|
|
|
const bool was_selected = selected;
|
|
|
bool hovered, held;
|
|
|
bool pressed = ButtonBehavior(bb, id, &hovered, &held, button_flags);
|
|
@@ -6235,14 +6234,15 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
|
|
else if (span_all_columns && g.CurrentTable)
|
|
|
TablePopBackgroundChannel();
|
|
|
|
|
|
- if (flags & ImGuiSelectableFlags_Disabled) PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]);
|
|
|
RenderTextClipped(text_min, text_max, label, NULL, &label_size, style.SelectableTextAlign, &bb);
|
|
|
- if (flags & ImGuiSelectableFlags_Disabled) PopStyleColor();
|
|
|
|
|
|
// Automatically close popups
|
|
|
if (pressed && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_DontClosePopups) && !(g.CurrentItemFlags & ImGuiItemFlags_SelectableDontClosePopup))
|
|
|
CloseCurrentPopup();
|
|
|
|
|
|
+ if (disabled_item && !disabled_global)
|
|
|
+ PopDisabled();
|
|
|
+
|
|
|
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags);
|
|
|
return pressed;
|
|
|
}
|
|
@@ -6600,38 +6600,46 @@ void ImGui::Value(const char* prefix, float v, const char* float_format)
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
|
// Helpers for internal use
|
|
|
-void ImGuiMenuColumns::Update(int count, float spacing, bool clear)
|
|
|
+void ImGuiMenuColumns::Update(float spacing, bool window_reappearing)
|
|
|
{
|
|
|
- IM_ASSERT(count == IM_ARRAYSIZE(Pos));
|
|
|
- IM_UNUSED(count);
|
|
|
- Width = NextWidth = 0.0f;
|
|
|
- Spacing = spacing;
|
|
|
- if (clear)
|
|
|
- memset(NextWidths, 0, sizeof(NextWidths));
|
|
|
- for (int i = 0; i < IM_ARRAYSIZE(Pos); i++)
|
|
|
- {
|
|
|
- if (i > 0 && NextWidths[i] > 0.0f)
|
|
|
- Width += Spacing;
|
|
|
- Pos[i] = IM_FLOOR(Width);
|
|
|
- Width += NextWidths[i];
|
|
|
- NextWidths[i] = 0.0f;
|
|
|
- }
|
|
|
+ if (window_reappearing)
|
|
|
+ memset(Widths, 0, sizeof(Widths));
|
|
|
+ Spacing = (ImU16)spacing;
|
|
|
+ CalcNextTotalWidth(true);
|
|
|
+ memset(Widths, 0, sizeof(Widths));
|
|
|
+ TotalWidth = NextTotalWidth;
|
|
|
+ NextTotalWidth = 0;
|
|
|
}
|
|
|
|
|
|
-float ImGuiMenuColumns::DeclColumns(float w0, float w1, float w2) // not using va_arg because they promote float to double
|
|
|
+void ImGuiMenuColumns::CalcNextTotalWidth(bool update_offsets)
|
|
|
{
|
|
|
- NextWidth = 0.0f;
|
|
|
- NextWidths[0] = ImMax(NextWidths[0], w0);
|
|
|
- NextWidths[1] = ImMax(NextWidths[1], w1);
|
|
|
- NextWidths[2] = ImMax(NextWidths[2], w2);
|
|
|
- for (int i = 0; i < IM_ARRAYSIZE(Pos); i++)
|
|
|
- NextWidth += NextWidths[i] + ((i > 0 && NextWidths[i] > 0.0f) ? Spacing : 0.0f);
|
|
|
- return ImMax(Width, NextWidth);
|
|
|
+ ImU16 offset = 0;
|
|
|
+ bool want_spacing = false;
|
|
|
+ for (int i = 0; i < IM_ARRAYSIZE(Widths); i++)
|
|
|
+ {
|
|
|
+ ImU16 width = Widths[i];
|
|
|
+ if (want_spacing && width > 0)
|
|
|
+ offset += Spacing;
|
|
|
+ want_spacing |= (width > 0);
|
|
|
+ if (update_offsets)
|
|
|
+ {
|
|
|
+ if (i == 1) { OffsetLabel = offset; }
|
|
|
+ if (i == 2) { OffsetShortcut = offset; }
|
|
|
+ if (i == 3) { OffsetMark = offset; }
|
|
|
+ }
|
|
|
+ offset += width;
|
|
|
+ }
|
|
|
+ NextTotalWidth = offset;
|
|
|
}
|
|
|
|
|
|
-float ImGuiMenuColumns::CalcExtraSpace(float avail_w) const
|
|
|
+float ImGuiMenuColumns::DeclColumns(float w_icon, float w_label, float w_shortcut, float w_mark)
|
|
|
{
|
|
|
- return ImMax(0.0f, avail_w - Width);
|
|
|
+ Widths[0] = ImMax(Widths[0], (ImU16)w_icon);
|
|
|
+ Widths[1] = ImMax(Widths[1], (ImU16)w_label);
|
|
|
+ Widths[2] = ImMax(Widths[2], (ImU16)w_shortcut);
|
|
|
+ Widths[3] = ImMax(Widths[3], (ImU16)w_mark);
|
|
|
+ CalcNextTotalWidth(false);
|
|
|
+ return (float)ImMax(TotalWidth, NextTotalWidth);
|
|
|
}
|
|
|
|
|
|
// FIXME: Provided a rectangle perhaps e.g. a BeginMenuBarEx() could be used anywhere..
|
|
@@ -6825,6 +6833,10 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
|
|
|
// However the final position is going to be different! It is chosen by FindBestWindowPosForPopup().
|
|
|
// e.g. Menus tend to overlap each other horizontally to amplify relative Z-ordering.
|
|
|
ImVec2 popup_pos, pos = window->DC.CursorPos;
|
|
|
+ PushID(label);
|
|
|
+ if (!enabled)
|
|
|
+ PushDisabled();
|
|
|
+ const ImGuiMenuColumns* offsets = &window->DC.MenuColumns;
|
|
|
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal)
|
|
|
{
|
|
|
// Menu inside an horizontal menu bar
|
|
@@ -6834,7 +6846,9 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
|
|
|
window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * 0.5f);
|
|
|
PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 2.0f, style.ItemSpacing.y));
|
|
|
float w = label_size.x;
|
|
|
- pressed = Selectable(label, menu_is_open, ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopups | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f));
|
|
|
+ ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset);
|
|
|
+ pressed = Selectable("", menu_is_open, ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopups, ImVec2(w, 0.0f));
|
|
|
+ RenderText(text_pos, label);
|
|
|
PopStyleVar();
|
|
|
window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar().
|
|
|
}
|
|
@@ -6844,14 +6858,20 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
|
|
|
// (In a typical menu window where all items are BeginMenu() or MenuItem() calls, extra_w will always be 0.0f.
|
|
|
// Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system.
|
|
|
popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y);
|
|
|
- float min_w = window->DC.MenuColumns.DeclColumns(label_size.x, 0.0f, IM_FLOOR(g.FontSize * 1.20f)); // Feedback to next frame
|
|
|
+ float icon_w = 0.0f; // FIXME: This not currently exposed for BeginMenu() however you can call window->DC.MenuColumns.DeclColumns(w, 0, 0, 0) yourself
|
|
|
+ float checkmark_w = IM_FLOOR(g.FontSize * 1.20f);
|
|
|
+ float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, 0.0f, checkmark_w); // Feedback to next frame
|
|
|
float extra_w = ImMax(0.0f, GetContentRegionAvail().x - min_w);
|
|
|
- pressed = Selectable(label, menu_is_open, ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_SpanAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(min_w, 0.0f));
|
|
|
- ImU32 text_col = GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled);
|
|
|
- RenderArrow(window->DrawList, pos + ImVec2(window->DC.MenuColumns.Pos[2] + extra_w + g.FontSize * 0.30f, 0.0f), text_col, ImGuiDir_Right);
|
|
|
+ ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset);
|
|
|
+ pressed = Selectable("", menu_is_open, ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, 0.0f));
|
|
|
+ RenderText(text_pos, label);
|
|
|
+ RenderArrow(window->DrawList, pos + ImVec2(offsets->OffsetMark + extra_w + g.FontSize * 0.30f, 0.0f), GetColorU32(ImGuiCol_Text), ImGuiDir_Right);
|
|
|
}
|
|
|
+ if (!enabled)
|
|
|
+ PopDisabled();
|
|
|
+ PopID();
|
|
|
|
|
|
- const bool hovered = enabled && ItemHoverable(window->DC.LastItemRect, id);
|
|
|
+ const bool hovered = (g.HoveredId == id) && enabled;
|
|
|
if (menuset_is_open)
|
|
|
g.NavWindow = backed_nav_window;
|
|
|
|
|
@@ -6878,6 +6898,8 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
|
|
|
moving_toward_other_child_menu = ImTriangleContainsPoint(ta, tb, tc, g.IO.MousePos);
|
|
|
//GetForegroundDrawList()->AddTriangleFilled(ta, tb, tc, moving_within_opened_triangle ? IM_COL32(0,128,0,128) : IM_COL32(128,0,0,128)); // [DEBUG]
|
|
|
}
|
|
|
+
|
|
|
+ // FIXME: Hovering a disabled BeginMenu or MenuItem won't close us
|
|
|
if (menu_is_open && !hovered && g.HoveredWindow == window && g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrame != id && !moving_toward_other_child_menu)
|
|
|
want_close = true;
|
|
|
|
|
@@ -6963,7 +6985,7 @@ void ImGui::EndMenu()
|
|
|
EndPopup();
|
|
|
}
|
|
|
|
|
|
-bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, bool enabled)
|
|
|
+bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut, bool selected, bool enabled)
|
|
|
{
|
|
|
ImGuiWindow* window = GetCurrentWindow();
|
|
|
if (window->SkipItems)
|
|
@@ -6976,8 +6998,12 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, boo
|
|
|
|
|
|
// We've been using the equivalent of ImGuiSelectableFlags_SetNavIdOnHover on all Selectable() since early Nav system days (commit 43ee5d73),
|
|
|
// but I am unsure whether this should be kept at all. For now moved it to be an opt-in feature used by menus only.
|
|
|
- ImGuiSelectableFlags flags = ImGuiSelectableFlags_SelectOnRelease | ImGuiSelectableFlags_SetNavIdOnHover | (enabled ? 0 : ImGuiSelectableFlags_Disabled);
|
|
|
bool pressed;
|
|
|
+ PushID(label);
|
|
|
+ if (!enabled)
|
|
|
+ PushDisabled(true);
|
|
|
+ const ImGuiSelectableFlags flags = ImGuiSelectableFlags_SelectOnRelease | ImGuiSelectableFlags_SetNavIdOnHover;
|
|
|
+ const ImGuiMenuColumns* offsets = &window->DC.MenuColumns;
|
|
|
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal)
|
|
|
{
|
|
|
// Mimic the exact layout spacing of BeginMenu() to allow MenuItem() inside a menu bar, which is a little misleading but may be useful
|
|
@@ -6985,8 +7011,9 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, boo
|
|
|
float w = label_size.x;
|
|
|
window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * 0.5f);
|
|
|
PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 2.0f, style.ItemSpacing.y));
|
|
|
- pressed = Selectable(label, selected, flags, ImVec2(w, 0.0f));
|
|
|
+ pressed = Selectable("", selected, flags, ImVec2(w, 0.0f));
|
|
|
PopStyleVar();
|
|
|
+ RenderText(pos + ImVec2(offsets->OffsetLabel, 0.0f), label);
|
|
|
window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar().
|
|
|
}
|
|
|
else
|
|
@@ -6994,27 +7021,40 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, boo
|
|
|
// Menu item inside a vertical menu
|
|
|
// (In a typical menu window where all items are BeginMenu() or MenuItem() calls, extra_w will always be 0.0f.
|
|
|
// Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system.
|
|
|
- float shortcut_w = shortcut ? CalcTextSize(shortcut, NULL).x : 0.0f;
|
|
|
- float min_w = window->DC.MenuColumns.DeclColumns(label_size.x, shortcut_w, IM_FLOOR(g.FontSize * 1.20f)); // Feedback for next frame
|
|
|
- float extra_w = ImMax(0.0f, GetContentRegionAvail().x - min_w);
|
|
|
- pressed = Selectable(label, false, flags | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, 0.0f));
|
|
|
+ float icon_w = (icon && icon[0]) ? CalcTextSize(icon, NULL).x : 0.0f;
|
|
|
+ float shortcut_w = (shortcut && shortcut[0]) ? CalcTextSize(shortcut, NULL).x : 0.0f;
|
|
|
+ float checkmark_w = IM_FLOOR(g.FontSize * 1.20f);
|
|
|
+ float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, shortcut_w, checkmark_w); // Feedback for next frame
|
|
|
+ float stretch_w = ImMax(0.0f, GetContentRegionAvail().x - min_w);
|
|
|
+ pressed = Selectable("", false, flags | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, 0.0f));
|
|
|
+ RenderText(pos + ImVec2(offsets->OffsetLabel, 0.0f), label);
|
|
|
+ if (icon_w > 0.0f)
|
|
|
+ RenderText(pos + ImVec2(offsets->OffsetIcon, 0.0f), icon);
|
|
|
if (shortcut_w > 0.0f)
|
|
|
{
|
|
|
- PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
|
|
|
- RenderText(pos + ImVec2(window->DC.MenuColumns.Pos[1] + extra_w, 0.0f), shortcut, NULL, false);
|
|
|
+ PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]);
|
|
|
+ RenderText(pos + ImVec2(offsets->OffsetShortcut + stretch_w, 0.0f), shortcut, NULL, false);
|
|
|
PopStyleColor();
|
|
|
}
|
|
|
if (selected)
|
|
|
- RenderCheckMark(window->DrawList, pos + ImVec2(window->DC.MenuColumns.Pos[2] + extra_w + g.FontSize * 0.40f, g.FontSize * 0.134f * 0.5f), GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled), g.FontSize * 0.866f);
|
|
|
+ RenderCheckMark(window->DrawList, pos + ImVec2(offsets->OffsetMark + stretch_w + g.FontSize * 0.40f, g.FontSize * 0.134f * 0.5f), GetColorU32(ImGuiCol_Text), g.FontSize * 0.866f);
|
|
|
}
|
|
|
+ if (!enabled)
|
|
|
+ PopDisabled();
|
|
|
+ PopID();
|
|
|
|
|
|
IMGUI_TEST_ENGINE_ITEM_INFO(window->DC.LastItemId, label, window->DC.LastItemStatusFlags | ImGuiItemStatusFlags_Checkable | (selected ? ImGuiItemStatusFlags_Checked : 0));
|
|
|
return pressed;
|
|
|
}
|
|
|
|
|
|
+bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, bool enabled)
|
|
|
+{
|
|
|
+ return MenuItemEx(label, NULL, shortcut, selected, enabled);
|
|
|
+}
|
|
|
+
|
|
|
bool ImGui::MenuItem(const char* label, const char* shortcut, bool* p_selected, bool enabled)
|
|
|
{
|
|
|
- if (MenuItem(label, shortcut, p_selected ? *p_selected : false, enabled))
|
|
|
+ if (MenuItemEx(label, NULL, shortcut, p_selected ? *p_selected : false, enabled))
|
|
|
{
|
|
|
if (p_selected)
|
|
|
*p_selected = !*p_selected;
|
|
@@ -7997,7 +8037,6 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
|
|
bool pressed = ButtonBehavior(bb, id, &hovered, &held, button_flags);
|
|
|
if (pressed && !is_tab_button)
|
|
|
tab_bar->NextSelectedTabId = id;
|
|
|
- hovered |= (g.HoveredId == id);
|
|
|
|
|
|
// Transfer active id window so the active id is not owned by the dock host (as StartMouseMovingWindow()
|
|
|
// will only do it on the drag). This allows FocusWindow() to be more conservative in how it clears active id.
|
|
@@ -8113,8 +8152,11 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
|
|
PopClipRect();
|
|
|
window->DC.CursorPos = backup_main_cursor_pos;
|
|
|
|
|
|
- // Tooltip (FIXME: Won't work over the close button because ItemOverlap systems messes up with HoveredIdTimer)
|
|
|
- // We test IsItemHovered() to discard e.g. when another item is active or drag and drop over the tab bar (which g.HoveredId ignores)
|
|
|
+ // Tooltip
|
|
|
+ // (Won't work over the close button because ItemOverlap systems messes up with HoveredIdTimer-> seems ok)
|
|
|
+ // (We test IsItemHovered() to discard e.g. when another item is active or drag and drop over the tab bar, which g.HoveredId ignores)
|
|
|
+ // FIXME: This is a mess.
|
|
|
+ // FIXME: We may want disabled tab to still display the tooltip?
|
|
|
if (text_clipped && g.HoveredId == id && !held && g.HoveredIdNotActiveTimer > g.TooltipSlowDelay && IsItemHovered())
|
|
|
if (!(tab_bar->Flags & ImGuiTabBarFlags_NoTooltip) && !(tab->Flags & ImGuiTabItemFlags_NoTooltip))
|
|
|
SetTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label), label);
|