From 420a9b4b8996f652bf162fedfb9dad996c9d6e82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20La=C5=A1t=C5=AFvka?= Date: Mon, 16 Sep 2024 19:18:05 +0200 Subject: [PATCH 01/17] Init --- src/Files.App/App.xaml.cs | 2 + .../Helpers/Application/AppLanguageHelper.cs | 38 +++++++++++++++++-- .../Helpers/Win32/Win32PInvoke.Consts.cs | 3 ++ .../Helpers/Win32/Win32PInvoke.Methods.cs | 13 +++++++ 4 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/Files.App/App.xaml.cs b/src/Files.App/App.xaml.cs index 083b1faab5fe..57a50c62bc2e 100644 --- a/src/Files.App/App.xaml.cs +++ b/src/Files.App/App.xaml.cs @@ -70,6 +70,8 @@ async Task ActivateAsync() var appActivationArguments = Microsoft.Windows.AppLifecycle.AppInstance.GetCurrent().GetActivatedEventArgs(); var isStartupTask = appActivationArguments.Data is Windows.ApplicationModel.Activation.IStartupTaskActivatedEventArgs; + AppLanguageHelper.UpdateTitleBar(MainWindow.Instance); + if (!isStartupTask) { // Initialize and activate MainWindow diff --git a/src/Files.App/Helpers/Application/AppLanguageHelper.cs b/src/Files.App/Helpers/Application/AppLanguageHelper.cs index 4a70d84fec66..d15c9b8574b4 100644 --- a/src/Files.App/Helpers/Application/AppLanguageHelper.cs +++ b/src/Files.App/Helpers/Application/AppLanguageHelper.cs @@ -1,8 +1,11 @@ // Copyright (c) 2024 Files Community // Licensed under the MIT License. See the LICENSE. +using Microsoft.UI.Xaml; using System.Globalization; +using System.Text.RegularExpressions; using Windows.Globalization; +using WinRT.Interop; namespace Files.App.Helpers { @@ -48,10 +51,10 @@ static AppLanguageHelper() // Set the system default language as the first item in the Languages collection var systemLanguage = new AppLanguageItem(CultureInfo.InstalledUICulture.Name, systemDefault: true); - if (appLanguages.Select(lang => lang.Name.Contains(systemLanguage.Name)).Any()) - appLanguages[0] = systemLanguage; - else - appLanguages[0] = new("en-US", systemDefault: true); + + appLanguages[0] = appLanguages.Select(lang => lang.Name.Contains(systemLanguage.Name)).Any() + ? systemLanguage + : new("en-US", systemDefault: true); // Initialize the list SupportedLanguages = new(appLanguages); @@ -104,5 +107,32 @@ public static bool TryChange(string code) ApplicationLanguages.PrimaryLanguageOverride = index == 0 ? _defaultCode : PreferredLanguage.Code; return true; } + + /// + /// Updates the title bar layout of the specified window based on the current culture. + /// + /// The window to be updated. + /// True if the update was successful; otherwise, false. + public static bool UpdateTitleBar(Window window) + { + try + { + var hwnd = WindowNative.GetWindowHandle(window); + var exStyle = Win32PInvoke.GetWindowLongPtr(hwnd, Win32PInvoke.GWL_EXSTYLE); + + exStyle = new CultureInfo(PreferredLanguage.Code).TextInfo.IsRightToLeft + ? new IntPtr(exStyle.ToInt64() | Win32PInvoke.WS_EX_LAYOUTRTL) // Set RTL layout + : new IntPtr(exStyle.ToInt64() & ~Win32PInvoke.WS_EX_LAYOUTRTL); // Set LTR layout + + if (Win32PInvoke.SetWindowLongPtr(hwnd, Win32PInvoke.GWL_EXSTYLE, exStyle) == 0) + return false; + } + catch (Exception) + { + return false; + } + + return true; + } } } diff --git a/src/Files.App/Helpers/Win32/Win32PInvoke.Consts.cs b/src/Files.App/Helpers/Win32/Win32PInvoke.Consts.cs index f1a573124ce9..76a85614e843 100644 --- a/src/Files.App/Helpers/Win32/Win32PInvoke.Consts.cs +++ b/src/Files.App/Helpers/Win32/Win32PInvoke.Consts.cs @@ -67,5 +67,8 @@ public static partial class Win32PInvoke public const string LOCALE_NAME_USER_DEFAULT = null; public const string LOCALE_NAME_INVARIANT = ""; public const string LOCALE_NAME_SYSTEM_DEFAULT = "!sys-default-locale"; + + public const int GWL_EXSTYLE = -20; + public const int WS_EX_LAYOUTRTL = 0x00400000; } } diff --git a/src/Files.App/Helpers/Win32/Win32PInvoke.Methods.cs b/src/Files.App/Helpers/Win32/Win32PInvoke.Methods.cs index 092e07a69af4..3d8fcbc4287a 100644 --- a/src/Files.App/Helpers/Win32/Win32PInvoke.Methods.cs +++ b/src/Files.App/Helpers/Win32/Win32PInvoke.Methods.cs @@ -104,6 +104,19 @@ public static extern IntPtr SetWindowLongPtr64( IntPtr dwNewLong ); + [DllImport("user32.dll", SetLastError = true)] + public static extern IntPtr SetWindowLongPtr( + HWND hWnd, + int nIndex, + IntPtr dwNewLong + ); + + [DllImport("user32.dll", SetLastError = true)] + public static extern IntPtr GetWindowLongPtr( + HWND hWnd, + int nIndex + ); + [DllImport("shell32.dll")] public static extern IntPtr SHBrowseForFolder( ref BROWSEINFO lpbi From 956f9d3bf2e805b28433628a6b9776cdc23c7a58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20La=C5=A1t=C5=AFvka?= Date: Tue, 17 Sep 2024 12:45:45 +0200 Subject: [PATCH 02/17] CQ: Adding testing methods --- src/Files.App/App.xaml.cs | 2 -- .../Helpers/Application/AppLanguageHelper.cs | 19 ++++++++++++++++++- src/Files.App/MainWindow.xaml.cs | 4 ++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/Files.App/App.xaml.cs b/src/Files.App/App.xaml.cs index 57a50c62bc2e..083b1faab5fe 100644 --- a/src/Files.App/App.xaml.cs +++ b/src/Files.App/App.xaml.cs @@ -70,8 +70,6 @@ async Task ActivateAsync() var appActivationArguments = Microsoft.Windows.AppLifecycle.AppInstance.GetCurrent().GetActivatedEventArgs(); var isStartupTask = appActivationArguments.Data is Windows.ApplicationModel.Activation.IStartupTaskActivatedEventArgs; - AppLanguageHelper.UpdateTitleBar(MainWindow.Instance); - if (!isStartupTask) { // Initialize and activate MainWindow diff --git a/src/Files.App/Helpers/Application/AppLanguageHelper.cs b/src/Files.App/Helpers/Application/AppLanguageHelper.cs index d15c9b8574b4..6e1f25e98b39 100644 --- a/src/Files.App/Helpers/Application/AppLanguageHelper.cs +++ b/src/Files.App/Helpers/Application/AppLanguageHelper.cs @@ -30,6 +30,8 @@ public static class AppLanguageHelper /// public static AppLanguageItem PreferredLanguage { get; private set; } + public static CultureInfo PreferredCulture => new(PreferredLanguage.Code); + /// /// Initializes the class. /// @@ -120,7 +122,7 @@ public static bool UpdateTitleBar(Window window) var hwnd = WindowNative.GetWindowHandle(window); var exStyle = Win32PInvoke.GetWindowLongPtr(hwnd, Win32PInvoke.GWL_EXSTYLE); - exStyle = new CultureInfo(PreferredLanguage.Code).TextInfo.IsRightToLeft + exStyle = PreferredCulture.TextInfo.IsRightToLeft ? new IntPtr(exStyle.ToInt64() | Win32PInvoke.WS_EX_LAYOUTRTL) // Set RTL layout : new IntPtr(exStyle.ToInt64() & ~Win32PInvoke.WS_EX_LAYOUTRTL); // Set LTR layout @@ -134,5 +136,20 @@ public static bool UpdateTitleBar(Window window) return true; } + + public static void UpdateContextLayout(FrameworkElement element) + { + element.FlowDirection = PreferredCulture.TextInfo.IsRightToLeft ? FlowDirection.RightToLeft : FlowDirection.LeftToRight; + } + + public static bool SetCultureLayout(Window window) + { + var res = UpdateTitleBar(window); + if (!res) + return res; + if (window.Content is FrameworkElement element) + UpdateContextLayout(element); + return res; + } } } diff --git a/src/Files.App/MainWindow.xaml.cs b/src/Files.App/MainWindow.xaml.cs index 34f4aed86bb6..0a43382e1539 100644 --- a/src/Files.App/MainWindow.xaml.cs +++ b/src/Files.App/MainWindow.xaml.cs @@ -36,6 +36,8 @@ public void ShowSplashScreen() var rootFrame = EnsureWindowIsInitialized(); rootFrame?.Navigate(typeof(SplashScreenPage)); + + AppLanguageHelper.UpdateTitleBar(Instance); } public async Task InitializeApplicationAsync(object activatedEventArgs) @@ -191,6 +193,8 @@ public async Task InitializeApplicationAsync(object activatedEventArgs) if (Windows.Win32.PInvoke.IsIconic(new(WindowHandle)) && AppWindow.Presenter is OverlappedPresenter presenter) presenter.Restore(); // Restore window if minimized + + AppLanguageHelper.UpdateContextLayout(rootFrame); } private Frame? EnsureWindowIsInitialized() From bc36808f229ab41a12a1469d3977965b91bf50ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20La=C5=A1t=C5=AFvka?= Date: Sun, 17 Nov 2024 20:41:15 +0100 Subject: [PATCH 03/17] CQ: Change to Win32 --- src/Files.App.CsWin32/NativeMethods.txt | 2 ++ .../Helpers/Application/AppLanguageHelper.cs | 13 +++++---- .../Helpers/Win32/Win32PInvoke.Consts.cs | 5 +--- .../Helpers/Win32/Win32PInvoke.Methods.cs | 29 +------------------ 4 files changed, 12 insertions(+), 37 deletions(-) diff --git a/src/Files.App.CsWin32/NativeMethods.txt b/src/Files.App.CsWin32/NativeMethods.txt index 3b611b024af5..72c18b60ebf5 100644 --- a/src/Files.App.CsWin32/NativeMethods.txt +++ b/src/Files.App.CsWin32/NativeMethods.txt @@ -156,3 +156,5 @@ IApplicationDestinations ApplicationDestinations IApplicationDocumentLists ApplicationDocumentLists +SetWindowLongPtr +GetWindowLongPtr \ No newline at end of file diff --git a/src/Files.App/Helpers/Application/AppLanguageHelper.cs b/src/Files.App/Helpers/Application/AppLanguageHelper.cs index 6e1f25e98b39..be093e5bbfff 100644 --- a/src/Files.App/Helpers/Application/AppLanguageHelper.cs +++ b/src/Files.App/Helpers/Application/AppLanguageHelper.cs @@ -6,6 +6,9 @@ using System.Text.RegularExpressions; using Windows.Globalization; using WinRT.Interop; +using Windows.Win32; +using Windows.Win32.Foundation; +using Windows.Win32.UI.WindowsAndMessaging; namespace Files.App.Helpers { @@ -119,14 +122,14 @@ public static bool UpdateTitleBar(Window window) { try { - var hwnd = WindowNative.GetWindowHandle(window); - var exStyle = Win32PInvoke.GetWindowLongPtr(hwnd, Win32PInvoke.GWL_EXSTYLE); + var hwnd = new HWND(WindowNative.GetWindowHandle(window)); + var exStyle = PInvoke.GetWindowLongPtr(hwnd, WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE); exStyle = PreferredCulture.TextInfo.IsRightToLeft - ? new IntPtr(exStyle.ToInt64() | Win32PInvoke.WS_EX_LAYOUTRTL) // Set RTL layout - : new IntPtr(exStyle.ToInt64() & ~Win32PInvoke.WS_EX_LAYOUTRTL); // Set LTR layout + ? new IntPtr((uint)exStyle | (uint)WINDOW_EX_STYLE.WS_EX_LAYOUTRTL) // Set RTL layout + : new IntPtr((uint)exStyle.ToInt64() & ~(uint)WINDOW_EX_STYLE.WS_EX_LAYOUTRTL); // Set LTR layout - if (Win32PInvoke.SetWindowLongPtr(hwnd, Win32PInvoke.GWL_EXSTYLE, exStyle) == 0) + if (PInvoke.SetWindowLongPtr(hwnd, WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE, exStyle) == 0) return false; } catch (Exception) diff --git a/src/Files.App/Helpers/Win32/Win32PInvoke.Consts.cs b/src/Files.App/Helpers/Win32/Win32PInvoke.Consts.cs index 76a85614e843..78bcac1db5da 100644 --- a/src/Files.App/Helpers/Win32/Win32PInvoke.Consts.cs +++ b/src/Files.App/Helpers/Win32/Win32PInvoke.Consts.cs @@ -67,8 +67,5 @@ public static partial class Win32PInvoke public const string LOCALE_NAME_USER_DEFAULT = null; public const string LOCALE_NAME_INVARIANT = ""; public const string LOCALE_NAME_SYSTEM_DEFAULT = "!sys-default-locale"; - - public const int GWL_EXSTYLE = -20; - public const int WS_EX_LAYOUTRTL = 0x00400000; } -} +} \ No newline at end of file diff --git a/src/Files.App/Helpers/Win32/Win32PInvoke.Methods.cs b/src/Files.App/Helpers/Win32/Win32PInvoke.Methods.cs index 03eb80b75775..8f4cacd992b1 100644 --- a/src/Files.App/Helpers/Win32/Win32PInvoke.Methods.cs +++ b/src/Files.App/Helpers/Win32/Win32PInvoke.Methods.cs @@ -90,33 +90,6 @@ public static extern uint CoWaitForMultipleObjects( out uint dwIndex ); - [DllImport("user32.dll", SetLastError = true, EntryPoint = "SetWindowLong")] - public static extern int SetWindowLongPtr32( - HWND hWnd, - WindowLongFlags nIndex, - IntPtr dwNewLong - ); - - [DllImport("user32.dll", SetLastError = true, EntryPoint = "SetWindowLongPtr")] - public static extern IntPtr SetWindowLongPtr64( - HWND hWnd, - WindowLongFlags nIndex, - IntPtr dwNewLong - ); - - [DllImport("user32.dll", SetLastError = true)] - public static extern IntPtr SetWindowLongPtr( - HWND hWnd, - int nIndex, - IntPtr dwNewLong - ); - - [DllImport("user32.dll", SetLastError = true)] - public static extern IntPtr GetWindowLongPtr( - HWND hWnd, - int nIndex - ); - [DllImport("shell32.dll")] public static extern IntPtr SHBrowseForFolder( ref BROWSEINFO lpbi @@ -521,4 +494,4 @@ out IntPtr pszPath [DllImport("shell32.dll", EntryPoint = "SHUpdateRecycleBinIcon", CharSet = CharSet.Unicode, SetLastError = true)] public static extern void SHUpdateRecycleBinIcon(); } -} +} \ No newline at end of file From 0987b0f116dd1cf002a91d1de4c0af71f9c02da3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20La=C5=A1t=C5=AFvka?= Date: Mon, 18 Nov 2024 09:30:19 +0100 Subject: [PATCH 04/17] CQ: Add to settings page --- src/Files.App/Dialogs/SettingsDialog.xaml.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Files.App/Dialogs/SettingsDialog.xaml.cs b/src/Files.App/Dialogs/SettingsDialog.xaml.cs index e70582a22432..c63a46bc62b8 100644 --- a/src/Files.App/Dialogs/SettingsDialog.xaml.cs +++ b/src/Files.App/Dialogs/SettingsDialog.xaml.cs @@ -24,6 +24,7 @@ public SettingsDialog() InitializeComponent(); MainWindow.Instance.SizeChanged += Current_SizeChanged; + AppLanguageHelper.UpdateContextLayout(this); UpdateDialogLayout(); } From c08abde58f1a92f8b613a6ccdb41a3dceeff314a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20La=C5=A1t=C5=AFvka?= Date: Mon, 18 Nov 2024 09:35:24 +0100 Subject: [PATCH 05/17] CQ: Comments --- src/Files.App/Helpers/Application/AppLanguageHelper.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Files.App/Helpers/Application/AppLanguageHelper.cs b/src/Files.App/Helpers/Application/AppLanguageHelper.cs index be093e5bbfff..ddfdfb309d80 100644 --- a/src/Files.App/Helpers/Application/AppLanguageHelper.cs +++ b/src/Files.App/Helpers/Application/AppLanguageHelper.cs @@ -12,6 +12,7 @@ namespace Files.App.Helpers { + // TODO: Replaced by RealTime Resources in the future /// /// Provides static helper to manage supported languages in the application. /// @@ -113,6 +114,7 @@ public static bool TryChange(string code) return true; } + // TODO: Replaced by RealTime Resources in the future /// /// Updates the title bar layout of the specified window based on the current culture. /// @@ -140,11 +142,13 @@ public static bool UpdateTitleBar(Window window) return true; } + // TODO: Replaced by RealTime Resources in the future public static void UpdateContextLayout(FrameworkElement element) { element.FlowDirection = PreferredCulture.TextInfo.IsRightToLeft ? FlowDirection.RightToLeft : FlowDirection.LeftToRight; } + // TODO: Replaced by RealTime Resources in the future public static bool SetCultureLayout(Window window) { var res = UpdateTitleBar(window); From 7b191a0a79ec07c21b231b46374ddaca6c2193aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20La=C5=A1t=C5=AFvka?= Date: Mon, 18 Nov 2024 10:00:20 +0100 Subject: [PATCH 06/17] CQ: Correct SideBar manipulation --- src/Files.App/Helpers/Application/AppLanguageHelper.cs | 4 +++- src/Files.App/UserControls/Sidebar/SidebarView.xaml.cs | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Files.App/Helpers/Application/AppLanguageHelper.cs b/src/Files.App/Helpers/Application/AppLanguageHelper.cs index ddfdfb309d80..f9a9e819c8e0 100644 --- a/src/Files.App/Helpers/Application/AppLanguageHelper.cs +++ b/src/Files.App/Helpers/Application/AppLanguageHelper.cs @@ -36,6 +36,8 @@ public static class AppLanguageHelper public static CultureInfo PreferredCulture => new(PreferredLanguage.Code); + public static FlowDirection FlowDirection => PreferredCulture.TextInfo.IsRightToLeft ? FlowDirection.RightToLeft : FlowDirection.LeftToRight; + /// /// Initializes the class. /// @@ -145,7 +147,7 @@ public static bool UpdateTitleBar(Window window) // TODO: Replaced by RealTime Resources in the future public static void UpdateContextLayout(FrameworkElement element) { - element.FlowDirection = PreferredCulture.TextInfo.IsRightToLeft ? FlowDirection.RightToLeft : FlowDirection.LeftToRight; + element.FlowDirection = FlowDirection; } // TODO: Replaced by RealTime Resources in the future diff --git a/src/Files.App/UserControls/Sidebar/SidebarView.xaml.cs b/src/Files.App/UserControls/Sidebar/SidebarView.xaml.cs index 0fc4c3bf2674..5e4d69516ebb 100644 --- a/src/Files.App/UserControls/Sidebar/SidebarView.xaml.cs +++ b/src/Files.App/UserControls/Sidebar/SidebarView.xaml.cs @@ -130,7 +130,8 @@ private void SidebarResizer_ManipulationStarted(object sender, ManipulationStart private void SidebarResizer_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e) { - var newWidth = preManipulationSidebarWidth + e.Cumulative.Translation.X; + var rePos = AppLanguageHelper.FlowDirection == FlowDirection.LeftToRight ? 1 : -1; + var newWidth = preManipulationSidebarWidth + (e.Cumulative.Translation.X * rePos); UpdateDisplayModeForPaneWidth(newWidth); e.Handled = true; } From ad9374866d4f162befd361555c1652fadcf68586 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20La=C5=A1t=C5=AFvka?= Date: Mon, 18 Nov 2024 10:00:20 +0100 Subject: [PATCH 07/17] CQ: Correct SideBar manipulation --- src/Files.App/Helpers/Application/AppLanguageHelper.cs | 4 +++- src/Files.App/UserControls/Sidebar/SidebarView.xaml.cs | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Files.App/Helpers/Application/AppLanguageHelper.cs b/src/Files.App/Helpers/Application/AppLanguageHelper.cs index ddfdfb309d80..f9a9e819c8e0 100644 --- a/src/Files.App/Helpers/Application/AppLanguageHelper.cs +++ b/src/Files.App/Helpers/Application/AppLanguageHelper.cs @@ -36,6 +36,8 @@ public static class AppLanguageHelper public static CultureInfo PreferredCulture => new(PreferredLanguage.Code); + public static FlowDirection FlowDirection => PreferredCulture.TextInfo.IsRightToLeft ? FlowDirection.RightToLeft : FlowDirection.LeftToRight; + /// /// Initializes the class. /// @@ -145,7 +147,7 @@ public static bool UpdateTitleBar(Window window) // TODO: Replaced by RealTime Resources in the future public static void UpdateContextLayout(FrameworkElement element) { - element.FlowDirection = PreferredCulture.TextInfo.IsRightToLeft ? FlowDirection.RightToLeft : FlowDirection.LeftToRight; + element.FlowDirection = FlowDirection; } // TODO: Replaced by RealTime Resources in the future diff --git a/src/Files.App/UserControls/Sidebar/SidebarView.xaml.cs b/src/Files.App/UserControls/Sidebar/SidebarView.xaml.cs index 0fc4c3bf2674..7c08045a3a8e 100644 --- a/src/Files.App/UserControls/Sidebar/SidebarView.xaml.cs +++ b/src/Files.App/UserControls/Sidebar/SidebarView.xaml.cs @@ -130,7 +130,8 @@ private void SidebarResizer_ManipulationStarted(object sender, ManipulationStart private void SidebarResizer_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e) { - var newWidth = preManipulationSidebarWidth + e.Cumulative.Translation.X; + var rePos = AppLanguageHelper.FlowDirection == FlowDirection.LeftToRight ? 1 : -1; + var newWidth = preManipulationSidebarWidth + (e.Cumulative.Translation.X * rePos); UpdateDisplayModeForPaneWidth(newWidth); e.Handled = true; } @@ -159,11 +160,13 @@ private void SidebarResizerControl_KeyDown(object sender, KeyRoutedEventArgs e) var ctrl = InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Control); var increment = ctrl.HasFlag(CoreVirtualKeyStates.Down) ? 5 : 1; + var rePos = AppLanguageHelper.FlowDirection == FlowDirection.LeftToRight ? 1 : -1; + // Left makes the pane smaller so we invert the increment if (e.Key == VirtualKey.Left) increment = -increment; - var newWidth = OpenPaneLength + increment; + var newWidth = OpenPaneLength + (increment * rePos); UpdateDisplayModeForPaneWidth(newWidth); e.Handled = true; return; From f5733bae4972e08e15ce55290b3425a04e5ee53a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20La=C5=A1t=C5=AFvka?= Date: Mon, 18 Nov 2024 11:37:06 +0100 Subject: [PATCH 08/17] CQ: Fix `TitleBarDragRegion` --- src/Files.App/Views/MainPage.xaml.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Files.App/Views/MainPage.xaml.cs b/src/Files.App/Views/MainPage.xaml.cs index 55b9a425aaa8..6b68eb8918ca 100644 --- a/src/Files.App/Views/MainPage.xaml.cs +++ b/src/Files.App/Views/MainPage.xaml.cs @@ -138,7 +138,11 @@ private void HorizontalMultitaskingControl_Loaded(object sender, RoutedEventArgs private int SetTitleBarDragRegion(InputNonClientPointerSource source, SizeInt32 size, double scaleFactor, Func getScaledRect) { var height = (int)TabControl.ActualHeight; - source.SetRegionRects(NonClientRegionKind.Passthrough, [getScaledRect(this, new RectInt32(0, 0, (int)(TabControl.ActualWidth + TabControl.Margin.Left - TabControl.DragArea.ActualWidth), height))]); + + var x = AppLanguageHelper.FlowDirection == FlowDirection.LeftToRight ? 0 : (int)TabControl.DragArea.ActualWidth; + var width = (int)(TabControl.ActualWidth + TabControl.Margin.Left - TabControl.DragArea.ActualWidth); + + source.SetRegionRects(NonClientRegionKind.Passthrough, [getScaledRect(this, new RectInt32(x, 0, width, height))]); return height; } From 5bef3476efced732cef3ac2b7e66b8f53f107397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20La=C5=A1t=C5=AFvka?= Date: Mon, 18 Nov 2024 13:08:30 +0100 Subject: [PATCH 09/17] CQ: Dialog fix --- src/Files.App/Dialogs/AddBranchDialog.xaml.cs | 1 + src/Files.App/Dialogs/AddItemDialog.xaml.cs | 1 + .../Dialogs/BulkRenameDialog.xaml.cs | 1 + .../Dialogs/CreateArchiveDialog.xaml.cs | 1 + .../Dialogs/CreateShortcutDialog.xaml.cs | 1 + .../Dialogs/CredentialDialog.xaml.cs | 1 + .../Dialogs/DecompressArchiveDialog.xaml.cs | 1 + src/Files.App/Dialogs/DynamicDialog.xaml.cs | 1 + .../Dialogs/ElevateConfirmDialog.xaml.cs | 1 + .../Dialogs/FileTooLargeDialog.xaml.cs | 1 + .../Dialogs/FilesystemOperationDialog.xaml.cs | 1 + .../Dialogs/GitHubLoginDialog.xaml.cs | 1 + .../Dialogs/ReleaseNotesDialog.xaml.cs | 1 + .../Dialogs/ReorderSidebarItemsDialog.xaml.cs | 1 + src/Files.App/Helpers/FlowDirectionHelper.cs | 43 +++++++++++++++++++ .../Properties/MainPropertiesPage.xaml.cs | 2 + 16 files changed, 59 insertions(+) create mode 100644 src/Files.App/Helpers/FlowDirectionHelper.cs diff --git a/src/Files.App/Dialogs/AddBranchDialog.xaml.cs b/src/Files.App/Dialogs/AddBranchDialog.xaml.cs index 0087cbab901b..a35c339bc8b3 100644 --- a/src/Files.App/Dialogs/AddBranchDialog.xaml.cs +++ b/src/Files.App/Dialogs/AddBranchDialog.xaml.cs @@ -21,6 +21,7 @@ public AddBranchDialogViewModel ViewModel public AddBranchDialog() { InitializeComponent(); + AppLanguageHelper.UpdateContextLayout(this); } public new async Task ShowAsync() => (DialogResult)await base.ShowAsync(); diff --git a/src/Files.App/Dialogs/AddItemDialog.xaml.cs b/src/Files.App/Dialogs/AddItemDialog.xaml.cs index 938f17d42495..4033cb52c3d3 100644 --- a/src/Files.App/Dialogs/AddItemDialog.xaml.cs +++ b/src/Files.App/Dialogs/AddItemDialog.xaml.cs @@ -24,6 +24,7 @@ public AddItemDialogViewModel ViewModel public AddItemDialog() { InitializeComponent(); + AppLanguageHelper.UpdateContextLayout(this); } public new async Task ShowAsync() diff --git a/src/Files.App/Dialogs/BulkRenameDialog.xaml.cs b/src/Files.App/Dialogs/BulkRenameDialog.xaml.cs index a7f5b5478b65..f442aeda3b89 100644 --- a/src/Files.App/Dialogs/BulkRenameDialog.xaml.cs +++ b/src/Files.App/Dialogs/BulkRenameDialog.xaml.cs @@ -19,6 +19,7 @@ public BulkRenameDialogViewModel ViewModel public BulkRenameDialog() { InitializeComponent(); + AppLanguageHelper.UpdateContextLayout(this); } public new async Task ShowAsync() diff --git a/src/Files.App/Dialogs/CreateArchiveDialog.xaml.cs b/src/Files.App/Dialogs/CreateArchiveDialog.xaml.cs index f54d0227afbc..fc58041cc3c0 100644 --- a/src/Files.App/Dialogs/CreateArchiveDialog.xaml.cs +++ b/src/Files.App/Dialogs/CreateArchiveDialog.xaml.cs @@ -65,6 +65,7 @@ public CreateArchiveDialog() InitializeComponent(); ViewModel.PropertyChanged += ViewModel_PropertyChanged; + AppLanguageHelper.UpdateContextLayout(this); } public new Task ShowAsync() diff --git a/src/Files.App/Dialogs/CreateShortcutDialog.xaml.cs b/src/Files.App/Dialogs/CreateShortcutDialog.xaml.cs index 09cd2f963e9f..1d5d88183573 100644 --- a/src/Files.App/Dialogs/CreateShortcutDialog.xaml.cs +++ b/src/Files.App/Dialogs/CreateShortcutDialog.xaml.cs @@ -29,6 +29,7 @@ public CreateShortcutDialog() { Source = ShortcutTarget }); + AppLanguageHelper.UpdateContextLayout(this); } private void CreateShortcutDialog_Closing(ContentDialog sender, ContentDialogClosingEventArgs args) diff --git a/src/Files.App/Dialogs/CredentialDialog.xaml.cs b/src/Files.App/Dialogs/CredentialDialog.xaml.cs index 92ba79ba03c5..c0fa59e38bf7 100644 --- a/src/Files.App/Dialogs/CredentialDialog.xaml.cs +++ b/src/Files.App/Dialogs/CredentialDialog.xaml.cs @@ -21,6 +21,7 @@ public CredentialDialogViewModel ViewModel public CredentialDialog() { InitializeComponent(); + AppLanguageHelper.UpdateContextLayout(this); } public new async Task ShowAsync() diff --git a/src/Files.App/Dialogs/DecompressArchiveDialog.xaml.cs b/src/Files.App/Dialogs/DecompressArchiveDialog.xaml.cs index 7a4543fd8476..748bbce6a294 100644 --- a/src/Files.App/Dialogs/DecompressArchiveDialog.xaml.cs +++ b/src/Files.App/Dialogs/DecompressArchiveDialog.xaml.cs @@ -22,6 +22,7 @@ public DecompressArchiveDialogViewModel ViewModel public DecompressArchiveDialog() { InitializeComponent(); + AppLanguageHelper.UpdateContextLayout(this); } private void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args) diff --git a/src/Files.App/Dialogs/DynamicDialog.xaml.cs b/src/Files.App/Dialogs/DynamicDialog.xaml.cs index fe0f628440a7..fd3788f5f7de 100644 --- a/src/Files.App/Dialogs/DynamicDialog.xaml.cs +++ b/src/Files.App/Dialogs/DynamicDialog.xaml.cs @@ -34,6 +34,7 @@ public DynamicDialog(DynamicDialogViewModel dynamicDialogViewModel) dynamicDialogViewModel.HideDialog = Hide; ViewModel = dynamicDialogViewModel; + AppLanguageHelper.UpdateContextLayout(this); } private void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args) diff --git a/src/Files.App/Dialogs/ElevateConfirmDialog.xaml.cs b/src/Files.App/Dialogs/ElevateConfirmDialog.xaml.cs index 924602ce2b3d..a51822b71d1a 100644 --- a/src/Files.App/Dialogs/ElevateConfirmDialog.xaml.cs +++ b/src/Files.App/Dialogs/ElevateConfirmDialog.xaml.cs @@ -23,6 +23,7 @@ public ElevateConfirmDialogViewModel ViewModel public ElevateConfirmDialog() { InitializeComponent(); + AppLanguageHelper.UpdateContextLayout(this); } public new async Task ShowAsync() diff --git a/src/Files.App/Dialogs/FileTooLargeDialog.xaml.cs b/src/Files.App/Dialogs/FileTooLargeDialog.xaml.cs index 4daf884822b9..9dc0bb93fdb9 100644 --- a/src/Files.App/Dialogs/FileTooLargeDialog.xaml.cs +++ b/src/Files.App/Dialogs/FileTooLargeDialog.xaml.cs @@ -20,6 +20,7 @@ public FileTooLargeDialogViewModel ViewModel public FileTooLargeDialog() { InitializeComponent(); + AppLanguageHelper.UpdateContextLayout(this); } public new async Task ShowAsync() diff --git a/src/Files.App/Dialogs/FilesystemOperationDialog.xaml.cs b/src/Files.App/Dialogs/FilesystemOperationDialog.xaml.cs index 9760cfa332dd..a9984e9bea6a 100644 --- a/src/Files.App/Dialogs/FilesystemOperationDialog.xaml.cs +++ b/src/Files.App/Dialogs/FilesystemOperationDialog.xaml.cs @@ -32,6 +32,7 @@ public FilesystemOperationDialog() InitializeComponent(); MainWindow.Instance.SizeChanged += Current_SizeChanged; + AppLanguageHelper.UpdateContextLayout(this); } public new async Task ShowAsync() diff --git a/src/Files.App/Dialogs/GitHubLoginDialog.xaml.cs b/src/Files.App/Dialogs/GitHubLoginDialog.xaml.cs index 973909dec988..dfc13fcd1a53 100644 --- a/src/Files.App/Dialogs/GitHubLoginDialog.xaml.cs +++ b/src/Files.App/Dialogs/GitHubLoginDialog.xaml.cs @@ -29,6 +29,7 @@ public GitHubLoginDialogViewModel ViewModel public GitHubLoginDialog() { InitializeComponent(); + AppLanguageHelper.UpdateContextLayout(this); } public new async Task ShowAsync() diff --git a/src/Files.App/Dialogs/ReleaseNotesDialog.xaml.cs b/src/Files.App/Dialogs/ReleaseNotesDialog.xaml.cs index d5aae7b549ea..adccfb25585c 100644 --- a/src/Files.App/Dialogs/ReleaseNotesDialog.xaml.cs +++ b/src/Files.App/Dialogs/ReleaseNotesDialog.xaml.cs @@ -23,6 +23,7 @@ public ReleaseNotesDialog() InitializeComponent(); MainWindow.Instance.SizeChanged += Current_SizeChanged; + AppLanguageHelper.UpdateContextLayout(this); UpdateDialogLayout(); } diff --git a/src/Files.App/Dialogs/ReorderSidebarItemsDialog.xaml.cs b/src/Files.App/Dialogs/ReorderSidebarItemsDialog.xaml.cs index 598d1da9edf6..9ccbe90915f4 100644 --- a/src/Files.App/Dialogs/ReorderSidebarItemsDialog.xaml.cs +++ b/src/Files.App/Dialogs/ReorderSidebarItemsDialog.xaml.cs @@ -29,6 +29,7 @@ public ReorderSidebarItemsDialogViewModel ViewModel public ReorderSidebarItemsDialog() { InitializeComponent(); + AppLanguageHelper.UpdateContextLayout(this); } private async void MoveItemAsync(object sender, PointerRoutedEventArgs e) diff --git a/src/Files.App/Helpers/FlowDirectionHelper.cs b/src/Files.App/Helpers/FlowDirectionHelper.cs new file mode 100644 index 000000000000..6846e28e4c71 --- /dev/null +++ b/src/Files.App/Helpers/FlowDirectionHelper.cs @@ -0,0 +1,43 @@ +using Microsoft.UI.Xaml; + +namespace Files.App.Helpers +{ + public static class FlowDirectionHelper + { + public static bool GetForceLeftToRight(DependencyObject obj) + => (bool)obj.GetValue(ForceLeftToRightProperty); + + public static void SetForceLeftToRight(DependencyObject obj, bool value) + => obj.SetValue(ForceLeftToRightProperty, value); + + public static readonly DependencyProperty ForceLeftToRightProperty = + DependencyProperty.RegisterAttached( + "ForceLeftToRight", + typeof(bool), + typeof(FlowDirectionHelper), + new PropertyMetadata(false, OnForceLeftToRightChanged)); + + private static void OnForceLeftToRightChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d is FrameworkElement element) + { + // Pokud je ForceLeftToRight true, nastavíme FlowDirection na LeftToRight + if ((bool)e.NewValue) + { + element.FlowDirection = FlowDirection.LeftToRight; + + // Přidáme event handler pro změny FlowDirection + _ = element.RegisterPropertyChangedCallback( + FrameworkElement.FlowDirectionProperty, + (sender, dp) => + { + if (GetForceLeftToRight(element)) + { + element.FlowDirection = FlowDirection.LeftToRight; + } + }); + } + } + } + } +} diff --git a/src/Files.App/Views/Properties/MainPropertiesPage.xaml.cs b/src/Files.App/Views/Properties/MainPropertiesPage.xaml.cs index 1b00d63022cc..1bcc3ce754c1 100644 --- a/src/Files.App/Views/Properties/MainPropertiesPage.xaml.cs +++ b/src/Files.App/Views/Properties/MainPropertiesPage.xaml.cs @@ -65,6 +65,8 @@ private void Page_Loaded(object sender, RoutedEventArgs e) UpdatePageLayout(); Window.RaiseSetTitleBarDragRegion(SetTitleBarDragRegion); Window.AppWindow.Changed += AppWindow_Changed; + + AppLanguageHelper.SetCultureLayout(Window); } private int SetTitleBarDragRegion(InputNonClientPointerSource source, SizeInt32 size, double scaleFactor, Func getScaledRect) From 6409c4cbaf22859e91082af0863f84e8ca16ae7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20La=C5=A1t=C5=AFvka?= Date: Mon, 18 Nov 2024 13:08:54 +0100 Subject: [PATCH 10/17] CQ: Reverse arrows --- .../UserControls/AddressToolbar.xaml | 133 ++++++++++-------- 1 file changed, 76 insertions(+), 57 deletions(-) diff --git a/src/Files.App/UserControls/AddressToolbar.xaml b/src/Files.App/UserControls/AddressToolbar.xaml index fcf48e0c9648..973aa4c5a97c 100644 --- a/src/Files.App/UserControls/AddressToolbar.xaml +++ b/src/Files.App/UserControls/AddressToolbar.xaml @@ -263,63 +263,68 @@ - - - + + + + +