Lots of SzGui work

This commit is contained in:
2026-02-25 00:08:27 -06:00
parent e6749c51c4
commit dad80e30da
20 changed files with 968 additions and 22 deletions

View File

@@ -0,0 +1,68 @@
using ImGuiNET;
using SzCore;
using SzCore.DataObjects;
namespace SzGui.Windows;
public class DatasetCreatorWindow : SzGuiWindowBase
{
private string _datasetName = "";
private int _selectedTemplateIndex = 0;
private List<string> _templateIds = new();
public DatasetCreatorWindow()
{
WindowName = "Create New Dataset";
RefreshTemplates();
}
private void RefreshTemplates()
{
_ = SZ.DataHandler.LoadAllDataObjectTemplatesAsync();
_templateIds = SZ.DataHandler.LoadedTemplates.Keys.ToList();
}
protected override void RenderContent()
{
ImGui.InputText("Dataset Name", ref _datasetName, 128);
if (_templateIds.Count == 0)
{
ImGui.TextColored(new System.Numerics.Vector4(1, 0, 0, 1), "No templates loaded! Create a template first.");
if (ImGui.Button("Refresh Template List")) RefreshTemplates();
}
else
{
string[] items = _templateIds.ToArray();
ImGui.Combo("Template", ref _selectedTemplateIndex, items, items.Length);
ImGui.Separator();
if (ImGui.Button("Create Dataset", new System.Numerics.Vector2(0, 30)))
{
if (!string.IsNullOrWhiteSpace(_datasetName))
{
ExecuteCreation();
}
}
}
}
private async void ExecuteCreation()
{
string selectedId = _templateIds[_selectedTemplateIndex];
var result = await SZ.DataHandler.CreateDatasetAsync(_datasetName, selectedId);
if (result.IsSuccess && result.Value != null)
{
await SZ.DataHandler.SaveDatasetAsync(result.Value);
IsOpen = false;
}
else
{
Console.WriteLine($"Error creating dataset: {result.Error}");
}
}
}

View File

@@ -0,0 +1,44 @@
using ImGuiNET;
using SzCore;
using SzCore.DataObjects;
using SzGui.Windows;
public class NewObjectModal : SzGuiWindowBase
{
private readonly SzDataset _dataset;
private string _objName = "";
public NewObjectModal(SzDataset dataset)
{
_dataset = dataset;
WindowName = $"Add Object to {dataset.Name}";
}
protected override void RenderContent()
{
ImGui.Text($"Creating object for template: {_dataset.DataObjectTemplateId}");
ImGui.InputText("Object Name", ref _objName, 64);
if (ImGui.Button("Create", new System.Numerics.Vector2(100, 0)))
{
Create();
}
}
private async void Create()
{
var templateResult = await SZ.DataHandler.LoadTemplateAsync<SzDataObjectTemplate>(_dataset.DataObjectTemplateId);
if (templateResult.IsSuccess)
{
var objResult = SZ.DataHandler.CreateDataObject(templateResult.Value!, _objName);
if (objResult.IsSuccess)
{
_dataset.DataObjects.Add(objResult.Value!.Id, objResult.Value);
await SZ.DataHandler.SaveDatasetAsync(_dataset);
IsOpen = false;
}
}
}
}

View File

@@ -0,0 +1,76 @@
using System.Numerics;
using ImGuiNET;
namespace SzGui.Windows;
public class SettingsWindow : SzGuiWindowBase
{
private bool _settingsDirty = false;
public SettingsWindow() => WindowName = "App Settings";
protected override void RenderContent()
{
ImGui.SeparatorText("Application Settings");
foreach (var setting in ApplicationSettings.GetAllSettings().ToList())
{
string key = setting.Key;
object val = setting.Value;
bool changed = false;
if (val is bool boolVal)
{
if (ImGui.Checkbox(key, ref boolVal))
{
ApplicationSettings.SetSettingValue(key, boolVal);
changed = true;
}
}
else if (val is float floatVal || val is double)
{
float f = Convert.ToSingle(val);
if (ImGui.DragFloat(key, ref f, 0.01f))
{
ApplicationSettings.SetSettingValue(key, f);
changed = true;
}
}
else if (val is string strVal)
{
if (ImGui.InputText(key, ref strVal, 256))
{
ApplicationSettings.SetSettingValue(key, strVal);
changed = true;
}
}
if (ImGui.IsItemHovered())
{
ImGui.SetTooltip($"Internal Key: {key}");
}
if (changed) _settingsDirty = true;
}
ImGui.Separator();
if (ImGui.Button("Save Changes"))
{
ApplicationSettings.SaveSettings();
_settingsDirty = false;
}
ImGui.SameLine();
if (ImGui.Button("Reload from Disk"))
{
ApplicationSettings.LoadSettings();
}
if (_settingsDirty)
{
ImGui.TextColored(new Vector4(1, 0.5f, 0, 1), "You have unsaved changes!");
}
}
}

View File

@@ -0,0 +1,15 @@
using ImGuiNET;
namespace SzGui.Windows;
public class StartupWindow : SzGuiWindowBase
{
public StartupWindow() => WindowName = "Startup";
protected override void RenderContent()
{
ImGui.TextUnformatted("Welcome to SessionZero!");
var testBttn = ImGui.Button(IconFonts.FontAwesome6.Gear + " Settings");
if (testBttn) SzApp.AppInstance.ActivateWindow(new SettingsWindow());
}
}

View File

@@ -0,0 +1,93 @@
using ImGuiNET;
using System.Numerics;
using SzCore;
using SzCore.DataObjects;
namespace SzGui.Windows;
public class SzDataObjectEditorWindow : SzGuiWindowBase
{
private readonly SzDataset _dataset;
private readonly SzDataObject _dataObject;
private bool _isDirty = false;
public SzDataObjectEditorWindow(SzDataset dataset, SzDataObject dataObject)
{
_dataset = dataset;
_dataObject = dataObject;
WindowName = $"Editing: {dataObject.Name} ({dataset.Name})";
}
protected override void RenderContent()
{
ImGui.TextDisabled($"ID: {_dataObject.Id}");
ImGui.SeparatorText("Fields");
foreach (var field in _dataObject.Fields.Values)
{
DrawFieldInput(field);
}
ImGui.Separator();
if (ImGui.Button("Save Object", new Vector2(120, 30)))
{
Save();
}
if (_isDirty)
{
ImGui.SameLine();
ImGui.TextColored(new Vector4(1, 0.5f, 0, 1), "Unsaved changes...");
}
}
private void DrawFieldInput(SzField field)
{
string label = $"{field.Id}##{field.Id}";
string val = field.Value ?? "";
switch (field.FieldType)
{
case SzFieldType.Text:
if (ImGui.InputText(label, ref val, 1024))
{
field.Value = val;
_isDirty = true;
}
break;
case SzFieldType.Bool:
bool bVal = val.ToLower() == "true";
if (ImGui.Checkbox(label, ref bVal))
{
field.Value = bVal.ToString().ToLower();
_isDirty = true;
}
break;
case SzFieldType.Number:
// Handling numbers as strings in the DataObject, but using DragFloat for UX
float.TryParse(val, out float fVal);
if (ImGui.DragFloat(label, ref fVal))
{
field.Value = fVal.ToString();
_isDirty = true;
}
break;
default:
ImGui.Text($"{field.Id}: {val} (Unsupported Type: {field.FieldType})");
break;
}
}
private async void Save()
{
var result = await SZ.DataHandler.SaveDatasetAsync(_dataset);
if (result.IsSuccess)
{
_isDirty = false;
}
}
}

View File

@@ -0,0 +1,137 @@
using ImGuiNET;
using System.Numerics;
using SzCore;
using SzCore.DataObjects;
namespace SzGui.Windows;
public class SzDataObjectTemplateEditorWindow : SzGuiWindowBase
{
private readonly ISzTemplate _template;
private string _name;
private string _type;
private string _description = "";
private List<SzTemplateField> _fields;
// Split ID components
private string _baseId = "";
private string _version = "1_0";
private string _newFieldId = "";
private int _selectedTypeIndex = 0;
public SzDataObjectTemplateEditorWindow(SzDataObjectTemplate template)
{
_template = template;
_name = template.Name;
_type = template.DataObjectType;
_fields = template.TemplateFields.Values.ToList();
if (template.Id.Contains('@'))
{
var parts = template.Id.Split('@');
_baseId = parts[0];
_version = parts[1];
}
else
{
_baseId = template.Id;
}
WindowName = $"Edit Template: {template.Id}";
}
protected override void RenderContent()
{
ImGui.SeparatorText("Metadata");
ImGui.InputText("Display Name", ref _name, 128);
ImGui.InputText("Object Type", ref _type, 128);
ImGui.Spacing();
ImGui.Text("Internal Identity");
ImGui.InputText("Base ID", ref _baseId, 64);
ImGui.SameLine();
ImGui.Text("@");
ImGui.SameLine();
ImGui.SetNextItemWidth(100);
ImGui.InputText("Version", ref _version, 16);
string fullIdPreview = $"{_baseId}@{_version}";
ImGui.TextDisabled($"Final ID Preview: {fullIdPreview}");
ImGui.SeparatorText("Fields Configuration");
if (ImGui.BeginTable("TemplateFieldsTable", 3, ImGuiTableFlags.Borders | ImGuiTableFlags.RowBg))
{
ImGui.TableSetupColumn("Field ID", ImGuiTableColumnFlags.WidthStretch);
ImGui.TableSetupColumn("Type", ImGuiTableColumnFlags.WidthFixed, 100);
ImGui.TableSetupColumn("Action", ImGuiTableColumnFlags.WidthFixed, 70);
ImGui.TableHeadersRow();
for (int i = 0; i < _fields.Count; i++)
{
ImGui.TableNextRow();
ImGui.TableNextColumn();
ImGui.TextUnformatted(_fields[i].Id);
ImGui.TableNextColumn();
ImGui.TextUnformatted(_fields[i].FieldType.ToString());
ImGui.TableNextColumn();
if (ImGui.SmallButton($"Remove##{i}")) _fields.RemoveAt(i);
}
ImGui.EndTable();
}
ImGui.Spacing();
ImGui.SeparatorText("Add New Field");
ImGui.InputText("Field ID", ref _newFieldId, 64);
string[] typeNames = Enum.GetNames<SzFieldType>();
ImGui.Combo("Type", ref _selectedTypeIndex, typeNames, typeNames.Length);
if (ImGui.Button("Add Field") && !string.IsNullOrWhiteSpace(_newFieldId))
{
var result = SZ.DataHandler.CreateTemplateField(_newFieldId, (SzFieldType)_selectedTypeIndex);
if (result.IsSuccess)
{
_fields.Add(result.Value!);
_newFieldId = "";
}
}
ImGui.Separator();
bool isNewVersion = fullIdPreview != _template.Id;
if (isNewVersion)
{
ImGui.PushStyleColor(ImGuiCol.Button, new Vector4(0.2f, 0.6f, 0.2f, 1.0f));
if (ImGui.Button("Save as New Version", new Vector2(0, 30))) Save(fullIdPreview);
ImGui.PopStyleColor();
}
else
{
if (ImGui.Button("Overwrite Template", new Vector2(0, 30))) Save(fullIdPreview);
}
}
private async void Save(string finalId)
{
var result = SZ.DataHandler.CreateDataObjectTemplate(
_name,
_type,
_version,
finalId,
null,
_fields
);
if (result.IsSuccess && result.Value != null)
{
await SZ.DataHandler.SaveTemplateAsync(result.Value);
IsOpen = false;
}
}
}

View File

@@ -0,0 +1,57 @@
using ImGuiNET;
using System.Numerics;
using SzCore;
using SzCore.DataObjects;
namespace SzGui.Windows;
public class SzDatasetViewerWindow : SzGuiWindowBase
{
private readonly SzDataset _dataset;
public SzDatasetViewerWindow(SzDataset dataset)
{
_dataset = dataset;
WindowName = $"Dataset: {dataset.Name} ({dataset.DataObjectTemplateId})";
}
protected override void RenderContent()
{
if (ImGui.Button("Add New Object"))
{
SzApp.AppInstance.ActivateWindow(new NewObjectModal(_dataset));
}
ImGui.Separator();
if (ImGui.BeginTable("ObjectTable", 2, ImGuiTableFlags.Borders | ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY))
{
ImGui.TableSetupColumn("Object Name", ImGuiTableColumnFlags.WidthStretch);
ImGui.TableSetupColumn("Actions", ImGuiTableColumnFlags.WidthFixed, 110);
ImGui.TableHeadersRow();
foreach (var dataObj in _dataset.DataObjects.Values.ToList())
{
ImGui.TableNextRow();
ImGui.TableNextColumn();
ImGui.TextUnformatted(dataObj.Name);
ImGui.TableNextColumn();
if (ImGui.SmallButton($"Edit##{dataObj.Id}"))
{
SzApp.AppInstance.ActivateWindow(new SzDataObjectEditorWindow(_dataset, dataObj));
}
ImGui.SameLine();
if (ImGui.SmallButton($"Delete##{dataObj.Id}"))
{
_dataset.DataObjects.Remove(dataObj.Id);
_ = SZ.DataHandler.SaveDatasetAsync(_dataset);
}
}
ImGui.EndTable();
}
}
}

View File

@@ -0,0 +1,22 @@
using ImGuiNET;
namespace SzGui.Windows;
public abstract class SzGuiWindowBase
{
public bool IsOpen = true;
public string WindowName { get; protected set; } = "Window";
public virtual void Draw()
{
if (!IsOpen) return;
if (ImGui.Begin(WindowName, ref IsOpen, ImGuiWindowFlags.MenuBar))
{
RenderContent();
}
ImGui.End();
}
protected abstract void RenderContent();
}

View File

@@ -0,0 +1,127 @@
using ImGuiNET;
using SzCore;
using SzCore.DataObjects;
namespace SzGui.Windows;
public class SzLibraryWindow : SzGuiWindowBase
{
public SzLibraryWindow()
{
WindowName = "SZ Library";
RefreshData();
}
private Dictionary<string, SzDataset> _loadedDatasets = [];
private Dictionary<string, SzDataObjectTemplate> _loadedDataObjectTemplates = [];
private async void RefreshData()
{
await SZ.DataHandler.LoadAllDatasetsAsync();
await SZ.DataHandler.LoadAllDataObjectTemplatesAsync();
_loadedDatasets = SZ.DataHandler.LoadedDatasets;
_loadedDataObjectTemplates = SZ.DataHandler.LoadedTemplates.Values
.OfType<SzDataObjectTemplate>()
.ToDictionary(t => t.Id, t => t);
}
protected override void RenderContent()
{
if (ImGui.BeginMenuBar())
{
if (ImGui.BeginMenu("Create"))
{
if (ImGui.MenuItem("New Template"))
{
SzApp.AppInstance.ActivateWindow(new SzTemplateCreatorWindow());
}
if (ImGui.MenuItem("New Dataset"))
{
SzApp.AppInstance.ActivateWindow(new DatasetCreatorWindow());
}
ImGui.EndMenu();
}
// Added Refresh to the menu bar
if (ImGui.MenuItem("Refresh"))
{
RefreshData();
}
ImGui.EndMenuBar();
}
if (ImGui.CollapsingHeader("Data Object Templates", ImGuiTreeNodeFlags.DefaultOpen))
{
if (ImGui.BeginTable("DataObjectTemplatesTable", 2, ImGuiTableFlags.Borders | ImGuiTableFlags.RowBg))
{
ImGui.TableSetupColumn("Template ID", ImGuiTableColumnFlags.WidthStretch);
ImGui.TableSetupColumn("Actions", ImGuiTableColumnFlags.WidthFixed, 120);
ImGui.TableHeadersRow();
foreach (var template in _loadedDataObjectTemplates)
{
ImGui.TableNextRow();
ImGui.TableNextColumn();
ImGui.TextUnformatted(template.Key);
ImGui.TableNextColumn();
if (ImGui.SmallButton($"Edit##T_{template.Key}"))
{
SzApp.AppInstance.ActivateWindow(new SzDataObjectTemplateEditorWindow(template.Value));
}
ImGui.SameLine();
if (ImGui.SmallButton($"Delete##T_{template.Key}"))
{
_ = Task.Run(async () => {
await SZ.DataHandler.DeleteTemplateAsync(template.Key);
RefreshData();
});
}
}
ImGui.EndTable();
}
}
ImGui.Spacing();
if (ImGui.CollapsingHeader("Datasets", ImGuiTreeNodeFlags.DefaultOpen))
{
if (ImGui.BeginTable("DatasetsTable", 2, ImGuiTableFlags.Borders | ImGuiTableFlags.RowBg))
{
ImGui.TableSetupColumn("Dataset Name", ImGuiTableColumnFlags.WidthStretch);
ImGui.TableSetupColumn("Actions", ImGuiTableColumnFlags.WidthFixed, 120);
ImGui.TableHeadersRow();
foreach (var datasetEntry in _loadedDatasets)
{
var dataset = datasetEntry.Value;
ImGui.TableNextRow();
ImGui.TableNextColumn();
ImGui.TextUnformatted(dataset.Name);
ImGui.TableNextColumn();
if (ImGui.SmallButton($"Open##{dataset.Id}"))
{
SzApp.AppInstance.ActivateWindow(new SzDatasetViewerWindow(dataset));
}
ImGui.SameLine();
if (ImGui.SmallButton($"Delete##{dataset.Id}"))
{
_ = Task.Run(async () => {
await SZ.DataHandler.DeleteDatasetAsync(dataset.Id);
RefreshData();
});
}
}
ImGui.EndTable();
}
}
}
}

View File

@@ -0,0 +1,66 @@
using ImGuiNET;
using SzCore;
using SzCore.DataObjects;
namespace SzGui.Windows;
public class SzTemplateCreatorWindow : SzGuiWindowBase
{
private string _name = "";
private string _type = "";
private List<SzTemplateField> _fields = new();
private string _newFieldId = "";
private int _selectedTypeIndex = 0;
public SzTemplateCreatorWindow() => WindowName = "Template Creator";
protected override void RenderContent()
{
ImGui.InputText("Template Name", ref _name, 64);
ImGui.InputText("Object Type", ref _type, 64);
ImGui.SeparatorText("Fields");
for (int i = 0; i < _fields.Count; i++)
{
ImGui.BulletText($"{_fields[i].Id} ({_fields[i].FieldType})");
ImGui.SameLine();
if (ImGui.Button($"Remove##{i}")) _fields.RemoveAt(i);
}
ImGui.Separator();
ImGui.InputText("Field ID", ref _newFieldId, 64);
string[] typeNames = Enum.GetNames<SzFieldType>();
ImGui.Combo("Type", ref _selectedTypeIndex, typeNames, typeNames.Length);
if (ImGui.Button("Add Field"))
{
var result = SZ.DataHandler.CreateTemplateField(_newFieldId, (SzFieldType)_selectedTypeIndex);
if (result.IsSuccess)
{
_fields.Add(result.Value!);
_newFieldId = ""; // Reset
}
}
ImGui.Separator();
if (ImGui.Button("Save Template", new System.Numerics.Vector2(0, 30)))
{
Save();
}
}
private async void Save()
{
var result = SZ.DataHandler.CreateDataObjectTemplate(_name, _type, fields: _fields);
if (result.IsSuccess)
{
await SZ.DataHandler.SaveTemplateAsync(result.Value!);
IsOpen = false;
}
}
}