mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-08-18 15:33:33 +08:00
change.重做天气,为回到系统提供自定义功能。
This commit is contained in:
559
.trae/documents/weather-widget-material-redesign.md
Normal file
559
.trae/documents/weather-widget-material-redesign.md
Normal file
@@ -0,0 +1,559 @@
|
||||
# 天气组件 Material Design 重设计计划
|
||||
|
||||
> **目标:** 全面重构阑山桌面天气组件的视觉设计,遵循 Material Design 3 规范,参考 Google Weather、几何天气、Breez 天气和柠檬天气的设计语言。
|
||||
|
||||
---
|
||||
|
||||
## 当前状态分析
|
||||
|
||||
### 现有组件
|
||||
1. **WeatherWidget** - 基础天气(温度+天气状况+位置)
|
||||
2. **ExtendedWeatherWidget** - 扩展天气(含指标、逐小时、逐日预报)
|
||||
3. **HourlyWeatherWidget** - 逐小时天气
|
||||
4. **MultiDayWeatherWidget** - 多日天气
|
||||
5. **WeatherClockWidget** - 天气时钟
|
||||
|
||||
### 现有问题
|
||||
- 排版层次不清晰,文字大小对比不够
|
||||
- 布局过于紧凑,缺乏呼吸感
|
||||
- 内部卡片使用简单纯色背景,缺乏 Material 风格
|
||||
- 背景场景和前景内容缺乏深度分离
|
||||
- 圆角和间距不统一
|
||||
|
||||
### 现有视觉系统
|
||||
- 4套调色板:Google(默认)、Geometric、Breezy、LemonFlutter
|
||||
- 动态背景场景:MaterialWeatherSceneControl 绘制渐变+装饰
|
||||
- 图标系统:WeatherIconView + WeatherIconAssetResolver
|
||||
|
||||
---
|
||||
|
||||
## 设计方向
|
||||
|
||||
### 核心原则
|
||||
1. **Material Design 3** - 使用 M3 的排版、颜色、间距和形状规范
|
||||
2. **信息层级清晰** - 大字体温度、次要信息弱化
|
||||
3. **呼吸感** - 合理的间距和留白
|
||||
4. **深度感** - 前景卡片与背景场景分离
|
||||
5. **圆角一致性** - 遵循 DesignCornerRadius 规范
|
||||
|
||||
### 参考风格
|
||||
- **Google Weather** - 大字体温度、清晰层级、圆角卡片、柔和渐变
|
||||
- **几何天气** - 几何装饰、现代感
|
||||
- **Breez** - 清新留白、柔和色彩
|
||||
- **柠檬天气** - 活泼明亮
|
||||
|
||||
---
|
||||
|
||||
## 具体改动计划
|
||||
|
||||
### Task 1: 优化 MaterialWeatherPalette 和调色板系统
|
||||
|
||||
**文件:** `LanMountainDesktop/Views/Components/MaterialWeatherVisualTheme.cs`
|
||||
|
||||
**改动:**
|
||||
- 调整所有调色板的对比度,确保文字可读性
|
||||
- 优化背景渐变色彩,更加柔和自然
|
||||
- 统一文字主色和次色的对比度比例
|
||||
- 为每个风格增加 `SurfaceColor` 和 `SurfaceVariantColor` 用于卡片背景
|
||||
|
||||
**当前调色板字段:**
|
||||
```csharp
|
||||
public sealed record MaterialWeatherPalette(
|
||||
Color BackgroundTop,
|
||||
Color BackgroundBottom,
|
||||
Color PrimaryShape,
|
||||
Color SecondaryShape,
|
||||
Color AccentShape,
|
||||
Color TextPrimary,
|
||||
Color TextSecondary,
|
||||
Color SurfaceTint,
|
||||
Color OverlayTint);
|
||||
```
|
||||
|
||||
**新增字段:**
|
||||
```csharp
|
||||
Color SurfaceColor, // 卡片表面色(低透明度白色/黑色)
|
||||
Color SurfaceVariantColor, // 变体表面色
|
||||
Color OutlineColor // 分割线/边框色
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 2: 重构 WeatherWidget(基础天气组件)
|
||||
|
||||
**文件:**
|
||||
- `LanMountainDesktop/Views/Components/WeatherWidget.axaml`
|
||||
- `LanMountainDesktop/Views/Components/WeatherWidget.axaml.cs`
|
||||
|
||||
**设计目标:**
|
||||
- 大字体温度显示(类似 Google Weather)
|
||||
- 天气状况文字清晰可读
|
||||
- 位置和温度范围弱化显示
|
||||
- 图标与文字对齐优化
|
||||
|
||||
**XAML 改动:**
|
||||
```xml
|
||||
<Border x:Name="RootBorder"
|
||||
CornerRadius="{DynamicResource DesignCornerRadiusComponent}"
|
||||
ClipToBounds="True">
|
||||
<Grid>
|
||||
<components:MaterialWeatherSceneControl x:Name="Scene" />
|
||||
<Border x:Name="OverlayBorder" />
|
||||
|
||||
<!-- 主内容区 -->
|
||||
<Grid x:Name="ContentGrid"
|
||||
RowDefinitions="*,Auto"
|
||||
Margin="20,16,20,14">
|
||||
|
||||
<!-- 上半区:温度 + 图标 -->
|
||||
<Grid ColumnDefinitions="*,Auto">
|
||||
<StackPanel VerticalAlignment="Center" Spacing="4">
|
||||
<!-- 温度:超大字体 -->
|
||||
<TextBlock x:Name="TemperatureTextBlock"
|
||||
Text="--°"
|
||||
FontSize="72"
|
||||
FontWeight="Bold"
|
||||
LineHeight="72" />
|
||||
<!-- 天气状况 -->
|
||||
<TextBlock x:Name="ConditionTextBlock"
|
||||
Text="Loading"
|
||||
FontSize="18"
|
||||
FontWeight="SemiBold"
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- 右侧图标 -->
|
||||
<components:WeatherIconView x:Name="MainIcon"
|
||||
Grid.Column="1"
|
||||
Width="72"
|
||||
Height="72"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
|
||||
<!-- 底部信息栏 -->
|
||||
<Grid Grid.Row="1" ColumnDefinitions="*,Auto">
|
||||
<TextBlock x:Name="LocationTextBlock"
|
||||
Text="Weather"
|
||||
FontSize="13"
|
||||
FontWeight="Medium"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
VerticalAlignment="Bottom" />
|
||||
<TextBlock x:Name="RangeTextBlock"
|
||||
Grid.Column="1"
|
||||
Text="-- / --"
|
||||
FontSize="13"
|
||||
FontWeight="Medium"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Bottom" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Border>
|
||||
```
|
||||
|
||||
**CS 改动:**
|
||||
- 调整响应式布局的字体缩放比例
|
||||
- 更新颜色绑定使用新的调色板字段
|
||||
|
||||
---
|
||||
|
||||
### Task 3: 重构 ExtendedWeatherWidget(扩展天气组件)
|
||||
|
||||
**文件:**
|
||||
- `LanMountainDesktop/Views/Components/ExtendedWeatherWidget.axaml`
|
||||
- `LanMountainDesktop/Views/Components/ExtendedWeatherWidget.axaml.cs`
|
||||
|
||||
**设计目标:**
|
||||
- 顶部区域:位置+温度+图标横向排列
|
||||
- 指标区域:使用 Material 3 风格的标签卡片
|
||||
- 逐小时预报:水平滚动卡片,时间+图标+温度
|
||||
- 逐日预报:列表式布局,日期+图标+高低温
|
||||
|
||||
**XAML 改动:**
|
||||
```xml
|
||||
<Border x:Name="RootBorder"
|
||||
CornerRadius="{DynamicResource DesignCornerRadiusComponent}"
|
||||
ClipToBounds="True">
|
||||
<Grid>
|
||||
<components:MaterialWeatherSceneControl x:Name="Scene" />
|
||||
<Border x:Name="OverlayBorder" />
|
||||
|
||||
<Grid x:Name="ContentGrid"
|
||||
RowDefinitions="Auto,Auto,Auto,Auto"
|
||||
Margin="20,16,20,14"
|
||||
RowSpacing="12">
|
||||
|
||||
<!-- 顶部:位置 + 图标 + 温度 -->
|
||||
<Grid ColumnDefinitions="*,Auto,Auto" VerticalAlignment="Center">
|
||||
<StackPanel VerticalAlignment="Center">
|
||||
<TextBlock x:Name="LocationTextBlock"
|
||||
Text="Weather"
|
||||
FontSize="13"
|
||||
FontWeight="Medium"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
Opacity="0.72" />
|
||||
<TextBlock x:Name="ConditionTextBlock"
|
||||
Text="Loading"
|
||||
FontSize="16"
|
||||
FontWeight="SemiBold"
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
</StackPanel>
|
||||
<components:WeatherIconView x:Name="MainIcon"
|
||||
Grid.Column="1"
|
||||
Width="56"
|
||||
Height="56"
|
||||
Margin="0,0,10,0" />
|
||||
<TextBlock x:Name="TemperatureTextBlock"
|
||||
Grid.Column="2"
|
||||
Text="--°"
|
||||
FontSize="56"
|
||||
FontWeight="Bold"
|
||||
VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
|
||||
<!-- 指标区域 -->
|
||||
<UniformGrid x:Name="MetricGrid" Grid.Row="1" Rows="1" Columns="3" />
|
||||
|
||||
<!-- 逐小时预报 -->
|
||||
<Border Grid.Row="2"
|
||||
Background="{DynamicResource SurfaceColor}"
|
||||
CornerRadius="{DynamicResource DesignCornerRadiusMd}"
|
||||
Padding="10,8">
|
||||
<UniformGrid x:Name="HourlyGrid" Rows="1" Columns="6" />
|
||||
</Border>
|
||||
|
||||
<!-- 逐日预报 -->
|
||||
<Border Grid.Row="3"
|
||||
Background="{DynamicResource SurfaceColor}"
|
||||
CornerRadius="{DynamicResource DesignCornerRadiusMd}"
|
||||
Padding="10,8">
|
||||
<UniformGrid x:Name="DailyGrid" Rows="1" Columns="5" />
|
||||
</Border>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Border>
|
||||
```
|
||||
|
||||
**CS 改动:**
|
||||
- `CreateMetric` 方法:使用圆角卡片,Material 3 风格标签
|
||||
- `BuildHourlyItems` 方法:改进卡片样式,统一圆角
|
||||
- `BuildDailyItems` 方法:改进卡片样式,统一圆角
|
||||
|
||||
---
|
||||
|
||||
### Task 4: 重构 HourlyWeatherWidget(逐小时天气组件)
|
||||
|
||||
**文件:**
|
||||
- `LanMountainDesktop/Views/Components/HourlyWeatherWidget.axaml`
|
||||
- `LanMountainDesktop/Views/Components/HourlyWeatherWidget.axaml.cs`
|
||||
|
||||
**设计目标:**
|
||||
- 顶部简洁信息栏
|
||||
- 逐小时预报使用 Material 卡片风格
|
||||
- 时间、图标、温度垂直排列
|
||||
|
||||
**XAML 改动:**
|
||||
```xml
|
||||
<Border x:Name="RootBorder"
|
||||
CornerRadius="{DynamicResource DesignCornerRadiusComponent}"
|
||||
ClipToBounds="True">
|
||||
<Grid>
|
||||
<components:MaterialWeatherSceneControl x:Name="Scene" />
|
||||
<Border x:Name="OverlayBorder" />
|
||||
|
||||
<Grid x:Name="ContentGrid"
|
||||
RowDefinitions="Auto,*"
|
||||
Margin="18,14"
|
||||
RowSpacing="12">
|
||||
|
||||
<!-- 顶部信息栏 -->
|
||||
<Grid ColumnDefinitions="Auto,*,Auto,Auto" VerticalAlignment="Center">
|
||||
<TextBlock x:Name="TemperatureTextBlock"
|
||||
Text="--°"
|
||||
FontSize="42"
|
||||
FontWeight="Bold"
|
||||
VerticalAlignment="Center" />
|
||||
<StackPanel Grid.Column="1" Margin="12,0,0,0" VerticalAlignment="Center">
|
||||
<TextBlock x:Name="ConditionTextBlock"
|
||||
Text="Loading"
|
||||
FontSize="15"
|
||||
FontWeight="SemiBold"
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
<TextBlock x:Name="LocationTextBlock"
|
||||
Text="Weather"
|
||||
FontSize="12"
|
||||
FontWeight="Medium"
|
||||
Opacity="0.72"
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
</StackPanel>
|
||||
<TextBlock x:Name="RangeTextBlock"
|
||||
Grid.Column="2"
|
||||
Text="-- / --"
|
||||
FontSize="12"
|
||||
FontWeight="Medium"
|
||||
VerticalAlignment="Center"
|
||||
Opacity="0.72"
|
||||
Margin="0,0,10,0" />
|
||||
<components:WeatherIconView x:Name="MainIcon"
|
||||
Grid.Column="3"
|
||||
Width="48"
|
||||
Height="48" />
|
||||
</Grid>
|
||||
|
||||
<!-- 逐小时预报卡片容器 -->
|
||||
<Border Grid.Row="1"
|
||||
Background="{DynamicResource SurfaceColor}"
|
||||
CornerRadius="{DynamicResource DesignCornerRadiusMd}"
|
||||
Padding="8,6">
|
||||
<UniformGrid x:Name="HourlyGrid" Rows="1" Columns="6" />
|
||||
</Border>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Border>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 5: 重构 MultiDayWeatherWidget(多日天气组件)
|
||||
|
||||
**文件:**
|
||||
- `LanMountainDesktop/Views/Components/MultiDayWeatherWidget.axaml`
|
||||
- `LanMountainDesktop/Views/Components/MultiDayWeatherWidget.axaml.cs`
|
||||
|
||||
**设计目标:**
|
||||
- 左侧:当前天气信息(图标+温度+状况+位置)
|
||||
- 右侧:多日预报列表,使用行式布局
|
||||
|
||||
**XAML 改动:**
|
||||
```xml
|
||||
<Border x:Name="RootBorder"
|
||||
CornerRadius="{DynamicResource DesignCornerRadiusComponent}"
|
||||
ClipToBounds="True">
|
||||
<Grid>
|
||||
<components:MaterialWeatherSceneControl x:Name="Scene" />
|
||||
<Border x:Name="OverlayBorder" />
|
||||
|
||||
<Grid x:Name="ContentGrid"
|
||||
ColumnDefinitions="1.2*,1.6*"
|
||||
Margin="18,14"
|
||||
ColumnSpacing="14">
|
||||
|
||||
<!-- 左侧当前天气 -->
|
||||
<StackPanel VerticalAlignment="Center" Spacing="6">
|
||||
<components:WeatherIconView x:Name="MainIcon"
|
||||
Width="64"
|
||||
Height="64"
|
||||
HorizontalAlignment="Left" />
|
||||
<TextBlock x:Name="TemperatureTextBlock"
|
||||
Text="--°"
|
||||
FontSize="42"
|
||||
FontWeight="Bold" />
|
||||
<TextBlock x:Name="ConditionTextBlock"
|
||||
Text="Loading"
|
||||
FontSize="15"
|
||||
FontWeight="SemiBold"
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
<TextBlock x:Name="LocationTextBlock"
|
||||
Text="Weather"
|
||||
FontSize="12"
|
||||
FontWeight="Medium"
|
||||
Opacity="0.72"
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- 右侧多日预报 -->
|
||||
<Border Grid.Column="1"
|
||||
Background="{DynamicResource SurfaceColor}"
|
||||
CornerRadius="{DynamicResource DesignCornerRadiusMd}"
|
||||
Padding="10,8">
|
||||
<ItemsControl x:Name="DailyItemsControl" />
|
||||
</Border>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Border>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 6: 重构 WeatherClockWidget(天气时钟组件)
|
||||
|
||||
**文件:**
|
||||
- `LanMountainDesktop/Views/Components/WeatherClockWidget.axaml`
|
||||
- `LanMountainDesktop/Views/Components/WeatherClockWidget.axaml.cs`
|
||||
|
||||
**设计目标:**
|
||||
- 左侧:大字体时间+日期
|
||||
- 右侧:天气图标+温度+状况
|
||||
- 信息层级清晰
|
||||
|
||||
**XAML 改动:**
|
||||
```xml
|
||||
<Border x:Name="RootBorder"
|
||||
CornerRadius="{DynamicResource DesignCornerRadiusComponent}"
|
||||
ClipToBounds="True">
|
||||
<Grid>
|
||||
<components:MaterialWeatherSceneControl x:Name="Scene" />
|
||||
<Border x:Name="OverlayBorder" />
|
||||
|
||||
<Grid x:Name="ContentGrid"
|
||||
ColumnDefinitions="*,Auto"
|
||||
Margin="18,12"
|
||||
ColumnSpacing="12">
|
||||
|
||||
<!-- 左侧时间 -->
|
||||
<StackPanel VerticalAlignment="Center" Spacing="2">
|
||||
<TextBlock x:Name="TimeTextBlock"
|
||||
Text="--:--"
|
||||
FontSize="38"
|
||||
FontWeight="Bold"
|
||||
LineHeight="38" />
|
||||
<TextBlock x:Name="DateTextBlock"
|
||||
Text="Weather"
|
||||
FontSize="12"
|
||||
FontWeight="Medium"
|
||||
Opacity="0.72"
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- 右侧天气 -->
|
||||
<StackPanel Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right"
|
||||
Spacing="1">
|
||||
<components:WeatherIconView x:Name="MainIcon"
|
||||
Width="44"
|
||||
Height="44"
|
||||
HorizontalAlignment="Right" />
|
||||
<TextBlock x:Name="TemperatureTextBlock"
|
||||
Text="--°"
|
||||
FontSize="20"
|
||||
FontWeight="SemiBold"
|
||||
HorizontalAlignment="Right" />
|
||||
<TextBlock x:Name="ConditionTextBlock"
|
||||
Text="Loading"
|
||||
FontSize="11"
|
||||
FontWeight="Medium"
|
||||
HorizontalAlignment="Right"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
MaxWidth="100"
|
||||
Opacity="0.82" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Border>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 7: 更新 ExtendedWeatherWidget 的代码后置文件
|
||||
|
||||
**文件:** `LanMountainDesktop/Views/Components/ExtendedWeatherWidget.axaml.cs`
|
||||
|
||||
**改动:**
|
||||
- `CreateMetric` 方法改进:
|
||||
- 使用 `DesignCornerRadiusSm` 圆角
|
||||
- 使用新的 `SurfaceColor` 作为卡片背景
|
||||
- 优化字体大小和间距
|
||||
|
||||
- `BuildHourlyItems` 方法改进:
|
||||
- 使用 `DesignCornerRadiusSm` 圆角
|
||||
- 使用 `SurfaceColor` 作为卡片背景
|
||||
- 时间、图标、温度垂直排列,居中对齐
|
||||
|
||||
- `BuildDailyItems` 方法改进:
|
||||
- 使用 `DesignCornerRadiusSm` 圆角
|
||||
- 使用 `SurfaceColor` 作为卡片背景
|
||||
- 日期、图标、高低温垂直排列
|
||||
|
||||
---
|
||||
|
||||
### Task 8: 更新 HourlyWeatherWidget 的代码后置文件
|
||||
|
||||
**文件:** `LanMountainDesktop/Views/Components/HourlyWeatherWidget.axaml.cs`
|
||||
|
||||
**改动:**
|
||||
- `CreateChip` 方法改进:
|
||||
- 使用 `DesignCornerRadiusSm` 圆角
|
||||
- 使用 `SurfaceColor` 作为卡片背景
|
||||
- 优化垂直排列的间距
|
||||
|
||||
---
|
||||
|
||||
### Task 9: 更新 MultiDayWeatherWidget 的代码后置文件
|
||||
|
||||
**文件:** `LanMountainDesktop/Views/Components/MultiDayWeatherWidget.axaml.cs`
|
||||
|
||||
**改动:**
|
||||
- `CreateRow` 方法改进:
|
||||
- 添加底部分割线(除最后一行)
|
||||
- 优化列间距和对齐
|
||||
- 高低温使用不同透明度区分
|
||||
|
||||
---
|
||||
|
||||
### Task 10: 更新 MaterialWeatherVisualTheme 调色板
|
||||
|
||||
**文件:** `LanMountainDesktop/Views/Components/MaterialWeatherVisualTheme.cs`
|
||||
|
||||
**改动:**
|
||||
- 为 `MaterialWeatherPalette` 添加新字段:
|
||||
- `SurfaceColor` - 用于卡片表面
|
||||
- `SurfaceVariantColor` - 用于变体表面
|
||||
- `OutlineColor` - 用于分割线
|
||||
|
||||
- 更新所有调色板生成方法:
|
||||
- `ResolveGooglePalette`
|
||||
- `ResolveGeometricPalette`
|
||||
- `ResolveBreezyPalette`
|
||||
- `ResolveLemonPalette`
|
||||
|
||||
- 每个调色板需要为白天/夜晚模式提供合适的 SurfaceColor:
|
||||
- 白天:低透明度白色(如 `#14FFFFFF`)
|
||||
- 夜晚:低透明度黑色(如 `#1A000000`)
|
||||
|
||||
---
|
||||
|
||||
### Task 11: 构建和测试
|
||||
|
||||
**命令:**
|
||||
```bash
|
||||
dotnet build LanMountainDesktop.slnx -c Debug
|
||||
dotnet test LanMountainDesktop.slnx -c Debug
|
||||
```
|
||||
|
||||
**验证清单:**
|
||||
- [ ] 所有天气组件正常编译
|
||||
- [ ] 运行时无异常
|
||||
- [ ] 4套视觉风格正常切换
|
||||
- [ ] 响应式布局正常工作
|
||||
- [ ] 圆角资源正确应用
|
||||
|
||||
---
|
||||
|
||||
## 文件改动汇总
|
||||
|
||||
| 文件 | 改动类型 | 说明 |
|
||||
|------|---------|------|
|
||||
| `MaterialWeatherVisualTheme.cs` | 修改 | 添加 SurfaceColor 等字段,更新所有调色板 |
|
||||
| `WeatherWidget.axaml` | 修改 | 重构布局,优化排版 |
|
||||
| `WeatherWidget.axaml.cs` | 修改 | 调整响应式布局和颜色绑定 |
|
||||
| `ExtendedWeatherWidget.axaml` | 修改 | 重构布局,添加卡片容器 |
|
||||
| `ExtendedWeatherWidget.axaml.cs` | 修改 | 改进卡片创建方法 |
|
||||
| `HourlyWeatherWidget.axaml` | 修改 | 重构布局,添加卡片容器 |
|
||||
| `HourlyWeatherWidget.axaml.cs` | 修改 | 改进卡片创建方法 |
|
||||
| `MultiDayWeatherWidget.axaml` | 修改 | 重构布局,添加卡片容器 |
|
||||
| `MultiDayWeatherWidget.axaml.cs` | 修改 | 改进行创建方法 |
|
||||
| `WeatherClockWidget.axaml` | 修改 | 重构布局,优化排版 |
|
||||
| `WeatherClockWidget.axaml.cs` | 修改 | 调整响应式布局 |
|
||||
|
||||
---
|
||||
|
||||
## 设计规范检查清单
|
||||
|
||||
- [ ] 所有组件根容器使用 `DesignCornerRadiusComponent`
|
||||
- [ ] 内部卡片使用 `DesignCornerRadiusMd` 或 `DesignCornerRadiusSm`
|
||||
- [ ] 不使用硬编码圆角值
|
||||
- [ ] 文字对比度符合 VISUAL_SPEC 要求
|
||||
- [ ] 间距使用一致的倍数(4px 基线)
|
||||
- [ ] 字体层级:温度(64-72px) > 状况(16-18px) > 位置/范围(12-13px)
|
||||
342
.trae/documents/weather-widget-visual-redesign.md
Normal file
342
.trae/documents/weather-widget-visual-redesign.md
Normal file
@@ -0,0 +1,342 @@
|
||||
# 天气组件视觉重构 Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 彻底重构阑山桌面天气系列组件的背景视觉和文字排版,为每种图标风格(Google Weather / Geometric / Breezy / Lemon)提供独立的背景配色和视觉质感,参考各天气 App 的 Material Design 风格,实现几何质感+柔和渐变+层次分明的排版。
|
||||
|
||||
**Architecture:** 保留现有数据层(WeatherWidgetBase、WeatherSnapshot、WeatherIconAssetResolver)和组件注册机制不变。核心改动:1) 将 `MaterialWeatherVisualTheme.ResolvePalette()` 扩展为按 styleId 分派不同配色方案;2) 重构 `MaterialWeatherSceneControl` 为按 styleId 渲染不同背景风格;3) 改进各天气 Widget 的文字排版层次。先创建 HTML Mock 验证视觉效果。
|
||||
|
||||
**Tech Stack:** Avalonia UI (XAML + C# code-behind)、HTML/CSS (Mock 预览)
|
||||
|
||||
---
|
||||
|
||||
## 当前状态分析
|
||||
|
||||
### 现有天气组件体系
|
||||
5 个天气组件,全部继承自 `WeatherWidgetBase`:
|
||||
|
||||
| 组件 | 文件 | 功能 |
|
||||
|------|------|------|
|
||||
| WeatherWidget | `WeatherWidget.axaml(.cs)` | 基础天气:温度+状况+图标+位置 |
|
||||
| WeatherClockWidget | `WeatherClockWidget.axaml(.cs)` | 天气+时钟 |
|
||||
| ExtendedWeatherWidget | `ExtendedWeatherWidget.axaml(.cs)` | 扩展天气:含指标/小时/多日预报 |
|
||||
| HourlyWeatherWidget | `HourlyWeatherWidget.axaml(.cs)` | 逐小时天气 |
|
||||
| MultiDayWeatherWidget | `MultiDayWeatherWidget.axaml(.cs)` | 多日天气 |
|
||||
|
||||
### 核心问题
|
||||
|
||||
1. **背景与图标风格脱钩**: `MaterialWeatherVisualTheme.ResolvePalette()` 只返回一套配色,与 `WeatherVisualStyleId`(GoogleWeatherV4/Geometric/Breezy/LemonFlutter)完全无关。切换图标风格时背景不变。
|
||||
2. **背景视觉单调**: `MaterialWeatherSceneControl` 只有一种手绘几何风格(椭圆+云+雨滴),质感差,缺乏各 App 的特色。
|
||||
3. **文字排版粗糙**: 温度数字不够大,信息层次不分明,指标用纯文字堆叠,预报区域无卡片样式。
|
||||
4. **半透明遮罩硬编码**: 所有组件都覆盖 `<Border Background="#30FFFFFF" />` 等硬编码遮罩,不随风格变化。
|
||||
|
||||
### 各天气 App 风格特征
|
||||
|
||||
**Google Weather (v4)**:
|
||||
- 背景:大面积柔和蓝白渐变,晴天偏暖黄蓝,雨天偏深蓝灰
|
||||
- 装饰:极简,几乎无几何装饰,纯靠渐变色彩表现天气氛围
|
||||
- 排版:温度超大(72px+),天气状况中等,位置小字
|
||||
|
||||
**Geometric Weather (几何天气)**:
|
||||
- 背景:深色系渐变(深蓝/深紫/深灰),搭配半透明几何圆形装饰
|
||||
- 装饰:大面积半透明圆形叠加,营造深度感
|
||||
- 排版:紧凑信息密度,指标用小标签
|
||||
|
||||
**Breezy Weather (微风天气)**:
|
||||
- 背景:清新渐变(浅蓝/浅绿/浅紫),比 Geometric 更明亮
|
||||
- 装饰:柔和波浪线条 + 少量几何装饰,Material Design 风格
|
||||
- 排版:卡片式预报,圆角芯片
|
||||
|
||||
**Lemon Weather (柠檬天气)**:
|
||||
- 背景:暖色系渐变(橙黄/粉紫/暖蓝),柠檬2偏扁平,柠檬3偏Material
|
||||
- 装饰:天气场景装饰(太阳光芒/云朵轮廓/雨丝),更有场景感
|
||||
- 排版:温度超大,天气图标突出
|
||||
|
||||
---
|
||||
|
||||
## 设计方案
|
||||
|
||||
### 视觉论文 (Visual Thesis)
|
||||
每种图标风格拥有独特的背景渐变配色和几何装饰语言——Google 纯净渐变、Geometric 深色几何、Breezy 清新波浪、Lemon 暖色场景——配合超大温度数字和层次分明的排版,在桌面小组件空间内实现 Material Design 的几何质感。
|
||||
|
||||
### 配色方案设计
|
||||
|
||||
每种风格 × 每种天气条件 × 昼夜 = 独立配色。以下为关键配色定义:
|
||||
|
||||
#### Google Weather 风格
|
||||
| 天气 | 白天 Top→Bottom | 夜晚 Top→Bottom |
|
||||
|------|----------------|----------------|
|
||||
| Clear | #4FC3F7 → #B3E5FC | #0D47A1 → #1A237E |
|
||||
| PartlyCloudy | #81D4FA → #E1F5FE | #1565C0 → #283593 |
|
||||
| Cloudy | #90A4AE → #CFD8DC | #37474F → #455A64 |
|
||||
| Rain | #78909C → #B0BEC5 | #263238 → #37474F |
|
||||
| Storm | #546E7A → #78909C | #1A1A2E → #263238 |
|
||||
| Snow | #E1F5FE → #FFFFFF | #1A237E → #283593 |
|
||||
| Fog/Haze | #B0BEC5 → #ECEFF1 | #455A64 → #546E7A |
|
||||
|
||||
#### Geometric 风格
|
||||
| 天气 | 白天 Top→Bottom | 夜晚 Top→Bottom |
|
||||
|------|----------------|----------------|
|
||||
| Clear | #1A237E → #3949AB | #0A0E27 → #1A1A3E |
|
||||
| PartlyCloudy | #283593 → #5C6BC0 | #0D1033 → #1E1E4A |
|
||||
| Cloudy | #37474F → #607D8B | #1A1A2E → #2D2D44 |
|
||||
| Rain | #1A237E → #3F51B5 | #0A0E27 → #1A1A3E |
|
||||
| Storm | #1A1A2E → #3F51B5 | #050510 → #1A1A2E |
|
||||
| Snow | #E8EAF6 → #C5CAE9 | #1A237E → #283593 |
|
||||
| Fog/Haze | #455A64 → #78909C | #1A1A2E → #37474F |
|
||||
|
||||
#### Breezy 风格
|
||||
| 天气 | 白天 Top→Bottom | 夜晚 Top→Bottom |
|
||||
|------|----------------|----------------|
|
||||
| Clear | #4DD0E1 → #80DEEA | #006064 → #00838F |
|
||||
| PartlyCloudy | #4FC3F7 → #B2EBF2 | #00695C → #00897B |
|
||||
| Cloudy | #80CBC4 → #B2DFDB | #37474F → #546E7A |
|
||||
| Rain | #4DB6AC → #80CBC4 | #004D40 → #00695C |
|
||||
| Storm | #26A69A → #4DB6AC | #1A1A2E → #004D40 |
|
||||
| Snow | #E0F7FA → #FFFFFF | #006064 → #00838F |
|
||||
| Fog/Haze | #80CBC4 → #E0F7FA | #37474F → #546E7A |
|
||||
|
||||
#### Lemon 风格
|
||||
| 天气 | 白天 Top→Bottom | 夜晚 Top→Bottom |
|
||||
|------|----------------|----------------|
|
||||
| Clear | #FFB74D → #FFF176 | #1A237E → #311B92 |
|
||||
| PartlyCloudy | #FF8A65 → #FFCC80 | #283593 → #4A148C |
|
||||
| Cloudy | #BCAAA4 → #D7CCC8 | #37474F → #4E342E |
|
||||
| Rain | #90A4AE → #B0BEC5 | #1A1A2E → #311B92 |
|
||||
| Storm | #78909C → #90A4AE | #0D0D1A → #1A1A2E |
|
||||
| Snow | #FFF9C4 → #FFFFFF | #1A237E → #311B92 |
|
||||
| Fog/Haze | #D7CCC8 → #EFEBE9 | #4E342E → #5D4037 |
|
||||
|
||||
### 排版改进方案
|
||||
|
||||
1. **温度超大化**: 温度字号从 56-58px 提升到 64-72px(基础组件),形成视觉锚点
|
||||
2. **层次分明**: 温度 → 天气状况 → 位置/指标,字号递减,透明度递减
|
||||
3. **指标标签化**: 湿度/风速/AQI 用半透明圆角标签展示,而非纯文字
|
||||
4. **预报芯片化**: 小时/每日预报用圆角半透明芯片卡片
|
||||
5. **图标间距**: 天气图标与文字之间增加 8-12px 间距
|
||||
|
||||
---
|
||||
|
||||
## 文件变更清单
|
||||
|
||||
| 文件 | 操作 | 说明 |
|
||||
|------|------|------|
|
||||
| `Views/Components/MaterialWeatherVisualTheme.cs` | 修改 | 扩展 ResolvePalette 支持 styleId 分派,新增4套风格配色 |
|
||||
| `Views/Components/MaterialWeatherSceneControl.cs` | 修改 | 按 styleId 渲染不同背景风格(纯渐变/深色几何/清新波浪/暖色场景) |
|
||||
| `Views/Components/WeatherWidgetBase.cs` | 修改 | 传递 styleId 到 SceneControl.Apply(),移除硬编码遮罩 |
|
||||
| `Views/Components/WeatherWidget.axaml` | 修改 | 改进排版层次,移除硬编码遮罩 |
|
||||
| `Views/Components/WeatherWidget.axaml.cs` | 修改 | 适配新排版 |
|
||||
| `Views/Components/WeatherClockWidget.axaml` | 修改 | 改进排版,移除硬编码遮罩 |
|
||||
| `Views/Components/WeatherClockWidget.axaml.cs` | 修改 | 适配新排版 |
|
||||
| `Views/Components/ExtendedWeatherWidget.axaml` | 修改 | 改进排版,指标标签化,预报芯片化 |
|
||||
| `Views/Components/ExtendedWeatherWidget.axaml.cs` | 修改 | 适配新排版+标签+芯片 |
|
||||
| `Views/Components/HourlyWeatherWidget.axaml` | 修改 | 改进排版,预报芯片化 |
|
||||
| `Views/Components/HourlyWeatherWidget.axaml.cs` | 修改 | 适配新排版+芯片 |
|
||||
| `Views/Components/MultiDayWeatherWidget.axaml` | 修改 | 改进排版 |
|
||||
| `Views/Components/MultiDayWeatherWidget.axaml.cs` | 修改 | 适配新排版 |
|
||||
| `mocks/weather-widget-mock.html` | 新建 | HTML Mock 预览(4种风格×2种天气×2种主题) |
|
||||
|
||||
---
|
||||
|
||||
## Task 分解
|
||||
|
||||
### Task 1: 创建 HTML Mock 预览
|
||||
|
||||
**Files:**
|
||||
- Create: `mocks/weather-widget-mock.html`
|
||||
|
||||
- [ ] **Step 1: 创建 HTML Mock 文件**
|
||||
|
||||
创建完整的 HTML Mock,包含:
|
||||
- 4 种风格(Google / Geometric / Breezy / Lemon)× 2 种天气(晴/雨)× 2 种主题(亮/暗)
|
||||
- 每种风格展示基础天气组件(温度+状况+图标+位置)
|
||||
- 改进后的排版:超大温度、层次分明、指标标签化
|
||||
- 亮色/暗色主题切换按钮
|
||||
|
||||
- [ ] **Step 2: 在浏览器中打开 Mock 验证效果**
|
||||
|
||||
Run: `start mocks/weather-widget-mock.html`
|
||||
|
||||
---
|
||||
|
||||
### Task 2: 扩展 MaterialWeatherVisualTheme 支持多风格配色
|
||||
|
||||
**Files:**
|
||||
- Modify: `LanMountainDesktop/Views/Components/MaterialWeatherVisualTheme.cs`
|
||||
|
||||
- [ ] **Step 1: 修改 ResolvePalette 方法签名**
|
||||
|
||||
将 `ResolvePalette(MaterialWeatherCondition condition, bool isNight)` 改为 `ResolvePalette(string? styleId, MaterialWeatherCondition condition, bool isNight)`,内部按 styleId 分派到不同配色方案。
|
||||
|
||||
- [ ] **Step 2: 新增 Google Weather 配色表**
|
||||
|
||||
为 GoogleWeatherV4 风格定义所有天气条件×昼夜的配色(参考上面配色方案设计章节)。
|
||||
|
||||
- [ ] **Step 3: 新增 Geometric 配色表**
|
||||
|
||||
为 Geometric 风格定义深色系配色。
|
||||
|
||||
- [ ] **Step 4: 新增 Breezy 配色表**
|
||||
|
||||
为 Breezy 风格定义清新渐变配色。
|
||||
|
||||
- [ ] **Step 5: 新增 Lemon 配色表**
|
||||
|
||||
为 LemonFlutter 风格定义暖色系配色。
|
||||
|
||||
- [ ] **Step 6: 更新所有调用点**
|
||||
|
||||
将所有 `ResolvePalette(condition, isNight)` 调用改为 `ResolvePalette(styleId, condition, isNight)`。
|
||||
|
||||
---
|
||||
|
||||
### Task 3: 重构 MaterialWeatherSceneControl 支持多风格背景
|
||||
|
||||
**Files:**
|
||||
- Modify: `LanMountainDesktop/Views/Components/MaterialWeatherSceneControl.cs`
|
||||
|
||||
- [ ] **Step 1: 扩展 Apply 方法签名**
|
||||
|
||||
将 `Apply(MaterialWeatherCondition condition, MaterialWeatherPalette palette, bool isLive)` 改为 `Apply(string? styleId, MaterialWeatherCondition condition, MaterialWeatherPalette palette, bool isLive)`,存储 styleId。
|
||||
|
||||
- [ ] **Step 2: 实现 Google Weather 风格渲染**
|
||||
|
||||
纯渐变背景,无几何装饰。背景使用 palette 的 BackgroundTop→BackgroundBottom 渐变。仅保留天气特效(雨滴/雪花/雾线)。
|
||||
|
||||
- [ ] **Step 3: 实现 Geometric 风格渲染**
|
||||
|
||||
深色渐变 + 大面积半透明几何圆形叠加。在基础渐变上叠加 2-3 个大椭圆(使用 palette 的 PrimaryShape/SecondaryShape/AccentShape),营造深度感。保留天气特效。
|
||||
|
||||
- [ ] **Step 4: 实现 Breezy 风格渲染**
|
||||
|
||||
清新渐变 + 柔和波浪线条。在基础渐变上绘制 2-3 条正弦波浪线(使用 palette 的 SurfaceTint),营造微风感。保留天气特效。
|
||||
|
||||
- [ ] **Step 5: 实现 Lemon 风格渲染**
|
||||
|
||||
暖色渐变 + 天气场景装饰。晴天绘制太阳光芒(放射线),多云绘制云朵轮廓,雨天绘制雨丝。保留天气特效。
|
||||
|
||||
- [ ] **Step 6: 更新所有调用点**
|
||||
|
||||
将所有 `SceneControl.Apply(condition, palette, isLive)` 改为 `SceneControl.Apply(styleId, condition, palette, isLive)`。
|
||||
|
||||
---
|
||||
|
||||
### Task 4: 更新 WeatherWidgetBase 传递 styleId
|
||||
|
||||
**Files:**
|
||||
- Modify: `LanMountainDesktop/Views/Components/WeatherWidgetBase.cs`
|
||||
|
||||
- [ ] **Step 1: 修改 ApplyCurrentScene 方法**
|
||||
|
||||
在 `ApplyCurrentScene()` 中将 `CurrentVisualStyleId` 传递给 `SceneControl.Apply()`。
|
||||
|
||||
- [ ] **Step 2: 修改 ApplySnapshot 中的 ResolvePalette 调用**
|
||||
|
||||
将 `MaterialWeatherVisualTheme.ResolvePalette(CurrentCondition, isNight)` 改为 `MaterialWeatherVisualTheme.ResolvePalette(CurrentVisualStyleId, CurrentCondition, isNight)`。
|
||||
|
||||
---
|
||||
|
||||
### Task 5: 改进各天气 Widget 的 XAML 排版
|
||||
|
||||
**Files:**
|
||||
- Modify: `WeatherWidget.axaml` — 移除硬编码遮罩 `<Border Background="#30FFFFFF" />`,改用 palette 驱动的半透明遮罩
|
||||
- Modify: `WeatherClockWidget.axaml` — 同上
|
||||
- Modify: `ExtendedWeatherWidget.axaml` — 同上 + 指标区域改用标签样式
|
||||
- Modify: `HourlyWeatherWidget.axaml` — 同上 + 预报区域改用芯片样式
|
||||
- Modify: `MultiDayWeatherWidget.axaml` — 同上
|
||||
|
||||
- [ ] **Step 1: 移除所有硬编码遮罩**
|
||||
|
||||
将 `<Border Background="#30FFFFFF" />` / `#42FFFFFF` / `#34FFFFFF` / `#38FFFFFF` / `#3CFFFFFF` 替换为 `<Border x:Name="OverlayBorder" />`,在 code-behind 中根据 palette 设置遮罩颜色。
|
||||
|
||||
- [ ] **Step 2: 改进 WeatherWidget 排版**
|
||||
|
||||
增大温度字号(58→64),增加图标与文字间距,调整位置文字透明度。
|
||||
|
||||
- [ ] **Step 3: 改进 WeatherClockWidget 排版**
|
||||
|
||||
增大时钟字号,增加天气信息与时间间距。
|
||||
|
||||
- [ ] **Step 4: 改进 ExtendedWeatherWidget 排版**
|
||||
|
||||
指标用半透明圆角标签,小时/每日预报用圆角芯片卡片。
|
||||
|
||||
- [ ] **Step 5: 改进 HourlyWeatherWidget 排版**
|
||||
|
||||
预报区域用圆角芯片卡片样式。
|
||||
|
||||
- [ ] **Step 6: 改进 MultiDayWeatherWidget 排版**
|
||||
|
||||
每日预报行增加分隔线和更好的间距。
|
||||
|
||||
---
|
||||
|
||||
### Task 6: 更新各天气 Widget 的 code-behind
|
||||
|
||||
**Files:**
|
||||
- Modify: 所有天气 Widget 的 `.axaml.cs` 文件
|
||||
|
||||
- [ ] **Step 1: 更新 WeatherWidget.axaml.cs**
|
||||
|
||||
- 设置 OverlayBorder 背景
|
||||
- 增大温度字号
|
||||
- 适配新排版参数
|
||||
|
||||
- [ ] **Step 2: 更新 WeatherClockWidget.axaml.cs**
|
||||
|
||||
- 设置 OverlayBorder 背景
|
||||
- 适配新排版
|
||||
|
||||
- [ ] **Step 3: 更新 ExtendedWeatherWidget.axaml.cs**
|
||||
|
||||
- 设置 OverlayBorder 背景
|
||||
- 指标标签化(CreateMetric 改为带圆角背景的标签)
|
||||
- 预报芯片化
|
||||
|
||||
- [ ] **Step 4: 更新 HourlyWeatherWidget.axaml.cs**
|
||||
|
||||
- 设置 OverlayBorder 背景
|
||||
- 预报芯片化(CreateChip 改为带圆角背景的芯片)
|
||||
|
||||
- [ ] **Step 5: 更新 MultiDayWeatherWidget.axaml.cs**
|
||||
|
||||
- 设置 OverlayBorder 背景
|
||||
- 适配新排版
|
||||
|
||||
---
|
||||
|
||||
### Task 7: 验证与测试
|
||||
|
||||
- [ ] **Step 1: 运行项目查看效果**
|
||||
|
||||
Run: `dotnet run --project LanMountainDesktop/LanMountainDesktop.csproj`
|
||||
|
||||
- [ ] **Step 2: 运行相关测试**
|
||||
|
||||
Run: `dotnet test LanMountainDesktop.slnx -c Debug`
|
||||
|
||||
- [ ] **Step 3: 检查圆角规范合规**
|
||||
|
||||
确认所有组件 RootBorder 使用 `DesignCornerRadiusComponent`,新增的标签/芯片使用 `DesignCornerRadiusSm`/`DesignCornerRadiusMd`。
|
||||
|
||||
---
|
||||
|
||||
## 假设与决策
|
||||
|
||||
1. **4 套独立风格**: 每种图标风格对应独立的背景配色和装饰风格,切换图标风格时背景也跟着变
|
||||
2. **配色表驱动**: 所有颜色定义在 `MaterialWeatherVisualTheme` 中,不硬编码到 SceneControl
|
||||
3. **保留天气特效**: 雨滴/雪花/雾线/闪电等天气特效在所有风格中保留,但颜色跟随 palette
|
||||
4. **遮罩动态化**: 半透明遮罩颜色从 palette 中派生,而非硬编码 `#30FFFFFF`
|
||||
5. **排版渐进改进**: 不做大规模 XAML 重构,而是在现有结构上优化字号/间距/透明度
|
||||
6. **数据层不变**: WeatherSnapshot、WeatherIconAssetResolver、WeatherWidgetBase 的数据逻辑不变
|
||||
7. **接口兼容**: IDesktopComponentWidget 等接口实现不变
|
||||
|
||||
## 验证步骤
|
||||
|
||||
1. HTML Mock 在浏览器中展示 4 种风格效果满意
|
||||
2. Avalonia 项目编译通过
|
||||
3. 运行项目,切换图标风格时背景配色和装饰风格跟着变化
|
||||
4. 亮色/暗色主题切换正常
|
||||
5. 5 个天气组件排版层次分明
|
||||
6. 指标标签化和预报芯片化正常显示
|
||||
7. 测试通过
|
||||
13
.trae/specs/dock-back-to-windows-button-display/checklist.md
Normal file
13
.trae/specs/dock-back-to-windows-button-display/checklist.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Checklist
|
||||
|
||||
- [ ] `AppSettingsSnapshot.BackToWindowsButtonDisplayMode` exists and defaults to `IconAndText`.
|
||||
- [ ] `AppSettingsSnapshot` contains icon source, Fluent icon name, and text icon settings with safe defaults.
|
||||
- [ ] General > Basic Settings includes one folded back-to-platform button settings expander.
|
||||
- [ ] The expander includes the display-mode dropdown.
|
||||
- [ ] The expander includes nested icon source, Fluent icon popup picker, and text icon input controls.
|
||||
- [ ] The Dock button left icon slot renders either a Fluent icon or custom text.
|
||||
- [ ] `IconAndText`, `IconOnly`, and `TextOnly` modes update the Dock button live.
|
||||
- [ ] Icon source, Fluent icon name, and text icon updates refresh the Dock button live.
|
||||
- [ ] The selected mode is preserved when MainWindow saves app settings.
|
||||
- [ ] Localization keys exist for zh-CN, en-US, ja-JP, and ko-KR.
|
||||
- [ ] `dotnet build LanMountainDesktop.slnx -c Debug` succeeds.
|
||||
29
.trae/specs/dock-back-to-windows-button-display/spec.md
Normal file
29
.trae/specs/dock-back-to-windows-button-display/spec.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Dock Back To Windows Button Display
|
||||
|
||||
## Summary
|
||||
|
||||
The Dock "Back to platform" action should expose a configurable left icon slot while keeping the localized platform text fixed.
|
||||
|
||||
## Requirements
|
||||
|
||||
- The default display mode is `IconAndText` so existing users keep a familiar Dock layout after upgrade.
|
||||
- The localized platform text remains controlled by the app and is not user-editable.
|
||||
- General > Basic Settings exposes one Fluent Avalonia `FASettingsExpander` for the back-to-platform button, with icon-related controls folded into nested `FASettingsExpanderItem` rows.
|
||||
- The main row exposes a dropdown with `IconAndText`, `IconOnly`, and `TextOnly` options.
|
||||
- A nested icon source row selects Fluent icon or text icon.
|
||||
- Fluent icon mode uses a popup picker-style flyout with search and a grid of the full FluentIcons `Icon` enum.
|
||||
- Text icon mode lets the user enter short text for the left icon slot.
|
||||
- Changing the dropdown persists to `AppSettingsSnapshot.BackToWindowsButtonDisplayMode` and updates the Dock button without restarting.
|
||||
- Changing the icon source, Fluent icon, or text icon persists to app settings and updates the Dock button without restarting.
|
||||
- `IconOnly` keeps the existing tooltip text so the button remains understandable.
|
||||
- `PinnedTaskbarActions` continues to control whether the action is visible; it does not replace the display mode setting.
|
||||
|
||||
## Acceptance Scenarios
|
||||
|
||||
- With default settings, the Dock button shows a small circle icon and the localized platform text.
|
||||
- Selecting icon only hides the platform text and keeps the configured left icon visible.
|
||||
- Selecting text only hides the left icon slot and keeps the localized platform text visible.
|
||||
- Choosing a Fluent icon changes the left icon slot.
|
||||
- Entering a short text icon changes the left icon slot.
|
||||
- Restarting the app restores the selected display mode.
|
||||
- Clicking the button still runs the existing minimize/back-to-platform behavior.
|
||||
@@ -1,3 +1,5 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Avalonia.Controls;
|
||||
using LanMountainDesktop.ComponentSystem;
|
||||
using LanMountainDesktop.Services;
|
||||
@@ -73,6 +75,48 @@ public sealed class DesktopComponentRenderModeTests
|
||||
Assert.Null(probe.RuntimeContext?.PlacementId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DefaultRuntimeRegistrations_IncludeMaterialWeatherComponents()
|
||||
{
|
||||
var componentIds = DesktopComponentRuntimeRegistry.GetDefaultRegistrations()
|
||||
.Select(registration => registration.ComponentId)
|
||||
.ToHashSet(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
Assert.Contains(BuiltInComponentIds.DesktopWeatherClock, componentIds);
|
||||
Assert.Contains(BuiltInComponentIds.DesktopWeather, componentIds);
|
||||
Assert.Contains(BuiltInComponentIds.DesktopHourlyWeather, componentIds);
|
||||
Assert.Contains(BuiltInComponentIds.DesktopMultiDayWeather, componentIds);
|
||||
Assert.Contains(BuiltInComponentIds.DesktopExtendedWeather, componentIds);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WeatherVisualStyleCatalog_NormalizesLegacyAndSupportedIds()
|
||||
{
|
||||
Assert.Equal(WeatherVisualStyleId.GoogleWeatherV4, WeatherVisualStyleCatalog.Normalize(null));
|
||||
Assert.Equal(WeatherVisualStyleId.GoogleWeatherV4, WeatherVisualStyleCatalog.Normalize("DefaultWeather"));
|
||||
Assert.Equal(WeatherVisualStyleId.GoogleWeatherV4, WeatherVisualStyleCatalog.Normalize("HyperOS3"));
|
||||
Assert.Equal(WeatherVisualStyleId.Geometric, WeatherVisualStyleCatalog.Normalize("Geometric"));
|
||||
Assert.Equal(WeatherVisualStyleId.Breezy, WeatherVisualStyleCatalog.Normalize("Breezy"));
|
||||
Assert.Equal(WeatherVisualStyleId.LemonFlutter, WeatherVisualStyleCatalog.Normalize("LemonFlutter"));
|
||||
Assert.Equal(WeatherVisualStyleId.GoogleWeatherV4, WeatherVisualStyleCatalog.Normalize("MissingPack"));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(WeatherVisualStyleId.GoogleWeatherV4)]
|
||||
[InlineData(WeatherVisualStyleId.Geometric)]
|
||||
[InlineData(WeatherVisualStyleId.Breezy)]
|
||||
[InlineData(WeatherVisualStyleId.LemonFlutter)]
|
||||
public void WeatherIconAssetResolver_ResolvesCoreWeatherStates(string styleId)
|
||||
{
|
||||
Assert.NotNull(WeatherIconAssetResolver.ResolveAssetUri(styleId, 0, "Clear", isDaylight: true));
|
||||
Assert.NotNull(WeatherIconAssetResolver.ResolveAssetUri(styleId, 1, "Partly cloudy", isDaylight: false));
|
||||
Assert.NotNull(WeatherIconAssetResolver.ResolveAssetUri(styleId, 7, "Rain", isDaylight: true));
|
||||
Assert.NotNull(WeatherIconAssetResolver.ResolveAssetUri(styleId, 4, "Thunderstorm", isDaylight: true));
|
||||
Assert.NotNull(WeatherIconAssetResolver.ResolveAssetUri(styleId, 13, "Snow", isDaylight: true));
|
||||
Assert.NotNull(WeatherIconAssetResolver.ResolveAssetUri(styleId, 18, "Fog", isDaylight: true));
|
||||
Assert.NotNull(WeatherIconAssetResolver.ResolveAssetUri(styleId, 999, "Unknown", isDaylight: true));
|
||||
}
|
||||
|
||||
private static DesktopComponentRuntimeDescriptor CreateDescriptor()
|
||||
{
|
||||
Assert.True(CreateRuntimeRegistry().TryGetDescriptor(ComponentId, out var descriptor));
|
||||
|
||||
16
LanMountainDesktop/Assets/MaterialWeatherIcons/NOTICE.md
Normal file
16
LanMountainDesktop/Assets/MaterialWeatherIcons/NOTICE.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# Material Weather Icons Sources
|
||||
|
||||
This folder contains weather icon assets imported for LanMountainDesktop weather widgets.
|
||||
|
||||
The icon packs are included because the product owner explicitly requested original-style assets and accepted the licensing risk for uncertain or non-free icon packs. Keep this notice with the assets.
|
||||
|
||||
## Included packs
|
||||
|
||||
- `google-weather-v4`: imported from `mbatthew/GoogleWeatherIconsV4Pack`, which documents that the application code is MIT but the weather icons are sourced from Google Weather Icons v4 and have uncertain licensing.
|
||||
- `geometric`: imported from `breezy-weather/geometric-icon-provider`, an open-source rewrite of the Geometric Weather icon provider. Breezy's icon-pack index documents related assets as non-free.
|
||||
- `breezy`: imported from `breezy-weather/breezy-weather` app resources. Breezy Weather is LGPL-3.0; verify individual asset terms before external redistribution.
|
||||
- `lemon-flutter`: imported from `yangSpica27/spica_weather_flutter`, MIT licensed.
|
||||
|
||||
## Pending sources
|
||||
|
||||
- Lemon Weather v2/v3 are not included yet. They should only be added after a concrete public repository and asset license are verified.
|
||||
@@ -0,0 +1,7 @@
|
||||
# Breezy Weather Icon Pack
|
||||
|
||||
- Source: https://github.com/breezy-weather/breezy-weather
|
||||
- Related icon-pack documentation: https://github.com/breezy-weather/breezy-weather-icon-packs
|
||||
- Imported path: `app/src/main/res/drawable/weather_*.png`
|
||||
- License note: Breezy Weather code is LGPL-3.0; verify individual asset terms before external redistribution.
|
||||
- Usage: bundled as a selectable weather visual style at user request.
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
# Geometric Weather Icon Pack
|
||||
|
||||
- Source: https://github.com/breezy-weather/geometric-icon-provider
|
||||
- Related references: https://github.com/WangDaYeeeeee/GeometricWeather and https://app.sharess.cn/page/app/detail?id=hfkx5khY8cWw6bTLWKadOg%3D%3D
|
||||
- Imported path: `app/src/main/res/drawable/weather_*.png`
|
||||
- License note: provider code is LGPL-3.0; related Breezy icon-pack documentation marks Geometric assets as non-free.
|
||||
- Usage: bundled as a selectable weather visual style at user request.
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user