Browse Source

Add main menu bare bones

pull/3755/head
Siegfried Pammer 3 months ago
parent
commit
1b603c762a
  1. 49
      ILSpy.Tests/MainMenuTests.cs
  2. 5
      ILSpy/App.axaml.cs
  3. 12
      ILSpy/ViewModels/MainWindowViewModel.cs
  4. 18
      ILSpy/Views/MainMenu.axaml
  5. 4
      ILSpy/Views/MainMenu.axaml.cs
  6. 30
      ILSpy/Views/MainWindow.axaml
  7. 14
      ILSpy/Views/MainWindow.axaml.cs

49
ILSpy.Tests/MainMenuTests.cs

@ -0,0 +1,49 @@ @@ -0,0 +1,49 @@
// Copyright (c) 2026 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System.Linq;
using Avalonia.Controls;
using Avalonia.Headless.NUnit;
using AwesomeAssertions;
using ILSpy;
using NUnit.Framework;
namespace ICSharpCode.ILSpy.Tests;
// MainMenu's top-level structure (File / View / Window with mnemonic underscores) is the
// scaffolding every later commit hangs items onto via MEF. If a future commit accidentally
// drops one of these top-levels or shuffles the order, the [ExportMainMenuCommand] entries
// that target them by header would silently land in the wrong menu.
[TestFixture]
public class MainMenuTests
{
[AvaloniaTest]
public void MainMenu_top_level_items_are_File_View_Window_in_order()
{
var mainMenu = new MainMenu();
var menu = mainMenu.FindControl<Menu>("Menu");
menu.Should().NotBeNull();
var headers = menu!.Items.OfType<MenuItem>().Select(m => m.Header as string).ToList();
headers.Should().Equal("_File", "_View", "_Window");
}
}

5
ILSpy/App.axaml.cs

@ -56,9 +56,8 @@ namespace ILSpy @@ -56,9 +56,8 @@ namespace ILSpy
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = new MainWindow {
DataContext = new MainWindowViewModel(),
};
desktop.MainWindow = Composition?.GetExport<MainWindow>()
?? new MainWindow();
desktop.Exit += (_, _) => Composition?.Dispose();
}

12
ILSpy/ViewModels/MainWindowViewModel.cs

@ -16,10 +16,18 @@ @@ -16,10 +16,18 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System.Composition;
namespace ILSpy.ViewModels
{
[Export]
[Shared]
public partial class MainWindowViewModel : ViewModelBase
{
public string Greeting { get; } = "Welcome to Avalonia!";
public MainWindowViewModel()
{
}
public string Title => "ILSpy";
}
}
}

18
ILSpy/Views/MainMenu.axaml

@ -2,11 +2,17 @@ @@ -2,11 +2,17 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="23"
x:Class="ILSpy.MainMenu">
<Menu DockPanel.Dock="Top" Name="Menu" Height="23" KeyboardNavigation.TabNavigation="None">
<MenuItem Header="_File" Tag="_File">
<!-- content of file menu is added using MEF -->
</MenuItem>
</Menu>
<Menu DockPanel.Dock="Top" Name="Menu" Height="23">
<MenuItem Header="_File" Tag="_File">
<!-- MEF-populated content (task #10) -->
</MenuItem>
<MenuItem Header="_View" Tag="_View">
<!-- API visibility toggles, theme selection, etc. wired in task #10 / #3 -->
</MenuItem>
<MenuItem Header="_Window" Name="WindowMenuItem" Tag="_Window">
<!-- Tool-pane / tab-page entries wired in task #10 -->
</MenuItem>
</Menu>
</UserControl>

4
ILSpy/Views/MainMenu.axaml.cs

@ -16,9 +16,7 @@ @@ -16,9 +16,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace ILSpy;
@ -28,4 +26,4 @@ public partial class MainMenu : UserControl @@ -28,4 +26,4 @@ public partial class MainMenu : UserControl
{
InitializeComponent();
}
}
}

30
ILSpy/Views/MainWindow.axaml

@ -1,24 +1,36 @@ @@ -1,24 +1,36 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:ILSpy.ViewModels"
xmlns:local="using:ILSpy"
xmlns:local="using:ILSpy"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="500"
x:Class="ILSpy.Views.MainWindow"
x:DataType="vm:MainWindowViewModel"
Icon="/Assets/ILSpy.ico"
Title="ILSpy">
MinWidth="250" MinHeight="200"
UseLayoutRounding="True"
Title="{Binding Title}">
<Design.DataContext>
<!-- This only sets the DataContext for the previewer in an IDE,
to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
<vm:MainWindowViewModel/>
</Design.DataContext>
<Design.DataContext>
<vm:MainWindowViewModel />
</Design.DataContext>
<DockPanel>
<!-- Main menu -->
<local:MainMenu DockPanel.Dock="Top" />
</DockPanel>
<!-- Status bar (hidden by default, like WPF) -->
<Border DockPanel.Dock="Bottom" Height="26" IsVisible="False" Name="statusBar">
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Right"
Margin="8,0" Name="statusLabel" Text="Stand by..." />
</Border>
<!-- Placeholder for DockingManager (task #4: replace with Dock.Avalonia) -->
<ContentControl Name="DockHost">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center"
Foreground="Gray" FontStyle="Italic"
Text="Docking workspace will appear here." />
</ContentControl>
</DockPanel>
</Window>

14
ILSpy/Views/MainWindow.axaml.cs

@ -16,15 +16,27 @@ @@ -16,15 +16,27 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System.Composition;
using Avalonia.Controls;
using ILSpy.ViewModels;
namespace ILSpy.Views
{
[Export]
[Shared]
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
[ImportingConstructor]
public MainWindow(MainWindowViewModel viewModel) : this()
{
DataContext = viewModel;
}
}
}
}

Loading…
Cancel
Save