diff --git a/FluentFlyoutWPF/App.config b/FluentFlyoutWPF/App.config
index 2042071..829f367 100644
--- a/FluentFlyoutWPF/App.config
+++ b/FluentFlyoutWPF/App.config
@@ -46,6 +46,12 @@
2
+
+ False
+
+
+ 2000
+
\ No newline at end of file
diff --git a/FluentFlyoutWPF/FluentFlyout.csproj b/FluentFlyoutWPF/FluentFlyout.csproj
index 09e282a..0bfb338 100644
--- a/FluentFlyoutWPF/FluentFlyout.csproj
+++ b/FluentFlyoutWPF/FluentFlyout.csproj
@@ -22,6 +22,7 @@
+
@@ -38,6 +39,9 @@
Always
+
+ Always
+
Always
diff --git a/FluentFlyoutWPF/MainWindow.xaml.cs b/FluentFlyoutWPF/MainWindow.xaml.cs
index f41c716..8447da1 100644
--- a/FluentFlyoutWPF/MainWindow.xaml.cs
+++ b/FluentFlyoutWPF/MainWindow.xaml.cs
@@ -7,20 +7,17 @@
using System.Windows.Media.Imaging;
using Windows.Storage.Streams;
using MicaWPF.Controls;
-using System.IO;
using System.Windows.Media.Animation;
using FluentFlyout;
using FluentFlyout.Properties;
using Microsoft.Win32;
-using System.Reflection;
using System.Drawing;
using System.Windows.Controls;
using Wpf.Ui.Controls;
-using Wpf.Ui.Appearance;
using FluentFlyout.Classes;
using MicaWPF.Core.Extensions;
-using MicaWPF.Core.Services;
-using Windows.UI.Composition;
+using FluentFlyout.Windows;
+using System.Windows.Input;
namespace FluentFlyoutWPF
@@ -54,6 +51,8 @@ public partial class MainWindow : MicaWindow
private NextUpWindow? nextUpWindow = null; // to prevent multiple instances of NextUpWindow
private string currentTitle = ""; // to prevent NextUpWindow from showing the same song
+ private LockWindow lockWindow;
+
public MainWindow()
{
WindowHelper.SetNoActivate(this); // prevents some fullscreen apps from minimizing
@@ -120,51 +119,61 @@ public EasingFunctionBase getEasingStyle(bool easeOut)
return easingStyle;
}
- public void OpenAnimation(MicaWindow window)
+ public void OpenAnimation(MicaWindow window, bool alwaysBottom = false)
{
-
var eventTriggers = window.Triggers[0] as EventTrigger;
var beginStoryboard = eventTriggers.Actions[0] as BeginStoryboard;
var storyboard = beginStoryboard.Storyboard;
DoubleAnimation moveAnimation = (DoubleAnimation)storyboard.Children[0];
- _position = Settings.Default.Position;
- if (_position == 0)
+
+ if (alwaysBottom == false)
{
- window.Left = 16;
- moveAnimation.From = SystemParameters.WorkArea.Height - window.Height + 4;
- moveAnimation.To = SystemParameters.WorkArea.Height - window.Height - 16;
+ _position = Settings.Default.Position;
+ if (_position == 0)
+ {
+ window.Left = 16;
+ moveAnimation.From = SystemParameters.WorkArea.Height - window.Height + 4;
+ moveAnimation.To = SystemParameters.WorkArea.Height - window.Height - 16;
+ }
+ else if (_position == 1)
+ {
+ window.Left = SystemParameters.WorkArea.Width / 2 - window.Width / 2;
+ moveAnimation.From = SystemParameters.WorkArea.Height - window.Height - 60;
+ moveAnimation.To = SystemParameters.WorkArea.Height - window.Height - 80;
+ }
+ else if (_position == 2)
+ {
+ window.Left = SystemParameters.WorkArea.Width - window.Width - 16;
+ moveAnimation.From = SystemParameters.WorkArea.Height - window.Height + 4;
+ moveAnimation.To = SystemParameters.WorkArea.Height - window.Height - 16;
+ }
+ else if (_position == 3)
+ {
+ window.Left = 16;
+ moveAnimation.From = -4;
+ moveAnimation.To = 16;
+ }
+ else if (_position == 4)
+ {
+ window.Left = SystemParameters.WorkArea.Width / 2 - window.Width / 2;
+ moveAnimation.From = -4;
+ moveAnimation.To = 16;
+ }
+ else if (_position == 5)
+ {
+ window.Left = SystemParameters.WorkArea.Width - window.Width - 16;
+ moveAnimation.From = -4;
+ moveAnimation.To = 16;
+ }
}
- else if (_position == 1)
+ else
{
window.Left = SystemParameters.WorkArea.Width / 2 - window.Width / 2;
- moveAnimation.From = SystemParameters.WorkArea.Height - window.Height - 60;
- moveAnimation.To = SystemParameters.WorkArea.Height - window.Height - 80;
- }
- else if (_position == 2)
- {
- window.Left = SystemParameters.WorkArea.Width - window.Width - 16;
moveAnimation.From = SystemParameters.WorkArea.Height - window.Height + 4;
moveAnimation.To = SystemParameters.WorkArea.Height - window.Height - 16;
}
- else if (_position == 3)
- {
- window.Left = 16;
- moveAnimation.From = -4;
- moveAnimation.To = 16;
- }
- else if (_position == 4)
- {
- window.Left = SystemParameters.WorkArea.Width / 2 - window.Width / 2;
- moveAnimation.From = -4;
- moveAnimation.To = 16;
- }
- else if (_position == 5)
- {
- window.Left = SystemParameters.WorkArea.Width - window.Width - 16;
- moveAnimation.From = -4;
- moveAnimation.To = 16;
- }
+
int msDuration = getDuration();
DoubleAnimation opacityAnimation = (DoubleAnimation)storyboard.Children[1];
@@ -179,29 +188,39 @@ public void OpenAnimation(MicaWindow window)
storyboard.Begin(window);
}
- public void CloseAnimation(MicaWindow window)
+ public void CloseAnimation(MicaWindow window, bool alwaysBottom = false)
{
var eventTriggers = window.Triggers[0] as EventTrigger;
var beginStoryboard = eventTriggers.Actions[0] as BeginStoryboard;
var storyboard = beginStoryboard.Storyboard;
DoubleAnimation moveAnimation = (DoubleAnimation)storyboard.Children[0];
- _position = Settings.Default.Position;
- if (_position == 0 || _position == 2)
- {
- moveAnimation.From = SystemParameters.WorkArea.Height - window.Height - 16;
- moveAnimation.To = SystemParameters.WorkArea.Height - window.Height + 4;
- }
- else if (_position == 1)
+
+ if (alwaysBottom == false)
{
- moveAnimation.From = SystemParameters.WorkArea.Height - window.Height - 80;
- moveAnimation.To = SystemParameters.WorkArea.Height - window.Height - 60;
+ _position = Settings.Default.Position;
+ if (_position == 0 || _position == 2)
+ {
+ moveAnimation.From = SystemParameters.WorkArea.Height - window.Height - 16;
+ moveAnimation.To = SystemParameters.WorkArea.Height - window.Height + 4;
+ }
+ else if (_position == 1)
+ {
+ moveAnimation.From = SystemParameters.WorkArea.Height - window.Height - 80;
+ moveAnimation.To = SystemParameters.WorkArea.Height - window.Height - 60;
+ }
+ else if (_position == 3 || _position == 4 || _position == 5)
+ {
+ moveAnimation.From = 16;
+ moveAnimation.To = -4;
+ }
}
- else if (_position == 3 || _position == 4 || _position == 5)
+ else
{
- moveAnimation.From = 16;
- moveAnimation.To = -4;
+ moveAnimation.From = SystemParameters.WorkArea.Height - window.Height - 16;
+ moveAnimation.To = SystemParameters.WorkArea.Height - window.Height + 4;
}
+
int msDuration = getDuration();
DoubleAnimation opacityAnimation = (DoubleAnimation)storyboard.Children[1];
@@ -285,15 +304,25 @@ private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
ShowMediaFlyout();
}
- if (vkCode == 0x14) // Caps Lock
- {
-
- }
-
- if (vkCode == 0x90) // Num Lock
+ if (Settings.Default.LockKeysEnabled == true)
{
+ if (vkCode == 0x14) // Caps Lock
+ {
+ lockWindow ??= new LockWindow();
+ lockWindow.ShowLockFlyout("Caps Lock", Keyboard.IsKeyToggled(Key.CapsLock));
+ }
- }
+ if (vkCode == 0x90) // Num Lock
+ {
+ lockWindow ??= new LockWindow();
+ lockWindow.ShowLockFlyout("Num Lock", Keyboard.IsKeyToggled(Key.NumLock));
+ }
+ if (vkCode == 0x91) // Scroll Lock
+ {
+ lockWindow ??= new LockWindow();
+ lockWindow.ShowLockFlyout("Scroll Lock", Keyboard.IsKeyToggled(Key.Scroll));
+ }
+ }
}
return CallNextHookEx(_hookId, nCode, wParam, lParam);
}
diff --git a/FluentFlyoutWPF/Properties/Settings.Designer.cs b/FluentFlyoutWPF/Properties/Settings.Designer.cs
index 5134587..f8a4fed 100644
--- a/FluentFlyoutWPF/Properties/Settings.Designer.cs
+++ b/FluentFlyoutWPF/Properties/Settings.Designer.cs
@@ -178,5 +178,29 @@ public int FlyoutAnimationEasingStyle {
this["FlyoutAnimationEasingStyle"] = value;
}
}
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ public bool LockKeysEnabled {
+ get {
+ return ((bool)(this["LockKeysEnabled"]));
+ }
+ set {
+ this["LockKeysEnabled"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("2000")]
+ public int LockKeysDuration {
+ get {
+ return ((int)(this["LockKeysDuration"]));
+ }
+ set {
+ this["LockKeysDuration"] = value;
+ }
+ }
}
}
diff --git a/FluentFlyoutWPF/Properties/Settings.settings b/FluentFlyoutWPF/Properties/Settings.settings
index 2a50a25..0848b8e 100644
--- a/FluentFlyoutWPF/Properties/Settings.settings
+++ b/FluentFlyoutWPF/Properties/Settings.settings
@@ -41,5 +41,11 @@
2
+
+ False
+
+
+ 2000
+
\ No newline at end of file
diff --git a/FluentFlyoutWPF/Resources/FluentFlyoutDemo5.1.png b/FluentFlyoutWPF/Resources/FluentFlyoutDemo5.1.png
new file mode 100644
index 0000000..b4cb4e8
Binary files /dev/null and b/FluentFlyoutWPF/Resources/FluentFlyoutDemo5.1.png differ
diff --git a/FluentFlyoutWPF/SettingsWindow.xaml b/FluentFlyoutWPF/SettingsWindow.xaml
index 65b88b5..c0aa47f 100644
--- a/FluentFlyoutWPF/SettingsWindow.xaml
+++ b/FluentFlyoutWPF/SettingsWindow.xaml
@@ -157,6 +157,44 @@
+
+
+
+
+
+
+
+
+
+
+ Check your lock key status at a glance.
+ Appears after pressing Caps Lock, Num Lock or Scroll Lock.
+ Convenient for laptops/keyboards without lock key indicators.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FluentFlyoutWPF/SettingsWindow.xaml.cs b/FluentFlyoutWPF/SettingsWindow.xaml.cs
index e3077e6..d808949 100644
--- a/FluentFlyoutWPF/SettingsWindow.xaml.cs
+++ b/FluentFlyoutWPF/SettingsWindow.xaml.cs
@@ -48,6 +48,8 @@ public SettingsWindow()
nIconLeftClickComboBox.SelectedIndex = Settings.Default.nIconLeftClick;
CenterTitleArtistSwitch.IsChecked = Settings.Default.CenterTitleArtist;
AnimationEasingStylesComboBox.SelectedIndex = Settings.Default.FlyoutAnimationEasingStyle;
+ LockKeysSwitch.IsChecked = Settings.Default.LockKeysEnabled;
+ LockKeysDurationTextBox.Text = Settings.Default.LockKeysDuration.ToString();
try // gets the version of the app, works only in release mode
{
@@ -60,6 +62,23 @@ public SettingsWindow()
}
}
+ public static void ShowInstance()
+ {
+ if (instance == null)
+ {
+ new SettingsWindow().Show();
+ }
+ else
+ {
+ if (instance.WindowState == WindowState.Minimized)
+ {
+ instance.WindowState = WindowState.Normal;
+ }
+ instance.Activate();
+ instance.Focus();
+ }
+ }
+
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
Close();
@@ -103,23 +122,6 @@ private void FlyoutAnimationSpeedComboBox_SelectionChanged(object sender, System
Settings.Default.Save();
}
- public static void ShowInstance()
- {
- if (instance == null)
- {
- new SettingsWindow().Show();
- }
- else
- {
- if (instance.WindowState == WindowState.Minimized)
- {
- instance.WindowState = WindowState.Normal;
- }
- instance.Activate();
- instance.Focus();
- }
- }
-
private void NextUpSwitch_Click(object sender, RoutedEventArgs e)
{
Settings.Default.NextUpEnabled = NextUpSwitch.IsChecked ?? false;
@@ -260,5 +262,44 @@ private void StartupHyperlink_RequestNavigate(object sender, System.Windows.Navi
Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri) { UseShellExecute = true });
e.Handled = true;
}
+
+ private void LockKeysSwitch_Click(object sender, RoutedEventArgs e)
+ {
+ Settings.Default.LockKeysEnabled = LockKeysSwitch.IsChecked ?? false;
+ Settings.Default.Save();
+ }
+
+ private void LockKeysDurationTextBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
+ {
+ string text = LockKeysDurationTextBox.Text.Trim();
+ string numericText = new string(text.Where(char.IsDigit).ToArray());
+
+ if (string.IsNullOrEmpty(numericText))
+ {
+ LockKeysDurationTextBox.Text = "0";
+ Settings.Default.LockKeysDuration = 0;
+ }
+ else
+ {
+ LockKeysDurationTextBox.Text = numericText;
+ if (int.TryParse(numericText, out int duration))
+ {
+ if (duration > 10000)
+ {
+ duration = 10000;
+ }
+ LockKeysDurationTextBox.Text = duration.ToString();
+ Settings.Default.LockKeysDuration = duration;
+ }
+ else
+ {
+ LockKeysDurationTextBox.Text = "2000";
+ Settings.Default.LockKeysDuration = 2000;
+ }
+ }
+
+ LockKeysDurationTextBox.CaretIndex = LockKeysDurationTextBox.Text.Length;
+ Settings.Default.Save();
+ }
}
}
diff --git a/FluentFlyoutWPF/Windows/LockWindow.xaml b/FluentFlyoutWPF/Windows/LockWindow.xaml
new file mode 100644
index 0000000..bca1e03
--- /dev/null
+++ b/FluentFlyoutWPF/Windows/LockWindow.xaml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FluentFlyoutWPF/Windows/LockWindow.xaml.cs b/FluentFlyoutWPF/Windows/LockWindow.xaml.cs
new file mode 100644
index 0000000..5f8e1be
--- /dev/null
+++ b/FluentFlyoutWPF/Windows/LockWindow.xaml.cs
@@ -0,0 +1,83 @@
+using FluentFlyout.Classes;
+using FluentFlyout.Properties;
+using FluentFlyoutWPF;
+using MicaWPF.Controls;
+using MicaWPF.Core.Extensions;
+using System.Windows;
+using Windows.UI;
+
+
+namespace FluentFlyout.Windows
+{
+ ///
+ /// Interaction logic for LockWindow.xaml
+ ///
+ public partial class LockWindow : MicaWindow
+ {
+ private CancellationTokenSource cts;
+ MainWindow mainWindow = (MainWindow)Application.Current.MainWindow;
+
+ public LockWindow()
+ {
+ WindowHelper.SetNoActivate(this);
+ InitializeComponent();
+ WindowHelper.SetTopmost(this);
+ CustomWindowChrome.CaptionHeight = 0;
+
+ WindowStartupLocation = WindowStartupLocation.Manual;
+ Left = SystemParameters.WorkArea.Width / 2 - Width / 2;
+ cts = new CancellationTokenSource();
+ mainWindow.OpenAnimation(this, true);
+ }
+
+ private void setStatus(string key, bool isOn)
+ {
+ Dispatcher.Invoke(() =>
+ {
+ this.EnableBackdrop();
+
+ LockTextBlock.Text = key + " is " + (isOn ? "on" : "off");
+ if (isOn)
+ {
+ LockIndicatorRectangle.Opacity = 1;
+ LockSymbol.Symbol = Wpf.Ui.Controls.SymbolRegular.LockClosed24;
+ }
+ else
+ {
+ LockIndicatorRectangle.Opacity = 0.2;
+ LockSymbol.Symbol = Wpf.Ui.Controls.SymbolRegular.LockOpen24;
+ }
+ });
+ }
+
+ public async void ShowLockFlyout(string key, bool isOn)
+ {
+ setStatus(key, isOn);
+
+ if (Visibility == Visibility.Hidden)
+ {
+ mainWindow.OpenAnimation(this, true);
+ }
+ cts.Cancel();
+ cts = new CancellationTokenSource();
+ var token = cts.Token;
+ Visibility = Visibility.Visible;
+ Topmost = true;
+ try
+ {
+ while (!token.IsCancellationRequested)
+ {
+ await Task.Delay(Settings.Default.LockKeysDuration, token);
+ mainWindow.CloseAnimation(this, true);
+ await Task.Delay(mainWindow.getDuration());
+ Hide();
+ break;
+ }
+ }
+ catch (TaskCanceledException)
+ {
+ // do nothing
+ }
+ }
+ }
+}