|
@@ -9981,7 +9981,7 @@ bool ImGui::BeginTabItem(const char* label, bool* p_open, ImGuiTabItemFlags f
|
|
|
IM_ASSERT_USER_ERROR(tab_bar, "Needs to be called between BeginTabBar() and EndTabBar()!");
|
|
|
return false;
|
|
|
}
|
|
|
- IM_ASSERT((flags & ImGuiTabItemFlags_Button) == 0); // BeginTabItem() Can't be used with button flags, use TabItemButton() instead!
|
|
|
+ IM_ASSERT((flags & ImGuiTabItemFlags_Button) == 0); // BeginTabItem() Can't be used with button flags, use TabItemButton() instead!
|
|
|
|
|
|
bool ret = TabItemEx(tab_bar, label, p_open, flags, NULL);
|
|
|
if (ret && !(flags & ImGuiTabItemFlags_NoPushId))
|
|
@@ -10027,6 +10027,23 @@ bool ImGui::TabItemButton(const char* label, ImGuiTabItemFlags flags)
|
|
|
return TabItemEx(tab_bar, label, NULL, flags | ImGuiTabItemFlags_Button | ImGuiTabItemFlags_NoReorder, NULL);
|
|
|
}
|
|
|
|
|
|
+void ImGui::TabItemSpacing(const char* str_id, ImGuiTabItemFlags flags, float width)
|
|
|
+{
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
+ ImGuiWindow* window = g.CurrentWindow;
|
|
|
+ if (window->SkipItems)
|
|
|
+ return;
|
|
|
+
|
|
|
+ ImGuiTabBar* tab_bar = g.CurrentTabBar;
|
|
|
+ if (tab_bar == NULL)
|
|
|
+ {
|
|
|
+ IM_ASSERT_USER_ERROR(tab_bar != NULL, "Needs to be called between BeginTabBar() and EndTabBar()!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ SetNextItemWidth(width);
|
|
|
+ TabItemEx(tab_bar, str_id, NULL, flags | ImGuiTabItemFlags_Button | ImGuiTabItemFlags_NoReorder | ImGuiTabItemFlags_Invisible, NULL);
|
|
|
+}
|
|
|
+
|
|
|
bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags, ImGuiWindow* docked_window)
|
|
|
{
|
|
|
// Layout whole tab bar if not already done
|
|
@@ -10174,8 +10191,11 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
|
|
ImGuiButtonFlags button_flags = ((is_tab_button ? ImGuiButtonFlags_PressedOnClickRelease : ImGuiButtonFlags_PressedOnClick) | ImGuiButtonFlags_AllowOverlap);
|
|
|
if (g.DragDropActive && !g.DragDropPayload.IsDataType(IMGUI_PAYLOAD_TYPE_WINDOW)) // FIXME: May be an opt-in property of the payload to disable this
|
|
|
button_flags |= ImGuiButtonFlags_PressedOnDragDropHold;
|
|
|
- bool hovered, held;
|
|
|
- bool pressed = ButtonBehavior(bb, id, &hovered, &held, button_flags);
|
|
|
+ bool hovered, held, pressed;
|
|
|
+ if (flags & ImGuiTabItemFlags_Invisible)
|
|
|
+ hovered = held = pressed = false;
|
|
|
+ else
|
|
|
+ pressed = ButtonBehavior(bb, id, &hovered, &held, button_flags);
|
|
|
if (pressed && !is_tab_button)
|
|
|
TabBarQueueFocus(tab_bar, tab);
|
|
|
|
|
@@ -10260,67 +10280,71 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
|
|
#endif
|
|
|
|
|
|
// Render tab shape
|
|
|
- ImDrawList* display_draw_list = window->DrawList;
|
|
|
- const ImU32 tab_col = GetColorU32((held || hovered) ? ImGuiCol_TabHovered : tab_contents_visible ? (tab_bar_focused ? ImGuiCol_TabSelected : ImGuiCol_TabDimmedSelected) : (tab_bar_focused ? ImGuiCol_Tab : ImGuiCol_TabDimmed));
|
|
|
- TabItemBackground(display_draw_list, bb, flags, tab_col);
|
|
|
- if (tab_contents_visible && (tab_bar->Flags & ImGuiTabBarFlags_DrawSelectedOverline) && style.TabBarOverlineSize > 0.0f)
|
|
|
- {
|
|
|
- // Might be moved to TabItemBackground() ?
|
|
|
- ImVec2 tl = bb.GetTL() + ImVec2(0, 1.0f * g.CurrentDpiScale);
|
|
|
- ImVec2 tr = bb.GetTR() + ImVec2(0, 1.0f * g.CurrentDpiScale);
|
|
|
- ImU32 overline_col = GetColorU32(tab_bar_focused ? ImGuiCol_TabSelectedOverline : ImGuiCol_TabDimmedSelectedOverline);
|
|
|
- if (style.TabRounding > 0.0f)
|
|
|
- {
|
|
|
- float rounding = style.TabRounding;
|
|
|
- display_draw_list->PathArcToFast(tl + ImVec2(+rounding, +rounding), rounding, 7, 9);
|
|
|
- display_draw_list->PathArcToFast(tr + ImVec2(-rounding, +rounding), rounding, 9, 11);
|
|
|
- display_draw_list->PathStroke(overline_col, 0, style.TabBarOverlineSize);
|
|
|
- }
|
|
|
- else
|
|
|
+ const bool is_visible = (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Visible) && !(flags & ImGuiTabItemFlags_Invisible);
|
|
|
+ if (is_visible)
|
|
|
+ {
|
|
|
+ ImDrawList* display_draw_list = window->DrawList;
|
|
|
+ const ImU32 tab_col = GetColorU32((held || hovered) ? ImGuiCol_TabHovered : tab_contents_visible ? (tab_bar_focused ? ImGuiCol_TabSelected : ImGuiCol_TabDimmedSelected) : (tab_bar_focused ? ImGuiCol_Tab : ImGuiCol_TabDimmed));
|
|
|
+ TabItemBackground(display_draw_list, bb, flags, tab_col);
|
|
|
+ if (tab_contents_visible && (tab_bar->Flags & ImGuiTabBarFlags_DrawSelectedOverline) && style.TabBarOverlineSize > 0.0f)
|
|
|
{
|
|
|
- display_draw_list->AddLine(tl - ImVec2(0.5f, 0.5f), tr - ImVec2(0.5f, 0.5f), overline_col, style.TabBarOverlineSize);
|
|
|
+ // Might be moved to TabItemBackground() ?
|
|
|
+ ImVec2 tl = bb.GetTL() + ImVec2(0, 1.0f * g.CurrentDpiScale);
|
|
|
+ ImVec2 tr = bb.GetTR() + ImVec2(0, 1.0f * g.CurrentDpiScale);
|
|
|
+ ImU32 overline_col = GetColorU32(tab_bar_focused ? ImGuiCol_TabSelectedOverline : ImGuiCol_TabDimmedSelectedOverline);
|
|
|
+ if (style.TabRounding > 0.0f)
|
|
|
+ {
|
|
|
+ float rounding = style.TabRounding;
|
|
|
+ display_draw_list->PathArcToFast(tl + ImVec2(+rounding, +rounding), rounding, 7, 9);
|
|
|
+ display_draw_list->PathArcToFast(tr + ImVec2(-rounding, +rounding), rounding, 9, 11);
|
|
|
+ display_draw_list->PathStroke(overline_col, 0, style.TabBarOverlineSize);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ display_draw_list->AddLine(tl - ImVec2(0.5f, 0.5f), tr - ImVec2(0.5f, 0.5f), overline_col, style.TabBarOverlineSize);
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
- RenderNavCursor(bb, id);
|
|
|
+ RenderNavCursor(bb, id);
|
|
|
|
|
|
- // Select with right mouse button. This is so the common idiom for context menu automatically highlight the current widget.
|
|
|
- const bool hovered_unblocked = IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup);
|
|
|
- if (tab_bar->SelectedTabId != tab->ID && hovered_unblocked && (IsMouseClicked(1) || IsMouseReleased(1)) && !is_tab_button)
|
|
|
- TabBarQueueFocus(tab_bar, tab);
|
|
|
+ // Select with right mouse button. This is so the common idiom for context menu automatically highlight the current widget.
|
|
|
+ const bool hovered_unblocked = IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup);
|
|
|
+ if (tab_bar->SelectedTabId != tab->ID && hovered_unblocked && (IsMouseClicked(1) || IsMouseReleased(1)) && !is_tab_button)
|
|
|
+ TabBarQueueFocus(tab_bar, tab);
|
|
|
|
|
|
- if (tab_bar->Flags & ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)
|
|
|
- flags |= ImGuiTabItemFlags_NoCloseWithMiddleMouseButton;
|
|
|
+ if (tab_bar->Flags & ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)
|
|
|
+ flags |= ImGuiTabItemFlags_NoCloseWithMiddleMouseButton;
|
|
|
|
|
|
- // Render tab label, process close button
|
|
|
- const ImGuiID close_button_id = p_open ? GetIDWithSeed("#CLOSE", NULL, docked_window ? docked_window->ID : id) : 0;
|
|
|
- bool just_closed;
|
|
|
- bool text_clipped;
|
|
|
- TabItemLabelAndCloseButton(display_draw_list, bb, tab_just_unsaved ? (flags & ~ImGuiTabItemFlags_UnsavedDocument) : flags, tab_bar->FramePadding, label, id, close_button_id, tab_contents_visible, &just_closed, &text_clipped);
|
|
|
- if (just_closed && p_open != NULL)
|
|
|
- {
|
|
|
- *p_open = false;
|
|
|
- TabBarCloseTab(tab_bar, tab);
|
|
|
- }
|
|
|
+ // Render tab label, process close button
|
|
|
+ const ImGuiID close_button_id = p_open ? GetIDWithSeed("#CLOSE", NULL, docked_window ? docked_window->ID : id) : 0;
|
|
|
+ bool just_closed;
|
|
|
+ bool text_clipped;
|
|
|
+ TabItemLabelAndCloseButton(display_draw_list, bb, tab_just_unsaved ? (flags & ~ImGuiTabItemFlags_UnsavedDocument) : flags, tab_bar->FramePadding, label, id, close_button_id, tab_contents_visible, &just_closed, &text_clipped);
|
|
|
+ if (just_closed && p_open != NULL)
|
|
|
+ {
|
|
|
+ *p_open = false;
|
|
|
+ TabBarCloseTab(tab_bar, tab);
|
|
|
+ }
|
|
|
|
|
|
- // Forward Hovered state so IsItemHovered() after Begin() can work (even though we are technically hovering our parent)
|
|
|
- // That state is copied to window->DockTabItemStatusFlags by our caller.
|
|
|
- if (docked_window && (hovered || g.HoveredId == close_button_id))
|
|
|
- g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow;
|
|
|
+ // Forward Hovered state so IsItemHovered() after Begin() can work (even though we are technically hovering our parent)
|
|
|
+ // That state is copied to window->DockTabItemStatusFlags by our caller.
|
|
|
+ if (docked_window && (hovered || g.HoveredId == close_button_id))
|
|
|
+ g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow;
|
|
|
+
|
|
|
+ // 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)
|
|
|
+ if (!(tab_bar->Flags & ImGuiTabBarFlags_NoTooltip) && !(tab->Flags & ImGuiTabItemFlags_NoTooltip))
|
|
|
+ SetItemTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label), label);
|
|
|
+ }
|
|
|
|
|
|
// Restore main window position so user can draw there
|
|
|
if (want_clip_rect)
|
|
|
PopClipRect();
|
|
|
window->DC.CursorPos = backup_main_cursor_pos;
|
|
|
|
|
|
- // 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)
|
|
|
- if (!(tab_bar->Flags & ImGuiTabBarFlags_NoTooltip) && !(tab->Flags & ImGuiTabItemFlags_NoTooltip))
|
|
|
- SetItemTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label), label);
|
|
|
-
|
|
|
IM_ASSERT(!is_tab_button || !(tab_bar->SelectedTabId == tab->ID && is_tab_button)); // TabItemButton should not be selected
|
|
|
if (is_tab_button)
|
|
|
return pressed;
|