1
0
mirror of https://github.com/ocornut/imgui.git synced 2024-11-14 19:17:48 +01:00

Tables: TableSetupColumn() user id uses ImGuiID as intended (typedef ImU32). internals: added GetCurrentTable(), LeftMostEnabledColumn. Demo/docs tweaks.

This commit is contained in:
ocornut 2021-02-16 16:53:56 +01:00
parent 9576dfd5e7
commit b47aa46d81
5 changed files with 34 additions and 20 deletions

View File

@ -9,13 +9,13 @@ your application or engine to easily integrate Dear ImGui.** Each backend is typ
e.g. Windows ([imgui_impl_win32.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_win32.cpp)), GLFW ([imgui_impl_glfw.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_glfw.cpp)), SDL2 ([imgui_impl_sdl.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_sdl.cpp)), etc. e.g. Windows ([imgui_impl_win32.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_win32.cpp)), GLFW ([imgui_impl_glfw.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_glfw.cpp)), SDL2 ([imgui_impl_sdl.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_sdl.cpp)), etc.
- The 'Renderer' backends are in charge of: creating atlas texture, rendering imgui draw data.<BR> - The 'Renderer' backends are in charge of: creating atlas texture, rendering imgui draw data.<BR>
e.g. DirectX11 ([imgui_impl_dx11.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_dx11.cpp)), OpenGL/WebGL ([imgui_impl_opengl3.cpp]((https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_opengl3.cpp)), Vulkan ([imgui_impl_vulkan.cpp]((https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_vulkan.cpp)), etc. e.g. DirectX11 ([imgui_impl_dx11.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_dx11.cpp)), OpenGL/WebGL ([imgui_impl_opengl3.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_opengl3.cpp), Vulkan ([imgui_impl_vulkan.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_vulkan.cpp), etc.
- For some high-level frameworks, a single backend usually handle both 'Platform' and 'Renderer' parts.<BR> - For some high-level frameworks, a single backend usually handle both 'Platform' and 'Renderer' parts.<BR>
e.g. Allegro 5 ([imgui_impl_allegro5.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_allegro5.cpp)), Marmalade ([imgui_impl_marmalade.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_marmalade.cpp)). If you end up creating a custom backend for your engine, you may want to do the same. e.g. Allegro 5 ([imgui_impl_allegro5.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_allegro5.cpp)), Marmalade ([imgui_impl_marmalade.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_marmalade.cpp)). If you end up creating a custom backend for your engine, you may want to do the same.
An application usually combines 1 Platform backend + 1 Renderer backend + main Dear ImGui sources. An application usually combines 1 Platform backend + 1 Renderer backend + main Dear ImGui sources.
For example, the [example_win32_directx11](https://github.com/ocornut/imgui/tree/master/examples/example_win32_directx11) application combines imgui_impl_win32.cpp + imgui_impl_dx11.cpp. See [EXAMPLES.MD](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md) for details. For example, the [example_win32_directx11](https://github.com/ocornut/imgui/tree/master/examples/example_win32_directx11) application combines imgui_impl_win32.cpp + imgui_impl_dx11.cpp. There are 20+ examples in the [examples/](https://github.com/ocornut/imgui/blob/master/examples/) folder. See [EXAMPLES.MD](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md) for details.
### What are backends ### What are backends
@ -36,7 +36,7 @@ Dear ImGui is highly portable and only requires a few things to run and render,
- Optional: multi-viewports support. - Optional: multi-viewports support.
etc. etc.
This is essentially what each backends are doing + obligatory portability cruft. This is essentially what each backends are doing + obligatory portability cruft. Using default backends ensure you can get all those features including the ones that would be harder to implement on your side (e.g. multi-viewports support).
It is important to understand the difference between the core Dear ImGui library (files in the root folder) It is important to understand the difference between the core Dear ImGui library (files in the root folder)
and backends which we are describing here (backends/ folder). and backends which we are describing here (backends/ folder).
@ -46,6 +46,11 @@ and backends which we are describing here (backends/ folder).
e.g. you can get creative and use software rendering or render remotely on a different machine. e.g. you can get creative and use software rendering or render remotely on a different machine.
### Integrating a backend
See "Getting Started" section of [EXAMPLES.MD](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md) for more details.
### List of backends ### List of backends
In the [backends/](https://github.com/ocornut/imgui/blob/master/backends) folder: In the [backends/](https://github.com/ocornut/imgui/blob/master/backends) folder:

View File

@ -701,7 +701,7 @@ namespace ImGui
// - You may manually submit headers using TableNextRow() + TableHeader() calls, but this is only useful in // - 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). // some advanced use cases (e.g. adding custom widgets in header row).
// - Use TableSetupScrollFreeze() to lock columns/rows so they stay visible when scrolled. // - 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 TableSetupColumn(const char* label, ImGuiTableColumnFlags flags = 0, float init_width_or_weight = 0.0f, ImGuiID user_id = 0);
IMGUI_API void TableSetupScrollFreeze(int cols, int rows); // lock columns/rows so they stay visible when scrolled. 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 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) IMGUI_API void TableHeader(const char* label); // submit one header cell manually (rarely used)
@ -711,7 +711,7 @@ namespace ImGui
// since last call, or the first time. Make sure to set 'SpecsDirty = false' after sorting, else you may // since last call, or the first time. Make sure to set 'SpecsDirty = false' after sorting, else you may
// wastefully sort your data every frame! // wastefully sort your data every frame!
// - Lifetime: don't hold on this pointer over multiple frames or past any subsequent call to BeginTable(). // - 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). IMGUI_API ImGuiTableSortSpecs* TableGetSortSpecs(); // get latest sort specs for the table (NULL if not sorting).
// Tables: Miscellaneous functions // Tables: Miscellaneous functions
// - Functions args 'int column_n' treat the default value of -1 as the same as passing the current column index. // - 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 TableGetColumnCount(); // return number of columns (value passed to BeginTable)

View File

@ -4856,6 +4856,9 @@ static void ShowDemoWindowTables()
ImGui::TreePop(); ImGui::TreePop();
} }
// In this example we'll expose most table flags and settings.
// For specific flags and settings refer to the corresponding section for more detailed explanation.
// This section is mostly useful to experiment with combining certain flags or settings with each others.
//ImGui::SetNextItemOpen(true, ImGuiCond_Once); // [DEBUG] //ImGui::SetNextItemOpen(true, ImGuiCond_Once); // [DEBUG]
if (open_action != -1) if (open_action != -1)
ImGui::SetNextItemOpen(open_action != 0); ImGui::SetNextItemOpen(open_action != 0);
@ -4994,7 +4997,7 @@ static void ShowDemoWindowTables()
ImGui::TreePop(); ImGui::TreePop();
} }
// Recreate/reset item list if we changed the number of items // Update item list if we changed the number of items
static ImVector<MyItem> items; static ImVector<MyItem> items;
static ImVector<int> selection; static ImVector<int> selection;
static bool items_need_sort = false; static bool items_need_sort = false;
@ -5016,6 +5019,7 @@ static void ShowDemoWindowTables()
ImVec2 table_scroll_cur, table_scroll_max; // For debug display ImVec2 table_scroll_cur, table_scroll_max; // For debug display
const ImDrawList* table_draw_list = NULL; // " const ImDrawList* table_draw_list = NULL; // "
// Submit table
const float inner_width_to_use = (flags & ImGuiTableFlags_ScrollX) ? inner_width_with_scroll : 0.0f; const float inner_width_to_use = (flags & ImGuiTableFlags_ScrollX) ? inner_width_with_scroll : 0.0f;
if (ImGui::BeginTable("table_advanced", 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))
{ {
@ -5074,9 +5078,9 @@ static void ShowDemoWindowTables()
const bool item_is_selected = selection.contains(item->ID); const bool item_is_selected = selection.contains(item->ID);
ImGui::PushID(item->ID); ImGui::PushID(item->ID);
ImGui::TableNextRow(ImGuiTableRowFlags_None, row_min_height); ImGui::TableNextRow(ImGuiTableRowFlags_None, row_min_height);
ImGui::TableNextColumn();
// For the demo purpose we can select among different type of items submitted in the first column // For the demo purpose we can select among different type of items submitted in the first column
ImGui::TableSetColumnIndex(0);
char label[32]; char label[32];
sprintf(label, "%04d", item->ID); sprintf(label, "%04d", item->ID);
if (contents_type == CT_Text) if (contents_type == CT_Text)
@ -5107,14 +5111,14 @@ static void ShowDemoWindowTables()
} }
} }
if (ImGui::TableNextColumn()) if (ImGui::TableSetColumnIndex(1))
ImGui::TextUnformatted(item->Name); ImGui::TextUnformatted(item->Name);
// Here we demonstrate marking our data set as needing to be sorted again if we modified a quantity, // Here we demonstrate marking our data set as needing to be sorted again if we modified a quantity,
// and we are currently sorting on the column showing the Quantity. // and we are currently sorting on the column showing the Quantity.
// To avoid triggering a sort while holding the button, we only trigger it when the button has been released. // To avoid triggering a sort while holding the button, we only trigger it when the button has been released.
// You will probably need a more advanced system in your code if you want to automatically sort when a specific entry changes. // You will probably need a more advanced system in your code if you want to automatically sort when a specific entry changes.
if (ImGui::TableNextColumn()) if (ImGui::TableSetColumnIndex(2))
{ {
if (ImGui::SmallButton("Chop")) { item->Quantity += 1; } if (ImGui::SmallButton("Chop")) { item->Quantity += 1; }
if (sorts_specs_using_quantity && ImGui::IsItemDeactivated()) { items_need_sort = true; } if (sorts_specs_using_quantity && ImGui::IsItemDeactivated()) { items_need_sort = true; }
@ -5123,16 +5127,16 @@ static void ShowDemoWindowTables()
if (sorts_specs_using_quantity && ImGui::IsItemDeactivated()) { items_need_sort = true; } if (sorts_specs_using_quantity && ImGui::IsItemDeactivated()) { items_need_sort = true; }
} }
if (ImGui::TableNextColumn()) if (ImGui::TableSetColumnIndex(3))
ImGui::Text("%d", item->Quantity); ImGui::Text("%d", item->Quantity);
ImGui::TableNextColumn(); ImGui::TableSetColumnIndex(4);
if (show_wrapped_text) if (show_wrapped_text)
ImGui::TextWrapped("Lorem ipsum dolor sit amet"); ImGui::TextWrapped("Lorem ipsum dolor sit amet");
else else
ImGui::Text("Lorem ipsum dolor sit amet"); ImGui::Text("Lorem ipsum dolor sit amet");
if (ImGui::TableNextColumn()) if (ImGui::TableSetColumnIndex(5))
ImGui::Text("1234"); ImGui::Text("1234");
ImGui::PopID(); ImGui::PopID();

View File

@ -2091,9 +2091,10 @@ struct ImGuiTable
ImGuiTableColumnIdx HeldHeaderColumn; // Index of column header being held. ImGuiTableColumnIdx HeldHeaderColumn; // Index of column header being held.
ImGuiTableColumnIdx ReorderColumn; // Index of column being reordered. (not cleared) ImGuiTableColumnIdx ReorderColumn; // Index of column being reordered. (not cleared)
ImGuiTableColumnIdx ReorderColumnDir; // -1 or +1 ImGuiTableColumnIdx ReorderColumnDir; // -1 or +1
ImGuiTableColumnIdx LeftMostEnabledColumn; // Index of left-most non-hidden column.
ImGuiTableColumnIdx RightMostEnabledColumn; // Index of right-most non-hidden column.
ImGuiTableColumnIdx LeftMostStretchedColumn; // Index of left-most stretched column. ImGuiTableColumnIdx LeftMostStretchedColumn; // Index of left-most stretched column.
ImGuiTableColumnIdx RightMostStretchedColumn; // Index of right-most stretched column. ImGuiTableColumnIdx RightMostStretchedColumn; // Index of right-most stretched column.
ImGuiTableColumnIdx RightMostEnabledColumn; // Index of right-most non-hidden column.
ImGuiTableColumnIdx ContextPopupColumn; // Column right-clicked on, of -1 if opening context menu from a neutral/empty spot ImGuiTableColumnIdx ContextPopupColumn; // Column right-clicked on, of -1 if opening context menu from a neutral/empty spot
ImGuiTableColumnIdx FreezeRowsRequest; // Requested frozen rows count ImGuiTableColumnIdx FreezeRowsRequest; // Requested frozen rows count
ImGuiTableColumnIdx FreezeRowsCount; // Actual frozen row count (== FreezeRowsRequest, or == 0 when no scrolling offset) ImGuiTableColumnIdx FreezeRowsCount; // Actual frozen row count (== FreezeRowsRequest, or == 0 when no scrolling offset)
@ -2349,6 +2350,7 @@ namespace ImGui
IMGUI_API void TablePopBackgroundChannel(); IMGUI_API void TablePopBackgroundChannel();
// Tables: Internals // Tables: Internals
inline ImGuiTable* GetCurrentTable() { ImGuiContext& g = *GImGui; return g.CurrentTable; }
IMGUI_API ImGuiTable* TableFindByID(ImGuiID id); IMGUI_API ImGuiTable* TableFindByID(ImGuiID id);
IMGUI_API bool BeginTableEx(const char* name, ImGuiID id, int columns_count, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(0, 0), float inner_width = 0.0f); IMGUI_API bool BeginTableEx(const char* name, ImGuiID id, int columns_count, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(0, 0), float inner_width = 0.0f);
IMGUI_API void TableBeginInitMemory(ImGuiTable* table, int columns_count); IMGUI_API void TableBeginInitMemory(ImGuiTable* table, int columns_count);

View File

@ -687,13 +687,14 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
table->ColumnsEnabledCount = 0; table->ColumnsEnabledCount = 0;
table->EnabledMaskByIndex = 0x00; table->EnabledMaskByIndex = 0x00;
table->EnabledMaskByDisplayOrder = 0x00; table->EnabledMaskByDisplayOrder = 0x00;
table->LeftMostEnabledColumn = -1;
table->MinColumnWidth = ImMax(1.0f, g.Style.FramePadding.x * 1.0f); // g.Style.ColumnsMinSpacing; // FIXME-TABLE table->MinColumnWidth = ImMax(1.0f, g.Style.FramePadding.x * 1.0f); // g.Style.ColumnsMinSpacing; // FIXME-TABLE
// [Part 1] Apply/lock Enabled and Order states. Calculate auto/ideal width for columns. Count fixed/stretch columns. // [Part 1] Apply/lock Enabled and Order states. Calculate auto/ideal width for columns. Count fixed/stretch columns.
// Process columns in their visible orders as we are building the Prev/Next indices. // Process columns in their visible orders as we are building the Prev/Next indices.
int count_fixed = 0; // Number of columns that have fixed sizing policies int count_fixed = 0; // Number of columns that have fixed sizing policies
int count_stretch = 0; // Number of columns that have stretch sizing policies int count_stretch = 0; // Number of columns that have stretch sizing policies
int last_visible_column_idx = -1; int prev_visible_column_idx = -1;
bool has_auto_fit_request = false; bool has_auto_fit_request = false;
bool has_resizable = false; bool has_resizable = false;
float stretch_sum_width_auto = 0.0f; float stretch_sum_width_auto = 0.0f;
@ -741,14 +742,16 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
} }
// Mark as enabled and link to previous/next enabled column // Mark as enabled and link to previous/next enabled column
column->PrevEnabledColumn = (ImGuiTableColumnIdx)last_visible_column_idx; column->PrevEnabledColumn = (ImGuiTableColumnIdx)prev_visible_column_idx;
column->NextEnabledColumn = -1; column->NextEnabledColumn = -1;
if (last_visible_column_idx != -1) if (prev_visible_column_idx != -1)
table->Columns[last_visible_column_idx].NextEnabledColumn = (ImGuiTableColumnIdx)column_n; table->Columns[prev_visible_column_idx].NextEnabledColumn = (ImGuiTableColumnIdx)column_n;
else
table->LeftMostEnabledColumn = (ImGuiTableColumnIdx)column_n;
column->IndexWithinEnabledSet = table->ColumnsEnabledCount++; column->IndexWithinEnabledSet = table->ColumnsEnabledCount++;
table->EnabledMaskByIndex |= (ImU64)1 << column_n; table->EnabledMaskByIndex |= (ImU64)1 << column_n;
table->EnabledMaskByDisplayOrder |= (ImU64)1 << column->DisplayOrder; table->EnabledMaskByDisplayOrder |= (ImU64)1 << column->DisplayOrder;
last_visible_column_idx = column_n; prev_visible_column_idx = column_n;
IM_ASSERT(column->IndexWithinEnabledSet <= column->DisplayOrder); IM_ASSERT(column->IndexWithinEnabledSet <= column->DisplayOrder);
// Calculate ideal/auto column width (that's the width required for all contents to be visible without clipping) // Calculate ideal/auto column width (that's the width required for all contents to be visible without clipping)
@ -778,8 +781,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
} }
if ((table->Flags & ImGuiTableFlags_Sortable) && table->SortSpecsCount == 0 && !(table->Flags & ImGuiTableFlags_SortTristate)) if ((table->Flags & ImGuiTableFlags_Sortable) && table->SortSpecsCount == 0 && !(table->Flags & ImGuiTableFlags_SortTristate))
table->IsSortSpecsDirty = true; table->IsSortSpecsDirty = true;
table->RightMostEnabledColumn = (ImGuiTableColumnIdx)last_visible_column_idx; table->RightMostEnabledColumn = (ImGuiTableColumnIdx)prev_visible_column_idx;
IM_ASSERT(table->RightMostEnabledColumn >= 0); IM_ASSERT(table->LeftMostEnabledColumn >= 0 && table->RightMostEnabledColumn >= 0);
// [Part 2] Disable child window clipping while fitting columns. This is not strictly necessary but makes it possible // [Part 2] Disable child window clipping while fitting columns. This is not strictly necessary but makes it possible
// to avoid the column fitting having to wait until the first visible frame of the child container (may or not be a good thing). // to avoid the column fitting having to wait until the first visible frame of the child container (may or not be a good thing).