@@ -10,19 +10,24 @@ namespace ktsu.SchemaEditor;
1010using System . Diagnostics ;
1111using System . Numerics ;
1212
13- using ImGuiNET ;
13+ using Hexa . NET . ImGui ;
1414
15+ using ktsu . Extensions ;
1516using ktsu . ImGui . App ;
1617using ktsu . ImGui . Styler ;
1718using ktsu . ImGui . Widgets ;
1819using ktsu . Schema . Models ;
1920using ktsu . Schema . Models . Names ;
2021using ktsu . Semantics . Paths ;
22+ using ktsu . Semantics . Strings ;
23+
24+ using SchemaTypes = ktsu . Schema . Models . Types ;
2125
2226public class SchemaEditor
2327{
2428 public static SchemaEditor Instance { get ; } = new ( ) ;
2529 internal Schema ? CurrentSchema { get ; set ; }
30+ internal AbsoluteFilePath CurrentSchemaPath { get ; set ; } = new ( ) ;
2631 internal SchemaClass ? CurrentClass { get ; set ; }
2732 internal DataSource ? CurrentDataSource { get ; set ; }
2833 internal AppData Options { get ; }
@@ -38,9 +43,9 @@ public class SchemaEditor
3843 private static void Main ( string [ ] _ )
3944 {
4045 string title = nameof ( SchemaEditor ) ;
41- if ( Instance . CurrentSchema is not null )
46+ if ( Instance . CurrentSchema is not null && ! string . IsNullOrEmpty ( Instance . CurrentSchemaPath ) )
4247 {
43- title += $ " - { Instance . CurrentSchema . FilePath . FileName } ";
48+ title += $ " - { Path . GetFileName ( Instance . CurrentSchemaPath ) } ";
4449 }
4550
4651 ImGuiApp . Start ( new ( )
@@ -71,9 +76,10 @@ public SchemaEditor()
7176 Popups = Options . Popups ;
7277
7378 // restore open schema
74- if ( Schema . TryLoad ( Options . CurrentSchemaPath , out Schema ? previouslyOpenSchema ) && previouslyOpenSchema is not null )
79+ if ( SchemaFile . TryLoad ( Options . CurrentSchemaPath , out Schema ? previouslyOpenSchema ) && previouslyOpenSchema is not null )
7580 {
7681 CurrentSchema = previouslyOpenSchema ;
82+ CurrentSchemaPath = Options . CurrentSchemaPath ;
7783 CurrentClass = null ;
7884 CurrentClass = CurrentSchema . GetClass ( Options . CurrentClassName ) ;
7985 }
@@ -101,7 +107,7 @@ private void DividerResized(ImGuiWidgets.DividerContainer container)
101107 //Dont call this directly, call QueueSaveOptions instead so that we can debounce the saves and avoid saving multiple times per frame or multiple frames in a row
102108 private void SaveOptionsInternal ( )
103109 {
104- Options . CurrentSchemaPath = CurrentSchema ? . FilePath ?? new ( ) ;
110+ Options . CurrentSchemaPath = CurrentSchemaPath ;
105111 Options . CurrentClassName = CurrentClass ? . Name ?? new ( ) ;
106112 Options . DividerStates [ DividerContainerCols . Id ] = DividerContainerCols . GetSizes ( ) ;
107113 // Note: WindowState property access needs to be updated for the current ImGuiApp version
@@ -126,7 +132,7 @@ private void SaveOptionsIfRequired()
126132
127133 private void OnRender ( float dt )
128134 {
129- using ( Theme . Color ( Theme . Palette . Normal ) )
135+ using ( Theme . FromColor ( Color . Palette . Semantic . Primary ) )
130136 {
131137 DividerContainerCols . Tick ( dt ) ;
132138
@@ -145,6 +151,7 @@ private void ShowRightPanel(float dt)
145151 private void Reset ( )
146152 {
147153 CurrentSchema = null ;
154+ CurrentSchemaPath = new ( ) ;
148155 CurrentClass = null ;
149156 }
150157
@@ -169,7 +176,7 @@ private void OnMenu()
169176
170177 ImGui . Separator ( ) ;
171178
172- string schemaFilePath = CurrentSchema ? . FilePath ?? "" ;
179+ string schemaFilePath = CurrentSchemaPath ;
173180 if ( ImGui . MenuItem ( "Open Externally" , ! string . IsNullOrEmpty ( schemaFilePath ) ) )
174181 {
175182 using Process p = new ( ) ;
@@ -194,9 +201,10 @@ private void Open()
194201 Popups . OpenBrowserFileOpen ( "Open Schema" , ( filePath ) =>
195202 {
196203 Reset ( ) ;
197- if ( Schema . TryLoad ( filePath , out Schema ? schema ) && schema is not null )
204+ if ( SchemaFile . TryLoad ( filePath , out Schema ? schema ) && schema is not null )
198205 {
199206 CurrentSchema = schema ;
207+ CurrentSchemaPath = filePath ;
200208 CurrentClass = CurrentSchema ? . FirstClass ;
201209 QueueSaveOptions ( ) ;
202210 }
@@ -209,20 +217,23 @@ private void Open()
209217
210218 private void Save ( )
211219 {
212- if ( string . IsNullOrEmpty ( CurrentSchema ? . FilePath ?? new ( ) ) )
220+ if ( string . IsNullOrEmpty ( CurrentSchemaPath ) )
213221 {
214222 SaveAs ( ) ;
215223 return ;
216224 }
217225
218- CurrentSchema ? . Save ( ) ;
226+ if ( CurrentSchema is not null )
227+ {
228+ SchemaFile . TrySave ( CurrentSchema , CurrentSchemaPath ) ;
229+ }
219230 }
220231
221232 private void SaveAs ( )
222233 {
223234 Popups . OpenBrowserFileSave ( "Save Schema" , ( filePath ) =>
224235 {
225- CurrentSchema ? . ChangeFilePath ( filePath ) ;
236+ CurrentSchemaPath = filePath ;
226237 Save ( ) ;
227238 QueueSaveOptions ( ) ;
228239 } , "*.schema.json" ) ;
@@ -245,8 +256,8 @@ internal static bool ToggleVisibility(string key)
245256 [ System . Diagnostics . CodeAnalysis . SuppressMessage ( "Minor Code Smell" , "S3267:Loops should be simplified with \" LINQ\" expressions" , Justification = "We want to separate out ImGui calls from enumerations" ) ]
246257 public void ShowMemberConfig ( Schema schema , SchemaMember schemaMember )
247258 {
248- ArgumentNullException . ThrowIfNull ( schema ) ;
249- ArgumentNullException . ThrowIfNull ( schemaMember ) ;
259+ Ensure . NotNull ( schema ) ;
260+ Ensure . NotNull ( schemaMember ) ;
250261
251262 if ( ImGui . Button ( $ "{ schemaMember . Type . DisplayName } ##Type{ schemaMember . Name } ", new Vector2 ( FieldWidth , 0 ) ) )
252263 {
@@ -259,7 +270,7 @@ public void ShowMemberConfig(Schema schema, SchemaMember schemaMember)
259270 ImGui . SetNextItemWidth ( FieldWidth ) ;
260271 string container = array . Container ;
261272 ImGui . InputText ( $ "##Container{ schemaMember . Name } ", ref container , 64 ) ;
262- array . Container = ( ContainerName ) container ;
273+ array . Container = container . As < ContainerName > ( ) ;
263274
264275 if ( array . ElementType is SchemaTypes . Object obj && obj . Class is not null )
265276 {
@@ -335,9 +346,9 @@ private void ShowSchemaConfig()
335346 {
336347 if ( CurrentSchema is not null )
337348 {
338- if ( string . IsNullOrEmpty ( CurrentSchema . FilePath ) )
349+ if ( string . IsNullOrEmpty ( CurrentSchemaPath ) )
339350 {
340- using ( Theme . Color ( Theme . Palette . Error ) )
351+ using ( Theme . FromColor ( Color . Palette . Semantic . Error ) )
341352 {
342353 ImGui . TextUnformatted ( "Schema has not been saved. Save it before configuring relative paths." ) ;
343354
@@ -350,78 +361,10 @@ private void ShowSchemaConfig()
350361 return ;
351362 }
352363
353- ImGui . TextUnformatted ( $ "Schema Path: { CurrentSchema . FilePath } ") ;
354-
355- bool projectRootIsSet = ValidateProjectRootIsSet ( ) ;
356- ShowSetProjectRoot ( ) ;
357- bool schemaLocationIsValid = ValidateSchemaLocation ( ) ;
358-
359- if ( projectRootIsSet && schemaLocationIsValid )
360- {
361- ImGui . TextUnformatted ( $ "Data Path: { CurrentSchema . RelativePaths . RelativeDataSourcePath } ") ;
362- ImGui . SameLine ( ) ;
363- if ( ImGui . Button ( "Set Data Path" ) )
364- {
365- Popups . OpenBrowserDirectory ( "Select Data Path" , ( path ) => CurrentSchema . RelativePaths . RelativeDataSourcePath = path . RelativeTo ( CurrentSchema . ProjectRootPath ) ) ;
366- }
367- }
364+ ImGui . TextUnformatted ( $ "Schema Path: { CurrentSchemaPath } ") ;
368365 }
369366 }
370367
371- private bool ValidateProjectRootIsSet ( )
372- {
373- if ( string . IsNullOrEmpty ( CurrentSchema ? . RelativePaths . RelativeProjectRootPath ) )
374- {
375- using ( Theme . Color ( Theme . Palette . Warning ) )
376- {
377- ImGui . TextUnformatted ( "Set the path of the project's root directory." ) ;
378- }
379-
380- return false ;
381- }
382-
383- return true ;
384- }
385-
386- private void ShowSetProjectRoot ( )
387- {
388- if ( CurrentSchema is not null )
389- {
390- ImGui . TextUnformatted ( $ "Project Root Path: { CurrentSchema . RelativePaths . RelativeProjectRootPath } ") ;
391- ImGui . SameLine ( ) ;
392- if ( ImGui . Button ( "Set Project Root" ) )
393- {
394- Popups . OpenBrowserDirectory ( "Select Project Root" , ( path ) => CurrentSchema . RelativePaths . RelativeProjectRootPath = path . RelativeTo ( CurrentSchema . FilePath ) ) ;
395- }
396- }
397- }
398-
399- private bool ValidateSchemaLocation ( )
400- {
401- if ( CurrentSchema is not null )
402- {
403- AbsoluteFilePath absoluteSchemaPath = ( AbsoluteFilePath ) Path . GetFullPath ( CurrentSchema . FilePath ) ;
404- AbsoluteDirectoryPath expectedProjectRoot = ( AbsoluteDirectoryPath ) Path . GetFullPath ( CurrentSchema . FilePath . DirectoryPath / CurrentSchema . RelativePaths . RelativeProjectRootPath ) ;
405- RelativeFilePath expectedRelativeSchemaPath = ( RelativeFilePath ) absoluteSchemaPath . WeakString . RemovePrefix ( expectedProjectRoot ) ;
406- AbsoluteFilePath expectedSchemaPath = expectedProjectRoot / expectedRelativeSchemaPath ;
407- if ( Path . GetFullPath ( expectedSchemaPath ) != Path . GetFullPath ( absoluteSchemaPath ) )
408- {
409- using ( Theme . Color ( Theme . Palette . Error ) )
410- {
411- ImGui . TextUnformatted ( "Schema appears to have been moved." ) ;
412- ImGui . TextUnformatted ( "Reset the path of the project's root directory." ) ;
413- }
414-
415- ImGui . TextUnformatted ( $ "Expected: { expectedSchemaPath } ") ;
416- ImGui . TextUnformatted ( $ "Actual: { absoluteSchemaPath } ") ;
417-
418- return false ;
419- }
420- }
421-
422- return true ;
423- }
424-
425368 internal void EditClass ( ClassName name ) => EditClass ( CurrentSchema ? . GetClass ( name ) ) ;
426369
427370 internal void EditClass ( SchemaClass ? schemaClass )
0 commit comments