12 changed files with 1902 additions and 4578 deletions
@ -1,372 +0,0 @@ |
|||||
<reactive:ReactiveWindow xmlns="https://github.com/avaloniaui" |
|
||||
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" |
|
||||
xmlns:vm="using:AuroraDesk.Presentation.ViewModels" |
|
||||
xmlns:converters="using:AuroraDesk.Presentation.Converters" |
|
||||
xmlns:tooltip="using:Avalonia.Controls" |
|
||||
xmlns:heroicons="clr-namespace:HeroIconsAvalonia.Controls;assembly=HeroIconsAvalonia" |
|
||||
xmlns:reactive="clr-namespace:Avalonia.ReactiveUI;assembly=Avalonia.ReactiveUI" |
|
||||
mc:Ignorable="d" d:DesignWidth="1200" d:DesignHeight="800" |
|
||||
x:Class="AuroraDesk.MainWindow" |
|
||||
x:TypeArguments="vm:MainWindowViewModel" |
|
||||
x:DataType="vm:MainWindowViewModel" |
|
||||
Title="{Binding Title}" |
|
||||
MinWidth="1000" MinHeight="600" |
|
||||
ExtendClientAreaToDecorationsHint="True" |
|
||||
ExtendClientAreaChromeHints="NoChrome" |
|
||||
SystemDecorations="None"> |
|
||||
|
|
||||
<Design.DataContext> |
|
||||
<vm:MainWindowViewModel /> |
|
||||
</Design.DataContext> |
|
||||
|
|
||||
<Grid> |
|
||||
<Grid.ColumnDefinitions> |
|
||||
<ColumnDefinition Width="250" MinWidth="200"/> |
|
||||
<ColumnDefinition Width="*"/> |
|
||||
</Grid.ColumnDefinitions> |
|
||||
|
|
||||
<!-- 左侧导航栏 --> |
|
||||
<Border Grid.Column="0" |
|
||||
Background="{StaticResource PrimaryDark}" |
|
||||
BorderBrush="{StaticResource PrimaryDarkHover}" |
|
||||
BorderThickness="0,0,1,0"> |
|
||||
<Grid> |
|
||||
<Grid.RowDefinitions> |
|
||||
<RowDefinition Height="Auto"/> |
|
||||
<RowDefinition Height="*"/> |
|
||||
<RowDefinition Height="Auto"/> |
|
||||
</Grid.RowDefinitions> |
|
||||
|
|
||||
<!-- 导航栏标题 --> |
|
||||
<StackPanel Grid.Row="0" Margin="20,20,20,30"> |
|
||||
<TextBlock Text="{StaticResource AppTitle}" |
|
||||
FontSize="20" |
|
||||
FontWeight="Bold" |
|
||||
Foreground="White" |
|
||||
HorizontalAlignment="Center"/> |
|
||||
<TextBlock Text="{StaticResource AppSubtitle}" |
|
||||
FontSize="12" |
|
||||
Foreground="{StaticResource SecondaryGray}" |
|
||||
HorizontalAlignment="Center" |
|
||||
Margin="0,5,0,0"/> |
|
||||
</StackPanel> |
|
||||
|
|
||||
<!-- 导航菜单 --> |
|
||||
<ScrollViewer Grid.Row="1" |
|
||||
VerticalScrollBarVisibility="Auto" |
|
||||
HorizontalScrollBarVisibility="Disabled" |
|
||||
Margin="10,0,10,0"> |
|
||||
<ItemsControl ItemsSource="{Binding NavigationItems}"> |
|
||||
<ItemsControl.ItemTemplate> |
|
||||
<DataTemplate> |
|
||||
<StackPanel> |
|
||||
<!-- 主导航项 --> |
|
||||
<Button Command="{Binding $parent[Window].DataContext.NavigateCommand}" |
|
||||
CommandParameter="{Binding}" |
|
||||
HorizontalAlignment="Stretch" |
|
||||
HorizontalContentAlignment="Left" |
|
||||
Margin="0,2" |
|
||||
Padding="15,12" |
|
||||
FontSize="14" |
|
||||
Background="Transparent" |
|
||||
Foreground="White" |
|
||||
BorderThickness="0" |
|
||||
CornerRadius="8"> |
|
||||
<Button.Styles> |
|
||||
<Style Selector="Button"> |
|
||||
<Setter Property="Background" Value="Transparent"/> |
|
||||
<Setter Property="Foreground" Value="White"/> |
|
||||
</Style> |
|
||||
<Style Selector="Button:pointerover"> |
|
||||
<Setter Property="Background" Value="{StaticResource PrimaryDarkHover}"/> |
|
||||
<Setter Property="Foreground" Value="{StaticResource TextWhite}"/> |
|
||||
</Style> |
|
||||
<Style Selector="Button:selected"> |
|
||||
<Setter Property="Background" Value="{StaticResource PrimaryBlue}"/> |
|
||||
<Setter Property="Foreground" Value="{StaticResource TextWhite}"/> |
|
||||
</Style> |
|
||||
</Button.Styles> |
|
||||
<Button.Content> |
|
||||
<StackPanel Orientation="Horizontal" Spacing="10"> |
|
||||
<heroicons:HeroIcon Type="{Binding IconType}" |
|
||||
Width="16" Height="16" |
|
||||
Foreground="{StaticResource TextWhite}"/> |
|
||||
<TextBlock Text="{Binding Title}" |
|
||||
VerticalAlignment="Center"/> |
|
||||
</StackPanel> |
|
||||
</Button.Content> |
|
||||
</Button> |
|
||||
|
|
||||
<!-- 子导航项 --> |
|
||||
<ItemsControl ItemsSource="{Binding Children}" |
|
||||
IsVisible="{Binding IsExpanded}" |
|
||||
Margin="20,0,0,0"> |
|
||||
<ItemsControl.ItemTemplate> |
|
||||
<DataTemplate> |
|
||||
<Button Command="{Binding $parent[Window].DataContext.NavigateCommand}" |
|
||||
CommandParameter="{Binding}" |
|
||||
HorizontalAlignment="Stretch" |
|
||||
HorizontalContentAlignment="Left" |
|
||||
Margin="0,1" |
|
||||
Padding="15,10" |
|
||||
FontSize="13" |
|
||||
Background="Transparent" |
|
||||
Foreground="{StaticResource SecondaryGray}" |
|
||||
BorderThickness="0" |
|
||||
CornerRadius="6"> |
|
||||
<Button.Styles> |
|
||||
<Style Selector="Button"> |
|
||||
<Setter Property="Background" Value="Transparent"/> |
|
||||
<Setter Property="Foreground" Value="{StaticResource SecondaryGray}"/> |
|
||||
</Style> |
|
||||
<Style Selector="Button:pointerover"> |
|
||||
<Setter Property="Background" Value="{StaticResource PrimaryDarkHover}"/> |
|
||||
<Setter Property="Foreground" Value="{StaticResource TextWhite}"/> |
|
||||
</Style> |
|
||||
<Style Selector="Button:selected"> |
|
||||
<Setter Property="Background" Value="{StaticResource PrimaryBlue}"/> |
|
||||
<Setter Property="Foreground" Value="{StaticResource TextWhite}"/> |
|
||||
</Style> |
|
||||
</Button.Styles> |
|
||||
<Button.Content> |
|
||||
<StackPanel Orientation="Horizontal" Spacing="8"> |
|
||||
<heroicons:HeroIcon Type="{Binding IconType}" |
|
||||
Width="14" Height="14" |
|
||||
Foreground="{Binding $parent[Button].Foreground}"/> |
|
||||
<TextBlock Text="{Binding Title}" |
|
||||
VerticalAlignment="Center"/> |
|
||||
</StackPanel> |
|
||||
</Button.Content> |
|
||||
</Button> |
|
||||
</DataTemplate> |
|
||||
</ItemsControl.ItemTemplate> |
|
||||
</ItemsControl> |
|
||||
</StackPanel> |
|
||||
</DataTemplate> |
|
||||
</ItemsControl.ItemTemplate> |
|
||||
</ItemsControl> |
|
||||
</ScrollViewer> |
|
||||
|
|
||||
<!-- 底部信息 --> |
|
||||
<StackPanel Grid.Row="2" Margin="20,0,20,20"> |
|
||||
<Border Background="{StaticResource PrimaryDarkHover}" CornerRadius="8" Padding="15"> |
|
||||
<StackPanel> |
|
||||
<TextBlock Text="{StaticResource VersionInfo}" |
|
||||
FontSize="12" |
|
||||
Foreground="{StaticResource SecondaryGray}" |
|
||||
HorizontalAlignment="Center"/> |
|
||||
<TextBlock Text="{StaticResource VersionNumber}" |
|
||||
FontSize="14" |
|
||||
FontWeight="Bold" |
|
||||
Foreground="White" |
|
||||
HorizontalAlignment="Center" |
|
||||
Margin="0,5,0,0"/> |
|
||||
</StackPanel> |
|
||||
</Border> |
|
||||
</StackPanel> |
|
||||
</Grid> |
|
||||
</Border> |
|
||||
|
|
||||
<!-- 右侧主内容区域 --> |
|
||||
<Grid Grid.Column="1"> |
|
||||
<Grid.RowDefinitions> |
|
||||
<RowDefinition Height="Auto"/> |
|
||||
<RowDefinition Height="Auto"/> |
|
||||
<RowDefinition Height="*"/> |
|
||||
</Grid.RowDefinitions> |
|
||||
|
|
||||
<!-- 头部区域 --> |
|
||||
<Border Grid.Row="0" |
|
||||
Background="{StaticResource BackgroundWhite}" |
|
||||
BorderBrush="{StaticResource BorderLight}" |
|
||||
BorderThickness="0,0,0,1" |
|
||||
Padding="0,0,0,0"> |
|
||||
<Grid Height="50" Name="TitleBarGrid"> |
|
||||
<Grid.ColumnDefinitions> |
|
||||
<ColumnDefinition Width="*"/> |
|
||||
<ColumnDefinition Width="Auto"/> |
|
||||
</Grid.ColumnDefinitions> |
|
||||
|
|
||||
<!-- 左侧标题区域 --> |
|
||||
<StackPanel Grid.Column="0" |
|
||||
VerticalAlignment="Center" |
|
||||
Margin="20,0,0,0"> |
|
||||
<TextBlock Text="{Binding HeaderTitle}" |
|
||||
FontSize="18" |
|
||||
FontWeight="SemiBold" |
|
||||
Foreground="{StaticResource TextPrimary}"/> |
|
||||
<TextBlock Text="{Binding HeaderSubtitle}" |
|
||||
FontSize="12" |
|
||||
Foreground="{StaticResource SecondaryGrayDark}" |
|
||||
Margin="0,2,0,0"/> |
|
||||
</StackPanel> |
|
||||
|
|
||||
<!-- 右侧按钮区域 --> |
|
||||
<StackPanel Grid.Column="1" |
|
||||
Orientation="Horizontal" |
|
||||
VerticalAlignment="Center" |
|
||||
Margin="0,0,0,0"> |
|
||||
|
|
||||
|
|
||||
<!-- 窗口控制按钮组 --> |
|
||||
<StackPanel Orientation="Horizontal" Spacing="0"> |
|
||||
<!-- 最小化按钮 --> |
|
||||
<Button Name="MinimizeButton" |
|
||||
Width="46" Height="30" |
|
||||
Background="Transparent" |
|
||||
BorderThickness="0" |
|
||||
tooltip:ToolTip.Tip="{StaticResource BtnMinimize}"> |
|
||||
<Button.Styles> |
|
||||
<Style Selector="Button:pointerover"> |
|
||||
<Setter Property="Background" Value="{StaticResource BackgroundLight}"/> |
|
||||
</Style> |
|
||||
</Button.Styles> |
|
||||
<heroicons:HeroIcon Type="Minus" |
|
||||
Width="16" Height="16" |
|
||||
Foreground="{StaticResource SecondaryGrayStroke}"/> |
|
||||
</Button> |
|
||||
|
|
||||
<!-- 最大化/还原按钮 --> |
|
||||
<Button Name="MaximizeButton" |
|
||||
Width="46" Height="30" |
|
||||
Background="Transparent" |
|
||||
BorderThickness="0" |
|
||||
tooltip:ToolTip.Tip="{StaticResource BtnMaximize}"> |
|
||||
<Button.Styles> |
|
||||
<Style Selector="Button:pointerover"> |
|
||||
<Setter Property="Background" Value="{StaticResource BackgroundLight}"/> |
|
||||
</Style> |
|
||||
</Button.Styles> |
|
||||
<heroicons:HeroIcon Type="ArrowsPointingOut" |
|
||||
Width="16" Height="16" |
|
||||
Foreground="{StaticResource SecondaryGrayStroke}"/> |
|
||||
</Button> |
|
||||
|
|
||||
<!-- 关闭按钮 --> |
|
||||
<Button Name="CloseButton" |
|
||||
Width="46" Height="30" |
|
||||
Background="Transparent" |
|
||||
BorderThickness="0" |
|
||||
tooltip:ToolTip.Tip="{StaticResource BtnClose}"> |
|
||||
<Button.Styles> |
|
||||
<Style Selector="Button:pointerover"> |
|
||||
<Setter Property="Background" Value="{StaticResource ButtonClose}"/> |
|
||||
</Style> |
|
||||
</Button.Styles> |
|
||||
<heroicons:HeroIcon Type="XMark" |
|
||||
Width="16" Height="16" |
|
||||
Foreground="{StaticResource SecondaryGrayStroke}"/> |
|
||||
</Button> |
|
||||
</StackPanel> |
|
||||
</StackPanel> |
|
||||
</Grid> |
|
||||
</Border> |
|
||||
|
|
||||
<!-- 标签页区域 --> |
|
||||
<Border Grid.Row="1" |
|
||||
Background="{StaticResource BackgroundLight}" |
|
||||
BorderBrush="{StaticResource BorderLight}" |
|
||||
BorderThickness="0,0,0,1" |
|
||||
Padding="0,0,0,0"> |
|
||||
<ScrollViewer HorizontalScrollBarVisibility="Auto" |
|
||||
VerticalScrollBarVisibility="Disabled"> |
|
||||
<ItemsControl ItemsSource="{Binding Tabs}" |
|
||||
Margin="8,4,8,0"> |
|
||||
<ItemsControl.ItemsPanel> |
|
||||
<ItemsPanelTemplate> |
|
||||
<StackPanel Orientation="Horizontal" Spacing="0"/> |
|
||||
</ItemsPanelTemplate> |
|
||||
</ItemsControl.ItemsPanel> |
|
||||
<ItemsControl.ItemTemplate> |
|
||||
<DataTemplate> |
|
||||
<Button Background="{Binding IsSelected, Converter={x:Static converters:TabStyleConverter.Instance}, ConverterParameter=Background}" |
|
||||
BorderBrush="{Binding IsSelected, Converter={x:Static converters:TabStyleConverter.Instance}, ConverterParameter=BorderBrush}" |
|
||||
BorderThickness="1,1,1,0" |
|
||||
CornerRadius="4,4,0,0" |
|
||||
Margin="0,0,1,0" |
|
||||
Padding="12,8,8,8" |
|
||||
MinWidth="120" |
|
||||
Cursor="Hand" |
|
||||
Command="{Binding $parent[Window].DataContext.SelectTabCommand}" |
|
||||
CommandParameter="{Binding}"> |
|
||||
<Button.Styles> |
|
||||
<Style Selector="Button:pointerover"> |
|
||||
<Setter Property="Background" Value="{StaticResource BackgroundLight}"/> |
|
||||
</Style> |
|
||||
</Button.Styles> |
|
||||
<Grid> |
|
||||
<Grid.ColumnDefinitions> |
|
||||
<ColumnDefinition Width="*"/> |
|
||||
<ColumnDefinition Width="Auto"/> |
|
||||
</Grid.ColumnDefinitions> |
|
||||
<StackPanel Grid.Column="0" |
|
||||
Orientation="Horizontal" |
|
||||
Spacing="6" |
|
||||
VerticalAlignment="Center"> |
|
||||
<heroicons:HeroIcon Type="{Binding IconType}" |
|
||||
Width="14" Height="14" |
|
||||
VerticalAlignment="Center"/> |
|
||||
<TextBlock Text="{Binding Title}" |
|
||||
FontSize="13" |
|
||||
FontWeight="Normal" |
|
||||
Foreground="{Binding IsSelected, Converter={x:Static converters:TabStyleConverter.Instance}, ConverterParameter=Foreground}" |
|
||||
VerticalAlignment="Center"/> |
|
||||
</StackPanel> |
|
||||
<Button Grid.Column="1" |
|
||||
Command="{Binding $parent[Window].DataContext.CloseTabCommand}" |
|
||||
CommandParameter="{Binding $parent[Button].DataContext}" |
|
||||
Width="18" Height="18" |
|
||||
Background="Transparent" |
|
||||
Foreground="{StaticResource SecondaryGrayLight}" |
|
||||
BorderThickness="0" |
|
||||
FontSize="12" |
|
||||
IsVisible="{Binding CanClose}" |
|
||||
Margin="6,0,0,0" |
|
||||
CornerRadius="9" |
|
||||
tooltip:ToolTip.Tip="{StaticResource BtnCloseTab}"> |
|
||||
<heroicons:HeroIcon Type="XMark" |
|
||||
Width="6" Height="6" |
|
||||
Foreground="{Binding $parent[Button].Foreground}" |
|
||||
HorizontalAlignment="Center" |
|
||||
VerticalAlignment="Center"/> |
|
||||
<Button.Styles> |
|
||||
<Style Selector="Button:pointerover"> |
|
||||
<Setter Property="Background" Value="{StaticResource ButtonCloseHover}"/> |
|
||||
<Setter Property="Foreground" Value="{StaticResource TextWhite}"/> |
|
||||
</Style> |
|
||||
<Style Selector="Button:pressed"> |
|
||||
<Setter Property="Background" Value="{StaticResource ButtonCloseActive}"/> |
|
||||
<Setter Property="Foreground" Value="{StaticResource TextWhite}"/> |
|
||||
</Style> |
|
||||
</Button.Styles> |
|
||||
</Button> |
|
||||
</Grid> |
|
||||
</Button> |
|
||||
</DataTemplate> |
|
||||
</ItemsControl.ItemTemplate> |
|
||||
</ItemsControl> |
|
||||
</ScrollViewer> |
|
||||
</Border> |
|
||||
|
|
||||
<!-- 内容区域 --> |
|
||||
<Border Grid.Row="2" |
|
||||
Background="{StaticResource BackgroundWhite}" |
|
||||
CornerRadius="8" |
|
||||
Margin="10" |
|
||||
Padding="5" |
|
||||
BorderBrush="{StaticResource BorderLight}" |
|
||||
BorderThickness="1"> |
|
||||
<Border.Effect> |
|
||||
<DropShadowEffect Color="{StaticResource ShadowBlack}" |
|
||||
Opacity="0.08" |
|
||||
BlurRadius="12" |
|
||||
OffsetX="0" |
|
||||
OffsetY="2"/> |
|
||||
</Border.Effect> |
|
||||
<reactive:RoutedViewHost Router="{Binding Router}"/> |
|
||||
</Border> |
|
||||
</Grid> |
|
||||
</Grid> |
|
||||
</reactive:ReactiveWindow> |
|
||||
@ -1,114 +0,0 @@ |
|||||
using System; |
|
||||
using Avalonia.Controls; |
|
||||
using Avalonia.Controls.Primitives; |
|
||||
using Avalonia.Input; |
|
||||
using Avalonia.Markup.Xaml; |
|
||||
using Avalonia.ReactiveUI; |
|
||||
using Microsoft.Extensions.Logging; |
|
||||
using AuroraDesk.Presentation.ViewModels; |
|
||||
using ReactiveUI; |
|
||||
using System.Reactive.Disposables; |
|
||||
|
|
||||
namespace AuroraDesk; |
|
||||
|
|
||||
public partial class MainWindow : ReactiveWindow<MainWindowViewModel>, IActivatableView |
|
||||
{ |
|
||||
private readonly ILogger<MainWindow>? _logger; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 无参构造函数,用于 XAML 设计器
|
|
||||
/// </summary>
|
|
||||
public MainWindow() |
|
||||
{ |
|
||||
InitializeComponent(); |
|
||||
SetupWindowControls(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 构造函数,接受依赖注入的 ViewModel
|
|
||||
/// </summary>
|
|
||||
/// <param name="viewModel">主窗口的 ViewModel</param>
|
|
||||
/// <param name="logger">日志记录器</param>
|
|
||||
public MainWindow(MainWindowViewModel viewModel, ILogger<MainWindow>? logger = null) |
|
||||
{ |
|
||||
ArgumentNullException.ThrowIfNull(viewModel); |
|
||||
|
|
||||
_logger = logger; |
|
||||
InitializeComponent(); |
|
||||
ViewModel = viewModel; |
|
||||
SetupWindowControls(); |
|
||||
|
|
||||
_logger?.LogInformation("MainWindow 已创建,ViewModel 已设置"); |
|
||||
|
|
||||
// 使用 WhenActivated 管理订阅
|
|
||||
this.WhenActivated(disposables => |
|
||||
{ |
|
||||
// 可以在这里添加窗口级别的订阅,如果需要的话
|
|
||||
// 例如:this.WhenAnyValue(x => x.ViewModel.Title)
|
|
||||
// .Subscribe(title => ...)
|
|
||||
// .DisposeWith(disposables);
|
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
private void InitializeComponent() |
|
||||
{ |
|
||||
AvaloniaXamlLoader.Load(this); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 设置窗口控制按钮事件
|
|
||||
/// </summary>
|
|
||||
private void SetupWindowControls() |
|
||||
{ |
|
||||
// 设置标题栏拖动功能
|
|
||||
var titleBarGrid = this.FindControl<Grid>("TitleBarGrid"); |
|
||||
if (titleBarGrid != null) |
|
||||
{ |
|
||||
titleBarGrid.PointerPressed += OnTitleBarPointerPressed; |
|
||||
} |
|
||||
|
|
||||
// 最小化按钮
|
|
||||
var minimizeButton = this.FindControl<Button>("MinimizeButton"); |
|
||||
if (minimizeButton != null) |
|
||||
{ |
|
||||
minimizeButton.Click += (sender, e) => WindowState = WindowState.Minimized; |
|
||||
} |
|
||||
|
|
||||
// 最大化/还原按钮
|
|
||||
var maximizeButton = this.FindControl<Button>("MaximizeButton"); |
|
||||
if (maximizeButton != null) |
|
||||
{ |
|
||||
maximizeButton.Click += (sender, e) => |
|
||||
{ |
|
||||
if (WindowState == WindowState.Maximized) |
|
||||
{ |
|
||||
WindowState = WindowState.Normal; |
|
||||
ToolTip.SetTip(maximizeButton, "最大化"); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
WindowState = WindowState.Maximized; |
|
||||
ToolTip.SetTip(maximizeButton, "还原"); |
|
||||
} |
|
||||
}; |
|
||||
} |
|
||||
|
|
||||
// 关闭按钮
|
|
||||
var closeButton = this.FindControl<Button>("CloseButton"); |
|
||||
if (closeButton != null) |
|
||||
{ |
|
||||
closeButton.Click += (sender, e) => Close(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 处理标题栏鼠标按下事件,实现窗口拖动
|
|
||||
/// </summary>
|
|
||||
private void OnTitleBarPointerPressed(object? sender, PointerPressedEventArgs e) |
|
||||
{ |
|
||||
if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed) |
|
||||
{ |
|
||||
BeginMoveDrag(e); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1 +1 @@ |
|||||
02d000a9cd9f4212cd5f985e8dde572b7faf973dcff59560607da4f46a53442e |
5ca4ed031f11e2a7ccc654d616879421a1337553d516bd89fe174081ee58b17a |
||||
|
|||||
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Loading…
Reference in new issue