mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-22 00:54:26 +08:00
0.5.8
插件市场
This commit is contained in:
@@ -180,6 +180,14 @@ public partial class MainWindow
|
||||
StatusBarSpacingCustomPanel.Content = L("settings.status_bar.spacing_custom_label", "Custom spacing (%)");
|
||||
|
||||
WeatherPanelTitleTextBlock.Text = L("settings.weather.title", "Weather");
|
||||
WeatherPreviewSectionTextBlock.Text = L("settings.weather.preview_section", "Weather Preview");
|
||||
WeatherSettingsSectionTextBlock.Text = L("settings.weather.settings_section", "Settings");
|
||||
WeatherPreviewSettingsExpander.Header = L("settings.weather.preview_panel_header", "Weather Preview");
|
||||
WeatherPreviewSettingsExpander.Description = L(
|
||||
"settings.weather.preview_panel_desc",
|
||||
"Refresh and verify current weather service status.");
|
||||
WeatherPreviewButton.Content = L("settings.weather.refresh_button", "Refresh");
|
||||
|
||||
WeatherLocationSettingsExpander.Header = L("settings.weather.location_source_header", "Location Source");
|
||||
WeatherLocationSettingsExpander.Description = L(
|
||||
"settings.weather.location_source_desc",
|
||||
@@ -189,6 +197,10 @@ public partial class MainWindow
|
||||
WeatherLocationModeCityChipItem.Content = L("settings.weather.mode_city_search", "City Search");
|
||||
WeatherLocationModeCoordinatesChipItem.Content = L("settings.weather.mode_coordinates", "Coordinates");
|
||||
WeatherAutoRefreshToggleSwitch.Content = L("settings.weather.auto_refresh", "Auto refresh location on startup");
|
||||
WeatherLocationSelectionTitleTextBlock.Text = L("settings.weather.city_selection_label", "City Selection");
|
||||
WeatherLocationSelectionDescriptionTextBlock.Text = L(
|
||||
"settings.weather.location_city_summary_desc",
|
||||
"Select the current city used for weather queries.");
|
||||
|
||||
WeatherCitySearchSettingsExpander.Header = L("settings.weather.city_search_header", "City Search");
|
||||
WeatherCitySearchSettingsExpander.Description = L(
|
||||
@@ -208,24 +220,12 @@ public partial class MainWindow
|
||||
WeatherLocationNameTextBox.Watermark = L("settings.weather.location_name_placeholder", "Display name (optional)");
|
||||
WeatherApplyCoordinatesButton.Content = L("settings.weather.apply_coordinates_button", "Apply Coordinates");
|
||||
|
||||
WeatherPreviewSettingsExpander.Header = L("settings.weather.preview_panel_header", "Weather Preview");
|
||||
WeatherPreviewSettingsExpander.Description = L(
|
||||
"settings.weather.preview_panel_desc",
|
||||
"Refresh and verify current weather service status.");
|
||||
WeatherPreviewButton.Content = L("settings.weather.refresh_button", "Refresh");
|
||||
|
||||
WeatherLocationSettingsExpander.Header = L("settings.weather.location_msg_header", "Location Source");
|
||||
WeatherLocationSettingsExpander.Description = L(
|
||||
"settings.weather.location_msg_desc",
|
||||
"Choose how weather widgets resolve location.");
|
||||
WeatherLocationModeCityChipItem.Content = L("settings.weather.mode_city", "City Search");
|
||||
WeatherLocationModeCoordinatesChipItem.Content = L("settings.weather.mode_coordinates", "Coordinates");
|
||||
WeatherAutoRefreshToggleSwitch.Content = L("settings.weather.auto_location_toggle", "Auto refresh location on startup");
|
||||
|
||||
WeatherAlertFilterSettingsExpander.Header = L("settings.weather.alert_filter_header", "Excluded Alerts");
|
||||
WeatherAlertFilterSettingsExpander.Description = L(
|
||||
"settings.weather.alert_filter_desc",
|
||||
"Alerts containing these words will not be shown. One rule per line.");
|
||||
WeatherAlertListTitleTextBlock.Text = L("settings.weather.alert_list_label", "Exclude List");
|
||||
WeatherAlertListDescriptionTextBlock.Text = L("settings.weather.alert_list_desc", "One exclusion rule per line.");
|
||||
WeatherExcludedAlertsTextBox.Watermark = L("settings.weather.alert_filter_placeholder", "One keyword per line");
|
||||
|
||||
WeatherIconPackSettingsExpander.Header = L("settings.weather.icon_style_header", "Weather Icon Style");
|
||||
@@ -239,6 +239,10 @@ public partial class MainWindow
|
||||
WeatherNoTlsSettingsExpander.Description = L(
|
||||
"settings.weather.no_tls_desc",
|
||||
"Not recommended. Enable only for incompatible network environments.");
|
||||
WeatherNoTlsToggleSwitch.Content = L("settings.weather.no_tls_toggle", "Allow non-TLS request fallback");
|
||||
WeatherFooterHintTextBlock.Text = L(
|
||||
"settings.weather.footer_hint",
|
||||
"Desktop weather widgets will reuse the location and alert exclusion settings configured here.");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(_weatherSearchKeyword))
|
||||
{
|
||||
@@ -418,6 +422,7 @@ public partial class MainWindow
|
||||
WeatherLocationStatusTextBlock.Text = L(
|
||||
"settings.weather.status_city_empty",
|
||||
"No city location is configured.");
|
||||
UpdateWeatherLocationSummaryCard();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -430,6 +435,7 @@ public partial class MainWindow
|
||||
modeText,
|
||||
locationName,
|
||||
_weatherLocationKey);
|
||||
UpdateWeatherLocationSummaryCard();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -442,6 +448,7 @@ public partial class MainWindow
|
||||
string.IsNullOrWhiteSpace(_weatherLocationKey)
|
||||
? BuildCoordinateLocationKey(_weatherLatitude, _weatherLongitude)
|
||||
: _weatherLocationKey);
|
||||
UpdateWeatherLocationSummaryCard();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1396,6 +1396,8 @@ public partial class MainWindow
|
||||
{
|
||||
WeatherCoordinateSettingsExpander.IsVisible = _weatherLocationMode == WeatherLocationMode.Coordinates;
|
||||
}
|
||||
|
||||
UpdateWeatherLocationSummaryCard();
|
||||
}
|
||||
|
||||
private void OnWeatherLocationModeSelectionChanged(object? sender, SelectionChangedEventArgs e)
|
||||
@@ -1879,7 +1881,7 @@ public partial class MainWindow
|
||||
var weather = snapshot.Current.WeatherText ??
|
||||
L("settings.weather.preview_unknown", "Unknown");
|
||||
var temperature = snapshot.Current.TemperatureC.HasValue
|
||||
? string.Create(CultureInfo.InvariantCulture, $"{snapshot.Current.TemperatureC.Value:F1} C")
|
||||
? FormatWeatherPreviewTemperature(snapshot.Current.TemperatureC.Value)
|
||||
: "--";
|
||||
var updatedAt = snapshot.ObservationTime ?? snapshot.FetchedAt;
|
||||
|
||||
@@ -1922,6 +1924,14 @@ public partial class MainWindow
|
||||
|
||||
private void UpdateWeatherPreviewSummary(int? weatherCode, string temperatureText, DateTimeOffset? updatedAt)
|
||||
{
|
||||
if (WeatherPreviewIconImage is not null)
|
||||
{
|
||||
var kind = HyperOS3WeatherTheme.ResolveVisualKind(weatherCode, _isNightMode);
|
||||
WeatherPreviewIconImage.Source = HyperOS3WeatherAssetLoader.LoadImage(
|
||||
HyperOS3WeatherTheme.ResolveIconAsset(kind)) ??
|
||||
HyperOS3WeatherAssetLoader.LoadImage(HyperOS3WeatherTheme.ResolveHeroIconAsset(kind));
|
||||
}
|
||||
|
||||
if (WeatherPreviewIconSymbol is not null)
|
||||
{
|
||||
WeatherPreviewIconSymbol.Symbol = ResolveWeatherPreviewSymbol(weatherCode, _isNightMode);
|
||||
@@ -1941,10 +1951,15 @@ public partial class MainWindow
|
||||
}
|
||||
|
||||
WeatherPreviewUpdatedTextBlock.Text = updatedAt.HasValue
|
||||
? Lf("weather.widget.updated_format", "Updated {0:HH:mm}", updatedAt.Value.LocalDateTime)
|
||||
? updatedAt.Value.LocalDateTime.ToString("yyyy/M/d HH:mm:ss", CultureInfo.InvariantCulture)
|
||||
: "-";
|
||||
}
|
||||
|
||||
private static string FormatWeatherPreviewTemperature(double temperatureC)
|
||||
{
|
||||
return string.Create(CultureInfo.InvariantCulture, $"{temperatureC:0.#}°C");
|
||||
}
|
||||
|
||||
private static Symbol ResolveWeatherPreviewSymbol(int? weatherCode, bool isNight)
|
||||
{
|
||||
return weatherCode switch
|
||||
@@ -1960,6 +1975,38 @@ public partial class MainWindow
|
||||
};
|
||||
}
|
||||
|
||||
private void UpdateWeatherLocationSummaryCard()
|
||||
{
|
||||
if (WeatherLocationSelectionTitleTextBlock is null ||
|
||||
WeatherLocationSelectionDescriptionTextBlock is null ||
|
||||
WeatherLocationValueTextBlock is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_weatherLocationMode == WeatherLocationMode.Coordinates)
|
||||
{
|
||||
WeatherLocationSelectionTitleTextBlock.Text = L("settings.weather.coordinates_selection_label", "Coordinate Location");
|
||||
WeatherLocationSelectionDescriptionTextBlock.Text = L(
|
||||
"settings.weather.location_coordinates_summary_desc",
|
||||
"Set latitude/longitude and optional location name used for weather queries.");
|
||||
WeatherLocationValueTextBlock.Text = string.IsNullOrWhiteSpace(_weatherLocationName)
|
||||
? string.Create(CultureInfo.InvariantCulture, $"{_weatherLatitude:F4}, {_weatherLongitude:F4}")
|
||||
: _weatherLocationName;
|
||||
return;
|
||||
}
|
||||
|
||||
WeatherLocationSelectionTitleTextBlock.Text = L("settings.weather.city_selection_label", "City Selection");
|
||||
WeatherLocationSelectionDescriptionTextBlock.Text = L(
|
||||
"settings.weather.location_city_summary_desc",
|
||||
"Select the current city used for weather queries.");
|
||||
WeatherLocationValueTextBlock.Text = !string.IsNullOrWhiteSpace(_weatherLocationName)
|
||||
? _weatherLocationName
|
||||
: !string.IsNullOrWhiteSpace(_weatherLocationKey)
|
||||
? _weatherLocationKey
|
||||
: L("settings.weather.location_not_selected", "No location selected");
|
||||
}
|
||||
|
||||
private void SetWeatherSearchBusy(bool isBusy)
|
||||
{
|
||||
if (WeatherSearchButton is not null)
|
||||
@@ -2661,6 +2708,8 @@ public partial class MainWindow
|
||||
|
||||
// --- WeatherSettingsPage ---
|
||||
internal TextBlock WeatherPanelTitleTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherPanelTitleTextBlock")!;
|
||||
internal TextBlock WeatherPreviewSectionTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherPreviewSectionTextBlock")!;
|
||||
internal TextBlock WeatherSettingsSectionTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherSettingsSectionTextBlock")!;
|
||||
internal FluentAvalonia.UI.Controls.SettingsExpander WeatherPreviewSettingsExpander => WeatherSettingsPanel.FindControl<FluentAvalonia.UI.Controls.SettingsExpander>("WeatherPreviewSettingsExpander")!;
|
||||
internal FluentAvalonia.UI.Controls.SettingsExpander WeatherLocationSettingsExpander => WeatherSettingsPanel.FindControl<FluentAvalonia.UI.Controls.SettingsExpander>("WeatherLocationSettingsExpander")!;
|
||||
internal FluentAvalonia.UI.Controls.SettingsExpander WeatherCitySearchSettingsExpander => WeatherSettingsPanel.FindControl<FluentAvalonia.UI.Controls.SettingsExpander>("WeatherCitySearchSettingsExpander")!;
|
||||
@@ -2691,6 +2740,7 @@ public partial class MainWindow
|
||||
internal FluentAvalonia.UI.Controls.NumberBox WeatherLongitudeNumberBox => WeatherSettingsPanel.FindControl<FluentAvalonia.UI.Controls.NumberBox>("WeatherLongitudeNumberBox")!;
|
||||
internal TextBlock WeatherCoordinateStatusTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherCoordinateStatusTextBlock")!;
|
||||
internal TextBlock WeatherPreviewResultTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherPreviewResultTextBlock")!;
|
||||
internal Image WeatherPreviewIconImage => WeatherSettingsPanel.FindControl<Image>("WeatherPreviewIconImage")!;
|
||||
internal FluentIcons.Avalonia.Fluent.SymbolIcon WeatherPreviewIconSymbol => WeatherSettingsPanel.FindControl<FluentIcons.Avalonia.Fluent.SymbolIcon>("WeatherPreviewIconSymbol")!;
|
||||
internal TextBlock WeatherPreviewTemperatureTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherPreviewTemperatureTextBlock")!;
|
||||
internal TextBlock WeatherPreviewUpdatedTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherPreviewUpdatedTextBlock")!;
|
||||
@@ -2698,7 +2748,13 @@ public partial class MainWindow
|
||||
internal FluentAvalonia.UI.Controls.ProgressRing WeatherPreviewProgressRing => WeatherSettingsPanel.FindControl<FluentAvalonia.UI.Controls.ProgressRing>("WeatherPreviewProgressRing")!;
|
||||
internal ComboBoxItem WeatherIconPackFluentRegularItem => WeatherSettingsPanel.FindControl<ComboBoxItem>("WeatherIconPackFluentRegularItem")!;
|
||||
internal ComboBoxItem WeatherIconPackFluentFilledItem => WeatherSettingsPanel.FindControl<ComboBoxItem>("WeatherIconPackFluentFilledItem")!;
|
||||
internal TextBlock WeatherLocationSelectionTitleTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherLocationSelectionTitleTextBlock")!;
|
||||
internal TextBlock WeatherLocationSelectionDescriptionTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherLocationSelectionDescriptionTextBlock")!;
|
||||
internal TextBlock WeatherLocationValueTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherLocationValueTextBlock")!;
|
||||
internal TextBlock WeatherLocationStatusTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherLocationStatusTextBlock")!;
|
||||
internal TextBlock WeatherAlertListTitleTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherAlertListTitleTextBlock")!;
|
||||
internal TextBlock WeatherAlertListDescriptionTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherAlertListDescriptionTextBlock")!;
|
||||
internal TextBlock WeatherFooterHintTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherFooterHintTextBlock")!;
|
||||
|
||||
// --- UpdateSettingsPage ---
|
||||
internal TextBlock UpdatePanelTitleTextBlock => UpdateSettingsPanel.FindControl<TextBlock>("UpdatePanelTitleTextBlock")!;
|
||||
|
||||
@@ -205,8 +205,7 @@ public partial class MainWindow : Window
|
||||
GridEdgeInsetSlider.ValueChanged += OnGridEdgeInsetSliderChanged;
|
||||
ApplyGridButton.Click += OnApplyGridSizeClick;
|
||||
|
||||
NightModeToggleSwitch.Checked += OnNightModeChecked;
|
||||
NightModeToggleSwitch.Unchecked += OnNightModeUnchecked;
|
||||
NightModeToggleSwitch.IsCheckedChanged += OnNightModeIsCheckedChanged;
|
||||
RecommendedColorButton1.Click += OnRecommendedColorClick;
|
||||
RecommendedColorButton2.Click += OnRecommendedColorClick;
|
||||
RecommendedColorButton3.Click += OnRecommendedColorClick;
|
||||
@@ -221,40 +220,67 @@ public partial class MainWindow : Window
|
||||
MonetColorButton5.Click += OnMonetColorClick;
|
||||
MonetColorButton6.Click += OnMonetColorClick;
|
||||
|
||||
StatusBarClockToggleSwitch.Checked += OnStatusBarClockChecked;
|
||||
StatusBarClockToggleSwitch.Unchecked += OnStatusBarClockUnchecked;
|
||||
ClockFormatHMSSRadio.Checked += OnClockFormatChanged;
|
||||
ClockFormatHMRadio.Checked += OnClockFormatChanged;
|
||||
StatusBarClockToggleSwitch.IsCheckedChanged += OnStatusBarClockIsCheckedChanged;
|
||||
ClockFormatHMSSRadio.IsCheckedChanged += OnClockFormatChanged;
|
||||
ClockFormatHMRadio.IsCheckedChanged += OnClockFormatChanged;
|
||||
StatusBarSpacingModeComboBox.SelectionChanged += OnStatusBarSpacingModeChanged;
|
||||
StatusBarSpacingSlider.ValueChanged += OnStatusBarSpacingSliderChanged;
|
||||
|
||||
WeatherPreviewButton.Click += OnTestWeatherRequestClick;
|
||||
WeatherLocationModeComboBox.SelectionChanged += OnWeatherLocationModeSelectionChanged;
|
||||
WeatherLocationModeChipListBox.SelectionChanged += OnWeatherLocationModeChipSelectionChanged;
|
||||
WeatherAutoRefreshToggleSwitch.Checked += OnWeatherAutoRefreshToggled;
|
||||
WeatherAutoRefreshToggleSwitch.Unchecked += OnWeatherAutoRefreshToggled;
|
||||
WeatherAutoRefreshToggleSwitch.IsCheckedChanged += OnWeatherAutoRefreshToggled;
|
||||
WeatherSearchButton.Click += OnSearchWeatherCityClick;
|
||||
WeatherApplyCityButton.Click += OnApplyWeatherCitySelectionClick;
|
||||
WeatherApplyCoordinatesButton.Click += OnApplyWeatherCoordinatesClick;
|
||||
WeatherExcludedAlertsTextBox.LostFocus += OnWeatherExcludedAlertsLostFocus;
|
||||
WeatherIconPackComboBox.SelectionChanged += OnWeatherIconPackSelectionChanged;
|
||||
WeatherNoTlsToggleSwitch.Checked += OnWeatherNoTlsToggled;
|
||||
WeatherNoTlsToggleSwitch.Unchecked += OnWeatherNoTlsToggled;
|
||||
WeatherNoTlsToggleSwitch.IsCheckedChanged += OnWeatherNoTlsToggled;
|
||||
|
||||
LanguageComboBox.SelectionChanged += OnLanguageSelectionChanged;
|
||||
TimeZoneComboBox.SelectionChanged += OnTimeZoneSelectionChanged;
|
||||
|
||||
AutoCheckUpdatesToggleSwitch.Checked += OnAutoCheckUpdatesToggled;
|
||||
AutoCheckUpdatesToggleSwitch.Unchecked += OnAutoCheckUpdatesToggled;
|
||||
AutoCheckUpdatesToggleSwitch.IsCheckedChanged += OnAutoCheckUpdatesToggled;
|
||||
UpdateChannelChipListBox.SelectionChanged += OnUpdateChannelSelectionChanged;
|
||||
CheckForUpdatesButton.Click += OnCheckForUpdatesClick;
|
||||
DownloadAndInstallUpdateButton.Click += OnDownloadAndInstallUpdateClick;
|
||||
|
||||
AutoStartWithWindowsToggleSwitch.Checked += OnAutoStartWithWindowsToggled;
|
||||
AutoStartWithWindowsToggleSwitch.Unchecked += OnAutoStartWithWindowsToggled;
|
||||
AutoStartWithWindowsToggleSwitch.IsCheckedChanged += OnAutoStartWithWindowsToggled;
|
||||
AppRenderModeComboBox.SelectionChanged += OnAppRenderModeSelectionChanged;
|
||||
}
|
||||
|
||||
private void OnNightModeIsCheckedChanged(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is not ToggleButton toggleButton)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (toggleButton.IsChecked == true)
|
||||
{
|
||||
OnNightModeChecked(sender, e);
|
||||
return;
|
||||
}
|
||||
|
||||
OnNightModeUnchecked(sender, e);
|
||||
}
|
||||
|
||||
private void OnStatusBarClockIsCheckedChanged(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is not ToggleButton toggleButton)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (toggleButton.IsChecked == true)
|
||||
{
|
||||
OnStatusBarClockChecked(sender, e);
|
||||
return;
|
||||
}
|
||||
|
||||
OnStatusBarClockUnchecked(sender, e);
|
||||
}
|
||||
|
||||
protected override void OnOpened(EventArgs e)
|
||||
{
|
||||
base.OnOpened(e);
|
||||
@@ -787,6 +813,11 @@ public partial class MainWindow : Window
|
||||
return;
|
||||
}
|
||||
|
||||
if (radioButton.IsChecked != true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_clockDisplayFormat = formatTag == "Hm"
|
||||
? ClockDisplayFormat.HourMinute
|
||||
: ClockDisplayFormat.HourMinuteSecond;
|
||||
|
||||
@@ -4,91 +4,116 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="using:FluentAvalonia.UI.Controls"
|
||||
xmlns:fi="using:FluentIcons.Avalonia.Fluent"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="1200"
|
||||
mc:Ignorable="d" d:DesignWidth="860" d:DesignHeight="1200"
|
||||
x:Class="LanMountainDesktop.Views.SettingsPages.WeatherSettingsPage">
|
||||
|
||||
<UserControl.Styles>
|
||||
<Style Selector="StackPanel.weather-settings-root TextBlock.section-eyebrow">
|
||||
<Setter Property="FontSize" Value="13" />
|
||||
<Setter Property="FontWeight" Value="SemiBold" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource AdaptiveTextSecondaryBrush}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="StackPanel.weather-settings-root Border.preview-icon-shell">
|
||||
<Setter Property="Width" Value="62" />
|
||||
<Setter Property="Height" Value="62" />
|
||||
<Setter Property="CornerRadius" Value="18" />
|
||||
<Setter Property="Background" Value="{DynamicResource AdaptiveSurfaceRaisedBrush}" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource AdaptiveButtonBorderBrush}" />
|
||||
<Setter Property="Padding" Value="10" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="StackPanel.weather-settings-root Border.settings-note-shell">
|
||||
<Setter Property="Background" Value="{DynamicResource AdaptiveSurfaceRaisedBrush}" />
|
||||
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusSm}" />
|
||||
<Setter Property="Padding" Value="14,12" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="StackPanel.weather-settings-root Border.settings-expander-shell">
|
||||
<Setter Property="Margin" Value="0" />
|
||||
</Style>
|
||||
</UserControl.Styles>
|
||||
|
||||
<StackPanel x:Name="WeatherSettingsContentPanel"
|
||||
Classes="settings-animated-intro weather-settings-root"
|
||||
Margin="0,0,8,0"
|
||||
Spacing="16">
|
||||
Spacing="12">
|
||||
<TextBlock x:Name="WeatherPanelTitleTextBlock"
|
||||
FontSize="24"
|
||||
FontSize="28"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
|
||||
Text="Weather" />
|
||||
|
||||
<!-- Weather Preview Card -->
|
||||
<Border Classes="settings-expander-shell">
|
||||
<ui:SettingsExpander x:Name="WeatherPreviewSettingsExpander"
|
||||
Header="Weather Preview"
|
||||
Description="Refresh and verify current weather service status."
|
||||
IsExpanded="True">
|
||||
<ui:SettingsExpander.IconSource>
|
||||
<fi:SymbolIconSource Symbol="WeatherSunny" />
|
||||
</ui:SettingsExpander.IconSource>
|
||||
<ui:SettingsExpander.Footer>
|
||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
||||
<Button x:Name="WeatherPreviewButton"
|
||||
Padding="12,8"
|
||||
Content="Refresh" />
|
||||
<ui:ProgressRing x:Name="WeatherPreviewProgressRing"
|
||||
Width="20"
|
||||
Height="20"
|
||||
IsActive="True"
|
||||
IsVisible="False" />
|
||||
</StackPanel>
|
||||
</ui:SettingsExpander.Footer>
|
||||
|
||||
<ui:SettingsExpanderItem>
|
||||
<Grid ColumnDefinitions="Auto,*" ColumnSpacing="12">
|
||||
<Border Width="44"
|
||||
Height="44"
|
||||
CornerRadius="{DynamicResource DesignCornerRadiusXs}"
|
||||
BorderThickness="1"
|
||||
BorderBrush="{DynamicResource AdaptiveButtonBorderBrush}"
|
||||
Background="{DynamicResource AdaptiveButtonBackgroundBrush}">
|
||||
<fi:SymbolIcon x:Name="WeatherPreviewIconSymbol"
|
||||
Symbol="WeatherSunny"
|
||||
IconVariant="Regular"
|
||||
FontSize="22"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
<StackPanel Spacing="8">
|
||||
<TextBlock x:Name="WeatherPreviewSectionTextBlock"
|
||||
Classes="section-eyebrow"
|
||||
Text="Weather Preview" />
|
||||
|
||||
<Border Classes="settings-expander-shell"
|
||||
Padding="18,16">
|
||||
<Grid RowDefinitions="Auto,Auto"
|
||||
RowSpacing="10">
|
||||
<Grid ColumnDefinitions="Auto,*,Auto"
|
||||
ColumnSpacing="14">
|
||||
<Border Classes="preview-icon-shell">
|
||||
<Image x:Name="WeatherPreviewIconImage"
|
||||
Stretch="Uniform" />
|
||||
</Border>
|
||||
|
||||
<StackPanel Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Spacing="2">
|
||||
Spacing="3">
|
||||
<TextBlock x:Name="WeatherPreviewTemperatureTextBlock"
|
||||
FontSize="22"
|
||||
FontSize="34"
|
||||
FontWeight="SemiBold"
|
||||
Text="--°" />
|
||||
Text="--" />
|
||||
<TextBlock x:Name="WeatherPreviewUpdatedTextBlock"
|
||||
FontSize="12"
|
||||
FontSize="13"
|
||||
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
|
||||
Text="-" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Column="2"
|
||||
Orientation="Horizontal"
|
||||
Spacing="8"
|
||||
VerticalAlignment="Center">
|
||||
<Button x:Name="WeatherPreviewButton"
|
||||
Padding="16,8"
|
||||
Content="Refresh" />
|
||||
<ui:ProgressRing x:Name="WeatherPreviewProgressRing"
|
||||
Width="20"
|
||||
Height="20"
|
||||
IsActive="True"
|
||||
IsVisible="False" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ui:SettingsExpanderItem>
|
||||
|
||||
<ui:SettingsExpanderItem>
|
||||
<TextBlock x:Name="WeatherPreviewResultTextBlock"
|
||||
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
|
||||
Grid.Row="1"
|
||||
TextWrapping="Wrap"
|
||||
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
|
||||
Text="Use refresh to verify your weather configuration." />
|
||||
</ui:SettingsExpanderItem>
|
||||
</ui:SettingsExpander>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
|
||||
<Border Background="{DynamicResource SurfaceStrokeColorDefaultBrush}"
|
||||
Height="1" />
|
||||
|
||||
<TextBlock x:Name="WeatherSettingsSectionTextBlock"
|
||||
Classes="section-eyebrow"
|
||||
Text="Settings" />
|
||||
|
||||
<!-- Location Source Card -->
|
||||
<Border Classes="settings-expander-shell">
|
||||
<ui:SettingsExpander x:Name="WeatherLocationSettingsExpander"
|
||||
Header="Location Source"
|
||||
Description="Choose how weather widgets resolve location."
|
||||
IsExpanded="True">
|
||||
<ui:SettingsExpander.IconSource>
|
||||
<fi:SymbolIconSource Symbol="Location" />
|
||||
</ui:SettingsExpander.IconSource>
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ListBox x:Name="WeatherLocationModeChipListBox"
|
||||
Classes="settings-chip-list"
|
||||
HorizontalAlignment="Right"
|
||||
SelectionMode="Single">
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
@@ -104,6 +129,39 @@
|
||||
</ListBox>
|
||||
</ui:SettingsExpander.Footer>
|
||||
|
||||
<ui:SettingsExpanderItem>
|
||||
<Grid ColumnDefinitions="*,Auto"
|
||||
ColumnSpacing="18">
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock x:Name="WeatherLocationSelectionTitleTextBlock"
|
||||
FontSize="17"
|
||||
FontWeight="SemiBold"
|
||||
Text="City Selection" />
|
||||
<TextBlock x:Name="WeatherLocationSelectionDescriptionTextBlock"
|
||||
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
|
||||
TextWrapping="Wrap"
|
||||
Text="Select the current city used for weather queries." />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Column="1"
|
||||
MaxWidth="420"
|
||||
HorizontalAlignment="Right"
|
||||
Spacing="4">
|
||||
<TextBlock x:Name="WeatherLocationValueTextBlock"
|
||||
FontSize="17"
|
||||
FontWeight="SemiBold"
|
||||
TextAlignment="Right"
|
||||
TextWrapping="Wrap"
|
||||
Text="No location selected" />
|
||||
<TextBlock x:Name="WeatherLocationStatusTextBlock"
|
||||
FontSize="12"
|
||||
TextAlignment="Right"
|
||||
TextWrapping="Wrap"
|
||||
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ui:SettingsExpanderItem>
|
||||
|
||||
<ui:SettingsExpanderItem>
|
||||
<ui:SettingsExpanderItem.Footer>
|
||||
<ToggleSwitch x:Name="WeatherAutoRefreshToggleSwitch"
|
||||
@@ -111,16 +169,18 @@
|
||||
</ui:SettingsExpanderItem.Footer>
|
||||
</ui:SettingsExpanderItem>
|
||||
|
||||
<!-- ComboBox hidden as in original -->
|
||||
<ComboBox x:Name="WeatherLocationModeComboBox"
|
||||
IsVisible="False">
|
||||
<ComboBoxItem x:Name="WeatherLocationModeCityItem" Tag="CitySearch" Content="City Search" />
|
||||
<ComboBoxItem x:Name="WeatherLocationModeCoordinatesItem" Tag="Coordinates" Content="Coordinates" />
|
||||
<ComboBoxItem x:Name="WeatherLocationModeCityItem"
|
||||
Tag="CitySearch"
|
||||
Content="City Search" />
|
||||
<ComboBoxItem x:Name="WeatherLocationModeCoordinatesItem"
|
||||
Tag="Coordinates"
|
||||
Content="Coordinates" />
|
||||
</ComboBox>
|
||||
</ui:SettingsExpander>
|
||||
</Border>
|
||||
|
||||
<!-- City Search Card -->
|
||||
<Border Classes="settings-expander-shell">
|
||||
<ui:SettingsExpander x:Name="WeatherCitySearchSettingsExpander"
|
||||
Header="City Search"
|
||||
@@ -128,38 +188,42 @@
|
||||
IsExpanded="True">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<Button x:Name="WeatherApplyCityButton"
|
||||
Padding="12,8"
|
||||
Padding="14,8"
|
||||
Content="Apply City" />
|
||||
</ui:SettingsExpander.Footer>
|
||||
|
||||
<ui:SettingsExpanderItem Content="Advanced Filters">
|
||||
<StackPanel Spacing="10">
|
||||
<Grid ColumnDefinitions="*,Auto,Auto" ColumnSpacing="8">
|
||||
<ui:SettingsExpanderItem>
|
||||
<StackPanel Spacing="12">
|
||||
<Grid ColumnDefinitions="*,Auto,Auto"
|
||||
ColumnSpacing="10">
|
||||
<TextBox x:Name="WeatherCitySearchTextBox"
|
||||
Watermark="e.g. Beijing" />
|
||||
<ui:ProgressRing x:Name="WeatherSearchProgressRing"
|
||||
Grid.Column="1"
|
||||
Width="24"
|
||||
Height="24"
|
||||
Width="22"
|
||||
Height="22"
|
||||
IsActive="True"
|
||||
IsVisible="False" />
|
||||
<Button x:Name="WeatherSearchButton"
|
||||
Grid.Column="2"
|
||||
Padding="12,8"
|
||||
Padding="14,8"
|
||||
Content="Search" />
|
||||
</Grid>
|
||||
|
||||
<ComboBox x:Name="WeatherCityResultsComboBox"
|
||||
Width="320" />
|
||||
HorizontalAlignment="Stretch"
|
||||
MinWidth="320" />
|
||||
|
||||
<TextBlock x:Name="WeatherSearchStatusTextBlock"
|
||||
FontSize="12"
|
||||
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
|
||||
TextWrapping="Wrap"
|
||||
Text="Search by city name and apply one location." />
|
||||
</StackPanel>
|
||||
</ui:SettingsExpanderItem>
|
||||
</ui:SettingsExpander>
|
||||
</Border>
|
||||
|
||||
<!-- Coordinates Card -->
|
||||
<Border Classes="settings-expander-shell">
|
||||
<ui:SettingsExpander x:Name="WeatherCoordinateSettingsExpander"
|
||||
Header="Coordinates"
|
||||
@@ -168,13 +232,14 @@
|
||||
IsExpanded="True">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<Button x:Name="WeatherApplyCoordinatesButton"
|
||||
Padding="12,8"
|
||||
Padding="14,8"
|
||||
Content="Apply Coordinates" />
|
||||
</ui:SettingsExpander.Footer>
|
||||
|
||||
<ui:SettingsExpanderItem>
|
||||
<StackPanel Spacing="12">
|
||||
<Grid ColumnDefinitions="*,*" ColumnSpacing="10">
|
||||
<Grid ColumnDefinitions="*,*"
|
||||
ColumnSpacing="10">
|
||||
<ui:NumberBox x:Name="WeatherLatitudeNumberBox"
|
||||
Grid.Column="0"
|
||||
Header="Latitude"
|
||||
@@ -194,65 +259,96 @@
|
||||
LargeChange="1"
|
||||
Value="116.4074" />
|
||||
</Grid>
|
||||
|
||||
<TextBox x:Name="WeatherLocationKeyTextBox"
|
||||
Watermark="Location key (optional)" />
|
||||
<TextBox x:Name="WeatherLocationNameTextBox"
|
||||
Watermark="Display name (optional)" />
|
||||
<TextBlock x:Name="WeatherCoordinateStatusTextBlock"
|
||||
FontSize="12"
|
||||
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}" />
|
||||
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
|
||||
TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
</ui:SettingsExpanderItem>
|
||||
</ui:SettingsExpander>
|
||||
</Border>
|
||||
|
||||
<!-- Excluded Alerts Card -->
|
||||
<Border Classes="settings-expander-shell">
|
||||
<ui:SettingsExpander x:Name="WeatherAlertFilterSettingsExpander"
|
||||
Header="Excluded Alerts"
|
||||
Description="Alerts containing these words will not be shown. One rule per line."
|
||||
IsExpanded="True">
|
||||
<ui:SettingsExpanderItem>
|
||||
<TextBox x:Name="WeatherExcludedAlertsTextBox"
|
||||
MinHeight="96"
|
||||
MaxHeight="220"
|
||||
Width="360"
|
||||
TextWrapping="Wrap"
|
||||
AcceptsReturn="True" />
|
||||
<Grid ColumnDefinitions="Auto,*"
|
||||
ColumnSpacing="20">
|
||||
<StackPanel Width="220"
|
||||
Spacing="4">
|
||||
<TextBlock x:Name="WeatherAlertListTitleTextBlock"
|
||||
FontSize="17"
|
||||
FontWeight="SemiBold"
|
||||
Text="Exclude List" />
|
||||
<TextBlock x:Name="WeatherAlertListDescriptionTextBlock"
|
||||
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
|
||||
TextWrapping="Wrap"
|
||||
Text="One exclusion rule per line." />
|
||||
</StackPanel>
|
||||
|
||||
<TextBox x:Name="WeatherExcludedAlertsTextBox"
|
||||
Grid.Column="1"
|
||||
MinHeight="96"
|
||||
MaxHeight="220"
|
||||
HorizontalAlignment="Stretch"
|
||||
AcceptsReturn="True"
|
||||
TextWrapping="Wrap"
|
||||
Watermark="One keyword per line" />
|
||||
</Grid>
|
||||
</ui:SettingsExpanderItem>
|
||||
</ui:SettingsExpander>
|
||||
</Border>
|
||||
|
||||
<!-- Weather Style Card -->
|
||||
<Border Classes="settings-expander-shell">
|
||||
<ui:SettingsExpander x:Name="WeatherIconPackSettingsExpander"
|
||||
Header="Weather Icon Style"
|
||||
Description="Choose Fluent Icon style for weather symbols."
|
||||
IsExpanded="True">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ComboBox x:Name="WeatherIconPackComboBox"
|
||||
Width="240">
|
||||
<ComboBoxItem x:Name="WeatherIconPackFluentRegularItem" Tag="FluentRegular" Content="Fluent Regular" />
|
||||
<ComboBoxItem x:Name="WeatherIconPackFluentFilledItem" Tag="FluentFilled" Content="Fluent Filled" />
|
||||
</ComboBox>
|
||||
</ui:SettingsExpander.Footer>
|
||||
</ui:SettingsExpander>
|
||||
</Border>
|
||||
|
||||
<!-- No TLS Card -->
|
||||
<Border Classes="settings-expander-shell">
|
||||
<ui:SettingsExpander x:Name="WeatherNoTlsSettingsExpander"
|
||||
Header="No TLS Weather Request"
|
||||
Description="Not recommended. Enable only for incompatible network environments."
|
||||
IsExpanded="True">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ToggleSwitch x:Name="WeatherNoTlsToggleSwitch" />
|
||||
<ToggleSwitch x:Name="WeatherNoTlsToggleSwitch"
|
||||
Content="Allow non-TLS request fallback" />
|
||||
</ui:SettingsExpander.Footer>
|
||||
</ui:SettingsExpander>
|
||||
</Border>
|
||||
|
||||
<TextBlock x:Name="WeatherLocationStatusTextBlock"
|
||||
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
|
||||
Text="No city location is configured." />
|
||||
<Border Classes="settings-note-shell">
|
||||
<TextBlock x:Name="WeatherFooterHintTextBlock"
|
||||
TextWrapping="Wrap"
|
||||
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
|
||||
Text="Desktop weather widgets will reuse the location and alert exclusion settings configured here." />
|
||||
</Border>
|
||||
|
||||
<Grid IsVisible="False">
|
||||
<ui:SettingsExpander x:Name="WeatherPreviewSettingsExpander"
|
||||
Header="Weather Preview"
|
||||
Description="Refresh and verify current weather service status." />
|
||||
<fi:SymbolIcon x:Name="WeatherPreviewIconSymbol"
|
||||
Symbol="WeatherSunny"
|
||||
IconVariant="Regular" />
|
||||
<Border Classes="settings-expander-shell">
|
||||
<ui:SettingsExpander x:Name="WeatherIconPackSettingsExpander"
|
||||
Header="Weather Icon Style"
|
||||
Description="Choose Fluent Icon style for weather symbols.">
|
||||
<ui:SettingsExpander.Footer>
|
||||
<ComboBox x:Name="WeatherIconPackComboBox"
|
||||
Width="220">
|
||||
<ComboBoxItem x:Name="WeatherIconPackFluentRegularItem"
|
||||
Tag="FluentRegular"
|
||||
Content="Fluent Regular" />
|
||||
<ComboBoxItem x:Name="WeatherIconPackFluentFilledItem"
|
||||
Tag="FluentFilled"
|
||||
Content="Fluent Filled" />
|
||||
</ComboBox>
|
||||
</ui:SettingsExpander.Footer>
|
||||
</ui:SettingsExpander>
|
||||
</Border>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
|
||||
@@ -126,6 +126,8 @@ public partial class SettingsWindow
|
||||
|
||||
// --- WeatherSettingsPage ---
|
||||
internal TextBlock WeatherPanelTitleTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherPanelTitleTextBlock")!;
|
||||
internal TextBlock WeatherPreviewSectionTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherPreviewSectionTextBlock")!;
|
||||
internal TextBlock WeatherSettingsSectionTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherSettingsSectionTextBlock")!;
|
||||
internal FluentAvalonia.UI.Controls.SettingsExpander WeatherPreviewSettingsExpander => WeatherSettingsPanel.FindControl<FluentAvalonia.UI.Controls.SettingsExpander>("WeatherPreviewSettingsExpander")!;
|
||||
internal FluentAvalonia.UI.Controls.SettingsExpander WeatherLocationSettingsExpander => WeatherSettingsPanel.FindControl<FluentAvalonia.UI.Controls.SettingsExpander>("WeatherLocationSettingsExpander")!;
|
||||
internal FluentAvalonia.UI.Controls.SettingsExpander WeatherCitySearchSettingsExpander => WeatherSettingsPanel.FindControl<FluentAvalonia.UI.Controls.SettingsExpander>("WeatherCitySearchSettingsExpander")!;
|
||||
@@ -156,6 +158,7 @@ public partial class SettingsWindow
|
||||
internal FluentAvalonia.UI.Controls.NumberBox WeatherLongitudeNumberBox => WeatherSettingsPanel.FindControl<FluentAvalonia.UI.Controls.NumberBox>("WeatherLongitudeNumberBox")!;
|
||||
internal TextBlock WeatherCoordinateStatusTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherCoordinateStatusTextBlock")!;
|
||||
internal TextBlock WeatherPreviewResultTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherPreviewResultTextBlock")!;
|
||||
internal Image WeatherPreviewIconImage => WeatherSettingsPanel.FindControl<Image>("WeatherPreviewIconImage")!;
|
||||
internal FluentIcons.Avalonia.Fluent.SymbolIcon WeatherPreviewIconSymbol => WeatherSettingsPanel.FindControl<FluentIcons.Avalonia.Fluent.SymbolIcon>("WeatherPreviewIconSymbol")!;
|
||||
internal TextBlock WeatherPreviewTemperatureTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherPreviewTemperatureTextBlock")!;
|
||||
internal TextBlock WeatherPreviewUpdatedTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherPreviewUpdatedTextBlock")!;
|
||||
@@ -163,7 +166,13 @@ public partial class SettingsWindow
|
||||
internal FluentAvalonia.UI.Controls.ProgressRing WeatherPreviewProgressRing => WeatherSettingsPanel.FindControl<FluentAvalonia.UI.Controls.ProgressRing>("WeatherPreviewProgressRing")!;
|
||||
internal ComboBoxItem WeatherIconPackFluentRegularItem => WeatherSettingsPanel.FindControl<ComboBoxItem>("WeatherIconPackFluentRegularItem")!;
|
||||
internal ComboBoxItem WeatherIconPackFluentFilledItem => WeatherSettingsPanel.FindControl<ComboBoxItem>("WeatherIconPackFluentFilledItem")!;
|
||||
internal TextBlock WeatherLocationSelectionTitleTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherLocationSelectionTitleTextBlock")!;
|
||||
internal TextBlock WeatherLocationSelectionDescriptionTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherLocationSelectionDescriptionTextBlock")!;
|
||||
internal TextBlock WeatherLocationValueTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherLocationValueTextBlock")!;
|
||||
internal TextBlock WeatherLocationStatusTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherLocationStatusTextBlock")!;
|
||||
internal TextBlock WeatherAlertListTitleTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherAlertListTitleTextBlock")!;
|
||||
internal TextBlock WeatherAlertListDescriptionTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherAlertListDescriptionTextBlock")!;
|
||||
internal TextBlock WeatherFooterHintTextBlock => WeatherSettingsPanel.FindControl<TextBlock>("WeatherFooterHintTextBlock")!;
|
||||
|
||||
// --- UpdateSettingsPage ---
|
||||
internal TextBlock UpdatePanelTitleTextBlock => UpdateSettingsPanel.FindControl<TextBlock>("UpdatePanelTitleTextBlock")!;
|
||||
|
||||
@@ -48,10 +48,166 @@ public partial class SettingsWindow
|
||||
base.OnClosed(e);
|
||||
}
|
||||
|
||||
private void OnSettingsNavSelectionChanged(object? sender, FluentAvalonia.UI.Controls.NavigationViewSelectionChangedEventArgs e)
|
||||
private void InitializeSettingsNavigation()
|
||||
{
|
||||
_settingsNavItems.Clear();
|
||||
_pluginSettingsNavItems.Clear();
|
||||
|
||||
SettingsPrimaryNavHost.Children.Clear();
|
||||
SettingsSecondaryNavHost.Children.Clear();
|
||||
SettingsPluginNavHost.Children.Clear();
|
||||
SettingsPluginNavSection.IsVisible = false;
|
||||
|
||||
AddSettingsNavItem(SettingsPrimaryNavHost, "Wallpaper", Symbol.Wallpaper, "Wallpaper");
|
||||
AddSettingsNavItem(SettingsPrimaryNavHost, "Grid", Symbol.Grid, "Grid");
|
||||
AddSettingsNavItem(SettingsPrimaryNavHost, "Color", Symbol.Color, "Color");
|
||||
AddSettingsNavItem(SettingsPrimaryNavHost, "StatusBar", Symbol.Status, "Status Bar");
|
||||
AddSettingsNavItem(SettingsPrimaryNavHost, "Weather", Symbol.WeatherSunny, "Weather");
|
||||
|
||||
AddSettingsNavItem(SettingsSecondaryNavHost, "Region", Symbol.Globe, "Region");
|
||||
AddSettingsNavItem(SettingsSecondaryNavHost, "Launcher", Symbol.Apps, "App Launcher");
|
||||
AddSettingsNavItem(SettingsSecondaryNavHost, "Update", Symbol.ArrowSync, "Update");
|
||||
AddSettingsNavItem(SettingsSecondaryNavHost, "About", Symbol.Info, "About");
|
||||
AddSettingsNavItem(SettingsSecondaryNavHost, "Plugins", Symbol.PuzzlePiece, "Plugins");
|
||||
}
|
||||
|
||||
private void OnSettingsNavItemClick(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is not Button button || button.Tag is not string tag)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SelectSettingsTab(tag, persistSelection: true);
|
||||
}
|
||||
|
||||
private Button AddSettingsNavItem(Panel host, string tag, Symbol symbol, string title)
|
||||
{
|
||||
var button = CreateSettingsNavItem(tag, symbol, title);
|
||||
host.Children.Add(button);
|
||||
_settingsNavItems[tag] = button;
|
||||
return button;
|
||||
}
|
||||
|
||||
private Button CreateSettingsNavItem(string tag, Symbol symbol, string title)
|
||||
{
|
||||
var icon = new SymbolIcon
|
||||
{
|
||||
Symbol = symbol,
|
||||
IconVariant = IconVariant.Regular
|
||||
};
|
||||
icon.Classes.Add("settings-nav-icon");
|
||||
|
||||
var iconShell = new Border
|
||||
{
|
||||
Child = icon,
|
||||
Classes = { "settings-sidebar-icon-shell" }
|
||||
};
|
||||
|
||||
var label = new TextBlock
|
||||
{
|
||||
Text = title,
|
||||
Classes = { "settings-nav-label" }
|
||||
};
|
||||
|
||||
var contentGrid = new Grid
|
||||
{
|
||||
ColumnDefinitions = new ColumnDefinitions("Auto,*"),
|
||||
ColumnSpacing = 12
|
||||
};
|
||||
contentGrid.Children.Add(iconShell);
|
||||
contentGrid.Children.Add(label);
|
||||
Grid.SetColumn(label, 1);
|
||||
|
||||
var button = new Button
|
||||
{
|
||||
Tag = tag,
|
||||
Content = contentGrid,
|
||||
Classes = { "settings-sidebar-item" }
|
||||
};
|
||||
button.Click += OnSettingsNavItemClick;
|
||||
return button;
|
||||
}
|
||||
|
||||
private IEnumerable<Button> EnumerateSettingsNavItems()
|
||||
{
|
||||
foreach (var button in SettingsPrimaryNavHost.Children.OfType<Button>())
|
||||
{
|
||||
yield return button;
|
||||
}
|
||||
|
||||
foreach (var button in SettingsSecondaryNavHost.Children.OfType<Button>())
|
||||
{
|
||||
yield return button;
|
||||
}
|
||||
|
||||
foreach (var button in SettingsPluginNavHost.Children.OfType<Button>())
|
||||
{
|
||||
yield return button;
|
||||
}
|
||||
}
|
||||
|
||||
private Button? GetSettingsNavItem(string tag)
|
||||
{
|
||||
if (_settingsNavItems.TryGetValue(tag, out var builtIn))
|
||||
{
|
||||
return builtIn;
|
||||
}
|
||||
|
||||
return _pluginSettingsNavItems.GetValueOrDefault(tag);
|
||||
}
|
||||
|
||||
private static void SetSettingsNavItemLabel(Button? button, string text)
|
||||
{
|
||||
if (button?.Content is Grid grid)
|
||||
{
|
||||
var label = grid.Children
|
||||
.OfType<TextBlock>()
|
||||
.FirstOrDefault(textBlock => textBlock.Classes.Contains("settings-nav-label"));
|
||||
|
||||
if (label is not null)
|
||||
{
|
||||
label.Text = text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SelectSettingsTab(string? tag, bool persistSelection)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(tag))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var selectedButton = GetSettingsNavItem(tag);
|
||||
if (selectedButton is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_selectedSettingsTabTag = tag;
|
||||
foreach (var button in EnumerateSettingsNavItems())
|
||||
{
|
||||
var isSelected = ReferenceEquals(button, selectedButton);
|
||||
if (isSelected)
|
||||
{
|
||||
if (!button.Classes.Contains("nav-selected"))
|
||||
{
|
||||
button.Classes.Add("nav-selected");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
button.Classes.Remove("nav-selected");
|
||||
}
|
||||
}
|
||||
|
||||
UpdateSettingsTabContent();
|
||||
PersistSettings();
|
||||
|
||||
if (persistSelection)
|
||||
{
|
||||
PersistSettings();
|
||||
}
|
||||
}
|
||||
|
||||
private int GetSettingsTabIndex()
|
||||
@@ -61,13 +217,7 @@ public partial class SettingsWindow
|
||||
|
||||
private void UpdateSettingsTabContent()
|
||||
{
|
||||
if (SettingsNavView is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var selectedItem = SettingsNavView.SelectedItem as FluentAvalonia.UI.Controls.NavigationViewItem;
|
||||
var tag = selectedItem?.Tag?.ToString();
|
||||
var tag = GetSelectedSettingsTabTag();
|
||||
|
||||
WallpaperSettingsPanel.IsVisible = tag == "Wallpaper";
|
||||
GridSettingsPanel.IsVisible = tag == "Grid";
|
||||
@@ -279,6 +429,11 @@ public partial class SettingsWindow
|
||||
return;
|
||||
}
|
||||
|
||||
if (radioButton.IsChecked != true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_clockDisplayFormat = formatTag == "Hm"
|
||||
? ClockDisplayFormat.HourMinute
|
||||
: ClockDisplayFormat.HourMinuteSecond;
|
||||
@@ -375,8 +530,7 @@ public partial class SettingsWindow
|
||||
|
||||
private TaskbarContext GetCurrentTaskbarContext()
|
||||
{
|
||||
var selectedItem = SettingsNavView?.SelectedItem as FluentAvalonia.UI.Controls.NavigationViewItem;
|
||||
return selectedItem?.Tag?.ToString() switch
|
||||
return GetSelectedSettingsTabTag() switch
|
||||
{
|
||||
"Wallpaper" => TaskbarContext.SettingsWallpaper,
|
||||
"Grid" => TaskbarContext.SettingsGrid,
|
||||
|
||||
@@ -83,11 +83,6 @@ public partial class SettingsWindow
|
||||
|
||||
private void OnGridSpacingPresetSelectionChanged(object? sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (_suppressGridSpacingEvents)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateGridPreviewLayout();
|
||||
}
|
||||
|
||||
|
||||
@@ -48,20 +48,32 @@ public partial class SettingsWindow
|
||||
|
||||
private void ApplyLocalization()
|
||||
{
|
||||
Title = L("settings.title", "Settings");
|
||||
WindowTitleTextBlock.Text = L("settings.title", "Settings");
|
||||
WindowSubtitleTextBlock.Text = L("settings.footer", "LanMountainDesktop Settings");
|
||||
Title = L("settings.shell.title", "Application Settings");
|
||||
WindowTitleTextBlock.Text = L("settings.shell.title", "Application Settings");
|
||||
WindowSubtitleTextBlock.Text = L("settings.shell.subtitle", "LanMountainDesktop standalone preferences");
|
||||
WindowVersionBadgeTextBlock.Text = GetAppVersionText();
|
||||
WindowCodeNameBadgeTextBlock.Text = AppCodeName;
|
||||
SettingsSidebarTitleTextBlock.Text = L("settings.nav_header", "Settings");
|
||||
SettingsSidebarHintTextBlock.Text = L(
|
||||
"settings.shell.sidebar_hint",
|
||||
"Choose a category to adjust application behavior and desktop appearance.");
|
||||
SettingsPrimaryGroupTextBlock.Text = L("settings.nav.group_desktop", "Desktop");
|
||||
SettingsSecondaryGroupTextBlock.Text = L("settings.nav.group_system", "System");
|
||||
SettingsPluginGroupTextBlock.Text = L("settings.nav.group_extensions", "Extensions");
|
||||
SettingsSidebarFooterTextBlock.Text = L(
|
||||
"settings.shell.footer_hint",
|
||||
"Tray-opened settings are managed in this standalone window.");
|
||||
|
||||
SettingsNavWallpaperItem.Content = L("settings.nav.wallpaper", "Wallpaper");
|
||||
SettingsNavGridItem.Content = L("settings.nav.grid", "Grid");
|
||||
SettingsNavColorItem.Content = L("settings.nav.color", "Color");
|
||||
SettingsNavStatusBarItem.Content = L("settings.nav.status_bar", "Status Bar");
|
||||
SettingsNavWeatherItem.Content = L("settings.nav.weather", "Weather");
|
||||
SettingsNavRegionItem.Content = L("settings.nav.region", "Region");
|
||||
SettingsNavUpdateItem.Content = L("settings.nav.update", "Update");
|
||||
SettingsNavAboutItem.Content = L("settings.nav.about", "About");
|
||||
SettingsNavLauncherItem.Content = L("settings.nav.launcher", "App Launcher");
|
||||
SettingsNavPluginsItem.Content = L("settings.nav.plugins", "Plugins");
|
||||
SetSettingsNavItemLabel(GetSettingsNavItem("Wallpaper"), L("settings.nav.wallpaper", "Wallpaper"));
|
||||
SetSettingsNavItemLabel(GetSettingsNavItem("Grid"), L("settings.nav.grid", "Grid"));
|
||||
SetSettingsNavItemLabel(GetSettingsNavItem("Color"), L("settings.nav.color", "Color"));
|
||||
SetSettingsNavItemLabel(GetSettingsNavItem("StatusBar"), L("settings.nav.status_bar", "Status Bar"));
|
||||
SetSettingsNavItemLabel(GetSettingsNavItem("Weather"), L("settings.nav.weather", "Weather"));
|
||||
SetSettingsNavItemLabel(GetSettingsNavItem("Region"), L("settings.nav.region", "Region"));
|
||||
SetSettingsNavItemLabel(GetSettingsNavItem("Update"), L("settings.nav.update", "Update"));
|
||||
SetSettingsNavItemLabel(GetSettingsNavItem("About"), L("settings.nav.about", "About"));
|
||||
SetSettingsNavItemLabel(GetSettingsNavItem("Launcher"), L("settings.nav.launcher", "App Launcher"));
|
||||
SetSettingsNavItemLabel(GetSettingsNavItem("Plugins"), L("settings.nav.plugins", "Plugins"));
|
||||
|
||||
WallpaperPanelTitleTextBlock.Text = L("settings.wallpaper.title", "Personalize your wallpaper");
|
||||
WallpaperPlacementSettingsExpander.Header = L("settings.wallpaper.placement_label", "Placement");
|
||||
@@ -96,6 +108,60 @@ public partial class SettingsWindow
|
||||
StatusBarSpacingModeCustomItem.Content = L("settings.status_bar.spacing_mode_custom", "Custom");
|
||||
StatusBarSpacingCustomPanel.Content = L("settings.status_bar.spacing_custom_label", "Custom spacing (%)");
|
||||
|
||||
WeatherPanelTitleTextBlock.Text = L("settings.weather.title", "Weather");
|
||||
WeatherPreviewSectionTextBlock.Text = L("settings.weather.preview_section", "Weather Preview");
|
||||
WeatherSettingsSectionTextBlock.Text = L("settings.weather.settings_section", "Settings");
|
||||
WeatherPreviewButton.Content = L("settings.weather.refresh_button", "Refresh");
|
||||
WeatherPreviewResultTextBlock.Text = L("settings.weather.preview_hint", "Use refresh to verify your weather configuration.");
|
||||
WeatherLocationSettingsExpander.Header = L("settings.weather.location_source_header", "Location Source");
|
||||
WeatherLocationSettingsExpander.Description = L(
|
||||
"settings.weather.location_source_desc",
|
||||
"Choose how weather widgets resolve location.");
|
||||
WeatherLocationModeCityItem.Content = L("settings.weather.mode_city_search", "City Search");
|
||||
WeatherLocationModeCoordinatesItem.Content = L("settings.weather.mode_coordinates", "Coordinates");
|
||||
WeatherLocationModeCityChipItem.Content = L("settings.weather.mode_city_search", "City Search");
|
||||
WeatherLocationModeCoordinatesChipItem.Content = L("settings.weather.mode_coordinates", "Coordinates");
|
||||
WeatherAutoRefreshToggleSwitch.Content = L("settings.weather.auto_refresh", "Auto refresh location on startup");
|
||||
WeatherCitySearchSettingsExpander.Header = L("settings.weather.city_search_header", "City Search");
|
||||
WeatherCitySearchSettingsExpander.Description = L(
|
||||
"settings.weather.city_search_desc",
|
||||
"Search cities and apply one weather location.");
|
||||
WeatherCitySearchTextBox.Watermark = L("settings.weather.search_placeholder", "e.g. Beijing");
|
||||
WeatherSearchButton.Content = L("settings.weather.search_button", "Search");
|
||||
WeatherApplyCityButton.Content = L("settings.weather.apply_city_button", "Apply City");
|
||||
WeatherSearchStatusTextBlock.Text = L("settings.weather.search_hint", "Search by city name and apply one location.");
|
||||
WeatherCoordinateSettingsExpander.Header = L("settings.weather.coordinates_header", "Coordinates");
|
||||
WeatherCoordinateSettingsExpander.Description = L(
|
||||
"settings.weather.coordinates_desc",
|
||||
"Set latitude/longitude and optional key/name.");
|
||||
WeatherLatitudeNumberBox.Header = L("settings.weather.latitude_label", "Latitude");
|
||||
WeatherLongitudeNumberBox.Header = L("settings.weather.longitude_label", "Longitude");
|
||||
WeatherLocationKeyTextBox.Watermark = L("settings.weather.location_key_placeholder", "Location key (optional)");
|
||||
WeatherLocationNameTextBox.Watermark = L("settings.weather.location_name_placeholder", "Display name (optional)");
|
||||
WeatherApplyCoordinatesButton.Content = L("settings.weather.apply_coordinates_button", "Apply Coordinates");
|
||||
WeatherAlertFilterSettingsExpander.Header = L("settings.weather.alert_filter_header", "Excluded Alerts");
|
||||
WeatherAlertFilterSettingsExpander.Description = L(
|
||||
"settings.weather.alert_filter_desc",
|
||||
"Alerts containing these words will not be shown. One rule per line.");
|
||||
WeatherAlertListTitleTextBlock.Text = L("settings.weather.alert_list_label", "Exclude List");
|
||||
WeatherAlertListDescriptionTextBlock.Text = L("settings.weather.alert_list_desc", "One exclusion rule per line.");
|
||||
WeatherExcludedAlertsTextBox.Watermark = L("settings.weather.alert_filter_placeholder", "One keyword per line");
|
||||
WeatherNoTlsSettingsExpander.Header = L("settings.weather.no_tls_header", "No TLS Weather Request");
|
||||
WeatherNoTlsSettingsExpander.Description = L(
|
||||
"settings.weather.no_tls_desc",
|
||||
"Not recommended. Enable only for incompatible network environments.");
|
||||
WeatherNoTlsToggleSwitch.Content = L("settings.weather.no_tls_toggle", "Allow non-TLS request fallback");
|
||||
WeatherFooterHintTextBlock.Text = L(
|
||||
"settings.weather.footer_hint",
|
||||
"Desktop weather widgets will reuse the location and alert exclusion settings configured here.");
|
||||
WeatherIconPackSettingsExpander.Header = L("settings.weather.icon_style_header", "Weather Icon Style");
|
||||
WeatherIconPackSettingsExpander.Description = L(
|
||||
"settings.weather.icon_style_desc",
|
||||
"Choose Fluent Icon style for weather symbols.");
|
||||
WeatherIconPackFluentRegularItem.Content = L("settings.weather.icon_style_fluent_regular", "Fluent Regular");
|
||||
WeatherIconPackFluentFilledItem.Content = L("settings.weather.icon_style_fluent_filled", "Fluent Filled");
|
||||
UpdateWeatherLocationStatusText();
|
||||
|
||||
RegionPanelTitleTextBlock.Text = L("settings.region.title", "Region");
|
||||
LanguageSettingsExpander.Header = L("settings.region.language_header", "Language");
|
||||
LanguageSettingsExpander.Description = L("settings.region.language_desc", "Select application language. Changes apply immediately.");
|
||||
|
||||
@@ -14,6 +14,7 @@ using Avalonia.Threading;
|
||||
using FluentIcons.Common;
|
||||
using LanMountainDesktop.Models;
|
||||
using LanMountainDesktop.Services;
|
||||
using LanMountainDesktop.Views.Components;
|
||||
|
||||
namespace LanMountainDesktop.Views;
|
||||
|
||||
@@ -225,6 +226,7 @@ public partial class SettingsWindow
|
||||
{
|
||||
WeatherCitySearchSettingsExpander.IsVisible = _weatherLocationMode == WeatherLocationMode.CitySearch;
|
||||
WeatherCoordinateSettingsExpander.IsVisible = _weatherLocationMode == WeatherLocationMode.Coordinates;
|
||||
UpdateWeatherLocationSummaryCard();
|
||||
}
|
||||
|
||||
private void OnWeatherLocationModeSelectionChanged(object? sender, SelectionChangedEventArgs e)
|
||||
@@ -584,7 +586,7 @@ public partial class SettingsWindow
|
||||
: snapshot.LocationName;
|
||||
var weather = snapshot.Current.WeatherText ?? L("settings.weather.preview_unknown", "Unknown");
|
||||
var temperature = snapshot.Current.TemperatureC.HasValue
|
||||
? string.Create(CultureInfo.InvariantCulture, $"{snapshot.Current.TemperatureC.Value:F1} C")
|
||||
? FormatWeatherPreviewTemperature(snapshot.Current.TemperatureC.Value)
|
||||
: "--";
|
||||
var updatedAt = snapshot.ObservationTime ?? snapshot.FetchedAt;
|
||||
|
||||
@@ -605,16 +607,25 @@ public partial class SettingsWindow
|
||||
|
||||
private void UpdateWeatherPreviewSummary(int? weatherCode, string temperatureText, DateTimeOffset? updatedAt)
|
||||
{
|
||||
var kind = HyperOS3WeatherTheme.ResolveVisualKind(weatherCode, _isNightMode);
|
||||
WeatherPreviewIconImage.Source = HyperOS3WeatherAssetLoader.LoadImage(
|
||||
HyperOS3WeatherTheme.ResolveIconAsset(kind)) ??
|
||||
HyperOS3WeatherAssetLoader.LoadImage(HyperOS3WeatherTheme.ResolveHeroIconAsset(kind));
|
||||
WeatherPreviewIconSymbol.Symbol = ResolveWeatherPreviewSymbol(weatherCode, _isNightMode);
|
||||
WeatherPreviewIconSymbol.IconVariant = string.Equals(_weatherIconPackId, "FluentFilled", StringComparison.OrdinalIgnoreCase)
|
||||
? IconVariant.Filled
|
||||
: IconVariant.Regular;
|
||||
WeatherPreviewTemperatureTextBlock.Text = string.IsNullOrWhiteSpace(temperatureText) ? "--" : temperatureText;
|
||||
WeatherPreviewUpdatedTextBlock.Text = updatedAt.HasValue
|
||||
? Lf("weather.widget.updated_format", "Updated {0:HH:mm}", updatedAt.Value.LocalDateTime)
|
||||
? updatedAt.Value.LocalDateTime.ToString("yyyy/M/d HH:mm:ss", CultureInfo.InvariantCulture)
|
||||
: "-";
|
||||
}
|
||||
|
||||
private static string FormatWeatherPreviewTemperature(double temperatureC)
|
||||
{
|
||||
return string.Create(CultureInfo.InvariantCulture, $"{temperatureC:0.#}°C");
|
||||
}
|
||||
|
||||
private static Symbol ResolveWeatherPreviewSymbol(int? weatherCode, bool isNight)
|
||||
{
|
||||
return weatherCode switch
|
||||
@@ -658,11 +669,13 @@ public partial class SettingsWindow
|
||||
if (string.IsNullOrWhiteSpace(_weatherLocationKey))
|
||||
{
|
||||
WeatherLocationStatusTextBlock.Text = L("settings.weather.status_city_empty", "No city location is configured.");
|
||||
UpdateWeatherLocationSummaryCard();
|
||||
return;
|
||||
}
|
||||
|
||||
var locationName = string.IsNullOrWhiteSpace(_weatherLocationName) ? _weatherLocationKey : _weatherLocationName;
|
||||
WeatherLocationStatusTextBlock.Text = Lf("settings.weather.status_city_format", "Mode: {0} | {1} | Key: {2}", modeText, locationName, _weatherLocationKey);
|
||||
UpdateWeatherLocationSummaryCard();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -673,6 +686,34 @@ public partial class SettingsWindow
|
||||
_weatherLatitude,
|
||||
_weatherLongitude,
|
||||
string.IsNullOrWhiteSpace(_weatherLocationKey) ? BuildCoordinateLocationKey(_weatherLatitude, _weatherLongitude) : _weatherLocationKey);
|
||||
UpdateWeatherLocationSummaryCard();
|
||||
}
|
||||
|
||||
private void UpdateWeatherLocationSummaryCard()
|
||||
{
|
||||
if (_weatherLocationMode == WeatherLocationMode.Coordinates)
|
||||
{
|
||||
WeatherLocationSelectionTitleTextBlock.Text = L("settings.weather.coordinates_selection_label", "Coordinate Location");
|
||||
WeatherLocationSelectionDescriptionTextBlock.Text = L(
|
||||
"settings.weather.location_coordinates_summary_desc",
|
||||
"Set latitude/longitude and optional location name used for weather queries.");
|
||||
|
||||
var locationName = string.IsNullOrWhiteSpace(_weatherLocationName)
|
||||
? string.Create(CultureInfo.InvariantCulture, $"{_weatherLatitude:F4}, {_weatherLongitude:F4}")
|
||||
: _weatherLocationName;
|
||||
WeatherLocationValueTextBlock.Text = locationName;
|
||||
return;
|
||||
}
|
||||
|
||||
WeatherLocationSelectionTitleTextBlock.Text = L("settings.weather.city_selection_label", "City Selection");
|
||||
WeatherLocationSelectionDescriptionTextBlock.Text = L(
|
||||
"settings.weather.location_city_summary_desc",
|
||||
"Select the current city used for weather queries.");
|
||||
WeatherLocationValueTextBlock.Text = !string.IsNullOrWhiteSpace(_weatherLocationName)
|
||||
? _weatherLocationName
|
||||
: !string.IsNullOrWhiteSpace(_weatherLocationKey)
|
||||
? _weatherLocationKey
|
||||
: L("settings.weather.location_not_selected", "No location selected");
|
||||
}
|
||||
|
||||
private void InitializeLauncherVisibilitySettings(LauncherSettingsSnapshot snapshot)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:ui="using:FluentAvalonia.UI.Controls"
|
||||
xmlns:fi="using:FluentIcons.Avalonia"
|
||||
xmlns:ic="using:FluentIcons.Avalonia.Fluent"
|
||||
xmlns:pages="using:LanMountainDesktop.Views.SettingsPages"
|
||||
@@ -8,16 +7,94 @@
|
||||
x:Class="LanMountainDesktop.Views.SettingsWindow"
|
||||
Title="Settings"
|
||||
Icon="/Assets/avalonia-logo.ico"
|
||||
Width="1360"
|
||||
Height="900"
|
||||
MinWidth="1120"
|
||||
MinHeight="760"
|
||||
Width="1520"
|
||||
Height="960"
|
||||
MinWidth="1240"
|
||||
MinHeight="820"
|
||||
ShowInTaskbar="True"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
ExtendClientAreaToDecorationsHint="True"
|
||||
ExtendClientAreaChromeHints="SystemChrome"
|
||||
Background="{DynamicResource AdaptiveSurfaceBaseBrush}">
|
||||
|
||||
<Window.Styles>
|
||||
<Style Selector="Border.settings-shell-card">
|
||||
<Setter Property="Background" Value="{DynamicResource AdaptiveGlassPanelBackgroundBrush}" />
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource AdaptiveGlassPanelBorderBrush}" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="28" />
|
||||
<Setter Property="BoxShadow" Value="0 10 28 #12000000" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="TextBlock.settings-shell-eyebrow">
|
||||
<Setter Property="FontSize" Value="12" />
|
||||
<Setter Property="FontWeight" Value="SemiBold" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource AdaptiveTextSecondaryBrush}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="TextBlock.settings-shell-hint">
|
||||
<Setter Property="FontSize" Value="13" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource AdaptiveTextSecondaryBrush}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="StackPanel.settings-sidebar-host Button.settings-sidebar-item">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="BorderBrush" Value="Transparent" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="18" />
|
||||
<Setter Property="Padding" Value="14,12" />
|
||||
<Setter Property="Margin" Value="0,0,0,8" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="Transitions">
|
||||
<Transitions>
|
||||
<BrushTransition Property="Background" Duration="{StaticResource FluttermotionToken.Duration.Fast}" Easing="0.22,1,0.36,1" />
|
||||
<BrushTransition Property="BorderBrush" Duration="{StaticResource FluttermotionToken.Duration.Fast}" Easing="0.22,1,0.36,1" />
|
||||
<TransformOperationsTransition Property="RenderTransform" Duration="{StaticResource FluttermotionToken.Duration.Fast}" Easing="0.22,1,0.36,1" />
|
||||
</Transitions>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style Selector="StackPanel.settings-sidebar-host Button.settings-sidebar-item:pointerover">
|
||||
<Setter Property="Background" Value="{DynamicResource AdaptiveButtonHoverBackgroundBrush}" />
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource AdaptiveButtonBorderBrush}" />
|
||||
<Setter Property="RenderTransform" Value="scale(1.01)" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="StackPanel.settings-sidebar-host Button.settings-sidebar-item.nav-selected">
|
||||
<Setter Property="Background" Value="{DynamicResource AdaptiveNavItemSelectedBackgroundBrush}" />
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource AdaptiveAccentBrush}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="Border.settings-sidebar-icon-shell">
|
||||
<Setter Property="Width" Value="34" />
|
||||
<Setter Property="Height" Value="34" />
|
||||
<Setter Property="CornerRadius" Value="12" />
|
||||
<Setter Property="Background" Value="{DynamicResource AdaptiveButtonBackgroundBrush}" />
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource AdaptiveButtonBorderBrush}" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="Button.settings-sidebar-item.nav-selected Border.settings-sidebar-icon-shell">
|
||||
<Setter Property="Background" Value="{DynamicResource AdaptiveAccentBrush}" />
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource AdaptiveAccentBrush}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="TextBlock.settings-nav-label">
|
||||
<Setter Property="FontSize" Value="16" />
|
||||
<Setter Property="FontWeight" Value="SemiBold" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="ic|SymbolIcon.settings-nav-icon">
|
||||
<Setter Property="Foreground" Value="{DynamicResource AdaptiveTextPrimaryBrush}" />
|
||||
<Setter Property="FontSize" Value="18" />
|
||||
<Setter Property="HorizontalAlignment" Value="Center" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="Button.settings-sidebar-item.nav-selected ic|SymbolIcon.settings-nav-icon">
|
||||
<Setter Property="Foreground" Value="White" />
|
||||
</Style>
|
||||
</Window.Styles>
|
||||
|
||||
<Grid x:Name="DesktopHost">
|
||||
<Border x:Name="DesktopWallpaperLayer"
|
||||
Background="{DynamicResource AdaptiveSurfaceBaseBrush}" />
|
||||
@@ -27,121 +104,142 @@
|
||||
IsVisible="True"
|
||||
Opacity="1"
|
||||
Margin="20">
|
||||
<Border x:Name="SettingsContentPanel"
|
||||
Background="Transparent"
|
||||
BorderThickness="0"
|
||||
Margin="0"
|
||||
Padding="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch">
|
||||
<Grid RowDefinitions="Auto,*">
|
||||
<Border Grid.Row="0"
|
||||
Classes="mica-strong"
|
||||
CornerRadius="24,24,0,0"
|
||||
Padding="20,16">
|
||||
<Grid ColumnDefinitions="Auto,*,Auto">
|
||||
<Border Width="40"
|
||||
Height="40"
|
||||
CornerRadius="20"
|
||||
Background="{DynamicResource AdaptiveAccentBrush}">
|
||||
<fi:FluentIcon Icon="Settings"
|
||||
IconVariant="Regular"
|
||||
Foreground="White"
|
||||
FontSize="18"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
</Border>
|
||||
<StackPanel Grid.Column="1"
|
||||
Margin="14,0,0,0"
|
||||
Spacing="2"
|
||||
VerticalAlignment="Center">
|
||||
<TextBlock x:Name="WindowTitleTextBlock"
|
||||
FontSize="24"
|
||||
<Grid x:Name="SettingsContentPanel"
|
||||
RowDefinitions="Auto,*"
|
||||
RowSpacing="18">
|
||||
<Border Grid.Row="0"
|
||||
Classes="settings-shell-card"
|
||||
Padding="20,18">
|
||||
<Grid ColumnDefinitions="Auto,*,Auto"
|
||||
ColumnSpacing="18">
|
||||
<Border Width="52"
|
||||
Height="52"
|
||||
CornerRadius="18"
|
||||
Background="{DynamicResource AdaptiveAccentBrush}">
|
||||
<TextBlock Text="LMD"
|
||||
FontSize="16"
|
||||
FontWeight="Bold"
|
||||
Foreground="White"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
</Border>
|
||||
|
||||
<StackPanel Grid.Column="1"
|
||||
Spacing="3"
|
||||
VerticalAlignment="Center">
|
||||
<TextBlock x:Name="WindowTitleTextBlock"
|
||||
FontSize="28"
|
||||
FontWeight="SemiBold"
|
||||
Text="Application Settings" />
|
||||
<TextBlock x:Name="WindowSubtitleTextBlock"
|
||||
Classes="settings-shell-hint"
|
||||
Text="LanMountainDesktop" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Column="2"
|
||||
Orientation="Horizontal"
|
||||
Spacing="10"
|
||||
VerticalAlignment="Center">
|
||||
<Border Classes="settings-shell-card"
|
||||
Padding="12,8"
|
||||
CornerRadius="18">
|
||||
<TextBlock x:Name="WindowVersionBadgeTextBlock"
|
||||
FontSize="14"
|
||||
FontWeight="SemiBold"
|
||||
Text="1.0.0" />
|
||||
</Border>
|
||||
<Border Classes="settings-shell-card"
|
||||
Padding="12,8"
|
||||
CornerRadius="18">
|
||||
<TextBlock x:Name="WindowCodeNameBadgeTextBlock"
|
||||
Classes="settings-shell-hint"
|
||||
Text="Administrate" />
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<Grid Grid.Row="1"
|
||||
ColumnDefinitions="300,20,*">
|
||||
<Border Grid.Column="0"
|
||||
Classes="settings-shell-card"
|
||||
Padding="18,18,18,16">
|
||||
<Grid RowDefinitions="Auto,*,Auto"
|
||||
RowSpacing="18">
|
||||
<StackPanel Spacing="6">
|
||||
<TextBlock x:Name="SettingsSidebarTitleTextBlock"
|
||||
Classes="settings-shell-eyebrow"
|
||||
Text="Settings" />
|
||||
<TextBlock x:Name="WindowSubtitleTextBlock"
|
||||
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
|
||||
Text="LanMountainDesktop preferences" />
|
||||
<TextBlock x:Name="SettingsSidebarHintTextBlock"
|
||||
Classes="settings-shell-hint"
|
||||
TextWrapping="Wrap"
|
||||
Text="Choose a category to adjust application behavior and desktop appearance." />
|
||||
</StackPanel>
|
||||
<Button Grid.Column="2"
|
||||
Padding="10,8"
|
||||
HorizontalAlignment="Right"
|
||||
Click="OnCloseWindowClick">
|
||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
||||
<fi:FluentIcon Icon="Dismiss" IconVariant="Regular" />
|
||||
<TextBlock Text="Close" VerticalAlignment="Center" />
|
||||
|
||||
<ScrollViewer Grid.Row="1"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel Spacing="20">
|
||||
<StackPanel Spacing="10">
|
||||
<TextBlock x:Name="SettingsPrimaryGroupTextBlock"
|
||||
Classes="settings-shell-eyebrow"
|
||||
Text="Desktop" />
|
||||
<StackPanel x:Name="SettingsPrimaryNavHost"
|
||||
Classes="settings-sidebar-host"
|
||||
Spacing="0" />
|
||||
</StackPanel>
|
||||
|
||||
<Border Background="{DynamicResource SurfaceStrokeColorDefaultBrush}"
|
||||
Height="1" />
|
||||
|
||||
<StackPanel Spacing="10">
|
||||
<TextBlock x:Name="SettingsSecondaryGroupTextBlock"
|
||||
Classes="settings-shell-eyebrow"
|
||||
Text="System" />
|
||||
<StackPanel x:Name="SettingsSecondaryNavHost"
|
||||
Classes="settings-sidebar-host"
|
||||
Spacing="0" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel x:Name="SettingsPluginNavSection"
|
||||
IsVisible="False"
|
||||
Spacing="10">
|
||||
<Border Background="{DynamicResource SurfaceStrokeColorDefaultBrush}"
|
||||
Height="1" />
|
||||
<TextBlock x:Name="SettingsPluginGroupTextBlock"
|
||||
Classes="settings-shell-eyebrow"
|
||||
Text="Extensions" />
|
||||
<StackPanel x:Name="SettingsPluginNavHost"
|
||||
Classes="settings-sidebar-host"
|
||||
Spacing="0" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</ScrollViewer>
|
||||
|
||||
<Border Grid.Row="2"
|
||||
Classes="settings-shell-card"
|
||||
Padding="14,12"
|
||||
CornerRadius="22">
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Text="LanMountainDesktop"
|
||||
FontWeight="SemiBold" />
|
||||
<TextBlock x:Name="SettingsSidebarFooterTextBlock"
|
||||
Classes="settings-shell-hint"
|
||||
TextWrapping="Wrap"
|
||||
Text="Tray-opened settings are managed in this standalone window." />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<Border Grid.Row="1"
|
||||
Classes="mica-strong"
|
||||
CornerRadius="0,0,24,24"
|
||||
Padding="18">
|
||||
<Grid RowDefinitions="*,Auto"
|
||||
RowSpacing="14">
|
||||
<ui:NavigationView x:Name="SettingsNavView"
|
||||
Grid.Row="0"
|
||||
PaneDisplayMode="Left"
|
||||
IsSettingsVisible="False"
|
||||
OpenPaneLength="240"
|
||||
SelectionChanged="OnSettingsNavSelectionChanged">
|
||||
<ui:NavigationView.MenuItems>
|
||||
<ui:NavigationViewItem x:Name="SettingsNavWallpaperItem" Content="壁纸" Tag="Wallpaper">
|
||||
<ui:NavigationViewItem.IconSource>
|
||||
<ic:SymbolIconSource Symbol="Wallpaper" IconVariant="Regular" />
|
||||
</ui:NavigationViewItem.IconSource>
|
||||
</ui:NavigationViewItem>
|
||||
<ui:NavigationViewItem x:Name="SettingsNavGridItem" Content="网格" Tag="Grid">
|
||||
<ui:NavigationViewItem.IconSource>
|
||||
<ic:SymbolIconSource Symbol="Grid" IconVariant="Regular" />
|
||||
</ui:NavigationViewItem.IconSource>
|
||||
</ui:NavigationViewItem>
|
||||
<ui:NavigationViewItem x:Name="SettingsNavColorItem" Content="颜色" Tag="Color">
|
||||
<ui:NavigationViewItem.IconSource>
|
||||
<ic:SymbolIconSource Symbol="Color" IconVariant="Regular" />
|
||||
</ui:NavigationViewItem.IconSource>
|
||||
</ui:NavigationViewItem>
|
||||
<ui:NavigationViewItem x:Name="SettingsNavStatusBarItem" Content="状态栏" Tag="StatusBar">
|
||||
<ui:NavigationViewItem.IconSource>
|
||||
<ic:SymbolIconSource Symbol="Status" IconVariant="Regular" />
|
||||
</ui:NavigationViewItem.IconSource>
|
||||
</ui:NavigationViewItem>
|
||||
<ui:NavigationViewItem x:Name="SettingsNavWeatherItem" Content="天气" Tag="Weather">
|
||||
<ui:NavigationViewItem.IconSource>
|
||||
<ic:SymbolIconSource Symbol="WeatherSunny" IconVariant="Regular" />
|
||||
</ui:NavigationViewItem.IconSource>
|
||||
</ui:NavigationViewItem>
|
||||
<ui:NavigationViewItem x:Name="SettingsNavRegionItem" Content="地区" Tag="Region">
|
||||
<ui:NavigationViewItem.IconSource>
|
||||
<ic:SymbolIconSource Symbol="Globe" IconVariant="Regular" />
|
||||
</ui:NavigationViewItem.IconSource>
|
||||
</ui:NavigationViewItem>
|
||||
<ui:NavigationViewItem x:Name="SettingsNavUpdateItem" Content="更新" Tag="Update">
|
||||
<ui:NavigationViewItem.IconSource>
|
||||
<ic:SymbolIconSource Symbol="ArrowSync" IconVariant="Regular" />
|
||||
</ui:NavigationViewItem.IconSource>
|
||||
</ui:NavigationViewItem>
|
||||
<ui:NavigationViewItem x:Name="SettingsNavAboutItem" Content="关于" Tag="About">
|
||||
<ui:NavigationViewItem.IconSource>
|
||||
<ic:SymbolIconSource Symbol="Info" IconVariant="Regular" />
|
||||
</ui:NavigationViewItem.IconSource>
|
||||
</ui:NavigationViewItem>
|
||||
<ui:NavigationViewItem x:Name="SettingsNavLauncherItem" Content="应用启动台" Tag="Launcher">
|
||||
<ui:NavigationViewItem.IconSource>
|
||||
<ic:SymbolIconSource Symbol="Apps" IconVariant="Regular" />
|
||||
</ui:NavigationViewItem.IconSource>
|
||||
</ui:NavigationViewItem>
|
||||
<ui:NavigationViewItem x:Name="SettingsNavPluginsItem" Content="插件" Tag="Plugins">
|
||||
<ui:NavigationViewItem.IconSource>
|
||||
<ic:SymbolIconSource Symbol="PuzzlePiece" IconVariant="Regular" />
|
||||
</ui:NavigationViewItem.IconSource>
|
||||
</ui:NavigationViewItem>
|
||||
</ui:NavigationView.MenuItems>
|
||||
|
||||
<Grid Grid.Column="2"
|
||||
RowDefinitions="*,Auto"
|
||||
RowSpacing="14">
|
||||
<Border Grid.Row="0"
|
||||
Classes="settings-shell-card"
|
||||
Padding="0">
|
||||
<ScrollViewer x:Name="SettingsContentScrollViewer"
|
||||
Padding="0,0,16,0"
|
||||
Padding="30,28,30,30"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<Grid x:Name="SettingsContentPagesHost">
|
||||
@@ -157,23 +255,23 @@
|
||||
<pages:PluginSettingsPage x:Name="PluginSettingsPanel" IsVisible="False" />
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</ui:NavigationView>
|
||||
</Border>
|
||||
|
||||
<Border x:Name="PendingRestartDock"
|
||||
Grid.Row="1"
|
||||
IsVisible="False"
|
||||
Classes="glass-panel"
|
||||
CornerRadius="18"
|
||||
Padding="14,12">
|
||||
Classes="settings-shell-card"
|
||||
Padding="16,14"
|
||||
CornerRadius="24">
|
||||
<Grid ColumnDefinitions="Auto,*,Auto"
|
||||
ColumnSpacing="12">
|
||||
<Border Width="34"
|
||||
Height="34"
|
||||
CornerRadius="17"
|
||||
ColumnSpacing="14">
|
||||
<Border Width="38"
|
||||
Height="38"
|
||||
CornerRadius="14"
|
||||
Background="{DynamicResource AdaptiveAccentBrush}">
|
||||
<fi:FluentIcon Icon="ArrowSync"
|
||||
IconVariant="Regular"
|
||||
FontSize="16"
|
||||
FontSize="18"
|
||||
Foreground="White"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
@@ -182,7 +280,7 @@
|
||||
Spacing="2"
|
||||
VerticalAlignment="Center">
|
||||
<TextBlock x:Name="PendingRestartDockTitleTextBlock"
|
||||
FontSize="13"
|
||||
FontSize="14"
|
||||
FontWeight="SemiBold"
|
||||
Text="Restart required" />
|
||||
<TextBlock x:Name="PendingRestartDockDescriptionTextBlock"
|
||||
@@ -192,7 +290,7 @@
|
||||
</StackPanel>
|
||||
<Button x:Name="PendingRestartDockButton"
|
||||
Grid.Column="2"
|
||||
Padding="14,8"
|
||||
Padding="16,8"
|
||||
Click="OnPendingRestartDockButtonClick">
|
||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
||||
<fi:FluentIcon Icon="ArrowSync"
|
||||
@@ -204,10 +302,9 @@
|
||||
</Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Grid IsVisible="False">
|
||||
|
||||
@@ -102,13 +102,14 @@ public partial class SettingsWindow : Window
|
||||
private readonly HashSet<string> _hiddenLauncherFolderPaths = new(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly HashSet<string> _hiddenLauncherAppPaths = new(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly Stack<StartMenuFolderNode> _launcherFolderStack = [];
|
||||
private readonly Dictionary<string, Button> _settingsNavItems = new(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly Dictionary<string, Button> _pluginSettingsNavItems = new(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
private StartMenuFolderNode _startMenuRoot = new("All Apps", string.Empty);
|
||||
private byte[]? _launcherFolderIconPngBytes;
|
||||
private Bitmap? _launcherFolderIconBitmap;
|
||||
|
||||
private int _targetShortSideCells;
|
||||
private bool _isSettingsOpen = true;
|
||||
private bool _isNightMode;
|
||||
private bool _enableDynamicTaskbarActions;
|
||||
private bool _suppressThemeToggleEvents;
|
||||
@@ -116,7 +117,6 @@ public partial class SettingsWindow : Window
|
||||
private bool _suppressTimeZoneSelectionEvents;
|
||||
private bool _suppressWeatherLocationEvents;
|
||||
private bool _suppressSettingsPersistence;
|
||||
private bool _suppressGridSpacingEvents;
|
||||
private bool _suppressGridInsetEvents;
|
||||
private bool _suppressStatusBarSpacingEvents;
|
||||
private bool _suppressAutoStartToggleEvents;
|
||||
@@ -135,8 +135,6 @@ public partial class SettingsWindow : Window
|
||||
private IReadOnlyList<Color> _monetColors = Array.Empty<Color>();
|
||||
private Color _selectedThemeColor = Color.Parse("#FF3B82F6");
|
||||
private double _currentDesktopCellSize;
|
||||
private double _currentDesktopCellGap;
|
||||
private double _currentDesktopEdgeInset;
|
||||
private string _gridSpacingPreset = "Relaxed";
|
||||
private string _statusBarSpacingMode = "Relaxed";
|
||||
private int _statusBarCustomSpacingPercent = 12;
|
||||
@@ -156,6 +154,7 @@ public partial class SettingsWindow : Window
|
||||
private bool _weatherNoTlsRequests;
|
||||
private bool _autoStartWithWindows;
|
||||
private string _weatherSearchKeyword = string.Empty;
|
||||
private string _selectedSettingsTabTag = "Wallpaper";
|
||||
private bool _isWeatherSearchInProgress;
|
||||
private bool _isWeatherPreviewInProgress;
|
||||
|
||||
@@ -163,6 +162,7 @@ public partial class SettingsWindow : Window
|
||||
{
|
||||
_componentRegistry = DesktopComponentRegistryFactory.Create((Application.Current as App)?.PluginRuntimeService);
|
||||
InitializeComponent();
|
||||
InitializeSettingsNavigation();
|
||||
InitializePluginSettingsNavigation();
|
||||
_fluentAvaloniaTheme = Application.Current?.Styles.OfType<FluentAvaloniaTheme>().FirstOrDefault();
|
||||
RequestedThemeVariant = Application.Current?.RequestedThemeVariant ?? ThemeVariant.Default;
|
||||
@@ -184,8 +184,7 @@ public partial class SettingsWindow : Window
|
||||
GridSpacingPresetComboBox.SelectionChanged += OnGridSpacingPresetSelectionChanged;
|
||||
GridEdgeInsetSlider.ValueChanged += OnGridEdgeInsetSliderChanged;
|
||||
ApplyGridButton.Click += OnApplyGridSizeClick;
|
||||
NightModeToggleSwitch.Checked += OnNightModeChecked;
|
||||
NightModeToggleSwitch.Unchecked += OnNightModeUnchecked;
|
||||
NightModeToggleSwitch.IsCheckedChanged += OnNightModeIsCheckedChanged;
|
||||
RecommendedColorButton1.Click += OnRecommendedColorClick;
|
||||
RecommendedColorButton2.Click += OnRecommendedColorClick;
|
||||
RecommendedColorButton3.Click += OnRecommendedColorClick;
|
||||
@@ -199,37 +198,64 @@ public partial class SettingsWindow : Window
|
||||
MonetColorButton4.Click += OnMonetColorClick;
|
||||
MonetColorButton5.Click += OnMonetColorClick;
|
||||
MonetColorButton6.Click += OnMonetColorClick;
|
||||
StatusBarClockToggleSwitch.Checked += OnStatusBarClockChecked;
|
||||
StatusBarClockToggleSwitch.Unchecked += OnStatusBarClockUnchecked;
|
||||
ClockFormatHMSSRadio.Checked += OnClockFormatChanged;
|
||||
ClockFormatHMRadio.Checked += OnClockFormatChanged;
|
||||
StatusBarClockToggleSwitch.IsCheckedChanged += OnStatusBarClockIsCheckedChanged;
|
||||
ClockFormatHMSSRadio.IsCheckedChanged += OnClockFormatChanged;
|
||||
ClockFormatHMRadio.IsCheckedChanged += OnClockFormatChanged;
|
||||
StatusBarSpacingModeComboBox.SelectionChanged += OnStatusBarSpacingModeChanged;
|
||||
StatusBarSpacingSlider.ValueChanged += OnStatusBarSpacingSliderChanged;
|
||||
WeatherPreviewButton.Click += OnTestWeatherRequestClick;
|
||||
WeatherLocationModeComboBox.SelectionChanged += OnWeatherLocationModeSelectionChanged;
|
||||
WeatherLocationModeChipListBox.SelectionChanged += OnWeatherLocationModeChipSelectionChanged;
|
||||
WeatherAutoRefreshToggleSwitch.Checked += OnWeatherAutoRefreshToggled;
|
||||
WeatherAutoRefreshToggleSwitch.Unchecked += OnWeatherAutoRefreshToggled;
|
||||
WeatherAutoRefreshToggleSwitch.IsCheckedChanged += OnWeatherAutoRefreshToggled;
|
||||
WeatherSearchButton.Click += OnSearchWeatherCityClick;
|
||||
WeatherApplyCityButton.Click += OnApplyWeatherCitySelectionClick;
|
||||
WeatherApplyCoordinatesButton.Click += OnApplyWeatherCoordinatesClick;
|
||||
WeatherExcludedAlertsTextBox.LostFocus += OnWeatherExcludedAlertsLostFocus;
|
||||
WeatherIconPackComboBox.SelectionChanged += OnWeatherIconPackSelectionChanged;
|
||||
WeatherNoTlsToggleSwitch.Checked += OnWeatherNoTlsToggled;
|
||||
WeatherNoTlsToggleSwitch.Unchecked += OnWeatherNoTlsToggled;
|
||||
WeatherNoTlsToggleSwitch.IsCheckedChanged += OnWeatherNoTlsToggled;
|
||||
LanguageComboBox.SelectionChanged += OnLanguageSelectionChanged;
|
||||
TimeZoneComboBox.SelectionChanged += OnTimeZoneSelectionChanged;
|
||||
AutoCheckUpdatesToggleSwitch.Checked += OnAutoCheckUpdatesToggled;
|
||||
AutoCheckUpdatesToggleSwitch.Unchecked += OnAutoCheckUpdatesToggled;
|
||||
AutoCheckUpdatesToggleSwitch.IsCheckedChanged += OnAutoCheckUpdatesToggled;
|
||||
UpdateChannelChipListBox.SelectionChanged += OnUpdateChannelSelectionChanged;
|
||||
CheckForUpdatesButton.Click += OnCheckForUpdatesClick;
|
||||
DownloadAndInstallUpdateButton.Click += OnDownloadAndInstallUpdateClick;
|
||||
AutoStartWithWindowsToggleSwitch.Checked += OnAutoStartWithWindowsToggled;
|
||||
AutoStartWithWindowsToggleSwitch.Unchecked += OnAutoStartWithWindowsToggled;
|
||||
AutoStartWithWindowsToggleSwitch.IsCheckedChanged += OnAutoStartWithWindowsToggled;
|
||||
AppRenderModeComboBox.SelectionChanged += OnAppRenderModeSelectionChanged;
|
||||
Opened += OnWindowOpened;
|
||||
}
|
||||
|
||||
private void OnNightModeIsCheckedChanged(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is not ToggleButton toggleButton)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (toggleButton.IsChecked == true)
|
||||
{
|
||||
OnNightModeChecked(sender, e);
|
||||
return;
|
||||
}
|
||||
|
||||
OnNightModeUnchecked(sender, e);
|
||||
}
|
||||
|
||||
private void OnStatusBarClockIsCheckedChanged(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is not ToggleButton toggleButton)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (toggleButton.IsChecked == true)
|
||||
{
|
||||
OnStatusBarClockChecked(sender, e);
|
||||
return;
|
||||
}
|
||||
|
||||
OnStatusBarClockUnchecked(sender, e);
|
||||
}
|
||||
|
||||
private void OnWindowOpened(object? sender, EventArgs e)
|
||||
{
|
||||
Opened -= OnWindowOpened;
|
||||
@@ -283,8 +309,6 @@ public partial class SettingsWindow : Window
|
||||
EnsureSelectedThemeColor();
|
||||
UpdateThemeColorSelectionState();
|
||||
ThemeColorStatusTextBlock.Text = Lf("settings.color.theme_ready_format", "Theme color ready: {0}.", _selectedThemeColor);
|
||||
WindowTitleTextBlock.Text = L("settings.title", "Settings");
|
||||
WindowSubtitleTextBlock.Text = L("settings.footer", "LanMountainDesktop Settings");
|
||||
_defaultDesktopBackground = DesktopWallpaperLayer.Background;
|
||||
RestoreSettingsTabSelection(snapshot);
|
||||
UpdateSettingsTabContent();
|
||||
|
||||
Reference in New Issue
Block a user