瀏覽代碼

Removed big ass grid

Krzysztof Krysiński 2 年之前
父節點
當前提交
12a194191e

+ 4 - 1
src/PixiEditor/Data/Localization/Languages/en.json

@@ -1,5 +1,8 @@
 {
   "RECENT_FILES": "Recent Files",
   "OPEN_FILE": "Open",
-  "NEW_FILE": "New"
+  "NEW_FILE": "New",
+  "RECENT_EMPTY_TEXT": "So much empty space",
+  
+  "LANGUAGE": "Language"
 }

+ 4 - 1
src/PixiEditor/Data/Localization/Languages/pl.json

@@ -1,5 +1,8 @@
 {
   "RECENT_FILES": "Ostatnie pliki",
   "OPEN_FILE": "Otwórz",
-  "NEW_FILE": "Nowy"
+  "NEW_FILE": "Nowy",
+  "RECENT_EMPTY_TEXT": "Ale tu pusto, na co czekasz, stwórz coś!",
+
+  "LANGUAGE": "Język"
 }

+ 24 - 0
src/PixiEditor/Helpers/Converters/SubtractConverter.cs

@@ -0,0 +1,24 @@
+using System.Globalization;
+
+namespace PixiEditor.Helpers.Converters;
+
+internal class SubtractConverter : SingleInstanceConverter<SubtractConverter>
+{
+    public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+    {
+        object parsedValue = value is string stringValue ? double.Parse(stringValue) : value;
+        object parsedParameter = parameter is string parameterString ? double.Parse(parameterString) : parameter;
+        
+        if (parsedValue is not double doubleValue)
+        {
+            return value;
+        }
+
+        if (parsedParameter is not double doubleParameter)
+        {
+            return value;
+        }
+
+        return doubleValue - doubleParameter;
+    }
+}

+ 1 - 0
src/PixiEditor/Localization/ILocalizationProvider.cs

@@ -16,4 +16,5 @@ public interface ILocalizationProvider
     /// </summary>
     public void LoadData();
     public void LoadLanguage(LanguageData languageData);
+    public Language DefaultLanguage { get; }
 }

+ 22 - 14
src/PixiEditor/Localization/LocalizationProvider.cs

@@ -1,5 +1,4 @@
 using System.IO;
-using PixiEditor.Models.Commands.Attributes.Commands;
 
 namespace PixiEditor.Localization;
 
@@ -9,6 +8,7 @@ internal class LocalizationProvider : ILocalizationProvider
     public LocalizationData LocalizationData { get; private set; }
     public Language CurrentLanguage { get; set; }
     public event Action<Language> OnLanguageChanged;
+    public Language DefaultLanguage { get; private set; }
 
     public void LoadData()
     {
@@ -33,6 +33,7 @@ internal class LocalizationProvider : ILocalizationProvider
         }
         
         LoadLanguage(LocalizationData.Languages[0]);
+        DefaultLanguage = CurrentLanguage;
     }
 
     public void LoadLanguage(LanguageData languageData)
@@ -47,28 +48,35 @@ internal class LocalizationProvider : ILocalizationProvider
             return;
         }
         
+        bool firstLoad = CurrentLanguage is null;
+
+        CurrentLanguage = LoadLanguageInternal(languageData);
+
+        if (!firstLoad)
+        {
+            OnLanguageChanged?.Invoke(CurrentLanguage);
+        }
+    }
+
+    private Language LoadLanguageInternal(LanguageData languageData)
+    {
         string localePath = Path.Combine("Data", "Localization", "Languages", languageData.LocaleFileName);
-        
-        if(!File.Exists(localePath))
+
+        if (!File.Exists(localePath))
         {
             throw new FileNotFoundException("Locale file not found.", localePath);
         }
-        
+
         Newtonsoft.Json.JsonSerializer serializer = new();
         using StreamReader reader = new(localePath);
-        Dictionary<string, string> locale = serializer.Deserialize<Dictionary<string, string>>(new Newtonsoft.Json.JsonTextReader(reader));
-        
+        Dictionary<string, string> locale =
+            serializer.Deserialize<Dictionary<string, string>>(new Newtonsoft.Json.JsonTextReader(reader));
+
         if (locale is null)
         {
             throw new InvalidDataException("Locale is null.");
         }
-        
-        bool firstLoad = CurrentLanguage is null;
-        CurrentLanguage = new(languageData, locale);
-        
-        if (!firstLoad)
-        {
-            OnLanguageChanged?.Invoke(CurrentLanguage);
-        }
+
+        return new(languageData, locale);
     }
 }

+ 26 - 2
src/PixiEditor/Localization/LocalizedString.cs

@@ -8,9 +8,33 @@ public struct LocalizedString
     public LocalizedString(string key)
     {
         Key = key;
-        Value = ILocalizationProvider.Current.CurrentLanguage.Locale.ContainsKey(key) ? ILocalizationProvider.Current.CurrentLanguage.Locale[key] : key;
+        Value = GetValue(key);
     }
-    
+
+    private static string GetValue(string key)
+    {
+        ILocalizationProvider localizationProvider = ILocalizationProvider.Current;
+        if (localizationProvider?.LocalizationData == null)
+        {
+            return key;
+        }
+
+        if (!localizationProvider.CurrentLanguage.Locale.ContainsKey(key))
+        {
+            Language defaultLanguage = localizationProvider.DefaultLanguage;
+
+            if (localizationProvider.CurrentLanguage == defaultLanguage || !defaultLanguage.Locale.ContainsKey(key))
+            {
+                return key;
+            }
+
+            return defaultLanguage.Locale[key];
+        }
+
+
+        return ILocalizationProvider.Current.CurrentLanguage.Locale[key];
+    }
+
     public static implicit operator LocalizedString(string key) => new(key);
     public static implicit operator string(LocalizedString localizedString) => localizedString.Value;
 }

+ 1 - 0
src/PixiEditor/Styles/LabelStyles.xaml

@@ -11,6 +11,7 @@
         <Setter Property="Padding" Value="0"/>
         <Setter Property="VerticalAlignment" Value="Center"/>
         <Setter Property="FontWeight" Value="DemiBold"/>
+        <Setter Property="Margin" Value="5 10"/>
     </Style>
 
     <Style x:Key="SettingsLink" TargetType="Hyperlink" BasedOn="{StaticResource {x:Type Hyperlink}}">

+ 5 - 8
src/PixiEditor/Views/Dialogs/HelloTherePopup.xaml

@@ -64,18 +64,16 @@
 
                 <StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center">
                     <Button Style="{StaticResource DarkRoundButton}" Command="{Binding OpenFileCommand}" Width="150" Margin="10"
-                            views:Translator.Key="OPEN_FILE"
-                            Content="{Binding Path=(views:Translator.Value), RelativeSource={RelativeSource Mode=Self}}"/>
+                            views:Translator.Key="OPEN_FILE"/>
                     <Button Style="{StaticResource DarkRoundButton}" Command="{Binding OpenNewFileCommand}" Width="150" Margin="10"
-                            views:Translator.Key="NEW_FILE"
-                            Content="{Binding Path=(views:Translator.Value), RelativeSource={RelativeSource Mode=Self}}"/>
+                            views:Translator.Key="NEW_FILE"/>
                 </StackPanel>
 
                 <StackPanel Grid.Row="2" HorizontalAlignment="Center" Margin="0,30,0,0">
                     <TextBlock FontSize="23" FontWeight="SemiBold" HorizontalAlignment="Center"
-                               views:Translator.Key="RECENT_FILES"
-                               Text="{Binding Path=(views:Translator.Value), RelativeSource={RelativeSource Self}}"/>
-                    <TextBlock Margin="0,12.5,0,0" Foreground="LightGray" HorizontalAlignment="Center">
+                               views:Translator.Key="RECENT_FILES"/>
+                    <TextBlock Margin="0,12.5,0,0" Foreground="LightGray" HorizontalAlignment="Center"
+                               views:Translator.Key="RECENT_EMPTY_TEXT">
                         <TextBlock.Visibility>
                             <Binding Path="RecentlyOpened.Count"
                                      Converter="{converters:EqualityBoolToVisibilityConverter}">
@@ -84,7 +82,6 @@
                                 </Binding.ConverterParameter>
                             </Binding>
                         </TextBlock.Visibility>
-                        So much empty here
                     </TextBlock>
                     <ItemsControl ItemsSource="{Binding RecentlyOpened}">
                         <ItemsControl.ItemTemplate>

+ 49 - 74
src/PixiEditor/Views/Dialogs/SettingsWindow.xaml

@@ -63,73 +63,58 @@
                 </x:Array>
             </ListBox.ItemsSource>
         </ListBox>
-
-        <Grid Grid.Row="1" Grid.Column="1" Background="{StaticResource AccentColor}">
-            <Grid Visibility="{Binding CurrentPage, Converter={converters:EqualityBoolToVisibilityConverter},
+        <StackPanel Orientation="Vertical" Background="{StaticResource AccentColor}">
+            <StackPanel Orientation="Vertical" Visibility="{Binding CurrentPage, Converter={converters:EqualityBoolToVisibilityConverter},
             ConverterParameter='General'}" Margin="15,10" Tag="27">
-                <Grid.ColumnDefinitions>
-                    <ColumnDefinition Width="15"/>
-                    <ColumnDefinition Width="230"/>
-                    <ColumnDefinition/>
-                </Grid.ColumnDefinitions>
-                <Grid.RowDefinitions>
-                    <RowDefinition Height="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=Tag}"/>
-                    <RowDefinition Height="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=Tag}"/>
-                    <RowDefinition Height="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=Tag}"/>
-                    <RowDefinition Height="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=Tag}"/>
-                    <RowDefinition Height="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=Tag}"/>
-                    <RowDefinition Height="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=Tag}"/>
-                    <RowDefinition Height="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=Tag}"/>
-                    <RowDefinition Height="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=Tag}"/>
-                    <RowDefinition Height="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=Tag}"/>
-                    <RowDefinition Height="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=Tag}"/>
-                    <RowDefinition Height="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=Tag}"/>
-                    <RowDefinition Height="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=Tag}"/>
-                    <RowDefinition Height="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=Tag}"/>
-                    <RowDefinition Height="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=Tag}"/>
-                    <RowDefinition Height="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=Tag}"/>
-                </Grid.RowDefinitions>
+                <Label Style="{StaticResource SettingsHeader}" views:Translator.Key="LANGUAGE"/>
 
-                <Label Grid.Row="0" Grid.ColumnSpan="2" Style="{StaticResource SettingsHeader}">Misc</Label>
+                <Label Style="{StaticResource SettingsHeader}">Misc</Label>
 
-                <CheckBox Grid.Row="1" Grid.Column="1"
+                <CheckBox Margin="27 0"
                           VerticalAlignment="Center"
                           IsChecked="{Binding SettingsSubViewModel.File.ShowStartupWindow}">Show startup window</CheckBox>
 
-                <CheckBox Grid.Row="2" Grid.Column="1"
+                <CheckBox Margin="27 10"
                           VerticalAlignment="Center"
                           IsChecked="{Binding SettingsSubViewModel.General.ImagePreviewInTaskbar}">Show image preview in taskbar</CheckBox>
 
-                <Label Grid.Row="3" Grid.Column="1" Style="{StaticResource SettingsText}"
+                <StackPanel Margin="27 0" Orientation="Horizontal">
+                <Label Style="{StaticResource SettingsText}"
                        ToolTip="How many documents are shown under File > Recent. Default: 8">Recent file list length</Label>
-                <usercontrols:NumberInput Grid.Row="3" Grid.Column="2" 
+                <usercontrols:NumberInput Margin="10 0 0 0"
                                    Min="0" FontSize="12" HorizontalAlignment="Left"
                                    Value="{Binding SettingsSubViewModel.File.MaxOpenedRecently, Mode=TwoWay}" Height="19" Width="40"/>
+                </StackPanel>
 
-                <Label Grid.Row="4" Grid.ColumnSpan="2"  Style="{StaticResource SettingsHeader}">Default new file size</Label>
+                <Label Style="{StaticResource SettingsHeader}">Default new file size</Label>
 
-                <Label Grid.Row="5" Grid.Column="1" Style="{StaticResource SettingsText}">Width</Label>
-                <usercontrols:SizeInput Grid.Row="5" Grid.Column="2" 
+                <StackPanel Orientation="Horizontal" Margin="27 5">
+                <Label Style="{StaticResource SettingsText}">Width</Label>
+                <usercontrols:SizeInput Margin="10 0 0 0" 
                                  Size="{Binding SettingsSubViewModel.File.DefaultNewFileWidth, Mode=TwoWay}" 
                                  Width="70" Height="21" MaxSize="9999" HorizontalAlignment="Left"/>
+                </StackPanel>
 
-                <Label Grid.Row="6" Grid.Column="1" Style="{StaticResource SettingsText}">Height</Label>
-                <usercontrols:SizeInput Grid.Row="6" Grid.Column="2" 
+                <StackPanel Orientation="Horizontal" Margin="27 5">
+                    <Label Style="{StaticResource SettingsText}">Height</Label>
+                <usercontrols:SizeInput Margin="7 0 0 0"
                                  Size="{Binding SettingsSubViewModel.File.DefaultNewFileHeight, Mode=TwoWay}" 
                                  Width="70" Height="21" MaxSize="9999" HorizontalAlignment="Left"/>
+                </StackPanel>
 
-                <Label Grid.Row="7" Grid.ColumnSpan="2" Style="{StaticResource SettingsHeader}">Tools</Label>
+                <Label Style="{StaticResource SettingsHeader}">Tools</Label>
 
-                <CheckBox Grid.Row="8" Grid.Column="1" VerticalAlignment="Center"
+                <CheckBox VerticalAlignment="Center" Margin="27 5"
                     IsChecked="{Binding SettingsSubViewModel.Tools.EnableSharedToolbar}">Enable shared toolbar</CheckBox>
 
-                <Label Grid.Row="9" Grid.ColumnSpan="2" Style="{StaticResource SettingsHeader}">Automatic updates</Label>
+                <Label Style="{StaticResource SettingsHeader}">Automatic updates</Label>
 
-                <CheckBox Grid.Row="10" Grid.Column="1" VerticalAlignment="Center" IsEnabled="{Binding Path=ShowUpdateTab}"
+                <CheckBox Margin="27 5" VerticalAlignment="Center" IsEnabled="{Binding Path=ShowUpdateTab}"
                     IsChecked="{Binding SettingsSubViewModel.Update.CheckUpdatesOnStartup}">Check updates on startup</CheckBox>
 
+                <StackPanel Orientation="Horizontal" Margin="27 5">
                 <Label Grid.Row="11" Grid.Column="1" Style="{StaticResource SettingsText}">Update stream</Label>
-                <StackPanel Orientation="Horizontal" Grid.Row="11" Grid.Column="2" VerticalAlignment="Center"
+                <StackPanel Margin="5 0" Orientation="Horizontal" VerticalAlignment="Center"
                             Height="21.96" HorizontalAlignment="Left">
                 <ComboBox Width="110" IsEnabled="{Binding Path=ShowUpdateTab}"
                     ItemsSource="{Binding SettingsSubViewModel.Update.UpdateChannels}"
@@ -139,47 +124,36 @@
                        Visibility="{Binding Path=ShowUpdateTab, Converter={converters:InverseBoolToVisibilityConverter}}"
                        ToolTip="Update channels can only be changed in standalone version (downloaded from https://pixieditor.net).&#x0a;Steam and Microsoft Store versions handle updates separately."/>
                 </StackPanel>
+                </StackPanel>
 
-                <Label Grid.Row="12" Grid.ColumnSpan="2" Style="{StaticResource SettingsHeader}">Debug</Label>
-                <CheckBox Grid.Row="13" Grid.Column="1" VerticalAlignment="Center"
+                <Label Style="{StaticResource SettingsHeader}">Debug</Label>
+                <CheckBox Margin="27 5" VerticalAlignment="Center"
                     IsChecked="{Binding SettingsSubViewModel.General.IsDebugModeEnabled}">Enable Debug Mode</CheckBox>
-                <Label Grid.Row="14" Grid.Column="1" Style="{StaticResource SettingsText}" VerticalAlignment="Center">
+                <Label Margin="0 5" Style="{StaticResource SettingsText}" VerticalAlignment="Center">
                     <Hyperlink Command="{cmds:Command PixiEditor.Debug.OpenCrashReportsDirectory}" Style="{StaticResource SettingsLink}">
                         <Run Text="Open Crash Reports Directory"/>
                         <Run Text="" FontFamily="{StaticResource Feather}"/>
                     </Hyperlink>
                 </Label>
-            </Grid>
+            </StackPanel>
 
             <StackPanel Visibility="{Binding CurrentPage, Converter={converters:EqualityBoolToVisibilityConverter},
             ConverterParameter='Discord'}" Margin="15,10">
-                <Grid Tag="27">
-                    <Grid.ColumnDefinitions>
-                        <ColumnDefinition Width="15"/>
-                        <ColumnDefinition/>
-                    </Grid.ColumnDefinitions>
-                    <Grid.RowDefinitions>
-                        <RowDefinition Height="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=Tag}"/>
-                        <RowDefinition Height="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=Tag}"/>
-                        <RowDefinition Height="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=Tag}"/>
-                        <RowDefinition Height="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=Tag}"/>
-                        <RowDefinition Height="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=Tag}"/>
-                    </Grid.RowDefinitions>
-
-                    <Label Grid.Row="0" Grid.ColumnSpan="2" Style="{StaticResource SettingsHeader}">Rich Presence</Label>
-
-                    <CheckBox Grid.Row="1" Grid.Column="1" VerticalAlignment="Center"
-                    IsChecked="{Binding SettingsSubViewModel.Discord.EnableRichPresence}">Enabled</CheckBox>
-                    <CheckBox Grid.Row="2" Grid.Column="1" VerticalAlignment="Center"
-                    IsEnabled="{Binding SettingsSubViewModel.Discord.EnableRichPresence}" 
-                    IsChecked="{Binding SettingsSubViewModel.Discord.ShowDocumentName}">Show image name</CheckBox>
-                    <CheckBox Grid.Row="3" Grid.Column="1" VerticalAlignment="Center"
-                    IsEnabled="{Binding SettingsSubViewModel.Discord.EnableRichPresence}" 
-                    IsChecked="{Binding SettingsSubViewModel.Discord.ShowDocumentSize}">Show image size</CheckBox>
-                    <CheckBox Grid.Row="4" Grid.Column="1" VerticalAlignment="Center"
-                    IsEnabled="{Binding SettingsSubViewModel.Discord.EnableRichPresence}" 
-                    IsChecked="{Binding SettingsSubViewModel.Discord.ShowLayerCount}">Show layer count</CheckBox>
-                </Grid>
+                <StackPanel Orientation="Vertical">
+                    <Label Style="{StaticResource SettingsHeader}">Rich Presence</Label>
+                    
+                    <CheckBox Margin="27 5" VerticalAlignment="Center"
+                              IsChecked="{Binding SettingsSubViewModel.Discord.EnableRichPresence}">Enabled</CheckBox>
+                    <CheckBox Margin="27 5" VerticalAlignment="Center"
+                              IsEnabled="{Binding SettingsSubViewModel.Discord.EnableRichPresence}" 
+                              IsChecked="{Binding SettingsSubViewModel.Discord.ShowDocumentName}">Show image name</CheckBox>
+                    <CheckBox Margin="27 5" VerticalAlignment="Center"
+                              IsEnabled="{Binding SettingsSubViewModel.Discord.EnableRichPresence}" 
+                              IsChecked="{Binding SettingsSubViewModel.Discord.ShowDocumentSize}">Show image size</CheckBox>
+                    <CheckBox Margin="27 5" VerticalAlignment="Center"
+                              IsEnabled="{Binding SettingsSubViewModel.Discord.EnableRichPresence}" 
+                              IsChecked="{Binding SettingsSubViewModel.Discord.ShowLayerCount}">Show layer count</CheckBox>
+                </StackPanel>
                 <usercontrols:DiscordRPPreview 
                     Margin="15"
                     Width="280"
@@ -188,8 +162,9 @@
                     IsPlaying="{Binding SettingsSubViewModel.Discord.EnableRichPresence}"/>
             </StackPanel>
 
-            <Grid Visibility="{Binding CurrentPage, Converter={converters:EqualityBoolToVisibilityConverter}, ConverterParameter='Keybinds'}"
-                        Margin="10,10,10,0">
+            <Grid Height="{Binding ElementName=window, Path=Height, Converter={converters:SubtractConverter}, ConverterParameter=50}"
+                  Visibility="{Binding CurrentPage, Converter={converters:EqualityBoolToVisibilityConverter}, ConverterParameter='Keybinds'}"
+                  Margin="10,10,10,50">
                 <Grid.RowDefinitions>
                     <RowDefinition Height="Auto"/>
                     <RowDefinition Height="Auto"/>
@@ -235,6 +210,6 @@
                     </Grid.Background>
                 </Grid>
             </Grid>
-        </Grid>
+        </StackPanel>
     </DockPanel>
 </Window>

+ 31 - 3
src/PixiEditor/Views/Translator.cs

@@ -1,11 +1,13 @@
 using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
 using PixiEditor.Localization;
 
 namespace PixiEditor.Views;
 
 public class Translator : UIElement
 {
-    private static void CurrentOnOnLanguageChanged(DependencyObject obj, Language newLanguage)
+    private static void OnLanguageChanged(DependencyObject obj, Language newLanguage)
     {
         obj.SetValue(ValueProperty, new LocalizedString(GetKey(obj)).Value);
     }
@@ -20,8 +22,34 @@ public class Translator : UIElement
     {
         if (e.NewValue is string key)
         {
-            d.SetValue(ValueProperty, new LocalizedString(key).Value);
-            ILocalizationProvider.Current.OnLanguageChanged += (lang) => CurrentOnOnLanguageChanged(d, lang);
+            LocalizedString localizedString = new(key);
+            if(d is TextBox textBox)
+            {
+                textBox.SetBinding(TextBox.TextProperty, new Binding()
+                { 
+                    Path = new PropertyPath("(views:Translator.Value)"),
+                    RelativeSource = new RelativeSource(RelativeSourceMode.Self) 
+                });
+            }
+            else if (d is TextBlock textBlock)
+            {
+                textBlock.SetBinding(TextBlock.TextProperty, new Binding()
+                { 
+                    Path = new PropertyPath("(views:Translator.Value)"),
+                    RelativeSource = new RelativeSource(RelativeSourceMode.Self) 
+                });
+            }
+            else if (d is ContentControl contentControl)
+            {
+                contentControl.SetBinding(ContentControl.ContentProperty, new Binding()
+                { 
+                    Path = new PropertyPath("(views:Translator.Value)"),
+                    RelativeSource = new RelativeSource(RelativeSourceMode.Self) 
+                });
+            }
+
+            d.SetValue(ValueProperty, localizedString.Value);
+            ILocalizationProvider.Current.OnLanguageChanged += (lang) => OnLanguageChanged(d, lang);
         }
     }