Skip to content

Commit

Permalink
Tab Bar: Added TabItemButton(), ImGuiTabItemFlags_Leading, ImGuiTabIt…
Browse files Browse the repository at this point in the history
…emFlags_Trailing + demo. (#3291)

(squashed various commits by 2 authors)
  • Loading branch information
Xipiryon authored and ocornut committed Sep 22, 2020
1 parent 2983641 commit 4a57a98
Show file tree
Hide file tree
Showing 5 changed files with 264 additions and 50 deletions.
5 changes: 5 additions & 0 deletions docs/CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ Other Changes:
generate an unnecessary extra draw call.
- Tab Bar: Fixed a small bug where toggling a tab bar from Reorderable to not Reorderable would leave
tabs reordered in the tab list popup. [@Xipiryon]
- Tab Bar: Added TabItemButton() to submit tab that behave like a button. (#3291) [@Xipiryon]
- Tab Bar: Added ImGuiTabItemFlags_Leading and ImGuiTabItemFlags_Trailing flags to position tabs or button at
either end of the tab bar. Those tabs won't be part of the scrolling region, won't shrink down, and when
reordering cannot be moving outside of their section. Most often used with TabItemButton(). (#3291) [@Xipiryon]
- Tab Bar: Added ImGuiTabItemFlags_NoReorder flag to disable reordering a given tab.
- Columns: Fix inverted ClipRect being passed to renderer when using certain primitives inside of
a fully clipped column. (#3475) [@szreder]
- Popups, Tooltips: Fix edge cases issues with positionning popups and tooltips when they are larger than
Expand Down
8 changes: 6 additions & 2 deletions imgui.h
Original file line number Diff line number Diff line change
Expand Up @@ -653,8 +653,9 @@ namespace ImGui
// Tab Bars, Tabs
IMGUI_API bool BeginTabBar(const char* str_id, ImGuiTabBarFlags flags = 0); // create and append into a TabBar
IMGUI_API void EndTabBar(); // only call EndTabBar() if BeginTabBar() returns true!
IMGUI_API bool BeginTabItem(const char* label, bool* p_open = NULL, ImGuiTabItemFlags flags = 0);// create a Tab. Returns true if the Tab is selected.
IMGUI_API bool BeginTabItem(const char* label, bool* p_open = NULL, ImGuiTabItemFlags flags = 0); // create a Tab. Returns true if the Tab is selected.
IMGUI_API void EndTabItem(); // only call EndTabItem() if BeginTabItem() returns true!
IMGUI_API bool TabItemButton(const char* label, ImGuiTabItemFlags flags = 0); // create a Tab behaving like a button
IMGUI_API void SetTabItemClosed(const char* tab_or_docked_window_label); // notify TabBar or Docking system of a closed tab/window ahead (useful to reduce visual flicker on reorderable tab bars). For tab-bar: call after BeginTabBar() and before Tab submissions. Otherwise call with a window name.

// Logging/Capture
Expand Down Expand Up @@ -954,7 +955,10 @@ enum ImGuiTabItemFlags_
ImGuiTabItemFlags_SetSelected = 1 << 1, // Trigger flag to programmatically make the tab selected when calling BeginTabItem()
ImGuiTabItemFlags_NoCloseWithMiddleMouseButton = 1 << 2, // Disable behavior of closing tabs (that are submitted with p_open != NULL) with middle mouse button. You can still repro this behavior on user's side with if (IsItemHovered() && IsMouseClicked(2)) *p_open = false.
ImGuiTabItemFlags_NoPushId = 1 << 3, // Don't call PushID(tab->ID)/PopID() on BeginTabItem()/EndTabItem()
ImGuiTabItemFlags_NoTooltip = 1 << 4 // Disable tooltip for the given tab
ImGuiTabItemFlags_NoTooltip = 1 << 4, // Disable tooltip for the given tab
ImGuiTabItemFlags_NoReorder = 1 << 5, // Disable reordering this tab or having another tab cross over this tab
ImGuiTabItemFlags_Leading = 1 << 6, // Enforce the tab position to the left of the tab bar (after the tab list popup button) and disable resizing down
ImGuiTabItemFlags_Trailing = 1 << 7 // Enforce the tab position to the right of the tab bar (before the scrolling buttons) and disable resizing down
};

// Flags for ImGui::IsWindowFocused()
Expand Down
85 changes: 85 additions & 0 deletions imgui_demo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2354,6 +2354,91 @@ static void ShowDemoWindowLayout()
ImGui::Separator();
ImGui::TreePop();
}

if (ImGui::TreeNode("TabItem Button"))
{
static int next_id = 0;
static ImVector<int> tabs_list;
if (next_id == 0) // Initialize with a default tab
for (int i = 0; i < 9; i++)
tabs_list.push_back(next_id++);

static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_Reorderable | ImGuiTabBarFlags_FittingPolicyResizeDown;
ImGui::CheckboxFlags("ImGuiTabBarFlags_Reorderable", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_Reorderable);
ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton);
if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown))
tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyResizeDown);
if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll))
tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyScroll);

static bool show_leading_button = true;
static bool show_trailing_button = true;
ImGui::Checkbox("Show Leading TabItemButton()", &show_leading_button);
ImGui::Checkbox("Show Trailing TabItemButton()", &show_trailing_button);
static bool enable_position = false;
ImGui::Checkbox("Enable Leading/Trailing TabItem()", &enable_position);

if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags))
{
if (show_leading_button)
{
if (ImGui::TabItemButton("+", ImGuiTabItemFlags_Leading | ImGuiTabItemFlags_NoTooltip))
tabs_list.push_back(next_id++);
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Add a new TabItem() in the tab bar");

// Popup Context also works with TabItemButton
if (ImGui::BeginPopupContextItem())
{
ImGui::Text("I'm a popup!");
if (ImGui::Button("Close"))
ImGui::CloseCurrentPopup();
ImGui::EndPopup();
}
}

bool close_current_tab = false;
if (show_trailing_button)
{
if (ImGui::TabItemButton("X", ImGuiTabItemFlags_Trailing | ImGuiTabItemFlags_NoTooltip))
close_current_tab = true;
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Close the currently selected TabItem()");
}

for (int n = 0; n < tabs_list.Size; )
{
int mod = tabs_list[n] % 3;
ImGuiTabItemFlags flags = mod == 0 ? 0 : mod == 1 ? ImGuiTabItemFlags_Leading : ImGuiTabItemFlags_Trailing;
if (!enable_position)
flags = 0;

char name[16];
snprintf(name, IM_ARRAYSIZE(name), "%04d", tabs_list[n]);
bool open = true;
if (ImGui::BeginTabItem(name, &open, flags))
{
ImGui::Text("This is the %s tab!", name);
ImGui::EndTabItem();

if (close_current_tab)
{
open = false;
ImGui::SetTabItemClosed(name);
}
}

if (!open)
tabs_list.erase(tabs_list.Data + n);
else
++n;
}

ImGui::EndTabBar();
}
ImGui::Separator();
ImGui::TreePop();
}
ImGui::TreePop();
}

Expand Down
6 changes: 4 additions & 2 deletions imgui_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -1703,7 +1703,8 @@ enum ImGuiTabBarFlagsPrivate_
// Extend ImGuiTabItemFlags_
enum ImGuiTabItemFlagsPrivate_
{
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 // [Internal] Used by TabItemButton, change the tab item behavior to mimic a button
};

// Storage for one active tab item (sizeof() 28~32 bytes)
Expand Down Expand Up @@ -1737,7 +1738,8 @@ struct ImGuiTabBar
float LastTabContentHeight; // Record the height of contents submitted below the tab bar
float WidthAllTabs; // Actual width of all tabs (locked during layout)
float WidthAllTabsIdeal; // Ideal width if all tabs were visible and not clipped
float OffsetNextTab; // Distance from BarRect.Min.x, incremented with each BeginTabItem() call, not used if ImGuiTabBarFlags_Reorderable if set.
float LeadingWidth; // Total width used by leading button
float TrailingWidth; // Total width used by trailing button
float ScrollingAnim;
float ScrollingTarget;
float ScrollingTargetDistToVisibility;
Expand Down
Loading

0 comments on commit 4a57a98

Please sign in to comment.