diff --git a/editor/App.axaml b/editor/App.axaml
index 3aed34e6d..2e5323c86 100644
--- a/editor/App.axaml
+++ b/editor/App.axaml
@@ -22,6 +22,7 @@
+
@@ -440,6 +441,8 @@
@@ -484,6 +487,7 @@
+
\ No newline at end of file
diff --git a/editor/Assets/AssetBrowserView.axaml b/editor/Assets/AssetBrowserView.axaml
index 80de4e38b..42522589d 100644
--- a/editor/Assets/AssetBrowserView.axaml
+++ b/editor/Assets/AssetBrowserView.axaml
@@ -47,6 +47,15 @@
Value="{StaticResource Red}" />
+
+
+
+
-
@@ -126,21 +135,21 @@
+ Padding="6">
+ VerticalAlignment="Center" Classes="compact-text" />
-
\ No newline at end of file
+
diff --git a/editor/Workspace/InspectorView.axaml b/editor/Workspace/InspectorView.axaml
index 7d80eeefe..415e8c4b0 100644
--- a/editor/Workspace/InspectorView.axaml
+++ b/editor/Workspace/InspectorView.axaml
@@ -10,10 +10,11 @@
d:DesignWidth="300"
d:DesignHeight="1000"
x:Class="editor.Workspace.InspectorView"
- Padding="8"
+ Padding="6"
Background="{StaticResource Bg2}"
x:DataType="vm:InspectorViewModel">
+
@@ -21,13 +22,13 @@
-
+
@@ -97,6 +98,18 @@
+
+
@@ -216,8 +229,7 @@
-
@@ -230,13 +242,13 @@
-
-
+ IsVisible="{Binding IsFloat}" Classes="compact-field" />
+ IsVisible="{Binding IsInt}" Classes="compact-field" />
+ IsVisible="{Binding IsEnum}" Classes="compact-field" />
+ IsVisible="{Binding IsBool}" Classes="compact-field" />
+ IsVisible="{Binding IsString}" Classes="compact-field" />
+ IsVisible="{Binding IsAssetRef}" Classes="compact-field" />
+ IsVisible="{Binding IsNodeRef}" Classes="compact-field" />
+ IsVisible="{Binding IsColor3}" Classes="compact-field" />
+ IsVisible="{Binding IsColor4}" Classes="compact-field" />
+ AddLabel="Add Element" Classes="compact-array">
@@ -335,38 +347,38 @@
Maximum="{Binding Max}"
Unit="{Binding Unit}"
IsEnabled="{Binding Editable}"
- IsVisible="{Binding IsFloat}" />
+ IsVisible="{Binding IsFloat}" Classes="compact-field" />
+ IsVisible="{Binding IsInt}" Classes="compact-field" />
+ IsVisible="{Binding IsBool}" Classes="compact-field" />
+ IsVisible="{Binding IsString}" Classes="compact-field" />
+ IsVisible="{Binding IsAssetRef}" Classes="compact-field" />
+ IsVisible="{Binding IsNodeRef}" Classes="compact-field" />
+ IsVisible="{Binding IsColor3}" Classes="compact-field" />
+ IsVisible="{Binding IsColor4}" Classes="compact-field" />
+ IsVisible="{Binding IsVec2}" Classes="compact-vector" />
+ IsVisible="{Binding IsVec3}" Classes="compact-vector" />
+ IsVisible="{Binding IsVec4}" Classes="compact-vector" />
@@ -412,12 +424,12 @@
+ IsVisible="{Binding IsReadOnlyText}" Classes="compact-text" />
-
+
-
@@ -430,13 +442,13 @@
-
-
+ IsVisible="{Binding IsVec2}" Classes="compact-vector" />
+ IsVisible="{Binding IsVec3}" Classes="compact-vector" />
+ IsVisible="{Binding IsVec4}" Classes="compact-vector" />
+ IsVisible="{Binding IsLayers}" Classes="compact-tags" />
@@ -491,7 +503,7 @@
-
@@ -502,14 +514,14 @@
-
@@ -523,7 +535,7 @@
-
@@ -534,18 +546,18 @@
+ Spacing="4">
-
@@ -562,7 +574,7 @@
HorizontalAlignment="Stretch"
Background="{StaticResource Bg4}"
CornerRadius="6"
- HorizontalContentAlignment="Center" />
+ HorizontalContentAlignment="Center" Classes="compact-control" />
@@ -570,7 +582,7 @@
-
@@ -583,7 +595,7 @@
+ Spacing="4">
+ VerticalAlignment="Center" Classes="compact-text" />
-
+
+
+
@@ -622,14 +636,14 @@
-
+
+ ColumnSpacing="4">
@@ -645,21 +659,21 @@
Padding="0"
HorizontalAlignment="Left"
Cursor="Hand"
- IsVisible="{Binding !IsEditingName}">
+ IsVisible="{Binding !IsEditingName}" Classes="inspector-name">
+ FontSize="14" />
+ Foreground="{StaticResource TextMuted}" Classes="compact-text" />
@@ -668,7 +682,7 @@
Background="{StaticResource Bg1}"
Text="{Binding FilterText, Mode=TwoWay}"
PlaceholderText="Filter parameters..."
- PlaceholderForeground="{StaticResource TextMuted}" />
+ PlaceholderForeground="{StaticResource TextMuted}" Classes="compact-control" />
@@ -684,17 +698,17 @@
Classes.warning="{Binding !Error}"
Classes.error="{Binding Error}"
CornerRadius="8"
- Padding="8">
+ Padding="6">
@@ -702,7 +716,7 @@
Foreground="{StaticResource Bg1}"
FontWeight="Bold"
TextWrapping="Wrap"
- VerticalAlignment="Center" />
+ VerticalAlignment="Center" Classes="compact-text" />
@@ -720,7 +734,7 @@
-
@@ -731,7 +745,7 @@
HorizontalAlignment="Center" />
+ TextAlignment="Center" Classes="compact-text" />
diff --git a/editor/Workspace/LabelWidthState.cs b/editor/Workspace/LabelWidthState.cs
new file mode 100644
index 000000000..74e9d1600
--- /dev/null
+++ b/editor/Workspace/LabelWidthState.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text.Json;
+using editor.Assets;
+
+namespace editor.Workspace;
+
+public sealed class LabelWidthState {
+ private readonly string m_path;
+ private readonly Dictionary m_widths;
+ private static LabelWidthState? s_project;
+ private LabelWidthState(string path, Dictionary widths) { m_path = path; m_widths = widths; }
+ public static LabelWidthState Load(string path) {
+ try {
+ return new LabelWidthState(path, File.Exists(path)
+ ? JsonSerializer.Deserialize>(File.ReadAllText(path)) ?? [] : []);
+ } catch { return new LabelWidthState(path, []); }
+ }
+ public static LabelWidthState? ForProject() {
+ if (!ProjectContext.IsInitialized) return null;
+ var path = ProjectContext.Resolve("cache://tools/label_widths.json");
+ if (s_project?.m_path != path) s_project = Load(path);
+ return s_project;
+ }
+ public double? Get(string key) => m_widths.TryGetValue(key, out var width) && double.IsFinite(width) && width >= 0 ? width : null;
+ public void Set(string key, double width) {
+ if (!double.IsFinite(width) || width < 0) return;
+ m_widths[key] = width;
+ try {
+ Directory.CreateDirectory(Path.GetDirectoryName(m_path)!);
+ var temp = m_path + ".tmp." + Guid.NewGuid().ToString("N");
+ File.WriteAllText(temp, JsonSerializer.Serialize(m_widths));
+ File.Move(temp, m_path, true);
+ } catch { /* Best-effort editor state. */ }
+ }
+}
diff --git a/editor/Workspace/MainWindowViewModel.cs b/editor/Workspace/MainWindowViewModel.cs
index a89caf1c9..274b61f8b 100644
--- a/editor/Workspace/MainWindowViewModel.cs
+++ b/editor/Workspace/MainWindowViewModel.cs
@@ -203,6 +203,9 @@ private void OnPlayModeChanged() {
SaveAllNodesCommand.NotifyCanExecuteChanged();
PlayCommand.NotifyCanExecuteChanged();
PlayInWindowCommand.NotifyCanExecuteChanged();
+ NewNodeCommand.NotifyCanExecuteChanged();
+ OpenNodeFileCommand.NotifyCanExecuteChanged();
+ foreach (var workspace in m_workspaces.Values) workspace.RefreshCanActivateTab();
}
private IEnumerable EnumerateAutosavables() {
@@ -403,6 +406,7 @@ private async void OnEditorOpenRequested(AssetFile file) {
if (file.Definition is not { CanBeEdited: true } def) return;
if (file.Uid is not { } uid) return;
if (!AssetDatabase.TryResolve(uid, out var virtualPath, out _)) return;
+ if (def.EditorTool == "NodeEditor" && !CanOpenNodes()) return;
// Opening a lockable asset nobody holds takes its lock
if (def is not ProjectSettingsAsset && def.EditorTool != "NodeEditor")
@@ -823,7 +827,12 @@ private async Task DeleteLayout(string? name) {
if (string.Equals(ActiveLayoutName, name, StringComparison.Ordinal)) ResetLayout();
}
- [RelayCommand]
+ // no tab may open under a running game
+ private static bool CanOpenNodes() {
+ return !WorkspaceViewModel.AnyPlayActive;
+ }
+
+ [RelayCommand(CanExecute = nameof(CanOpenNodes))]
private async Task NewNode() {
if (App.MainWindow is not { } owner) return;
var popup = new NodeTypeTree();
@@ -835,7 +844,7 @@ private async Task NewNode() {
SyncActiveWorkspace();
}
- [RelayCommand]
+ [RelayCommand(CanExecute = nameof(CanOpenNodes))]
private async Task OpenNodeFile() {
if (App.MainWindow is not { } owner) return;
var uid = await new AssetList("Node").ShowDialog(owner);
diff --git a/editor/Workspace/ProjectSettingsView.axaml b/editor/Workspace/ProjectSettingsView.axaml
index 4add50fee..7606d2beb 100644
--- a/editor/Workspace/ProjectSettingsView.axaml
+++ b/editor/Workspace/ProjectSettingsView.axaml
@@ -49,7 +49,7 @@
+ Value="6" />