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

@@ -1,2 +1,3 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADictionary_00602_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003Fhome_003Fchris_003F_002Econfig_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fa7e0e0f67f744397a03b2e746d7e5534b2e200_003F39_003F247644fd_003FDictionary_00602_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADictionary_00602_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003Fhome_003Fchris_003F_002Econfig_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fa7e0e0f67f744397a03b2e746d7e5534b2e200_003F39_003F247644fd_003FDictionary_00602_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AThrowHelper_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003Fhome_003Fchris_003F_002Econfig_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fa7e0e0f67f744397a03b2e746d7e5534b2e200_003F73_003F819b2530_003FThrowHelper_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>

View File

@@ -0,0 +1,9 @@
namespace SzCore.DataObjects;
public class SzCharacterTemplate : ISzTemplate
{
public string Name { get; set; } = "";
public string Id { get; set; } = "";
public string Description { get; set; } = "";
public Dictionary<string, SzTemplateField> TemplateFields { get; set; } = [];
}

View File

@@ -7,6 +7,9 @@ public class SzDataHandler
private readonly Dictionary<string, SzDataset> _loadedDatasets = [];
private readonly Dictionary<string, ISzTemplate> _loadedTemplates = [];
public Dictionary<string, SzDataset> LoadedDatasets => _loadedDatasets;
public Dictionary<string, ISzTemplate> LoadedTemplates => _loadedTemplates;
public SzDataHandler() { }
public void ClearCache()
@@ -247,5 +250,18 @@ public class SzDataHandler
await LoadDatasetAsync(id, ct);
}
}
public async Task LoadAllDataObjectTemplatesAsync(CancellationToken ct = default)
{
_loadedTemplates.Clear();
if (!Directory.Exists(SZ.LocalFileManager.TemplatesPath)) return;
var dirs = Directory.GetDirectories(SZ.LocalFileManager.TemplatesPath);
foreach (var dir in dirs)
{
var id = Path.GetFileName(dir);
await LoadTemplateAsync<SzDataObjectTemplate>(id, ct);
}
}
#endregion
}

View File

@@ -0,0 +1,81 @@
using System.IO;
using Raylib_cs;
using Tomlyn;
namespace SzGui;
public static class ApplicationSettings
{
private static Dictionary<string, object> _settings = new();
private static readonly string _filePath = "settings.toml";
public static Dictionary<string, object> GetAllSettings() => _settings;
public static void CreateInitialSettings()
{
CreateSetting("ShowStartup", false);
CreateSetting("BackgroundColor", Color.DarkGray);
SaveSettings();
}
public static T GetSettingValue<T>(string settingName, T defaultValue = default!)
{
if (_settings.TryGetValue(settingName, out var value))
{
try
{
if (typeof(T) == typeof(float) && value is double d)
return (T)(object)(float)d;
return (T)Convert.ChangeType(value, typeof(T));
}
catch { return defaultValue; }
}
return defaultValue;
}
public static bool SetSettingValue(string settingName, object value)
{
if (!_settings.ContainsKey(settingName)) return false;
_settings[settingName] = value;
return true;
}
public static bool CreateSetting(string name, object value)
{
return _settings.TryAdd(name, value);
}
public static void SaveSettings()
{
try
{
var saveDict = new Dictionary<string, object>();
foreach(var kvp in _settings)
{
if (kvp.Value is Color c)
saveDict[kvp.Key] = new int[] { c.R, c.G, c.B };
else
saveDict[kvp.Key] = kvp.Value;
}
var tomlString = Toml.FromModel(saveDict);
File.WriteAllText(_filePath, tomlString);
}
catch (Exception ex) { Console.WriteLine($"Save Error: {ex.Message}"); }
}
public static void LoadSettings()
{
if (!File.Exists(_filePath)) { SaveSettings(); return; }
try
{
var tomlString = File.ReadAllText(_filePath);
var loaded = Toml.ToModel<Dictionary<string, object>>(tomlString);
if (loaded != null) _settings = loaded;
}
catch (Exception ex) { Console.WriteLine($"Load Error: {ex.Message}"); }
}
}

View File

@@ -1,6 +1,12 @@
// See https://aka.ms/new-console-template for more information
using SzCore;
using SzCore.Defaults;
using SzGui;
var app = new SzApp();
app.Init();
DefaultLocalFileManager _fileManager = new();
ISzLogger _logger = new SzLogger();
ISzDatabaseHandler _databaseHandler = new SzDatabaseHandler();
SZ.Init(_fileManager, _logger, _databaseHandler);
SzApp.AppInstance.Init();

View File

@@ -2,29 +2,51 @@ using System.Numerics;
using ImGuiNET;
using Raylib_cs;
using rlImGui_cs;
using SzGui.Windows;
namespace SzGui;
public class SzApp
{
public static readonly SzApp AppInstance = new();
private SzApp() { }
private List<SzGuiWindowBase> _activeWindows = new();
public void ActivateWindow(SzGuiWindowBase window)
{
if (_activeWindows.Any(w => w.GetType() == window.GetType()))
{
ImGui.SetWindowFocus(window.WindowName);
return;
}
_activeWindows.Add(window);
}
public void Init()
{
ApplicationSettings.LoadSettings();
Raylib.SetConfigFlags(ConfigFlags.Msaa4xHint | ConfigFlags.VSyncHint | ConfigFlags.ResizableWindow);
Raylib.InitWindow(1280, 800, "SessionZero");
rlImGui.Setup(true, true);
ImGui.GetIO().ConfigWindowsMoveFromTitleBarOnly = true;
if (ApplicationSettings.GetSettingValue<bool>("ShowStartup")) ActivateWindow(new StartupWindow());
while (!Raylib.WindowShouldClose())
{
Raylib.BeginDrawing();
Raylib.ClearBackground(new Color(0, 20, 50));
Raylib.ClearBackground(Color.Gray);
rlImGui.Begin();
ImGui.PushStyleColor(ImGuiCol.WindowBg, new Vector4(0, 0, 0, 0));
ImGui.DockSpaceOverViewport(0);
ImGui.PopStyleColor();
// ImGui.ShowDemoWindow();
ImGui.ShowStyleEditor();
HandleShortcuts();
DrawImGui();
rlImGui.End();
@@ -35,12 +57,71 @@ public class SzApp
Raylib.CloseWindow();
}
private void HandleShortcuts()
{
var io = ImGui.GetIO();
if (io is { KeyCtrl: true, KeyAlt: true } && ImGui.IsKeyPressed(ImGuiKey.S))
{
ActivateWindow(new SettingsWindow());
}
if (io is { KeyCtrl: true, KeyAlt: true } && ImGui.IsKeyPressed(ImGuiKey.Q))
{
Raylib.CloseWindow();
}
}
private void UpdateImGuiTheme()
{
var c = ApplicationSettings.GetSettingValue<Color>("BackgroundColor");
Vector4 styleColor = new Vector4(c.R / 255f, c.G / 255f, c.B / 255f, 1.0f);
ImGui.GetStyle().Colors[(int)ImGuiCol.WindowBg] = styleColor;
}
private void DrawImGui()
{
if(ImGui.Begin("SessionZero"))
DrawGlobalMenuBar();
for (int i = _activeWindows.Count - 1; i >= 0; i--)
{
ImGui.TextUnformatted("Test: " + IconFonts.FontAwesome6.House);
_activeWindows[i].Draw();
if (!_activeWindows[i].IsOpen) _activeWindows.RemoveAt(i);
}
ImGui.End();
}
private void DrawGlobalMenuBar()
{
if (ImGui.BeginMainMenuBar())
{
if (ImGui.BeginMenu("File"))
{
if (ImGui.MenuItem("Exit", "Ctrl+Alt+Q")) Raylib.CloseWindow();
ImGui.EndMenu();
}
if (ImGui.BeginMenu("Edit"))
{
if (ImGui.MenuItem("Settings", "Ctrl+Alt+S"))
{
ActivateWindow(new SettingsWindow());
}
ImGui.EndMenu();
}
if (ImGui.BeginMenu("View"))
{
if (ImGui.MenuItem("Start window"))
{
ActivateWindow(new StartupWindow());
}
ImGui.EndMenu();
}
if (ImGui.MenuItem("Library")) ActivateWindow(new SzLibraryWindow());
ImGui.EndMainMenuBar();
}
}
}

View File

@@ -0,0 +1,19 @@
using SzCore;
using SzCore.DataObjects;
namespace SzGui;
public class SzDatabaseHandler : ISzDatabaseHandler
{
public bool InternetAllowed { get; set; }
public Dictionary<string, string> SzDbUrls { get; set; }
public Task<SzDataset?> TryRetrieveDatasetAsync(Guid uuid, CancellationToken ct = default)
{
return null;
}
public Task<ISzTemplate?> TryRetrieveTemplateAsync(Guid uuid, CancellationToken ct = default)
{
return null;
}
}

View File

@@ -11,6 +11,7 @@
<PackageReference Include="ImGui.NET" Version="1.91.6.1" />
<PackageReference Include="Raylib-cs" Version="7.0.2" />
<PackageReference Include="rlImgui-cs" Version="3.2.0" />
<PackageReference Include="Tomlyn" Version="0.20.0" />
</ItemGroup>
<ItemGroup>

23
SzGui/SzLogger.cs Normal file
View File

@@ -0,0 +1,23 @@
using SzCore;
namespace SzGui;
public class SzLogger : ISzLogger
{
public bool LogToFile { get; set; }
public string LogFilePath { get; set; }
public int LogFileMaxLines { get; set; }
public void Log(string text)
{
}
public void LogError(string text)
{
}
public void LogWarning(string text)
{
}
}

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;
}
}
}

View File

@@ -1,23 +1,25 @@
[Window][Debug##Default]
Pos=1006,402
Size=762,814
Pos=637,781
Size=776,368
Collapsed=0
[Window][SessionZero]
Pos=0,0
Size=3792,2067
Size=1692,1377
Collapsed=0
DockId=0x08BD597D,0
DockId=0x00000001,1
[Window][Dear ImGui Demo]
Size=1894,2067
Pos=0,0
Size=1692,1377
Collapsed=0
DockId=0x08BD597D,0
DockId=0x00000001,0
[Window][Dear ImGui Style Editor]
Pos=96,60
Size=692,1365
Pos=1694,0
Size=834,1377
Collapsed=0
DockId=0x00000002,0
[Window][Example: Assets Browser]
Pos=60,60
@@ -61,7 +63,7 @@ Size=300,409
[Window][WindowOverViewport_11111111]
Pos=0,0
Size=3792,2067
Size=2528,1377
Collapsed=0
[Table][0xB6880529,2]
@@ -74,6 +76,8 @@ Column 0 Width=4
Column 1 Weight=2.0000
[Docking][Data]
DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=0,0 Size=3792,2067 CentralNode=1 Selected=0x3C0097EB
DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=0,0 Size=2528,1377 Split=X Selected=0x5E5F7166
DockNode ID=0x00000001 Parent=0x08BD597D SizeRef=1692,1377 CentralNode=1 Selected=0x5E5F7166
DockNode ID=0x00000002 Parent=0x08BD597D SizeRef=834,1377 Selected=0x3EEA4247
DockSpace ID=0xC0DFADC4 Pos=0,38 Size=3840,2122 CentralNode=1