Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/wolfpld/tracy.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/imgui
diff options
context:
space:
mode:
authorBartosz Taudul <wolf.pld@gmail.com>2021-01-22 00:53:59 +0300
committerBartosz Taudul <wolf.pld@gmail.com>2021-01-22 01:26:32 +0300
commit9f4efc8474e89a7b59d55c42be49500c4ee0f405 (patch)
treebbd87e14082f0e8d02957d10d131f9c9435e4732 /imgui
parent5fc4eb2efa7b712e3679c5f998ea52e6374d084c (diff)
Update ImGui to 1.80 + docking.
Diffstat (limited to 'imgui')
-rw-r--r--imgui/imconfig.h4
-rw-r--r--imgui/imgui.cpp189
-rw-r--r--imgui/imgui.h222
-rw-r--r--imgui/imgui_demo.cpp472
-rw-r--r--imgui/imgui_draw.cpp2
-rw-r--r--imgui/imgui_internal.h56
-rw-r--r--imgui/imgui_tables.cpp234
-rw-r--r--imgui/imgui_widgets.cpp46
8 files changed, 727 insertions, 498 deletions
diff --git a/imgui/imconfig.h b/imgui/imconfig.h
index 736958b3..e17c5a90 100644
--- a/imgui/imconfig.h
+++ b/imgui/imconfig.h
@@ -59,8 +59,8 @@
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
-//---- Unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined, use the much faster STB sprintf library implementation of vsnprintf instead of the one from the default C library.
-// Note that stb_sprintf.h is meant to be provided by the user and available in the include path at compile time. Also, the compatibility checks of the arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf.
+//---- Use stb_printf's faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
+// Requires 'stb_sprintf.h' to be available in the include path. Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf.
// #define IMGUI_USE_STB_SPRINTF
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
diff --git a/imgui/imgui.cpp b/imgui/imgui.cpp
index bbe9a7fa..e97dce13 100644
--- a/imgui/imgui.cpp
+++ b/imgui/imgui.cpp
@@ -1,4 +1,4 @@
-// dear imgui, v1.80 WIP
+// dear imgui, v1.80
// (main code and documentation)
// Help:
@@ -2488,6 +2488,11 @@ struct ImGuiStyleVarInfo
void* GetVarPtr(ImGuiStyle* style) const { return (void*)((unsigned char*)style + Offset); }
};
+static const ImGuiCol GWindowDockStyleColors[ImGuiWindowDockStyleCol_COUNT] =
+{
+ ImGuiCol_Text, ImGuiCol_Tab, ImGuiCol_TabHovered, ImGuiCol_TabActive, ImGuiCol_TabUnfocused, ImGuiCol_TabUnfocusedActive
+};
+
static const ImGuiStyleVarInfo GStyleVarInfo[] =
{
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, Alpha) }, // ImGuiStyleVar_Alpha
@@ -4059,7 +4064,7 @@ void ImGui::NewFrame()
// Undocking
// (needs to be before UpdateMouseMovingWindowNewFrame so the window is already offset and following the mouse on the detaching frame)
- DockContextUpdateUndocking(&g);
+ DockContextNewFrameUpdateUndocking(&g);
// Find hovered window
// (needs to be before UpdateMouseMovingWindowNewFrame so we fill g.HoveredWindowUnderMovingWindow on the mouse release frame)
@@ -4123,7 +4128,7 @@ void ImGui::NewFrame()
ClosePopupsOverWindow(g.NavWindow, false);
// Docking
- DockContextUpdateDocking(&g);
+ DockContextNewFrameUpdateDocking(&g);
// [DEBUG] Item picker tool - start with DebugStartItemPicker() - useful to visually select an item and break into its call-stack.
UpdateDebugToolItemPicker();
@@ -5142,16 +5147,15 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b
SetNextWindowSize(size);
// Build up name. If you need to append to a same child from multiple location in the ID stack, use BeginChild(ImGuiID id) with a stable value.
- char title[256];
if (name)
- ImFormatString(title, IM_ARRAYSIZE(title), "%s/%s_%08X", parent_window->Name, name, id);
+ ImFormatString(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), "%s/%s_%08X", parent_window->Name, name, id);
else
- ImFormatString(title, IM_ARRAYSIZE(title), "%s/%08X", parent_window->Name, id);
+ ImFormatString(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), "%s/%08X", parent_window->Name, id);
const float backup_border_size = g.Style.ChildBorderSize;
if (!border)
g.Style.ChildBorderSize = 0.0f;
- bool ret = Begin(title, NULL, flags);
+ bool ret = Begin(g.TempBuffer, NULL, flags);
g.Style.ChildBorderSize = backup_border_size;
ImGuiWindow* child_window = g.CurrentWindow;
@@ -5377,18 +5381,24 @@ static ImVec2 CalcWindowSizeAfterConstraint(ImGuiWindow* window, ImVec2 new_size
return new_size;
}
-static ImVec2 CalcWindowContentSize(ImGuiWindow* window)
+static void CalcWindowContentSizes(ImGuiWindow* window, ImVec2* content_size_current, ImVec2* content_size_ideal)
{
- if (window->Collapsed)
- if (window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0)
- return window->ContentSize;
- if (window->Hidden && window->HiddenFramesCannotSkipItems == 0 && window->HiddenFramesCanSkipItems > 0)
- return window->ContentSize;
+ bool preserve_old_content_sizes = false;
+ if (window->Collapsed && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0)
+ preserve_old_content_sizes = true;
+ else if (window->Hidden && window->HiddenFramesCannotSkipItems == 0 && window->HiddenFramesCanSkipItems > 0)
+ preserve_old_content_sizes = true;
+ if (preserve_old_content_sizes)
+ {
+ *content_size_current = window->ContentSize;
+ *content_size_ideal = window->ContentSizeIdeal;
+ return;
+ }
- ImVec2 sz;
- sz.x = IM_FLOOR((window->ContentSizeExplicit.x != 0.0f) ? window->ContentSizeExplicit.x : window->DC.CursorMaxPos.x - window->DC.CursorStartPos.x);
- sz.y = IM_FLOOR((window->ContentSizeExplicit.y != 0.0f) ? window->ContentSizeExplicit.y : window->DC.CursorMaxPos.y - window->DC.CursorStartPos.y);
- return sz;
+ content_size_current->x = (window->ContentSizeExplicit.x != 0.0f) ? window->ContentSizeExplicit.x : IM_FLOOR(window->DC.CursorMaxPos.x - window->DC.CursorStartPos.x);
+ content_size_current->y = (window->ContentSizeExplicit.y != 0.0f) ? window->ContentSizeExplicit.y : IM_FLOOR(window->DC.CursorMaxPos.y - window->DC.CursorStartPos.y);
+ content_size_ideal->x = (window->ContentSizeExplicit.x != 0.0f) ? window->ContentSizeExplicit.x : IM_FLOOR(ImMax(window->DC.CursorMaxPos.x, window->DC.IdealMaxPos.x) - window->DC.CursorStartPos.x);
+ content_size_ideal->y = (window->ContentSizeExplicit.y != 0.0f) ? window->ContentSizeExplicit.y : IM_FLOOR(ImMax(window->DC.CursorMaxPos.y, window->DC.IdealMaxPos.y) - window->DC.CursorStartPos.y);
}
static ImVec2 CalcWindowAutoFitSize(ImGuiWindow* window, const ImVec2& size_contents)
@@ -5434,10 +5444,12 @@ static ImVec2 CalcWindowAutoFitSize(ImGuiWindow* window, const ImVec2& size_cont
}
}
-ImVec2 ImGui::CalcWindowExpectedSize(ImGuiWindow* window)
+ImVec2 ImGui::CalcWindowNextAutoFitSize(ImGuiWindow* window)
{
- ImVec2 size_contents = CalcWindowContentSize(window);
- ImVec2 size_auto_fit = CalcWindowAutoFitSize(window, size_contents);
+ ImVec2 size_contents_current;
+ ImVec2 size_contents_ideal;
+ CalcWindowContentSizes(window, &size_contents_current, &size_contents_ideal);
+ ImVec2 size_auto_fit = CalcWindowAutoFitSize(window, size_contents_ideal);
ImVec2 size_final = CalcWindowSizeAfterConstraint(window, size_auto_fit);
return size_final;
}
@@ -6118,7 +6130,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// UPDATE CONTENTS SIZE, UPDATE HIDDEN STATUS
// Update contents size from last frame for auto-fitting (or use explicit size)
- window->ContentSize = CalcWindowContentSize(window);
+ CalcWindowContentSizes(window, &window->ContentSize, &window->ContentSizeIdeal);
if (window->HiddenFramesCanSkipItems > 0)
window->HiddenFramesCanSkipItems--;
if (window->HiddenFramesCannotSkipItems > 0)
@@ -6141,7 +6153,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->Size.x = window->SizeFull.x = 0.f;
if (!window_size_y_set_by_api)
window->Size.y = window->SizeFull.y = 0.f;
- window->ContentSize = ImVec2(0.f, 0.f);
+ window->ContentSize = window->ContentSizeIdeal = ImVec2(0.f, 0.f);
}
}
@@ -6194,7 +6206,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// SIZE
// Calculate auto-fit size, handle automatic resize
- const ImVec2 size_auto_fit = CalcWindowAutoFitSize(window, window->ContentSize);
+ const ImVec2 size_auto_fit = CalcWindowAutoFitSize(window, window->ContentSizeIdeal);
bool use_current_size_for_scrollbar_x = window_just_created;
bool use_current_size_for_scrollbar_y = window_just_created;
if ((flags & ImGuiWindowFlags_AlwaysAutoResize) && !window->Collapsed)
@@ -6618,6 +6630,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->DC.CursorPos = window->DC.CursorStartPos;
window->DC.CursorPosPrevLine = window->DC.CursorPos;
window->DC.CursorMaxPos = window->DC.CursorStartPos;
+ window->DC.IdealMaxPos = window->DC.CursorStartPos;
window->DC.CurrLineSize = window->DC.PrevLineSize = ImVec2(0.0f, 0.0f);
window->DC.CurrLineTextBaseOffset = window->DC.PrevLineTextBaseOffset = 0.0f;
@@ -6678,7 +6691,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// This works but 1. doesn't handle multiple Begin/End pairs, 2. recursing into another Begin/End pair - so we need to work that out and add better logging scope.
// Maybe we can support CTRL+C on every element?
/*
- if (g.ActiveId == move_id)
+ //if (g.NavWindow == window && g.ActiveId == 0)
+ if (g.ActiveId == window->MoveId)
if (g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_C))
LogToClipboard();
*/
@@ -7339,7 +7353,7 @@ void ImGui::SetNextWindowContentSize(const ImVec2& size)
{
ImGuiContext& g = *GImGui;
g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasContentSize;
- g.NextWindowData.ContentSizeVal = size;
+ g.NextWindowData.ContentSizeVal = ImFloor(size);
}
void ImGui::SetNextWindowScroll(const ImVec2& scroll)
@@ -11930,6 +11944,50 @@ void ImGui::DestroyPlatformWindows()
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
+// Typical Docking call flow: (root level is generally public API):
+//-----------------------------------------------------------------------------
+// - NewFrame() new dear imgui frame
+// | DockContextNewFrameUpdateUndocking() - process queued undocking requests
+// | - DockContextProcessUndockWindow() - process one window undocking request
+// | - DockContextProcessUndockNode() - process one whole node undocking request
+// | DockContextNewFrameUpdateUndocking() - process queue docking requests, create floating dock nodes
+// | - update g.HoveredDockNode - [debug] update node hovered by mouse
+// | - DockContextProcessDock() - process one docking request
+// | - DockNodeUpdate()
+// | - DockNodeUpdateForRootNode()
+// | - DockNodeUpdateVisibleFlagAndInactiveChilds()
+// | - DockNodeFindInfo()
+// | - destroy unused node or tab bar
+// | - create dock node host window
+// | - Begin() etc.
+// | - DockNodeStartMouseMovingWindow()
+// | - DockNodeTreeUpdatePosSize()
+// | - DockNodeTreeUpdateSplitter()
+// | - draw node background
+// | - DockNodeUpdateTabBar() - create/update tab bar for a docking node
+// | - DockNodeAddTabBar()
+// | - DockNodeUpdateWindowMenu()
+// | - DockNodeCalcTabBarLayout()
+// | - BeginTabBarEx()
+// | - TabItemEx() calls
+// | - EndTabBar()
+// | - BeginDockableDragDropTarget()
+// | - DockNodeUpdate() - recurse into child nodes...
+//-----------------------------------------------------------------------------
+// - DockSpace() user submit a dockspace into a window
+// | Begin(Child) - create a child window
+// | DockNodeUpdate() - call main dock node update function
+// | End(Child)
+// | ItemSize()
+//-----------------------------------------------------------------------------
+// - Begin()
+// | BeginDocked()
+// | BeginDockableDragDropSource()
+// | BeginDockableDragDropTarget()
+// | - DockNodePreviewDockRender()
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
// Docking: Internal Types
//-----------------------------------------------------------------------------
// - ImGuiDockRequestType
@@ -12079,8 +12137,8 @@ namespace ImGui
// - DockContextShutdown()
// - DockContextClearNodes()
// - DockContextRebuildNodes()
-// - DockContextUpdateUndocking()
-// - DockContextUpdateDocking()
+// - DockContextNewFrameUpdateUndocking()
+// - DockContextNewFrameUpdateDocking()
// - DockContextFindNodeByID()
// - DockContextBindNodeToWindow()
// - DockContextGenNodeID()
@@ -12139,7 +12197,7 @@ void ImGui::DockContextRebuildNodes(ImGuiContext* ctx)
}
// Docking context update function, called by NewFrame()
-void ImGui::DockContextUpdateUndocking(ImGuiContext* ctx)
+void ImGui::DockContextNewFrameUpdateUndocking(ImGuiContext* ctx)
{
ImGuiContext& g = *ctx;
ImGuiDockContext* dc = &ctx->DockContext;
@@ -12183,14 +12241,16 @@ void ImGui::DockContextUpdateUndocking(ImGuiContext* ctx)
}
// Docking context update function, called by NewFrame()
-void ImGui::DockContextUpdateDocking(ImGuiContext* ctx)
+void ImGui::DockContextNewFrameUpdateDocking(ImGuiContext* ctx)
{
ImGuiContext& g = *ctx;
ImGuiDockContext* dc = &ctx->DockContext;
if (!(g.IO.ConfigFlags & ImGuiConfigFlags_DockingEnable))
return;
- // Store hovered dock node. We could in theory use DockNodeTreeFindVisibleNodeByPos() on the root host dock node, but using ->DockNode is a good shortcut.
+ // [DEBUG] Store hovered dock node.
+ // We could in theory use DockNodeTreeFindVisibleNodeByPos() on the root host dock node, but using ->DockNode is a good shortcut.
+ // Note this is mostly a debug thing and isn't actually used for docking target, because docking involve more detailed filtering.
g.HoveredDockNode = NULL;
if (ImGuiWindow* hovered_window = g.HoveredWindowUnderMovingWindow)
{
@@ -13274,8 +13334,8 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node)
if (g.NavWindow && g.NavWindow->RootWindowDockStop->DockNode && g.NavWindow->RootWindowDockStop->ParentWindow == host_window)
node->LastFocusedNodeId = g.NavWindow->RootWindowDockStop->DockNode->ID;
- // We need to draw a background at the root level if requested by ImGuiDockNodeFlags_PassthruCentralNode, but we will only know the correct pos/size after
- // processing the resizing splitters. So we are using the DrawList channel splitting facility to submit drawing primitives out of order!
+ // We need to draw a background at the root level if requested by ImGuiDockNodeFlags_PassthruCentralNode, but we will only know the correct pos/size
+ // _after_ processing the resizing splitters. So we are using the DrawList channel splitting facility to submit drawing primitives out of order!
const bool render_dockspace_bg = node->IsRootNode() && host_window && (node_flags & ImGuiDockNodeFlags_PassthruCentralNode) != 0;
if (render_dockspace_bg)
{
@@ -13514,6 +13574,17 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
ImVec2 window_menu_button_pos;
DockNodeCalcTabBarLayout(node, &title_bar_rect, &tab_bar_rect, &window_menu_button_pos);
+ // Submit new tabs and apply NavWindow focus back to the tab bar. They will be added as Unsorted and sorted below based on relative DockOrder value.
+ const int tabs_count_old = tab_bar->Tabs.Size;
+ for (int window_n = 0; window_n < node->Windows.Size; window_n++)
+ {
+ ImGuiWindow* window = node->Windows[window_n];
+ if (g.NavWindow && g.NavWindow->RootWindowDockStop == window)
+ tab_bar->SelectedTabId = window->ID;
+ if (TabBarFindTabByID(tab_bar, window->ID) == NULL)
+ TabBarAddTab(tab_bar, ImGuiTabItemFlags_Unsorted, window);
+ }
+
// Title bar
if (is_focused)
node->LastFrameFocused = g.FrameCount;
@@ -13529,17 +13600,6 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
focus_tab_id = tab_bar->SelectedTabId;
}
- // Submit new tabs and apply NavWindow focus back to the tab bar. They will be added as Unsorted and sorted below based on relative DockOrder value.
- const int tabs_count_old = tab_bar->Tabs.Size;
- for (int window_n = 0; window_n < node->Windows.Size; window_n++)
- {
- ImGuiWindow* window = node->Windows[window_n];
- if (g.NavWindow && g.NavWindow->RootWindowDockStop == window)
- tab_bar->SelectedTabId = window->ID;
- if (TabBarFindTabByID(tab_bar, window->ID) == NULL)
- TabBarAddTab(tab_bar, ImGuiTabItemFlags_Unsorted, window);
- }
-
// If multiple tabs are appearing on the same frame, sort them based on their persistent DockOrder value
int tabs_unsorted_start = tab_bar->Tabs.Size;
for (int tab_n = tab_bar->Tabs.Size - 1; tab_n >= 0 && (tab_bar->Tabs[tab_n].Flags & ImGuiTabItemFlags_Unsorted); tab_n--)
@@ -13571,6 +13631,11 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
BeginTabBarEx(tab_bar, tab_bar_rect, tab_bar_flags, node);
//host_window->DrawList->AddRect(tab_bar_rect.Min, tab_bar_rect.Max, IM_COL32(255,0,255,255));
+ // Backup style colors
+ ImVec4 backup_style_cols[ImGuiWindowDockStyleCol_COUNT];
+ for (int color_n = 0; color_n < ImGuiWindowDockStyleCol_COUNT; color_n++)
+ backup_style_cols[color_n] = g.Style.Colors[GWindowDockStyleColors[color_n]];
+
// Submit actual tabs
node->VisibleWindow = NULL;
for (int window_n = 0; window_n < node->Windows.Size; window_n++)
@@ -13581,11 +13646,16 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
if (window->LastFrameActive + 1 >= g.FrameCount || !node_was_active)
{
ImGuiTabItemFlags tab_item_flags = 0;
+ tab_item_flags |= window->WindowClass.TabItemFlagsOverrideSet;
if (window->Flags & ImGuiWindowFlags_UnsavedDocument)
tab_item_flags |= ImGuiTabItemFlags_UnsavedDocument;
if (tab_bar->Flags & ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)
tab_item_flags |= ImGuiTabItemFlags_NoCloseWithMiddleMouseButton;
+ // Apply stored style overrides for the window
+ for (int color_n = 0; color_n < ImGuiWindowDockStyleCol_COUNT; color_n++)
+ g.Style.Colors[GWindowDockStyleColors[color_n]] = ColorConvertU32ToFloat4(window->DockStyle.Colors[color_n]);
+
bool tab_open = true;
TabItemEx(tab_bar, window->Name, window->HasCloseButton ? &tab_open : NULL, tab_item_flags, window);
if (!tab_open)
@@ -13603,6 +13673,10 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
}
}
+ // Restore style colors
+ for (int color_n = 0; color_n < ImGuiWindowDockStyleCol_COUNT; color_n++)
+ g.Style.Colors[GWindowDockStyleColors[color_n]] = backup_style_cols[color_n];
+
// Notify root of visible window (used to display title in OS task bar)
if (node->VisibleWindow)
if (is_focused || root_node->VisibleWindow == NULL)
@@ -13951,7 +14025,6 @@ static void ImGui::DockNodePreviewDockRender(ImGuiWindow* host_window, ImGuiDock
overlay_draw_lists[overlay_draw_lists_count++] = GetForegroundDrawList(root_payload->Viewport);
// Draw main preview rectangle
- const ImU32 overlay_col_tabs = GetColorU32(ImGuiCol_TabActive);
const ImU32 overlay_col_main = GetColorU32(ImGuiCol_DockingPreview, is_transparent_payload ? 0.60f : 0.40f);
const ImU32 overlay_col_drop = GetColorU32(ImGuiCol_DockingPreview, is_transparent_payload ? 0.90f : 0.70f);
const ImU32 overlay_col_drop_hovered = GetColorU32(ImGuiCol_DockingPreview, is_transparent_payload ? 1.20f : 1.00f);
@@ -14006,6 +14079,9 @@ static void ImGui::DockNodePreviewDockRender(ImGuiWindow* host_window, ImGuiDock
ImVec2 tab_size = TabItemCalcSize(payload_window->Name, payload_window->HasCloseButton);
ImRect tab_bb(tab_pos.x, tab_pos.y, tab_pos.x + tab_size.x, tab_pos.y + tab_size.y);
tab_pos.x += tab_size.x + g.Style.ItemInnerSpacing.x;
+ const ImU32 overlay_col_text = GetColorU32(payload_window->DockStyle.Colors[ImGuiWindowDockStyleCol_Text]);
+ const ImU32 overlay_col_tabs = GetColorU32(payload_window->DockStyle.Colors[ImGuiWindowDockStyleCol_TabActive]);
+ PushStyleColor(ImGuiCol_Text, overlay_col_text);
for (int overlay_n = 0; overlay_n < overlay_draw_lists_count; overlay_n++)
{
ImGuiTabItemFlags tab_flags = ImGuiTabItemFlags_Preview | ((payload_window->Flags & ImGuiWindowFlags_UnsavedDocument) ? ImGuiTabItemFlags_UnsavedDocument : 0);
@@ -14016,6 +14092,7 @@ static void ImGui::DockNodePreviewDockRender(ImGuiWindow* host_window, ImGuiDock
if (!tab_bar_rect.Contains(tab_bb))
overlay_draw_lists[overlay_n]->PopClipRect();
}
+ PopStyleColor();
}
}
@@ -15094,7 +15171,7 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
// Note how we are testing for LastFrameAlive and NOT LastFrameActive. A DockSpace node can be maintained alive while being inactive with ImGuiDockNodeFlags_KeepAliveOnly.
if (node->LastFrameAlive < g.FrameCount)
{
- // If the window has been orphaned, transition the docknode to an implicit node processed in DockContextUpdateDocking()
+ // If the window has been orphaned, transition the docknode to an implicit node processed in DockContextNewFrameUpdateDocking()
ImGuiDockNode* root_node = DockNodeGetRootNode(node);
if (root_node->LastFrameAlive < g.FrameCount)
{
@@ -15108,6 +15185,10 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
return;
}
+ // Store style overrides
+ for (int color_n = 0; color_n < ImGuiWindowDockStyleCol_COUNT; color_n++)
+ window->DockStyle.Colors[color_n] = ColorConvertFloat4ToU32(g.Style.Colors[GWindowDockStyleColors[color_n]]);
+
// Fast path return. It is common for windows to hold on a persistent DockId but be the only visible window,
// and never create neither a host window neither a tab bar.
// FIXME-DOCK: replace ->HostWindow NULL compare with something more explicit (~was initially intended as a first frame test)
@@ -15179,6 +15260,10 @@ void ImGui::BeginDockableDragDropSource(ImGuiWindow* window)
{
SetDragDropPayload(IMGUI_PAYLOAD_TYPE_WINDOW, &window, sizeof(window));
EndDragDropSource();
+
+ // Store style overrides
+ for (int color_n = 0; color_n < ImGuiWindowDockStyleCol_COUNT; color_n++)
+ window->DockStyle.Colors[color_n] = ColorConvertFloat4ToU32(g.Style.Colors[GWindowDockStyleColors[color_n]]);
}
}
@@ -15736,10 +15821,10 @@ void ImGui::ShowMetricsWindow(bool* p_open)
Separator();
// Debugging enums
- enum { WRT_OuterRect, WRT_OuterRectClipped, WRT_InnerRect, WRT_InnerClipRect, WRT_WorkRect, WRT_Content, WRT_ContentRegionRect, WRT_Count }; // Windows Rect Type
- const char* wrt_rects_names[WRT_Count] = { "OuterRect", "OuterRectClipped", "InnerRect", "InnerClipRect", "WorkRect", "Content", "ContentRegionRect" };
- enum { TRT_OuterRect, TRT_InnerRect, TRT_WorkRect, TRT_HostClipRect, TRT_InnerClipRect, TRT_BackgroundClipRect, TRT_ColumnsRect, TRT_ColumnsClipRect, TRT_ColumnsContentHeadersUsed, TRT_ColumnsContentHeadersIdeal, TRT_ColumnsContentFrozen, TRT_ColumnsContentUnfrozen, TRT_Count }; // Tables Rect Type
- const char* trt_rects_names[TRT_Count] = { "OuterRect", "InnerRect", "WorkRect", "HostClipRect", "InnerClipRect", "BackgroundClipRect", "ColumnsRect", "ColumnsClipRect", "ColumnsContentHeadersUsed", "ColumnsContentHeadersIdeal", "ColumnsContentFrozen", "ColumnsContentUnfrozen" };
+ enum { WRT_OuterRect, WRT_OuterRectClipped, WRT_InnerRect, WRT_InnerClipRect, WRT_WorkRect, WRT_Content, WRT_ContentIdeal, WRT_ContentRegionRect, WRT_Count }; // Windows Rect Type
+ const char* wrt_rects_names[WRT_Count] = { "OuterRect", "OuterRectClipped", "InnerRect", "InnerClipRect", "WorkRect", "Content", "ContentIdeal", "ContentRegionRect" };
+ enum { TRT_OuterRect, TRT_InnerRect, TRT_WorkRect, TRT_HostClipRect, TRT_InnerClipRect, TRT_BackgroundClipRect, TRT_ColumnsRect, TRT_ColumnsWorkRect, TRT_ColumnsClipRect, TRT_ColumnsContentHeadersUsed, TRT_ColumnsContentHeadersIdeal, TRT_ColumnsContentFrozen, TRT_ColumnsContentUnfrozen, TRT_Count }; // Tables Rect Type
+ const char* trt_rects_names[TRT_Count] = { "OuterRect", "InnerRect", "WorkRect", "HostClipRect", "InnerClipRect", "BackgroundClipRect", "ColumnsRect", "ColumnsWorkRect", "ColumnsClipRect", "ColumnsContentHeadersUsed", "ColumnsContentHeadersIdeal", "ColumnsContentFrozen", "ColumnsContentUnfrozen" };
if (cfg->ShowWindowsRectsType < 0)
cfg->ShowWindowsRectsType = WRT_WorkRect;
if (cfg->ShowTablesRectsType < 0)
@@ -15756,6 +15841,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
else if (rect_type == TRT_InnerClipRect) { return table->InnerClipRect; }
else if (rect_type == TRT_BackgroundClipRect) { return table->BgClipRect; }
else if (rect_type == TRT_ColumnsRect) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->MinX, table->InnerClipRect.Min.y, c->MaxX, table->InnerClipRect.Min.y + table->LastOuterHeight); }
+ else if (rect_type == TRT_ColumnsWorkRect) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->WorkRect.Min.y, c->WorkMaxX, table->WorkRect.Max.y); }
else if (rect_type == TRT_ColumnsClipRect) { ImGuiTableColumn* c = &table->Columns[n]; return c->ClipRect; }
else if (rect_type == TRT_ColumnsContentHeadersUsed){ ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y, c->ContentMaxXHeadersUsed, table->InnerClipRect.Min.y + table->LastFirstRowHeight); } // Note: y1/y2 not always accurate
else if (rect_type == TRT_ColumnsContentHeadersIdeal){ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y, c->ContentMaxXHeadersIdeal, table->InnerClipRect.Min.y + table->LastFirstRowHeight); }
@@ -15772,7 +15858,8 @@ void ImGui::ShowMetricsWindow(bool* p_open)
else if (rect_type == WRT_InnerRect) { return window->InnerRect; }
else if (rect_type == WRT_InnerClipRect) { return window->InnerClipRect; }
else if (rect_type == WRT_WorkRect) { return window->WorkRect; }
- else if (rect_type == WRT_Content) { ImVec2 min = window->InnerRect.Min - window->Scroll + window->WindowPadding; return ImRect(min, min + window->ContentSize); }
+ else if (rect_type == WRT_Content) { ImVec2 min = window->InnerRect.Min - window->Scroll + window->WindowPadding; return ImRect(min, min + window->ContentSize); }
+ else if (rect_type == WRT_ContentIdeal) { ImVec2 min = window->InnerRect.Min - window->Scroll + window->WindowPadding; return ImRect(min, min + window->ContentSizeIdeal); }
else if (rect_type == WRT_ContentRegionRect) { return window->ContentRegionRect; }
IM_ASSERT(0);
return ImRect();
@@ -16412,7 +16499,7 @@ void ImGui::DebugNodeWindow(ImGuiWindow* window, const char* label)
ImGuiWindowFlags flags = window->Flags;
DebugNodeDrawList(window, window->Viewport, window->DrawList, "DrawList");
- BulletText("Pos: (%.1f,%.1f), Size: (%.1f,%.1f), ContentSize (%.1f,%.1f)", window->Pos.x, window->Pos.y, window->Size.x, window->Size.y, window->ContentSize.x, window->ContentSize.y);
+ BulletText("Pos: (%.1f,%.1f), Size: (%.1f,%.1f), ContentSize (%.1f,%.1f) Ideal (%.1f,%.1f)", window->Pos.x, window->Pos.y, window->Size.x, window->Size.y, window->ContentSize.x, window->ContentSize.y, window->ContentSizeIdeal.x, window->ContentSizeIdeal.y);
BulletText("Flags: 0x%08X (%s%s%s%s%s%s%s%s%s..)", flags,
(flags & ImGuiWindowFlags_ChildWindow) ? "Child " : "", (flags & ImGuiWindowFlags_Tooltip) ? "Tooltip " : "", (flags & ImGuiWindowFlags_Popup) ? "Popup " : "",
(flags & ImGuiWindowFlags_Modal) ? "Modal " : "", (flags & ImGuiWindowFlags_ChildMenu) ? "ChildMenu " : "", (flags & ImGuiWindowFlags_NoSavedSettings) ? "NoSavedSettings " : "",
diff --git a/imgui/imgui.h b/imgui/imgui.h
index 26ba8ecc..29b0d5a2 100644
--- a/imgui/imgui.h
+++ b/imgui/imgui.h
@@ -1,4 +1,4 @@
-// dear imgui, v1.80 WIP
+// dear imgui, v1.80
// (headers)
// Help:
@@ -59,8 +59,8 @@ Index of this file:
// Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
-#define IMGUI_VERSION "1.80 WIP"
-#define IMGUI_VERSION_NUM 17909
+#define IMGUI_VERSION "1.80"
+#define IMGUI_VERSION_NUM 18000
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
#define IMGUI_HAS_TABLE
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch
@@ -83,7 +83,7 @@ Index of this file:
#endif
#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR) / sizeof(*(_ARR)))) // Size of a static C-style array. Don't use on pointers!
#define IM_UNUSED(_VAR) ((void)(_VAR)) // Used to silence "unused variable warnings". Often useful as asserts may be stripped out from final builds.
-#if (__cplusplus >= 201100)
+#if (__cplusplus >= 201100) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201100)
#define IM_OFFSETOF(_TYPE,_MEMBER) offsetof(_TYPE, _MEMBER) // Offset of _MEMBER within _TYPE. Standardized as offsetof() in C++11
#else
#define IM_OFFSETOF(_TYPE,_MEMBER) ((size_t)&(((_TYPE*)0)->_MEMBER)) // Offset of _MEMBER within _TYPE. Old style macro.
@@ -580,7 +580,7 @@ namespace ImGui
IMGUI_API void TreePop(); // ~ Unindent()+PopId()
IMGUI_API float GetTreeNodeToLabelSpacing(); // horizontal distance preceding label when using TreeNode*() or Bullet() == (g.FontSize + style.FramePadding.x*2) for a regular unframed TreeNode
IMGUI_API bool CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags = 0); // if returning 'true' the header is open. doesn't indent nor push on ID stack. user doesn't have to call TreePop().
- IMGUI_API bool CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags flags = 0); // when 'p_open' isn't NULL, display an additional small close button on upper right of the header
+ IMGUI_API bool CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFlags flags = 0); // when 'p_visible != NULL': if '*p_visible==true' display an additional small close button on upper right of the header which will set the bool to false when clicked, if '*p_visible==false' don't display the header.
IMGUI_API void SetNextItemOpen(bool is_open, ImGuiCond cond = 0); // set next TreeNode/CollapsingHeader open state.
// Widgets: Selectables
@@ -668,62 +668,62 @@ namespace ImGui
IMGUI_API bool IsPopupOpen(const char* str_id, ImGuiPopupFlags flags = 0); // return true if the popup is open.
// Tables
- // [BETA API] API may evolve!
+ // [BETA API] API may evolve slightly! If you use this, please update to the next version when it comes out!
// - Full-featured replacement for old Columns API.
- // - See Demo->Tables for details.
+ // - See Demo->Tables for demo code.
+ // - See top of imgui_tables.cpp for general commentary.
// - See ImGuiTableFlags_ and ImGuiTableColumnFlags_ enums for a description of available flags.
// The typical call flow is:
- // - 1. Call BeginTable()
- // - 2. Optionally call TableSetupColumn() to submit column name/flags/defaults
- // - 3. Optionally call TableSetupScrollFreeze() to request scroll freezing of columns/rows
- // - 4. Optionally call TableHeadersRow() to submit a header row. Names will be pulled from data provided TableSetupColumn() calls)
- // - 5. Populate contents
+ // - 1. Call BeginTable().
+ // - 2. Optionally call TableSetupColumn() to submit column name/flags/defaults.
+ // - 3. Optionally call TableSetupScrollFreeze() to request scroll freezing of columns/rows.
+ // - 4. Optionally call TableHeadersRow() to submit a header row. Names are pulled from TableSetupColumn() data.
+ // - 5. Populate contents:
// - In most situations you can use TableNextRow() + TableSetColumnIndex(N) to start appending into a column.
// - If you are using tables as a sort of grid, where every columns is holding the same type of contents,
// you may prefer using TableNextColumn() instead of TableNextRow() + TableSetColumnIndex().
// TableNextColumn() will automatically wrap-around into the next row if needed.
// - IMPORTANT: Comparatively to the old Columns() API, we need to call TableNextColumn() for the first column!
- // - Both TableSetColumnIndex() and TableNextColumn() return true when the column is visible or performing
- // width measurements. Otherwise, you may skip submitting the contents of a cell/column, BUT ONLY if you know
- // it is not going to contribute to row height.
- // In many situations, you may skip submitting contents for every columns but one (e.g. the first one).
// - Summary of possible call flow:
- // ----------------------------------------------------------------------------------------------------------
- // TableNextRow() -> TableSetColumnIndex(0) -> Text("Hello 0") -> TableSetColumnIndex(1) -> Text("Hello 1") // OK
- // TableNextRow() -> TableNextColumn() -> Text("Hello 0") -> TableNextColumn() -> Text("Hello 1") // OK
- // TableNextColumn() -> Text("Hello 0") -> TableNextColumn() -> Text("Hello 1") // OK: TableNextColumn() automatically gets to next row!
- // TableNextRow() -> Text("Hello 0") // Not OK! Missing TableSetColumnIndex() or TableNextColumn()! Text will not appear!
- // ----------------------------------------------------------------------------------------------------------
+ // --------------------------------------------------------------------------------------------------------
+ // TableNextRow() -> TableSetColumnIndex(0) -> Text("Hello 0") -> TableSetColumnIndex(1) -> Text("Hello 1") // OK
+ // TableNextRow() -> TableNextColumn() -> Text("Hello 0") -> TableNextColumn() -> Text("Hello 1") // OK
+ // TableNextColumn() -> Text("Hello 0") -> TableNextColumn() -> Text("Hello 1") // OK: TableNextColumn() automatically gets to next row!
+ // TableNextRow() -> Text("Hello 0") // Not OK! Missing TableSetColumnIndex() or TableNextColumn()! Text will not appear!
+ // --------------------------------------------------------------------------------------------------------
// - 5. Call EndTable()
- IMGUI_API bool BeginTable(const char* str_id, int columns_count, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(-FLT_MIN, 0), float inner_width = 0.0f);
+ IMGUI_API bool BeginTable(const char* str_id, int column, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(0.0f, 0.0f), float inner_width = 0.0f);
IMGUI_API void EndTable(); // only call EndTable() if BeginTable() returns true!
IMGUI_API void TableNextRow(ImGuiTableRowFlags row_flags = 0, float min_row_height = 0.0f); // append into the first cell of a new row.
IMGUI_API bool TableNextColumn(); // append into the next column (or first column of next row if currently in last column). Return true when column is visible.
IMGUI_API bool TableSetColumnIndex(int column_n); // append into the specified column. Return true when column is visible.
- IMGUI_API int TableGetColumnIndex(); // return current column index.
- IMGUI_API int TableGetRowIndex(); // return current row index.
// Tables: Headers & Columns declaration
// - Use TableSetupColumn() to specify label, resizing policy, default width/weight, id, various other flags etc.
- // Important: this will not display anything! The name passed to TableSetupColumn() is used by TableHeadersRow() and context-menus.
- // - Use TableHeadersRow() to create a row and automatically submit a TableHeader() for each column.
- // Headers are required to perform: reordering, sorting, and opening the context menu (but context menu can also be available in columns body using ImGuiTableFlags_ContextMenuInBody).
- // - You may manually submit headers using TableNextRow() + TableHeader() calls, but this is only useful in some advanced cases (e.g. adding custom widgets in header row).
- // - Use TableSetupScrollFreeze() to lock columns (from the right) or rows (from the top) so they stay visible when scrolled.
- IMGUI_API void TableSetupColumn(const char* label, ImGuiTableColumnFlags flags = 0, float init_width_or_weight = -1.0f, ImU32 user_id = 0);
+ // - Use TableHeadersRow() to create a header row and automatically submit a TableHeader() for each column.
+ // Headers are required to perform: reordering, sorting, and opening the context menu.
+ // The context menu can also be made available in columns body using ImGuiTableFlags_ContextMenuInBody.
+ // - You may manually submit headers using TableNextRow() + TableHeader() calls, but this is only useful in
+ // some advanced use cases (e.g. adding custom widgets in header row).
+ // - Use TableSetupScrollFreeze() to lock columns/rows so they stay visible when scrolled.
+ IMGUI_API void TableSetupColumn(const char* label, ImGuiTableColumnFlags flags = 0, float init_width_or_weight = 0.0f, ImU32 user_id = 0);
IMGUI_API void TableSetupScrollFreeze(int cols, int rows); // lock columns/rows so they stay visible when scrolled.
IMGUI_API void TableHeadersRow(); // submit all headers cells based on data provided to TableSetupColumn() + submit context menu
IMGUI_API void TableHeader(const char* label); // submit one header cell manually (rarely used)
+ // Tables: Sorting
+ // - Call TableGetSortSpecs() to retrieve latest sort specs for the table. NULL when not sorting.
+ // - When 'SpecsDirty == true' you should sort your data. It will be true when sorting specs have changed
+ // since last call, or the first time. Make sure to set 'SpecsDirty = false' after sorting, else you may
+ // wastefully sort your data every frame!
+ // - Lifetime: don't hold on this pointer over multiple frames or past any subsequent call to BeginTable().
+ IMGUI_API ImGuiTableSortSpecs* TableGetSortSpecs(); // get latest sort specs for the table (NULL if not sorting).
// Tables: Miscellaneous functions
- // - Most functions taking 'int column_n' treat the default value of -1 as the same as passing the current column index
- // - Sorting: call TableGetSortSpecs() to retrieve latest sort specs for the table. Return value will be NULL if no sorting.
- // When 'SpecsDirty == true' you should sort your data. It will be true when sorting specs have changed since last call, or the first time.
- // Make sure to set 'SpecsDirty = false' after sorting, else you may wastefully sort your data every frame!
- // Lifetime: don't hold on this pointer over multiple frames or past any subsequent call to BeginTable().
+ // - Functions args 'int column_n' treat the default value of -1 as the same as passing the current column index.
IMGUI_API int TableGetColumnCount(); // return number of columns (value passed to BeginTable)
+ IMGUI_API int TableGetColumnIndex(); // return current column index.
+ IMGUI_API int TableGetRowIndex(); // return current row index.
IMGUI_API const char* TableGetColumnName(int column_n = -1); // return "" if column didn't have a name declared by TableSetupColumn(). Pass -1 to use current column.
- IMGUI_API ImGuiTableColumnFlags TableGetColumnFlags(int column_n = -1); // return column flags so you can query their Enabled/Visible/Sorted/Hovered status flags.
- IMGUI_API ImGuiTableSortSpecs* TableGetSortSpecs(); // get latest sort specs for the table (NULL if not sorting).
- IMGUI_API void TableSetBgColor(ImGuiTableBgTarget bg_target, ImU32 color, int column_n = -1); // change the color of a cell, row, or column. See ImGuiTableBgTarget_ flags for details.
+ IMGUI_API ImGuiTableColumnFlags TableGetColumnFlags(int column_n = -1); // return column flags so you can query their Enabled/Visible/Sorted/Hovered status flags. Pass -1 to use current column.
+ IMGUI_API void TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n = -1); // change the color of a cell, row, or column. See ImGuiTableBgTarget_ flags for details.
// Legacy Columns API (2020: prefer using Tables!)
// - You can also use SameLine(pos_x) to mimic simplified columns.
@@ -1079,6 +1079,7 @@ enum ImGuiTabItemFlags_
};
// Flags for ImGui::BeginTable()
+// [BETA API] API may evolve slightly! If you use this, please update to the next version when it comes out!
// - Important! Sizing policies have complex and subtle side effects, more so than you would expect.
// Read comments/demos carefully + experiment with live demos to get acquainted with them.
// - The DEFAULT sizing policies are:
@@ -1093,7 +1094,7 @@ enum ImGuiTabItemFlags_
// The typical use of mixing sizing policies is: any number of LEADING Fixed columns, followed by one or two TRAILING Stretch columns.
// (this is because the visible order of columns have subtle but necessary effects on how they react to manual resizing).
// - When ScrollX is on:
-// - Table defaults to ImGuiTableFlags_SizingFixedFit -> all Columns defaults to ImGuiTableColumnFlags_WidthFixed or ImGuiTableColumnFlags_WidthAuto.
+// - Table defaults to ImGuiTableFlags_SizingFixedFit -> all Columns defaults to ImGuiTableColumnFlags_WidthFixed
// - Columns sizing policy allowed: Fixed/Auto mostly.
// - Fixed Columns can be enlarged as needed. Table will show an horizontal scrollbar if needed.
// - When using auto-resizing (non-resizable) fixed columns, querying the content width to use item right-alignment e.g. SetNextItemWidth(-FLT_MIN) doesn't make sense, would create a feedback loop.
@@ -1103,55 +1104,56 @@ enum ImGuiTabItemFlags_
enum ImGuiTableFlags_
{
// Features
- ImGuiTableFlags_None = 0,
- ImGuiTableFlags_Resizable = 1 << 0, // Enable resizing columns.
- ImGuiTableFlags_Reorderable = 1 << 1, // Enable reordering columns in header row (need calling TableSetupColumn() + TableHeadersRow() to display headers)
- ImGuiTableFlags_Hideable = 1 << 2, // Enable hiding/disabling columns in context menu.
- ImGuiTableFlags_Sortable = 1 << 3, // Enable sorting. Call TableGetSortSpecs() to obtain sort specs. Also see ImGuiTableFlags_SortMulti and ImGuiTableFlags_SortTristate.
- ImGuiTableFlags_NoSavedSettings = 1 << 4, // Disable persisting columns order, width and sort settings in the .ini file.
- ImGuiTableFlags_ContextMenuInBody = 1 << 5, // Right-click on columns body/contents will display table context menu. By default it is available in TableHeadersRow().
+ ImGuiTableFlags_None = 0,
+ ImGuiTableFlags_Resizable = 1 << 0, // Enable resizing columns.
+ ImGuiTableFlags_Reorderable = 1 << 1, // Enable reordering columns in header row (need calling TableSetupColumn() + TableHeadersRow() to display headers)
+ ImGuiTableFlags_Hideable = 1 << 2, // Enable hiding/disabling columns in context menu.
+ ImGuiTableFlags_Sortable = 1 << 3, // Enable sorting. Call TableGetSortSpecs() to obtain sort specs. Also see ImGuiTableFlags_SortMulti and ImGuiTableFlags_SortTristate.
+ ImGuiTableFlags_NoSavedSettings = 1 << 4, // Disable persisting columns order, width and sort settings in the .ini file.
+ ImGuiTableFlags_ContextMenuInBody = 1 << 5, // Right-click on columns body/contents will display table context menu. By default it is available in TableHeadersRow().
// Decorations
- ImGuiTableFlags_RowBg = 1 << 6, // Set each RowBg color with ImGuiCol_TableRowBg or ImGuiCol_TableRowBgAlt (equivalent of calling TableSetBgColor with ImGuiTableBgFlags_RowBg0 on each row manually)
- ImGuiTableFlags_BordersInnerH = 1 << 7, // Draw horizontal borders between rows.
- ImGuiTableFlags_BordersOuterH = 1 << 8, // Draw horizontal borders at the top and bottom.
- ImGuiTableFlags_BordersInnerV = 1 << 9, // Draw vertical borders between columns.
- ImGuiTableFlags_BordersOuterV = 1 << 10, // Draw vertical borders on the left and right sides.
- ImGuiTableFlags_BordersH = ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_BordersOuterH, // Draw horizontal borders.
- ImGuiTableFlags_BordersV = ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersOuterV, // Draw vertical borders.
- ImGuiTableFlags_BordersInner = ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersInnerH, // Draw inner borders.
- ImGuiTableFlags_BordersOuter = ImGuiTableFlags_BordersOuterV | ImGuiTableFlags_BordersOuterH, // Draw outer borders.
- ImGuiTableFlags_Borders = ImGuiTableFlags_BordersInner | ImGuiTableFlags_BordersOuter, // Draw all borders.
- ImGuiTableFlags_NoBordersInBody = 1 << 11, // [ALPHA] Disable vertical borders in columns Body (borders will always appears in Headers). -> May move to style
- ImGuiTableFlags_NoBordersInBodyUntilResize = 1 << 12, // [ALPHA] Disable vertical borders in columns Body until hovered for resize (borders will always appears in Headers). -> May move to style
+ ImGuiTableFlags_RowBg = 1 << 6, // Set each RowBg color with ImGuiCol_TableRowBg or ImGuiCol_TableRowBgAlt (equivalent of calling TableSetBgColor with ImGuiTableBgFlags_RowBg0 on each row manually)
+ ImGuiTableFlags_BordersInnerH = 1 << 7, // Draw horizontal borders between rows.
+ ImGuiTableFlags_BordersOuterH = 1 << 8, // Draw horizontal borders at the top and bottom.
+ ImGuiTableFlags_BordersInnerV = 1 << 9, // Draw vertical borders between columns.
+ ImGuiTableFlags_BordersOuterV = 1 << 10, // Draw vertical borders on the left and right sides.
+ ImGuiTableFlags_BordersH = ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_BordersOuterH, // Draw horizontal borders.
+ ImGuiTableFlags_BordersV = ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersOuterV, // Draw vertical borders.
+ ImGuiTableFlags_BordersInner = ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersInnerH, // Draw inner borders.
+ ImGuiTableFlags_BordersOuter = ImGuiTableFlags_BordersOuterV | ImGuiTableFlags_BordersOuterH, // Draw outer borders.
+ ImGuiTableFlags_Borders = ImGuiTableFlags_BordersInner | ImGuiTableFlags_BordersOuter, // Draw all borders.
+ ImGuiTableFlags_NoBordersInBody = 1 << 11, // [ALPHA] Disable vertical borders in columns Body (borders will always appears in Headers). -> May move to style
+ ImGuiTableFlags_NoBordersInBodyUntilResize = 1 << 12, // [ALPHA] Disable vertical borders in columns Body until hovered for resize (borders will always appears in Headers). -> May move to style
// Sizing Policy (read above for defaults)
- ImGuiTableFlags_SizingFixedFit = 1 << 13, // Columns default to _WidthFixed or _WidthAuto (if resizable or not resizable), matching contents width.
- ImGuiTableFlags_SizingFixedSame = 2 << 13, // Columns default to _WidthFixed or _WidthAuto (if resizable or not resizable), matching the maximum contents width of all columns. Implicitly enable ImGuiTableFlags_NoKeepColumnsVisible.
- ImGuiTableFlags_SizingStretchProp = 3 << 13, // Columns default to _WidthStretch with default weights proportional to each columns contents widths.
- ImGuiTableFlags_SizingStretchSame = 4 << 13, // Columns default to _WidthStretch with default weights all equal, unless overriden by TableSetupColumn().
+ ImGuiTableFlags_SizingFixedFit = 1 << 13, // Columns default to _WidthFixed or _WidthAuto (if resizable or not resizable), matching contents width.
+ ImGuiTableFlags_SizingFixedSame = 2 << 13, // Columns default to _WidthFixed or _WidthAuto (if resizable or not resizable), matching the maximum contents width of all columns. Implicitly enable ImGuiTableFlags_NoKeepColumnsVisible.
+ ImGuiTableFlags_SizingStretchProp = 3 << 13, // Columns default to _WidthStretch with default weights proportional to each columns contents widths.
+ ImGuiTableFlags_SizingStretchSame = 4 << 13, // Columns default to _WidthStretch with default weights all equal, unless overriden by TableSetupColumn().
// Sizing Extra Options
- ImGuiTableFlags_NoHostExtendY = 1 << 16, // Disable extending table past the limit set by outer_size.y. Only meaningful when neither ScrollX nor ScrollY are set (data below the limit will be clipped and not visible)
- ImGuiTableFlags_NoKeepColumnsVisible = 1 << 17, // Disable keeping column always minimally visible when ScrollX is off and table gets too small. Not recommended if columns are resizable.
- ImGuiTableFlags_PreciseWidths = 1 << 18, // Disable distributing remainder width to stretched columns (width allocation on a 100-wide table with 3 columns: Without this flag: 33,33,34. With this flag: 33,33,33). With larger number of columns, resizing will appear to be less smooth.
+ ImGuiTableFlags_NoHostExtendX = 1 << 16, // Make outer width auto-fit to columns, overriding outer_size.x value. Only available when ScrollX/ScrollY are disabled and Stretch columns are not used.
+ ImGuiTableFlags_NoHostExtendY = 1 << 17, // Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit). Only available when ScrollX/ScrollY are disabled. Data below the limit will be clipped and not visible.
+ ImGuiTableFlags_NoKeepColumnsVisible = 1 << 18, // Disable keeping column always minimally visible when ScrollX is off and table gets too small. Not recommended if columns are resizable.
+ ImGuiTableFlags_PreciseWidths = 1 << 19, // Disable distributing remainder width to stretched columns (width allocation on a 100-wide table with 3 columns: Without this flag: 33,33,34. With this flag: 33,33,33). With larger number of columns, resizing will appear to be less smooth.
// Clipping
- ImGuiTableFlags_NoClip = 1 << 19, // Disable clipping rectangle for every individual columns (reduce draw command count, items will be able to overflow into other columns). Generally incompatible with TableSetupScrollFreeze().
+ ImGuiTableFlags_NoClip = 1 << 20, // Disable clipping rectangle for every individual columns (reduce draw command count, items will be able to overflow into other columns). Generally incompatible with TableSetupScrollFreeze().
// Padding
- ImGuiTableFlags_PadOuterX = 1 << 20, // Default if BordersOuterV is on. Enable outer-most padding.
- ImGuiTableFlags_NoPadOuterX = 1 << 21, // Default if BordersOuterV is off. Disable outer-most padding.
- ImGuiTableFlags_NoPadInnerX = 1 << 22, // Disable inner padding between columns (double inner padding if BordersOuterV is on, single inner padding if BordersOuterV is off).
+ ImGuiTableFlags_PadOuterX = 1 << 21, // Default if BordersOuterV is on. Enable outer-most padding. Generally desirable if you have headers.
+ ImGuiTableFlags_NoPadOuterX = 1 << 22, // Default if BordersOuterV is off. Disable outer-most padding.
+ ImGuiTableFlags_NoPadInnerX = 1 << 23, // Disable inner padding between columns (double inner padding if BordersOuterV is on, single inner padding if BordersOuterV is off).
// Scrolling
- ImGuiTableFlags_ScrollX = 1 << 23, // Enable horizontal scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size. Changes default sizing policy. Because this create a child window, ScrollY is currently generally recommended when using ScrollX.
- ImGuiTableFlags_ScrollY = 1 << 24, // Enable vertical scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size.
+ ImGuiTableFlags_ScrollX = 1 << 24, // Enable horizontal scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size. Changes default sizing policy. Because this create a child window, ScrollY is currently generally recommended when using ScrollX.
+ ImGuiTableFlags_ScrollY = 1 << 25, // Enable vertical scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size.
// Sorting
- ImGuiTableFlags_SortMulti = 1 << 25, // Hold shift when clicking headers to sort on multiple column. TableGetSortSpecs() may return specs where (SpecsCount > 1).
- ImGuiTableFlags_SortTristate = 1 << 26, // Allow no sorting, disable default sorting. TableGetSortSpecs() may return specs where (SpecsCount == 0).
+ ImGuiTableFlags_SortMulti = 1 << 26, // Hold shift when clicking headers to sort on multiple column. TableGetSortSpecs() may return specs where (SpecsCount > 1).
+ ImGuiTableFlags_SortTristate = 1 << 27, // Allow no sorting, disable default sorting. TableGetSortSpecs() may return specs where (SpecsCount == 0).
// [Internal] Combinations and masks
- ImGuiTableFlags_SizingMask_ = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_SizingFixedSame | ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_SizingStretchSame
+ ImGuiTableFlags_SizingMask_ = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_SizingFixedSame | ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_SizingStretchSame
// Obsolete names (will be removed soon)
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
- , ImGuiTableFlags_ColumnsWidthFixed = ImGuiTableFlags_SizingFixedFit, ImGuiTableFlags_ColumnsWidthStretch = ImGuiTableFlags_SizingStretchSame // WIP Tables 2020/12
- , ImGuiTableFlags_SizingPolicyFixed = ImGuiTableFlags_SizingFixedFit, ImGuiTableFlags_SizingPolicyStretch = ImGuiTableFlags_SizingStretchSame // WIP Tables 2021/01
+ //, ImGuiTableFlags_ColumnsWidthFixed = ImGuiTableFlags_SizingFixedFit, ImGuiTableFlags_ColumnsWidthStretch = ImGuiTableFlags_SizingStretchSame // WIP Tables 2020/12
+ //, ImGuiTableFlags_SizingPolicyFixed = ImGuiTableFlags_SizingFixedFit, ImGuiTableFlags_SizingPolicyStretch = ImGuiTableFlags_SizingStretchSame // WIP Tables 2021/01
#endif
};
@@ -1159,36 +1161,40 @@ enum ImGuiTableFlags_
enum ImGuiTableColumnFlags_
{
// Input configuration flags
- ImGuiTableColumnFlags_None = 0,
- ImGuiTableColumnFlags_DefaultHide = 1 << 0, // Default as a hidden/disabled column.
- ImGuiTableColumnFlags_DefaultSort = 1 << 1, // Default as a sorting column.
- ImGuiTableColumnFlags_WidthStretch = 1 << 2, // Column will stretch. Preferable with horizontal scrolling disabled (default if table sizing policy is _SizingStretchSame or _SizingStretchProp).
- ImGuiTableColumnFlags_WidthFixed = 1 << 3, // Column will not stretch. Preferable with horizontal scrolling enabled (default if table sizing policy is _SizingFixedFit and table is resizable).
- ImGuiTableColumnFlags_WidthAuto = 1 << 4, // Column will not stretch and keep resizing based on submitted contents (default if table sizing policy is _SizingFixedFit and table is not resizable, or policy is _SizingFixedSame). Generally compatible with using right-most fitting widgets (e.g. SetNextItemWidth(-FLT_MIN))
- ImGuiTableColumnFlags_NoResize = 1 << 5, // Disable manual resizing.
- ImGuiTableColumnFlags_NoReorder = 1 << 6, // Disable manual reordering this column, this will also prevent other columns from crossing over this column.
- ImGuiTableColumnFlags_NoHide = 1 << 7, // Disable ability to hide/disable this column.
- ImGuiTableColumnFlags_NoClip = 1 << 8, // Disable clipping for this column (all NoClip columns will render in a same draw command).
- ImGuiTableColumnFlags_NoSort = 1 << 9, // Disable ability to sort on this field (even if ImGuiTableFlags_Sortable is set on the table).
- ImGuiTableColumnFlags_NoSortAscending = 1 << 10, // Disable ability to sort in the ascending direction.
- ImGuiTableColumnFlags_NoSortDescending = 1 << 11, // Disable ability to sort in the descending direction.
- ImGuiTableColumnFlags_NoHeaderWidth = 1 << 12, // Disable header text width contribution to automatic column width.
- ImGuiTableColumnFlags_PreferSortAscending = 1 << 13, // Make the initial sort direction Ascending when first sorting on this column (default).
- ImGuiTableColumnFlags_PreferSortDescending = 1 << 14, // Make the initial sort direction Descending when first sorting on this column.
- ImGuiTableColumnFlags_IndentEnable = 1 << 15, // Use current Indent value when entering cell (default for column 0).
- ImGuiTableColumnFlags_IndentDisable = 1 << 16, // Ignore current Indent value when entering cell (default for columns > 0). Indentation changes _within_ the cell will still be honored.
+ ImGuiTableColumnFlags_None = 0,
+ ImGuiTableColumnFlags_DefaultHide = 1 << 0, // Default as a hidden/disabled column.
+ ImGuiTableColumnFlags_DefaultSort = 1 << 1, // Default as a sorting column.
+ ImGuiTableColumnFlags_WidthStretch = 1 << 2, // Column will stretch. Preferable with horizontal scrolling disabled (default if table sizing policy is _SizingStretchSame or _SizingStretchProp).
+ ImGuiTableColumnFlags_WidthFixed = 1 << 3, // Column will not stretch. Preferable with horizontal scrolling enabled (default if table sizing policy is _SizingFixedFit and table is resizable).
+ ImGuiTableColumnFlags_NoResize = 1 << 4, // Disable manual resizing.
+ ImGuiTableColumnFlags_NoReorder = 1 << 5, // Disable manual reordering this column, this will also prevent other columns from crossing over this column.
+ ImGuiTableColumnFlags_NoHide = 1 << 6, // Disable ability to hide/disable this column.
+ ImGuiTableColumnFlags_NoClip = 1 << 7, // Disable clipping for this column (all NoClip columns will render in a same draw command).
+ ImGuiTableColumnFlags_NoSort = 1 << 8, // Disable ability to sort on this field (even if ImGuiTableFlags_Sortable is set on the table).
+ ImGuiTableColumnFlags_NoSortAscending = 1 << 9, // Disable ability to sort in the ascending direction.
+ ImGuiTableColumnFlags_NoSortDescending = 1 << 10, // Disable ability to sort in the descending direction.
+ ImGuiTableColumnFlags_NoHeaderWidth = 1 << 11, // Disable header text width contribution to automatic column width.
+ ImGuiTableColumnFlags_PreferSortAscending = 1 << 12, // Make the initial sort direction Ascending when first sorting on this column (default).
+ ImGuiTableColumnFlags_PreferSortDescending = 1 << 13, // Make the initial sort direction Descending when first sorting on this column.
+ ImGuiTableColumnFlags_IndentEnable = 1 << 14, // Use current Indent value when entering cell (default for column 0).
+ ImGuiTableColumnFlags_IndentDisable = 1 << 15, // Ignore current Indent value when entering cell (default for columns > 0). Indentation changes _within_ the cell will still be honored.
// Output status flags, read-only via TableGetColumnFlags()
- ImGuiTableColumnFlags_IsEnabled = 1 << 20, // Status: is enabled == not hidden by user/api (referred to as "Hide" in _DefaultHide and _NoHide) flags.
- ImGuiTableColumnFlags_IsVisible = 1 << 21, // Status: is visible == is enabled AND not clipped by scrolling.
- ImGuiTableColumnFlags_IsSorted = 1 << 22, // Status: is currently part of the sort specs
- ImGuiTableColumnFlags_IsHovered = 1 << 23, // Status: is hovered by mouse
+ ImGuiTableColumnFlags_IsEnabled = 1 << 20, // Status: is enabled == not hidden by user/api (referred to as "Hide" in _DefaultHide and _NoHide) flags.
+ ImGuiTableColumnFlags_IsVisible = 1 << 21, // Status: is visible == is enabled AND not clipped by scrolling.
+ ImGuiTableColumnFlags_IsSorted = 1 << 22, // Status: is currently part of the sort specs
+ ImGuiTableColumnFlags_IsHovered = 1 << 23, // Status: is hovered by mouse
// [Internal] Combinations and masks
- ImGuiTableColumnFlags_WidthMask_ = ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthAuto,
- ImGuiTableColumnFlags_IndentMask_ = ImGuiTableColumnFlags_IndentEnable | ImGuiTableColumnFlags_IndentDisable,
- ImGuiTableColumnFlags_StatusMask_ = ImGuiTableColumnFlags_IsEnabled | ImGuiTableColumnFlags_IsVisible | ImGuiTableColumnFlags_IsSorted | ImGuiTableColumnFlags_IsHovered,
- ImGuiTableColumnFlags_NoDirectResize_ = 1 << 30 // [Internal] Disable user resizing this column directly (it may however we resized indirectly from its left edge)
+ ImGuiTableColumnFlags_WidthMask_ = ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_WidthFixed,
+ ImGuiTableColumnFlags_IndentMask_ = ImGuiTableColumnFlags_IndentEnable | ImGuiTableColumnFlags_IndentDisable,
+ ImGuiTableColumnFlags_StatusMask_ = ImGuiTableColumnFlags_IsEnabled | ImGuiTableColumnFlags_IsVisible | ImGuiTableColumnFlags_IsSorted | ImGuiTableColumnFlags_IsHovered,
+ ImGuiTableColumnFlags_NoDirectResize_ = 1 << 30 // [Internal] Disable user resizing this column directly (it may however we resized indirectly from its left edge)
+
+ // Obsolete names (will be removed soon)
+#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
+ //ImGuiTableColumnFlags_WidthAuto = ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoResize, // Column will not stretch and keep resizing based on submitted contents.
+#endif
};
// Flags for ImGui::TableNextRow()
@@ -1834,10 +1840,11 @@ struct ImGuiIO
// Miscellaneous options
bool MouseDrawCursor; // = false // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). Cannot be easily renamed to 'io.ConfigXXX' because this is frequently used by backend implementations.
bool ConfigMacOSXBehaviors; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl.
- bool ConfigInputTextCursorBlink; // = true // Set to false to disable blinking cursor, for users who consider it distracting.
+ bool ConfigInputTextCursorBlink; // = true // Enable blinking cursor (optional as some users consider it to be distracting).
+ bool ConfigDragClickToInputText; // = false // [BETA] Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving). Not desirable on devices without a keyboard.
bool ConfigWindowsResizeFromEdges; // = true // Enable resizing of windows from their edges and from the lower-left corner. This requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback. (This used to be a per-window ImGuiWindowFlags_ResizeFromAnySide flag)
- bool ConfigWindowsMoveFromTitleBarOnly; // = false // [BETA] Set to true to only allow moving windows when clicked+dragged from the title bar. Windows without a title bar are not affected.
- float ConfigMemoryCompactTimer; // = 60.0f // [BETA] Free transient windows/tables memory buffers when unused for given amount of time. Set to -1.0f to disable.
+ bool ConfigWindowsMoveFromTitleBarOnly; // = false // Enable allowing to move windows only when clicking on their title bar. Does not apply to windows without a title bar.
+ float ConfigMemoryCompactTimer; // = 60.0f // Timer (in seconds) to free transient windows/tables memory buffers when unused. Set to -1.0f to disable.
//------------------------------------------------------------------
// Platform Functions
@@ -1993,12 +2000,13 @@ struct ImGuiWindowClass
ImGuiID ParentViewportId; // Hint for the platform backend. If non-zero, the platform backend can create a parent<>child relationship between the platform windows. Not conforming backends are free to e.g. parent every viewport to the main viewport or not.
ImGuiViewportFlags ViewportFlagsOverrideSet; // Viewport flags to set when a window of this class owns a viewport. This allows you to enforce OS decoration or task bar icon, override the defaults on a per-window basis.
ImGuiViewportFlags ViewportFlagsOverrideClear; // Viewport flags to clear when a window of this class owns a viewport. This allows you to enforce OS decoration or task bar icon, override the defaults on a per-window basis.
+ ImGuiTabItemFlags TabItemFlagsOverrideSet; // [EXPERIMENTAL] TabItem flags to set when a window of this class gets submitted into a dock node tab bar. May use with ImGuiTabItemFlags_Leading or ImGuiTabItemFlags_Trailing.
ImGuiDockNodeFlags DockNodeFlagsOverrideSet; // [EXPERIMENTAL] Dock node flags to set when a window of this class is hosted by a dock node (it doesn't have to be selected!)
ImGuiDockNodeFlags DockNodeFlagsOverrideClear; // [EXPERIMENTAL]
bool DockingAlwaysTabBar; // Set to true to enforce single floating windows of this class always having their own docking node (equivalent of setting the global io.ConfigDockingAlwaysTabBar)
bool DockingAllowUnclassed; // Set to true to allow windows of this class to be docked/merged with an unclassed window. // FIXME-DOCK: Move to DockNodeFlags override?
- ImGuiWindowClass() { ClassId = 0; ParentViewportId = 0; ViewportFlagsOverrideSet = ViewportFlagsOverrideClear = 0x00; DockNodeFlagsOverrideSet = DockNodeFlagsOverrideClear = 0x00; DockingAlwaysTabBar = false; DockingAllowUnclassed = true; }
+ ImGuiWindowClass() { memset(this, 0, sizeof(*this)); DockingAllowUnclassed = true; }
};
// Data payload for Drag and Drop operations: AcceptDragDropPayload(), GetDragDropPayload()
diff --git a/imgui/imgui_demo.cpp b/imgui/imgui_demo.cpp
index e9691bc6..1377425f 100644
--- a/imgui/imgui_demo.cpp
+++ b/imgui/imgui_demo.cpp
@@ -1,4 +1,4 @@
-// dear imgui, v1.80 WIP
+// dear imgui, v1.80
// (demo code)
// Help:
@@ -473,7 +473,9 @@ void ImGui::ShowDemoWindow(bool* p_open)
}
ImGui::Checkbox("io.ConfigInputTextCursorBlink", &io.ConfigInputTextCursorBlink);
- ImGui::SameLine(); HelpMarker("Set to false to disable blinking cursor, for users who consider it distracting");
+ ImGui::SameLine(); HelpMarker("Enable blinking cursor (optional as some users consider it to be distracting)");
+ ImGui::Checkbox("io.ConfigDragClickToInputText", &io.ConfigDragClickToInputText);
+ ImGui::SameLine(); HelpMarker("Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving).");
ImGui::Checkbox("io.ConfigWindowsResizeFromEdges", &io.ConfigWindowsResizeFromEdges);
ImGui::SameLine(); HelpMarker("Enable resizing of windows from their edges and from the lower-left corner.\nThis requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback.");
ImGui::Checkbox("io.ConfigWindowsMoveFromTitleBarOnly", &io.ConfigWindowsMoveFromTitleBarOnly);
@@ -1408,9 +1410,149 @@ static void ShowDemoWindowWidgets()
ImGui::TreePop();
}
- // Plot/Graph widgets are currently fairly limited.
- // Consider writing your own plotting widget, or using a third-party one
- // (for third-party Plot widgets, see 'Wiki->Useful Widgets' or https://github.com/ocornut/imgui/labels/plot%2Fgraph)
+ // Tabs
+ if (ImGui::TreeNode("Tabs"))
+ {
+ if (ImGui::TreeNode("Basic"))
+ {
+ ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_None;
+ if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags))
+ {
+ if (ImGui::BeginTabItem("Avocado"))
+ {
+ ImGui::Text("This is the Avocado tab!\nblah blah blah blah blah");
+ ImGui::EndTabItem();
+ }
+ if (ImGui::BeginTabItem("Broccoli"))
+ {
+ ImGui::Text("This is the Broccoli tab!\nblah blah blah blah blah");
+ ImGui::EndTabItem();
+ }
+ if (ImGui::BeginTabItem("Cucumber"))
+ {
+ ImGui::Text("This is the Cucumber tab!\nblah blah blah blah blah");
+ ImGui::EndTabItem();
+ }
+ ImGui::EndTabBar();
+ }
+ ImGui::Separator();
+ ImGui::TreePop();
+ }
+
+ if (ImGui::TreeNode("Advanced & Close Button"))
+ {
+ // Expose a couple of the available flags. In most cases you may just call BeginTabBar() with no flags (0).
+ static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_Reorderable;
+ ImGui::CheckboxFlags("ImGuiTabBarFlags_Reorderable", &tab_bar_flags, ImGuiTabBarFlags_Reorderable);
+ ImGui::CheckboxFlags("ImGuiTabBarFlags_AutoSelectNewTabs", &tab_bar_flags, ImGuiTabBarFlags_AutoSelectNewTabs);
+ ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", &tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton);
+ ImGui::CheckboxFlags("ImGuiTabBarFlags_NoCloseWithMiddleMouseButton", &tab_bar_flags, ImGuiTabBarFlags_NoCloseWithMiddleMouseButton);
+ if ((tab_bar_flags & ImGuiTabBarFlags_FittingPolicyMask_) == 0)
+ tab_bar_flags |= ImGuiTabBarFlags_FittingPolicyDefault_;
+ if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown))
+ tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyResizeDown);
+ if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll))
+ tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyScroll);
+
+ // Tab Bar
+ const char* names[4] = { "Artichoke", "Beetroot", "Celery", "Daikon" };
+ static bool opened[4] = { true, true, true, true }; // Persistent user state
+ for (int n = 0; n < IM_ARRAYSIZE(opened); n++)
+ {
+ if (n > 0) { ImGui::SameLine(); }
+ ImGui::Checkbox(names[n], &opened[n]);
+ }
+
+ // Passing a bool* to BeginTabItem() is similar to passing one to Begin():
+ // the underlying bool will be set to false when the tab is closed.
+ if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags))
+ {
+ for (int n = 0; n < IM_ARRAYSIZE(opened); n++)
+ if (opened[n] && ImGui::BeginTabItem(names[n], &opened[n], ImGuiTabItemFlags_None))
+ {
+ ImGui::Text("This is the %s tab!", names[n]);
+ if (n & 1)
+ ImGui::Text("I am an odd tab.");
+ ImGui::EndTabItem();
+ }
+ ImGui::EndTabBar();
+ }
+ ImGui::Separator();
+ ImGui::TreePop();
+ }
+
+ if (ImGui::TreeNode("TabItemButton & Leading/Trailing flags"))
+ {
+ static ImVector<int> active_tabs;
+ static int next_tab_id = 0;
+ if (next_tab_id == 0) // Initialize with some default tabs
+ for (int i = 0; i < 3; i++)
+ active_tabs.push_back(next_tab_id++);
+
+ // TabItemButton() and Leading/Trailing flags are distinct features which we will demo together.
+ // (It is possible to submit regular tabs with Leading/Trailing flags, or TabItemButton tabs without Leading/Trailing flags...
+ // but they tend to make more sense together)
+ 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);
+
+ // Expose some other flags which are useful to showcase how they interact with Leading/Trailing tabs
+ static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_AutoSelectNewTabs | ImGuiTabBarFlags_Reorderable | ImGuiTabBarFlags_FittingPolicyResizeDown;
+ ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", &tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton);
+ if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown))
+ tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyResizeDown);
+ if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll))
+ tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyScroll);
+
+ if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags))
+ {
+ // Demo a Leading TabItemButton(): click the "?" button to open a menu
+ if (show_leading_button)
+ if (ImGui::TabItemButton("?", ImGuiTabItemFlags_Leading | ImGuiTabItemFlags_NoTooltip))
+ ImGui::OpenPopup("MyHelpMenu");
+ if (ImGui::BeginPopup("MyHelpMenu"))
+ {
+ ImGui::Selectable("Hello!");
+ ImGui::EndPopup();
+ }
+
+ // Demo Trailing Tabs: click the "+" button to add a new tab (in your app you may want to use a font icon instead of the "+")
+ // Note that we submit it before the regular tabs, but because of the ImGuiTabItemFlags_Trailing flag it will always appear at the end.
+ if (show_trailing_button)
+ if (ImGui::TabItemButton("+", ImGuiTabItemFlags_Trailing | ImGuiTabItemFlags_NoTooltip))
+ active_tabs.push_back(next_tab_id++); // Add new tab
+
+ // Submit our regular tabs
+ for (int n = 0; n < active_tabs.Size; )
+ {
+ bool open = true;
+ char name[16];
+ snprintf(name, IM_ARRAYSIZE(name), "%04d", active_tabs[n]);
+ if (ImGui::BeginTabItem(name, &open, ImGuiTabItemFlags_None))
+ {
+ ImGui::Text("This is the %s tab!", name);
+ ImGui::EndTabItem();
+ }
+
+ if (!open)
+ active_tabs.erase(active_tabs.Data + n);
+ else
+ n++;
+ }
+
+ ImGui::EndTabBar();
+ }
+ ImGui::Separator();
+ ImGui::TreePop();
+ }
+ ImGui::TreePop();
+ }
+
+ // Plot/Graph widgets are not very good.
+ // Consider writing your own, or using a third-party one, see:
+ // - ImPlot https://github.com/epezent/implot
+ // - others https://github.com/ocornut/imgui/wiki/Useful-Widgets
if (ImGui::TreeNode("Plots Widgets"))
{
static bool animate = true;
@@ -2437,144 +2579,6 @@ static void ShowDemoWindowLayout()
ImGui::TreePop();
}
- if (ImGui::TreeNode("Tabs"))
- {
- if (ImGui::TreeNode("Basic"))
- {
- ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_None;
- if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags))
- {
- if (ImGui::BeginTabItem("Avocado"))
- {
- ImGui::Text("This is the Avocado tab!\nblah blah blah blah blah");
- ImGui::EndTabItem();
- }
- if (ImGui::BeginTabItem("Broccoli"))
- {
- ImGui::Text("This is the Broccoli tab!\nblah blah blah blah blah");
- ImGui::EndTabItem();
- }
- if (ImGui::BeginTabItem("Cucumber"))
- {
- ImGui::Text("This is the Cucumber tab!\nblah blah blah blah blah");
- ImGui::EndTabItem();
- }
- ImGui::EndTabBar();
- }
- ImGui::Separator();
- ImGui::TreePop();
- }
-
- if (ImGui::TreeNode("Advanced & Close Button"))
- {
- // Expose a couple of the available flags. In most cases you may just call BeginTabBar() with no flags (0).
- static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_Reorderable;
- ImGui::CheckboxFlags("ImGuiTabBarFlags_Reorderable", &tab_bar_flags, ImGuiTabBarFlags_Reorderable);
- ImGui::CheckboxFlags("ImGuiTabBarFlags_AutoSelectNewTabs", &tab_bar_flags, ImGuiTabBarFlags_AutoSelectNewTabs);
- ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", &tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton);
- ImGui::CheckboxFlags("ImGuiTabBarFlags_NoCloseWithMiddleMouseButton", &tab_bar_flags, ImGuiTabBarFlags_NoCloseWithMiddleMouseButton);
- if ((tab_bar_flags & ImGuiTabBarFlags_FittingPolicyMask_) == 0)
- tab_bar_flags |= ImGuiTabBarFlags_FittingPolicyDefault_;
- if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown))
- tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyResizeDown);
- if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll))
- tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyScroll);
-
- // Tab Bar
- const char* names[4] = { "Artichoke", "Beetroot", "Celery", "Daikon" };
- static bool opened[4] = { true, true, true, true }; // Persistent user state
- for (int n = 0; n < IM_ARRAYSIZE(opened); n++)
- {
- if (n > 0) { ImGui::SameLine(); }
- ImGui::Checkbox(names[n], &opened[n]);
- }
-
- // Passing a bool* to BeginTabItem() is similar to passing one to Begin():
- // the underlying bool will be set to false when the tab is closed.
- if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags))
- {
- for (int n = 0; n < IM_ARRAYSIZE(opened); n++)
- if (opened[n] && ImGui::BeginTabItem(names[n], &opened[n], ImGuiTabItemFlags_None))
- {
- ImGui::Text("This is the %s tab!", names[n]);
- if (n & 1)
- ImGui::Text("I am an odd tab.");
- ImGui::EndTabItem();
- }
- ImGui::EndTabBar();
- }
- ImGui::Separator();
- ImGui::TreePop();
- }
-
- if (ImGui::TreeNode("TabItemButton & Leading/Trailing flags"))
- {
- static ImVector<int> active_tabs;
- static int next_tab_id = 0;
- if (next_tab_id == 0) // Initialize with some default tabs
- for (int i = 0; i < 3; i++)
- active_tabs.push_back(next_tab_id++);
-
- // TabItemButton() and Leading/Trailing flags are distinct features which we will demo together.
- // (It is possible to submit regular tabs with Leading/Trailing flags, or TabItemButton tabs without Leading/Trailing flags...
- // but they tend to make more sense together)
- 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);
-
- // Expose some other flags which are useful to showcase how they interact with Leading/Trailing tabs
- static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_AutoSelectNewTabs | ImGuiTabBarFlags_Reorderable | ImGuiTabBarFlags_FittingPolicyResizeDown;
- ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", &tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton);
- if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown))
- tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyResizeDown);
- if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll))
- tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyScroll);
-
- if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags))
- {
- // Demo a Leading TabItemButton(): click the "?" button to open a menu
- if (show_leading_button)
- if (ImGui::TabItemButton("?", ImGuiTabItemFlags_Leading | ImGuiTabItemFlags_NoTooltip))
- ImGui::OpenPopup("MyHelpMenu");
- if (ImGui::BeginPopup("MyHelpMenu"))
- {
- ImGui::Selectable("Hello!");
- ImGui::EndPopup();
- }
-
- // Demo Trailing Tabs: click the "+" button to add a new tab (in your app you may want to use a font icon instead of the "+")
- // Note that we submit it before the regular tabs, but because of the ImGuiTabItemFlags_Trailing flag it will always appear at the end.
- if (show_trailing_button)
- if (ImGui::TabItemButton("+", ImGuiTabItemFlags_Trailing | ImGuiTabItemFlags_NoTooltip))
- active_tabs.push_back(next_tab_id++); // Add new tab
-
- // Submit our regular tabs
- for (int n = 0; n < active_tabs.Size; )
- {
- bool open = true;
- char name[16];
- snprintf(name, IM_ARRAYSIZE(name), "%04d", active_tabs[n]);
- if (ImGui::BeginTabItem(name, &open, ImGuiTabItemFlags_None))
- {
- ImGui::Text("This is the %s tab!", name);
- ImGui::EndTabItem();
- }
-
- if (!open)
- active_tabs.erase(active_tabs.Data + n);
- else
- n++;
- }
-
- ImGui::EndTabBar();
- }
- ImGui::Separator();
- ImGui::TreePop();
- }
- ImGui::TreePop();
- }
-
if (ImGui::TreeNode("Groups"))
{
HelpMarker(
@@ -3463,8 +3467,6 @@ static void EditTableColumnsFlags(ImGuiTableColumnFlags* p_flags)
*p_flags &= ~(ImGuiTableColumnFlags_WidthMask_ ^ ImGuiTableColumnFlags_WidthStretch);
if (ImGui::CheckboxFlags("_WidthFixed", p_flags, ImGuiTableColumnFlags_WidthFixed))
*p_flags &= ~(ImGuiTableColumnFlags_WidthMask_ ^ ImGuiTableColumnFlags_WidthFixed);
- if (ImGui::CheckboxFlags("_WidthAuto", p_flags, ImGuiTableColumnFlags_WidthAuto))
- *p_flags &= ~(ImGuiTableColumnFlags_WidthMask_ ^ ImGuiTableColumnFlags_WidthAuto);
ImGui::CheckboxFlags("_NoResize", p_flags, ImGuiTableColumnFlags_NoResize);
ImGui::CheckboxFlags("_NoReorder", p_flags, ImGuiTableColumnFlags_NoReorder);
ImGui::CheckboxFlags("_NoHide", p_flags, ImGuiTableColumnFlags_NoHide);
@@ -3537,7 +3539,7 @@ static void ShowDemoWindowTables()
// [Method 1] Using TableNextRow() to create a new row, and TableSetColumnIndex() to select the column.
// In many situations, this is the most flexible and easy to use pattern.
HelpMarker("Using TableNextRow() + calling TableSetColumnIndex() _before_ each cell, in a loop.");
- if (ImGui::BeginTable("##table1", 3))
+ if (ImGui::BeginTable("table1", 3))
{
for (int row = 0; row < 4; row++)
{
@@ -3554,7 +3556,7 @@ static void ShowDemoWindowTables()
// [Method 2] Using TableNextColumn() called multiple times, instead of using a for loop + TableSetColumnIndex().
// This is generally more convenient when you have code manually submitting the contents of each columns.
HelpMarker("Using TableNextRow() + calling TableNextColumn() _before_ each cell, manually.");
- if (ImGui::BeginTable("##table2", 3))
+ if (ImGui::BeginTable("table2", 3))
{
for (int row = 0; row < 4; row++)
{
@@ -3575,7 +3577,7 @@ static void ShowDemoWindowTables()
HelpMarker(
"Only using TableNextColumn(), which tends to be convenient for tables where every cells contains the same type of contents.\n"
"This is also more similar to the old NextColumn() function of the Columns API, and provided to facilitate the Columns->Tables API transition.");
- if (ImGui::BeginTable("##table3", 3))
+ if (ImGui::BeginTable("table3", 3))
{
for (int item = 0; item < 14; item++)
{
@@ -3627,7 +3629,7 @@ static void ShowDemoWindowTables()
ImGui::CheckboxFlags("ImGuiTableFlags_NoBordersInBody", &flags, ImGuiTableFlags_NoBordersInBody); ImGui::SameLine(); HelpMarker("Disable vertical borders in columns Body (borders will always appears in Headers");
PopStyleCompact();
- if (ImGui::BeginTable("##table1", 3, flags))
+ if (ImGui::BeginTable("table1", 3, flags))
{
// Display headers so we can inspect their interaction with borders.
// (Headers are not the main purpose of this section of the demo, so we are not elaborating on them too much. See other sections for details)
@@ -3671,7 +3673,7 @@ static void ShowDemoWindowTables()
ImGui::SameLine(); HelpMarker("Using the _Resizable flag automatically enables the _BordersInnerV flag as well, this is why the resize borders are still showing when unchecking this.");
PopStyleCompact();
- if (ImGui::BeginTable("##table1", 3, flags))
+ if (ImGui::BeginTable("table1", 3, flags))
{
for (int row = 0; row < 5; row++)
{
@@ -3701,12 +3703,10 @@ static void ShowDemoWindowTables()
"Double-click a column border to auto-fit the column to its contents.");
PushStyleCompact();
static ImGuiTableFlags flags = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_ContextMenuInBody;
- static bool fixed_fill = true;
- ImGui::Checkbox("fill", &fixed_fill);
+ ImGui::CheckboxFlags("ImGuiTableFlags_NoHostExtendX", &flags, ImGuiTableFlags_NoHostExtendX);
PopStyleCompact();
- ImVec2 outer_size(fixed_fill ? -FLT_MIN : 0.0f, 0.0f);
- if (ImGui::BeginTable("##table1", 3, flags, outer_size))
+ if (ImGui::BeginTable("table1", 3, flags))
{
for (int row = 0; row < 5; row++)
{
@@ -3731,7 +3731,7 @@ static void ShowDemoWindowTables()
"When combining Fixed and Stretch columns, generally you only want one, maybe two trailing columns to use _WidthStretch.");
static ImGuiTableFlags flags = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable;
- if (ImGui::BeginTable("##table1", 3, flags))
+ if (ImGui::BeginTable("table1", 3, flags))
{
ImGui::TableSetupColumn("AAA", ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("BBB", ImGuiTableColumnFlags_WidthFixed);
@@ -3748,7 +3748,7 @@ static void ShowDemoWindowTables()
}
ImGui::EndTable();
}
- if (ImGui::BeginTable("##table2", 6, flags))
+ if (ImGui::BeginTable("table2", 6, flags))
{
ImGui::TableSetupColumn("AAA", ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("BBB", ImGuiTableColumnFlags_WidthFixed);
@@ -3787,7 +3787,7 @@ static void ShowDemoWindowTables()
ImGui::CheckboxFlags("ImGuiTableFlags_NoBordersInBodyUntilResize", &flags, ImGuiTableFlags_NoBordersInBodyUntilResize); ImGui::SameLine(); HelpMarker("Disable vertical borders in columns Body until hovered for resize (borders will always appears in Headers)");
PopStyleCompact();
- if (ImGui::BeginTable("##table1", 3, flags))
+ if (ImGui::BeginTable("table1", 3, flags))
{
// Submit columns name with TableSetupColumn() and call TableHeadersRow() to create a row with a header in each column.
// (Later we will show how TableSetupColumn() has other uses, optional flags, sizing weight etc.)
@@ -3808,7 +3808,7 @@ static void ShowDemoWindowTables()
}
// Use outer_size.x == 0.0f instead of default to make the table as tight as possible (only valid when no scrolling and no stretch column)
- if (ImGui::BeginTable("##table2", 3, flags | ImGuiTableFlags_SizingFixedFit, ImVec2(0.0f, 0.0f)))
+ if (ImGui::BeginTable("table2", 3, flags | ImGuiTableFlags_SizingFixedFit, ImVec2(0.0f, 0.0f)))
{
ImGui::TableSetupColumn("One");
ImGui::TableSetupColumn("Two");
@@ -3857,7 +3857,7 @@ static void ShowDemoWindowTables()
ImGui::Checkbox("show_headers", &show_headers);
PopStyleCompact();
- if (ImGui::BeginTable("##table1", 3, flags1))
+ if (ImGui::BeginTable("table_padding", 3, flags1))
{
if (show_headers)
{
@@ -3910,7 +3910,7 @@ static void ShowDemoWindowTables()
PopStyleCompact();
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cell_padding);
- if (ImGui::BeginTable("##table2", 3, flags2))
+ if (ImGui::BeginTable("table_padding_2", 3, flags2))
{
static char text_bufs[3 * 5][16]; // Mini text storage for 3x5 cells
static bool init = true;
@@ -3940,18 +3940,12 @@ static void ShowDemoWindowTables()
ImGui::SetNextItemOpen(open_action != 0);
if (ImGui::TreeNode("Sizing policies"))
{
- static bool fixed_fill = true;
static ImGuiTableFlags flags1 = ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_RowBg | ImGuiTableFlags_ContextMenuInBody;
PushStyleCompact();
- ImGui::Checkbox("fill", &fixed_fill);
- ImGui::SameLine(); HelpMarker(
- "Value passed to outer_size only affects tables with _SizingFixedFit or _SizingFixedSame sizing policies.\n\n"
- " - outer_size.x == 0: table fit to columns total contents.\n"
- " - outer_size.x == -FLT_MIN: table fill until right-most edge.");
ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags1, ImGuiTableFlags_Resizable);
+ ImGui::CheckboxFlags("ImGuiTableFlags_NoHostExtendX", &flags1, ImGuiTableFlags_NoHostExtendX);
PopStyleCompact();
- ImVec2 outer_size = ImVec2(fixed_fill ? -FLT_MIN : 0.0f, 0.0f);
static ImGuiTableFlags sizing_policy_flags[4] = { ImGuiTableFlags_SizingFixedFit, ImGuiTableFlags_SizingFixedSame, ImGuiTableFlags_SizingStretchProp, ImGuiTableFlags_SizingStretchSame };
for (int table_n = 0; table_n < 4; table_n++)
{
@@ -3961,7 +3955,7 @@ static void ShowDemoWindowTables()
// To make it easier to understand the different sizing policy,
// For each policy: we display one table where the columns have equal contents width, and one where the columns have different contents width.
- if (ImGui::BeginTable("##table1", 3, sizing_policy_flags[table_n] | flags1, outer_size))
+ if (ImGui::BeginTable("table1", 3, sizing_policy_flags[table_n] | flags1))
{
for (int row = 0; row < 3; row++)
{
@@ -3972,7 +3966,7 @@ static void ShowDemoWindowTables()
}
ImGui::EndTable();
}
- if (ImGui::BeginTable("##table2", 3, sizing_policy_flags[table_n] | flags1, outer_size))
+ if (ImGui::BeginTable("table2", 3, sizing_policy_flags[table_n] | flags1))
{
for (int row = 0; row < 3; row++)
{
@@ -4017,8 +4011,7 @@ static void ShowDemoWindowTables()
ImGui::PopID();
PopStyleCompact();
- outer_size = ImVec2(-FLT_MIN, TEXT_BASE_HEIGHT * 7);
- if (ImGui::BeginTable("##table2", column_count, flags, outer_size))
+ if (ImGui::BeginTable("table2", column_count, flags, ImVec2(0.0f, TEXT_BASE_HEIGHT * 7)))
{
for (int cell = 0; cell < 10 * column_count; cell++)
{
@@ -4059,8 +4052,8 @@ static void ShowDemoWindowTables()
// When using ScrollX or ScrollY we need to specify a size for our table container!
// Otherwise by default the table will fit all available space, like a BeginChild() call.
- ImVec2 size = ImVec2(-FLT_MIN, TEXT_BASE_HEIGHT * 8);
- if (ImGui::BeginTable("##table1", 3, flags, size))
+ ImVec2 outer_size = ImVec2(0.0f, TEXT_BASE_HEIGHT * 8);
+ if (ImGui::BeginTable("table_scrolly", 3, flags, outer_size))
{
ImGui::TableSetupScrollFreeze(0, 1); // Make top row always visible
ImGui::TableSetupColumn("One", ImGuiTableColumnFlags_None);
@@ -4113,8 +4106,8 @@ static void ShowDemoWindowTables()
// When using ScrollX or ScrollY we need to specify a size for our table container!
// Otherwise by default the table will fit all available space, like a BeginChild() call.
- ImVec2 outer_size = ImVec2(-FLT_MIN, TEXT_BASE_HEIGHT * 8);
- if (ImGui::BeginTable("##table1", 7, flags, outer_size))
+ ImVec2 outer_size = ImVec2(0.0f, TEXT_BASE_HEIGHT * 8);
+ if (ImGui::BeginTable("table_scrollx", 7, flags, outer_size))
{
ImGui::TableSetupScrollFreeze(freeze_cols, freeze_rows);
ImGui::TableSetupColumn("Line #", ImGuiTableColumnFlags_NoHide); // Make the first column not hideable to match our use of TableSetupScrollFreeze()
@@ -4164,7 +4157,7 @@ static void ShowDemoWindowTables()
ImGui::PopItemWidth();
ImGui::PopID();
PopStyleCompact();
- if (ImGui::BeginTable("##table2", 7, flags2, outer_size, inner_width))
+ if (ImGui::BeginTable("table2", 7, flags2, outer_size, inner_width))
{
for (int cell = 0; cell < 20 * 7; cell++)
{
@@ -4186,7 +4179,7 @@ static void ShowDemoWindowTables()
static ImGuiTableColumnFlags column_flags[column_count] = { ImGuiTableColumnFlags_DefaultSort, ImGuiTableColumnFlags_None, ImGuiTableColumnFlags_DefaultHide };
static ImGuiTableColumnFlags column_flags_out[column_count] = { 0, 0, 0 }; // Output from TableGetColumnFlags()
- if (ImGui::BeginTable("##flags", column_count, ImGuiTableFlags_None))
+ if (ImGui::BeginTable("table_columns_flags_checkboxes", column_count, ImGuiTableFlags_None))
{
PushStyleCompact();
for (int column = 0; column < column_count; column++)
@@ -4214,8 +4207,8 @@ static void ShowDemoWindowTables()
= ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY
| ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV
| ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Sortable;
- ImVec2 size = ImVec2(-FLT_MIN, TEXT_BASE_HEIGHT * 9);
- if (ImGui::BeginTable("##table", column_count, flags, size))
+ ImVec2 outer_size = ImVec2(0.0f, TEXT_BASE_HEIGHT * 9);
+ if (ImGui::BeginTable("table_columns_flags", column_count, flags, outer_size))
{
for (int column = 0; column < column_count; column++)
ImGui::TableSetupColumn(column_names[column], column_flags[column]);
@@ -4244,16 +4237,44 @@ static void ShowDemoWindowTables()
ImGui::SetNextItemOpen(open_action != 0);
if (ImGui::TreeNode("Columns widths"))
{
- HelpMarker("Using TableSetupColumn() to setup explicit width.");
+ HelpMarker("Using TableSetupColumn() to setup default width.");
- static ImGuiTableFlags flags = ImGuiTableFlags_None;
+ static ImGuiTableFlags flags1 = ImGuiTableFlags_Borders | ImGuiTableFlags_NoBordersInBodyUntilResize;
PushStyleCompact();
- ImGui::CheckboxFlags("ImGuiTableFlags_NoKeepColumnsVisible", &flags, ImGuiTableFlags_NoKeepColumnsVisible);
- ImGui::CheckboxFlags("ImGuiTableFlags_BordersInnerV", &flags, ImGuiTableFlags_BordersInnerV);
- ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuterV", &flags, ImGuiTableFlags_BordersOuterV);
+ ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags1, ImGuiTableFlags_Resizable);
+ ImGui::CheckboxFlags("ImGuiTableFlags_NoBordersInBodyUntilResize", &flags1, ImGuiTableFlags_NoBordersInBodyUntilResize);
PopStyleCompact();
+ if (ImGui::BeginTable("table1", 3, flags1))
+ {
+ // We could also set ImGuiTableFlags_SizingFixedFit on the table and all columns will default to ImGuiTableColumnFlags_WidthFixed.
+ ImGui::TableSetupColumn("one", ImGuiTableColumnFlags_WidthFixed, 100.0f); // Default to 100.0f
+ ImGui::TableSetupColumn("two", ImGuiTableColumnFlags_WidthFixed, 200.0f); // Default to 200.0f
+ ImGui::TableSetupColumn("three", ImGuiTableColumnFlags_WidthFixed); // Default to auto
+ ImGui::TableHeadersRow();
+ for (int row = 0; row < 4; row++)
+ {
+ ImGui::TableNextRow();
+ for (int column = 0; column < 3; column++)
+ {
+ ImGui::TableSetColumnIndex(column);
+ if (row == 0)
+ ImGui::Text("(w: %5.1f)", ImGui::GetContentRegionAvail().x);
+ else
+ ImGui::Text("Hello %d,%d", column, row);
+ }
+ }
+ ImGui::EndTable();
+ }
+
+ HelpMarker("Using TableSetupColumn() to setup explicit width.\n\nUnless _NoKeepColumnsVisible is set, fixed columns with set width may still be shrunk down if there's not enough space in the host.");
- if (ImGui::BeginTable("##table1", 4, flags))
+ static ImGuiTableFlags flags2 = ImGuiTableFlags_None;
+ PushStyleCompact();
+ ImGui::CheckboxFlags("ImGuiTableFlags_NoKeepColumnsVisible", &flags2, ImGuiTableFlags_NoKeepColumnsVisible);
+ ImGui::CheckboxFlags("ImGuiTableFlags_BordersInnerV", &flags2, ImGuiTableFlags_BordersInnerV);
+ ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuterV", &flags2, ImGuiTableFlags_BordersOuterV);
+ PopStyleCompact();
+ if (ImGui::BeginTable("table2", 4, flags2))
{
// We could also set ImGuiTableFlags_SizingFixedFit on the table and all columns will default to ImGuiTableColumnFlags_WidthFixed.
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, 100.0f);
@@ -4267,8 +4288,9 @@ static void ShowDemoWindowTables()
{
ImGui::TableSetColumnIndex(column);
if (row == 0)
- ImGui::Text("(%.2f)", ImGui::GetContentRegionAvail().x);
- ImGui::Text("Hello %d,%d", column, row);
+ ImGui::Text("(w: %5.1f)", ImGui::GetContentRegionAvail().x);
+ else
+ ImGui::Text("Hello %d,%d", column, row);
}
}
ImGui::EndTable();
@@ -4282,7 +4304,7 @@ static void ShowDemoWindowTables()
{
HelpMarker("This demonstrate embedding a table into another table cell.");
- if (ImGui::BeginTable("nested1", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable))
+ if (ImGui::BeginTable("table_nested1", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable))
{
ImGui::TableSetupColumn("A0");
ImGui::TableSetupColumn("A1");
@@ -4292,7 +4314,7 @@ static void ShowDemoWindowTables()
ImGui::Text("A0 Cell 0");
{
float rows_height = TEXT_BASE_HEIGHT * 2;
- if (ImGui::BeginTable("nested2", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable))
+ if (ImGui::BeginTable("table_nested2", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable))
{
ImGui::TableSetupColumn("B0");
ImGui::TableSetupColumn("B1");
@@ -4325,7 +4347,7 @@ static void ShowDemoWindowTables()
if (ImGui::TreeNode("Row height"))
{
HelpMarker("You can pass a 'min_row_height' to TableNextRow().\n\nRows are padded with 'style.CellPadding.y' on top and bottom, so effectively the minimum row height will always be >= 'style.CellPadding.y * 2.0f'.\n\nWe cannot honor a _maximum_ row height as that would requires a unique clipping rectangle per row.");
- if (ImGui::BeginTable("##Table", 1, ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersInnerV))
+ if (ImGui::BeginTable("table_row_height", 1, ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersInnerV))
{
for (int row = 0; row < 10; row++)
{
@@ -4343,19 +4365,19 @@ static void ShowDemoWindowTables()
ImGui::SetNextItemOpen(open_action != 0);
if (ImGui::TreeNode("Outer size"))
{
- // Showcasing use of outer_size.x == 0.0f and ImGuiTableFlags_NoHostExtendY
- // The default value of outer_size.x is -FLT_MIN which right-align tables.
- // Using outer_size.x == 0.0f on a table with no scrolling and no stretch column we can make them tighter.
- ImGui::Text("Using auto/all width, using NoHostExtendY:");
+ // Showcasing use of ImGuiTableFlags_NoHostExtendX and ImGuiTableFlags_NoHostExtendY
+ // Important to that note how the two flags have slightly different behaviors!
+ ImGui::Text("Using NoHostExtendX and NoHostExtendY:");
PushStyleCompact();
- static ImGuiTableFlags flags = ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_ContextMenuInBody | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit;
- static bool fixed_fill = false;
- ImGui::Checkbox("fill", &fixed_fill);
+ static ImGuiTableFlags flags = ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_ContextMenuInBody | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoHostExtendX;
+ ImGui::CheckboxFlags("ImGuiTableFlags_NoHostExtendX", &flags, ImGuiTableFlags_NoHostExtendX);
+ ImGui::SameLine(); HelpMarker("Make outer width auto-fit to columns, overriding outer_size.x value.\n\nOnly available when ScrollX/ScrollY are disabled and Stretch columns are not used.");
ImGui::CheckboxFlags("ImGuiTableFlags_NoHostExtendY", &flags, ImGuiTableFlags_NoHostExtendY);
+ ImGui::SameLine(); HelpMarker("Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit).\n\nOnly available when ScrollX/ScrollY are disabled. Data below the limit will be clipped and not visible.");
PopStyleCompact();
- ImVec2 outer_size = ImVec2(fixed_fill ? -FLT_MIN : 0.0f, TEXT_BASE_HEIGHT * 5.5f);
- if (ImGui::BeginTable("##table3", 3, flags, outer_size))
+ ImVec2 outer_size = ImVec2(0.0f, TEXT_BASE_HEIGHT * 5.5f);
+ if (ImGui::BeginTable("table1", 3, flags, outer_size))
{
for (int row = 0; row < 10; row++)
{
@@ -4374,7 +4396,7 @@ static void ShowDemoWindowTables()
ImGui::Spacing();
ImGui::Text("Using explicit size:");
- if (ImGui::BeginTable("##table1", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg, ImVec2(TEXT_BASE_WIDTH * 30, 0.0f)))
+ if (ImGui::BeginTable("table2", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg, ImVec2(TEXT_BASE_WIDTH * 30, 0.0f)))
{
for (int row = 0; row < 5; row++)
{
@@ -4388,7 +4410,7 @@ static void ShowDemoWindowTables()
ImGui::EndTable();
}
ImGui::SameLine();
- if (ImGui::BeginTable("##table2", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg, ImVec2(TEXT_BASE_WIDTH * 30, 0.0f)))
+ if (ImGui::BeginTable("table3", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg, ImVec2(TEXT_BASE_WIDTH * 30, 0.0f)))
{
for (int row = 0; row < 3; row++)
{
@@ -4426,7 +4448,7 @@ static void ShowDemoWindowTables()
IM_ASSERT(cell_bg_type >= 0 && cell_bg_type <= 1);
PopStyleCompact();
- if (ImGui::BeginTable("##Table", 5, flags))
+ if (ImGui::BeginTable("table1", 5, flags))
{
for (int row = 0; row < 6; row++)
{
@@ -4468,7 +4490,7 @@ static void ShowDemoWindowTables()
{
static ImGuiTableFlags flags = ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody;
- if (ImGui::BeginTable("##3ways", 3, flags))
+ if (ImGui::BeginTable("3ways", 3, flags))
{
// The first column will use the default _WidthStretch when ScrollX is Off and _WidthFixed when ScrollX is On
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_NoHide);
@@ -4540,7 +4562,7 @@ static void ShowDemoWindowTables()
HelpMarker(
"Showcase using PushItemWidth() and how it is preserved on a per-column basis.\n\n"
"Note that on auto-resizing non-resizable fixed columns, querying the content width for e.g. right-alignment doesn't make sense.");
- if (ImGui::BeginTable("##table2", 3, ImGuiTableFlags_Borders))
+ if (ImGui::BeginTable("table_item_width", 3, ImGuiTableFlags_Borders))
{
ImGui::TableSetupColumn("small");
ImGui::TableSetupColumn("half");
@@ -4583,7 +4605,7 @@ static void ShowDemoWindowTables()
if (ImGui::TreeNode("Custom headers"))
{
const int COLUMNS_COUNT = 3;
- if (ImGui::BeginTable("##table1", COLUMNS_COUNT, ImGuiTableFlags_Borders | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable))
+ if (ImGui::BeginTable("table_custom_headers", COLUMNS_COUNT, ImGuiTableFlags_Borders | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable))
{
ImGui::TableSetupColumn("Apricot");
ImGui::TableSetupColumn("Banana");
@@ -4633,14 +4655,14 @@ static void ShowDemoWindowTables()
static ImGuiTableFlags flags1 = ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders | ImGuiTableFlags_ContextMenuInBody;
PushStyleCompact();
- ImGui::CheckboxFlags("ImGuiTableFlags_ContextMenuInBody", (unsigned int*)&flags1, ImGuiTableFlags_ContextMenuInBody);
+ ImGui::CheckboxFlags("ImGuiTableFlags_ContextMenuInBody", &flags1, ImGuiTableFlags_ContextMenuInBody);
PopStyleCompact();
// Context Menus: first example
// [1.1] Right-click on the TableHeadersRow() line to open the default table context menu.
// [1.2] Right-click in columns also open the default table context menu (if ImGuiTableFlags_ContextMenuInBody is set)
const int COLUMNS_COUNT = 3;
- if (ImGui::BeginTable("##table1", COLUMNS_COUNT, flags1))
+ if (ImGui::BeginTable("table_context_menu", COLUMNS_COUNT, flags1))
{
ImGui::TableSetupColumn("One");
ImGui::TableSetupColumn("Two");
@@ -4668,7 +4690,7 @@ static void ShowDemoWindowTables()
// [2.3] Right-click in columns to open another custom popup
HelpMarker("Demonstrate mixing table context menu (over header), item context button (over button) and custom per-colum context menu (over column body).");
ImGuiTableFlags flags2 = ImGuiTableFlags_Resizable | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders;
- if (ImGui::BeginTable("##table2", COLUMNS_COUNT, flags2))
+ if (ImGui::BeginTable("table_context_menu_2", COLUMNS_COUNT, flags2))
{
ImGui::TableSetupColumn("One");
ImGui::TableSetupColumn("Two");
@@ -4797,7 +4819,7 @@ static void ShowDemoWindowTables()
ImGui::SameLine(); HelpMarker("When sorting is enabled: allow no sorting, disable default sorting. TableGetSortSpecs() may return specs where (SpecsCount == 0).");
PopStyleCompact();
- if (ImGui::BeginTable("##table", 4, flags, ImVec2(-FLT_MIN, TEXT_BASE_HEIGHT * 15), 0.0f))
+ if (ImGui::BeginTable("table_sorting", 4, flags, ImVec2(0.0f, TEXT_BASE_HEIGHT * 15), 0.0f))
{
// Declare columns
// We use the "user_id" parameter of TableSetupColumn() to specify a user id that will be stored in the sort specifications.
@@ -4806,10 +4828,10 @@ static void ShowDemoWindowTables()
// - ImGuiTableColumnFlags_DefaultSort
// - ImGuiTableColumnFlags_NoSort / ImGuiTableColumnFlags_NoSortAscending / ImGuiTableColumnFlags_NoSortDescending
// - ImGuiTableColumnFlags_PreferSortAscending / ImGuiTableColumnFlags_PreferSortDescending
- ImGui::TableSetupColumn("ID", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, -1.0f, MyItemColumnID_ID);
- ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, -1.0f, MyItemColumnID_Name);
- ImGui::TableSetupColumn("Action", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, -1.0f, MyItemColumnID_Action);
- ImGui::TableSetupColumn("Quantity", ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthStretch, -1.0f, MyItemColumnID_Quantity);
+ ImGui::TableSetupColumn("ID", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, MyItemColumnID_ID);
+ ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, 0.0f, MyItemColumnID_Name);
+ ImGui::TableSetupColumn("Action", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, MyItemColumnID_Action);
+ ImGui::TableSetupColumn("Quantity", ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthStretch, 0.0f, MyItemColumnID_Quantity);
ImGui::TableSetupScrollFreeze(0, 1); // Make row always visible
ImGui::TableHeadersRow();
@@ -4867,7 +4889,7 @@ static void ShowDemoWindowTables()
static int freeze_cols = 1;
static int freeze_rows = 1;
static int items_count = IM_ARRAYSIZE(template_items_names) * 2;
- static ImVec2 outer_size_value = ImVec2(-FLT_MIN, TEXT_BASE_HEIGHT * 12);
+ static ImVec2 outer_size_value = ImVec2(0.0f, TEXT_BASE_HEIGHT * 12);
static float row_min_height = 0.0f; // Auto
static float inner_width_with_scroll = 0.0f; // Auto-extend
static bool outer_size_enabled = true;
@@ -4910,7 +4932,10 @@ static void ShowDemoWindowTables()
{
EditTableSizingFlags(&flags);
ImGui::SameLine(); HelpMarker("In the Advanced demo we override the policy of each column so those table-wide settings have less effect that typical.");
+ ImGui::CheckboxFlags("ImGuiTableFlags_NoHostExtendX", &flags, ImGuiTableFlags_NoHostExtendX);
+ ImGui::SameLine(); HelpMarker("Make outer width auto-fit to columns, overriding outer_size.x value.\n\nOnly available when ScrollX/ScrollY are disabled and Stretch columns are not used.");
ImGui::CheckboxFlags("ImGuiTableFlags_NoHostExtendY", &flags, ImGuiTableFlags_NoHostExtendY);
+ ImGui::SameLine(); HelpMarker("Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit).\n\nOnly available when ScrollX/ScrollY are disabled. Data below the limit will be clipped and not visible.");
ImGui::CheckboxFlags("ImGuiTableFlags_NoKeepColumnsVisible", &flags, ImGuiTableFlags_NoKeepColumnsVisible);
ImGui::SameLine(); HelpMarker("Only available if ScrollX is disabled.");
ImGui::CheckboxFlags("ImGuiTableFlags_PreciseWidths", &flags, ImGuiTableFlags_PreciseWidths);
@@ -5007,16 +5032,16 @@ static void ShowDemoWindowTables()
const ImDrawList* table_draw_list = NULL; // "
const float inner_width_to_use = (flags & ImGuiTableFlags_ScrollX) ? inner_width_with_scroll : 0.0f;
- if (ImGui::BeginTable("##table", 6, flags, outer_size_enabled ? outer_size_value : ImVec2(0, 0), inner_width_to_use))
+ if (ImGui::BeginTable("table_advanced", 6, flags, outer_size_enabled ? outer_size_value : ImVec2(0, 0), inner_width_to_use))
{
// Declare columns
// We use the "user_id" parameter of TableSetupColumn() to specify a user id that will be stored in the sort specifications.
// This is so our sort function can identify a column given our own identifier. We could also identify them based on their index!
- ImGui::TableSetupColumn("ID", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHide, -1.0f, MyItemColumnID_ID);
- ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, -1.0f, MyItemColumnID_Name);
- ImGui::TableSetupColumn("Action", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, -1.0f, MyItemColumnID_Action);
- ImGui::TableSetupColumn("Quantity", ImGuiTableColumnFlags_PreferSortDescending, -1.0f, MyItemColumnID_Quantity);
- ImGui::TableSetupColumn("Description", ImGuiTableColumnFlags_WidthStretch, -1.0f, MyItemColumnID_Description);
+ ImGui::TableSetupColumn("ID", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHide, 0.0f, MyItemColumnID_ID);
+ ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, 0.0f, MyItemColumnID_Name);
+ ImGui::TableSetupColumn("Action", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, MyItemColumnID_Action);
+ ImGui::TableSetupColumn("Quantity", ImGuiTableColumnFlags_PreferSortDescending, 0.0f, MyItemColumnID_Quantity);
+ ImGui::TableSetupColumn("Description", (flags & ImGuiTableFlags_NoHostExtendX) ? 0 : ImGuiTableColumnFlags_WidthStretch, 0.0f, MyItemColumnID_Description);
ImGui::TableSetupColumn("Hidden", ImGuiTableColumnFlags_DefaultHide | ImGuiTableColumnFlags_NoSort);
ImGui::TableSetupScrollFreeze(freeze_cols, freeze_rows);
@@ -5614,6 +5639,9 @@ void ImGui::ShowAboutWindow(bool* p_open)
#ifdef _MSC_VER
ImGui::Text("define: _MSC_VER=%d", _MSC_VER);
#endif
+#ifdef _MSVC_LANG
+ ImGui::Text("define: _MSVC_LANG=%d", (int)_MSVC_LANG);
+#endif
#ifdef __MINGW32__
ImGui::Text("define: __MINGW32__");
#endif
@@ -7088,7 +7116,7 @@ static void ShowExampleAppCustomRendering(bool* p_open)
{
if (ImGui::BeginTabItem("Primitives"))
{
- ImGui::PushItemWidth(-ImGui::GetFontSize() * 10);
+ ImGui::PushItemWidth(-ImGui::GetFontSize() * 15);
ImDrawList* draw_list = ImGui::GetWindowDrawList();
// Draw gradients
@@ -7182,7 +7210,7 @@ static void ShowExampleAppCustomRendering(bool* p_open)
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + 1, y + 1), col); x += sz; // Pixel (faster than AddLine)
draw_list->AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x + sz, y + sz), IM_COL32(0, 0, 0, 255), IM_COL32(255, 0, 0, 255), IM_COL32(255, 255, 0, 255), IM_COL32(0, 255, 0, 255));
- ImGui::Dummy(ImVec2((sz + spacing) * 8.8f, (sz + spacing) * 3.0f));
+ ImGui::Dummy(ImVec2((sz + spacing) * 10.2f, (sz + spacing) * 3.0f));
ImGui::PopItemWidth();
ImGui::EndTabItem();
}
diff --git a/imgui/imgui_draw.cpp b/imgui/imgui_draw.cpp
index a076e03d..835336e1 100644
--- a/imgui/imgui_draw.cpp
+++ b/imgui/imgui_draw.cpp
@@ -1,4 +1,4 @@
-// dear imgui, v1.80 WIP
+// dear imgui, v1.80
// (drawing and font code)
/*
diff --git a/imgui/imgui_internal.h b/imgui/imgui_internal.h
index ea7b7899..1b3462a6 100644
--- a/imgui/imgui_internal.h
+++ b/imgui/imgui_internal.h
@@ -1,4 +1,4 @@
-// dear imgui, v1.80 WIP
+// dear imgui, v1.80
// (internal structures/api)
// You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility!
@@ -190,7 +190,7 @@ namespace ImStb
#define IMGUI_DEBUG_LOG_DOCKING(...) ((void)0) // Disable log
// Static Asserts
-#if (__cplusplus >= 201100)
+#if (__cplusplus >= 201100) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201100)
#define IM_STATIC_ASSERT(_COND) static_assert(_COND, "")
#else
#define IM_STATIC_ASSERT(_COND) typedef char static_assertion_##__line__[(_COND)?1:-1]
@@ -478,8 +478,9 @@ struct IMGUI_API ImRect
inline bool ImBitArrayTestBit(const ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); return (arr[n >> 5] & mask) != 0; }
inline void ImBitArrayClearBit(ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); arr[n >> 5] &= ~mask; }
inline void ImBitArraySetBit(ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); arr[n >> 5] |= mask; }
-inline void ImBitArraySetBitRange(ImU32* arr, int n, int n2)
+inline void ImBitArraySetBitRange(ImU32* arr, int n, int n2) // Works on range [n..n2)
{
+ n2--;
while (n <= n2)
{
int a_mod = (n & 31);
@@ -497,11 +498,12 @@ struct IMGUI_API ImBitArray
{
ImU32 Storage[(BITCOUNT + 31) >> 5];
ImBitArray() { }
- void ClearBits() { memset(Storage, 0, sizeof(Storage)); }
+ void ClearAllBits() { memset(Storage, 0, sizeof(Storage)); }
+ void SetAllBits() { memset(Storage, 255, sizeof(Storage)); }
bool TestBit(int n) const { IM_ASSERT(n < BITCOUNT); return ImBitArrayTestBit(Storage, n); }
void SetBit(int n) { IM_ASSERT(n < BITCOUNT); ImBitArraySetBit(Storage, n); }
void ClearBit(int n) { IM_ASSERT(n < BITCOUNT); ImBitArrayClearBit(Storage, n); }
- void SetBitRange(int n1, int n2) { ImBitArraySetBitRange(Storage, n1, n2); }
+ void SetBitRange(int n, int n2) { ImBitArraySetBitRange(Storage, n, n2); } // Works on range [n..n2)
};
// Helper: ImBitVector
@@ -1247,13 +1249,33 @@ struct ImGuiDockNode
ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); }
};
+// List of colors that are stored at the time of Begin() into Docked Windows.
+// We currently store the packed colors in a simple array window->DockStyle.Colors[].
+// A better solution may involve appending into a log of colors in ImGuiContext + store offsets into those arrays in ImGuiWindow,
+// but it would be more complex as we'd need to double-buffer both as e.g. drop target may refer to window from last frame.
+enum ImGuiWindowDockStyleCol
+{
+ ImGuiWindowDockStyleCol_Text,
+ ImGuiWindowDockStyleCol_Tab,
+ ImGuiWindowDockStyleCol_TabHovered,
+ ImGuiWindowDockStyleCol_TabActive,
+ ImGuiWindowDockStyleCol_TabUnfocused,
+ ImGuiWindowDockStyleCol_TabUnfocusedActive,
+ ImGuiWindowDockStyleCol_COUNT
+};
+
+struct ImGuiWindowDockStyle
+{
+ ImU32 Colors[ImGuiWindowDockStyleCol_COUNT];
+};
+
struct ImGuiDockContext
{
ImGuiStorage Nodes; // Map ID -> ImGuiDockNode*: Active nodes
ImVector<ImGuiDockRequest> Requests;
ImVector<ImGuiDockNodeSettings> NodesSettings;
bool WantFullRebuild;
- ImGuiDockContext() { WantFullRebuild = false; }
+ ImGuiDockContext() { memset(this, 0, sizeof(*this)); }
};
#endif // #ifdef IMGUI_HAS_DOCK
@@ -1821,7 +1843,8 @@ struct IMGUI_API ImGuiWindowTempData
ImVec2 CursorPos; // Current emitting position, in absolute coordinates.
ImVec2 CursorPosPrevLine;
ImVec2 CursorStartPos; // Initial position after Begin(), generally ~ window position + WindowPadding.
- ImVec2 CursorMaxPos; // Used to implicitly calculate the size of our contents, always growing during the frame. Used to calculate window->ContentSize at the beginning of next frame
+ ImVec2 CursorMaxPos; // Used to implicitly calculate ContentSize at the beginning of next frame, for scrolling range and auto-resize. Always growing during the frame.
+ ImVec2 IdealMaxPos; // Used to implicitly calculate ContentSizeIdeal at the beginning of next frame, for auto-resize only. Always growing during the frame.
ImVec2 CurrLineSize;
ImVec2 PrevLineSize;
float CurrLineTextBaseOffset; // Baseline offset (0.0f by default on a new line, generally == style.FramePadding.y when a framed item has been added).
@@ -1884,6 +1907,7 @@ struct IMGUI_API ImGuiWindow
ImVec2 Size; // Current size (==SizeFull or collapsed title bar size)
ImVec2 SizeFull; // Size when non collapsed
ImVec2 ContentSize; // Size of contents/scrollable client area (calculated from the extents reach of the cursor) from previous frame. Does not include window decoration or window padding.
+ ImVec2 ContentSizeIdeal;
ImVec2 ContentSizeExplicit; // Size of contents/scrollable client area explicitly request by the user via SetNextWindowContentSize().
ImVec2 WindowPadding; // Window padding at the time of Begin().
float WindowRounding; // Window rounding at the time of Begin(). May be clamped lower to avoid rendering artifacts with title bar, menu bar etc.
@@ -1970,15 +1994,16 @@ struct IMGUI_API ImGuiWindow
bool MemoryCompacted; // Set when window extraneous data have been garbage collected
// Docking
+ bool DockIsActive :1; // When docking artifacts are actually visible. When this is set, DockNode is guaranteed to be != NULL. ~~ (DockNode != NULL) && (DockNode->Windows.Size > 1).
+ bool DockTabIsVisible :1; // Is our window visible this frame? ~~ is the corresponding tab selected?
+ bool DockTabWantClose :1;
+ short DockOrder; // Order of the last time the window was visible within its DockNode. This is used to reorder windows that are reappearing on the same frame. Same value between windows that were active and windows that were none are possible.
+ ImGuiWindowDockStyle DockStyle;
ImGuiDockNode* DockNode; // Which node are we docked into. Important: Prefer testing DockIsActive in many cases as this will still be set when the dock node is hidden.
ImGuiDockNode* DockNodeAsHost; // Which node are we owning (for parent windows)
ImGuiID DockId; // Backup of last valid DockNode->ID, so single window remember their dock node id even when they are not bound any more
ImGuiItemStatusFlags DockTabItemStatusFlags;
ImRect DockTabItemRect;
- short DockOrder; // Order of the last time the window was visible within its DockNode. This is used to reorder windows that are reappearing on the same frame. Same value between windows that were active and windows that were none are possible.
- bool DockIsActive :1; // When docking artifacts are actually visible. When this is set, DockNode is guaranteed to be != NULL. ~~ (DockNode != NULL) && (DockNode->Windows.Size > 1).
- bool DockTabIsVisible :1; // Is our window visible this frame? ~~ is the corresponding tab selected?
- bool DockTabWantClose :1;
public:
ImGuiWindow(ImGuiContext* context, const char* name);
@@ -2245,6 +2270,7 @@ struct ImGuiTable
ImVec2 HostBackupPrevLineSize; // Backup of InnerWindow->DC.PrevLineSize at the end of BeginTable()
ImVec2 HostBackupCurrLineSize; // Backup of InnerWindow->DC.CurrLineSize at the end of BeginTable()
ImVec2 HostBackupCursorMaxPos; // Backup of InnerWindow->DC.CursorMaxPos at the end of BeginTable()
+ ImVec2 UserOuterSize; // outer_size.x passed to BeginTable()
ImVec1 HostBackupColumnsOffset; // Backup of OuterWindow->DC.ColumnsOffset at the end of BeginTable()
float HostBackupItemWidth; // Backup of OuterWindow->DC.ItemWidth at the end of BeginTable()
int HostBackupItemWidthStackSize;// Backup of OuterWindow->DC.ItemWidthStack.Size at the end of BeginTable()
@@ -2291,7 +2317,7 @@ struct ImGuiTable
bool IsResetAllRequest;
bool IsResetDisplayOrderRequest;
bool IsUnfrozenRows; // Set when we got past the frozen row.
- bool IsOuterRectAutoFitX; // Set when outer_size.x == 0.0f in BeginTable(), scrolling is disabled, and there are stretch columns.
+ bool IsDefaultSizingPolicy; // Set if user didn't explicitely set a sizing policy in BeginTable()
bool MemoryCompacted;
bool HostSkipItems; // Backup of InnerWindow->SkipItem at the end of BeginTable(), because we will overwrite InnerWindow->SkipItem on a per-column basis
@@ -2356,7 +2382,7 @@ namespace ImGui
IMGUI_API ImGuiWindow* FindWindowByID(ImGuiID id);
IMGUI_API ImGuiWindow* FindWindowByName(const char* name);
IMGUI_API void UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags flags, ImGuiWindow* parent_window);
- IMGUI_API ImVec2 CalcWindowExpectedSize(ImGuiWindow* window);
+ IMGUI_API ImVec2 CalcWindowNextAutoFitSize(ImGuiWindow* window);
IMGUI_API bool IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent);
IMGUI_API bool IsWindowAbove(ImGuiWindow* potential_above, ImGuiWindow* potential_below);
IMGUI_API bool IsWindowNavFocusable(ImGuiWindow* window);
@@ -2504,8 +2530,8 @@ namespace ImGui
IMGUI_API void DockContextShutdown(ImGuiContext* ctx);
IMGUI_API void DockContextClearNodes(ImGuiContext* ctx, ImGuiID root_id, bool clear_settings_refs); // Use root_id==0 to clear all
IMGUI_API void DockContextRebuildNodes(ImGuiContext* ctx);
- IMGUI_API void DockContextUpdateUndocking(ImGuiContext* ctx);
- IMGUI_API void DockContextUpdateDocking(ImGuiContext* ctx);
+ IMGUI_API void DockContextNewFrameUpdateUndocking(ImGuiContext* ctx);
+ IMGUI_API void DockContextNewFrameUpdateDocking(ImGuiContext* ctx);
IMGUI_API ImGuiID DockContextGenNodeID(ImGuiContext* ctx);
IMGUI_API void DockContextQueueDock(ImGuiContext* ctx, ImGuiWindow* target, ImGuiDockNode* target_node, ImGuiWindow* payload, ImGuiDir split_dir, float split_ratio, bool split_outer);
IMGUI_API void DockContextQueueUndockWindow(ImGuiContext* ctx, ImGuiWindow* window);
diff --git a/imgui/imgui_tables.cpp b/imgui/imgui_tables.cpp
index a574e8c7..19fa625d 100644
--- a/imgui/imgui_tables.cpp
+++ b/imgui/imgui_tables.cpp
@@ -1,4 +1,4 @@
-// dear imgui, v1.80 WIP
+// dear imgui, v1.80
// (tables and columns code)
/*
@@ -74,24 +74,30 @@ Index of this file:
//-----------------------------------------------------------------------------
// About 'outer_size':
// Its meaning needs to differ slightly depending of if we are using ScrollX/ScrollY flags.
-// Default value is ImVec2(-FLT_MIN, 0.0f). When binding this in a scripting language please follow this default value.
+// Default value is ImVec2(0.0f, 0.0f).
// X
-// - outer_size.x < 0.0f -> Right-align from window/work-rect right-most edge. With -FLT_MIN will right-align exactly on right-most edge. With -1.0f will right-align one pixel away from right-most edge.
-// - outer_size.x = 0.0f -> Auto width. Generally use all available width. When NOT using scrolling and NOT using any Stretch column, use only necessary width, otherwise same as -FLT_MIN.
-// - outer_size.x > 0.0f -> Fixed width.
+// - outer_size.x <= 0.0f -> Right-align from window/work-rect right-most edge. With -FLT_MIN or 0.0f will align exactly on right-most edge.
+// - outer_size.x > 0.0f -> Set Fixed width.
// Y with ScrollX/ScrollY disabled: we output table directly in current window
-// - outer_size.y < 0.0f -> Bottom-align (but will auto extend, unless NoHostExtendV is set)
-// - outer_size.y = 0.0f -> No minimum height (but will auto extend, unless NoHostExtendV is set)
-// - outer_size.y > 0.0f -> Set Minimum height (but will auto extend, unless NoHostExtendV is set)
+// - outer_size.y < 0.0f -> Bottom-align (but will auto extend, unless _NoHostExtendY is set). Not meaningful is parent window can vertically scroll.
+// - outer_size.y = 0.0f -> No minimum height (but will auto extend, unless _NoHostExtendY is set)
+// - outer_size.y > 0.0f -> Set Minimum height (but will auto extend, unless _NoHostExtenY is set)
// Y with ScrollX/ScrollY enabled: using a child window for scrolling
-// - outer_size.y < 0.0f -> Bottom-align
-// - outer_size.y = 0.0f -> Bottom-align, consistent with BeginChild(). Not recommended unless table is last item in parent window.
-// - outer_size.y > 0.0f -> Set Exact height. Recommended when using Scrolling on any axis.
+// - outer_size.y < 0.0f -> Bottom-align. Not meaningful is parent window can vertically scroll.
+// - outer_size.y = 0.0f -> Bottom-align, consistent with BeginChild(). Not recommended unless table is last item in parent window.
+// - outer_size.y > 0.0f -> Set Exact height. Recommended when using Scrolling on any axis.
+//-----------------------------------------------------------------------------
+// Outer size is also affected by the NoHostExtendX/NoHostExtendY flags.
+// Important to that note how the two flags have slightly different behaviors!
+// - ImGuiTableFlags_NoHostExtendX -> Make outer width auto-fit to columns (overriding outer_size.x value). Only available when ScrollX/ScrollY are disabled and Stretch columns are not used.
+// - ImGuiTableFlags_NoHostExtendY -> Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit). Only available when ScrollX/ScrollY are disabled. Data below the limit will be clipped and not visible.
+// In theory ImGuiTableFlags_NoHostExtendY could be the default and any non-scrolling tables with outer_size.y != 0.0f would use exact height.
+// This would be consistent but perhaps less useful and more confusing (as vertically clipped items are not easily noticeable)
//-----------------------------------------------------------------------------
// About 'inner_width':
// With ScrollX disabled:
// - inner_width -> *ignored*
-// With ScrollX enable:
+// With ScrollX enabled:
// - inner_width < 0.0f -> *illegal* fit in known width (right align from outer_size.x) <-- weird
// - inner_width = 0.0f -> fit in outer_width: Fixed size columns will take space they need (if avail, otherwise shrink down), Stretch columns becomes Fixed columns.
// - inner_width > 0.0f -> override scrolling width, generally to be larger than outer_size.x. Fixed column take space they need (if avail, otherwise shrink down), Stretch columns share remaining space!
@@ -108,7 +114,6 @@ Index of this file:
//-----------------------------------------------------------------------------
// About overriding column sizing policy and width/weight with TableSetupColumn():
// We use a default parameter of 'init_width_or_weight == -1'.
-// - with ImGuiTableColumnFlags_WidthAuto, init_width (ignored) --> width is automatic
// - with ImGuiTableColumnFlags_WidthFixed, init_width <= 0 (default) --> width is automatic
// - with ImGuiTableColumnFlags_WidthFixed, init_width > 0 (explicit) --> width is custom
// - with ImGuiTableColumnFlags_WidthStretch, init_weight <= 0 (default) --> weight is 1.0f
@@ -117,11 +122,11 @@ Index of this file:
// and you can fit a 100.0f wide item in it without clipping and with full padding.
//-----------------------------------------------------------------------------
// About default sizing policy (if you don't specify a ImGuiTableColumnFlags_WidthXXXX flag)
-// - with Table policy ImGuiTableFlags_SizingFixedFit && (Resizable == 1 || init_width > 0) --> default Column policy is ImGuiTableColumnFlags_WidthFixed, default Width is equal to contents width
-// - with Table policy ImGuiTableFlags_SizingFixedFit && (Resizable == 0 && init_width <= 0) --> default Column policy is ImGuiTableColumnFlags_WidthAuto, Width always equal to contents width
-// - with Table policy ImGuiTableFlags_SizingFixedSame --> default Column policy is ImGuiTableColumnFlags_WidthAuto, default Width is max of all contents width
-// - with Table policy ImGuiTableFlags_SizingStretchSame --> default Column policy is ImGuiTableColumnFlags_WidthStretch, default Weight is 1.0f
-// - with Table policy ImGuiTableFlags_SizingStretchWeight --> default Column policy is ImGuiTableColumnFlags_WidthStretch, default Weight is proportional to contents
+// - with Table policy ImGuiTableFlags_SizingFixedFit --> default Column policy is ImGuiTableColumnFlags_WidthFixed, default Width is equal to contents width
+// - with Table policy ImGuiTableFlags_SizingFixedSame --> default Column policy is ImGuiTableColumnFlags_WidthFixed, default Width is max of all contents width
+// - with Table policy ImGuiTableFlags_SizingStretchSame --> default Column policy is ImGuiTableColumnFlags_WidthStretch, default Weight is 1.0f
+// - with Table policy ImGuiTableFlags_SizingStretchWeight --> default Column policy is ImGuiTableColumnFlags_WidthStretch, default Weight is proportional to contents
+// Default Width and default Weight can be overriden when calling TableSetupColumn().
//-----------------------------------------------------------------------------
// About mixing Fixed/Auto and Stretch columns together:
// - the typical use of mixing sizing policies is: any number of LEADING Fixed columns, followed by one or two TRAILING Stretch columns.
@@ -130,6 +135,16 @@ Index of this file:
// - when using ImGuiTableFlags_SizingFixedSame with mixed columns, only the Fixed/Auto columns will match their widths to the maximum contents width.
// - when using ImGuiTableFlags_SizingStretchSame with mixed columns, only the Stretch columns will match their weight/widths.
//-----------------------------------------------------------------------------
+// About using column width:
+// If a column is manual resizable or has a width specified with TableSetupColumn():
+// - you may use GetContentRegionAvail().x to query the width available in a given column.
+// - right-side alignment features such as SetNextItemWidth(-x) or PushItemWidth(-x) will rely on this width.
+// If the column is not resizable and has no width specified with TableSetupColumn():
+// - its width will be automatic and be the set to the max of items submitted.
+// - therefore you generally cannot have ALL items of the columns use e.g. SetNextItemWidth(-FLT_MIN).
+// - but if the column has one or more item of known/fixed size, this will become the reference width used by SetNextItemWidth(-FLT_MIN).
+//-----------------------------------------------------------------------------
+
//-----------------------------------------------------------------------------
// TABLES CLIPPING/CULLING
@@ -138,11 +153,15 @@ Index of this file:
// - For large numbers of rows, it is recommended you use ImGuiListClipper to only submit visible rows.
// ImGuiListClipper is reliant on the fact that rows are of equal height.
// See 'Demo->Tables->Vertical Scrolling' or 'Demo->Tables->Advanced' for a demo of using the clipper.
-// - Note that columns with the ImGuiTableColumnFlags_WidthAuto policy generally don't play well with using the clipper,
-// and by default a table with _ScrollX but without _Resizable will have columns default to _WidthAuto.
-// So, if you want to use the clipper, make sure to either enable _Resizable, either setup columns explicitly with _WidthFixed.
+// - Note that auto-resizing columns don't play well with using the clipper.
+// By default a table with _ScrollX but without _Resizable will have column auto-resize.
+// So, if you want to use the clipper, make sure to either enable _Resizable, either setup columns width explicitly with _WidthFixed.
//-----------------------------------------------------------------------------
// About clipping/culling of Columns in Tables:
+// - Both TableSetColumnIndex() and TableNextColumn() return true when the column is visible or performing
+// width measurements. Otherwise, you may skip submitting the contents of a cell/column, BUT ONLY if you know
+// it is not going to contribute to row height.
+// In many situations, you may skip submitting contents for every columns but one (e.g. the first one).
// - Case A: column is not hidden by user, and at least partially in sight (most common case).
// - Case B: column is clipped / out of sight (because of scrolling or parent ClipRect): TableNextColumn() return false as a hint but we still allow layout output.
// - Case C: column is hidden explicitly by the user (e.g. via the context menu, or _DefaultHide column flag, etc.).
@@ -240,9 +259,9 @@ inline ImGuiTableFlags TableFixFlags(ImGuiTableFlags flags, ImGuiWindow* outer_w
if (flags & ImGuiTableFlags_Resizable)
flags |= ImGuiTableFlags_BordersInnerV;
- // Adjust flags: disable NoHostExtendY if we have any scrolling going on
- if ((flags & ImGuiTableFlags_NoHostExtendY) && (flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) != 0)
- flags &= ~ImGuiTableFlags_NoHostExtendY;
+ // Adjust flags: disable NoHostExtendX/NoHostExtendY if we have any scrolling going on
+ if (flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY))
+ flags &= ~(ImGuiTableFlags_NoHostExtendX | ImGuiTableFlags_NoHostExtendY);
// Adjust flags: NoBordersInBodyUntilResize takes priority over NoBordersInBody
if (flags & ImGuiTableFlags_NoBordersInBodyUntilResize)
@@ -309,6 +328,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
IM_ASSERT(table->ColumnsCount == columns_count && "BeginTable(): Cannot change columns count mid-frame while preserving same ID");
// Fix flags
+ table->IsDefaultSizingPolicy = (flags & ImGuiTableFlags_SizingMask_) == 0;
flags = TableFixFlags(flags, outer_window);
// Initialize
@@ -320,7 +340,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
table->ColumnsCount = columns_count;
table->IsLayoutLocked = false;
table->InnerWidth = inner_width;
- table->IsOuterRectAutoFitX = (outer_size.x == 0.0f) && (use_child_window == false);
+ table->UserOuterSize = outer_size;
// When not using a child window, WorkRect.Max will grow as we append contents.
if (use_child_window)
@@ -341,6 +361,10 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
if (override_content_size.x != FLT_MAX || override_content_size.y != FLT_MAX)
SetNextWindowContentSize(ImVec2(override_content_size.x != FLT_MAX ? override_content_size.x : 0.0f, override_content_size.y != FLT_MAX ? override_content_size.y : 0.0f));
+ // Reset scroll if we are reactivating it
+ if ((table_last_flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) == 0)
+ SetNextWindowScroll(ImVec2(0.0f, 0.0f));
+
// Create scrolling region (without border and zero window padding)
ImGuiWindowFlags child_flags = (flags & ImGuiTableFlags_ScrollX) ? ImGuiWindowFlags_HorizontalScrollbar : ImGuiWindowFlags_None;
BeginChildEx(name, instance_id, outer_rect.GetSize(), false, child_flags);
@@ -601,10 +625,9 @@ static void TableSetupColumnFlags(ImGuiTable* table, ImGuiTableColumn* column, I
// Sizing Policy
if ((flags & ImGuiTableColumnFlags_WidthMask_) == 0)
{
- // FIXME-TABLE: clarify promotion to WidthAuto?
const ImGuiTableFlags table_sizing_policy = (table->Flags & ImGuiTableFlags_SizingMask_);
if (table_sizing_policy == ImGuiTableFlags_SizingFixedFit || table_sizing_policy == ImGuiTableFlags_SizingFixedSame)
- flags |= ((table->Flags & ImGuiTableFlags_Resizable) && !(flags & ImGuiTableColumnFlags_NoResize)) ? ImGuiTableColumnFlags_WidthFixed : ImGuiTableColumnFlags_WidthAuto;
+ flags |= ImGuiTableColumnFlags_WidthFixed;
else
flags |= ImGuiTableColumnFlags_WidthStretch;
}
@@ -614,7 +637,7 @@ static void TableSetupColumnFlags(ImGuiTable* table, ImGuiTableColumn* column, I
}
// Resize
- if ((flags & ImGuiTableColumnFlags_WidthAuto) != 0 || (table->Flags & ImGuiTableFlags_Resizable) == 0)
+ if ((table->Flags & ImGuiTableFlags_Resizable) == 0)
flags |= ImGuiTableColumnFlags_NoResize;
// Sorting
@@ -707,7 +730,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
table->IsSortSpecsDirty = true;
// Auto-fit unsized columns
- const bool start_auto_fit = (column->Flags & (ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthAuto)) ? (column->WidthRequest < 0.0f) : (column->StretchWeight < 0.0f);
+ const bool start_auto_fit = (column->Flags & ImGuiTableColumnFlags_WidthFixed) ? (column->WidthRequest < 0.0f) : (column->StretchWeight < 0.0f);
if (start_auto_fit)
column->AutoFitQueue = column->CannotSkipItemsQueue = (1 << 3) - 1; // Fit for three frames
@@ -777,7 +800,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
ImGuiTableColumn* column = &table->Columns[column_n];
const bool column_is_resizable = (column->Flags & ImGuiTableColumnFlags_NoResize) == 0;
- if (column->Flags & (ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthAuto))
+ if (column->Flags & ImGuiTableColumnFlags_WidthFixed)
{
// Apply same widths policy
float width_auto = column->WidthAuto;
@@ -786,7 +809,9 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
// Apply automatic width
// Latch initial size for fixed columns and update it constantly for auto-resizing column (unless clipped!)
- if ((column->AutoFitQueue != 0x00) || ((column->Flags & ImGuiTableColumnFlags_WidthAuto) && column->IsVisibleX) || ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && !column_is_resizable))
+ if (column->AutoFitQueue != 0x00)
+ column->WidthRequest = width_auto;
+ else if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && !column_is_resizable && (table->RequestOutputMaskByIndex & ((ImU64)1 << column_n)))
column->WidthRequest = width_auto;
// FIXME-TABLE: Increase minimum size during init frame to avoid biasing auto-fitting widgets
@@ -823,7 +848,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
}
table->ColumnsEnabledFixedCount = (ImGuiTableColumnIdx)count_fixed;
- // [Part 5] Apply final widths based on requested widths
+ // [Part 4] Apply final widths based on requested widths
const ImRect work_rect = table->WorkRect;
const float width_spacings = (table->OuterPaddingX * 2.0f) + (table->CellSpacingX1 + table->CellSpacingX2) * (table->ColumnsEnabledCount - 1);
const float width_avail = ((table->Flags & ImGuiTableFlags_ScrollX) && table->InnerWidth == 0.0f) ? table->InnerClipRect.GetWidth() : work_rect.GetWidth();
@@ -854,7 +879,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
table->ColumnsGivenWidth += column->WidthGiven;
}
- // [Part 6] Redistribute stretch remainder width due to rounding (remainder width is < 1.0f * number of Stretch column).
+ // [Part 5] Redistribute stretch remainder width due to rounding (remainder width is < 1.0f * number of Stretch column).
// Using right-to-left distribution (more likely to match resizing cursor).
if (width_remaining_for_stretched_columns >= 1.0f && !(table->Flags & ImGuiTableFlags_PreciseWidths))
for (int order_n = table->ColumnsCount - 1; stretch_sum_weights > 0.0f && width_remaining_for_stretched_columns >= 1.0f && order_n >= 0; order_n--)
@@ -874,7 +899,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
const ImRect mouse_hit_rect(table->OuterRect.Min.x, table->OuterRect.Min.y, table->OuterRect.Max.x, ImMax(table->OuterRect.Max.y, table->OuterRect.Min.y + table->LastOuterHeight));
const bool is_hovering_table = ItemHoverable(mouse_hit_rect, 0);
- // [Part 7] Setup final position, offset, skip/clip states and clipping rectangles, detect hovered column
+ // [Part 6] Setup final position, offset, skip/clip states and clipping rectangles, detect hovered column
// Process columns in their visible orders as we are comparing the visible order and adjusting host_clip_rect while looping.
int visible_n = 0;
bool offset_x_frozen = (table->FreezeColumnsCount > 0);
@@ -994,13 +1019,13 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
}
if (visible_n < table->FreezeColumnsCount)
- host_clip_rect.Min.x = ImMax(host_clip_rect.Min.x, column->MaxX + TABLE_BORDER_SIZE);
+ host_clip_rect.Min.x = ImClamp(column->MaxX + TABLE_BORDER_SIZE, host_clip_rect.Min.x, host_clip_rect.Max.x);
offset_x += column->WidthGiven + table->CellSpacingX1 + table->CellSpacingX2 + table->CellPaddingX * 2.0f;
visible_n++;
}
- // [Part 8] Detect/store when we are hovering the unused space after the right-most column (so e.g. context menus can react on it)
+ // [Part 7] Detect/store when we are hovering the unused space after the right-most column (so e.g. context menus can react on it)
// Clear Resizable flag if none of our column are actually resizable (either via an explicit _NoResize flag, either
// because of using _WidthAuto/_WidthStretch). This will hide the resizing option from the context menu.
const float unused_x1 = ImMax(table->WorkRect.Min.x, table->Columns[table->RightMostEnabledColumn].ClipRect.Max.x);
@@ -1012,12 +1037,12 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
if (has_resizable == false && (table->Flags & ImGuiTableFlags_Resizable))
table->Flags &= ~ImGuiTableFlags_Resizable;
- // [Part 9] Lock actual OuterRect/WorkRect right-most position.
+ // [Part 8] Lock actual OuterRect/WorkRect right-most position.
// This is done late to handle the case of fixed-columns tables not claiming more widths that they need.
// Because of this we are careful with uses of WorkRect and InnerClipRect before this point.
if (table->RightMostStretchedColumn != -1)
- table->IsOuterRectAutoFitX = false;
- if (table->IsOuterRectAutoFitX)
+ table->Flags &= ~ImGuiTableFlags_NoHostExtendX;
+ if (table->Flags & ImGuiTableFlags_NoHostExtendX)
{
table->OuterRect.Max.x = table->WorkRect.Max.x = unused_x1;
table->InnerClipRect.Max.x = ImMin(table->InnerClipRect.Max.x, unused_x1);
@@ -1026,17 +1051,17 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
table->BorderX1 = table->InnerClipRect.Min.x;// +((table->Flags & ImGuiTableFlags_BordersOuter) ? 0.0f : -1.0f);
table->BorderX2 = table->InnerClipRect.Max.x;// +((table->Flags & ImGuiTableFlags_BordersOuter) ? 0.0f : +1.0f);
- // [Part 10] Allocate draw channels and setup background cliprect
+ // [Part 9] Allocate draw channels and setup background cliprect
TableSetupDrawChannels(table);
- // [Part 11] Hit testing on borders
+ // [Part 10] Hit testing on borders
if (table->Flags & ImGuiTableFlags_Resizable)
TableUpdateBorders(table);
table->LastFirstRowHeight = 0.0f;
table->IsLayoutLocked = true;
table->IsUsingHeaders = false;
- // [Part 12] Context menu
+ // [Part 11] Context menu
if (table->IsContextPopupOpen && table->InstanceCurrent == table->InstanceInteracted)
{
const ImGuiID context_menu_id = ImHashStr("##ContextMenu", 0, table->ID);
@@ -1155,27 +1180,37 @@ void ImGui::EndTable()
// Context menu in columns body
if (flags & ImGuiTableFlags_ContextMenuInBody)
- if (table->HoveredColumnBody != -1 && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Right))
+ if (table->HoveredColumnBody != -1 && !IsAnyItemHovered() && IsMouseReleased(ImGuiMouseButton_Right))
TableOpenContextMenu((int)table->HoveredColumnBody);
// Finalize table height
inner_window->DC.PrevLineSize = table->HostBackupPrevLineSize;
inner_window->DC.CurrLineSize = table->HostBackupCurrLineSize;
inner_window->DC.CursorMaxPos = table->HostBackupCursorMaxPos;
+ const float inner_content_max_y = table->RowPosY2;
+ IM_ASSERT(table->RowPosY2 == inner_window->DC.CursorPos.y);
if (inner_window != outer_window)
- {
- // Both OuterRect/InnerRect are valid from BeginTable
- inner_window->DC.CursorMaxPos.y = table->RowPosY2;
- }
+ inner_window->DC.CursorMaxPos.y = inner_content_max_y;
else if (!(flags & ImGuiTableFlags_NoHostExtendY))
- {
- // Patch OuterRect/InnerRect height
- table->OuterRect.Max.y = table->InnerRect.Max.y = ImMax(table->OuterRect.Max.y, inner_window->DC.CursorPos.y);
- inner_window->DC.CursorMaxPos.y = table->RowPosY2;
- }
+ table->OuterRect.Max.y = table->InnerRect.Max.y = ImMax(table->OuterRect.Max.y, inner_content_max_y); // Patch OuterRect/InnerRect height
table->WorkRect.Max.y = ImMax(table->WorkRect.Max.y, table->OuterRect.Max.y);
table->LastOuterHeight = table->OuterRect.GetHeight();
+ // Setup inner scrolling range
+ // FIXME: This ideally should be done earlier, in BeginTable() SetNextWindowContentSize call, just like writing to inner_window->DC.CursorMaxPos.y,
+ // but since the later is likely to be impossible to do we'd rather update both axises together.
+ if (table->Flags & ImGuiTableFlags_ScrollX)
+ {
+ const float outer_padding_for_border = (table->Flags & ImGuiTableFlags_BordersOuterV) ? TABLE_BORDER_SIZE : 0.0f;
+ float max_pos_x = table->InnerWindow->DC.CursorMaxPos.x;
+ if (table->RightMostEnabledColumn != -1)
+ max_pos_x = ImMax(max_pos_x, table->Columns[table->RightMostEnabledColumn].WorkMaxX + table->CellPaddingX + table->OuterPaddingX - outer_padding_for_border);
+ if (table->ResizedColumn != -1)
+ max_pos_x = ImMax(max_pos_x, table->ResizeLockMinContentsX2);
+ table->InnerWindow->DC.CursorMaxPos.x = max_pos_x;
+ }
+
+ // Pop clipping rect
if (!(flags & ImGuiTableFlags_NoClip))
inner_window->DrawList->PopClipRect();
inner_window->ClipRect = inner_window->DrawList->_ClipRectStack.back();
@@ -1208,7 +1243,13 @@ void ImGui::EndTable()
table->ColumnsAutoFitWidth = width_spacings + (table->CellPaddingX * 2.0f) * table->ColumnsEnabledCount;
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
if (table->EnabledMaskByIndex & ((ImU64)1 << column_n))
- table->ColumnsAutoFitWidth += TableGetColumnWidthAuto(table, &table->Columns[column_n]);
+ {
+ ImGuiTableColumn* column = &table->Columns[column_n];
+ if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && !(column->Flags & ImGuiTableColumnFlags_NoResize))
+ table->ColumnsAutoFitWidth += column->WidthRequest;
+ else
+ table->ColumnsAutoFitWidth += TableGetColumnWidthAuto(table, column);
+ }
// Update scroll
if ((table->Flags & ImGuiTableFlags_ScrollX) == 0 && inner_window != outer_window)
@@ -1240,15 +1281,8 @@ void ImGui::EndTable()
IM_ASSERT_USER_ERROR(outer_window->DC.ItemWidthStack.Size >= table->HostBackupItemWidthStackSize, "Too many PopItemWidth!");
PopID();
- // Layout in outer window
- const float backup_outer_cursor_pos_x = outer_window->DC.CursorPos.x;
- const float backup_outer_max_pos_x = outer_window->DC.CursorMaxPos.x;
- const float backup_inner_max_pos_x = inner_window->DC.CursorMaxPos.x;
- float max_pos_x = backup_inner_max_pos_x;
- if (table->RightMostEnabledColumn != -1)
- max_pos_x = ImMax(max_pos_x, table->Columns[table->RightMostEnabledColumn].MaxX);
- if (table->ResizedColumn != -1)
- max_pos_x = ImMax(max_pos_x, table->ResizeLockMinContentsX2);
+ // Restore window data that we modified
+ const ImVec2 backup_outer_max_pos = outer_window->DC.CursorMaxPos;
inner_window->WorkRect = table->HostBackupWorkRect;
inner_window->ParentWorkRect = table->HostBackupParentWorkRect;
inner_window->SkipItems = table->HostSkipItems;
@@ -1256,28 +1290,48 @@ void ImGui::EndTable()
outer_window->DC.ItemWidth = table->HostBackupItemWidth;
outer_window->DC.ItemWidthStack.Size = table->HostBackupItemWidthStackSize;
outer_window->DC.ColumnsOffset = table->HostBackupColumnsOffset;
- const float outer_width = table->IsOuterRectAutoFitX ? table->WorkRect.GetWidth() : table->ColumnsAutoFitWidth;
+
+ // Layout in outer window
+ // (FIXME: To allow auto-fit and allow desirable effect of SameLine() we dissociate 'used' vs 'ideal' size by overriding
+ // CursorPosPrevLine and CursorMaxPos manually. That should be a more general layout feature, see same problem e.g. #3414)
if (inner_window != outer_window)
{
EndChild();
}
else
{
- ImVec2 item_size(outer_width, table->OuterRect.GetHeight());
- ItemSize(item_size);
+ ItemSize(table->OuterRect.GetSize());
+ ItemAdd(table->OuterRect, 0);
}
- // Override EndChild/ItemSize max extent with our own to enable auto-resize on the X axis when possible
- // FIXME-TABLE: This can be improved (e.g. for Fixed columns we don't want to auto AutoFitWidth? or propagate window auto-fit to table?)
- if (table->Flags & ImGuiTableFlags_ScrollX)
+ // Override declared contents width/height to enable auto-resize while not needlessly adding a scrollbar
+ if (table->Flags & ImGuiTableFlags_NoHostExtendX)
+ {
+ // FIXME-TABLE: Could we remove this section?
+ // ColumnsAutoFitWidth may be one frame ahead here since for Fixed+NoResize is calculated from latest contents
+ IM_ASSERT((table->Flags & ImGuiTableFlags_ScrollX) == 0);
+ outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth);
+ }
+ else if (table->UserOuterSize.x <= 0.0f)
+ {
+ const float decoration_size = (table->Flags & ImGuiTableFlags_ScrollX) ? inner_window->ScrollbarSizes.x : 0.0f;
+ outer_window->DC.IdealMaxPos.x = ImMax(outer_window->DC.IdealMaxPos.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth + decoration_size - table->UserOuterSize.x);
+ outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, ImMin(table->OuterRect.Max.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth));
+ }
+ else
+ {
+ outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, table->OuterRect.Max.x);
+ }
+ if (table->UserOuterSize.y <= 0.0f)
{
- inner_window->DC.CursorMaxPos.x = max_pos_x; // Set contents width for scrolling
- outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos_x, backup_outer_cursor_pos_x + table->ColumnsGivenWidth + inner_window->ScrollbarSizes.x); // For scrolling
+ const float decoration_size = (table->Flags & ImGuiTableFlags_ScrollY) ? inner_window->ScrollbarSizes.y : 0.0f;
+ outer_window->DC.IdealMaxPos.y = ImMax(outer_window->DC.IdealMaxPos.y, inner_content_max_y + decoration_size - table->UserOuterSize.y);
+ outer_window->DC.CursorMaxPos.y = ImMax(backup_outer_max_pos.y, ImMin(table->OuterRect.Max.y, inner_content_max_y));
}
else
{
- outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos_x, table->WorkRect.Min.x + outer_width); // For auto-fit
- outer_window->DC.CursorPosPrevLine.x = table->WorkRect.Max.x; // For consistent reaction to SameLine() // FIXME: Should be a feature of layout/ItemAdd
+ // OuterRect.Max.y may already have been pushed downward from the initial value (unless ImGuiTableFlags_NoHostExtendY is set)
+ outer_window->DC.CursorMaxPos.y = ImMax(backup_outer_max_pos.y, table->OuterRect.Max.y);
}
// Save settings
@@ -1292,7 +1346,8 @@ void ImGui::EndTable()
outer_window->DC.CurrentTableIdx = g.CurrentTable ? g.Tables.GetIndex(g.CurrentTable) : -1;
}
-// See "COLUMN SIZING POLICIES" comments at the top of this file
+// See "COLUMN SIZING POLICIES" comments at the top of this file
+// If (init_width_or_weight <= 0.0f) it is ignored
void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, float init_width_or_weight, ImGuiID user_id)
{
ImGuiContext& g = *GImGui;
@@ -1309,6 +1364,11 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
ImGuiTableColumn* column = &table->Columns[table->DeclColumnsCount];
table->DeclColumnsCount++;
+ // Assert when passing a width or weight if policy is entirely left to default, to avoid storing width into weight and vice-versa.
+ // Give a grace to users of ImGuiTableFlags_ScrollX.
+ if (table->IsDefaultSizingPolicy && (flags & ImGuiTableColumnFlags_WidthMask_) == 0 && (flags & ImGuiTableFlags_ScrollX) == 0)
+ IM_ASSERT(init_width_or_weight <= 0.0f && "Can only specify width/weight if sizing policy is set explicitely in either Table or Column.");
+
// When passing a width automatically enforce WidthFixed policy
// (whereas TableSetupColumnFlags would default to WidthAuto if table is not Resizable)
if ((flags & ImGuiTableColumnFlags_WidthMask_) == 0 && init_width_or_weight > 0.0f)
@@ -1320,8 +1380,6 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
flags = column->Flags;
// Initialize defaults
- if (flags & ImGuiTableColumnFlags_WidthStretch)
- IM_ASSERT(init_width_or_weight != 0.0f && "Need to provide a valid weight!");
column->InitStretchWeightOrWidth = init_width_or_weight;
if (table->IsInitializing)
{
@@ -1436,7 +1494,7 @@ ImRect ImGui::TableGetCellBgRect(const ImGuiTable* table, int column_n)
// Return the resizing ID for the right-side of the given column.
ImGuiID ImGui::TableGetColumnResizeID(const ImGuiTable* table, int column_n, int instance_no)
{
- IM_ASSERT(column_n < table->ColumnsCount);
+ IM_ASSERT(column_n >= 0 && column_n < table->ColumnsCount);
ImGuiID id = table->ID + 1 + (instance_no * table->ColumnsCount) + column_n;
return id;
}
@@ -1451,17 +1509,17 @@ int ImGui::TableGetHoveredColumn()
return (int)table->HoveredColumnBody;
}
-void ImGui::TableSetBgColor(ImGuiTableBgTarget bg_target, ImU32 color, int column_n)
+void ImGui::TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n)
{
ImGuiContext& g = *GImGui;
ImGuiTable* table = g.CurrentTable;
- IM_ASSERT(bg_target != ImGuiTableBgTarget_None);
+ IM_ASSERT(target != ImGuiTableBgTarget_None);
if (color == IM_COL32_DISABLE)
color = 0;
// We cannot draw neither the cell or row background immediately as we don't know the row height at this point in time.
- switch (bg_target)
+ switch (target)
{
case ImGuiTableBgTarget_CellBg:
{
@@ -1484,7 +1542,7 @@ void ImGui::TableSetBgColor(ImGuiTableBgTarget bg_target, ImU32 color, int colum
if (table->RowPosY1 > table->InnerClipRect.Max.y) // Discard
return;
IM_ASSERT(column_n == -1);
- int bg_idx = (bg_target == ImGuiTableBgTarget_RowBg1) ? 1 : 0;
+ int bg_idx = (target == ImGuiTableBgTarget_RowBg1) ? 1 : 0;
table->RowBgColor[bg_idx] = color;
break;
}
@@ -2249,8 +2307,8 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
g.DrawChannelsTempMergeBuffer.resize(splitter->_Count - LEADING_DRAW_CHANNELS); // Use shared temporary storage so the allocation gets amortized
ImDrawChannel* dst_tmp = g.DrawChannelsTempMergeBuffer.Data;
ImBitArray<IMGUI_TABLE_MAX_DRAW_CHANNELS> remaining_mask; // We need 132-bit of storage
- remaining_mask.ClearBits();
- remaining_mask.SetBitRange(LEADING_DRAW_CHANNELS, splitter->_Count - 1);
+ remaining_mask.ClearAllBits();
+ remaining_mask.SetBitRange(LEADING_DRAW_CHANNELS, splitter->_Count);
remaining_mask.ClearBit(table->Bg2DrawChannelUnfrozen);
IM_ASSERT(has_freeze_v == false || table->Bg2DrawChannelUnfrozen != TABLE_DRAW_CHANNEL_BG2_FROZEN);
int remaining_count = splitter->_Count - (has_freeze_v ? LEADING_DRAW_CHANNELS + 1 : LEADING_DRAW_CHANNELS);
@@ -2324,7 +2382,7 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
void ImGui::TableDrawBorders(ImGuiTable* table)
{
ImGuiWindow* inner_window = table->InnerWindow;
- if (inner_window->Hidden || !table->HostClipRect.Overlaps(table->InnerClipRect))
+ if (!table->OuterWindow->ClipRect.Overlaps(table->OuterRect))
return;
ImDrawList* inner_drawlist = inner_window->DrawList;
@@ -2335,7 +2393,7 @@ void ImGui::TableDrawBorders(ImGuiTable* table)
const float border_size = TABLE_BORDER_SIZE;
const float draw_y1 = table->InnerRect.Min.y;
const float draw_y2_body = table->InnerRect.Max.y;
- const float draw_y2_head = table->IsUsingHeaders ? ((table->FreezeRowsCount >= 1 ? table->OuterRect.Min.y : table->WorkRect.Min.y) + table->LastFirstRowHeight) : draw_y1;
+ const float draw_y2_head = table->IsUsingHeaders ? ImMin(table->InnerRect.Max.y, (table->FreezeRowsCount >= 1 ? table->InnerRect.Min.y : table->WorkRect.Min.y) + table->LastFirstRowHeight) : draw_y1;
if (table->Flags & ImGuiTableFlags_BordersInnerV)
{
for (int order_n = 0; order_n < table->ColumnsCount; order_n++)
@@ -2349,11 +2407,12 @@ void ImGui::TableDrawBorders(ImGuiTable* table)
const bool is_resized = (table->ResizedColumn == column_n) && (table->InstanceInteracted == table->InstanceCurrent);
const bool is_resizable = (column->Flags & (ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_NoDirectResize_)) == 0;
const bool is_frozen_separator = (table->FreezeColumnsCount != -1 && table->FreezeColumnsCount == order_n + 1);
-
if (column->MaxX > table->InnerClipRect.Max.x && !is_resized)
continue;
+
+ // Decide whether right-most column is visible
if (column->NextEnabledColumn == -1 && !is_resizable)
- if ((table->Flags & ImGuiTableFlags_SizingMask_) != ImGuiTableFlags_SizingFixedSame || table->IsOuterRectAutoFitX)
+ if ((table->Flags & ImGuiTableFlags_SizingMask_) != ImGuiTableFlags_SizingFixedSame || (table->Flags & ImGuiTableFlags_NoHostExtendX))
continue;
if (column->MaxX <= column->ClipRect.Min.x) // FIXME-TABLE FIXME-STYLE: Assume BorderSize==1, this is problematic if we want to increase the border size..
continue;
@@ -3367,7 +3426,7 @@ void ImGui::DebugNodeTable(ImGuiTable* table)
"WidthGiven: %.1f, Request/Auto: %.1f/%.1f, StretchWeight: %.3f (%.1f%%)\n"
"MinX: %.1f, MaxX: %.1f (%+.1f), ClipRect: %.1f to %.1f (+%.1f)\n"
"ContentWidth: %.1f,%.1f, HeadersUsed/Ideal %.1f/%.1f\n"
- "Sort: %d%s, UserID: 0x%08X, Flags: 0x%04X: %s%s%s%s..",
+ "Sort: %d%s, UserID: 0x%08X, Flags: 0x%04X: %s%s%s..",
n, column->DisplayOrder, name, column->MinX - table->WorkRect.Min.x, column->MaxX - table->WorkRect.Min.x, (n < table->FreezeColumnsRequest) ? " (Frozen)" : "",
column->IsEnabled, column->IsVisibleX, column->IsVisibleY, column->IsRequestOutput, column->IsSkipItems, column->DrawChannelFrozen, column->DrawChannelUnfrozen,
column->WidthGiven, column->WidthRequest, column->WidthAuto, column->StretchWeight, column->StretchWeight > 0.0f ? (column->StretchWeight / sum_weights) * 100.0f : 0.0f,
@@ -3376,7 +3435,6 @@ void ImGui::DebugNodeTable(ImGuiTable* table)
column->SortOrder, (column->SortDirection == ImGuiSortDirection_Ascending) ? " (Asc)" : (column->SortDirection == ImGuiSortDirection_Descending) ? " (Des)" : "", column->UserID, column->Flags,
(column->Flags & ImGuiTableColumnFlags_WidthStretch) ? "WidthStretch " : "",
(column->Flags & ImGuiTableColumnFlags_WidthFixed) ? "WidthFixed " : "",
- (column->Flags & ImGuiTableColumnFlags_WidthAuto) ? "WidthAuto " : "",
(column->Flags & ImGuiTableColumnFlags_NoResize) ? "NoResize " : "");
Bullet();
Selectable(buf);
diff --git a/imgui/imgui_widgets.cpp b/imgui/imgui_widgets.cpp
index 3bf7254f..92964bd4 100644
--- a/imgui/imgui_widgets.cpp
+++ b/imgui/imgui_widgets.cpp
@@ -1,4 +1,4 @@
-// dear imgui, v1.80 WIP
+// dear imgui, v1.80
// (widgets code)
/*
@@ -86,6 +86,10 @@ Index of this file:
// Data
//-------------------------------------------------------------------------
+// Widgets
+static const float DRAGDROP_HOLD_TO_OPEN_TIMER = 0.70f; // Time for drag-hold to activate items accepting the ImGuiButtonFlags_PressedOnDragDropHold button behavior.
+static const float DRAG_MOUSE_THRESHOLD_FACTOR = 0.50f; // Multiplier for the default value of io.MouseDragThreshold to make DragFloat/DragInt react faster to mouse drags.
+
// Those MIN/MAX values are not define because we need to point to them
static const signed char IM_S8_MIN = -128;
static const signed char IM_S8_MAX = 127;
@@ -516,10 +520,9 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
if (g.DragDropActive && (flags & ImGuiButtonFlags_PressedOnDragDropHold) && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoHoldToOpenOthers))
if (IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem))
{
- const float DRAG_DROP_HOLD_TIMER = 0.70f;
hovered = true;
SetHoveredID(id);
- if (CalcTypematicRepeatAmount(g.HoveredIdTimer + 0.0001f - g.IO.DeltaTime, g.HoveredIdTimer + 0.0001f, DRAG_DROP_HOLD_TIMER, 0.00f))
+ if (CalcTypematicRepeatAmount(g.HoveredIdTimer + 0.0001f - g.IO.DeltaTime, g.HoveredIdTimer + 0.0001f, DRAGDROP_HOLD_TO_OPEN_TIMER, 0.00f))
{
pressed = true;
g.DragDropHoldJustPressedId = id;
@@ -1621,7 +1624,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
if (popup_window->WasActive)
{
// Always override 'AutoPosLastDirection' to not leave a chance for a past value to affect us.
- ImVec2 size_expected = CalcWindowExpectedSize(popup_window);
+ ImVec2 size_expected = CalcWindowNextAutoFitSize(popup_window);
if (flags & ImGuiComboFlags_PopupAlignLeft)
popup_window->AutoPosLastDirection = ImGuiDir_Left; // "Below, Toward Left"
else
@@ -2115,7 +2118,7 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const
// Inputs accumulates into g.DragCurrentAccum, which is flushed into the current value as soon as it makes a difference with our precision settings
float adjust_delta = 0.0f;
- if (g.ActiveIdSource == ImGuiInputSource_Mouse && IsMousePosValid() && g.IO.MouseDragMaxDistanceSqr[0] > 1.0f * 1.0f)
+ if (g.ActiveIdSource == ImGuiInputSource_Mouse && IsMousePosValid() && IsMouseDragPastThreshold(0, g.IO.MouseDragThreshold * DRAG_MOUSE_THRESHOLD_FACTOR))
{
adjust_delta = g.IO.MouseDelta[axis];
if (g.IO.KeyAlt)
@@ -2278,7 +2281,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
else if (data_type == ImGuiDataType_S32 && strcmp(format, "%d") != 0) // (FIXME-LEGACY: Patch old "%.0f" format string to use "%d", read function more details.)
format = PatchFormatStringFloatToInt(format);
- // Tabbing or CTRL-clicking on Drag turns it into an input box
+ // Tabbing or CTRL-clicking on Drag turns it into an InputText
const bool hovered = ItemHoverable(frame_bb, id);
const bool temp_input_allowed = (flags & ImGuiSliderFlags_NoInput) == 0;
bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
@@ -2299,6 +2302,15 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
FocusableItemUnregister(window);
}
}
+ // Experimental: simple click (without moving) turns Drag into an InputText
+ // FIXME: Currently polling ImGuiConfigFlags_IsTouchScreen, may either poll an hypothetical ImGuiBackendFlags_HasKeyboard and/or an explicit drag settings.
+ if (g.IO.ConfigDragClickToInputText && temp_input_allowed && !temp_input_is_active)
+ if (g.ActiveId == id && hovered && g.IO.MouseReleased[0] && !IsMouseDragPastThreshold(0, g.IO.MouseDragThreshold * DRAG_MOUSE_THRESHOLD_FACTOR))
+ {
+ g.NavInputId = id;
+ temp_input_is_active = true;
+ FocusableItemUnregister(window);
+ }
}
if (temp_input_is_active)
@@ -5908,21 +5920,25 @@ bool ImGui::CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags)
return TreeNodeBehavior(window->GetID(label), flags | ImGuiTreeNodeFlags_CollapsingHeader, label);
}
-bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags flags)
+// p_visible == NULL : regular collapsing header
+// p_visible != NULL && *p_visible == true : show a small close button on the corner of the header, clicking the button will set *p_visible = false
+// p_visible != NULL && *p_visible == false : do not show the header at all
+// Do not mistake this with the Open state of the header itself, which you can adjust with SetNextItemOpen() or ImGuiTreeNodeFlags_DefaultOpen.
+bool ImGui::CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFlags flags)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
return false;
- if (p_open && !*p_open)
+ if (p_visible && !*p_visible)
return false;
ImGuiID id = window->GetID(label);
flags |= ImGuiTreeNodeFlags_CollapsingHeader;
- if (p_open)
+ if (p_visible)
flags |= ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_ClipLabelForTrailingButton;
bool is_open = TreeNodeBehavior(id, flags, label);
- if (p_open != NULL)
+ if (p_visible != NULL)
{
// Create a small overlapping close button
// FIXME: We can evolve this into user accessible helpers to add extra buttons on title bars, headers, etc.
@@ -5934,7 +5950,7 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags
float button_y = window->DC.LastItemRect.Min.y;
ImGuiID close_button_id = GetIDWithSeed("#CLOSE", NULL, id);
if (CloseButton(close_button_id, ImVec2(button_x, button_y)))
- *p_open = false;
+ *p_visible = false;
last_item_backup.Restore();
}
@@ -6239,6 +6255,11 @@ bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(v
// - PlotLines()
// - PlotHistogram()
//-------------------------------------------------------------------------
+// Plot/Graph widgets are not very good.
+// Consider writing your own, or using a third-party one, see:
+// - ImPlot https://github.com/epezent/implot
+// - others https://github.com/ocornut/imgui/wiki/Useful-Widgets
+//-------------------------------------------------------------------------
int ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 frame_size)
{
@@ -7275,7 +7296,8 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
// Actual layout in host window (we don't do it in BeginTabBar() so as not to waste an extra frame)
ImGuiWindow* window = g.CurrentWindow;
window->DC.CursorPos = tab_bar->BarRect.Min;
- ItemSize(ImVec2(tab_bar->WidthAllTabsIdeal, tab_bar->BarRect.GetHeight()), tab_bar->FramePadding.y);
+ ItemSize(ImVec2(tab_bar->WidthAllTabs, tab_bar->BarRect.GetHeight()), tab_bar->FramePadding.y);
+ window->DC.IdealMaxPos.x = ImMax(window->DC.IdealMaxPos.x, tab_bar->BarRect.Min.x + tab_bar->WidthAllTabsIdeal);
}
// Dockable uses Name/ID in the global namespace. Non-dockable items use the ID stack.