rearranging the settings window layout

This commit is contained in:
2026-08-09 20:25:56 +05:00
parent 163b86d239
commit 7ecad05e1c
2 changed files with 414 additions and 271 deletions
+163 -42
View File
@@ -8,7 +8,7 @@
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=vm:SettingsViewModel}"
Title="{Binding Localization[SettingsTitle]}"
Width="560" SizeToContent="Height" MaxHeight="900"
Width="1000" SizeToContent="Height" MaxHeight="900"
ResizeMode="CanMinimize"
Background="{DynamicResource Theme.WindowBackground}"
Foreground="{DynamicResource Theme.Foreground}">
@@ -16,12 +16,13 @@
<local:EnumToVisibilityConverter x:Key="EnumToVisibility" />
<local:ColorToBrushConverter x:Key="ColorToBrush" />
<local:ColorToHexConverter x:Key="ColorToHex" />
<BooleanToVisibilityConverter x:Key="BooleanToVisibility" />
<DataTemplate x:Key="EnumOptionTemplate">
<TextBlock Text="{Binding Display}" />
</DataTemplate>
<!-- Образец цвета с подписью: одинаково для фона и для текста -->
<!-- A colour swatch with a caption: the same for the background and for the text -->
<DataTemplate x:Key="ColorSwatchTemplate">
<StackPanel Orientation="Horizontal">
<Border Width="32" Height="16" CornerRadius="2"
@@ -52,12 +53,18 @@
screen entirely and does without scrolling. Scrolling is kept for the case of
a large system font, with which the content is taller than the monitor after all -->
<ScrollViewer VerticalScrollBarVisibility="Auto" Padding="16">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel>
<GroupBox Header="{Binding Localization[SectionInterface]}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="180" />
<ColumnDefinition Width="164" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
@@ -87,7 +94,7 @@
<GroupBox Header="{Binding Localization[SectionPlacement]}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="180" />
<ColumnDefinition Width="164" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
@@ -109,7 +116,7 @@
SelectedValuePath="Value"
SelectedValue="{Binding Settings.PlacementMode}" />
<!-- Режим «у курсора»: своя сторона и свой отступ -->
<!-- The "at cursor" mode: a side and an offset of its own -->
<TextBlock Grid.Row="1" Margin="0,12,12,0"
Style="{StaticResource FieldLabel}"
Text="{Binding Localization[CursorCornerLabel]}"
@@ -144,7 +151,7 @@
Converter={StaticResource EnumToVisibility},
ConverterParameter=AtCursor}" />
<!-- Режим «у каретки»: свои сторона и отступ -->
<!-- The "at caret" mode: a side and an offset of its own -->
<TextBlock Grid.Row="3" Margin="0,12,12,0"
Style="{StaticResource FieldLabel}"
Text="{Binding Localization[CursorCornerLabel]}"
@@ -179,7 +186,7 @@
Converter={StaticResource EnumToVisibility},
ConverterParameter=AtCaret}" />
<!-- Режим «фиксированная точка» -->
<!-- The "fixed point" mode -->
<TextBlock Grid.Row="5" Margin="0,12,12,0"
Style="{StaticResource FieldLabel}"
Text="{Binding Localization[ScreenPositionLabel]}"
@@ -216,10 +223,106 @@
</Grid>
</GroupBox>
<GroupBox Header="{Binding Localization[SectionBehavior]}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="164" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Style="{StaticResource FieldLabel}"
Text="{Binding Localization[DurationLabel]}" />
<Slider Grid.Column="1" Minimum="200" Maximum="5000" TickFrequency="100"
Value="{Binding Settings.DurationMilliseconds}" />
<StackPanel Grid.Column="2" Orientation="Horizontal" VerticalAlignment="Center">
<TextBlock Style="{StaticResource FieldValue}"
Text="{Binding Settings.DurationMilliseconds, StringFormat={}{0:F0}}" />
<TextBlock Margin="4,0,0,0"
Foreground="{DynamicResource Theme.SecondaryForeground}"
Text="{Binding Localization[MillisecondsSuffix]}" />
</StackPanel>
<TextBlock Grid.Row="1" Margin="0,12,12,0"
Style="{StaticResource FieldLabel}"
Text="{Binding Localization[CapsLockLabel]}" />
<CheckBox Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" Margin="0,12,0,0"
IsChecked="{Binding Settings.UseCapsLockHotkey}"
Content="{Binding Localization[CapsLockHotkeyCheck]}" />
<TextBlock Grid.Row="2" Margin="0,12,12,0"
Style="{StaticResource FieldLabel}"
Text="{Binding Localization[CapsLockHoldLabel]}" />
<Slider Grid.Row="2" Grid.Column="1" Margin="0,12,0,0"
Minimum="150" Maximum="1500" TickFrequency="50"
Value="{Binding Settings.CapsLockHoldMilliseconds}"
IsEnabled="{Binding Settings.UseCapsLockHotkey}" />
<StackPanel Grid.Row="2" Grid.Column="2" Margin="0,12,0,0"
Orientation="Horizontal" VerticalAlignment="Center">
<TextBlock Style="{StaticResource FieldValue}"
Text="{Binding Settings.CapsLockHoldMilliseconds, StringFormat={}{0:F0}}" />
<TextBlock Margin="4,0,0,0"
Foreground="{DynamicResource Theme.SecondaryForeground}"
Text="{Binding Localization[MillisecondsSuffix]}" />
</StackPanel>
<TextBlock Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2"
Margin="0,6,0,0" TextWrapping="Wrap"
Foreground="{DynamicResource Theme.SecondaryForeground}">
<Run Text="{Binding Localization[CapsLockHoldHint], Mode=OneWay}" />
<InlineUIContainer BaselineAlignment="Baseline">
<!-- The elevation caveat lives in the tooltip to keep the section compact -->
<TextBlock Text="{Binding Localization[MoreInfoLink]}"
Foreground="{DynamicResource Theme.Accent}"
TextDecorations="Underline"
Cursor="Help"
ToolTipService.InitialShowDelay="200"
ToolTipService.ShowDuration="60000"
Visibility="{Binding Settings.UseCapsLockHotkey, Converter={StaticResource BooleanToVisibility}}">
<TextBlock.ToolTip>
<ToolTip>
<TextBlock TextWrapping="Wrap"
Text="{Binding Localization[CapsLockElevationHint]}" />
</ToolTip>
</TextBlock.ToolTip>
</TextBlock>
</InlineUIContainer>
</TextBlock>
<TextBlock Grid.Row="4" Margin="0,12,12,0"
Style="{StaticResource FieldLabel}"
Visibility="{Binding IsStartupAvailable, Converter={StaticResource BooleanToVisibility}}"
Text="{Binding Localization[StartupLabel]}" />
<CheckBox Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="2" Margin="0,12,0,0"
Visibility="{Binding IsStartupAvailable, Converter={StaticResource BooleanToVisibility}}"
IsEnabled="{Binding CanChangeStartup}"
IsChecked="{Binding RunAtStartup}"
Content="{Binding Localization[StartupCheck]}" />
<TextBlock Grid.Row="5" Grid.Column="1" Grid.ColumnSpan="2"
Margin="0,6,0,0" TextWrapping="Wrap"
Foreground="{DynamicResource Theme.SecondaryForeground}"
Visibility="{Binding IsStartupLocked, Converter={StaticResource BooleanToVisibility}}"
Text="{Binding Localization[StartupLockedHint]}" />
</Grid>
</GroupBox>
</StackPanel>
<StackPanel Grid.Column="1" Margin="16,0,0,0">
<GroupBox Header="{Binding Localization[SectionAppearance]}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="180" />
<ColumnDefinition Width="164" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
@@ -267,9 +370,12 @@
<TextBlock Grid.Row="4" Margin="0,12,12,0"
Style="{StaticResource FieldLabel}"
Text="{Binding Localization[PreviewLabel]}" />
<!-- The height of the area is sized for the largest font
available: the sample text is fully visible at any
position of the slider -->
<Border Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="2"
Margin="0,12,0,0" Padding="16"
Height="144" ClipToBounds="True"
Height="152" ClipToBounds="True"
Background="{DynamicResource Theme.SurfaceStrong}" CornerRadius="4"
HorizontalAlignment="Stretch">
<Border CornerRadius="4" Padding="10,4"
@@ -286,10 +392,12 @@
</Grid>
</GroupBox>
<GroupBox Header="{Binding Localization[SectionBehavior]}">
<!-- The section is absent for an app from the Store: the Store updates it itself -->
<GroupBox Header="{Binding Localization[SectionUpdates]}"
Visibility="{Binding Updates.IsSupported, Converter={StaticResource BooleanToVisibility}}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="180" />
<ColumnDefinition Width="164" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
@@ -298,50 +406,63 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Style="{StaticResource FieldLabel}"
Text="{Binding Localization[DurationLabel]}" />
<Slider Grid.Column="1" Minimum="200" Maximum="5000" TickFrequency="100"
Value="{Binding Settings.DurationMilliseconds}" />
<StackPanel Grid.Column="2" Orientation="Horizontal" VerticalAlignment="Center">
<TextBlock Style="{StaticResource FieldValue}"
Text="{Binding Settings.DurationMilliseconds, StringFormat={}{0:F0}}" />
<TextBlock Margin="4,0,0,0"
Foreground="{DynamicResource Theme.SecondaryForeground}"
Text="{Binding Localization[MillisecondsSuffix]}" />
</StackPanel>
Text="{Binding Localization[CurrentVersionLabel]}" />
<TextBlock Grid.Column="1" VerticalAlignment="Center"
Text="{Binding Updates.CurrentVersion}" />
<Button Grid.Column="2" Padding="12,4"
Command="{Binding Updates.CheckCommand}"
IsEnabled="{Binding Updates.CanCheck}"
Content="{Binding Localization[CheckUpdatesButton]}" />
<TextBlock Grid.Row="1" Margin="0,12,12,0"
Style="{StaticResource FieldLabel}"
Text="{Binding Localization[CapsLockLabel]}" />
<CheckBox Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" Margin="0,12,0,0"
IsChecked="{Binding Settings.UseCapsLockHotkey}"
Content="{Binding Localization[CapsLockHotkeyCheck]}" />
IsChecked="{Binding Updates.CheckAutomatically}"
Content="{Binding Localization[UpdateAutoCheck]}" />
<TextBlock Grid.Row="2" Margin="0,12,12,0"
Style="{StaticResource FieldLabel}"
Text="{Binding Localization[CapsLockHoldLabel]}" />
<Slider Grid.Row="2" Grid.Column="1" Margin="0,12,0,0"
Minimum="150" Maximum="1500" TickFrequency="50"
Value="{Binding Settings.CapsLockHoldMilliseconds}"
IsEnabled="{Binding Settings.UseCapsLockHotkey}" />
<StackPanel Grid.Row="2" Grid.Column="2" Margin="0,12,0,0"
Orientation="Horizontal" VerticalAlignment="Center">
<TextBlock Style="{StaticResource FieldValue}"
Text="{Binding Settings.CapsLockHoldMilliseconds, StringFormat={}{0:F0}}" />
<TextBlock Margin="4,0,0,0"
Foreground="{DynamicResource Theme.SecondaryForeground}"
Text="{Binding Localization[MillisecondsSuffix]}" />
<TextBlock Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2"
Margin="0,12,0,0" TextWrapping="Wrap"
Visibility="{Binding Updates.HasStatus, Converter={StaticResource BooleanToVisibility}}"
Text="{Binding Updates.StatusText}" />
<!-- The downloaded fraction is not always known: not every hosting reports the file size -->
<ProgressBar Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2"
Margin="0,8,0,0" Height="4" Maximum="1"
Value="{Binding Updates.Progress, Mode=OneWay}"
IsIndeterminate="{Binding Updates.IsProgressUnknown}"
Visibility="{Binding Updates.IsProgressShown, Converter={StaticResource BooleanToVisibility}}" />
<StackPanel Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="2"
Margin="0,12,0,0" Orientation="Horizontal">
<Button Padding="12,4"
Command="{Binding Updates.DownloadCommand}"
Visibility="{Binding Updates.IsDownloadOffered, Converter={StaticResource BooleanToVisibility}}"
Content="{Binding Localization[DownloadUpdateButton]}" />
<Button Padding="12,4"
Command="{Binding Updates.InstallCommand}"
Visibility="{Binding Updates.IsInstallOffered, Converter={StaticResource BooleanToVisibility}}"
Content="{Binding Localization[InstallUpdateButton]}" />
<TextBlock Margin="12,0,0,0" VerticalAlignment="Center"
Visibility="{Binding Updates.IsReleaseLinkShown, Converter={StaticResource BooleanToVisibility}}">
<Hyperlink NavigateUri="{Binding Updates.ReleaseUrl}"
RequestNavigate="OnReleaseLinkNavigate">
<Run Text="{Binding Localization[ReleasePageLink], Mode=OneWay}" />
</Hyperlink>
</TextBlock>
</StackPanel>
<TextBlock Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2"
<TextBlock Grid.Row="5" Grid.Column="1" Grid.ColumnSpan="2"
Margin="0,6,0,0" TextWrapping="Wrap"
Foreground="{DynamicResource Theme.SecondaryForeground}"
Text="{Binding Localization[CapsLockHoldHint]}" />
Visibility="{Binding Updates.IsInstallOffered, Converter={StaticResource BooleanToVisibility}}"
Text="{Binding Localization[UpdateInstallHint]}" />
</Grid>
</GroupBox>
</StackPanel>
</Grid>
</ScrollViewer>
</Window>
+22
View File
@@ -1,4 +1,7 @@
using System.ComponentModel;
using System.Diagnostics;
using System.Windows;
using System.Windows.Navigation;
using CursorLang.Services;
using CursorLang.ViewModels;
@@ -16,4 +19,23 @@ public partial class MainWindow : Window
theme.Register(this);
placement.Attach(this);
}
/// <summary>
/// Opens the release page in a browser. A link in WPF leads nowhere on its own:
/// where to hand it over is up to the application.
/// </summary>
private void OnReleaseLinkNavigate(object sender, RequestNavigateEventArgs e)
{
e.Handled = true;
try
{
Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri) { UseShellExecute = true })?.Dispose();
}
catch (Exception exception) when (exception is Win32Exception or InvalidOperationException)
{
// There is no browser in the system — that does not get in the way of the
// update, which is downloaded by the button next to it anyway
}
}
}