diff --git a/src/Carnac.Logic/Carnac.Logic.csproj b/src/Carnac.Logic/Carnac.Logic.csproj
index 915b663a..6b14133a 100644
--- a/src/Carnac.Logic/Carnac.Logic.csproj
+++ b/src/Carnac.Logic/Carnac.Logic.csproj
@@ -38,6 +38,9 @@
false
+
+ ..\packages\MouseKeyHook.5.6.0\lib\net40\Gma.System.MouseKeyHook.dll
+
@@ -93,6 +96,7 @@
+
diff --git a/src/Carnac.Logic/KeyProvider.cs b/src/Carnac.Logic/KeyProvider.cs
index 66f05236..4e8beda1 100644
--- a/src/Carnac.Logic/KeyProvider.cs
+++ b/src/Carnac.Logic/KeyProvider.cs
@@ -10,6 +10,7 @@
using Carnac.Logic.Models;
using Microsoft.Win32;
using System.Windows.Media;
+using Carnac.Logic.MouseMonitor;
using SettingsProviderNet;
using System.Text.RegularExpressions;
@@ -96,7 +97,10 @@ public IObservable GetKeyStream()
winKeyPressed = false;
}, observer.OnError);
- var keyStreamSubsription = interceptKeysSource.GetKeyStream()
+ var keyStreamSubsription = Observable.Merge(
+ new IObservable[2] {
+ interceptKeysSource.GetKeyStream(),
+ InterceptMouse.Current.GetKeyStream() })
.Select(DetectWindowsKey)
.Where(k => !IsModifierKeyPress(k) && k.KeyDirection == KeyDirection.Down)
.Select(ToCarnacKeyPress)
@@ -160,6 +164,7 @@ static IEnumerable ToInputs(bool isLetter, bool isWinKeyPressed, Interce
var controlPressed = interceptKeyEventArgs.ControlPressed;
var altPressed = interceptKeyEventArgs.AltPressed;
var shiftPressed = interceptKeyEventArgs.ShiftPressed;
+ var mouseAction = InterceptMouse.MouseKeys.Contains(interceptKeyEventArgs.Key);
if (controlPressed)
yield return "Ctrl";
if (altPressed)
@@ -167,7 +172,7 @@ static IEnumerable ToInputs(bool isLetter, bool isWinKeyPressed, Interce
if (isWinKeyPressed)
yield return "Win";
- if (controlPressed || altPressed)
+ if (controlPressed || altPressed || mouseAction)
{
//Treat as a shortcut, don't be too smart
if (shiftPressed)
diff --git a/src/Carnac.Logic/Models/Message.cs b/src/Carnac.Logic/Models/Message.cs
index 43c46cd0..84e9793e 100644
--- a/src/Carnac.Logic/Models/Message.cs
+++ b/src/Carnac.Logic/Models/Message.cs
@@ -3,6 +3,7 @@
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Media;
+using Carnac.Logic.MouseMonitor;
namespace Carnac.Logic.Models
{
@@ -30,7 +31,8 @@ public Message(KeyPress key)
{
processName = key.Process.ProcessName;
processIcon = key.Process.ProcessIcon;
- canBeMerged = !key.HasModifierPressed;
+ // allow to aggregate all key combination as to not spam if ctrl + mousewheel is used.
+ canBeMerged = true; // !key.HasModifierPressed;
isModifier = key.HasModifierPressed;
keys = new ReadOnlyCollection(new[] { key });
@@ -109,6 +111,28 @@ public static Message MergeIfNeeded(Message previousMessage, Message newMessage)
return ShouldCreateNewMessage(previousMessage, newMessage)
? newMessage
: previousMessage.Merge(newMessage);
+ /*
+ * Code used when mouse and show modifiers standalone are mixed together
+ */
+ /*
+ // replace key was after standalone modifier keypress, replace by new Message
+ if (previousMessage.keys != null && KeyProvider.IsModifierKeyPress(previousMessage.keys[0].InterceptKeyEventArgs))
+ {
+ return previousMessage.Replace(newMessage);
+ }
+ // if current is modifier and previous is a mouse action ignore modifierkeypress
+ if (previousMessage.keys != null && KeyProvider.IsModifierKeyPress(newMessage.keys[0].InterceptKeyEventArgs)
+ && InterceptMouse.MouseKeys.Contains(previousMessage.keys[0].Key))
+ {
+ return previousMessage.Replace(previousMessage);
+ }
+
+ if (ShouldCreateNewMessage(previousMessage, newMessage))
+ {
+ return newMessage;
+ }
+ return previousMessage.Merge(newMessage);
+ */
}
static bool ShouldCreateNewMessage(Message previous, Message current)
@@ -116,7 +140,11 @@ static bool ShouldCreateNewMessage(Message previous, Message current)
return previous.ProcessName != current.ProcessName ||
current.LastMessage.Subtract(previous.LastMessage) > OneSecond ||
!previous.CanBeMerged ||
- !current.CanBeMerged;
+ !current.CanBeMerged ||
+ // new message for different mouse keys;
+ ((InterceptMouse.MouseKeys.Contains(current.keys[0].Key) ||
+ (previous.keys != null && InterceptMouse.MouseKeys.Contains(previous.keys[0].Key)))
+ && !previous.keys[0].Input.SequenceEqual(current.keys[0].Input)); ;
}
public Message FadeOut()
diff --git a/src/Carnac.Logic/Models/PopupSettings.cs b/src/Carnac.Logic/Models/PopupSettings.cs
index b2be6486..8195e3b4 100644
--- a/src/Carnac.Logic/Models/PopupSettings.cs
+++ b/src/Carnac.Logic/Models/PopupSettings.cs
@@ -93,5 +93,40 @@ public string SortDescription
public bool SettingsConfigured { get; set; }
public bool ShowOnlyModifiers { get; set; }
public bool ShowSpaceAsUnicode { get; set; }
+
+ /* Following mouse-related settings */
+ [DefaultValue(true)]
+ public bool ShowMouseClicks { get; set; }
+
+ [DefaultValue(true)]
+ public bool ShowMousePopup { get; set; }
+
+ [DefaultValue("YellowGreen")]
+ public string LeftClickColor { get; set; }
+
+ [DefaultValue("RoyalBlue")]
+ public string RightClickColor { get; set; }
+
+ [DefaultValue(1)]
+ public double ClickStartScale { get; set; }
+
+ [DefaultValue(4)]
+ public double ClickStopScale { get; set; }
+
+ [DefaultValue(3700)]
+ public int ClickFadeDelay { get; set; }
+
+ [DefaultValue(1)]
+ public double ClickStartBorder { get; set; }
+
+ [DefaultValue(0.8)]
+ public double ClickStartOpacity { get; set; }
+
+ [DefaultValue(2)]
+ public double ClickStopBorder { get; set; }
+
+ [DefaultValue(0)]
+ public double ClickStopOpacity { get; set; }
+ public string ClickColor { get; set; }
}
}
diff --git a/src/Carnac.Logic/MouseMonitor/InterceptMouse.cs b/src/Carnac.Logic/MouseMonitor/InterceptMouse.cs
new file mode 100644
index 00000000..b6562528
--- /dev/null
+++ b/src/Carnac.Logic/MouseMonitor/InterceptMouse.cs
@@ -0,0 +1,111 @@
+using Carnac.Logic.KeyMonitor;
+using System;
+using System.Diagnostics;
+using System.Reactive.Disposables;
+using System.Reactive.Linq;
+using System.Windows.Forms;
+using Gma.System.MouseKeyHook;
+using System.Collections.Generic;
+
+namespace Carnac.Logic.MouseMonitor
+{
+ public class InterceptMouse : IInterceptKeys
+ {
+
+ public static readonly InterceptMouse Current = new InterceptMouse();
+ readonly IKeyboardMouseEvents m_GlobalHook = Hook.GlobalEvents();
+ readonly IObservable keyStream;
+ private IObserver observer;
+ private readonly KeysConverter kc = new KeysConverter();
+
+ public static readonly List MouseKeys = new List()
+ {
+ Keys.LButton,
+ Keys.MButton,
+ Keys.RButton,
+ Keys.XButton1,
+ Keys.XButton2,
+ Keys.VolumeUp,
+ Keys.VolumeDown
+ };
+
+ InterceptMouse()
+ {
+ keyStream = Observable.Create(observer =>
+ {
+ this.observer = observer;
+ m_GlobalHook.MouseClick += OnMouseClick;
+ m_GlobalHook.MouseDoubleClick += OnMouseDoubleClick;
+ m_GlobalHook.MouseWheel += HookManager_MouseWheel;
+ Debug.Write("Subscribed to mouse");
+
+ return Disposable.Create(() =>
+ {
+ m_GlobalHook.MouseClick -= OnMouseClick;
+ m_GlobalHook.MouseDoubleClick -= OnMouseDoubleClick;
+ m_GlobalHook.MouseWheel -= HookManager_MouseWheel;
+ m_GlobalHook.Dispose();
+ Debug.Write("Unsubscribed from mouse");
+ });
+ })
+ .Publish().RefCount();
+
+ }
+
+ private Keys MouseButtonsToKeys(MouseButtons button)
+ {
+ switch (button)
+ {
+ case MouseButtons.Left:
+ return Keys.LButton;
+ case MouseButtons.Middle:
+ return Keys.MButton;
+ case MouseButtons.Right:
+ return Keys.RButton;
+ case MouseButtons.XButton1:
+ return Keys.XButton1;
+ case MouseButtons.XButton2:
+ return Keys.XButton2;
+ default:
+ return Keys.None;
+ }
+ }
+
+ private void OnMouseClick(object sender, MouseEventArgs e)
+ {
+ observer.OnNext(new InterceptKeyEventArgs(
+ MouseButtonsToKeys(e.Button),
+ KeyDirection.Down,
+ Control.ModifierKeys == Keys.Alt,
+ Control.ModifierKeys == Keys.Control,
+ Control.ModifierKeys == Keys.Shift));
+ }
+
+ private void OnMouseDoubleClick(object sender, MouseEventArgs e)
+ {
+ observer.OnNext(new InterceptKeyEventArgs(
+ MouseButtonsToKeys(e.Button),
+ KeyDirection.Down,
+ Control.ModifierKeys == Keys.Alt,
+ Control.ModifierKeys == Keys.Control,
+ Control.ModifierKeys == Keys.Shift));
+ }
+
+ private void HookManager_MouseWheel(object sender, MouseEventArgs e)
+ {
+ // for now using VolumeDown and Up as proxy could be refactored
+ observer.OnNext(new InterceptKeyEventArgs(
+ e.Delta > 0 ? Keys.VolumeUp : Keys.VolumeDown,
+ KeyDirection.Down,
+ Control.ModifierKeys == Keys.Alt,
+ Control.ModifierKeys == Keys.Control,
+ Control.ModifierKeys == Keys.Shift));
+ }
+
+ public IObservable GetKeyStream()
+ {
+ return keyStream;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/src/Carnac.Logic/Properties/AssemblyInfo.cs b/src/Carnac.Logic/Properties/AssemblyInfo.cs
index fbaf1e20..89b0c8d4 100644
--- a/src/Carnac.Logic/Properties/AssemblyInfo.cs
+++ b/src/Carnac.Logic/Properties/AssemblyInfo.cs
@@ -31,8 +31,8 @@
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
-// [assembly: AssemblyVersion("2.3.0.0")]
-[assembly: AssemblyVersion("2.3.0.0")]
-[assembly: AssemblyFileVersion("2.3.0.0")]
+// [assembly: AssemblyVersion("2.4.0.0")]
+[assembly: AssemblyVersion("2.4.0.0")]
+[assembly: AssemblyFileVersion("2.4.0.0")]
-[assembly: AssemblyInformationalVersion("2.3.0-ci.32+Branch.master.Sha.69515520313d5c26261a8b05660255cd9da08bfa")]
+[assembly: AssemblyInformationalVersion("2.4.0-mouse-presenter.1+4.Branch.feature-mouse-presenter.Sha.ac8188c012650eb9eda0fba4233527d9c4933fb7")]
diff --git a/src/Carnac.Logic/packages.config b/src/Carnac.Logic/packages.config
index 6d600c42..041b9458 100644
--- a/src/Carnac.Logic/packages.config
+++ b/src/Carnac.Logic/packages.config
@@ -1,6 +1,7 @@
+
diff --git a/src/Carnac.Tests/Properties/AssemblyInfo.cs b/src/Carnac.Tests/Properties/AssemblyInfo.cs
index bd014ecc..cc79c23a 100644
--- a/src/Carnac.Tests/Properties/AssemblyInfo.cs
+++ b/src/Carnac.Tests/Properties/AssemblyInfo.cs
@@ -31,8 +31,8 @@
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
-// [assembly: AssemblyVersion("2.3.0.0")]
-[assembly: AssemblyVersion("2.3.0.0")]
-[assembly: AssemblyFileVersion("2.3.0.0")]
+// [assembly: AssemblyVersion("2.4.0.0")]
+[assembly: AssemblyVersion("2.4.0.0")]
+[assembly: AssemblyFileVersion("2.4.0.0")]
-[assembly: AssemblyInformationalVersion("2.3.0-ci.32+Branch.master.Sha.69515520313d5c26261a8b05660255cd9da08bfa")]
+[assembly: AssemblyInformationalVersion("2.4.0-mouse-presenter.1+4.Branch.feature-mouse-presenter.Sha.ac8188c012650eb9eda0fba4233527d9c4933fb7")]
diff --git a/src/Carnac/App.xaml.cs b/src/Carnac/App.xaml.cs
index 040c9b84..441b4309 100644
--- a/src/Carnac/App.xaml.cs
+++ b/src/Carnac/App.xaml.cs
@@ -83,6 +83,7 @@ protected override void OnExit(ExitEventArgs e)
{
trayIcon.Dispose();
carnac.Dispose();
+ keyShowView.Dispose();
ProcessUtilities.DestroyMutex();
base.OnExit(e);
diff --git a/src/Carnac/Carnac.csproj b/src/Carnac/Carnac.csproj
index 04636d02..53c1c9ca 100644
--- a/src/Carnac/Carnac.csproj
+++ b/src/Carnac/Carnac.csproj
@@ -87,6 +87,9 @@
..\packages\DeltaCompressionDotNet.1.0.0\lib\net45\DeltaCompressionDotNet.PatchApi.dll
+
+ ..\packages\MouseKeyHook.5.6.0\lib\net40\Gma.System.MouseKeyHook.dll
+
..\packages\squirrel.windows.1.5.2\lib\Net45\ICSharpCode.SharpZipLib.dll
diff --git a/src/Carnac/CarnacTrayIcon.cs b/src/Carnac/CarnacTrayIcon.cs
index cf776940..30e25c49 100644
--- a/src/Carnac/CarnacTrayIcon.cs
+++ b/src/Carnac/CarnacTrayIcon.cs
@@ -19,12 +19,17 @@ public CarnacTrayIcon()
Text = Properties.Resources.ShellView_Exit
};
+ var PreferencesMenuItem = new MenuItem
+ {
+ Text = Properties.Resources.ShellView_Preferences
+ };
+
var iconStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Carnac.icon.embedded.ico");
trayIcon = new NotifyIcon
{
Icon = new Icon(iconStream),
- ContextMenu = new ContextMenu(new[] { exitMenuItem })
+ ContextMenu = new ContextMenu(new[] { PreferencesMenuItem, exitMenuItem })
};
exitMenuItem.Click += (sender, args) =>
@@ -32,6 +37,12 @@ public CarnacTrayIcon()
trayIcon.Visible = false;
Application.Current.Shutdown();
};
+
+ PreferencesMenuItem.Click += (sender, args) =>
+ {
+ ShowPreferencesWindow();
+ };
+
trayIcon.MouseClick += NotifyIconClick;
trayIcon.Visible = true;
}
@@ -42,15 +53,20 @@ void NotifyIconClick(object sender, MouseEventArgs mouseEventArgs)
{
if (mouseEventArgs.Button == MouseButtons.Left)
{
- var preferencesWindow = Application.Current.Windows.Cast().FirstOrDefault(x => x.Name == "PreferencesViewWindow");
- if (preferencesWindow != null)
- {
- preferencesWindow.Activate();
- }
- else
- {
- OpenPreferences();
- }
+ ShowPreferencesWindow();
+ }
+ }
+
+ public void ShowPreferencesWindow()
+ {
+ var preferencesWindow = Application.Current.Windows.Cast().FirstOrDefault(x => x.Name == "PreferencesViewWindow");
+ if (preferencesWindow != null)
+ {
+ preferencesWindow.Activate();
+ }
+ else
+ {
+ OpenPreferences();
}
}
diff --git a/src/Carnac/Properties/AssemblyInfo.cs b/src/Carnac/Properties/AssemblyInfo.cs
index 2ccb2557..322377f6 100644
--- a/src/Carnac/Properties/AssemblyInfo.cs
+++ b/src/Carnac/Properties/AssemblyInfo.cs
@@ -48,7 +48,7 @@
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
-// [assembly: AssemblyVersion("2.3.0.0")]
-[assembly: AssemblyVersion("2.3.0.0")]
-[assembly: AssemblyFileVersion("2.3.0.0")]
-[assembly: AssemblyInformationalVersion("2.3.0-ci.32+Branch.master.Sha.69515520313d5c26261a8b05660255cd9da08bfa")]
+// [assembly: AssemblyVersion("2.4.0.0")]
+[assembly: AssemblyVersion("2.4.0.0")]
+[assembly: AssemblyFileVersion("2.4.0.0")]
+[assembly: AssemblyInformationalVersion("2.4.0-mouse-presenter.1+4.Branch.feature-mouse-presenter.Sha.ac8188c012650eb9eda0fba4233527d9c4933fb7")]
diff --git a/src/Carnac/Properties/Resources.Designer.cs b/src/Carnac/Properties/Resources.Designer.cs
index 5a19a7ce..40a8c0e2 100644
--- a/src/Carnac/Properties/Resources.Designer.cs
+++ b/src/Carnac/Properties/Resources.Designer.cs
@@ -19,7 +19,7 @@ namespace Carnac.Properties {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
@@ -68,5 +68,14 @@ internal static string ShellView_Exit {
return ResourceManager.GetString("ShellView_Exit", resourceCulture);
}
}
+
+ ///
+ /// Looks up a localized string similar to Preferences.
+ ///
+ internal static string ShellView_Preferences {
+ get {
+ return ResourceManager.GetString("ShellView_Preferences", resourceCulture);
+ }
+ }
}
}
diff --git a/src/Carnac/Properties/Resources.resx b/src/Carnac/Properties/Resources.resx
index 8acde8dc..af198c3e 100644
--- a/src/Carnac/Properties/Resources.resx
+++ b/src/Carnac/Properties/Resources.resx
@@ -46,7 +46,7 @@
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
- : System.Serialization.Formatters.Binary.BinaryFormatter
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
@@ -60,6 +60,7 @@
: and then encoded with base64 encoding.
-->
+
@@ -68,9 +69,10 @@
-
+
+
@@ -85,9 +87,10 @@
-
+
+
@@ -109,12 +112,15 @@
2.0
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Exit
+
+ Preferences
+
\ No newline at end of file
diff --git a/src/Carnac/UI/KeyShowView.xaml b/src/Carnac/UI/KeyShowView.xaml
index 4fb16157..4d8a13c4 100644
--- a/src/Carnac/UI/KeyShowView.xaml
+++ b/src/Carnac/UI/KeyShowView.xaml
@@ -24,7 +24,7 @@
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Carnac/UI/KeyShowView.xaml.cs b/src/Carnac/UI/KeyShowView.xaml.cs
index 72abbdf7..1b615fd3 100644
--- a/src/Carnac/UI/KeyShowView.xaml.cs
+++ b/src/Carnac/UI/KeyShowView.xaml.cs
@@ -3,16 +3,22 @@
using System.Timers;
using System.Windows;
using System.Windows.Interop;
+using System.Windows.Media.Animation;
using Carnac.Logic;
+using Gma.System.MouseKeyHook;
namespace Carnac.UI
{
- public partial class KeyShowView
+ public partial class KeyShowView : IDisposable
{
+ private Storyboard sb;
+ IKeyboardMouseEvents m_GlobalHook = null;
+
public KeyShowView(KeyShowViewModel keyShowViewModel)
{
DataContext = keyShowViewModel;
InitializeComponent();
+ keyShowViewModel.Settings.PropertyChanged += Settings_PropertyChanged;
}
protected override void OnSourceInitialized(EventArgs e)
@@ -37,6 +43,18 @@ protected override void OnSourceInitialized(EventArgs e)
Left = vm.Settings.Left;
vm.Settings.LeftChanged += SettingsLeftChanged;
WindowState = WindowState.Maximized;
+ if (vm.Settings.ShowMouseClicks)
+ {
+ SetupMouseEvents();
+ }
+ }
+
+ public void Dispose()
+ {
+ if (m_GlobalHook != null)
+ {
+ m_GlobalHook.Dispose();
+ }
}
[DllImport("user32.dll", SetLastError = true)]
@@ -82,7 +100,7 @@ public static readonly int
private void WindowLoaded(object sender, RoutedEventArgs e)
{
-
+ sb = this.FindResource("clickHighlighterStoryboard") as Storyboard;
}
void SettingsLeftChanged(object sender, EventArgs e)
@@ -92,5 +110,69 @@ void SettingsLeftChanged(object sender, EventArgs e)
Left = vm.Settings.Left;
WindowState = WindowState.Maximized;
}
+
+ void Settings_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
+ {
+ var vm = ((KeyShowViewModel)DataContext);
+ switch (e.PropertyName)
+ {
+ case "ClickFadeDelay":
+ Duration d = TimeSpan.FromMilliseconds(vm.Settings.ClickFadeDelay);
+ foreach (DoubleAnimation da in sb.Children)
+ {
+ da.Duration = d;
+ }
+ break;
+ case "ShowMouseClicks":
+ if (vm.Settings.ShowMouseClicks)
+ {
+ SetupMouseEvents();
+ }
+ else
+ {
+ DestroyMouseEvents();
+ }
+ break;
+ }
+ }
+
+ void SetupMouseEvents()
+ {
+ if (m_GlobalHook == null)
+ {
+ m_GlobalHook = Hook.GlobalEvents();
+ }
+ m_GlobalHook.MouseDown += OnMouseDown;
+ m_GlobalHook.MouseMove += OnMouseMove;
+ }
+
+ void DestroyMouseEvents()
+ {
+ if (m_GlobalHook == null)
+ {
+ return;
+ }
+ m_GlobalHook.MouseDown -= OnMouseDown;
+ m_GlobalHook.MouseMove -= OnMouseMove;
+ m_GlobalHook.Dispose();
+ m_GlobalHook = null;
+ }
+
+ private void OnMouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
+ {
+ var vm = ((KeyShowViewModel)DataContext);
+ vm.Settings.ClickColor = vm.Settings.LeftClickColor;
+ if (e.Button == System.Windows.Forms.MouseButtons.Right)
+ {
+ vm.Settings.ClickColor = vm.Settings.RightClickColor;
+ }
+ sb.Begin();
+ }
+
+ private void OnMouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
+ {
+ var vm = ((KeyShowViewModel)DataContext);
+ vm.CursorPosition = PointFromScreen(new Point(e.X, e.Y));
+ }
}
}
diff --git a/src/Carnac/UI/KeyShowViewModel.cs b/src/Carnac/UI/KeyShowViewModel.cs
index 590608cf..c2381988 100644
--- a/src/Carnac/UI/KeyShowViewModel.cs
+++ b/src/Carnac/UI/KeyShowViewModel.cs
@@ -1,4 +1,5 @@
using System.Collections.ObjectModel;
+using System.Windows;
using Carnac.Logic;
using Carnac.Logic.Models;
@@ -15,5 +16,12 @@ public KeyShowViewModel(PopupSettings popupSettings)
public ObservableCollection Messages { get; private set; }
public PopupSettings Settings { get; set; }
+
+ public Point CursorPosition { get; set; }
+
+ public Thickness CursorMargins
+ {
+ get { return new Thickness(CursorPosition.X - 10, CursorPosition.Y - 10, 0, 0); }
+ }
}
}
diff --git a/src/Carnac/UI/PreferencesView.xaml b/src/Carnac/UI/PreferencesView.xaml
index 583487c1..d4732207 100644
--- a/src/Carnac/UI/PreferencesView.xaml
+++ b/src/Carnac/UI/PreferencesView.xaml
@@ -95,7 +95,7 @@
-
+
@@ -166,6 +166,86 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Carnac/UI/PreferencesViewModel.cs b/src/Carnac/UI/PreferencesViewModel.cs
index 7eb14b5d..a690a64f 100644
--- a/src/Carnac/UI/PreferencesViewModel.cs
+++ b/src/Carnac/UI/PreferencesViewModel.cs
@@ -40,9 +40,23 @@ public PreferencesViewModel(ISettingsProvider settingsProvider, IScreenManager s
if (Settings.ItemBackgroundColor == name)
ItemBackgroundColor = availableColor;
+ if (Settings.LeftClickColor == name)
+ LeftClickColor = availableColor;
+ if (Settings.RightClickColor == name)
+ RightClickColor = availableColor;
+
AvailableColors.Add(availableColor);
}
+ if (LeftClickColor == null)
+ {
+ LeftClickColor = new AvailableColor("YellowGreen", Colors.OrangeRed);
+ }
+ if (RightClickColor == null)
+ {
+ RightClickColor = new AvailableColor("RoyalBlue", Colors.RoyalBlue);
+ }
+
SaveCommand = new DelegateCommand(SaveSettings);
ResetToDefaultsCommand = new DelegateCommand(() => settingsProvider.ResetToDefaults());
VisitCommand = new DelegateCommand(Visit);
@@ -77,7 +91,9 @@ public string Version
"Dmitry Pursanov",
"Chris Sainty",
"Andrew Tobin",
- "Henrik Andersson"
+ "Henrik Andersson",
+ "Boris Fritscher",
+ "Dimitrios Karvounaris"
};
readonly List components = new List
{
@@ -85,7 +101,8 @@ public string Version
"Fody",
"NSubstitute",
"Reactive Extensions",
- "Squirrel.Windows"
+ "Squirrel.Windows",
+ "MouseKeyHook"
};
public string Authors
{
@@ -101,6 +118,10 @@ public string Components
public AvailableColor ItemBackgroundColor { get; set; }
+ public AvailableColor LeftClickColor { get; set; }
+
+ public AvailableColor RightClickColor { get; set; }
+
void Visit()
{
try
@@ -139,6 +160,8 @@ void SaveSettings()
Settings.SettingsConfigured = true;
Settings.FontColor = FontColor.Name;
Settings.ItemBackgroundColor = ItemBackgroundColor.Name;
+ Settings.LeftClickColor = LeftClickColor.Name;
+ Settings.RightClickColor = RightClickColor.Name;
settingsProvider.SaveSettings(Settings);
}
diff --git a/src/Carnac/packages.config b/src/Carnac/packages.config
index f61f5d46..2c0c5591 100644
--- a/src/Carnac/packages.config
+++ b/src/Carnac/packages.config
@@ -6,6 +6,7 @@
+
diff --git a/src/KeyStreamCapture/Properties/AssemblyInfo.cs b/src/KeyStreamCapture/Properties/AssemblyInfo.cs
index 71c0db37..5b8b6444 100644
--- a/src/KeyStreamCapture/Properties/AssemblyInfo.cs
+++ b/src/KeyStreamCapture/Properties/AssemblyInfo.cs
@@ -50,8 +50,8 @@
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
-// [assembly: AssemblyVersion("2.3.0.0")]
-[assembly: AssemblyVersion("2.3.0.0")]
-[assembly: AssemblyFileVersion("2.3.0.0")]
+// [assembly: AssemblyVersion("2.4.0.0")]
+[assembly: AssemblyVersion("2.4.0.0")]
+[assembly: AssemblyFileVersion("2.4.0.0")]
-[assembly: AssemblyInformationalVersion("2.3.0-ci.32+Branch.master.Sha.69515520313d5c26261a8b05660255cd9da08bfa")]
+[assembly: AssemblyInformationalVersion("2.4.0-mouse-presenter.1+4.Branch.feature-mouse-presenter.Sha.ac8188c012650eb9eda0fba4233527d9c4933fb7")]