From c94a04b3e16be42f42738ad0b34c614860e80a7a Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sat, 27 Nov 2021 13:38:47 +1100 Subject: [PATCH] refinements to delay and show hide toggle --- Flow.Launcher/MainWindow.xaml.cs | 109 ++++++++++++----------- Flow.Launcher/PublicAPIInstance.cs | 2 +- Flow.Launcher/ViewModel/MainViewModel.cs | 67 ++++++++++---- 3 files changed, 110 insertions(+), 68 deletions(-) diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs index a69f99435..5b0a620ae 100644 --- a/Flow.Launcher/MainWindow.xaml.cs +++ b/Flow.Launcher/MainWindow.xaml.cs @@ -1,10 +1,9 @@ -using System; +using System; using System.ComponentModel; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; using System.Windows.Media.Animation; -using System.Windows.Media; using System.Windows.Controls; using System.Windows.Forms; using Flow.Launcher.Core.Plugin; @@ -78,9 +77,9 @@ namespace Flow.Launcher { switch (e.PropertyName) { - case nameof(MainViewModel.WinToggleStatus): + case nameof(MainViewModel.MainWindowVisibilityStatus): { - if (_viewModel.WinToggleStatus == true) + if (_viewModel.MainWindowVisibilityStatus) { UpdatePosition(); Activate(); @@ -116,7 +115,7 @@ namespace Flow.Launcher _progressBarStoryboard.Stop(ProgressBar); isProgressBarStoryboardPaused = true; } - else if (_viewModel.MainWindowVisibility == Visibility.Visible && + else if (_viewModel.MainWindowVisibilityStatus && isProgressBarStoryboardPaused) { _progressBarStoryboard.Begin(ProgressBar, true); @@ -260,30 +259,30 @@ namespace Flow.Launcher public void WindowAnimator() { - if (_settings.UseAnimation) - { - if (_animating) - return; - _animating = true; - UpdatePosition(); - Storyboard sb = new Storyboard(); - Storyboard iconsb = new Storyboard(); - CircleEase easing = new CircleEase(); // or whatever easing class you want - easing.EasingMode = EasingMode.EaseInOut; - var da = new DoubleAnimation - { - From = 0, - To = 1, - Duration = TimeSpan.FromSeconds(0.25), - FillBehavior = FillBehavior.Stop - }; - var da2 = new DoubleAnimation - { - From = Top + 10, - To = Top, - Duration = TimeSpan.FromSeconds(0.25), - FillBehavior = FillBehavior.Stop - }; + if (_animating) + return; + + _animating = true; + UpdatePosition(); + Storyboard sb = new Storyboard(); + Storyboard iconsb = new Storyboard(); + CircleEase easing = new CircleEase(); // or whatever easing class you want + easing.EasingMode = EasingMode.EaseInOut; + var da = new DoubleAnimation + { + From = 0, + To = 1, + Duration = TimeSpan.FromSeconds(0.25), + FillBehavior = FillBehavior.Stop + }; + + var da2 = new DoubleAnimation + { + From = Top + 10, + To = Top, + Duration = TimeSpan.FromSeconds(0.25), + FillBehavior = FillBehavior.Stop + }; var da3 = new DoubleAnimation { From = 12, @@ -292,25 +291,18 @@ namespace Flow.Launcher Duration = TimeSpan.FromSeconds(0.36), FillBehavior = FillBehavior.Stop }; - Storyboard.SetTarget(da, this); - Storyboard.SetTargetProperty(da, new PropertyPath(Window.OpacityProperty)); - Storyboard.SetTargetProperty(da2, new PropertyPath(Window.TopProperty)); - Storyboard.SetTargetProperty(da3, new PropertyPath(TopProperty)); - sb.Children.Add(da); - sb.Children.Add(da2); - iconsb.Children.Add(da3); - sb.Completed += (_, _) => _animating = false; - _settings.WindowLeft = Left; - _settings.WindowTop = Top; - iconsb.Begin(SearchIcon); - sb.Begin(FlowMainWindow); - } - if (_settings.UseSound) - { - MediaPlayer media = new MediaPlayer(); - media.Open(new Uri(AppDomain.CurrentDomain.BaseDirectory + "Resources\\open.wav")); - media.Play(); - } + Storyboard.SetTarget(da, this); + Storyboard.SetTargetProperty(da, new PropertyPath(Window.OpacityProperty)); + Storyboard.SetTargetProperty(da2, new PropertyPath(Window.TopProperty)); + Storyboard.SetTargetProperty(da3, new PropertyPath(TopProperty)); + sb.Children.Add(da); + sb.Children.Add(da2); + iconsb.Children.Add(da3); + sb.Completed += (_, _) => _animating = false; + _settings.WindowLeft = Left; + _settings.WindowTop = Top; + iconsb.Begin(SearchIcon); + sb.Begin(FlowMainWindow); } private void OnMouseDown(object sender, MouseButtonEventArgs e) @@ -348,17 +340,30 @@ namespace Flow.Launcher private async void OnContextMenusForSettingsClick(object sender, RoutedEventArgs e) { _viewModel.Hide(); - await Task.Delay(50); + + if(_settings.UseAnimation) + await Task.Delay(100); + App.API.OpenSettingDialog(); } private async void OnDeactivated(object sender, EventArgs e) { - if (_settings.HideWhenDeactive && _viewModel.MainWindowVisibility != Visibility.Collapsed) + //This condition stops extra hide call when animator is on, + // which causes the toggling to occasional hide instead of show. + if (_viewModel.MainWindowVisibilityStatus) { - await Task.Delay(50); - _viewModel.Hide(); + // Need time to initialize the main query window animation. + // This also stops the mainwindow from flickering occasionally after Settings window is opened + // and always after Settings window is closed. + if (_settings.UseAnimation) + await Task.Delay(100); + + if (_settings.HideWhenDeactive) + { + _viewModel.Hide(); + } } } diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs index a5c9f3afe..51484e53e 100644 --- a/Flow.Launcher/PublicAPIInstance.cs +++ b/Flow.Launcher/PublicAPIInstance.cs @@ -55,7 +55,7 @@ namespace Flow.Launcher public void RestartApp() { - _mainVM.MainWindowVisibility = Visibility.Hidden; + _mainVM.Hide(); // we must manually save // UpdateManager.RestartApp() will call Environment.Exit(0) diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index c0074f1a9..4b413da0d 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -5,6 +5,7 @@ using System.Threading; using System.Threading.Tasks; using System.Threading.Tasks.Dataflow; using System.Windows; +using System.Windows.Media; using System.Windows.Input; using Flow.Launcher.Core.Plugin; using Flow.Launcher.Core.Resource; @@ -20,6 +21,9 @@ using Flow.Launcher.Infrastructure.Logger; using Microsoft.VisualStudio.Threading; using System.Threading.Channels; using ISavable = Flow.Launcher.Plugin.ISavable; +using System.Windows.Threading; +using NHotkey; +using Windows.Web.Syndication; namespace Flow.Launcher.ViewModel @@ -153,6 +157,26 @@ namespace Flow.Launcher.ViewModel }; } } + + private void UpdateLastQUeryMode() + { + switch (_settings.LastQueryMode) + { + case LastQueryMode.Empty: + ChangeQueryText(string.Empty); + break; + case LastQueryMode.Preserved: + LastQuerySelected = true; + break; + case LastQueryMode.Selected: + LastQuerySelected = false; + break; + default: + throw new ArgumentException($"wrong LastQueryMode: <{_settings.LastQueryMode}>"); + + } + } + private void InitializeKeyCommands() { EscCommand = new RelayCommand(_ => @@ -362,7 +386,11 @@ namespace Flow.Launcher.ViewModel public Visibility ProgressBarVisibility { get; set; } public Visibility MainWindowVisibility { get; set; } public double MainWindowOpacity { get; set; } = 1; - public bool WinToggleStatus { get; set; } = true; + + // This is to be used for determining the visibility status of the mainwindow instead of MainWindowVisibility + // because it is more accurate and reliable representation than using Visibility as a condition check + public bool MainWindowVisibilityStatus { get; set; } = true; + public double MainWindowWidth => _settings.WindowSize; public ICommand EscCommand { get; set; } @@ -690,7 +718,7 @@ namespace Flow.Launcher.ViewModel public void ToggleFlowLauncher() { - if (WinToggleStatus != true) + if (!MainWindowVisibilityStatus) { Show(); } @@ -699,43 +727,52 @@ namespace Flow.Launcher.ViewModel Hide(); } } + public void Show() { - ((MainWindow)Application.Current.MainWindow).WindowAnimator(); + if (_settings.UseSound) + { + MediaPlayer media = new MediaPlayer(); + media.Open(new Uri(AppDomain.CurrentDomain.BaseDirectory + "Resources\\open.wav")); + media.Play(); + } + MainWindowVisibility = Visibility.Visible; - WinToggleStatus = true; + + MainWindowVisibilityStatus = true; + + if(_settings.UseAnimation) + ((MainWindow)Application.Current.MainWindow).WindowAnimator(); + MainWindowOpacity = 1; } public async void Hide() { + // Trick for no delay + MainWindowOpacity = 0; + switch (_settings.LastQueryMode) { case LastQueryMode.Empty: ChangeQueryText(string.Empty); - MainWindowOpacity = 0; // Trick for no delay - await Task.Delay(50); //Time for change to opacity + await Task.Delay(100); //Time for change to opacity break; case LastQueryMode.Preserved: - MainWindowOpacity = 0; if (_settings.UseAnimation) - { - await Task.Delay(50); - } + await Task.Delay(100); LastQuerySelected = true; break; case LastQueryMode.Selected: - MainWindowOpacity = 0; if (_settings.UseAnimation) - { - await Task.Delay(50); - } + await Task.Delay(100); LastQuerySelected = false; break; default: throw new ArgumentException($"wrong LastQueryMode: <{_settings.LastQueryMode}>"); } - WinToggleStatus = false; + + MainWindowVisibilityStatus = false; MainWindowVisibility = Visibility.Collapsed; }