mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-15 01:17:00 +00:00
Tables: Allow hot-reload of settings (merge policy), tidying up settings code
This commit is contained in:
parent
9b6d0fdb7a
commit
95c273618e
10
imgui.cpp
10
imgui.cpp
@ -3970,15 +3970,7 @@ void ImGui::Initialize(ImGuiContext* context)
|
|||||||
|
|
||||||
#ifdef IMGUI_HAS_TABLE
|
#ifdef IMGUI_HAS_TABLE
|
||||||
// Add .ini handle for ImGuiTable type
|
// Add .ini handle for ImGuiTable type
|
||||||
{
|
TableInstallSettingsHandler(context);
|
||||||
ImGuiSettingsHandler ini_handler;
|
|
||||||
ini_handler.TypeName = "Table";
|
|
||||||
ini_handler.TypeHash = ImHashStr("Table");
|
|
||||||
ini_handler.ReadOpenFn = TableSettingsHandler_ReadOpen;
|
|
||||||
ini_handler.ReadLineFn = TableSettingsHandler_ReadLine;
|
|
||||||
ini_handler.WriteAllFn = TableSettingsHandler_WriteAll;
|
|
||||||
g.SettingsHandlers.push_back(ini_handler);
|
|
||||||
}
|
|
||||||
#endif // #ifdef IMGUI_HAS_TABLE
|
#endif // #ifdef IMGUI_HAS_TABLE
|
||||||
|
|
||||||
#ifdef IMGUI_HAS_DOCK
|
#ifdef IMGUI_HAS_DOCK
|
||||||
|
@ -2066,9 +2066,10 @@ struct ImGuiTableColumnSettings
|
|||||||
struct ImGuiTableSettings
|
struct ImGuiTableSettings
|
||||||
{
|
{
|
||||||
ImGuiID ID; // Set to 0 to invalidate/delete the setting
|
ImGuiID ID; // Set to 0 to invalidate/delete the setting
|
||||||
ImGuiTableFlags SaveFlags;
|
ImGuiTableFlags SaveFlags; // Indicate data we want to save using the Resizable/Reorderable/Sortable/Hideable flags (could be using its own flags..)
|
||||||
ImS8 ColumnsCount;
|
ImS8 ColumnsCount;
|
||||||
ImS8 ColumnsCountMax;
|
ImS8 ColumnsCountMax; // Maximum number of columns this settings instance can store, we can recycle a settings instance with lower number of columns but not higher
|
||||||
|
bool WantApply; // Set when loaded from .ini data (to enable merging/loading .ini data into an already running context)
|
||||||
|
|
||||||
ImGuiTableSettings() { memset(this, 0, sizeof(*this)); }
|
ImGuiTableSettings() { memset(this, 0, sizeof(*this)); }
|
||||||
ImGuiTableColumnSettings* GetColumnSettings() { return (ImGuiTableColumnSettings*)(this + 1); }
|
ImGuiTableColumnSettings* GetColumnSettings() { return (ImGuiTableColumnSettings*)(this + 1); }
|
||||||
@ -2271,10 +2272,8 @@ namespace ImGui
|
|||||||
IMGUI_API void PopTableBackground();
|
IMGUI_API void PopTableBackground();
|
||||||
IMGUI_API void TableLoadSettings(ImGuiTable* table);
|
IMGUI_API void TableLoadSettings(ImGuiTable* table);
|
||||||
IMGUI_API void TableSaveSettings(ImGuiTable* table);
|
IMGUI_API void TableSaveSettings(ImGuiTable* table);
|
||||||
IMGUI_API ImGuiTableSettings* TableFindSettings(const ImGuiTable* table);
|
IMGUI_API ImGuiTableSettings* TableGetBoundSettings(const ImGuiTable* table);
|
||||||
IMGUI_API void* TableSettingsHandler_ReadOpen(ImGuiContext*, ImGuiSettingsHandler*, const char* name);
|
IMGUI_API void TableInstallSettingsHandler(ImGuiContext* context);
|
||||||
IMGUI_API void TableSettingsHandler_ReadLine(ImGuiContext*, ImGuiSettingsHandler*, void* entry, const char* line);
|
|
||||||
IMGUI_API void TableSettingsHandler_WriteAll(ImGuiContext*, ImGuiSettingsHandler*, ImGuiTextBuffer* buf);
|
|
||||||
|
|
||||||
// Tab Bars
|
// Tab Bars
|
||||||
IMGUI_API bool BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& bb, ImGuiTabBarFlags flags);
|
IMGUI_API bool BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& bb, ImGuiTabBarFlags flags);
|
||||||
|
120
imgui_tables.cpp
120
imgui_tables.cpp
@ -2305,19 +2305,28 @@ void ImGui::TableSortSpecsSanitize(ImGuiTable* table)
|
|||||||
// [Main] 4: TableSettingsHandler_WriteAll() When .ini file is dirty (which can come from other source), save TableSettings into .ini file.
|
// [Main] 4: TableSettingsHandler_WriteAll() When .ini file is dirty (which can come from other source), save TableSettings into .ini file.
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Clear and initialize empty settings instance
|
||||||
|
static void InitTableSettings(ImGuiTableSettings* settings, ImGuiID id, int columns_count, int columns_count_max)
|
||||||
|
{
|
||||||
|
IM_PLACEMENT_NEW(settings) ImGuiTableSettings();
|
||||||
|
ImGuiTableColumnSettings* settings_column = settings->GetColumnSettings();
|
||||||
|
for (int n = 0; n < columns_count_max; n++, settings_column++)
|
||||||
|
IM_PLACEMENT_NEW(settings_column) ImGuiTableColumnSettings();
|
||||||
|
settings->ID = id;
|
||||||
|
settings->ColumnsCount = (ImS8)columns_count;
|
||||||
|
settings->ColumnsCountMax = (ImS8)columns_count_max;
|
||||||
|
settings->WantApply = true;
|
||||||
|
}
|
||||||
|
|
||||||
static ImGuiTableSettings* CreateTableSettings(ImGuiID id, int columns_count)
|
static ImGuiTableSettings* CreateTableSettings(ImGuiID id, int columns_count)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiTableSettings* settings = g.SettingsTables.alloc_chunk(sizeof(ImGuiTableSettings) + (size_t)columns_count * sizeof(ImGuiTableColumnSettings));
|
ImGuiTableSettings* settings = g.SettingsTables.alloc_chunk(sizeof(ImGuiTableSettings) + (size_t)columns_count * sizeof(ImGuiTableColumnSettings));
|
||||||
IM_PLACEMENT_NEW(settings) ImGuiTableSettings();
|
InitTableSettings(settings, id, columns_count, columns_count);
|
||||||
ImGuiTableColumnSettings* settings_column = settings->GetColumnSettings();
|
|
||||||
for (int n = 0; n < columns_count; n++, settings_column++)
|
|
||||||
IM_PLACEMENT_NEW(settings_column) ImGuiTableColumnSettings();
|
|
||||||
settings->ID = id;
|
|
||||||
settings->ColumnsCount = settings->ColumnsCountMax = (ImS8)columns_count;
|
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find existing settings
|
||||||
static ImGuiTableSettings* FindTableSettingsByID(ImGuiID id)
|
static ImGuiTableSettings* FindTableSettingsByID(ImGuiID id)
|
||||||
{
|
{
|
||||||
// FIXME-OPT: Might want to store a lookup map for this?
|
// FIXME-OPT: Might want to store a lookup map for this?
|
||||||
@ -2328,20 +2337,19 @@ static ImGuiTableSettings* FindTableSettingsByID(ImGuiID id)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGuiTableSettings* ImGui::TableFindSettings(const ImGuiTable* table)
|
// Get settings for a given table, NULL if none
|
||||||
|
ImGuiTableSettings* ImGui::TableGetBoundSettings(const ImGuiTable* table)
|
||||||
{
|
{
|
||||||
if (table->SettingsOffset == -1)
|
if (table->SettingsOffset != -1)
|
||||||
return NULL;
|
|
||||||
|
|
||||||
ImGuiContext& g = *GImGui;
|
|
||||||
ImGuiTableSettings* settings = g.SettingsTables.ptr_from_offset(table->SettingsOffset);
|
|
||||||
IM_ASSERT(settings->ID == table->ID);
|
|
||||||
if (settings->ColumnsCountMax < table->ColumnsCount)
|
|
||||||
{
|
{
|
||||||
settings->ID = 0; // Ditch storage if we won't fit because of a count change
|
ImGuiContext& g = *GImGui;
|
||||||
return NULL;
|
ImGuiTableSettings* settings = g.SettingsTables.ptr_from_offset(table->SettingsOffset);
|
||||||
|
IM_ASSERT(settings->ID == table->ID);
|
||||||
|
if (settings->ColumnsCountMax >= table->ColumnsCount)
|
||||||
|
return settings; // OK
|
||||||
|
settings->ID = 0; // Invalidate storage, we won't fit because of a count change
|
||||||
}
|
}
|
||||||
return settings;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::TableSaveSettings(ImGuiTable* table)
|
void ImGui::TableSaveSettings(ImGuiTable* table)
|
||||||
@ -2352,7 +2360,7 @@ void ImGui::TableSaveSettings(ImGuiTable* table)
|
|||||||
|
|
||||||
// Bind or create settings data
|
// Bind or create settings data
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiTableSettings* settings = TableFindSettings(table);
|
ImGuiTableSettings* settings = TableGetBoundSettings(table);
|
||||||
if (settings == NULL)
|
if (settings == NULL)
|
||||||
{
|
{
|
||||||
settings = CreateTableSettings(table->ID, table->ColumnsCount);
|
settings = CreateTableSettings(table->ID, table->ColumnsCount);
|
||||||
@ -2370,7 +2378,7 @@ void ImGui::TableSaveSettings(ImGuiTable* table)
|
|||||||
settings->SaveFlags = ImGuiTableFlags_Resizable;
|
settings->SaveFlags = ImGuiTableFlags_Resizable;
|
||||||
for (int n = 0; n < table->ColumnsCount; n++, column++, column_settings++)
|
for (int n = 0; n < table->ColumnsCount; n++, column++, column_settings++)
|
||||||
{
|
{
|
||||||
//column_settings->WidthOrWeight = column->WidthRequested; // FIXME-WIP
|
//column_settings->WidthOrWeight = column->WidthRequested; // FIXME-TABLE: Missing
|
||||||
column_settings->Index = (ImS8)n;
|
column_settings->Index = (ImS8)n;
|
||||||
column_settings->DisplayOrder = column->DisplayOrder;
|
column_settings->DisplayOrder = column->DisplayOrder;
|
||||||
column_settings->SortOrder = column->SortOrder;
|
column_settings->SortOrder = column->SortOrder;
|
||||||
@ -2378,7 +2386,7 @@ void ImGui::TableSaveSettings(ImGuiTable* table)
|
|||||||
column_settings->Visible = column->IsActive;
|
column_settings->Visible = column->IsActive;
|
||||||
|
|
||||||
// We skip saving some data in the .ini file when they are unnecessary to restore our state
|
// We skip saving some data in the .ini file when they are unnecessary to restore our state
|
||||||
// FIXME-TABLE: We don't have logic to easily compare SortOrder to DefaultSortOrder yet so it's always saved.
|
// FIXME-TABLE: We don't have logic to easily compare SortOrder to DefaultSortOrder yet so it's always saved when present.
|
||||||
if (column->DisplayOrder != n)
|
if (column->DisplayOrder != n)
|
||||||
settings->SaveFlags |= ImGuiTableFlags_Reorderable;
|
settings->SaveFlags |= ImGuiTableFlags_Reorderable;
|
||||||
if (column_settings->SortOrder != -1)
|
if (column_settings->SortOrder != -1)
|
||||||
@ -2409,9 +2417,10 @@ void ImGui::TableLoadSettings(ImGuiTable* table)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
settings = g.SettingsTables.ptr_from_offset(table->SettingsOffset);
|
settings = TableGetBoundSettings(table);
|
||||||
}
|
}
|
||||||
table->SettingsLoadedFlags = settings->SaveFlags;
|
table->SettingsLoadedFlags = settings->SaveFlags;
|
||||||
|
IM_ASSERT(settings->ColumnsCount == table->ColumnsCount);
|
||||||
|
|
||||||
// Serialize ImGuiTableSettings/ImGuiTableColumnSettings into ImGuiTable/ImGuiTableColumn
|
// Serialize ImGuiTableSettings/ImGuiTableColumnSettings into ImGuiTable/ImGuiTableColumn
|
||||||
ImGuiTableColumnSettings* column_settings = settings->GetColumnSettings();
|
ImGuiTableColumnSettings* column_settings = settings->GetColumnSettings();
|
||||||
@ -2422,14 +2431,13 @@ void ImGui::TableLoadSettings(ImGuiTable* table)
|
|||||||
continue;
|
continue;
|
||||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||||
//column->WidthRequested = column_settings->WidthOrWeight; // FIXME-WIP
|
//column->WidthRequested = column_settings->WidthOrWeight; // FIXME-WIP
|
||||||
if (column_settings->DisplayOrder != -1)
|
if (settings->SaveFlags & ImGuiTableFlags_Reorderable)
|
||||||
column->DisplayOrder = column_settings->DisplayOrder;
|
column->DisplayOrder = column_settings->DisplayOrder;
|
||||||
if (column_settings->SortOrder != -1)
|
else
|
||||||
{
|
column->DisplayOrder = (ImS8)column_n;
|
||||||
column->SortOrder = column_settings->SortOrder;
|
|
||||||
column->SortDirection = column_settings->SortDirection;
|
|
||||||
}
|
|
||||||
column->IsActive = column->IsActiveNextFrame = column_settings->Visible;
|
column->IsActive = column->IsActiveNextFrame = column_settings->Visible;
|
||||||
|
column->SortOrder = column_settings->SortOrder;
|
||||||
|
column->SortDirection = column_settings->SortDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME-TABLE: Need to validate .ini data
|
// FIXME-TABLE: Need to validate .ini data
|
||||||
@ -2437,16 +2445,46 @@ void ImGui::TableLoadSettings(ImGuiTable* table)
|
|||||||
table->DisplayOrderToIndex[table->Columns[column_n].DisplayOrder] = (ImS8)column_n;
|
table->DisplayOrderToIndex[table->Columns[column_n].DisplayOrder] = (ImS8)column_n;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* ImGui::TableSettingsHandler_ReadOpen(ImGuiContext*, ImGuiSettingsHandler*, const char* name)
|
static void TableSettingsHandler_ClearAll(ImGuiContext* ctx, ImGuiSettingsHandler*)
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *ctx;
|
||||||
|
for (int i = 0; i != g.Tables.GetSize(); i++)
|
||||||
|
g.Tables.GetByIndex(i)->SettingsOffset = -1;
|
||||||
|
g.SettingsTables.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply to existing windows (if any)
|
||||||
|
static void TableSettingsHandler_ApplyAll(ImGuiContext* ctx, ImGuiSettingsHandler*)
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *ctx;
|
||||||
|
for (int i = 0; i != g.Tables.GetSize(); i++)
|
||||||
|
{
|
||||||
|
ImGuiTable* table = g.Tables.GetByIndex(i);
|
||||||
|
table->IsSettingsRequestLoad = true;
|
||||||
|
table->SettingsOffset = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* TableSettingsHandler_ReadOpen(ImGuiContext*, ImGuiSettingsHandler*, const char* name)
|
||||||
{
|
{
|
||||||
ImGuiID id = 0;
|
ImGuiID id = 0;
|
||||||
int columns_count = 0;
|
int columns_count = 0;
|
||||||
if (sscanf(name, "0x%08X,%d", &id, &columns_count) < 2)
|
if (sscanf(name, "0x%08X,%d", &id, &columns_count) < 2)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (ImGuiTableSettings* settings = FindTableSettingsByID(id))
|
||||||
|
{
|
||||||
|
if (settings->ColumnsCountMax >= columns_count)
|
||||||
|
{
|
||||||
|
InitTableSettings(settings, id, columns_count, settings->ColumnsCountMax); // Recycle
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
settings->ID = 0; // Invalidate storage if we won't fit because of a count change
|
||||||
|
}
|
||||||
return CreateTableSettings(id, columns_count);
|
return CreateTableSettings(id, columns_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::TableSettingsHandler_ReadLine(ImGuiContext*, ImGuiSettingsHandler*, void* entry, const char* line)
|
static void TableSettingsHandler_ReadLine(ImGuiContext*, ImGuiSettingsHandler*, void* entry, const char* line)
|
||||||
{
|
{
|
||||||
// "Column 0 UserID=0x42AD2D21 Width=100 Visible=1 Order=0 Sort=0v"
|
// "Column 0 UserID=0x42AD2D21 Width=100 Visible=1 Order=0 Sort=0v"
|
||||||
ImGuiTableSettings* settings = (ImGuiTableSettings*)entry;
|
ImGuiTableSettings* settings = (ImGuiTableSettings*)entry;
|
||||||
@ -2465,7 +2503,7 @@ void ImGui::TableSettingsHandler_ReadLine(ImGuiContext*, ImGuiSettingsHandler
|
|||||||
if (sscanf(line, "Sort=%d%c%n", &n, &c, &r) == 2) { line = ImStrSkipBlank(line + r); column->SortOrder = (ImS8)n; column->SortDirection = (c == '^') ? ImGuiSortDirection_Descending : ImGuiSortDirection_Ascending; settings->SaveFlags |= ImGuiTableFlags_Sortable; }
|
if (sscanf(line, "Sort=%d%c%n", &n, &c, &r) == 2) { line = ImStrSkipBlank(line + r); column->SortOrder = (ImS8)n; column->SortDirection = (c == '^') ? ImGuiSortDirection_Descending : ImGuiSortDirection_Ascending; settings->SaveFlags |= ImGuiTableFlags_Sortable; }
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::TableSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* buf)
|
static void TableSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* buf)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *ctx;
|
ImGuiContext& g = *ctx;
|
||||||
for (ImGuiTableSettings* settings = g.SettingsTables.begin(); settings != NULL; settings = g.SettingsTables.next_chunk(settings))
|
for (ImGuiTableSettings* settings = g.SettingsTables.begin(); settings != NULL; settings = g.SettingsTables.next_chunk(settings))
|
||||||
@ -2488,10 +2526,8 @@ void ImGui::TableSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHan
|
|||||||
for (int column_n = 0; column_n < settings->ColumnsCount; column_n++, column++)
|
for (int column_n = 0; column_n < settings->ColumnsCount; column_n++, column++)
|
||||||
{
|
{
|
||||||
// "Column 0 UserID=0x42AD2D21 Width=100 Visible=1 Order=0 Sort=0v"
|
// "Column 0 UserID=0x42AD2D21 Width=100 Visible=1 Order=0 Sort=0v"
|
||||||
if (column->UserID != 0)
|
buf->appendf("Column %-2d", column_n);
|
||||||
buf->appendf("Column %-2d UserID=%08X", column_n, column->UserID);
|
if (column->UserID != 0) buf->appendf(" UserID=%08X", column->UserID);
|
||||||
else
|
|
||||||
buf->appendf("Column %-2d", column_n);
|
|
||||||
if (save_size) buf->appendf(" Width=%d", 0);// (int)settings_column->WidthOrWeight); // FIXME-TABLE
|
if (save_size) buf->appendf(" Width=%d", 0);// (int)settings_column->WidthOrWeight); // FIXME-TABLE
|
||||||
if (save_visible) buf->appendf(" Visible=%d", column->Visible);
|
if (save_visible) buf->appendf(" Visible=%d", column->Visible);
|
||||||
if (save_order) buf->appendf(" Order=%d", column->DisplayOrder);
|
if (save_order) buf->appendf(" Order=%d", column->DisplayOrder);
|
||||||
@ -2502,6 +2538,20 @@ void ImGui::TableSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImGui::TableInstallSettingsHandler(ImGuiContext* context)
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *context;
|
||||||
|
ImGuiSettingsHandler ini_handler;
|
||||||
|
ini_handler.TypeName = "Table";
|
||||||
|
ini_handler.TypeHash = ImHashStr("Table");
|
||||||
|
ini_handler.ClearAllFn = TableSettingsHandler_ClearAll;
|
||||||
|
ini_handler.ReadOpenFn = TableSettingsHandler_ReadOpen;
|
||||||
|
ini_handler.ReadLineFn = TableSettingsHandler_ReadLine;
|
||||||
|
ini_handler.ApplyAllFn = TableSettingsHandler_ApplyAll;
|
||||||
|
ini_handler.WriteAllFn = TableSettingsHandler_WriteAll;
|
||||||
|
g.SettingsHandlers.push_back(ini_handler);
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
// TABLE - Debugging
|
// TABLE - Debugging
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
@ -2543,7 +2593,7 @@ void ImGui::DebugNodeTable(ImGuiTable* table)
|
|||||||
(column->Flags & ImGuiTableColumnFlags_WidthAlwaysAutoResize) ? "WidthAlwaysAutoResize " : "",
|
(column->Flags & ImGuiTableColumnFlags_WidthAlwaysAutoResize) ? "WidthAlwaysAutoResize " : "",
|
||||||
(column->Flags & ImGuiTableColumnFlags_NoResize) ? "NoResize " : "");
|
(column->Flags & ImGuiTableColumnFlags_NoResize) ? "NoResize " : "");
|
||||||
}
|
}
|
||||||
if (ImGuiTableSettings* settings = TableFindSettings(table))
|
if (ImGuiTableSettings* settings = TableGetBoundSettings(table))
|
||||||
DebugNodeTableSettings(settings);
|
DebugNodeTableSettings(settings);
|
||||||
TreePop();
|
TreePop();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user