1
- using System ;
1
+ using System ;
2
2
using System . ComponentModel ;
3
3
using System . Threading . Tasks ;
4
4
using System . Windows ;
11
11
using Flow . Launcher . Helper ;
12
12
using Flow . Launcher . Infrastructure . UserSettings ;
13
13
using Flow . Launcher . ViewModel ;
14
- using Microsoft . AspNetCore . Authorization ;
15
- using Application = System . Windows . Application ;
16
14
using Screen = System . Windows . Forms . Screen ;
17
15
using ContextMenuStrip = System . Windows . Forms . ContextMenuStrip ;
18
- using DataFormats = System . Windows . DataFormats ;
19
16
using DragEventArgs = System . Windows . DragEventArgs ;
20
17
using KeyEventArgs = System . Windows . Input . KeyEventArgs ;
21
- using MessageBox = System . Windows . MessageBox ;
22
18
using NotifyIcon = System . Windows . Forms . NotifyIcon ;
23
- using System . Windows . Interop ;
24
19
25
20
namespace Flow . Launcher
26
21
{
@@ -34,6 +29,7 @@ public partial class MainWindow
34
29
private NotifyIcon _notifyIcon ;
35
30
private ContextMenu contextMenu ;
36
31
private MainViewModel _viewModel ;
32
+ private bool _animating ;
37
33
38
34
#endregion
39
35
@@ -43,6 +39,7 @@ public MainWindow(Settings settings, MainViewModel mainVM)
43
39
_viewModel = mainVM ;
44
40
_settings = settings ;
45
41
InitializeComponent ( ) ;
42
+ InitializePosition ( ) ;
46
43
}
47
44
48
45
public MainWindow ( )
@@ -52,6 +49,8 @@ public MainWindow()
52
49
53
50
private async void OnClosing ( object sender , CancelEventArgs e )
54
51
{
52
+ _settings . WindowTop = Top ;
53
+ _settings . WindowLeft = Left ;
55
54
_notifyIcon . Visible = false ;
56
55
_viewModel . Save ( ) ;
57
56
e . Cancel = true ;
@@ -65,12 +64,12 @@ private void OnInitialized(object sender, EventArgs e)
65
64
66
65
private void OnLoaded ( object sender , RoutedEventArgs _ )
67
66
{
67
+ HideStartup ( ) ;
68
68
// show notify icon when flowlauncher is hidden
69
69
InitializeNotifyIcon ( ) ;
70
70
InitializeDarkMode ( ) ;
71
71
WindowsInteropHelper . DisableControlBox ( this ) ;
72
72
InitProgressbarAnimation ( ) ;
73
- InitializePosition ( ) ;
74
73
// since the default main window visibility is visible
75
74
// so we need set focus during startup
76
75
QueryTextBox . Focus ( ) ;
@@ -79,13 +78,13 @@ private void OnLoaded(object sender, RoutedEventArgs _)
79
78
{
80
79
switch ( e . PropertyName )
81
80
{
82
- case nameof ( MainViewModel . MainWindowVisibility ) :
81
+ case nameof ( MainViewModel . MainWindowVisibilityStatus ) :
83
82
{
84
- if ( _viewModel . MainWindowVisibility == Visibility . Visible )
83
+ if ( _viewModel . MainWindowVisibilityStatus )
85
84
{
85
+ UpdatePosition ( ) ;
86
86
Activate ( ) ;
87
87
QueryTextBox . Focus ( ) ;
88
- UpdatePosition ( ) ;
89
88
_settings . ActivateTimes ++ ;
90
89
if ( ! _viewModel . LastQuerySelected )
91
90
{
@@ -117,7 +116,7 @@ private void OnLoaded(object sender, RoutedEventArgs _)
117
116
_progressBarStoryboard . Stop ( ProgressBar ) ;
118
117
isProgressBarStoryboardPaused = true ;
119
118
}
120
- else if ( _viewModel . MainWindowVisibility == Visibility . Visible &&
119
+ else if ( _viewModel . MainWindowVisibilityStatus &&
121
120
isProgressBarStoryboardPaused )
122
121
{
123
122
_progressBarStoryboard . Begin ( ProgressBar , true ) ;
@@ -148,16 +147,20 @@ private void OnLoaded(object sender, RoutedEventArgs _)
148
147
break ;
149
148
}
150
149
} ;
151
-
152
- InitializePosition ( ) ;
153
150
}
154
151
155
152
private void InitializePosition ( )
156
153
{
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
+ }
161
164
}
162
165
163
166
private void UpdateNotifyIconText ( )
@@ -181,7 +184,7 @@ private void InitializeNotifyIcon()
181
184
182
185
var header = new MenuItem
183
186
{
184
- Header = "Flow Launcher" ,
187
+ Header = "Flow Launcher" ,
185
188
IsEnabled = false
186
189
} ;
187
190
var open = new MenuItem
@@ -201,7 +204,7 @@ private void InitializeNotifyIcon()
201
204
Header = InternationalizationManager . Instance . GetTranslation ( "iconTrayExit" )
202
205
} ;
203
206
204
- open . Click += ( o , e ) => Visibility = Visibility . Visible ;
207
+ open . Click += ( o , e ) => _viewModel . ToggleFlowLauncher ( ) ;
205
208
gamemode . Click += ( o , e ) => ToggleGameMode ( ) ;
206
209
settings . Click += ( o , e ) => App . API . OpenSettingDialog ( ) ;
207
210
exit . Click += ( o , e ) => Close ( ) ;
@@ -255,6 +258,54 @@ private void InitProgressbarAnimation()
255
258
isProgressBarStoryboardPaused = true ;
256
259
}
257
260
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
+
258
309
private void OnMouseDown ( object sender , MouseButtonEventArgs e )
259
310
{
260
311
if ( e . ChangedButton == MouseButton . Left ) DragMove ( ) ;
@@ -287,22 +338,41 @@ private void OnPreviewDragOver(object sender, DragEventArgs e)
287
338
e . Handled = true ;
288
339
}
289
340
290
- private void OnContextMenusForSettingsClick ( object sender , RoutedEventArgs e )
341
+ private async void OnContextMenusForSettingsClick ( object sender , RoutedEventArgs e )
291
342
{
343
+ _viewModel . Hide ( ) ;
344
+
345
+ if ( _settings . UseAnimation )
346
+ await Task . Delay ( 100 ) ;
347
+
292
348
App . API . OpenSettingDialog ( ) ;
293
349
}
294
350
295
351
296
- private void OnDeactivated ( object sender , EventArgs e )
352
+ private async void OnDeactivated ( object sender , EventArgs e )
297
353
{
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 )
299
357
{
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
+ }
301
368
}
302
369
}
303
370
304
371
private void UpdatePosition ( )
305
372
{
373
+ if ( _animating )
374
+ return ;
375
+
306
376
if ( _settings . RememberLastLaunchLocation )
307
377
{
308
378
Left = _settings . WindowLeft ;
@@ -317,14 +387,29 @@ private void UpdatePosition()
317
387
318
388
private void OnLocationChanged ( object sender , EventArgs e )
319
389
{
390
+ if ( _animating )
391
+ return ;
320
392
if ( _settings . RememberLastLaunchLocation )
321
393
{
322
394
_settings . WindowLeft = Left ;
323
395
_settings . WindowTop = Top ;
324
396
}
325
397
}
326
398
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 ( )
328
413
{
329
414
var screen = Screen . FromPoint ( System . Windows . Forms . Cursor . Position ) ;
330
415
var dip1 = WindowsInteropHelper . TransformPixelsToDIP ( this , screen . WorkingArea . X , 0 ) ;
@@ -333,7 +418,7 @@ private double WindowLeft()
333
418
return left ;
334
419
}
335
420
336
- private double WindowTop ( )
421
+ public double WindowTop ( )
337
422
{
338
423
var screen = Screen . FromPoint ( System . Windows . Forms . Cursor . Position ) ;
339
424
var dip1 = WindowsInteropHelper . TransformPixelsToDIP ( this , 0 , screen . WorkingArea . Y ) ;
0 commit comments