diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index 211bc1798..d42fd425f 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -199,7 +199,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings } public bool LeaveCmdOpen { get; set; } public bool HideWhenDeactive { get; set; } = true; - public bool RememberLastLaunchLocation { get; set; } + public SearchWindowPositions SearchWindowPosition { get; set; } = SearchWindowPositions.MouseScreenCenter; public bool IgnoreHotkeysOnFullscreen { get; set; } public HttpProxy Proxy { get; set; } = new HttpProxy(); @@ -225,4 +225,12 @@ namespace Flow.Launcher.Infrastructure.UserSettings Light, Dark } + public enum SearchWindowPositions + { + RememberLastLaunchLocation, + MouseScreenCenter, + MouseScreenCenterTop, + MouseScreenLeftTop, + MouseScreenRightTop + } } diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 824201f7d..4a0841940 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -23,6 +23,8 @@ Text Game Mode Suspend the use of Hotkeys. + Position Reset + Reset search window position Flow Launcher Settings @@ -33,7 +35,13 @@ Error setting launch on startup Hide Flow Launcher when focus is lost Do not show new version notifications + Search Window Position Remember last launch location + Remember Last Location + Mouse Focused Screen - Center + Mouse Focused Screen - Center Top + Mouse Focused Screen - Left Top + Mouse Focused Screen - Right Top Language Last Query Style Show/Hide previous results when Flow Launcher is reactivated. diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml index cc605edc9..9f7d16ab1 100644 --- a/Flow.Launcher/MainWindow.xaml +++ b/Flow.Launcher/MainWindow.xaml @@ -32,9 +32,7 @@ Visibility="{Binding MainWindowVisibility, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" WindowStartupLocation="Manual" WindowStyle="None" - mc:Ignorable="d" - Left="{Binding Left, Mode=TwoWay}" - Top="{Binding Top, Mode=TwoWay}"> + mc:Ignorable="d"> @@ -88,20 +86,20 @@ + Command="{Binding IncreaseWidthCommand}" + Modifiers="Control" /> + Command="{Binding DecreaseWidthCommand}" + Modifiers="Control" /> + Command="{Binding IncreaseMaxResultCommand}" + Modifiers="Control" /> + Command="{Binding DecreaseMaxResultCommand}" + Modifiers="Control" /> diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs index 1c6845623..fe6c119e1 100644 --- a/Flow.Launcher/MainWindow.xaml.cs +++ b/Flow.Launcher/MainWindow.xaml.cs @@ -46,6 +46,7 @@ namespace Flow.Launcher _viewModel = mainVM; _settings = settings; InitializeComponent(); + InitializePosition(); animationSound.Open(new Uri(AppDomain.CurrentDomain.BaseDirectory + "Resources\\open.wav")); } @@ -108,7 +109,6 @@ namespace Flow.Launcher animationSound.Position = TimeSpan.Zero; animationSound.Play(); } - UpdatePosition(); Activate(); QueryTextBox.Focus(); @@ -161,6 +161,7 @@ namespace Flow.Launcher _viewModel.QueryTextCursorMovedToEnd = false; } break; + } }; _settings.PropertyChanged += (o, e) => @@ -176,17 +177,51 @@ namespace Flow.Launcher case nameof(Settings.Hotkey): UpdateNotifyIconText(); break; + case nameof(Settings.WindowLeft): + Left = _settings.WindowLeft; + break; + case nameof(Settings.WindowTop): + Top = _settings.WindowTop; + break; } }; } + private void InitializePosition() + { + switch (_settings.SearchWindowPosition) + { + case SearchWindowPositions.RememberLastLaunchLocation: + Top = _settings.WindowTop; + Left = _settings.WindowLeft; + break; + case SearchWindowPositions.MouseScreenCenter: + Left = HorizonCenter(); + Top = VerticalCenter(); + break; + case SearchWindowPositions.MouseScreenCenterTop: + Left = HorizonCenter(); + Top = 10; + break; + case SearchWindowPositions.MouseScreenLeftTop: + Left = 10; + Top = 10; + break; + case SearchWindowPositions.MouseScreenRightTop: + Left = HorizonRight(); + Top = 10; + break; + } + } + private void UpdateNotifyIconText() { var menu = contextMenu; ((MenuItem)menu.Items[1]).Header = InternationalizationManager.Instance.GetTranslation("iconTrayOpen") + " (" + _settings.Hotkey + ")"; ((MenuItem)menu.Items[2]).Header = InternationalizationManager.Instance.GetTranslation("GameMode"); - ((MenuItem)menu.Items[3]).Header = InternationalizationManager.Instance.GetTranslation("iconTraySettings"); - ((MenuItem)menu.Items[4]).Header = InternationalizationManager.Instance.GetTranslation("iconTrayExit"); + ((MenuItem)menu.Items[3]).Header = InternationalizationManager.Instance.GetTranslation("PositionReset"); + ((MenuItem)menu.Items[4]).Header = InternationalizationManager.Instance.GetTranslation("iconTraySettings"); + ((MenuItem)menu.Items[5]).Header = InternationalizationManager.Instance.GetTranslation("iconTrayExit"); } private void InitializeNotifyIcon() @@ -212,6 +247,10 @@ namespace Flow.Launcher { Header = InternationalizationManager.Instance.GetTranslation("GameMode") }; + var positionreset = new MenuItem + { + Header = InternationalizationManager.Instance.GetTranslation("PositionReset") + }; var settings = new MenuItem { Header = InternationalizationManager.Instance.GetTranslation("iconTraySettings") @@ -223,12 +262,15 @@ namespace Flow.Launcher open.Click += (o, e) => _viewModel.ToggleFlowLauncher(); gamemode.Click += (o, e) => ToggleGameMode(); + positionreset.Click += (o, e) => PositionReset(); settings.Click += (o, e) => App.API.OpenSettingDialog(); exit.Click += (o, e) => Close(); contextMenu.Items.Add(header); contextMenu.Items.Add(open); gamemode.ToolTip = InternationalizationManager.Instance.GetTranslation("GameModeToolTip"); + positionreset.ToolTip = InternationalizationManager.Instance.GetTranslation("PositionResetToolTip"); contextMenu.Items.Add(gamemode); + contextMenu.Items.Add(positionreset); contextMenu.Items.Add(settings); contextMenu.Items.Add(exit); @@ -275,10 +317,17 @@ namespace Flow.Launcher _viewModel.GameModeStatus = true; } } + private async void PositionReset() + { + _viewModel.Show(); + await Task.Delay(300); // If don't give a time, Positioning will be weird. + Left = HorizonCenter(); + Top = VerticalCenter(); + } private void InitProgressbarAnimation() { var da = new DoubleAnimation(ProgressBar.X2, ActualWidth + 150, - new Duration(new TimeSpan(0, 0, 0, 0, 1600))); + new Duration(new TimeSpan(0, 0, 0, 0, 1600))); var da1 = new DoubleAnimation(ProgressBar.X1, ActualWidth + 50, new Duration(new TimeSpan(0, 0, 0, 0, 1600))); Storyboard.SetTargetProperty(da, new PropertyPath("(Line.X2)")); Storyboard.SetTargetProperty(da1, new PropertyPath("(Line.X1)")); @@ -382,6 +431,8 @@ namespace Flow.Launcher private async void OnDeactivated(object sender, EventArgs e) { + _settings.WindowLeft = Left; + _settings.WindowTop = Top; //This condition stops extra hide call when animator is on, // which causes the toggling to occasional hide instead of show. if (_viewModel.MainWindowVisibilityStatus) @@ -403,24 +454,14 @@ namespace Flow.Launcher { if (_animating) return; - - if (_settings.RememberLastLaunchLocation) - { - Left = _settings.WindowLeft; - Top = _settings.WindowTop; - } - else - { - Left = WindowLeft(); - Top = WindowTop(); - } + InitializePosition(); } private void OnLocationChanged(object sender, EventArgs e) { if (_animating) return; - if (_settings.RememberLastLaunchLocation) + if (_settings.SearchWindowPosition == SearchWindowPositions.RememberLastLaunchLocation) { _settings.WindowLeft = Left; _settings.WindowTop = Top; @@ -439,17 +480,8 @@ namespace Flow.Launcher _viewModel.Show(); } } - - private void InitializePosition() - { - if (!_settings.RememberLastLaunchLocation) - { - Left = WindowLeft(); - Top = WindowTop(); - } - } - public double WindowLeft() + public double HorizonCenter() { var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position); var dip1 = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.X, 0); @@ -458,7 +490,7 @@ namespace Flow.Launcher return left; } - public double WindowTop() + public double VerticalCenter() { var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position); var dip1 = WindowsInteropHelper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Y); @@ -467,6 +499,15 @@ namespace Flow.Launcher return top; } + public double HorizonRight() + { + var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position); + var dip1 = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.X, 0); + var dip2 = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.Width, 0); + var left = (dip2.X - ActualWidth) - 10; + return left; + } + /// /// Register up and down key /// todo: any way to put this in xaml ? diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index 3e8a4f0a1..b763330c0 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -685,12 +685,25 @@ - + - + - + + +  + diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index 2f07f43db..57c791f5e 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -341,25 +341,6 @@ namespace Flow.Launcher.ViewModel } - public double Top - { - get => _settings.WindowTop; - set - { - _settings.WindowTop = value; - OnPropertyChanged(); - } - } - public double Left - { - get => _settings.WindowLeft; - set - { - _settings.WindowLeft = value; - OnPropertyChanged(); - } - } - [RelayCommand] private void IncreaseWidth() { @@ -370,7 +351,7 @@ namespace Flow.Launcher.ViewModel else { _settings.WindowSize += 100; - Left -= 50; + _settings.WindowLeft -= 50; } OnPropertyChanged(); } @@ -384,7 +365,7 @@ namespace Flow.Launcher.ViewModel } else { - Left += 50; + _settings.WindowLeft += 50; _settings.WindowSize -= 100; } OnPropertyChanged(); diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs index 24a1fd782..1ef1edeb9 100644 --- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs +++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs @@ -385,6 +385,33 @@ namespace Flow.Launcher.ViewModel } } + + + public class SearchWindowPosition + { + public string Display { get; set; } + public SearchWindowPositions Value { get; set; } + } + + public List SearchWindowPositions + { + get + { + List modes = new List(); + var enums = (SearchWindowPositions[])Enum.GetValues(typeof(SearchWindowPositions)); + foreach (var e in enums) + { + var key = $"SearchWindowPosition{e}"; + var display = _translater.GetTranslation(key); + var m = new SearchWindowPosition { Display = display, Value = e, }; + modes.Add(m); + } + return modes; + } + } + + + public double WindowWidthSize { get => Settings.WindowSize;