mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-20 23:54:26 +08:00
153 lines
5.4 KiB
C#
153 lines
5.4 KiB
C#
using System;
|
|
using System.Linq;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Interactivity;
|
|
using LanMountainDesktop.ComponentSystem;
|
|
using LanMountainDesktop.Models;
|
|
using LanMountainDesktop.Services;
|
|
|
|
namespace LanMountainDesktop.Views.ComponentEditors;
|
|
|
|
public partial class WorldClockComponentEditor : ComponentEditorViewBase
|
|
{
|
|
private readonly TimeZoneService _timeZoneService = new();
|
|
private readonly ComboBox[] _timeZoneCombos;
|
|
private bool _suppressEvents;
|
|
|
|
public WorldClockComponentEditor()
|
|
: this(null)
|
|
{
|
|
}
|
|
|
|
public WorldClockComponentEditor(DesktopComponentEditorContext? context)
|
|
: base(context)
|
|
{
|
|
if (context is not null)
|
|
{
|
|
_timeZoneService.CurrentTimeZone = context.SettingsFacade.Region.GetTimeZoneService().CurrentTimeZone;
|
|
}
|
|
|
|
InitializeComponent();
|
|
_timeZoneCombos = [ClockOneComboBox, ClockTwoComboBox, ClockThreeComboBox, ClockFourComboBox];
|
|
ApplyState();
|
|
}
|
|
|
|
private void ApplyState()
|
|
{
|
|
HeadlineTextBlock.Text = Context?.Definition.DisplayName ?? "World Clock";
|
|
DescriptionTextBlock.Text = L("worldclock.settings.desc", "分别为四个时钟选择时区。");
|
|
ClockOneLabelTextBlock.Text = L("worldclock.settings.clock_1", "时钟 1");
|
|
ClockTwoLabelTextBlock.Text = L("worldclock.settings.clock_2", "时钟 2");
|
|
ClockThreeLabelTextBlock.Text = L("worldclock.settings.clock_3", "时钟 3");
|
|
ClockFourLabelTextBlock.Text = L("worldclock.settings.clock_4", "时钟 4");
|
|
SecondHandLabelTextBlock.Text = L("worldclock.settings.second_mode_label", "秒针方式");
|
|
TickRadioButton.Content = L("clock.second_mode.tick", "跳针");
|
|
SweepRadioButton.Content = L("clock.second_mode.sweep", "扫针");
|
|
|
|
var allTimeZones = _timeZoneService.GetAllTimeZones()
|
|
.OrderBy(zone => zone.GetUtcOffset(DateTime.UtcNow))
|
|
.ThenBy(zone => zone.DisplayName, StringComparer.OrdinalIgnoreCase)
|
|
.ToList();
|
|
var selectedIds = WorldClockTimeZoneCatalog.NormalizeTimeZoneIds(LoadSnapshot().WorldClockTimeZoneIds, allTimeZones);
|
|
|
|
_suppressEvents = true;
|
|
foreach (var combo in _timeZoneCombos)
|
|
{
|
|
combo.Items.Clear();
|
|
foreach (var zone in allTimeZones)
|
|
{
|
|
var item = new ComboBoxItem
|
|
{
|
|
Tag = zone.Id,
|
|
Content = FormatTimeZone(zone)
|
|
};
|
|
item.Classes.Add("component-editor-select-item");
|
|
combo.Items.Add(item);
|
|
}
|
|
}
|
|
|
|
for (var index = 0; index < _timeZoneCombos.Length; index++)
|
|
{
|
|
var combo = _timeZoneCombos[index];
|
|
var targetId = index < selectedIds.Count ? selectedIds[index] : TimeZoneInfo.Local.Id;
|
|
combo.SelectedItem = combo.Items
|
|
.OfType<ComboBoxItem>()
|
|
.FirstOrDefault(item => string.Equals(item.Tag as string, targetId, StringComparison.OrdinalIgnoreCase))
|
|
?? combo.Items.OfType<ComboBoxItem>().FirstOrDefault();
|
|
}
|
|
|
|
var secondMode = ClockSecondHandMode.Normalize(LoadSnapshot().WorldClockSecondHandMode);
|
|
TickRadioButton.IsChecked = string.Equals(secondMode, ClockSecondHandMode.Tick, StringComparison.OrdinalIgnoreCase);
|
|
SweepRadioButton.IsChecked = string.Equals(secondMode, ClockSecondHandMode.Sweep, StringComparison.OrdinalIgnoreCase);
|
|
_suppressEvents = false;
|
|
}
|
|
|
|
private void OnTimeZoneSelectionChanged(object? sender, SelectionChangedEventArgs e)
|
|
{
|
|
_ = sender;
|
|
_ = e;
|
|
if (_suppressEvents)
|
|
{
|
|
return;
|
|
}
|
|
|
|
SaveState();
|
|
}
|
|
|
|
private void OnSecondHandChanged(object? sender, RoutedEventArgs e)
|
|
{
|
|
_ = sender;
|
|
_ = e;
|
|
if (_suppressEvents)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_suppressEvents = true;
|
|
if (sender == TickRadioButton)
|
|
{
|
|
TickRadioButton.IsChecked = true;
|
|
SweepRadioButton.IsChecked = false;
|
|
}
|
|
else if (sender == SweepRadioButton)
|
|
{
|
|
SweepRadioButton.IsChecked = true;
|
|
TickRadioButton.IsChecked = false;
|
|
}
|
|
|
|
if (TickRadioButton.IsChecked != true && SweepRadioButton.IsChecked != true)
|
|
{
|
|
TickRadioButton.IsChecked = true;
|
|
}
|
|
|
|
_suppressEvents = false;
|
|
SaveState();
|
|
}
|
|
|
|
private void SaveState()
|
|
{
|
|
var snapshot = LoadSnapshot();
|
|
snapshot.WorldClockTimeZoneIds = _timeZoneCombos
|
|
.Select(combo => combo.SelectedItem is ComboBoxItem item && item.Tag is string tag ? tag : TimeZoneInfo.Local.Id)
|
|
.ToList();
|
|
snapshot.WorldClockSecondHandMode = SweepRadioButton.IsChecked == true
|
|
? ClockSecondHandMode.Sweep
|
|
: ClockSecondHandMode.Tick;
|
|
|
|
SaveSnapshot(
|
|
snapshot,
|
|
nameof(ComponentSettingsSnapshot.WorldClockTimeZoneIds),
|
|
nameof(ComponentSettingsSnapshot.WorldClockSecondHandMode));
|
|
}
|
|
|
|
private static string FormatTimeZone(TimeZoneInfo timeZone)
|
|
{
|
|
var offset = timeZone.GetUtcOffset(DateTime.UtcNow);
|
|
var sign = offset >= TimeSpan.Zero ? "+" : "-";
|
|
var totalMinutes = Math.Abs((int)offset.TotalMinutes);
|
|
var hours = totalMinutes / 60;
|
|
var minutes = totalMinutes % 60;
|
|
return $"(UTC{sign}{hours:D2}:{minutes:D2}) {timeZone.StandardName}";
|
|
}
|
|
}
|