using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using Microsoft.Win32;
namespace UbisamBase.Launcher;
///
/// 업데이트를 확인하고 받는 동안 보여주는 창. 런처를 누르자마자 떠서 "지금 뭘 하고 있는지"를 알린다
/// (예전에는 받는 동안 아무것도 안 보여서 프로그램이 안 켜지는 것처럼 보였다).
///
/// 받기가 끝나면 이 창은 닫히고, 설치 여부는 UpdateDialog가 묻는다.
/// 색은 UpdateDialog와 같은 방식으로(윈도우 밝게/어둡게) 직접 넣는다 — Core를 참조할 수 없기 때문.
///
public partial class ProgressWindow : Window
{
private double percent;
public ProgressWindow()
{
InitializeComponent();
ApplyTheme(IsSystemLightTheme());
SizeChanged += (_, _) => UpdateFillWidth(animate: false);
}
/// 제목과 설명을 바꾼다. 어느 스레드에서 불러도 된다.
public void SetStage(string headline, string status)
=> Dispatcher.Invoke(() =>
{
HeadlineText.Text = headline;
StatusText.Text = status;
});
/// 0~100. 뒤로 가지 않도록 지금 값보다 큰 값만 반영한다 — git이 단계마다 0%부터 다시 세기 때문.
public void SetPercent(double value)
=> Dispatcher.Invoke(() =>
{
var clamped = Math.Max(0, Math.Min(100, value));
if (clamped <= percent)
{
return;
}
percent = clamped;
PercentText.Text = ((int)percent) + "%";
UpdateFillWidth(animate: true);
});
private void UpdateFillWidth(bool animate)
{
var target = Math.Max(0, TrackBorder.ActualWidth * percent / 100.0);
if (!animate)
{
FillBorder.BeginAnimation(WidthProperty, null);
FillBorder.Width = target;
return;
}
// 숫자가 툭툭 튀지 않도록 짧게 이어 붙인다.
FillBorder.BeginAnimation(WidthProperty, new DoubleAnimation(target, TimeSpan.FromMilliseconds(220))
{
EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut },
FillBehavior = FillBehavior.HoldEnd
});
}
private void ApplyTheme(bool light)
{
var background = Brush(light ? "#FFFFFFFF" : "#FF2A2E34");
var foreground = Brush(light ? "#FF1D1F20" : "#FFE8EAED");
var border = Brush(light ? "#FFD6D6D9" : "#FF3A3F47");
var muted = Brush(light ? "#FF98989B" : "#FF8A9099");
var accent = Brush(light ? "#FF2196F3" : "#FF4DA6F5");
var track = Brush(light ? "#FFEDEDEF" : "#FF23262B");
var chip = Brush(light ? "#142196F3" : "#1F4DA6F5");
Background = background;
Foreground = foreground;
RootBorder.BorderBrush = border;
AccentStrip.Background = accent;
IconChip.Background = chip;
IconPath.Stroke = accent;
HeadlineText.Foreground = foreground;
StatusText.Foreground = muted;
PercentText.Foreground = muted;
TrackBorder.Background = track;
FillBorder.Background = accent;
}
private static SolidColorBrush Brush(string hex)
=> new SolidColorBrush((Color)ColorConverter.ConvertFromString(hex));
private static bool IsSystemLightTheme()
{
try
{
using var key = Registry.CurrentUser.OpenSubKey(
@"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize");
return key?.GetValue("AppsUseLightTheme") is not int value || value != 0;
}
catch
{
return true;
}
}
private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) => DragMove();
}