diff --git a/README.md b/README.md
index df59e8fb..45420cb3 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,10 @@
-## Carnac the Magnificent Keyboard Utility
+## Carnac the Magnificent Keyboard Utility & Mouse Highlighter*
+
+This is a Fork of Carnac which adds mouse click highlights with circles, as well as key icons. The current version can be manually downloaded and tested from the [release page](https://github.com/bfritscher/carnac/releases). This project is not actively maintained, but patched together in my spare time and based on my needs when giving tutorials.
+
+
+## Original Readme
+
[![Join the chat at https://gitter.im/Code52/carnac](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Code52/carnac?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
@@ -21,7 +27,7 @@ Alternatively, you can grab the latest zip file from [here](https://github.com/C
### Updating
-We use `Squirrel.Windows` to update your `carnac` application.
+We use `Squirrel.Windows` to update your `carnac` application.
The application will check for updates in the background, if a new version has been released, it will automatically install the new version and once you restart `carnac` you will be up-to-date.
@@ -40,13 +46,13 @@ If you want to stop `Carnac` from recording certain key strokes, you can enter _
* [The simple guide to GIT guide](http://rogerdudler.github.com/git-guide/)
* [Open an issue](https://github.com/Code52/carnac/issues) if you encounter a bug or have a suggestion for improvements/features
-Once you're familiar with Git and GitHub, clone the repository and run the ```.\build.cmd``` script to compile the code and run all the unit tests. You can use this script to test your changes quickly.
+Once you're familiar with Git and GitHub, clone the repository and run the `.\build.cmd` script to compile the code and run all the unit tests. You can use this script to test your changes quickly.
### Resources
This blog series covers a series of refactorings which have recently happened in Carnac to make better use of Rx.
If you are learning Rx and want to be shown through Carnac's codebase then this blog series may help you.
-[Part 1 - Refactoring the InterceptKeys class ](http://jake.ginnivan.net/blog/carnac-improvements/part-1/)
-[Part 2 - Refactoring the MessageProvider class](http://jake.ginnivan.net/blog/carnac-improvements/part-2/)
-[Part 3 - Introducing the MessageController class](http://jake.ginnivan.net/blog/carnac-improvements/part-3/)
+[Part 1 - Refactoring the InterceptKeys class ](http://jake.ginnivan.net/blog/carnac-improvements/part-1/)
+[Part 2 - Refactoring the MessageProvider class](http://jake.ginnivan.net/blog/carnac-improvements/part-2/)
+[Part 3 - Introducing the MessageController class](http://jake.ginnivan.net/blog/carnac-improvements/part-3/)
diff --git a/src/Carnac.Logic/Carnac.Logic.csproj b/src/Carnac.Logic/Carnac.Logic.csproj
index 38a1f54e..2b9e39e1 100644
--- a/src/Carnac.Logic/Carnac.Logic.csproj
+++ b/src/Carnac.Logic/Carnac.Logic.csproj
@@ -38,6 +38,9 @@
false
+
+ ..\packages\MouseKeyHook.5.4.0\lib\net40\Gma.System.MouseKeyHook.dll
+
@@ -93,6 +96,7 @@
+
@@ -151,7 +155,7 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
@@ -135,7 +431,7 @@
-
+
@@ -164,40 +460,68 @@
-
+
-
-
+
-
-
-
+
+
+
+
-
-
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -206,4 +530,12 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Carnac/UI/KeyShowView.xaml.cs b/src/Carnac/UI/KeyShowView.xaml.cs
index 72abbdf7..6f6409fc 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,81 @@ 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;
+ }
+ else if (e.Button == System.Windows.Forms.MouseButtons.Middle)
+ {
+ vm.Settings.ClickColor = vm.Settings.ScrollClickColor;
+ }
+ else if (e.Button == System.Windows.Forms.MouseButtons.XButton1)
+ {
+ vm.Settings.ClickColor = vm.Settings.XButton1ClickColor;
+ }
+ else if (e.Button == System.Windows.Forms.MouseButtons.XButton2)
+ {
+ vm.Settings.ClickColor = vm.Settings.XButton2ClickColor;
+ }
+ 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..98c8a412 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..bca69c7c 100644
--- a/src/Carnac/UI/PreferencesView.xaml
+++ b/src/Carnac/UI/PreferencesView.xaml
@@ -95,7 +95,7 @@
-
+
@@ -166,6 +166,114 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Carnac/UI/PreferencesViewModel.cs b/src/Carnac/UI/PreferencesViewModel.cs
index 7eb14b5d..1d1d3681 100644
--- a/src/Carnac/UI/PreferencesViewModel.cs
+++ b/src/Carnac/UI/PreferencesViewModel.cs
@@ -40,9 +40,42 @@ public PreferencesViewModel(ISettingsProvider settingsProvider, IScreenManager s
if (Settings.ItemBackgroundColor == name)
ItemBackgroundColor = availableColor;
+ if (Settings.LeftClickColor == name)
+ LeftClickColor = availableColor;
+ if (Settings.RightClickColor == name)
+ RightClickColor = availableColor;
+ if (Settings.ScrollClickColor == name)
+ ScrollClickColor = availableColor;
+ if (Settings.XButton1ClickColor == name)
+ XButton1ClickColor = availableColor;
+ if (Settings.XButton2ClickColor == name)
+ XButton2ClickColor = availableColor;
+
AvailableColors.Add(availableColor);
}
+ if (LeftClickColor == null)
+ {
+ LeftClickColor = new AvailableColor("OrangeRed", Colors.OrangeRed);
+ }
+ if (RightClickColor == null)
+ {
+ RightClickColor = new AvailableColor("RoyalBlue", Colors.RoyalBlue);
+ }
+ if (ScrollClickColor == null)
+ {
+ ScrollClickColor = new AvailableColor("Gold", Colors.Gold);
+ }
+ if (XButton1ClickColor == null)
+ {
+ XButton1ClickColor = new AvailableColor("Peru", Colors.Peru);
+ }
+ if (XButton2ClickColor == null)
+ {
+ XButton2ClickColor = new AvailableColor("Plum", Colors.Plum);
+ }
+
+
SaveCommand = new DelegateCommand(SaveSettings);
ResetToDefaultsCommand = new DelegateCommand(() => settingsProvider.ResetToDefaults());
VisitCommand = new DelegateCommand(Visit);
@@ -77,7 +110,8 @@ public string Version
"Dmitry Pursanov",
"Chris Sainty",
"Andrew Tobin",
- "Henrik Andersson"
+ "Henrik Andersson",
+ "Boris Fritscher"
};
readonly List components = new List
{
@@ -85,7 +119,8 @@ public string Version
"Fody",
"NSubstitute",
"Reactive Extensions",
- "Squirrel.Windows"
+ "Squirrel.Windows",
+ "MouseKeyHook"
};
public string Authors
{
@@ -101,6 +136,16 @@ public string Components
public AvailableColor ItemBackgroundColor { get; set; }
+ public AvailableColor LeftClickColor { get; set; }
+
+ public AvailableColor RightClickColor { get; set; }
+
+ public AvailableColor ScrollClickColor { get; set; }
+
+ public AvailableColor XButton1ClickColor { get; set; }
+
+ public AvailableColor XButton2ClickColor { get; set; }
+
void Visit()
{
try
@@ -139,6 +184,11 @@ void SaveSettings()
Settings.SettingsConfigured = true;
Settings.FontColor = FontColor.Name;
Settings.ItemBackgroundColor = ItemBackgroundColor.Name;
+ Settings.LeftClickColor = LeftClickColor.Name;
+ Settings.RightClickColor = RightClickColor.Name;
+ Settings.ScrollClickColor = ScrollClickColor.Name;
+ Settings.XButton1ClickColor = XButton1ClickColor.Name;
+ Settings.XButton2ClickColor = XButton2ClickColor.Name;
settingsProvider.SaveSettings(Settings);
}
diff --git a/src/Carnac/UI/ToSpecialKeyConverter.cs b/src/Carnac/UI/ToSpecialKeyConverter.cs
new file mode 100644
index 00000000..185b2858
--- /dev/null
+++ b/src/Carnac/UI/ToSpecialKeyConverter.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Windows.Data;
+
+namespace Carnac.UI
+{
+ public class ToSpecialKeyConverter : IValueConverter
+ {
+
+ private readonly List specialKeys = new List(){
+ "Escape",
+ "Alt",
+ "Ctrl",
+ "Shift",
+ "Tab",
+ "Delete",
+ "Insert",
+ "Home",
+ "Next",
+ "PageUp",
+ "PageDown",
+ "End",
+ "Back",
+ "NumLock",
+ "PrintScreen",
+ "Scroll",
+ "Capital",
+ "F1",
+ "F2",
+ "F3",
+ "F4",
+ "F5",
+ "F6",
+ "F7",
+ "F8",
+ "F9",
+ "F10",
+ "F11",
+ "F12",
+ "Apps",
+ "BrowserHome",
+ };
+
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return specialKeys.Contains(value.ToString()) ? "SPECIAL_KEY" : value;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/src/Carnac/packages.config b/src/Carnac/packages.config
index f61f5d46..dcd43146 100644
--- a/src/Carnac/packages.config
+++ b/src/Carnac/packages.config
@@ -6,6 +6,7 @@
+