Editor/MainWindow.cs
using Sandbox.Diagnostics;
using System.IO;
using System.Linq;
namespace Panelize;
[EditorApp( "Panelize", "preview", "Create and preview UI panels." )]
public partial class MainWindow : DockWindow
{
public static MainWindow Instance { get; private set; }
private Editor.ActionGraphs.UndoStack undoStack;
private Option undoMenuOption;
private Option redoMenuOption;
internal List<PanelEditor> editors = new();
private PanelList list;
private Properties properties;
private PanelEditorConfig config;
public MainWindow()
{
if(Instance.IsValid())
{
Instance.Focus();
Destroy();
return;
//Instance.Destroy();
}
Instance = this;
DeleteOnClose = true;
Title = "Panelize";
Size = new Vector2( 1920, 1080f );
undoStack = new( () => "Serialize" );
BuildUI();
Show();
MakeMaximized();
Focus();
}
~MainWindow()
{
if(Instance == this || !Instance.IsValid())
Instance = null;
}
private void BuildUI()
{
BuildMenuBar();
RestoreDefaultDockLayout();
}
private void BuildMenuBar()
{
MenuBar.Clear();
var file = MenuBar.AddMenu( "File" );
file.AddOption( "New", "common/new.png", New, "editor.new" ).StatusTip = "New Graph";
file.AddOption( "Open", "common/open.png", Open, "editor.open" ).StatusTip = "Open Graph";
file.AddOption( "Save", "common/save.png", Save, "editor.save" ).StatusTip = "Save Graph";
file.AddOption( "Save As...", "common/save.png", SaveAs, "editor.save-as" ).StatusTip = "Save Graph As...";
file.AddSeparator();
file.AddOption( "Quit", null, Quit, "editor.quit" ).StatusTip = "Quit";
/*
var edit = MenuBar.AddMenu( "Edit" );
undoMenuOption = edit.AddOption( "Undo", "undo", Undo, "editor.undo" );
redoMenuOption = edit.AddOption( "Redo", "redo", Redo, "editor.redo" );
*/
/*
edit.AddSeparator();
edit.AddOption( "Cut", "common/cut.png", CutSelection, "editor.cut" );
edit.AddOption( "Copy", "common/copy.png", CopySelection, "editor.copy" );
edit.AddOption( "Paste", "common/paste.png", PasteSelection, "editor.paste" );
edit.AddOption( "Select All", "select_all", SelectAll, "editor.select-all" );
*/
var view = MenuBar.AddMenu( "View" );
view.AboutToShow += () => OnViewMenu( view );
}
protected override void RestoreDefaultDockLayout()
{
PanelEditorSession.Current = null;
Properties.SelectedObject = null;
editors.Clear();
DockManager.Clear();
DockManager.RegisterDockType( "Inspector", "edit", () => new Properties( this ) );
DockManager.RegisterDockType( "Panels", "web_asset", () => new PanelList( ) );
config = new();
properties = new( this );
list = new();
DockManager.AddDock( null, list, DockArea.Left, DockManager.DockProperty.HideOnClose, 0.3f );
DockManager.AddDock( null, properties, DockArea.Right, DockManager.DockProperty.HideOnClose, 0.8f );
DockManager.AddDock( properties, config, DockArea.Left, DockManager.DockProperty.HideCloseButton | DockManager.DockProperty.DisallowUserDocking, 0.7f );
// Add empty editor
//CreateEditor();
}
private void OnViewMenu( Menu view )
{
view.Clear();
view.AddOption( "Restore To Default", "settings_backup_restore", RestoreDefaultDockLayout );
view.AddSeparator();
foreach ( var dock in DockManager.DockTypes )
{
var o = view.AddOption( dock.Title, dock.Icon );
o.Checkable = true;
o.Checked = DockManager.IsDockOpen( dock.Title );
o.Toggled += ( b ) => DockManager.SetDockState( dock.Title, b );
}
}
public PanelEditor CreateEditor()
{
PanelEditor editor = new();
if ( editors.Count > 0 )
{
DockManager.AddDock( editors.First(), editor, DockArea.Inside, DockManager.DockProperty.DisallowFloatWindow );
}
else
{
DockManager.AddDock( config, editor, DockArea.Inside, DockManager.DockProperty.DisallowFloatWindow );
}
editors.Add( editor );
editor.Session.MakeActive();
return editor;
}
public void RemoveEditor(PanelEditor editor)
{
editors.Remove( editor );
if(editors.Count != 0)
{
editors.Last().Session.MakeActive();
}
}
private void New()
{
var editor = CreateEditor();
editor.Session.MakeActive();
}
private void Open()
{
FileDialog openDialog = new( null )
{
Title = "Open Razor Panel",
DefaultSuffix = $".razor"
};
openDialog.SetFindExistingFile();
openDialog.SetNameFilter( "Razor Files (*.razor)" );
if ( !openDialog.Execute() )
return;
Open( openDialog.SelectedFile );
}
private void Open(string path )
{
var editor = CreateEditor();
if ( !editor.IsValid() ) return;
editor.Session.LoadPanel( path );
editor.Session.MakeActive();
}
private void Save()
{
var session = PanelEditorSession.Current;
if ( string.IsNullOrEmpty( session.FilePath ))
{
SaveAs();
return;
}
Save( session, session.FilePath );
}
private void SaveAs()
{
FileDialog saveDialog = new( null )
{
Title = "Save Razor Panel",
DefaultSuffix = $".razor",
};
saveDialog.SetNameFilter( "Razor Files (*.razor)" );
if ( !saveDialog.Execute() )
return;
Save( PanelEditorSession.Current, saveDialog.SelectedFile );
}
private void Save(PanelEditorSession session, string path)
{
Dialog.AskConfirm( () => DoSave( session, path ), $"Do you want to save? Panelize is experimental and might destroy your razor file." );
}
private void DoSave( PanelEditorSession session, string path )
{
ArgumentNullException.ThrowIfNull( session );
Assert.False( string.IsNullOrEmpty( path ) );
// 1) Remove directory from path
// 2) Remove file extension from path
string panelName = path.Split( '/', '\\' ).Last()
.Split( '.' ).First();
string content = PanelSerializer.SerializeSession( session, true, panelName );
File.WriteAllText( path, content );
}
private void Quit()
{
Close();
}
private void Redo()
{
throw new NotImplementedException();
}
private void Undo()
{
throw new NotImplementedException();
}
}