Browse Source

View menu items

Krzysztof Krysiński 1 year ago
parent
commit
522212faf0

+ 2 - 1
src/PixiEditor.AvaloniaUI/Data/Localization/Languages/en.json

@@ -591,5 +591,6 @@
   "BROWSE_DIRECTORY": "Browse Directory",
   "CRASH_NOT_ALL_DOCUMENTS_RECOVERED_TITLE": "Not all documents were recovered",
   "CRASH_NOT_ALL_DOCUMENTS_RECOVERED": "Could not recover all documents. Git gud at saving your work.",
-  "SEND": "Send report"
+  "SEND": "Send report",
+  "OPEN_DOCKABLE_MENU": "Open Tab"
 }

+ 5 - 1
src/PixiEditor.AvaloniaUI/Helpers/ServiceCollectionHelpers.cs

@@ -11,6 +11,7 @@ using PixiEditor.AvaloniaUI.Models.IO.PaletteParsers.JascPalFile;
 using PixiEditor.AvaloniaUI.Models.Localization;
 using PixiEditor.AvaloniaUI.Models.Palettes;
 using PixiEditor.AvaloniaUI.Models.Preferences;
+using PixiEditor.AvaloniaUI.ViewModels.Dock;
 using PixiEditor.AvaloniaUI.ViewModels.Document;
 using PixiEditor.AvaloniaUI.ViewModels.Menu;
 using PixiEditor.AvaloniaUI.ViewModels.Menu.MenuBuilders;
@@ -63,6 +64,7 @@ internal static class ServiceCollectionHelpers
             .AddSingleton<SearchViewModel>()
             .AddSingleton<ISearchHandler, SearchViewModel>(x => x.GetRequiredService<SearchViewModel>())
             .AddSingleton<AdditionalContentViewModel>()
+            .AddSingleton<LayoutManager>()
             .AddSingleton<LayoutViewModel>()
             .AddSingleton(x => new ExtensionsViewModel(x.GetService<ViewModelMain>(), extensionLoader))
             // Controllers
@@ -116,7 +118,9 @@ internal static class ServiceCollectionHelpers
     {
         return collection
             .AddSingleton<MenuItemBuilder, RecentFilesMenuBuilder>()
-            .AddSingleton<MenuItemBuilder, FileExitMenuBuilder>();
+            .AddSingleton<MenuItemBuilder, FileExitMenuBuilder>()
+            .AddSingleton<MenuItemBuilder, SymmetryMenuBuilder>()
+            .AddSingleton<MenuItemBuilder, OpenDockablesMenuBuilder>();
     }
 
     public static IServiceCollection AddExtensionServices(this IServiceCollection collection, ExtensionLoader loader) =>

+ 1 - 1
src/PixiEditor.AvaloniaUI/Models/Commands/XAML/Command.cs

@@ -41,7 +41,7 @@ internal class Command : MarkupExtension
             commandController = CommandController.Current; // TODO: Find a better way to get the current CommandController
         }
 
-        var command = commandController.Commands[Name];
+        Commands.Command command = commandController.Commands[Name];
         return GetPixiCommand ? command : GetICommand(command, UseProvided);
     }
 

+ 20 - 10
src/PixiEditor.AvaloniaUI/ViewModels/Document/DocumentManagerViewModel.cs

@@ -62,12 +62,16 @@ internal class DocumentManagerViewModel : SubViewModel<ViewModelMain>, IDocument
         MenuItemPath = "IMAGE/CLIP_CANVAS", MenuItemOrder = 2)]
     public void ClipCanvas() => ActiveDocument?.Operations.ClipCanvas();
 
-    [Command.Basic("PixiEditor.Document.FlipImageHorizontal", FlipType.Horizontal, "FLIP_IMG_HORIZONTALLY", "FLIP_IMG_HORIZONTALLY", CanExecute = "PixiEditor.HasDocument")]
-    [Command.Basic("PixiEditor.Document.FlipImageVertical", FlipType.Vertical, "FLIP_IMG_VERTICALLY", "FLIP_IMG_VERTICALLY", CanExecute = "PixiEditor.HasDocument")]
+    [Command.Basic("PixiEditor.Document.FlipImageHorizontal", FlipType.Horizontal, "FLIP_IMG_HORIZONTALLY", "FLIP_IMG_HORIZONTALLY", CanExecute = "PixiEditor.HasDocument",
+        MenuItemPath = "IMAGE/FLIP/FLIP_IMG_HORIZONTALLY", MenuItemOrder = 14)]
+    [Command.Basic("PixiEditor.Document.FlipImageVertical", FlipType.Vertical, "FLIP_IMG_VERTICALLY", "FLIP_IMG_VERTICALLY", CanExecute = "PixiEditor.HasDocument",
+        MenuItemPath = "IMAGE/FLIP/FLIP_IMG_VERTICALLY", MenuItemOrder = 15)]
     public void FlipImage(FlipType type) => ActiveDocument?.Operations.FlipImage(type);
 
-    [Command.Basic("PixiEditor.Document.FlipLayersHorizontal", FlipType.Horizontal, "FLIP_LAYERS_HORIZONTALLY", "FLIP_LAYERS_HORIZONTALLY", CanExecute = "PixiEditor.HasDocument")]
-    [Command.Basic("PixiEditor.Document.FlipLayersVertical", FlipType.Vertical, "FLIP_LAYERS_VERTICALLY", "FLIP_LAYERS_VERTICALLY", CanExecute = "PixiEditor.HasDocument")]
+    [Command.Basic("PixiEditor.Document.FlipLayersHorizontal", FlipType.Horizontal, "FLIP_LAYERS_HORIZONTALLY", "FLIP_LAYERS_HORIZONTALLY", CanExecute = "PixiEditor.HasDocument",
+        MenuItemPath = "IMAGE/FLIP/FLIP_LAYERS_HORIZONTALLY", MenuItemOrder = 16)]
+    [Command.Basic("PixiEditor.Document.FlipLayersVertical", FlipType.Vertical, "FLIP_LAYERS_VERTICALLY", "FLIP_LAYERS_VERTICALLY", CanExecute = "PixiEditor.HasDocument",
+        MenuItemPath = "IMAGE/FLIP/FLIP_LAYERS_VERTICALLY", MenuItemOrder = 17)]
     public void FlipLayers(FlipType type)
     {
         if (ActiveDocument?.SelectedStructureMember == null)
@@ -77,19 +81,25 @@ internal class DocumentManagerViewModel : SubViewModel<ViewModelMain>, IDocument
     }
 
     [Command.Basic("PixiEditor.Document.Rotate90Deg", "ROT_IMG_90",
-        "ROT_IMG_90", CanExecute = "PixiEditor.HasDocument", Parameter = RotationAngle.D90)]
+        "ROT_IMG_90", CanExecute = "PixiEditor.HasDocument", Parameter = RotationAngle.D90,
+        MenuItemPath = "IMAGE/ROTATION/ROT_IMG_90_D", MenuItemOrder = 8)]
     [Command.Basic("PixiEditor.Document.Rotate180Deg", "ROT_IMG_180",
-        "ROT_IMG_180", CanExecute = "PixiEditor.HasDocument", Parameter = RotationAngle.D180)]
+        "ROT_IMG_180", CanExecute = "PixiEditor.HasDocument", Parameter = RotationAngle.D180,
+        MenuItemPath = "IMAGE/ROTATION/ROT_IMG_180_D", MenuItemOrder = 9)]
     [Command.Basic("PixiEditor.Document.Rotate270Deg", "ROT_IMG_-90",
-        "ROT_IMG_-90", CanExecute = "PixiEditor.HasDocument", Parameter = RotationAngle.D270)]
+        "ROT_IMG_-90", CanExecute = "PixiEditor.HasDocument", Parameter = RotationAngle.D270,
+        MenuItemPath = "IMAGE/ROTATION/ROT_IMG_-90_D", MenuItemOrder = 10)]
     public void RotateImage(RotationAngle angle) => ActiveDocument?.Operations.RotateImage(angle);
 
     [Command.Basic("PixiEditor.Document.Rotate90DegLayers", "ROT_LAYERS_90",
-        "ROT_LAYERS_90", CanExecute = "PixiEditor.HasDocument", Parameter = RotationAngle.D90)]
+        "ROT_LAYERS_90", CanExecute = "PixiEditor.HasDocument", Parameter = RotationAngle.D90,
+        MenuItemPath = "IMAGE/ROTATION/ROT_LAYERS_90_D", MenuItemOrder = 11)]
     [Command.Basic("PixiEditor.Document.Rotate180DegLayers", "ROT_LAYERS_180",
-        "ROT_LAYERS_180", CanExecute = "PixiEditor.HasDocument", Parameter = RotationAngle.D180)]
+        "ROT_LAYERS_180", CanExecute = "PixiEditor.HasDocument", Parameter = RotationAngle.D180,
+        MenuItemPath = "IMAGE/ROTATION/ROT_LAYERS_180_D", MenuItemOrder = 12)]
     [Command.Basic("PixiEditor.Document.Rotate270DegLayers", "ROT_LAYERS_-90",
-        "ROT_LAYERS_-90", CanExecute = "PixiEditor.HasDocument", Parameter = RotationAngle.D270)]
+        "ROT_LAYERS_-90", CanExecute = "PixiEditor.HasDocument", Parameter = RotationAngle.D270,
+        MenuItemPath = "IMAGE/ROTATION/ROT_LAYERS_-90_D", MenuItemOrder = 13)]
     public void RotateLayers(RotationAngle angle)
     {
         if (ActiveDocument?.SelectedStructureMember == null)

+ 3 - 1
src/PixiEditor.AvaloniaUI/ViewModels/Menu/MenuBuilders/FileExitMenuBuilder.cs

@@ -2,6 +2,7 @@
 using Avalonia.Controls;
 using PixiEditor.AvaloniaUI.Views;
 using PixiEditor.Extensions.Common.Localization;
+using PixiEditor.Extensions.UI;
 
 namespace PixiEditor.AvaloniaUI.ViewModels.Menu.MenuBuilders;
 
@@ -13,11 +14,12 @@ internal class FileExitMenuBuilder : MenuItemBuilder
         {
             var exitMenuItem = new MenuItem
             {
-                Header = new LocalizedString("EXIT"),
                 Command = SystemCommands.CloseWindowCommand,
                 CommandParameter = MainWindow.Current
             };
 
+            Translator.SetKey(exitMenuItem, "EXIT");
+
             fileMenuItem!.Items.Add(new Separator());
             fileMenuItem!.Items.Add(exitMenuItem);
         }

+ 51 - 0
src/PixiEditor.AvaloniaUI/ViewModels/Menu/MenuBuilders/OpenDockablesMenuBuilder.cs

@@ -0,0 +1,51 @@
+using System.Collections.Generic;
+using System.Windows.Input;
+using Avalonia.Controls;
+using Avalonia.Media;
+using PixiEditor.AvaloniaUI.Models.Commands;
+using PixiEditor.Extensions.UI;
+using LayoutManager = PixiEditor.AvaloniaUI.ViewModels.Dock.LayoutManager;
+
+namespace PixiEditor.AvaloniaUI.ViewModels.Menu.MenuBuilders;
+
+internal class OpenDockablesMenuBuilder : MenuItemBuilder
+{
+    public LayoutManager LayoutManager { get; set; }
+
+    public OpenDockablesMenuBuilder(LayoutManager layoutManager)
+    {
+        LayoutManager = layoutManager;
+    }
+
+    public override void ModifyMenuTree(ICollection<MenuItem> tree)
+    {
+        if (TryFindMenuItem(tree, "VIEW", out MenuItem? viewItem))
+        {
+            MenuItem dockablesItem = new MenuItem();
+            Translator.SetKey(dockablesItem, "OPEN_DOCKABLE_MENU");
+
+            viewItem!.Items.Add(dockablesItem);
+
+            foreach (var dockable in LayoutManager.RegisteredDockables)
+            {
+                MenuItem dockableItem = new MenuItem();
+                Translator.SetKey(dockableItem, dockable.Title);
+
+                string commandId = "PixiEditor.Window.ShowDockWindow";
+
+                dockableItem.Command =
+                    (ICommand)new Models.Commands.XAML.Command(commandId) { UseProvided = true }
+                        .ProvideValue(null);
+                dockableItem.CommandParameter = dockable.Id;
+
+                dockableItem.Icon = new Image()
+                {
+                    Source = (IImage?)dockable.TabCustomizationSettings?.Icon,
+                    Width = Models.Commands.XAML.Menu.IconDimensions,
+                    Height = Models.Commands.XAML.Menu.IconDimensions
+                };
+                dockablesItem.Items.Add(dockableItem);
+            }
+        }
+    }
+}

+ 4 - 4
src/PixiEditor.AvaloniaUI/ViewModels/Menu/MenuBuilders/RecentFilesMenuBuilder.cs

@@ -6,6 +6,7 @@ using Avalonia.Styling;
 using PixiEditor.AvaloniaUI.Models.UserData;
 using PixiEditor.AvaloniaUI.ViewModels.SubViewModels;
 using PixiEditor.Extensions.Common.Localization;
+using PixiEditor.Extensions.UI;
 
 namespace PixiEditor.AvaloniaUI.ViewModels.Menu;
 
@@ -22,10 +23,9 @@ internal class RecentFilesMenuBuilder : MenuItemBuilder
     {
         if(TryFindMenuItem(tree, "FILE", out MenuItem? fileMenuItem))
         {
-            var recentFilesMenuItem = new MenuItem
-            {
-                Header = new LocalizedString("RECENT")
-            };
+            var recentFilesMenuItem = new MenuItem();
+
+            Translator.SetKey(recentFilesMenuItem, "RECENT");
 
             Style style = new Style((selector => selector.OfType<MenuItem>()))
             {

+ 63 - 0
src/PixiEditor.AvaloniaUI/ViewModels/Menu/MenuBuilders/SymmetryMenuBuilder.cs

@@ -0,0 +1,63 @@
+using System.Collections.Generic;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Data;
+using Avalonia.Input;
+using PixiEditor.AvaloniaUI.Helpers.Converters;
+using PixiEditor.AvaloniaUI.Views.Input;
+using PixiEditor.Extensions.UI;
+
+namespace PixiEditor.AvaloniaUI.ViewModels.Menu.MenuBuilders;
+
+internal class SymmetryMenuBuilder : MenuItemBuilder
+{
+    public override void ModifyMenuTree(ICollection<MenuItem> tree)
+    {
+        if (TryFindMenuItem(tree, "IMAGE", out MenuItem? viewItem))
+        {
+            int index = viewItem!.Items.Count >= 3 ? 3 : viewItem.Items.Count - 1;
+            viewItem!.Items.Insert(index, new Separator());
+            ToggleableMenuItem horizontalSymmetryItem = new ToggleableMenuItem();
+            Translator.SetKey(horizontalSymmetryItem, "HORIZONTAL_LINE_SYMMETRY");
+            horizontalSymmetryItem.Icon = new Image()
+            {
+                Source = ImagePathToBitmapConverter.LoadBitmapFromRelativePath("/Images/SymmetryHorizontal.png"),
+                Width = Models.Commands.XAML.Menu.IconDimensions,
+                Height = Models.Commands.XAML.Menu.IconDimensions
+            };
+
+            BindItem(horizontalSymmetryItem, "DocumentManagerSubViewModel.ActiveDocument.HorizontalSymmetryAxisEnabledBindable");
+            viewItem.Items.Insert(index + 1, horizontalSymmetryItem);
+
+            ToggleableMenuItem verticalSymmetryItem = new ToggleableMenuItem();
+            Translator.SetKey(verticalSymmetryItem, "VERTICAL_LINE_SYMMETRY");
+            verticalSymmetryItem.Icon = new Image()
+            {
+                Source = ImagePathToBitmapConverter.LoadBitmapFromRelativePath("/Images/SymmetryVertical.png"),
+                Width = Models.Commands.XAML.Menu.IconDimensions,
+                Height = Models.Commands.XAML.Menu.IconDimensions
+            };
+
+            BindItem(verticalSymmetryItem, "DocumentManagerSubViewModel.ActiveDocument.VerticalSymmetryAxisEnabledBindable");
+            viewItem.Items.Insert(index + 2, verticalSymmetryItem);
+            viewItem.Items.Insert(index + 3, new Separator());
+        }
+    }
+
+    private void BindItem(ToggleableMenuItem item, string checkedBindingPath)
+    {
+        Binding isEnabledBinding = new Binding("!!DocumentManagerSubViewModel.ActiveDocument")
+        {
+            Source = ViewModelMain.Current
+        };
+
+        Binding isCheckedBinding = new Binding(checkedBindingPath)
+        {
+            Source = ViewModelMain.Current,
+            Mode = BindingMode.TwoWay
+        };
+
+        item.Bind(ToggleableMenuItem.IsCheckedProperty, isCheckedBinding);
+        item.Bind(InputElement.IsEnabledProperty, isEnabledBinding);
+    }
+}

+ 2 - 2
src/PixiEditor.AvaloniaUI/ViewModels/SubViewModels/LayoutViewModel.cs

@@ -13,9 +13,9 @@ internal class LayoutViewModel : SubViewModel<ViewModelMain>
         private init => SetProperty(ref layoutManagerManager, value);
     }
 
-    public LayoutViewModel(ViewModelMain owner) : base(owner)
+    public LayoutViewModel(ViewModelMain owner, LayoutManager layoutManager) : base(owner)
     {
-        LayoutManager = new();
+        LayoutManager = layoutManager;
         owner.WindowSubViewModel.ViewportAdded += WindowSubViewModel_ViewportAdded;
         owner.WindowSubViewModel.ViewportClosed += WindowSubViewModel_ViewportRemoved;
     }

+ 8 - 8
src/PixiEditor.AvaloniaUI/ViewModels/SubViewModels/SelectionViewModel.cs

@@ -15,7 +15,7 @@ internal class SelectionViewModel : SubViewModel<ViewModelMain>
     }
 
     [Command.Basic("PixiEditor.Selection.SelectAll", "SELECT_ALL", "SELECT_ALL_DESCRIPTIVE", CanExecute = "PixiEditor.HasDocument", Key = Key.A, Modifiers = KeyModifiers.Control,
-        MenuItemPath = "EDIT/SELECT/SELECT_ALL", MenuItemOrder = 8)]
+        MenuItemPath = "SELECT/SELECT_ALL", MenuItemOrder = 8)]
     public void SelectAll()
     {
         var doc = Owner.DocumentManagerSubViewModel.ActiveDocument;
@@ -25,7 +25,7 @@ internal class SelectionViewModel : SubViewModel<ViewModelMain>
     }
 
     [Command.Basic("PixiEditor.Selection.Clear", "CLEAR_SELECTION", "CLEAR_SELECTION", CanExecute = "PixiEditor.Selection.IsNotEmpty", Key = Key.D, Modifiers = KeyModifiers.Control,
-        MenuItemPath = "EDIT/SELECT/DESELECT", MenuItemOrder = 9)]
+        MenuItemPath = "SELECT/DESELECT", MenuItemOrder = 9)]
     public void ClearSelection()
     {
         var doc = Owner.DocumentManagerSubViewModel.ActiveDocument;
@@ -35,7 +35,7 @@ internal class SelectionViewModel : SubViewModel<ViewModelMain>
     }
 
     [Command.Basic("PixiEditor.Selection.InvertSelection", "INVERT_SELECTION", "INVERT_SELECTION_DESCRIPTIVE", CanExecute = "PixiEditor.Selection.IsNotEmpty", Key = Key.I, Modifiers = KeyModifiers.Control,
-        MenuItemPath = "EDIT/SELECT/INVERT", MenuItemOrder = 10)]
+        MenuItemPath = "SELECT/INVERT", MenuItemOrder = 10)]
     public void InvertSelection()
     {
         Owner.DocumentManagerSubViewModel.ActiveDocument?.Operations.InvertSelection();
@@ -70,13 +70,13 @@ internal class SelectionViewModel : SubViewModel<ViewModelMain>
     }
 
     [Command.Basic("PixiEditor.Selection.NewToMask", SelectionMode.New, "MASK_FROM_SELECTION", "MASK_FROM_SELECTION_DESCRIPTIVE", CanExecute = "PixiEditor.Selection.IsNotEmpty",
-        MenuItemPath = "EDIT/SELECT/SELECTION_TO_MASK/TO_NEW_MASK", MenuItemOrder = 12)]
+        MenuItemPath = "SELECT/SELECTION_TO_MASK/TO_NEW_MASK", MenuItemOrder = 12)]
     [Command.Basic("PixiEditor.Selection.AddToMask", SelectionMode.Add, "ADD_SELECTION_TO_MASK", "ADD_SELECTION_TO_MASK", CanExecute = "PixiEditor.Selection.IsNotEmpty",
-        MenuItemPath = "EDIT/SELECT/SELECTION_TO_MASK/ADD_TO_MASK", MenuItemOrder = 13)]
+        MenuItemPath = "SELECT/SELECTION_TO_MASK/ADD_TO_MASK", MenuItemOrder = 13)]
     [Command.Basic("PixiEditor.Selection.SubtractFromMask", SelectionMode.Subtract, "SUBTRACT_SELECTION_FROM_MASK", "SUBTRACT_SELECTION_FROM_MASK", CanExecute = "PixiEditor.Selection.IsNotEmptyAndHasMask",
-        MenuItemPath = "EDIT/SELECT/SELECTION_TO_MASK/SUBTRACT_FROM_MASK", MenuItemOrder = 14)]
+        MenuItemPath = "SELECT/SELECTION_TO_MASK/SUBTRACT_FROM_MASK", MenuItemOrder = 14)]
     [Command.Basic("PixiEditor.Selection.IntersectSelectionMask", SelectionMode.Intersect, "INTERSECT_SELECTION_MASK", "INTERSECT_SELECTION_MASK", CanExecute = "PixiEditor.Selection.IsNotEmptyAndHasMask",
-        MenuItemPath = "EDIT/SELECT/SELECTION_TO_MASK/INTERSECT_WITH_MASK", MenuItemOrder = 15)]
+        MenuItemPath = "SELECT/SELECTION_TO_MASK/INTERSECT_WITH_MASK", MenuItemOrder = 15)]
     [Command.Filter("PixiEditor.Selection.ToMaskMenu", "SELECTION_TO_MASK", "SELECTION_TO_MASK", Key = Key.M, Modifiers = KeyModifiers.Control)]
     public void SelectionToMask(SelectionMode mode)
     {
@@ -84,7 +84,7 @@ internal class SelectionViewModel : SubViewModel<ViewModelMain>
     }
 
     [Command.Basic("PixiEditor.Selection.CropToSelection", "CROP_TO_SELECTION", "CROP_TO_SELECTION_DESCRIPTIVE", CanExecute = "PixiEditor.Selection.IsNotEmpty",
-        MenuItemPath = "EDIT/SELECT/CROP_TO_SELECTION", MenuItemOrder = 11)]
+        MenuItemPath = "SELECT/CROP_TO_SELECTION", MenuItemOrder = 11)]
     public void CropToSelection()
     {
         var document = Owner.DocumentManagerSubViewModel.ActiveDocument;

+ 8 - 4
src/PixiEditor.AvaloniaUI/ViewModels/SubViewModels/WindowViewModel.cs

@@ -49,7 +49,8 @@ internal class WindowViewModel : SubViewModel<ViewModelMain>
         this.commandController = commandController;
     }
 
-    [Command.Basic("PixiEditor.Window.CreateNewViewport", "NEW_WINDOW_FOR_IMG", "NEW_WINDOW_FOR_IMG", IconPath = "@Images/Plus-square.png", CanExecute = "PixiEditor.HasDocument")]
+    [Command.Basic("PixiEditor.Window.CreateNewViewport", "NEW_WINDOW_FOR_IMG", "NEW_WINDOW_FOR_IMG", IconPath = "@Images/Plus-square.png", CanExecute = "PixiEditor.HasDocument",
+        MenuItemPath = "VIEW/NEW_WINDOW_FOR_IMG", MenuItemOrder = 0)]
     public void CreateNewViewport()
     {
         var doc = ViewModelMain.Current?.DocumentManagerSubViewModel.ActiveDocument;
@@ -157,13 +158,15 @@ internal class WindowViewModel : SubViewModel<ViewModelMain>
         settings.Show();
     }
 
-    [Command.Basic("PixiEditor.Window.OpenStartupWindow", "OPEN_STARTUP_WINDOW", "OPEN_STARTUP_WINDOW")]
+    [Command.Basic("PixiEditor.Window.OpenStartupWindow", "OPEN_STARTUP_WINDOW", "OPEN_STARTUP_WINDOW",
+        MenuItemPath = "VIEW/OPEN_STARTUP_WINDOW", MenuItemOrder = 1)]
     public void OpenHelloThereWindow()
     {
         new HelloTherePopup(Owner.FileSubViewModel).Show(MainWindow.Current);
     }
 
-    [Command.Basic("PixiEditor.Window.OpenShortcutWindow", "OPEN_SHORTCUT_WINDOW", "OPEN_SHORTCUT_WINDOW", Key = Key.F1)]
+    [Command.Basic("PixiEditor.Window.OpenShortcutWindow", "OPEN_SHORTCUT_WINDOW", "OPEN_SHORTCUT_WINDOW", Key = Key.F1,
+        MenuItemPath = "VIEW/OPEN_SHORTCUT_WINDOW", MenuItemOrder = 2)]
     public void ShowShortcutWindow()
     {
         ShortcutsPopup.Show();
@@ -171,7 +174,7 @@ internal class WindowViewModel : SubViewModel<ViewModelMain>
     }
 
     [Command.Basic("PixiEditor.Window.OpenPalettesBrowserWindow", "OPEN_PALETTE_BROWSER", "OPEN_PALETTE_BROWSER",
-        IconPath = "Database.png")]
+        IconPath = "Database.png", MenuItemPath = "VIEW/OPEN_PALETTE_BROWSER", MenuItemOrder = 3)]
     public void ShowPalettesBrowserWindow()
     {
         PalettesBrowser.Open();
@@ -183,6 +186,7 @@ internal class WindowViewModel : SubViewModel<ViewModelMain>
         new AboutPopup().Show();
     }
 
+    [Command.Internal("PixiEditor.Window.ShowDockWindow")]
     [Command.Basic("PixiEditor.Window.OpenNavigationWindow", "Navigator", "OPEN_NAVIGATION_WINDOW", "OPEN_NAVIGATION_WINDOW")]
     public void ShowDockWindow(string id)
     {