mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-22 09:14:25 +08:00
0.2.0
组件系统
This commit is contained in:
@@ -8,11 +8,9 @@
|
||||
x:Class="LanMontainDesktop.Views.Components.ClockWidget">
|
||||
|
||||
<Border x:Name="RootBorder"
|
||||
Classes="glass-panel"
|
||||
Padding="8"
|
||||
CornerRadius="0"
|
||||
BorderBrush="Transparent"
|
||||
BorderThickness="0"
|
||||
Background="Transparent">
|
||||
CornerRadius="8">
|
||||
<TextBlock x:Name="TimeTextBlock"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
|
||||
@@ -4,6 +4,7 @@ using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Threading;
|
||||
using LanMontainDesktop.Services;
|
||||
|
||||
namespace LanMontainDesktop.Views.Components;
|
||||
|
||||
@@ -14,6 +15,8 @@ public partial class ClockWidget : UserControl
|
||||
Interval = TimeSpan.FromSeconds(1)
|
||||
};
|
||||
|
||||
private TimeZoneService? _timeZoneService;
|
||||
|
||||
public ClockWidget()
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -24,6 +27,21 @@ public partial class ClockWidget : UserControl
|
||||
UpdateClock();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置时区服务
|
||||
/// </summary>
|
||||
public void SetTimeZoneService(TimeZoneService timeZoneService)
|
||||
{
|
||||
if (_timeZoneService != null)
|
||||
{
|
||||
_timeZoneService.TimeZoneChanged -= OnTimeZoneChanged;
|
||||
}
|
||||
|
||||
_timeZoneService = timeZoneService;
|
||||
_timeZoneService.TimeZoneChanged += OnTimeZoneChanged;
|
||||
UpdateClock();
|
||||
}
|
||||
|
||||
private void OnAttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
UpdateClock();
|
||||
@@ -40,9 +58,14 @@ public partial class ClockWidget : UserControl
|
||||
UpdateClock();
|
||||
}
|
||||
|
||||
private void OnTimeZoneChanged(object? sender, EventArgs e)
|
||||
{
|
||||
UpdateClock();
|
||||
}
|
||||
|
||||
private void UpdateClock()
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
var now = _timeZoneService?.GetCurrentTime() ?? DateTime.Now;
|
||||
TimeTextBlock.Text = now.ToString("HH:mm:ss", CultureInfo.CurrentCulture);
|
||||
}
|
||||
|
||||
|
||||
83
LanMontainDesktop/Views/Components/DateWidget.axaml
Normal file
83
LanMontainDesktop/Views/Components/DateWidget.axaml
Normal file
@@ -0,0 +1,83 @@
|
||||
<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="400"
|
||||
d:DesignHeight="200"
|
||||
x:Class="LanMontainDesktop.Views.Components.DateWidget">
|
||||
|
||||
<Border x:Name="RootBorder"
|
||||
Background="Transparent"
|
||||
CornerRadius="16"
|
||||
ClipToBounds="True">
|
||||
<Grid ColumnDefinitions="*,*">
|
||||
<!-- 左侧:月历 -->
|
||||
<Border x:Name="CalendarBackgroundBorder"
|
||||
Grid.Column="0"
|
||||
Padding="12"
|
||||
Background="{DynamicResource AdaptiveSurfaceBaseBrush}">
|
||||
<Grid RowDefinitions="Auto,*">
|
||||
<!-- 月份年份 -->
|
||||
<TextBlock x:Name="CalendarMonthYearTextBlock"
|
||||
Grid.Row="0"
|
||||
HorizontalAlignment="Center"
|
||||
FontSize="12"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
|
||||
Margin="0,0,0,8" />
|
||||
|
||||
<!-- 月历网格 -->
|
||||
<Grid x:Name="CalendarGrid"
|
||||
Grid.Row="1"
|
||||
RowDefinitions="Auto,*,*,*,*,*"
|
||||
ColumnDefinitions="*,*,*,*,*,*,*">
|
||||
<!-- 星期标题 -->
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Text="日" HorizontalAlignment="Center" FontSize="10" Foreground="{DynamicResource AdaptiveTextSecondaryBrush}" />
|
||||
<TextBlock Grid.Row="0" Grid.Column="1" Text="一" HorizontalAlignment="Center" FontSize="10" Foreground="{DynamicResource AdaptiveTextSecondaryBrush}" />
|
||||
<TextBlock Grid.Row="0" Grid.Column="2" Text="二" HorizontalAlignment="Center" FontSize="10" Foreground="{DynamicResource AdaptiveTextSecondaryBrush}" />
|
||||
<TextBlock Grid.Row="0" Grid.Column="3" Text="三" HorizontalAlignment="Center" FontSize="10" Foreground="{DynamicResource AdaptiveTextSecondaryBrush}" />
|
||||
<TextBlock Grid.Row="0" Grid.Column="4" Text="四" HorizontalAlignment="Center" FontSize="10" Foreground="{DynamicResource AdaptiveTextSecondaryBrush}" />
|
||||
<TextBlock Grid.Row="0" Grid.Column="5" Text="五" HorizontalAlignment="Center" FontSize="10" Foreground="{DynamicResource AdaptiveTextSecondaryBrush}" />
|
||||
<TextBlock Grid.Row="0" Grid.Column="6" Text="六" HorizontalAlignment="Center" FontSize="10" Foreground="{DynamicResource AdaptiveTextSecondaryBrush}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- 右侧:今日详情 -->
|
||||
<Border x:Name="TodayBackgroundBorder"
|
||||
Grid.Column="1"
|
||||
Background="{DynamicResource AdaptiveAccentBrush}"
|
||||
Padding="16">
|
||||
<Grid RowDefinitions="Auto,*,Auto">
|
||||
<!-- 今日标签 -->
|
||||
<TextBlock Grid.Row="0"
|
||||
Text="今天"
|
||||
HorizontalAlignment="Center"
|
||||
FontSize="11"
|
||||
FontWeight="Medium"
|
||||
Opacity="0.8"
|
||||
Foreground="{DynamicResource AdaptiveOnAccentBrush}" />
|
||||
|
||||
<!-- 日期数字 -->
|
||||
<TextBlock x:Name="TodayDayTextBlock"
|
||||
Grid.Row="1"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="56"
|
||||
FontWeight="Light"
|
||||
Foreground="{DynamicResource AdaptiveOnAccentBrush}" />
|
||||
|
||||
<!-- 星期 -->
|
||||
<TextBlock x:Name="TodayWeekdayTextBlock"
|
||||
Grid.Row="2"
|
||||
HorizontalAlignment="Center"
|
||||
FontSize="13"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource AdaptiveOnAccentBrush}" />
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
</UserControl>
|
||||
180
LanMontainDesktop/Views/Components/DateWidget.axaml.cs
Normal file
180
LanMontainDesktop/Views/Components/DateWidget.axaml.cs
Normal file
@@ -0,0 +1,180 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Threading;
|
||||
using LanMontainDesktop.Services;
|
||||
|
||||
namespace LanMontainDesktop.Views.Components;
|
||||
|
||||
public partial class DateWidget : UserControl
|
||||
{
|
||||
private readonly DispatcherTimer _timer = new()
|
||||
{
|
||||
Interval = TimeSpan.FromMinutes(1)
|
||||
};
|
||||
|
||||
private TimeZoneService? _timeZoneService;
|
||||
|
||||
public DateWidget()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_timer.Tick += OnTimerTick;
|
||||
AttachedToVisualTree += OnAttachedToVisualTree;
|
||||
DetachedFromVisualTree += OnDetachedFromVisualTree;
|
||||
UpdateDate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置时区服务
|
||||
/// </summary>
|
||||
public void SetTimeZoneService(TimeZoneService timeZoneService)
|
||||
{
|
||||
if (_timeZoneService != null)
|
||||
{
|
||||
_timeZoneService.TimeZoneChanged -= OnTimeZoneChanged;
|
||||
}
|
||||
|
||||
_timeZoneService = timeZoneService;
|
||||
_timeZoneService.TimeZoneChanged += OnTimeZoneChanged;
|
||||
UpdateDate();
|
||||
}
|
||||
|
||||
private void OnAttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
UpdateDate();
|
||||
_timer.Start();
|
||||
}
|
||||
|
||||
private void OnDetachedFromVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
_timer.Stop();
|
||||
}
|
||||
|
||||
private void OnTimerTick(object? sender, EventArgs e)
|
||||
{
|
||||
UpdateDate();
|
||||
}
|
||||
|
||||
private void OnTimeZoneChanged(object? sender, EventArgs e)
|
||||
{
|
||||
UpdateDate();
|
||||
}
|
||||
|
||||
private void UpdateDate()
|
||||
{
|
||||
var now = _timeZoneService?.GetCurrentTime() ?? DateTime.Now;
|
||||
var culture = CultureInfo.CurrentCulture;
|
||||
|
||||
// 右侧:今日详情
|
||||
TodayDayTextBlock.Text = now.Day.ToString();
|
||||
TodayWeekdayTextBlock.Text = now.ToString("dddd", culture);
|
||||
|
||||
// 左侧:月历
|
||||
CalendarMonthYearTextBlock.Text = now.ToString("yyyy年M月", culture);
|
||||
|
||||
// 生成月历
|
||||
GenerateCalendar(now);
|
||||
}
|
||||
|
||||
private void GenerateCalendar(DateTime currentDate)
|
||||
{
|
||||
// 清空之前的日期(保留星期标题)
|
||||
var childrenToRemove = new List<Control>();
|
||||
foreach (var child in CalendarGrid.Children)
|
||||
{
|
||||
if (child is TextBlock tb && tb.Tag?.ToString() == "day")
|
||||
{
|
||||
childrenToRemove.Add(tb);
|
||||
}
|
||||
}
|
||||
foreach (var child in childrenToRemove)
|
||||
{
|
||||
CalendarGrid.Children.Remove(child);
|
||||
}
|
||||
|
||||
var year = currentDate.Year;
|
||||
var month = currentDate.Month;
|
||||
var today = currentDate.Day;
|
||||
|
||||
// 获取该月第一天
|
||||
var firstDayOfMonth = new DateTime(year, month, 1);
|
||||
var daysInMonth = DateTime.DaysInMonth(year, month);
|
||||
var startDayOfWeek = (int)firstDayOfMonth.DayOfWeek; // 0 = Sunday
|
||||
|
||||
// 生成日期
|
||||
for (int day = 1; day <= daysInMonth; day++)
|
||||
{
|
||||
var row = ((day + startDayOfWeek - 1) / 7) + 1; // +1 because row 0 is weekday headers
|
||||
var col = (day + startDayOfWeek - 1) % 7;
|
||||
|
||||
if (row > 5) continue; // 最多显示6行
|
||||
|
||||
var dayText = new TextBlock
|
||||
{
|
||||
Text = day.ToString(),
|
||||
HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Center,
|
||||
VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center,
|
||||
FontSize = 10,
|
||||
Tag = "day"
|
||||
};
|
||||
|
||||
// 今天高亮
|
||||
if (day == today)
|
||||
{
|
||||
// 使用主题色高亮今天
|
||||
var accentBrush = this.TryFindResource("AdaptiveAccentBrush", out var accent)
|
||||
? accent as IBrush
|
||||
: Brushes.Blue;
|
||||
var onAccentBrush = this.TryFindResource("AdaptiveOnAccentBrush", out var onAccent)
|
||||
? onAccent as IBrush
|
||||
: Brushes.White;
|
||||
|
||||
dayText.Foreground = onAccentBrush;
|
||||
dayText.FontWeight = FontWeight.Bold;
|
||||
dayText.Background = new SolidColorBrush(Colors.Transparent);
|
||||
|
||||
// 添加背景圆
|
||||
var highlight = new Border
|
||||
{
|
||||
Background = accentBrush,
|
||||
CornerRadius = new CornerRadius(10),
|
||||
Width = 20,
|
||||
Height = 20,
|
||||
HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Center,
|
||||
VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center,
|
||||
Child = dayText
|
||||
};
|
||||
Grid.SetRow(highlight, row);
|
||||
Grid.SetColumn(highlight, col);
|
||||
CalendarGrid.Children.Add(highlight);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 使用主题次要文本颜色
|
||||
var secondaryBrush = this.TryFindResource("AdaptiveTextSecondaryBrush", out var secondary)
|
||||
? secondary as IBrush
|
||||
: Brushes.Gray;
|
||||
dayText.Foreground = secondaryBrush;
|
||||
Grid.SetRow(dayText, row);
|
||||
Grid.SetColumn(dayText, col);
|
||||
CalendarGrid.Children.Add(dayText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ApplyCellSize(double cellSize)
|
||||
{
|
||||
// 根据格子大小调整圆角
|
||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(cellSize * 0.12, 8, 20));
|
||||
|
||||
// 调整字体大小
|
||||
var baseFontSize = cellSize * 0.25;
|
||||
TodayDayTextBlock.FontSize = Math.Clamp(baseFontSize * 2.8, 28, 72);
|
||||
TodayWeekdayTextBlock.FontSize = Math.Clamp(baseFontSize * 0.6, 10, 16);
|
||||
CalendarMonthYearTextBlock.FontSize = Math.Clamp(baseFontSize * 0.55, 9, 14);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user