1
0
mirror of https://github.com/ocornut/imgui.git synced 2025-02-02 20:47:23 +01:00

TabBar: Internals: added TabItemSpacing(). (#8349, #3291)

This commit is contained in:
ocornut 2025-01-27 15:41:24 +01:00
parent a05d547ae8
commit 9c4948a4d1
2 changed files with 73 additions and 46 deletions

View File

@ -2612,6 +2612,8 @@ enum ImGuiTabItemFlagsPrivate_
ImGuiTabItemFlags_SectionMask_ = ImGuiTabItemFlags_Leading | ImGuiTabItemFlags_Trailing, ImGuiTabItemFlags_SectionMask_ = ImGuiTabItemFlags_Leading | ImGuiTabItemFlags_Trailing,
ImGuiTabItemFlags_NoCloseButton = 1 << 20, // Track whether p_open was set or not (we'll need this info on the next frame to recompute ContentWidth during layout) ImGuiTabItemFlags_NoCloseButton = 1 << 20, // Track whether p_open was set or not (we'll need this info on the next frame to recompute ContentWidth during layout)
ImGuiTabItemFlags_Button = 1 << 21, // Used by TabItemButton, change the tab item behavior to mimic a button ImGuiTabItemFlags_Button = 1 << 21, // Used by TabItemButton, change the tab item behavior to mimic a button
ImGuiTabItemFlags_Invisible = 1 << 22, // To reserve space e.g. with ImGuiTabItemFlags_Leading
//ImGuiTabItemFlags_Unsorted = 1 << 23, // [Docking] Trailing tabs with the _Unsorted flag will be sorted based on the DockOrder of their Window.
}; };
// Storage for one active tab item (sizeof() 40 bytes) // Storage for one active tab item (sizeof() 40 bytes)
@ -3378,6 +3380,7 @@ namespace ImGui
IMGUI_API void TabBarQueueReorderFromMousePos(ImGuiTabBar* tab_bar, ImGuiTabItem* tab, ImVec2 mouse_pos); IMGUI_API void TabBarQueueReorderFromMousePos(ImGuiTabBar* tab_bar, ImGuiTabItem* tab, ImVec2 mouse_pos);
IMGUI_API bool TabBarProcessReorder(ImGuiTabBar* tab_bar); IMGUI_API bool TabBarProcessReorder(ImGuiTabBar* tab_bar);
IMGUI_API bool TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags, ImGuiWindow* docked_window); IMGUI_API bool TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags, ImGuiWindow* docked_window);
IMGUI_API void TabItemSpacing(const char* str_id, ImGuiTabItemFlags flags, float width);
IMGUI_API ImVec2 TabItemCalcSize(const char* label, bool has_close_button_or_unsaved_marker); IMGUI_API ImVec2 TabItemCalcSize(const char* label, bool has_close_button_or_unsaved_marker);
IMGUI_API ImVec2 TabItemCalcSize(ImGuiWindow* window); IMGUI_API ImVec2 TabItemCalcSize(ImGuiWindow* window);
IMGUI_API void TabItemBackground(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImU32 col); IMGUI_API void TabItemBackground(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImU32 col);

View File

@ -9925,7 +9925,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()!"); IM_ASSERT_USER_ERROR(tab_bar, "Needs to be called between BeginTabBar() and EndTabBar()!");
return false; return false;
} }
IM_ASSERT(!(flags & ImGuiTabItemFlags_Button)); // 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); bool ret = TabItemEx(tab_bar, label, p_open, flags, NULL);
if (ret && !(flags & ImGuiTabItemFlags_NoPushId)) if (ret && !(flags & ImGuiTabItemFlags_NoPushId))
@ -9971,6 +9971,23 @@ bool ImGui::TabItemButton(const char* label, ImGuiTabItemFlags flags)
return TabItemEx(tab_bar, label, NULL, flags | ImGuiTabItemFlags_Button | ImGuiTabItemFlags_NoReorder, NULL); 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) 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 // Layout whole tab bar if not already done
@ -10116,8 +10133,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); ImGuiButtonFlags button_flags = ((is_tab_button ? ImGuiButtonFlags_PressedOnClickRelease : ImGuiButtonFlags_PressedOnClick) | ImGuiButtonFlags_AllowOverlap);
if (g.DragDropActive) if (g.DragDropActive)
button_flags |= ImGuiButtonFlags_PressedOnDragDropHold; button_flags |= ImGuiButtonFlags_PressedOnDragDropHold;
bool hovered, held; bool hovered, held, pressed;
bool pressed = ButtonBehavior(bb, id, &hovered, &held, button_flags); if (flags & ImGuiTabItemFlags_Invisible)
hovered = held = pressed = false;
else
pressed = ButtonBehavior(bb, id, &hovered, &held, button_flags);
if (pressed && !is_tab_button) if (pressed && !is_tab_button)
TabBarQueueFocus(tab_bar, tab); TabBarQueueFocus(tab_bar, tab);
@ -10149,6 +10169,9 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
#endif #endif
// Render tab shape // Render tab shape
const bool is_visible = (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Visible) && !(flags & ImGuiTabItemFlags_Invisible);
if (is_visible)
{
ImDrawList* display_draw_list = window->DrawList; 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)); 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); TabItemBackground(display_draw_list, bb, flags, tab_col);
@ -10191,11 +10214,6 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
TabBarCloseTab(tab_bar, tab); TabBarCloseTab(tab_bar, tab);
} }
// Restore main window position so user can draw there
if (want_clip_rect)
PopClipRect();
window->DC.CursorPos = backup_main_cursor_pos;
// Tooltip // Tooltip
// (Won't work over the close button because ItemOverlap systems messes up with HoveredIdTimer-> seems ok) // (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) // (We test IsItemHovered() to discard e.g. when another item is active or drag and drop over the tab bar, which g.HoveredId ignores)
@ -10204,6 +10222,12 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
if (text_clipped && g.HoveredId == id && !held) if (text_clipped && g.HoveredId == id && !held)
if (!(tab_bar->Flags & ImGuiTabBarFlags_NoTooltip) && !(tab->Flags & ImGuiTabItemFlags_NoTooltip)) if (!(tab_bar->Flags & ImGuiTabBarFlags_NoTooltip) && !(tab->Flags & ImGuiTabItemFlags_NoTooltip))
SetItemTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label), label); 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;
IM_ASSERT(!is_tab_button || !(tab_bar->SelectedTabId == tab->ID && is_tab_button)); // TabItemButton should not be selected IM_ASSERT(!is_tab_button || !(tab_bar->SelectedTabId == tab->ID && is_tab_button)); // TabItemButton should not be selected
if (is_tab_button) if (is_tab_button)