mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-24 02:14:26 +08:00
0.1.2
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
<Application xmlns="https://github.com/avaloniaui"
|
<Application xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:sty="using:FluentAvalonia.Styling"
|
||||||
x:Class="LanMontainDesktop.App"
|
x:Class="LanMontainDesktop.App"
|
||||||
xmlns:local="using:LanMontainDesktop"
|
xmlns:local="using:LanMontainDesktop"
|
||||||
RequestedThemeVariant="Default">
|
RequestedThemeVariant="Default">
|
||||||
@@ -10,6 +11,6 @@
|
|||||||
</Application.DataTemplates>
|
</Application.DataTemplates>
|
||||||
|
|
||||||
<Application.Styles>
|
<Application.Styles>
|
||||||
<FluentTheme />
|
<sty:FluentAvaloniaTheme />
|
||||||
</Application.Styles>
|
</Application.Styles>
|
||||||
</Application>
|
</Application>
|
||||||
|
|||||||
@@ -24,5 +24,6 @@
|
|||||||
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
|
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.1" />
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.1" />
|
||||||
|
<PackageReference Include="FluentAvaloniaUI" Version="2.5.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -2,5 +2,5 @@
|
|||||||
|
|
||||||
public partial class MainWindowViewModel : ViewModelBase
|
public partial class MainWindowViewModel : ViewModelBase
|
||||||
{
|
{
|
||||||
public string Greeting { get; } = "Welcome to Avalonia!";
|
public string Greeting { get; } = "A modern desktop shell powered by FluentAvalonia.";
|
||||||
}
|
}
|
||||||
|
|||||||
23
LanMontainDesktop/Views/Components/ClockWidget.axaml
Normal file
23
LanMontainDesktop/Views/Components/ClockWidget.axaml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<UserControl 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"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
d:DesignWidth="220"
|
||||||
|
d:DesignHeight="70"
|
||||||
|
x:Class="LanMontainDesktop.Views.Components.ClockWidget">
|
||||||
|
|
||||||
|
<Border Padding="8"
|
||||||
|
CornerRadius="8"
|
||||||
|
BorderBrush="#80A5B4FC"
|
||||||
|
BorderThickness="1"
|
||||||
|
Background="#CC0F172A">
|
||||||
|
<TextBlock x:Name="TimeTextBlock"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
FontSize="26"
|
||||||
|
FontWeight="SemiBold"
|
||||||
|
Foreground="White" />
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
</UserControl>
|
||||||
47
LanMontainDesktop/Views/Components/ClockWidget.axaml.cs
Normal file
47
LanMontainDesktop/Views/Components/ClockWidget.axaml.cs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Threading;
|
||||||
|
|
||||||
|
namespace LanMontainDesktop.Views.Components;
|
||||||
|
|
||||||
|
public partial class ClockWidget : UserControl
|
||||||
|
{
|
||||||
|
private readonly DispatcherTimer _timer = new()
|
||||||
|
{
|
||||||
|
Interval = TimeSpan.FromSeconds(1)
|
||||||
|
};
|
||||||
|
|
||||||
|
public ClockWidget()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
_timer.Tick += OnTimerTick;
|
||||||
|
AttachedToVisualTree += OnAttachedToVisualTree;
|
||||||
|
DetachedFromVisualTree += OnDetachedFromVisualTree;
|
||||||
|
UpdateClock();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnAttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
|
||||||
|
{
|
||||||
|
UpdateClock();
|
||||||
|
_timer.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDetachedFromVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
|
||||||
|
{
|
||||||
|
_timer.Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnTimerTick(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
UpdateClock();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateClock()
|
||||||
|
{
|
||||||
|
var now = DateTime.Now;
|
||||||
|
TimeTextBlock.Text = now.ToString("HH:mm:ss", CultureInfo.CurrentCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,20 +1,91 @@
|
|||||||
<Window xmlns="https://github.com/avaloniaui"
|
<Window xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:vm="using:LanMontainDesktop.ViewModels"
|
xmlns:vm="using:LanMontainDesktop.ViewModels"
|
||||||
|
xmlns:ui="using:FluentAvalonia.UI.Controls"
|
||||||
|
xmlns:comp="using:LanMontainDesktop.Views.Components"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
mc:Ignorable="d"
|
||||||
|
d:DesignWidth="1280"
|
||||||
|
d:DesignHeight="720"
|
||||||
x:Class="LanMontainDesktop.Views.MainWindow"
|
x:Class="LanMontainDesktop.Views.MainWindow"
|
||||||
x:DataType="vm:MainWindowViewModel"
|
x:DataType="vm:MainWindowViewModel"
|
||||||
Icon="/Assets/avalonia-logo.ico"
|
Icon="/Assets/avalonia-logo.ico"
|
||||||
|
WindowState="FullScreen"
|
||||||
|
SystemDecorations="None"
|
||||||
|
CanResize="False"
|
||||||
|
Background="#FF020617"
|
||||||
Title="LanMontainDesktop">
|
Title="LanMontainDesktop">
|
||||||
|
|
||||||
<Design.DataContext>
|
<Design.DataContext>
|
||||||
<!-- This only sets the DataContext for the previewer in an IDE,
|
<vm:MainWindowViewModel />
|
||||||
to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
|
|
||||||
<vm:MainWindowViewModel/>
|
|
||||||
</Design.DataContext>
|
</Design.DataContext>
|
||||||
|
|
||||||
<TextBlock Text="{Binding Greeting}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
<Grid>
|
||||||
|
<Border x:Name="DesktopHost"
|
||||||
|
ClipToBounds="True"
|
||||||
|
Background="#FF020617">
|
||||||
|
<Grid x:Name="DesktopGrid"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
ShowGridLines="False">
|
||||||
|
<comp:ClockWidget x:Name="ClockWidget"
|
||||||
|
Grid.Row="0"
|
||||||
|
Grid.Column="0"
|
||||||
|
Grid.ColumnSpan="3"
|
||||||
|
Margin="4" />
|
||||||
|
|
||||||
|
<Button x:Name="BackToWindowsButton"
|
||||||
|
Grid.Row="0"
|
||||||
|
Grid.Column="0"
|
||||||
|
Grid.ColumnSpan="4"
|
||||||
|
Margin="4"
|
||||||
|
Padding="8"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
Click="OnMinimizeClick"
|
||||||
|
Content="回到Windows" />
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<Border HorizontalAlignment="Right"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Margin="10"
|
||||||
|
Padding="10"
|
||||||
|
CornerRadius="10"
|
||||||
|
Background="#BF111827"
|
||||||
|
BorderBrush="#80334155"
|
||||||
|
BorderThickness="1">
|
||||||
|
<Grid ColumnDefinitions="Auto,Auto,Auto"
|
||||||
|
RowDefinitions="Auto,Auto"
|
||||||
|
ColumnSpacing="8"
|
||||||
|
RowSpacing="6">
|
||||||
|
<TextBlock Grid.Row="0"
|
||||||
|
Grid.Column="0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Foreground="#FFE5E7EB"
|
||||||
|
Text="短边格数" />
|
||||||
|
<ui:NumberBox x:Name="GridSizeNumberBox"
|
||||||
|
Grid.Row="0"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="100"
|
||||||
|
Minimum="6"
|
||||||
|
Maximum="96"
|
||||||
|
Value="12" />
|
||||||
|
<Button Grid.Row="0"
|
||||||
|
Grid.Column="2"
|
||||||
|
Padding="12,6"
|
||||||
|
Click="OnApplyGridSizeClick"
|
||||||
|
Content="应用" />
|
||||||
|
|
||||||
|
<TextBlock x:Name="GridInfoTextBlock"
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.Column="0"
|
||||||
|
Grid.ColumnSpan="3"
|
||||||
|
Foreground="#FF93C5FD"
|
||||||
|
Text="Grid: - cols x - rows (1:1)" />
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
</Window>
|
</Window>
|
||||||
|
|||||||
@@ -1,11 +1,125 @@
|
|||||||
|
using System;
|
||||||
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Interactivity;
|
||||||
|
|
||||||
namespace LanMontainDesktop.Views;
|
namespace LanMontainDesktop.Views;
|
||||||
|
|
||||||
public partial class MainWindow : Window
|
public partial class MainWindow : Window
|
||||||
{
|
{
|
||||||
|
private const int MinShortSideCells = 6;
|
||||||
|
private const int MaxShortSideCells = 96;
|
||||||
|
private int _targetShortSideCells;
|
||||||
|
|
||||||
public MainWindow()
|
public MainWindow()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
protected override void OnOpened(EventArgs e)
|
||||||
|
{
|
||||||
|
base.OnOpened(e);
|
||||||
|
|
||||||
|
_targetShortSideCells = CalculateDefaultShortSideCellCountFromDpi();
|
||||||
|
GridSizeNumberBox.Value = _targetShortSideCells;
|
||||||
|
DesktopHost.SizeChanged += OnDesktopHostSizeChanged;
|
||||||
|
RebuildDesktopGrid();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnClosed(EventArgs e)
|
||||||
|
{
|
||||||
|
DesktopHost.SizeChanged -= OnDesktopHostSizeChanged;
|
||||||
|
base.OnClosed(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int CalculateDefaultShortSideCellCountFromDpi()
|
||||||
|
{
|
||||||
|
var dpi = 96d * RenderScaling;
|
||||||
|
var count = (int)Math.Round(dpi / 8d);
|
||||||
|
return Math.Clamp(count, MinShortSideCells, MaxShortSideCells);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDesktopHostSizeChanged(object? sender, SizeChangedEventArgs e)
|
||||||
|
{
|
||||||
|
RebuildDesktopGrid();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnApplyGridSizeClick(object? sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var requested = (int)Math.Round(GridSizeNumberBox.Value);
|
||||||
|
if (requested <= 0)
|
||||||
|
{
|
||||||
|
requested = _targetShortSideCells;
|
||||||
|
}
|
||||||
|
|
||||||
|
_targetShortSideCells = Math.Clamp(requested, MinShortSideCells, MaxShortSideCells);
|
||||||
|
|
||||||
|
if (Math.Abs(GridSizeNumberBox.Value - _targetShortSideCells) > double.Epsilon)
|
||||||
|
{
|
||||||
|
GridSizeNumberBox.Value = _targetShortSideCells;
|
||||||
|
}
|
||||||
|
|
||||||
|
RebuildDesktopGrid();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RebuildDesktopGrid()
|
||||||
|
{
|
||||||
|
var hostWidth = DesktopHost.Bounds.Width;
|
||||||
|
var hostHeight = DesktopHost.Bounds.Height;
|
||||||
|
if (hostWidth <= 1 || hostHeight <= 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var shortSideCells = Math.Max(1, _targetShortSideCells);
|
||||||
|
double cellSize;
|
||||||
|
int columnCount;
|
||||||
|
int rowCount;
|
||||||
|
|
||||||
|
if (hostWidth >= hostHeight)
|
||||||
|
{
|
||||||
|
rowCount = shortSideCells;
|
||||||
|
cellSize = hostHeight / rowCount;
|
||||||
|
columnCount = Math.Max(1, (int)Math.Ceiling(hostWidth / cellSize));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
columnCount = shortSideCells;
|
||||||
|
cellSize = hostWidth / columnCount;
|
||||||
|
rowCount = Math.Max(1, (int)Math.Ceiling(hostHeight / cellSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
DesktopGrid.RowDefinitions.Clear();
|
||||||
|
DesktopGrid.ColumnDefinitions.Clear();
|
||||||
|
DesktopGrid.Width = columnCount * cellSize;
|
||||||
|
DesktopGrid.Height = rowCount * cellSize;
|
||||||
|
|
||||||
|
for (var row = 0; row < rowCount; row++)
|
||||||
|
{
|
||||||
|
DesktopGrid.RowDefinitions.Add(new RowDefinition(new GridLength(cellSize, GridUnitType.Pixel)));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var col = 0; col < columnCount; col++)
|
||||||
|
{
|
||||||
|
DesktopGrid.ColumnDefinitions.Add(new ColumnDefinition(new GridLength(cellSize, GridUnitType.Pixel)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Grid.SetRow(ClockWidget, 0);
|
||||||
|
Grid.SetColumn(ClockWidget, 0);
|
||||||
|
Grid.SetRowSpan(ClockWidget, 1);
|
||||||
|
Grid.SetColumnSpan(ClockWidget, Math.Min(3, columnCount));
|
||||||
|
|
||||||
|
Grid.SetRow(BackToWindowsButton, rowCount - 1);
|
||||||
|
Grid.SetColumn(BackToWindowsButton, 0);
|
||||||
|
Grid.SetRowSpan(BackToWindowsButton, 1);
|
||||||
|
Grid.SetColumnSpan(BackToWindowsButton, Math.Min(4, columnCount));
|
||||||
|
|
||||||
|
GridInfoTextBlock.Text =
|
||||||
|
$"Grid: {columnCount} cols x {rowCount} rows | cell {cellSize:F1}px (1:1)";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnMinimizeClick(object? sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
WindowState = WindowState.Minimized;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user