Skip to content

Commit

Permalink
Merge pull request #1052 from xoascf/clock-update
Browse files Browse the repository at this point in the history
Fix calendar loading for Clock
  • Loading branch information
dremin authored Feb 17, 2025
2 parents 5611263 + 57d1783 commit af1b8e6
Showing 1 changed file with 56 additions and 31 deletions.
87 changes: 56 additions & 31 deletions RetroBar/Controls/Clock.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
Expand All @@ -19,30 +21,32 @@ namespace RetroBar.Controls
/// </summary>
public partial class Clock : UserControl
{
public static DependencyProperty NowProperty = DependencyProperty.Register("Now", typeof(DateTime), typeof(Clock));
public static readonly DependencyProperty NowProperty = DependencyProperty.Register(nameof(Now), typeof(DateTime), typeof(Clock));

public DateTime Now
{
get { return (DateTime)GetValue(NowProperty); }
set { SetValue(NowProperty, value); }
get => (DateTime)GetValue(NowProperty);
set => SetValue(NowProperty, value);
}

private readonly DispatcherTimer clock = new DispatcherTimer(DispatcherPriority.Background);

private readonly DispatcherTimer _clock = new DispatcherTimer(DispatcherPriority.Background);
private CultureInfo _userCulture;
private bool _isLoaded;

private const int LOCALE_NAME_MAX_LENGTH = 85;

public Clock()
{
InitializeComponent();
DataContext = this;

clock.Interval = TimeSpan.FromMilliseconds(200);
clock.Tick += Clock_Tick;
_clock.Interval = TimeSpan.FromMilliseconds(200);
_clock.Tick += Clock_Tick;
}

private void Initialize()
{
SetCurrentCulture();
UpdateUserCulture();
if (Settings.Instance.ShowClock)
{
StartClock();
Expand All @@ -61,14 +65,14 @@ private void StartClock()
{
SetTime();

clock.Start();
_clock.Start();

Visibility = Visibility.Visible;
}

private void StopClock()
{
clock.Stop();
_clock.Stop();

Visibility = Visibility.Collapsed;
}
Expand Down Expand Up @@ -98,7 +102,7 @@ private void TimeChanged(object sender, EventArgs e)
TimeZoneInfo.ClearCachedData();
}

private static void SetConverterCultureRecursively(DependencyObject main)
private static void SetConverterCultureRecursively(DependencyObject main, CultureInfo ci)
{
if (main != null)
{
Expand All @@ -108,50 +112,58 @@ private static void SetConverterCultureRecursively(DependencyObject main)
{
BindingOperations.SetBinding(main, TextBlock.TextProperty,
new Binding(binding.Path.Path)
{ StringFormat = binding.StringFormat, ConverterCulture = CultureInfo.CurrentCulture });
{ StringFormat = binding.StringFormat, ConverterCulture = ci });
}

for (int i = 0; i < VisualTreeHelper.GetChildrenCount(main); i++)
{
if (VisualTreeHelper.GetChild(main, i) is UIElement sub)
{
SetConverterCultureRecursively(sub);
SetConverterCultureRecursively(sub, ci);
}
}
}
}

private void SetCurrentCulture()
private void UpdateUserCulture()
{
try
{
var iKey = Registry.CurrentUser.OpenSubKey(@"Control Panel\International", false);
if (iKey == null) return;
var iCi = (CultureInfo)CultureInfo.GetCultureInfo((string)iKey.GetValue("LocaleName")).Clone();
iCi.DateTimeFormat.ShortDatePattern = (string)iKey.GetValue("sShortDate");
iCi.DateTimeFormat.ShortTimePattern = (string)iKey.GetValue("sShortTime");
iCi.DateTimeFormat.LongDatePattern = (string)iKey.GetValue("sLongDate");
iCi.DateTimeFormat.LongTimePattern = (string)iKey.GetValue("sTimeFormat");
iCi.DateTimeFormat.DateSeparator = (string)iKey.GetValue("sDate");
iCi.DateTimeFormat.TimeSeparator = (string)iKey.GetValue("sTime");
iCi.DateTimeFormat.AMDesignator = (string)iKey.GetValue("s1159");
iCi.DateTimeFormat.PMDesignator = (string)iKey.GetValue("s2359");

CultureInfo.CurrentCulture = iCi;
SetConverterCultureRecursively(this);
SetConverterCultureRecursively(ClockTip);
string localeName = GetUserDefaultLocaleNameWrapper();

if (!string.IsNullOrEmpty(localeName))
{
_userCulture = new CultureInfo(localeName);
}
else
{
// Fallback: use LCID if locale name isn't available.
int lcid = GetUserDefaultLCID();
_userCulture = new CultureInfo(lcid);
}
}
catch (Exception e)
{
ShellLogger.Error($"Clock: Unable to set the current culture: {e.Message}");
ShellLogger.Error($"Clock: Unable to get the user culture: {e.Message}, defaulting to en-US");
_userCulture = new CultureInfo("en-US");
}

// Make mutable if necessary...
if (_userCulture.IsReadOnly)
{
_userCulture = (CultureInfo)_userCulture.Clone();
}

SetConverterCultureRecursively(this, _userCulture);
SetConverterCultureRecursively(ClockTip, _userCulture);
}

private void UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e)
{
if (e.Category == UserPreferenceCategory.Locale)
{
SetCurrentCulture();
CultureInfo.CurrentCulture.ClearCachedData();
UpdateUserCulture();
}
}

Expand All @@ -160,6 +172,19 @@ private void SetTime()
Now = DateTime.Now;
}

private static string GetUserDefaultLocaleNameWrapper()
{
var sb = new StringBuilder(LOCALE_NAME_MAX_LENGTH);
int ret = GetUserDefaultLocaleName(sb, sb.Capacity);
return ret > 0 ? sb.ToString() : null;
}

[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
private static extern int GetUserDefaultLocaleName(StringBuilder lpLocaleName, int cchLocaleName);

[DllImport("kernel32.dll")]
private static extern int GetUserDefaultLCID();

private void Clock_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (Settings.Instance.ClockClickAction == ClockClickOption.DoNothing)
Expand Down

0 comments on commit af1b8e6

Please sign in to comment.