Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add theme-independent clock format customization #754

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 38 additions & 10 deletions RetroBar/Controls/Clock.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,16 +78,26 @@ private void StopClock()

private void Settings_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "ShowClock")
{
if (Settings.Instance.ShowClock)
{
StartClock();
}
else
{
StopClock();
}
switch (e.PropertyName) {
case "ShowClock":
if (Settings.Instance.ShowClock)
{
StartClock();
}
else
{
StopClock();
}
break;

case "Theme":
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does Theme need to be here? I don't believe it will influence SetCurrentCulture, and it doesn't seem to fix the odd Properties preview bug you mentioned in your comment.

case "OverrideClockFormat":
case "ClockFormat":
case "OverrideAMPMDesignators":
case "AMDesignator":
case "PMDesignator":
SetCurrentCulture();
break;
}
}

Expand Down Expand Up @@ -156,6 +166,24 @@ private void SetCurrentCulture()
iCi.DateTimeFormat.AMDesignator = (string)iKey.GetValue("s1159");
iCi.DateTimeFormat.PMDesignator = (string)iKey.GetValue("s2359");

// Override culture info if desired, inserting newlines where appropriate
if (Settings.Instance.OverrideClockFormat && Settings.Instance.ClockFormat != "")
{
iCi.DateTimeFormat.ShortTimePattern = Settings.Instance.ClockFormat.Replace("\\n", "\n");
}

if (Settings.Instance.OverrideAMPMDesignators)
{
if (Settings.Instance.AMDesignator != "")
{
iCi.DateTimeFormat.AMDesignator = Settings.Instance.AMDesignator;
}
if (Settings.Instance.PMDesignator != "")
{
iCi.DateTimeFormat.PMDesignator = Settings.Instance.PMDesignator;
}
}

CultureInfo.CurrentCulture = iCi;
SetConverterCultureRecursively(this);
SetConverterCultureRecursively(ClockTip);
Expand Down
9 changes: 9 additions & 0 deletions RetroBar/Languages/English.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

<s:String x:Key="retrobar_properties">RetroBar Properties</s:String>
<s:String x:Key="taskbar_tab">Taskbar</s:String>
<s:String x:Key="clock_tab">Clock</s:String>
<s:String x:Key="advanced_tab">Advanced</s:String>
<s:String x:Key="taskbar_appearance">Taskbar appearance</s:String>
<s:String x:Key="notification_area">Notification area</s:String>
Expand Down Expand Up @@ -57,6 +58,14 @@
<s:String x:Key="debug_logging">Enable debug logging</s:String>
<s:String x:Key="ok_dialog">OK</s:String>

<s:String x:Key="clock_appearance">Clock appearance</s:String>
<s:String x:Key="clock_format_info" xml:space="preserve">What the notations mean:&#10;&#10;h = hour; m = minute, s = second, tt = AM/PM&#10;d = day; M = month; yy, yyyy = year&#10;ddd, dddd = weekday; MMM, MMMM = month name&#10;&#10;h/H = 12/24 hour&#10;hh, mm, ss, dd, MM = display leading zero&#10;h, m, s, d, M = do not display leading zero&#10;&#10;\n = split clock into multiple lines&#10;(not recommended on all themes)&#10;&#10;Use "\" in front of other notations to use their actual characters</s:String>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems a bit gnarly to localize. Given that we are using standard format specifiers, what are your thoughts regarding instead providing a link to this table which also includes examples and descriptions of all specifiers?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They probably wanted to copy the design from these intl.cpl dialogs (which, interestingly, also store the text as one big string with \n\ns in between):

изображение
изображение

<s:String x:Key="clock_format_warning" xml:space="preserve">Note: Custom clock formatting may not be applied&#10;if your selected theme specifies its own format.</s:String>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of putting a manual break in here, we can add padding/margin to the TextBlock to limit its width.

<s:String x:Key="override_clock_format">Custom clock _format:</s:String>
<s:String x:Key="override_ampm_designators">Custom _designators:</s:String>
<s:String x:Key="am_designator">AM:</s:String>
<s:String x:Key="pm_designator">PM:</s:String>

<s:String x:Key="customize_notifications">Customize Notifications</s:String>
<s:String x:Key="customize_notifications_info">RetroBar displays icons for active and urgent notifications, and hides inactive ones. You can change this behavior for items in the list below.</s:String>
<s:String x:Key="customize_notifications_instruction">Select an item, then choose its notification behavior:</s:String>
Expand Down
159 changes: 112 additions & 47 deletions RetroBar/PropertiesWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,50 @@
<Setter Property="Width"
Value="335" />
</Style>
<ControlTemplate x:Key="NotificationAreaPreview">
<Border Style="{StaticResource PreviewBorder}">
<ContentControl Height="{DynamicResource TaskbarHeight}"
IsHitTestVisible="False"
Focusable="False"
ClipToBounds="True"
Style="{DynamicResource Taskbar}">
<TextOptions.TextRenderingMode>
<Binding Source="{x:Static Settings:Settings.Instance}"
Path="AllowFontSmoothing"
Converter="{StaticResource textRenderingModeConverter}" />
</TextOptions.TextRenderingMode>
<DockPanel>
<controls:ShowDesktopButton DockPanel.Dock="Right" HorizontalAlignment="Center" Visibility="{Binding Source={x:Static Settings:Settings.Instance}, Path=ShowDesktopButton, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource boolToVisibilityConverter}}" />
<GroupBox Style="{DynamicResource Tray}"
DockPanel.Dock="Right">
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal">
<ToggleButton x:Name="NotifyIconToggleButton"
Focusable="False"
Visibility="{Binding CollapseNotifyIcons, Converter={StaticResource boolToVisibilityConverter}, Source={x:Static Settings:Settings.Instance}, UpdateSourceTrigger=PropertyChanged}"
Style="{DynamicResource TrayToggleButton}"/>
<ItemsControl Focusable="False"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<Border>
<Image Source="Resources\retrobar.ico"
Style="{DynamicResource NotifyIcon}" />
</Border>
</ItemsControl>
</StackPanel>
<controls:Clock VerticalAlignment="Center" />
</StackPanel>
</GroupBox>
<StackPanel/>
</DockPanel>
</ContentControl>
</Border>
</ControlTemplate>
</ResourceDictionary>
</Window.Resources>
<Grid Margin="7">
Expand Down Expand Up @@ -229,53 +273,8 @@
</GroupBox>
<GroupBox Header="{DynamicResource notification_area}">
<StackPanel Orientation="Vertical">
<Border Style="{StaticResource PreviewBorder}">
<ContentControl Height="{DynamicResource TaskbarHeight}"
IsHitTestVisible="False"
Focusable="False"
ClipToBounds="True"
Style="{DynamicResource Taskbar}">
<TextOptions.TextRenderingMode>
<Binding Source="{x:Static Settings:Settings.Instance}"
Path="AllowFontSmoothing"
Converter="{StaticResource textRenderingModeConverter}" />
</TextOptions.TextRenderingMode>
<DockPanel>
<controls:ShowDesktopButton DockPanel.Dock="Right" HorizontalAlignment="Center" Visibility="{Binding Source={x:Static Settings:Settings.Instance}, Path=ShowDesktopButton, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource boolToVisibilityConverter}}" />
<GroupBox Style="{DynamicResource Tray}"
DockPanel.Dock="Right">
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal">
<ToggleButton Name="NotifyIconToggleButton"
Focusable="False"
Visibility="{Binding Source={x:Static Settings:Settings.Instance}, Path=CollapseNotifyIcons, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource boolToVisibilityConverter}}"
Style="{DynamicResource TrayToggleButton}"/>
<ItemsControl Focusable="False"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"></WrapPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<Border>
<Image Source="Resources\retrobar.ico"
Style="{DynamicResource NotifyIcon}" />
</Border>
</ItemsControl>
</StackPanel>
<controls:Clock VerticalAlignment="Center" />
</StackPanel>
</GroupBox>
<StackPanel></StackPanel>
<controls:KeyboardLayout VerticalAlignment="Center" HorizontalAlignment="Right"/>
</DockPanel>
</ContentControl>
</Border>
<CheckBox x:Name="cbShowKeyboardLayout"
IsChecked="{Binding Source={x:Static Settings:Settings.Instance}, Path=ShowKeyboardLayout, UpdateSourceTrigger=PropertyChanged}">
<Label Content="{DynamicResource show_keyboard_layout}" />
</CheckBox>
<ContentControl Template="{StaticResource NotificationAreaPreview}"
Focusable="False" />
<CheckBox x:Name="cbShowClock"
IsChecked="{Binding Source={x:Static Settings:Settings.Instance}, Path=ShowClock, UpdateSourceTrigger=PropertyChanged}">
<Label Content="{DynamicResource show_clock}" />
Expand All @@ -298,6 +297,72 @@
</GroupBox>
</StackPanel>
</TabItem>
<TabItem Header="{DynamicResource clock_tab}" >
<StackPanel Orientation="Vertical"
Margin="10">
<DockPanel>
<GroupBox Header="{DynamicResource clock_appearance}"
Margin="0,0,0,10">
<StackPanel Orientation="Vertical">
<ContentControl Template="{StaticResource NotificationAreaPreview}"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bug with the preview seems to happen because the clock control has no children at the time the Loaded event fires, so the ConverterCulture doesn't get set. I'm not sure why it is happening in this specific case.

IMO this should be fixed before the changes can be merged. There is an alternative, we could remove the extra preview, but that would make the Clock tab a bit sparse. Together with replacing the explanatory string with a link, the clock format section could fit on the Advanced tab instead.

Focusable="False" />
<CheckBox IsChecked="{Binding Source={x:Static Settings:Settings.Instance}, Path=ShowClock, UpdateSourceTrigger=PropertyChanged}">
<Label Content="{DynamicResource show_clock}" />
</CheckBox>
<DockPanel DockPanel.Dock="Top">
<CheckBox x:Name="cbOverrideClockFormat"
VerticalAlignment="Center"
IsChecked="{Binding Source={x:Static Settings:Settings.Instance}, Path=OverrideClockFormat, UpdateSourceTrigger=PropertyChanged}">
<Label Content="{DynamicResource override_clock_format}" />
</CheckBox>
<TextBox Text="{Binding Source={x:Static Settings:Settings.Instance}, Path=ClockFormat, UpdateSourceTrigger=PropertyChanged}"
TextWrapping="Wrap"
VerticalAlignment="Center"
Margin="5,0,0,0"
IsEnabled="{Binding Source={x:Static Settings:Settings.Instance}, Path=OverrideClockFormat, UpdateSourceTrigger=PropertyChanged}" />
</DockPanel>
<DockPanel VerticalAlignment="Top" >
<CheckBox x:Name="cbOverrideAMPMDesignators"
VerticalAlignment="Center"
IsChecked="{Binding Source={x:Static Settings:Settings.Instance}, Path=OverrideAMPMDesignators, UpdateSourceTrigger=PropertyChanged}">
<Label Content="{DynamicResource override_ampm_designators}" />
</CheckBox>
<UniformGrid Columns="2">
<DockPanel>
<Label Content="{DynamicResource am_designator}"
VerticalAlignment="Center"
Margin="10,0,0,2"
IsEnabled="{Binding Source={x:Static Settings:Settings.Instance}, Path=OverrideAMPMDesignators, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Text="{Binding Source={x:Static Settings:Settings.Instance}, Path=AMDesignator, UpdateSourceTrigger=PropertyChanged}"
TextWrapping="Wrap"
VerticalAlignment="Center"
Margin="5,0,0,0"
IsEnabled="{Binding Source={x:Static Settings:Settings.Instance}, Path=OverrideAMPMDesignators, UpdateSourceTrigger=PropertyChanged}" />
</DockPanel>
<DockPanel>
<Label Content="{DynamicResource pm_designator}"
Margin="10,0,0,2"
VerticalAlignment="Center"
IsEnabled="{Binding Source={x:Static Settings:Settings.Instance}, Path=OverrideAMPMDesignators, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Text="{Binding Source={x:Static Settings:Settings.Instance}, Path=PMDesignator, UpdateSourceTrigger=PropertyChanged}"
TextWrapping="Wrap"
VerticalAlignment="Center"
Margin="5,0,0,0"
IsEnabled="{Binding Source={x:Static Settings:Settings.Instance}, Path=OverrideAMPMDesignators, UpdateSourceTrigger=PropertyChanged}" />
</DockPanel>
</UniformGrid>
</DockPanel>
<TextBlock Text="{DynamicResource clock_format_warning}"
TextWrapping="Wrap"
TextAlignment="Center"
Margin="0,3,0,3" />
</StackPanel>
</GroupBox>
</DockPanel>
<TextBlock Text="{DynamicResource clock_format_info}"
TextWrapping="Wrap" />
</StackPanel>
</TabItem>
<TabItem Header="{DynamicResource advanced_tab}">
<StackPanel Orientation="Vertical"
Margin="10">
Expand Down
Loading