Skip to content

Commit 16c6e8b

Browse files
committed
Merge Dev
2 parents 65fdca5 + 5e57d73 commit 16c6e8b

File tree

21 files changed

+393
-109
lines changed

21 files changed

+393
-109
lines changed

Flow.Launcher.Infrastructure/UserSettings/Settings.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ public CustomExplorerViewModel CustomExplorer
8383
}
8484
};
8585

86+
public bool UseAnimation { get; set; } = true;
87+
public bool UseSound { get; set; } = true;
8688

8789
/// <summary>
8890
/// when false Alphabet static service will always return empty results

Flow.Launcher/App.xaml.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,6 @@ await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () =>
100100
AutoUpdates();
101101

102102
API.SaveAppAllSettings();
103-
104-
_mainVM.MainWindowVisibility = _settings.HideOnStartup ? Visibility.Hidden : Visibility.Visible;
105103
Log.Info("|App.OnStartup|End Flow Launcher startup ---------------------------------------------------- ");
106104
});
107105
}
@@ -178,7 +176,7 @@ public void Dispose()
178176

179177
public void OnSecondAppStarted()
180178
{
181-
Current.MainWindow.Visibility = Visibility.Visible;
179+
Current.MainWindow.Show();
182180
}
183181
}
184182
}

Flow.Launcher/CustomQueryHotkeySetting.xaml.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
using Flow.Launcher.Core.Resource;
22
using Flow.Launcher.Helper;
3-
using Flow.Launcher.Infrastructure.Hotkey;
43
using Flow.Launcher.Infrastructure.UserSettings;
5-
using System;
64
using System.Collections.ObjectModel;
75
using System.Linq;
86
using System.Windows;
@@ -91,9 +89,9 @@ public void UpdateItem(CustomPluginHotkey item)
9189
private void BtnTestActionKeyword_OnClick(object sender, RoutedEventArgs e)
9290
{
9391
App.API.ChangeQuery(tbAction.Text);
94-
Application.Current.MainWindow.Visibility = Visibility.Visible;
92+
Application.Current.MainWindow.Show();
93+
Application.Current.MainWindow.Opacity = 1;
9594
Application.Current.MainWindow.Focus();
96-
9795
}
9896

9997
private void cmdEsc_OnPress(object sender, ExecutedRoutedEventArgs e)

Flow.Launcher/Flow.Launcher.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,12 @@
104104
<ProjectReference Include="..\Flow.Launcher.Plugin\Flow.Launcher.Plugin.csproj" />
105105
</ItemGroup>
106106

107+
<ItemGroup>
108+
<Content Include="Resources\open.wav">
109+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
110+
</Content>
111+
</ItemGroup>
112+
107113
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
108114
<Exec Command="taskkill /f /fi &quot;IMAGENAME eq Flow.Launcher.exe&quot;" />
109115
</Target>

Flow.Launcher/Helper/HotKeyMapper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ internal static void SetCustomQueryHotkey(CustomPluginHotkey hotkey)
7777
if (mainViewModel.ShouldIgnoreHotkeys() || mainViewModel.GameModeStatus)
7878
return;
7979

80-
mainViewModel.MainWindowVisibility = Visibility.Visible;
80+
mainViewModel.Show();
8181
mainViewModel.ChangeQueryText(hotkey.ActionKeyword, true);
8282
});
8383
}

Flow.Launcher/Helper/SingletonWindowOpener.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ public static T Open<T>(params object[] args) where T : Window
1010
{
1111
var window = Application.Current.Windows.OfType<Window>().FirstOrDefault(x => x.GetType() == typeof(T))
1212
?? (T)Activator.CreateInstance(typeof(T), args);
13-
Application.Current.MainWindow.Hide();
1413

1514
// Fix UI bug
1615
// Add `window.WindowState = WindowState.Normal`

Flow.Launcher/Languages/en.xaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@
8989
<system:String x:Key="DarkModeSystem">System Default</system:String>
9090
<system:String x:Key="DarkModeLight">Light</system:String>
9191
<system:String x:Key="DarkModeDark">Dark</system:String>
92+
<system:String x:Key="SoundEffect">Sound Effect</system:String>
93+
<system:String x:Key="SoundEffectTip">Play a small sound when the search window opens</system:String>
94+
<system:String x:Key="Animation">Animation</system:String>
95+
<system:String x:Key="AnimationTip">Use Animation in UI</system:String>
9296

9397
<!-- Setting Hotkey -->
9498
<system:String x:Key="hotkey">Hotkey</system:String>

Flow.Launcher/MainWindow.xaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
99
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
1010
xmlns:vm="clr-namespace:Flow.Launcher.ViewModel"
11+
Name="FlowMainWindow"
1112
Title="Flow Launcher"
1213
MinWidth="{Binding MainWindowWidth, Mode=OneWay}"
1314
MaxWidth="{Binding MainWindowWidth, Mode=OneWay}"
@@ -21,6 +22,7 @@
2122
Initialized="OnInitialized"
2223
Loaded="OnLoaded"
2324
LocationChanged="OnLocationChanged"
25+
Opacity="{Binding MainWindowOpacity, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
2426
PreviewKeyDown="OnKeyDown"
2527
ResizeMode="NoResize"
2628
ShowInTaskbar="False"
@@ -184,6 +186,7 @@
184186
</TextBox>
185187
<Canvas Style="{DynamicResource SearchIconPosition}">
186188
<Path
189+
Name="SearchIcon"
187190
Margin="0"
188191
Data="{DynamicResource SearchIconImg}"
189192
Stretch="Fill"

Flow.Launcher/MainWindow.xaml.cs

Lines changed: 110 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.ComponentModel;
33
using System.Threading.Tasks;
44
using System.Windows;
@@ -11,16 +11,11 @@
1111
using Flow.Launcher.Helper;
1212
using Flow.Launcher.Infrastructure.UserSettings;
1313
using Flow.Launcher.ViewModel;
14-
using Microsoft.AspNetCore.Authorization;
15-
using Application = System.Windows.Application;
1614
using Screen = System.Windows.Forms.Screen;
1715
using ContextMenuStrip = System.Windows.Forms.ContextMenuStrip;
18-
using DataFormats = System.Windows.DataFormats;
1916
using DragEventArgs = System.Windows.DragEventArgs;
2017
using KeyEventArgs = System.Windows.Input.KeyEventArgs;
21-
using MessageBox = System.Windows.MessageBox;
2218
using NotifyIcon = System.Windows.Forms.NotifyIcon;
23-
using System.Windows.Interop;
2419

2520
namespace Flow.Launcher
2621
{
@@ -34,6 +29,7 @@ public partial class MainWindow
3429
private NotifyIcon _notifyIcon;
3530
private ContextMenu contextMenu;
3631
private MainViewModel _viewModel;
32+
private bool _animating;
3733

3834
#endregion
3935

@@ -43,6 +39,7 @@ public MainWindow(Settings settings, MainViewModel mainVM)
4339
_viewModel = mainVM;
4440
_settings = settings;
4541
InitializeComponent();
42+
InitializePosition();
4643
}
4744

4845
public MainWindow()
@@ -52,6 +49,8 @@ public MainWindow()
5249

5350
private async void OnClosing(object sender, CancelEventArgs e)
5451
{
52+
_settings.WindowTop = Top;
53+
_settings.WindowLeft = Left;
5554
_notifyIcon.Visible = false;
5655
_viewModel.Save();
5756
e.Cancel = true;
@@ -65,12 +64,12 @@ private void OnInitialized(object sender, EventArgs e)
6564

6665
private void OnLoaded(object sender, RoutedEventArgs _)
6766
{
67+
HideStartup();
6868
// show notify icon when flowlauncher is hidden
6969
InitializeNotifyIcon();
7070
InitializeDarkMode();
7171
WindowsInteropHelper.DisableControlBox(this);
7272
InitProgressbarAnimation();
73-
InitializePosition();
7473
// since the default main window visibility is visible
7574
// so we need set focus during startup
7675
QueryTextBox.Focus();
@@ -79,13 +78,13 @@ private void OnLoaded(object sender, RoutedEventArgs _)
7978
{
8079
switch (e.PropertyName)
8180
{
82-
case nameof(MainViewModel.MainWindowVisibility):
81+
case nameof(MainViewModel.MainWindowVisibilityStatus):
8382
{
84-
if (_viewModel.MainWindowVisibility == Visibility.Visible)
83+
if (_viewModel.MainWindowVisibilityStatus)
8584
{
85+
UpdatePosition();
8686
Activate();
8787
QueryTextBox.Focus();
88-
UpdatePosition();
8988
_settings.ActivateTimes++;
9089
if (!_viewModel.LastQuerySelected)
9190
{
@@ -117,7 +116,7 @@ private void OnLoaded(object sender, RoutedEventArgs _)
117116
_progressBarStoryboard.Stop(ProgressBar);
118117
isProgressBarStoryboardPaused = true;
119118
}
120-
else if (_viewModel.MainWindowVisibility == Visibility.Visible &&
119+
else if (_viewModel.MainWindowVisibilityStatus &&
121120
isProgressBarStoryboardPaused)
122121
{
123122
_progressBarStoryboard.Begin(ProgressBar, true);
@@ -148,16 +147,20 @@ private void OnLoaded(object sender, RoutedEventArgs _)
148147
break;
149148
}
150149
};
151-
152-
InitializePosition();
153150
}
154151

155152
private void InitializePosition()
156153
{
157-
Top = WindowTop();
158-
Left = WindowLeft();
159-
_settings.WindowTop = Top;
160-
_settings.WindowLeft = Left;
154+
if (_settings.RememberLastLaunchLocation)
155+
{
156+
Top = _settings.WindowTop;
157+
Left = _settings.WindowLeft;
158+
}
159+
else
160+
{
161+
Left = WindowLeft();
162+
Top = WindowTop();
163+
}
161164
}
162165

163166
private void UpdateNotifyIconText()
@@ -181,7 +184,7 @@ private void InitializeNotifyIcon()
181184

182185
var header = new MenuItem
183186
{
184-
Header = "Flow Launcher",
187+
Header = "Flow Launcher",
185188
IsEnabled = false
186189
};
187190
var open = new MenuItem
@@ -201,7 +204,7 @@ private void InitializeNotifyIcon()
201204
Header = InternationalizationManager.Instance.GetTranslation("iconTrayExit")
202205
};
203206

204-
open.Click += (o, e) => Visibility = Visibility.Visible;
207+
open.Click += (o, e) => _viewModel.ToggleFlowLauncher();
205208
gamemode.Click += (o, e) => ToggleGameMode();
206209
settings.Click += (o, e) => App.API.OpenSettingDialog();
207210
exit.Click += (o, e) => Close();
@@ -255,6 +258,54 @@ private void InitProgressbarAnimation()
255258
isProgressBarStoryboardPaused = true;
256259
}
257260

261+
public void WindowAnimator()
262+
{
263+
if (_animating)
264+
return;
265+
266+
_animating = true;
267+
UpdatePosition();
268+
Storyboard sb = new Storyboard();
269+
Storyboard iconsb = new Storyboard();
270+
CircleEase easing = new CircleEase(); // or whatever easing class you want
271+
easing.EasingMode = EasingMode.EaseInOut;
272+
var da = new DoubleAnimation
273+
{
274+
From = 0,
275+
To = 1,
276+
Duration = TimeSpan.FromSeconds(0.25),
277+
FillBehavior = FillBehavior.Stop
278+
};
279+
280+
var da2 = new DoubleAnimation
281+
{
282+
From = Top + 10,
283+
To = Top,
284+
Duration = TimeSpan.FromSeconds(0.25),
285+
FillBehavior = FillBehavior.Stop
286+
};
287+
var da3 = new DoubleAnimation
288+
{
289+
From = 12,
290+
To = 0,
291+
EasingFunction = easing,
292+
Duration = TimeSpan.FromSeconds(0.36),
293+
FillBehavior = FillBehavior.Stop
294+
};
295+
Storyboard.SetTarget(da, this);
296+
Storyboard.SetTargetProperty(da, new PropertyPath(Window.OpacityProperty));
297+
Storyboard.SetTargetProperty(da2, new PropertyPath(Window.TopProperty));
298+
Storyboard.SetTargetProperty(da3, new PropertyPath(TopProperty));
299+
sb.Children.Add(da);
300+
sb.Children.Add(da2);
301+
iconsb.Children.Add(da3);
302+
sb.Completed += (_, _) => _animating = false;
303+
_settings.WindowLeft = Left;
304+
_settings.WindowTop = Top;
305+
iconsb.Begin(SearchIcon);
306+
sb.Begin(FlowMainWindow);
307+
}
308+
258309
private void OnMouseDown(object sender, MouseButtonEventArgs e)
259310
{
260311
if (e.ChangedButton == MouseButton.Left) DragMove();
@@ -287,22 +338,41 @@ private void OnPreviewDragOver(object sender, DragEventArgs e)
287338
e.Handled = true;
288339
}
289340

290-
private void OnContextMenusForSettingsClick(object sender, RoutedEventArgs e)
341+
private async void OnContextMenusForSettingsClick(object sender, RoutedEventArgs e)
291342
{
343+
_viewModel.Hide();
344+
345+
if(_settings.UseAnimation)
346+
await Task.Delay(100);
347+
292348
App.API.OpenSettingDialog();
293349
}
294350

295351

296-
private void OnDeactivated(object sender, EventArgs e)
352+
private async void OnDeactivated(object sender, EventArgs e)
297353
{
298-
if (_settings.HideWhenDeactive)
354+
//This condition stops extra hide call when animator is on,
355+
// which causes the toggling to occasional hide instead of show.
356+
if (_viewModel.MainWindowVisibilityStatus)
299357
{
300-
_viewModel.Hide();
358+
// Need time to initialize the main query window animation.
359+
// This also stops the mainwindow from flickering occasionally after Settings window is opened
360+
// and always after Settings window is closed.
361+
if (_settings.UseAnimation)
362+
await Task.Delay(100);
363+
364+
if (_settings.HideWhenDeactive)
365+
{
366+
_viewModel.Hide();
367+
}
301368
}
302369
}
303370

304371
private void UpdatePosition()
305372
{
373+
if (_animating)
374+
return;
375+
306376
if (_settings.RememberLastLaunchLocation)
307377
{
308378
Left = _settings.WindowLeft;
@@ -317,14 +387,29 @@ private void UpdatePosition()
317387

318388
private void OnLocationChanged(object sender, EventArgs e)
319389
{
390+
if (_animating)
391+
return;
320392
if (_settings.RememberLastLaunchLocation)
321393
{
322394
_settings.WindowLeft = Left;
323395
_settings.WindowTop = Top;
324396
}
325397
}
326398

327-
private double WindowLeft()
399+
public void HideStartup()
400+
{
401+
UpdatePosition();
402+
if (_settings.HideOnStartup)
403+
{
404+
_viewModel.Hide();
405+
}
406+
else
407+
{
408+
_viewModel.Show();
409+
}
410+
}
411+
412+
public double WindowLeft()
328413
{
329414
var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position);
330415
var dip1 = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.X, 0);
@@ -333,7 +418,7 @@ private double WindowLeft()
333418
return left;
334419
}
335420

336-
private double WindowTop()
421+
public double WindowTop()
337422
{
338423
var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position);
339424
var dip1 = WindowsInteropHelper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Y);

0 commit comments

Comments
 (0)