diff --git a/AnneProKeyboard/AboutPage.xaml b/AnneProKeyboard/AboutPage.xaml
new file mode 100644
index 0000000..d5d2536
--- /dev/null
+++ b/AnneProKeyboard/AboutPage.xaml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/AnneProKeyboard/AboutPage.xaml.cs b/AnneProKeyboard/AboutPage.xaml.cs
new file mode 100644
index 0000000..dd766e1
--- /dev/null
+++ b/AnneProKeyboard/AboutPage.xaml.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices.WindowsRuntime;
+using Windows.Foundation;
+using Windows.Foundation.Collections;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Controls.Primitives;
+using Windows.UI.Xaml.Data;
+using Windows.UI.Xaml.Input;
+using Windows.UI.Xaml.Media;
+using Windows.UI.Xaml.Navigation;
+
+// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
+
+namespace AnneProKeyboard
+{
+ ///
+ /// An empty page that can be used on its own or navigated to within a Frame.
+ ///
+ public sealed partial class AboutPage : Page
+ {
+ public AboutPage()
+ {
+ this.InitializeComponent();
+ }
+ }
+}
diff --git a/AnneProKeyboard/AnneProKeyboard.csproj b/AnneProKeyboard/AnneProKeyboard.csproj
index 9695768..b6e9601 100644
--- a/AnneProKeyboard/AnneProKeyboard.csproj
+++ b/AnneProKeyboard/AnneProKeyboard.csproj
@@ -97,15 +97,24 @@
+
+ AboutPage.xaml
+ App.xaml
+
+ MainPage.xaml
+
+
+ LightingPage.xaml
+
-
- MainPage.xaml
+
+ LayoutPage.xaml
@@ -116,7 +125,9 @@
+
+
@@ -131,7 +142,19 @@
MSBuild:CompileDesigner
+
+ Designer
+ MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+ MSBuild:CompileDesigner
diff --git a/AnneProKeyboard/App.xaml.cs b/AnneProKeyboard/App.xaml.cs
index 614b584..15ba4a4 100644
--- a/AnneProKeyboard/App.xaml.cs
+++ b/AnneProKeyboard/App.xaml.cs
@@ -5,8 +5,11 @@
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
+using Windows.ApplicationModel.Core;
using Windows.Foundation;
using Windows.Foundation.Collections;
+using Windows.UI.Core;
+using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
@@ -22,30 +25,19 @@ namespace AnneProKeyboard
///
sealed partial class App : Application
{
- ///
- /// Initializes the singleton application object. This is the first line of authored code
- /// executed, and as such is the logical equivalent of main() or WinMain().
- ///
+
public App()
{
this.InitializeComponent();
this.Suspending += OnSuspending;
}
- ///
- /// Invoked when the application is launched normally by the end user. Other entry points
- /// will be used such as when the application is launched to open a specific file.
- ///
- /// Details about the launch request and process.
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
-#if DEBUG
- if (System.Diagnostics.Debugger.IsAttached)
- {
- this.DebugSettings.EnableFrameRateCounter = true;
- }
-#endif
Frame rootFrame = Window.Current.Content as Frame;
+ ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;
+ ApplicationView.PreferredLaunchViewSize = new Size(1074, 800);
+ ApplicationView.GetForCurrentView().SetPreferredMinSize(new Size(1024, 604));
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
@@ -55,55 +47,68 @@ protected override void OnLaunched(LaunchActivatedEventArgs e)
rootFrame = new Frame();
rootFrame.NavigationFailed += OnNavigationFailed;
+ rootFrame.Navigated += OnNavigated;
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
- //TODO: Load state from previously suspended application
+ // TODO: Load state from previously suspended application
}
// Place the frame in the current Window
Window.Current.Content = rootFrame;
+
+ // Register a handler for BackRequested events and set the
+ // visibility of the Back button
+ SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested;
+
+ SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
+ rootFrame.CanGoBack ?
+ AppViewBackButtonVisibility.Visible :
+ AppViewBackButtonVisibility.Collapsed;
}
- if (e.PrelaunchActivated == false)
+ if (rootFrame.Content == null)
{
- if (rootFrame.Content == null)
- {
- // When the navigation stack isn't restored navigate to the first page,
- // configuring the new page by passing required information as a navigation
- // parameter
- rootFrame.Navigate(typeof(MainPage), e.Arguments);
- }
- // Ensure the current window is active
- Window.Current.Activate();
+ // When the navigation stack isn't restored navigate to the first page,
+ // configuring the new page by passing required information as a navigation
+ // parameter
+ rootFrame.Navigate(typeof(MainPage), e.Arguments);
}
- this.DebugSettings.EnableFrameRateCounter = false;
- this.DebugSettings.EnableRedrawRegions = false;
+ // Ensure the current window is active
+ Window.Current.Activate();
}
- ///
- /// Invoked when Navigation to a certain page fails
- ///
- /// The Frame which failed navigation
- /// Details about the navigation failure
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
{
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}
- ///
- /// Invoked when application execution is being suspended. Application state is saved
- /// without knowing whether the application will be terminated or resumed with the contents
- /// of memory still intact.
- ///
- /// The source of the suspend request.
- /// Details about the suspend request.
+ private void OnNavigated(object sender, NavigationEventArgs e)
+ {
+ // Each time a navigation event occurs, update the Back button's visibility
+ SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
+ ((Frame)sender).CanGoBack ?
+ AppViewBackButtonVisibility.Visible :
+ AppViewBackButtonVisibility.Collapsed;
+ }
+
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
- //TODO: Save application state and stop any background activity
+ // TODO: Save application state and stop any background activity
deferral.Complete();
}
+
+ private void OnBackRequested(object sender, BackRequestedEventArgs e)
+ {
+ Frame rootFrame = Window.Current.Content as Frame;
+
+ if (rootFrame.CanGoBack)
+ {
+ e.Handled = true;
+ rootFrame.GoBack();
+ }
+ }
}
}
diff --git a/AnneProKeyboard/Assets/README.html b/AnneProKeyboard/Assets/README.html
new file mode 100644
index 0000000..e90f910
--- /dev/null
+++ b/AnneProKeyboard/Assets/README.html
@@ -0,0 +1,25 @@
+
+
+
Anne Keyboard Windows
+
A Universal Windows App for controlling the an Anne Pro keyboard over Bluetooth Low Energy.
+
Requirements
+
This app has been tested against Windows 10. Other version of Windows is not supported due to Universal Windows App (UWP) platform only supporting Windows 10. The keyboard has to be in L0 mode by: pressing Fn+B, Fn+0, ESC, Fn+B, +
+
Supported Features
+
+
Automatic keyboard pairing (launch the app, and it should start scanning for the keyboard)
None so far. Please submit an issue to report any bugs.
+
+
License
+
The codebase and the project are released under the permissive MIT License. The images and icons are generated using the Font Awesome font released under the OFIL license, and the font can be found on Github.
+
\ No newline at end of file
diff --git a/AnneProKeyboard/Assets/controls.png b/AnneProKeyboard/Assets/controls.png
new file mode 100644
index 0000000..be24fa4
Binary files /dev/null and b/AnneProKeyboard/Assets/controls.png differ
diff --git a/AnneProKeyboard/KeyboardProfileItem.cs b/AnneProKeyboard/KeyboardProfileItem.cs
index 76f08f0..6b62ee3 100644
--- a/AnneProKeyboard/KeyboardProfileItem.cs
+++ b/AnneProKeyboard/KeyboardProfileItem.cs
@@ -43,7 +43,7 @@ public KeyboardProfileItem(int ID, string Label)
{
this.ID = ID;
this.Label = Label;
-
+
this.KeyboardColours = new List();
// We only need 70 values to represent the 61 keys (70 is needed for some reason by the keyboard..)
@@ -176,7 +176,7 @@ public void SyncProfile(GattCharacteristic gatt)
{
this.SyncProfilePhase1(gatt);
}
-
+
// send the backlight first data, should cause a waterfall effect on syncing up the profile
private void SyncProfilePhase1(GattCharacteristic gatt)
{
@@ -190,7 +190,7 @@ private void SyncProfilePhase1(GattCharacteristic gatt)
KeyboardWriter keyboard_writer = new KeyboardWriter(gatt, lighting_meta_data, light_data);
keyboard_writer.WriteToKeyboard();
- keyboard_writer.OnWriteFinished += (object_s, events) => { SyncProfilePhase2(gatt); NotifyStatus("Keyboard light has been synced"); }; // we need to do this because of async calls, threading is fun!
+ keyboard_writer.OnWriteFinished += (object_s, events) => { SyncProfilePhase2(gatt); NotifyStatus("Keyboard light has been synced"); }; // we need to do this because of async calls, threading is fun!
keyboard_writer.OnWriteFailed += (object_s, events) => { NotifyStatus("Failed to sync profile (light): exception handled"); };
}
@@ -224,5 +224,40 @@ private void NotifyStatus(string status)
handler(status, EventArgs.Empty);
}
}
+
+ public override Boolean Equals(object obj)
+ {
+ if (obj == null)
+ {
+ return false;
+ }
+
+ if (obj.GetType() == typeof(KeyboardProfileItem))
+ {
+ KeyboardProfileItem that = obj as KeyboardProfileItem;
+ return (this.ID == that.ID && this.Label == that.Label);
+ }
+
+ return false;
+ }
+
+ public static bool operator ==(KeyboardProfileItem a, KeyboardProfileItem b)
+ {
+ if (object.ReferenceEquals(a, null))
+ {
+ return object.ReferenceEquals(b, null);
+ }
+ return a.Equals(b);
+ }
+
+ public static bool operator !=(KeyboardProfileItem a, KeyboardProfileItem b)
+ {
+ return !(a == b);
+ }
+
+ public override int GetHashCode()
+ {
+ return base.GetHashCode();
+ }
}
}
diff --git a/AnneProKeyboard/LayoutPage.xaml b/AnneProKeyboard/LayoutPage.xaml
new file mode 100644
index 0000000..fef207c
--- /dev/null
+++ b/AnneProKeyboard/LayoutPage.xaml
@@ -0,0 +1,293 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AnneProKeyboard/LayoutPage.xaml.cs b/AnneProKeyboard/LayoutPage.xaml.cs
new file mode 100644
index 0000000..1f56070
--- /dev/null
+++ b/AnneProKeyboard/LayoutPage.xaml.cs
@@ -0,0 +1,426 @@
+using System;
+using System.Diagnostics;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.IO;
+using System.Runtime.Serialization;
+using System.Collections.Specialized;
+using System.Threading.Tasks;
+using System.Runtime.InteropServices.WindowsRuntime;
+
+using Windows.UI.Xaml.Controls;
+using Windows.Devices.Enumeration;
+using Windows.Devices.Bluetooth.GenericAttributeProfile;
+using Windows.UI.Core;
+using Windows.Devices.Bluetooth;
+using Windows.UI;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Media;
+using Windows.Storage;
+using Windows.Storage.Streams;
+using Windows.UI.Xaml.Navigation;
+using Windows.Foundation;
+
+// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
+
+namespace AnneProKeyboard
+{
+ ///
+ /// An empty page that can be used on its own or navigated to within a Frame.
+ ///
+ public sealed partial class LayoutPage : Page
+ {
+ //public MainPage ParentWindow { get; set; }
+
+ private ObservableCollection _keyboardProfiles = new ObservableCollection();
+ public KeyboardProfileItem EditingProfile;
+ public KeyboardProfileItem RenamingProfile;
+
+ public ObservableCollection KeyboardProfiles
+ {
+ get { return _keyboardProfiles; }
+ set { }
+ }
+
+ public ObservableCollection KeyboardKeyLabels = new ObservableCollection();
+ private Dictionary KeyboardKeyLabelTranslation = new Dictionary();
+
+ private Button CurrentlyEditingStandardKey;
+ private Button CurrentlyEditingFnKey;
+
+ public LayoutPage()
+ {
+ foreach(KeyboardKey key in KeyboardKey.StringKeyboardKeys.Values)
+ {
+ KeyboardKeyLabels.Add(key.KeyShortLabel);
+ KeyboardKeyLabelTranslation[key.KeyShortLabel] = key.KeyLabel;
+ }
+
+ this.InitializeComponent();
+
+ LoadProfiles();
+
+ this._keyboardProfiles.CollectionChanged += KeyboardProfiles_CollectionChanged;
+ }
+
+ public async void SaveProfiles()
+ {
+ MemoryStream memory_stream = new MemoryStream();
+ DataContractSerializer serialiser = new DataContractSerializer(typeof(ObservableCollection));
+ serialiser.WriteObject(memory_stream, this._keyboardProfiles);
+ try
+ {
+ StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync("KeyboardProfilesData", CreationCollisionOption.ReplaceExisting);
+ using (Stream file_stream = await file.OpenStreamForWriteAsync())
+ {
+ memory_stream.Seek(0, SeekOrigin.Begin);
+ await memory_stream.CopyToAsync(file_stream);
+ await file_stream.FlushAsync();
+ }
+ } catch(UnauthorizedAccessException)
+ {
+ throw new UnauthorizedAccessException();
+ }
+ }
+
+ public async void LoadProfiles()
+ {
+ try
+ {
+ StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync("KeyboardProfilesData");
+ using (IInputStream inStream = await file.OpenSequentialReadAsync())
+ {
+ DataContractSerializer serialiser = new DataContractSerializer(typeof(ObservableCollection));
+ ObservableCollection saved_profiles = (ObservableCollection)serialiser.ReadObject(inStream.AsStreamForRead());
+
+ foreach (KeyboardProfileItem profile in saved_profiles)
+ {
+ if (!_keyboardProfiles.Contains(profile))
+ {
+ this._keyboardProfiles.Add(profile);
+ }
+ }
+ }
+ }
+ catch
+ {
+ }
+
+ // UI init code
+ if (this._keyboardProfiles.Count == 0)
+ {
+ this.CreateNewKeyboardProfile();
+ }
+
+ ChangeSelectedProfile(this._keyboardProfiles[0]);
+ }
+
+ private void CreateNewKeyboardProfile()
+ {
+ KeyboardProfileItem profile_item = new KeyboardProfileItem(this._keyboardProfiles.Count, "Profile " + (this._keyboardProfiles.Count + 1));
+ this._keyboardProfiles.Add(profile_item);
+ }
+
+ private void ChangeSelectedProfile(KeyboardProfileItem profile)
+ {
+ if(profile == null)
+ {
+ return;
+ }
+ this.EditingProfile = profile;
+
+ // set up the background colours for the keyboard lights
+ for (int i = 0; i < 70; i++)
+ {
+ // set the standard layout keys
+ if (i < 61)
+ {
+ string layout_id = "keyboardStandardLayoutButton" + i;
+ Button layout_button = (this.FindName(layout_id) as Button);
+
+ if (layout_button != null)
+ {
+ layout_button.Content = profile.NormalKeys[i].KeyShortLabel;
+ }
+
+ string fn_layout_id = "keyboardFNLayoutButton" + i;
+ Button fn_layout_button = (this.FindName(fn_layout_id) as Button);
+
+ if (fn_layout_id != null)
+ {
+ if (profile.FnKeys[i].KeyShortLabel == "None")
+ {
+ fn_layout_button.Content = "";
+ }
+ else
+ {
+ fn_layout_button.Content = profile.FnKeys[i].KeyShortLabel;
+ }
+ }
+ }
+
+ string s = "keyboardButton" + i;
+ Button button = (this.FindName(s) as Button);
+
+ // NOTE: last 4 keys (RALT, FN, Anne, Ctrl) are identify as 66,67,68,69
+ if (button == null)
+ {
+ continue;
+ }
+ int coloured_int = profile.KeyboardColours[i];
+ }
+ }
+
+ //private void KeyboardProfiles_ItemClick(object sender, EventArgs e)
+ //{
+ // KeyboardProfileItem profile = ProfilesCombo.SelectedItem as KeyboardProfileItem;
+ // ChangeSelectedProfile(profile);
+ //}
+
+ private void ProfileNameChangedEvent_TextChanged(object sender, TextChangedEventArgs e)
+ {
+ TextBox profileName = (sender as TextBox);
+ // update Views and KeyboardProfileItem class
+ if(this.EditingProfile == RenamingProfile)
+ {
+ }
+
+ if(this.RenamingProfile != null)
+ {
+ this.RenamingProfile.Label = profileName.Text;
+ }
+ }
+
+ private void ProfileAddButton_Click(object sender, RoutedEventArgs e)
+ {
+ this.CreateNewKeyboardProfile();
+ this.SaveProfiles();
+ this.ChangeSelectedProfile(_keyboardProfiles[_keyboardProfiles.Count - 1]);
+ this.LayoutProfilesCombo.SelectedIndex = this.LayoutProfilesCombo.Items.Count - 1;
+ }
+
+ private void ProfileEditButton_Click(object sender, RoutedEventArgs e)
+ {
+ Button button = (Button)sender;
+ FrameworkElement parent = (FrameworkElement)button.Parent;
+
+ TextBox textbox = (TextBox)parent.FindName("ProfileNameTextbox");
+ textbox.IsEnabled = true;
+ textbox.Visibility = Visibility.Visible;
+ FocusState focus_state = FocusState.Keyboard;
+ textbox.Focus(focus_state);
+
+ TextBlock textblock = (TextBlock)parent.FindName("ProfileNameTextblock");
+ textblock.Visibility = Visibility.Collapsed;
+
+ this.RenamingProfile = this._keyboardProfiles[(int)button.Tag];
+ }
+
+ private void ProfileDeleteButton_Click(object sender, RoutedEventArgs e)
+ {
+ Button button = (Button)sender;
+ FrameworkElement parent = (FrameworkElement)button.Parent;
+ TextBox textbox = (TextBox)parent.FindName("ProfileNameTextbox");
+ KeyboardProfileItem selected_profile = this._keyboardProfiles[(int)button.Tag];
+
+ this._keyboardProfiles.Remove(selected_profile);
+ //this.LayoutProfilesCombo.Items.Remove(selected_profile);
+
+ // always make sure that the keyboard profiles list has 1 element in it
+ if (this._keyboardProfiles.Count == 0)
+ {
+ this.CreateNewKeyboardProfile();
+ }
+
+ // Change the chosen profile to the first element
+ ChangeSelectedProfile(this._keyboardProfiles[0]);
+ LayoutProfilesCombo.SelectedIndex = 0;
+ LayoutProfilesCombo.IsDropDownOpen = false;
+ this.SaveProfiles();
+ }
+
+ private void ProfileNameTextbox_LostFocus(object sender, RoutedEventArgs e)
+ {
+ this.SaveProfiles();
+
+ TextBox textbox = (TextBox)sender;
+
+ this.RenamingProfile = null;
+ }
+
+ private void KeyboardProfiles_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
+ {
+ if(e.Action == NotifyCollectionChangedAction.Add || e.Action == NotifyCollectionChangedAction.Remove)
+ {
+ // Really inefficient, we should consider re-implementing this later
+ for (int i = 0; i < this._keyboardProfiles.Count; i++)
+ {
+ KeyboardProfileItem profile = this._keyboardProfiles[i];
+ profile.ID = i;
+ }
+ }
+ }
+
+ private async void KeyboardLayoutButton_Click(object sender, RoutedEventArgs e)
+ {
+ if(this.CurrentlyEditingFnKey != null)
+ {
+ this.CurrentlyEditingFnKey.Visibility = Visibility.Visible;
+ this.CurrentlyEditingFnKey = null;
+ }
+
+ if(this.CurrentlyEditingStandardKey != null)
+ {
+ this.CurrentlyEditingStandardKey.Visibility = Visibility.Visible;
+ this.CurrentlyEditingStandardKey = null;
+ }
+
+ Button button = (Button)sender;
+
+ bool fn_mode = button.Name.StartsWith("keyboardFNLayoutButton");
+
+ if(fn_mode)
+ {
+ this.CurrentlyEditingFnKey = button;
+ }
+ else
+ {
+ this.CurrentlyEditingStandardKey = button;
+ }
+
+ // Switch parents
+ RelativePanel selector_parent = (RelativePanel)keyboardLayoutSelection.Parent;
+ selector_parent.Children.Remove(keyboardLayoutSelection);
+
+ //add the combobox to relative panel and place it into the correct position
+ RelativePanel parent = (RelativePanel)button.Parent;
+ parent.Children.Add(keyboardLayoutSelection);
+ var button_idx = parent.Children.IndexOf(button);
+ var width = button.Width + 1;
+ if (button_idx != 0)
+ {
+ RelativePanel.SetRightOf(keyboardLayoutSelection, parent.Children[parent.Children.IndexOf(button) - 1]);
+ } else
+ {
+ RelativePanel.SetRightOf(keyboardLayoutSelection, null);
+ width += 1;
+ }
+ if (button_idx != parent.Children.Count - 2) //added combobox, account for it here
+ {
+ RelativePanel.SetRightOf(parent.Children[parent.Children.IndexOf(button) + 1], keyboardLayoutSelection);
+ }
+ keyboardLayoutSelection.Width = width; //account for 1px between buttons
+ keyboardLayoutSelection.SelectedIndex = this.KeyboardKeyLabels.IndexOf((string)button.Content);
+
+ button.Visibility = Visibility.Collapsed;
+
+ keyboardLayoutSelection.Visibility = Visibility.Visible;
+
+ await Task.Delay(1);
+
+ keyboardLayoutSelection.IsDropDownOpen = true;
+ }
+
+ private void KeyboardStandardLayout_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ string label = keyboardLayoutSelection.SelectedItem as string;
+
+ if(String.IsNullOrEmpty(label))
+ {
+ label = KeyboardKey.IntKeyboardKeys[0].KeyShortLabel;
+ }
+
+ Button button = (this.CurrentlyEditingStandardKey != null) ? this.CurrentlyEditingStandardKey : this.CurrentlyEditingFnKey;
+ int length = (this.CurrentlyEditingStandardKey != null) ? 28 : 22; // special constants
+
+ int index = -1;
+
+ try
+ {
+ Int32.TryParse(button.Name.Substring(length), out index);
+ }
+ catch
+ {
+ }
+
+ if(index >= 0)
+ {
+ string full_label = this.KeyboardKeyLabelTranslation[label];
+
+ if(this.CurrentlyEditingFnKey != null)
+ {
+ this.EditingProfile.FnKeys[index] = KeyboardKey.StringKeyboardKeys[full_label];
+
+
+ this.CurrentlyEditingFnKey.Content = label;
+ this.CurrentlyEditingFnKey.Visibility = Visibility.Visible;
+ }
+ else
+ {
+ this.EditingProfile.NormalKeys[index] = KeyboardKey.StringKeyboardKeys[full_label];
+
+ this.CurrentlyEditingStandardKey.Content = label;
+ this.CurrentlyEditingStandardKey.Visibility = Visibility.Visible;
+ }
+ }
+
+ this.SaveProfiles();
+ }
+
+ private void KeyboardStandardLayout_DropDownClosed(object sender, object e)
+ {
+
+ if (this.CurrentlyEditingFnKey != null)
+ {
+ this.CurrentlyEditingFnKey.Visibility = Visibility.Visible;
+ RelativePanel parent = (RelativePanel)CurrentlyEditingFnKey.Parent;
+ var button_idx = parent.Children.IndexOf(CurrentlyEditingFnKey);
+ if (button_idx != 0)
+ {
+ RelativePanel.SetRightOf(CurrentlyEditingFnKey, parent.Children[parent.Children.IndexOf(CurrentlyEditingFnKey) - 1]);
+ }
+ if (button_idx != parent.Children.Count - 2)
+ {
+ RelativePanel.SetRightOf(parent.Children[parent.Children.IndexOf(CurrentlyEditingFnKey) + 1], CurrentlyEditingFnKey);
+ }
+ }
+
+ if (this.CurrentlyEditingStandardKey != null)
+ {
+ this.CurrentlyEditingStandardKey.Visibility = Visibility.Visible;
+ RelativePanel parent = (RelativePanel)CurrentlyEditingStandardKey.Parent;
+ var button_idx = parent.Children.IndexOf(CurrentlyEditingStandardKey);
+ if (button_idx != 0)
+ {
+ RelativePanel.SetRightOf(CurrentlyEditingStandardKey, parent.Children[parent.Children.IndexOf(CurrentlyEditingStandardKey) - 1]);
+ }
+ if (button_idx != parent.Children.Count - 2)
+ {
+ RelativePanel.SetRightOf(parent.Children[parent.Children.IndexOf(CurrentlyEditingStandardKey) + 1], CurrentlyEditingStandardKey);
+ }
+ }
+
+ this.keyboardLayoutSelection.Visibility = Visibility.Collapsed;
+ }
+
+ private void LayoutProfilesCombo_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (LayoutProfilesCombo == null) return;
+ var combo = (ComboBox) sender;
+ var item = (KeyboardProfileItem) combo.SelectedItem;
+ ChangeSelectedProfile(item);
+ }
+
+ private void LayoutProfilesCombo_Loaded(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ LayoutProfilesCombo.SelectedIndex = 0;
+ } catch
+ {
+ //some occassions the load doesn't load correctly
+ //dont set any in combobox
+ }
+ }
+ }
+}
diff --git a/AnneProKeyboard/LightingPage.xaml b/AnneProKeyboard/LightingPage.xaml
new file mode 100644
index 0000000..5ff4cc4
--- /dev/null
+++ b/AnneProKeyboard/LightingPage.xaml
@@ -0,0 +1,212 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AnneProKeyboard/LightingPage.xaml.cs b/AnneProKeyboard/LightingPage.xaml.cs
new file mode 100644
index 0000000..82a2ce0
--- /dev/null
+++ b/AnneProKeyboard/LightingPage.xaml.cs
@@ -0,0 +1,605 @@
+using System;
+using System.Diagnostics;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.IO;
+using System.Runtime.Serialization;
+using System.Collections.Specialized;
+using System.Threading.Tasks;
+using System.Runtime.InteropServices.WindowsRuntime;
+
+using Windows.UI.Xaml.Controls;
+using Windows.Devices.Enumeration;
+using Windows.Devices.Bluetooth.GenericAttributeProfile;
+using Windows.UI.Core;
+using Windows.Devices.Bluetooth;
+using Windows.UI;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Media;
+using Windows.Storage;
+using Windows.Storage.Streams;
+using Windows.UI.Xaml.Navigation;
+
+// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
+
+namespace AnneProKeyboard
+{
+ ///
+ /// An empty page that can be used on its own or navigated to within a Frame.
+ ///
+ public partial class LightingPage : Page
+ {
+ private ObservableCollection _keyboardProfiles = new ObservableCollection();
+ public KeyboardProfileItem EditingProfile;
+ public KeyboardProfileItem RenamingProfile;
+
+ private Color SelectedColour;
+ private Boolean matchingButtonColour = false;
+
+ public ObservableCollection KeyboardProfiles
+ {
+ get { return _keyboardProfiles; }
+ set { }
+ }
+
+ protected override void OnNavigatedTo(NavigationEventArgs e)
+ {
+ }
+
+ public LightingPage()
+ {
+ this.InitializeComponent();
+ LoadProfiles();
+ SelectedColour = colourPicker.SelectedColor.Color;
+ this._keyboardProfiles.CollectionChanged += KeyboardProfiles_CollectionChanged;
+ }
+
+ public async void SaveProfiles()
+ {
+ MemoryStream memory_stream = new MemoryStream();
+ DataContractSerializer serialiser = new DataContractSerializer(typeof(ObservableCollection));
+ serialiser.WriteObject(memory_stream, this._keyboardProfiles);
+
+ try
+ {
+ StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync("KeyboardProfilesData", CreationCollisionOption.ReplaceExisting);
+ using (Stream file_stream = await file.OpenStreamForWriteAsync())
+ {
+ memory_stream.Seek(0, SeekOrigin.Begin);
+ await memory_stream.CopyToAsync(file_stream);
+ await file_stream.FlushAsync();
+ }
+ }
+ catch (UnauthorizedAccessException)
+ {
+ throw new UnauthorizedAccessException();
+ }
+ }
+
+ public async void LoadProfiles()
+ {
+ try
+ {
+ StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync("KeyboardProfilesData");
+ using (IInputStream inStream = await file.OpenSequentialReadAsync())
+ {
+ DataContractSerializer serialiser = new DataContractSerializer(typeof(ObservableCollection));
+ ObservableCollection saved_profiles = (ObservableCollection)serialiser.ReadObject(inStream.AsStreamForRead());
+
+ foreach (KeyboardProfileItem profile in saved_profiles)
+ {
+ if(!_keyboardProfiles.Contains(profile))
+ {
+ this._keyboardProfiles.Add(profile);
+ }
+ }
+ }
+ }
+ catch
+ {
+ }
+
+ // UI init code
+ if (this._keyboardProfiles.Count == 0)
+ {
+ this.CreateNewKeyboardProfile();
+ }
+
+ ChangeSelectedProfile(this._keyboardProfiles[0]);
+ }
+
+ private void CreateNewKeyboardProfile()
+ {
+ KeyboardProfileItem profile_item = new KeyboardProfileItem(this._keyboardProfiles.Count, "Profile " + (this._keyboardProfiles.Count + 1));
+ this._keyboardProfiles.Add(profile_item);
+ }
+
+ private void ChangeSelectedProfile(KeyboardProfileItem profile)
+ {
+ this.EditingProfile = profile;
+ //chosenProfileName.Title = profile.Label;
+
+ // set up the background colours for the keyboard lights
+ for (int i = 0; i < 70; i++)
+ {
+ // set the standard layout keys
+ if (i < 61)
+ {
+ string layout_id = "keyboardStandardLayoutButton" + i;
+ Button layout_button = (this.FindName(layout_id) as Button);
+
+ if (layout_button != null)
+ {
+ layout_button.Content = profile.NormalKeys[i].KeyShortLabel;
+ }
+
+ string fn_layout_id = "keyboardFNLayoutButton" + i;
+ Button fn_layout_button = (this.FindName(fn_layout_id) as Button);
+
+ }
+
+ string s = "keyboardButton" + i;
+ Button button = (this.FindName(s) as Button);
+
+ // NOTE: last 4 keys (RALT, FN, Anne, Ctrl) are identify as 66,67,68,69
+ if (button == null)
+ {
+ continue;
+ }
+
+ int coloured_int = profile.KeyboardColours[i];
+
+ Color colour = ConvertIntToColour(coloured_int);
+
+ button.BorderBrush = new SolidColorBrush(colour);
+ button.BorderThickness = new Thickness(1);
+ button.Background = new SolidColorBrush(colour);
+ }
+
+ //colour the multi selection buttons
+ //check the WASD keys. If all same, color WASD button
+ Color multi_colour = ConvertIntToColour(profile.KeyboardColours[16]); //W key idx
+ Button multi_button = (this.FindName("WASDKeys") as Button);
+ Color default_colour = Color.FromArgb(255,94,97,102);
+ if (colour_wasd(profile))
+ {
+ setButtonColour(multi_button, multi_colour);
+ }
+ else
+ {
+ setButtonColour(multi_button, default_colour);
+ }
+
+ //check IJKL keys
+ if (colour_ijkl(profile))
+ {
+ multi_colour = ConvertIntToColour(profile.KeyboardColours[22]); //I key idx
+ multi_button = (this.FindName("IJKLKeys") as Button);
+ setButtonColour(multi_button, multi_colour);
+ }
+ else
+ {
+ setButtonColour(multi_button, default_colour);
+ }
+
+ //check Modifier Keys
+ if (colour_modifiers(profile))
+ {
+ multi_colour = ConvertIntToColour(profile.KeyboardColours[14]); //Tab key idx
+ multi_button = (this.FindName("ModifierKeys") as Button);
+ setButtonColour(multi_button, multi_colour);
+ }
+ else
+ {
+ setButtonColour(multi_button, default_colour);
+ }
+
+ //check num row
+ if (colour_num_row(profile))
+ {
+ multi_colour = ConvertIntToColour(profile.KeyboardColours[1]); //1 key idx
+ multi_button = (this.FindName("NumKeys") as Button);
+ setButtonColour(multi_button, multi_colour);
+ }
+ else
+ {
+ setButtonColour(multi_button, default_colour);
+ }
+
+ //set all buttons colour to default colour. Easy to see if all buttons are the same colour
+ multi_button = (this.FindName("AllKeys") as Button);
+ setButtonColour(multi_button, default_colour);
+ }
+
+ private Boolean colour_wasd(KeyboardProfileItem profile)
+ {
+ return (
+ profile.KeyboardColours[16] == profile.KeyboardColours[29] &&
+ profile.KeyboardColours[29] == profile.KeyboardColours[30] &&
+ profile.KeyboardColours[30] == profile.KeyboardColours[31]
+ );
+ }
+
+ private Boolean colour_ijkl(KeyboardProfileItem profile)
+ {
+ return (
+ profile.KeyboardColours[22] == profile.KeyboardColours[35] &&
+ profile.KeyboardColours[35] == profile.KeyboardColours[36] &&
+ profile.KeyboardColours[36] == profile.KeyboardColours[37]
+ );
+ }
+
+ private Boolean colour_num_row(KeyboardProfileItem profile)
+ {
+ int colour = profile.KeyboardColours[1];
+ for (int i = 2; i < 11; i++)
+ {
+ if (profile.KeyboardColours[i] != colour)
+ return false;
+ }
+ return true;
+ }
+
+ private Boolean colour_modifiers(KeyboardProfileItem profile)
+ {
+ int[] modifiers = new int[14] { 14, 28, 42, 56, 57, 58, 66, 67, 68, 69, 55, 41, 13, 27 }; //Tab->LCtrl->RCtrl->Bkspc: 14,28,42,56,57,58,66,67,68,69,55,41,13,27
+
+ int colour = profile.KeyboardColours[14];
+ foreach (int i in modifiers)
+ {
+ if (profile.KeyboardColours[i] != colour)
+ return false;
+ }
+ return true;
+ }
+
+ private void KeyboardProfiles_ItemClick(object sender, ItemClickEventArgs e)
+ {
+ KeyboardProfileItem profile = (e.ClickedItem as KeyboardProfileItem);
+ ChangeSelectedProfile(profile);
+ }
+
+ private void setButtonColour(Button button)
+ {
+ setButtonColour(button, this.SelectedColour);
+ }
+
+ private void setButtonColour(Button button, Color colour)
+ {
+ if (!matchingButtonColour)
+ {
+ button.BorderBrush = new SolidColorBrush(colour);
+ button.BorderThickness = new Thickness(1);
+ button.Background = new SolidColorBrush(colour);
+ if (Brightness(colour) > 200)
+ {
+ button.Foreground = new SolidColorBrush(Color.FromArgb(255, 75, 75, 75));
+ }
+ else
+ {
+ button.Foreground = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));
+ }
+ }
+ else if (button.Name.Length > 14)
+ {
+ //Never gets hit, methinks
+ int button_index = Int32.Parse(button.Name.Remove(0, 14));
+ int colour_int = this.EditingProfile.KeyboardColours[button_index];
+ this.SelectedColour = colour;
+ colourPicker.SelectedColor = new SolidColorBrush(colour);
+ matchingButtonColour = false;
+ }
+ }
+
+ private int Brightness(Color c)
+ {
+ return (int)Math.Sqrt(
+ c.R * c.R * .241 +
+ c.G * c.G * .691 +
+ c.B * c.B * .068);
+ }
+
+ private void KeyboardColourButton_Click(object sender, RoutedEventArgs e)
+ {
+ if (matchingButtonColour)
+ {
+ (this.FindName("ColourTool") as Button).Content = "Match a Colour";
+ matchingButtonColour = false;
+ Button button = (Button)sender;
+ int btn_int = Int32.Parse(button.Name.Remove(0, 14));
+ btn_int = this.EditingProfile.KeyboardColours[btn_int];
+ colourPicker.PreviousSelectedColor = colourPicker.SelectedColor;
+ colourPicker.SelectedColor = new SolidColorBrush(ConvertIntToColour(btn_int));
+ this.SelectedColour = ConvertIntToColour(btn_int);
+ //enable multikey buttons
+ enableMultiButtons();
+ }
+ else
+ {
+ Button button = (Button)sender;
+ setButtonColour(button);
+
+ int button_index = Int32.Parse(button.Name.Remove(0, 14));
+
+ this.EditingProfile.KeyboardColours[button_index] = ConvertColourToInt(this.SelectedColour);
+
+ //this may be resource intensive, but it's the only way to gurantee that profiles get saved
+ this.SaveProfiles();
+ }
+ }
+
+ private void KeyboardAllButton_Click(object sender, RoutedEventArgs e)
+ {
+
+ Button button = (Button)sender;
+ setButtonColour(button);
+
+ for (int i = 0; i < 70; i++)
+ {
+ if (i == 40 || i == 53 || i == 54 || i == 59 || i == 60 || i == 62 || i == 63 || i == 64 || i == 65)
+ {
+ continue;
+ }
+ this.EditingProfile.KeyboardColours[i] = ConvertColourToInt(this.SelectedColour);
+ string s = "keyboardButton" + i;
+ button = (this.FindName(s) as Button);
+ setButtonColour(button);
+ }
+ //set Multi selection button colors
+ setButtonColour(this.FindName("WASDKeys") as Button);
+ setButtonColour(this.FindName("IJKLKeys") as Button);
+ setButtonColour(this.FindName("NumKeys") as Button);
+ setButtonColour(this.FindName("AllKeys") as Button);
+ setButtonColour(this.FindName("ModifierKeys") as Button);
+
+ //this may be resource intensive, but it's the only way to gurantee that profiles get saved
+ this.SaveProfiles();
+ }
+
+ private void KeyboardWASDButton_Click(object sender, RoutedEventArgs e)
+ {
+ Button button = (Button)sender;
+ setButtonColour(button);
+
+ int[] modifiers = new int[4] { 16, 29, 30, 31 };
+ foreach (int i in modifiers)
+ {
+ this.EditingProfile.KeyboardColours[i] = ConvertColourToInt(this.SelectedColour);
+
+ string s = "keyboardButton" + i;
+ button = (this.FindName(s) as Button);
+ setButtonColour(button);
+ }
+
+ //this may be resource intensive, but it's the only way to gurantee that profiles get saved
+ this.SaveProfiles();
+ }
+
+ private void KeyboardIJKLButton_Click(object sender, RoutedEventArgs e)
+ {
+ Button button = (Button)sender;
+ setButtonColour(button);
+
+ int[] modifiers = new int[4] { 22, 35, 36, 37 };
+ foreach (int i in modifiers)
+ {
+ this.EditingProfile.KeyboardColours[i] = ConvertColourToInt(this.SelectedColour);
+
+ string s = "keyboardButton" + i;
+ button = (this.FindName(s) as Button);
+ setButtonColour(button);
+ }
+
+ //this may be resource intensive, but it's the only way to gurantee that profiles get saved
+ this.SaveProfiles();
+ }
+
+ private void KeyboardNumRowButton_Click(object sender, RoutedEventArgs e)
+ {
+ Button button = (Button)sender;
+ setButtonColour(button);
+
+ for (int i = 1; i < 11; i++) //num: 1-10 -=: 11-12
+ {
+ this.EditingProfile.KeyboardColours[i] = ConvertColourToInt(this.SelectedColour);
+ string s = "keyboardButton" + i;
+ button = (this.FindName(s) as Button);
+ setButtonColour(button);
+ }
+
+ //this may be resource intensive, but it's the only way to gurantee that profiles get saved
+ this.SaveProfiles();
+ }
+
+ private void KeyboardModifiersButton_Click(object sender, RoutedEventArgs e)
+ {
+ Button button = (Button)sender;
+ setButtonColour(button);
+
+ int[] modifiers = new int[14] { 14, 28, 42, 56, 57, 58, 66, 67, 68, 69, 55, 41, 13, 27 }; //Tab->LCtrl->RCtrl->Bkspc: 14,28,42,56,57,58,66,67,68,69,55,41,13,27
+ foreach (int i in modifiers)
+ {
+ this.EditingProfile.KeyboardColours[i] = ConvertColourToInt(this.SelectedColour);
+ string s = "keyboardButton" + i;
+ button = (this.FindName(s) as Button);
+ setButtonColour(button);
+ }
+
+ //this may be resource intensive, but it's the only way to gurantee that profiles get saved
+ this.SaveProfiles();
+ }
+
+ private void KeyboardColourPickerButton_Click(object sender, RoutedEventArgs e)
+ {
+ Button button = (Button)sender;
+ Button wasd = this.FindName("WASDKeys") as Button;
+
+ if (!matchingButtonColour)
+ {
+ matchingButtonColour = true;
+ button.Content = "Cancel";
+ //Disable multikey buttons
+ disableMultiButtons();
+ }
+ else
+ {
+ matchingButtonColour = false;
+ button.Content = "Match a Colour";
+ //enable multikey buttons
+ enableMultiButtons();
+ }
+ }
+
+ private void enableMultiButtons()
+ {
+ (this.FindName("WASDKeys") as Button).IsEnabled = true;
+ (this.FindName("IJKLKeys") as Button).IsEnabled = true;
+ (this.FindName("NumKeys") as Button).IsEnabled = true;
+ (this.FindName("AllKeys") as Button).IsEnabled = true;
+ (this.FindName("ModifierKeys") as Button).IsEnabled = true;
+ }
+
+ private void disableMultiButtons()
+ {
+ (this.FindName("WASDKeys") as Button).IsEnabled = false;
+ (this.FindName("IJKLKeys") as Button).IsEnabled = false;
+ (this.FindName("NumKeys") as Button).IsEnabled = false;
+ (this.FindName("AllKeys") as Button).IsEnabled = false;
+ (this.FindName("ModifierKeys") as Button).IsEnabled = false;
+ }
+
+
+ private int ConvertColourToInt(Color colour)
+ {
+ int colour_int = colour.R;
+ colour_int = (colour_int << 8) + colour.G;
+ colour_int = (colour_int << 8) + colour.B;
+
+ return colour_int;
+ }
+
+ private Color ConvertIntToColour(int coloured_int)
+ {
+ int red = (coloured_int >> 16) & 0xff;
+ int green = (coloured_int >> 8) & 0xff;
+ int blue = (coloured_int >> 0) & 0xff;
+
+ return Color.FromArgb(255, (byte)red, (byte)green, (byte)blue);
+ }
+
+ private void ProfileNameChangedEvent_TextChanged(object sender, TextChangedEventArgs e)
+ {
+ TextBox profileName = (sender as TextBox);
+ // update Views and KeyboardProfileItem class
+ if (this.EditingProfile == RenamingProfile)
+ {
+ //chosenProfileName.Title = profileName.Text;
+ }
+
+ if (this.RenamingProfile != null)
+ {
+ this.RenamingProfile.Label = profileName.Text;
+ }
+ }
+
+ private void ProfileAddButton_Click(object sender, RoutedEventArgs e)
+ {
+ this.CreateNewKeyboardProfile();
+ this.SaveProfiles();
+ this.ChangeSelectedProfile(_keyboardProfiles[_keyboardProfiles.Count - 1]);
+ this.LightingProfilesCombo.SelectedIndex = this.LightingProfilesCombo.Items.Count - 1;
+ }
+
+ private void ProfileEditButton_Click(object sender, RoutedEventArgs e)
+ {
+ Button button = (Button)sender;
+ FrameworkElement parent = (FrameworkElement)button.Parent;
+
+ TextBox textbox = (TextBox)parent.FindName("ProfileNameTextbox");
+ textbox.IsEnabled = true;
+ textbox.Visibility = Visibility.Visible;
+ FocusState focus_state = FocusState.Keyboard;
+ textbox.Focus(focus_state);
+
+ TextBlock textblock = (TextBlock)parent.FindName("ProfileNameTextblock");
+ textblock.Visibility = Visibility.Collapsed;
+
+ this.RenamingProfile = this._keyboardProfiles[(int)button.Tag];
+ }
+
+ private void ProfileDeleteButton_Click(object sender, RoutedEventArgs e)
+ {
+ Button button = (Button)sender;
+ FrameworkElement parent = (FrameworkElement)button.Parent;
+ TextBox textbox = (TextBox)parent.FindName("ProfileNameTextbox");
+ KeyboardProfileItem selected_profile = this._keyboardProfiles[(int)button.Tag];
+
+ this._keyboardProfiles.Remove(selected_profile);
+
+ // always make sure that the keyboard profiles list has 1 element in it
+ if (this._keyboardProfiles.Count == 0)
+ {
+ this.CreateNewKeyboardProfile();
+ }
+
+ // Change the chosen profile to the first element
+ ChangeSelectedProfile(this._keyboardProfiles[0]);
+ LightingProfilesCombo.SelectedIndex = 0;
+
+ this.SaveProfiles();
+ }
+
+ private void ProfileNameTextbox_LostFocus(object sender, RoutedEventArgs e)
+ {
+ this.SaveProfiles();
+
+ TextBox textbox = (TextBox)sender;
+
+ this.RenamingProfile = null;
+ }
+
+ private void KeyboardProfiles_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
+ {
+ if (e.Action == NotifyCollectionChangedAction.Add || e.Action == NotifyCollectionChangedAction.Remove)
+ {
+ // Really inefficient, we should consider re-implementing this later
+ for (int i = 0; i < this._keyboardProfiles.Count; i++)
+ {
+ KeyboardProfileItem profile = this._keyboardProfiles[i];
+ profile.ID = i;
+ }
+ }
+ }
+
+ private void LightingProfilesCombo_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (LightingProfilesCombo == null) return;
+ var combo = (ComboBox)sender;
+ var item = (KeyboardProfileItem)combo.SelectedItem;
+ if (item == null)
+ {
+ this.CreateNewKeyboardProfile();
+ ChangeSelectedProfile(_keyboardProfiles[0]);
+ } else
+ {
+ ChangeSelectedProfile(item);
+ }
+ }
+
+ private void LightingProfilesCombo_Loaded(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ LightingProfilesCombo.SelectedIndex = 0;
+ } catch
+ {
+
+ }
+ }
+
+ private void colourPicker_SelectedColorChanged(object sender, EventArgs e)
+ {
+ this.SelectedColour = colourPicker.SelectedColor.Color;
+ }
+ }
+}
diff --git a/AnneProKeyboard/MainPage.xaml b/AnneProKeyboard/MainPage.xaml
index 3d896db..3d3701d 100644
--- a/AnneProKeyboard/MainPage.xaml
+++ b/AnneProKeyboard/MainPage.xaml
@@ -5,347 +5,90 @@
xmlns:local="using:AnneProKeyboard"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:xcp="using:Color_Picker"
+ xmlns:fa="using:FontAwesome.UWP"
mc:Ignorable="d" MinWidth="960" MinHeight="480">
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/AnneProKeyboard/MainPage.xaml.cs b/AnneProKeyboard/MainPage.xaml.cs
index ce930d7..f480c2e 100644
--- a/AnneProKeyboard/MainPage.xaml.cs
+++ b/AnneProKeyboard/MainPage.xaml.cs
@@ -18,6 +18,9 @@
using Windows.UI.Xaml.Media;
using Windows.Storage;
using Windows.Storage.Streams;
+using Windows.UI.ViewManagement;
+using Windows.ApplicationModel.Core;
+using Windows.UI.Xaml.Input;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
@@ -30,51 +33,42 @@ public sealed partial class MainPage : Page
{
private DeviceWatcher BluetoothDeviceWatcher;
private DeviceWatcher AllDevicesWatcher;
-
+
private readonly Guid OAD_GUID = new Guid("f000ffc0-0451-4000-b000-000000000000");
private readonly Guid WRITE_GATT_GUID = new Guid("f000ffc2-0451-4000-b000-000000000000");
- private readonly Guid READ_GATT_GUID = new Guid("f000ffc1-0451-4000-b000-000000000000");
-
- private GattCharacteristic WriteGatt;
- private GattCharacteristic ReadGatt;
- private DeviceInformation KeyboardDeviceInformation;
-
- private ObservableCollection _keyboardProfiles = new ObservableCollection();
- private KeyboardProfileItem EditingProfile;
- private KeyboardProfileItem RenamingProfile;
-
- private Color SelectedColour;
- private Boolean matchingButtonColour = false;
+ private readonly Guid READ_GATT_GUID = new Guid("f000ffc1-0451-4000-b000-000000000000");
- public ObservableCollection KeyboardProfiles
- {
- get { return _keyboardProfiles; }
- set { }
- }
+ private GattCharacteristic WriteGatt;
+ private GattCharacteristic ReadGatt;
+ private DeviceInformation KeyboardDeviceInformation;
- public ObservableCollection KeyboardKeyLabels = new ObservableCollection();
- private Dictionary KeyboardKeyLabelTranslation = new Dictionary();
+ private ApplicationViewTitleBar titleBar = ApplicationView.GetForCurrentView().TitleBar;
- private Button CurrentlyEditingStandardKey;
- private Button CurrentlyEditingFnKey;
+ private AboutPage aboutPage;
+ private LayoutPage layoutPage;
+ private LightingPage lightingPage;
public MainPage()
{
- foreach(KeyboardKey key in KeyboardKey.StringKeyboardKeys.Values)
- {
- KeyboardKeyLabels.Add(key.KeyShortLabel);
- KeyboardKeyLabelTranslation[key.KeyShortLabel] = key.KeyLabel;
- }
-
this.InitializeComponent();
-
+ initPages();
+ _frame.Content = layoutPage;
// Start up the background thread to find the keyboard
FindKeyboard();
+ CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true;
+ titleBar = ApplicationView.GetForCurrentView().TitleBar;
+ titleBar.ButtonInactiveBackgroundColor = Colors.White;
+ titleBar.ButtonInactiveForegroundColor = Color.FromArgb(1, 152, 152, 152);
+ Window.Current.SetTitleBar(MainTitleBar);
+ Window.Current.Activated += Current_Activated;
+ Color systemAccentColor = (Color)App.Current.Resources["SystemAccentColor"];
+ }
- LoadProfiles();
- SelectedColour = colourPicker.SelectedColor;
-
- this._keyboardProfiles.CollectionChanged += KeyboardProfiles_CollectionChanged;
+ private void initPages()
+ {
+ layoutPage = new LayoutPage();
+ aboutPage = new AboutPage();
+ lightingPage = new LightingPage();
}
private async void FindKeyboard()
@@ -98,50 +92,6 @@ private async void FindKeyboard()
// Make sure to disable Bluetooth listener
this.SetupBluetooth();
}
-
- private async void SaveProfiles()
- {
- MemoryStream memory_stream = new MemoryStream();
- DataContractSerializer serialiser = new DataContractSerializer(typeof(ObservableCollection));
- serialiser.WriteObject(memory_stream, this._keyboardProfiles);
-
- StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync("KeyboardProfilesData", CreationCollisionOption.ReplaceExisting);
- using (Stream file_stream = await file.OpenStreamForWriteAsync())
- {
- memory_stream.Seek(0, SeekOrigin.Begin);
- await memory_stream.CopyToAsync(file_stream);
- await file_stream.FlushAsync();
- }
- }
-
- private async void LoadProfiles()
- {
- try
- {
- StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync("KeyboardProfilesData");
- using (IInputStream inStream = await file.OpenSequentialReadAsync())
- {
- DataContractSerializer serialiser = new DataContractSerializer(typeof(ObservableCollection));
- ObservableCollection saved_profiles = (ObservableCollection)serialiser.ReadObject(inStream.AsStreamForRead());
-
- foreach(KeyboardProfileItem profile in saved_profiles)
- {
- this._keyboardProfiles.Add(profile);
- }
- }
- }
- catch
- {
- }
-
- // UI init code
- if (this._keyboardProfiles.Count == 0)
- {
- this.CreateNewKeyboardProfile();
- }
-
- ChangeSelectedProfile(this._keyboardProfiles[0]);
- }
private void SetupBluetooth()
{
@@ -160,7 +110,7 @@ private void SetupBluetooth()
}
}
- if(AllDevicesWatcher == null)
+ if (AllDevicesWatcher == null)
{
AllDevicesWatcher = DeviceInformation.CreateWatcher(DeviceClass.All);
@@ -178,7 +128,12 @@ private void SetupBluetooth()
private async void HIDDeviceUpdated(DeviceWatcher sender, DeviceInformationUpdate args)
{
DeviceInformation device_info = await DeviceInformation.CreateFromIdAsync(args.Id);
-
+
+ if(device_info == null)
+ {
+ return;
+ }
+
// Do not let the background task starve, check if we are paired then connect to the keyboard
if (device_info.Name.Contains("ANNE"))
{
@@ -190,11 +145,10 @@ private async void HIDDeviceUpdated(DeviceWatcher sender, DeviceInformationUpdat
{
await Dispatcher.RunAsync(CoreDispatcherPriority.High, () =>
{
- KeyboardDeviceInformation = null;
- connectionStatusLabel.Text = "Not Connected";
+ KeyboardDeviceInformation = null;
+ connectionStatusLabel.Text = "Not Connected";
connectionStatusLabel.Foreground = new SolidColorBrush(Colors.Red);
- LightSyncButton.IsEnabled = false;
- LayoutSyncButton.IsEnabled = false;
+ ProfileSyncButton.IsEnabled = true;
});
}
}
@@ -212,7 +166,7 @@ private void App_Suspending(object sender, Windows.ApplicationModel.SuspendingEv
this.BluetoothDeviceWatcher = null;
}
- if(this.AllDevicesWatcher != null)
+ if (this.AllDevicesWatcher != null)
{
AllDevicesWatcher.Updated -= HIDDeviceUpdated;
@@ -229,13 +183,13 @@ private void App_Resuming(object sender, object e)
private async void BluetoothDeviceAdded(DeviceWatcher watcher, DeviceInformation device)
{
- if(device.Name.Contains("ANNE"))
+ if (device.Name.Contains("ANNE"))
{
- if(device.Pairing.IsPaired)
+ if (device.Pairing.IsPaired)
{
ConnectToKeyboard(device);
}
- else if(device.Pairing.CanPair)
+ else if (device.Pairing.CanPair)
{
var result = await device.Pairing.PairAsync();
@@ -247,19 +201,19 @@ private async void BluetoothDeviceAdded(DeviceWatcher watcher, DeviceInformation
}
}
- private void BluetoothDeviceUpdated(DeviceWatcher watcher, DeviceInformationUpdate device)
+ private void BluetoothDeviceUpdated(DeviceWatcher watcher, DeviceInformationUpdate device)
{
// Need this function for Bluetooth LE device watcher, otherwise it won't detect anything
}
-
+
private async void ConnectToKeyboard(DeviceInformation device)
{
try
{
- if(this.KeyboardDeviceInformation != null)
- {
- return;
- }
+ if (this.KeyboardDeviceInformation != null)
+ {
+ return;
+ }
var keyboard = await BluetoothLEDevice.FromIdAsync(device.Id);
@@ -268,680 +222,236 @@ private async void ConnectToKeyboard(DeviceInformation device)
return;
}
- if(keyboard.ConnectionStatus != BluetoothConnectionStatus.Connected)
+ if (keyboard.ConnectionStatus != BluetoothConnectionStatus.Connected)
{
return;
}
var service = keyboard.GetGattService(OAD_GUID);
- if (service == null)
+ if (service == null)
{
return;
}
- var write_gatt = service.GetCharacteristics(WRITE_GATT_GUID)[0];
- var read_gatt = service.GetCharacteristics(READ_GATT_GUID)[0];
+ var write_gatt = service.GetCharacteristics(WRITE_GATT_GUID)[0];
+ var read_gatt = service.GetCharacteristics(READ_GATT_GUID)[0];
- if (write_gatt == null || read_gatt == null)
+ if (write_gatt == null || read_gatt == null)
{
return;
}
this.WriteGatt = write_gatt;
- this.ReadGatt = read_gatt;
- this.KeyboardDeviceInformation = device;
-
- await this.ReadGatt.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify);
- this.ReadGatt.ValueChanged += ReadGatt_ValueChanged;
-
- // Sync up the profile data
- this.RequestKeyboardSync();
- }
- // We should actually catch errors here...
- catch(Exception ex)
- {
- Debug.WriteLine(ex);
- }
- }
-
- private void ReadGatt_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
- {
- var data = args.CharacteristicValue.ToArray();
-
- //TODO: handle the retrieved data
- }
-
- private void RequestKeyboardSync()
- {
- // expect firmware version and mac address
- byte[] device_id_meta_data = { 0x02, 0x01, 0x01 };
-
- KeyboardWriter keyboard_writer = new KeyboardWriter(this.WriteGatt, device_id_meta_data, null);
- keyboard_writer.WriteToKeyboard();
-
- keyboard_writer.OnWriteFinished += (object_s, events) =>
- {
- FinishSync();
- };
- }
-
- private async void FinishSync()
- {
- await Dispatcher.RunAsync(CoreDispatcherPriority.High, () =>
- {
- this.connectionStatusLabel.Text = "Connected";
- this.connectionStatusLabel.Foreground = new SolidColorBrush(Colors.Green);
- this.LightSyncButton.IsEnabled = true;
- this.LayoutSyncButton.IsEnabled = true;
- });
- }
-
- private void CreateNewKeyboardProfile()
- {
- KeyboardProfileItem profile_item = new KeyboardProfileItem(this._keyboardProfiles.Count, "Profile " + (this._keyboardProfiles.Count + 1));
- this._keyboardProfiles.Add(profile_item);
- }
-
- private void ChangeSelectedProfile(KeyboardProfileItem profile)
- {
- this.EditingProfile = profile;
- chosenProfileName.Title = profile.Label;
-
- // set up the background colours for the keyboard lights
- for (int i = 0; i < 70; i++)
- {
- // set the standard layout keys
- if (i < 61)
- {
- string layout_id = "keyboardStandardLayoutButton" + i;
- Button layout_button = (this.FindName(layout_id) as Button);
-
- if (layout_button != null)
- {
- layout_button.Content = profile.NormalKeys[i].KeyShortLabel;
- }
+ this.ReadGatt = read_gatt;
+ this.KeyboardDeviceInformation = device;
- string fn_layout_id = "keyboardFNLayoutButton" + i;
- Button fn_layout_button = (this.FindName(fn_layout_id) as Button);
+ await this.ReadGatt.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify);
+ this.ReadGatt.ValueChanged += ReadGatt_ValueChanged;
- if (fn_layout_id != null)
- {
- fn_layout_button.Content = profile.FnKeys[i].KeyShortLabel;
- }
- }
-
- string s = "keyboardButton" + i;
- Button button = (this.FindName(s) as Button);
-
- // NOTE: last 4 keys (RALT, FN, Anne, Ctrl) are identify as 66,67,68,69
- if (button == null)
- {
- continue;
- }
-
- int coloured_int = profile.KeyboardColours[i];
-
- Color colour = ConvertIntToColour(coloured_int);
-
- button.BorderBrush = new SolidColorBrush(colour);
- button.BorderThickness = new Thickness(1);
- button.Background = new SolidColorBrush(colour);
- }
-
- //colour the multi selection buttons
- //check the WASD keys. If all same, color WASD button
- Color multi_colour = ConvertIntToColour(profile.KeyboardColours[16]); //W key idx
- Button multi_button = (this.FindName("WASDKeys") as Button);
- Color default_colour = Color.FromArgb(255, 75, 75, 75);
- if (colour_wasd(profile))
- {
- setButtonColour(multi_button, multi_colour);
- }
- else
- {
- setButtonColour(multi_button, default_colour);
- }
-
- //check IJKL keys
- if (colour_ijkl(profile))
- {
- multi_colour = ConvertIntToColour(profile.KeyboardColours[22]); //I key idx
- multi_button = (this.FindName("IJKLKeys") as Button);
- setButtonColour(multi_button, multi_colour);
- }
- else
- {
- setButtonColour(multi_button, default_colour);
- }
-
- //check Modifier Keys
- if (colour_modifiers(profile))
- {
- multi_colour = ConvertIntToColour(profile.KeyboardColours[14]); //Tab key idx
- multi_button = (this.FindName("ModifierKeys") as Button);
- setButtonColour(multi_button, multi_colour);
- }
- else
- {
- setButtonColour(multi_button, default_colour);
- }
-
- //check num row
- if (colour_num_row(profile))
- {
- multi_colour = ConvertIntToColour(profile.KeyboardColours[1]); //1 key idx
- multi_button = (this.FindName("NumKeys") as Button);
- setButtonColour(multi_button, multi_colour);
+ // Sync up the profile data
+ this.RequestKeyboardSync();
}
- else
+ // We should actually catch errors here...
+ catch (Exception ex)
{
- setButtonColour(multi_button, default_colour);
+ Debug.WriteLine(ex);
}
-
- //set all buttons colour to default colour. Easy to see if all buttons are the same colour
- multi_button = (this.FindName("AllKeys") as Button);
- setButtonColour(multi_button, default_colour);
}
- private Boolean colour_wasd(KeyboardProfileItem profile)
+ private void ReadGatt_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
{
- return (
- profile.KeyboardColours[16] == profile.KeyboardColours[29] &&
- profile.KeyboardColours[29] == profile.KeyboardColours[30] &&
- profile.KeyboardColours[30] == profile.KeyboardColours[31]
- );
- }
+ var data = args.CharacteristicValue.ToArray();
- private Boolean colour_ijkl(KeyboardProfileItem profile)
- {
- return (
- profile.KeyboardColours[22] == profile.KeyboardColours[35] &&
- profile.KeyboardColours[35] == profile.KeyboardColours[36] &&
- profile.KeyboardColours[36] == profile.KeyboardColours[37]
- );
+ //TODO: handle the retrieved data
}
- private Boolean colour_num_row(KeyboardProfileItem profile)
+ private void RequestKeyboardSync()
{
- int colour = profile.KeyboardColours[1];
- for (int i = 2; i < 11; i++)
- {
- if (profile.KeyboardColours[i] != colour)
- return false;
- }
- return true;
- }
+ // expect firmware version and mac address
+ byte[] device_id_meta_data = { 0x02, 0x01, 0x01 };
- private Boolean colour_modifiers(KeyboardProfileItem profile)
- {
- int[] modifiers = new int[14] { 14, 28, 42, 56, 57, 58, 66, 67, 68, 69, 55, 41, 13, 27 }; //Tab->LCtrl->RCtrl->Bkspc: 14,28,42,56,57,58,66,67,68,69,55,41,13,27
+ KeyboardWriter keyboard_writer = new KeyboardWriter(this.WriteGatt, device_id_meta_data, null);
+ keyboard_writer.WriteToKeyboard();
- int colour = profile.KeyboardColours[14];
- foreach (int i in modifiers)
+ keyboard_writer.OnWriteFinished += (object_s, events) =>
{
- if (profile.KeyboardColours[i] != colour)
- return false;
- }
- return true;
+ FinishSync();
+ };
}
- private void KeyboardProfiles_ItemClick(object sender, ItemClickEventArgs e)
+ private async void FinishSync()
{
- KeyboardProfileItem profile = (e.ClickedItem as KeyboardProfileItem);
- ChangeSelectedProfile(profile);
+ await Dispatcher.RunAsync(CoreDispatcherPriority.High, () =>
+ {
+ this.connectionStatusLabel.Text = "Connected";
+ this.connectionStatusLabel.Foreground = new SolidColorBrush(Colors.Green);
+ ProfileSyncButton.IsEnabled = true;
+ });
}
- private void setButtonColour(Button button)
+ public void SyncProfile(KeyboardProfileItem EditingProfile)
{
- setButtonColour(button, this.SelectedColour);
+ EditingProfile.SyncProfile(this.WriteGatt);
}
- private void setButtonColour(Button button, Color colour)
+ private void hamburgerHover(object sender, RoutedEventArgs e)
{
- if (!matchingButtonColour)
- {
- button.BorderBrush = new SolidColorBrush(colour);
- button.BorderThickness = new Thickness(1);
- button.Background = new SolidColorBrush(colour);
- if (Brightness(colour) > 200)
- {
- button.Foreground = new SolidColorBrush(Color.FromArgb(255,75,75,75));
- }
- else
- {
- button.Foreground = new SolidColorBrush(Color.FromArgb(255,255,255,255));
- }
- }
- else if(button.Name.Length > 14)
- {
- int button_index = Int32.Parse(button.Name.Remove(0, 14));
- int colour_int = this.EditingProfile.KeyboardColours[button_index];
- this.SelectedColour = colour;
- this.colourPicker.SelectedColor = colour;
- matchingButtonColour = false;
- }
+ //HamburgerButton.Background = new SolidColorBrush(Colors.Red);
}
- private int Brightness(Color c)
+ private static Color lightenDarkenColor(Color color, double correctionFactor)
{
- return (int)Math.Sqrt(
- c.R * c.R * .241 +
- c.G * c.G * .691 +
- c.B * c.B * .068);
+ double red = (255 - color.R) * correctionFactor + color.R;
+ double green = (255 - color.G) * correctionFactor + color.G;
+ double blue = (255 - color.B) * correctionFactor + color.B;
+ return Color.FromArgb(color.A, (byte)red, (byte)green, (byte)blue);
}
- private void KeyboardColourButton_Click(object sender, RoutedEventArgs e)
+ private void Current_Activated(object sender, WindowActivatedEventArgs e)
{
- if (matchingButtonColour)
+ if (e.WindowActivationState != CoreWindowActivationState.Deactivated)
{
- (this.FindName("ColourTool") as Button).Content = "Match a Colour";
- matchingButtonColour = false;
- Button button = (Button)sender;
- int btn_int = Int32.Parse(button.Name.Remove(0, 14));
- btn_int = this.EditingProfile.KeyboardColours[btn_int];
- this.SelectedColour = ConvertIntToColour(btn_int);
- //enable multikey buttons
- enableMultiButtons();
+ MainTitleBar.Background = new SolidColorBrush((Color)this.Resources["SystemAccentColor"]);
+ pageHeader.Foreground = new SolidColorBrush(Colors.White);
+ HamburgerButton.Background = new SolidColorBrush(Color.FromArgb(51,255,255,255));
+ HamburgerButton.Foreground = new SolidColorBrush(Colors.White);
}
else
{
- Button button = (Button)sender;
- setButtonColour(button);
-
- int button_index = Int32.Parse(button.Name.Remove(0, 14));
-
- this.EditingProfile.KeyboardColours[button_index] = ConvertColourToInt(this.SelectedColour);
-
- //this may be resource intensive, but it's the only way to gurantee that profiles get saved
- this.SaveProfiles();
+ pageHeader.Foreground = new SolidColorBrush(Color.FromArgb(255, 152, 152, 152));
+ MainTitleBar.Background = new SolidColorBrush(Colors.White);
+ HamburgerButton.Background = new SolidColorBrush(Colors.White);
+ HamburgerButton.Foreground = new SolidColorBrush(Color.FromArgb(255, 152, 152, 152));
}
}
- private void KeyboardAllButton_Click(object sender, RoutedEventArgs e)
+ private void KeyboardSyncButton_Click(object sender, RoutedEventArgs e)
{
-
- Button button = (Button)sender;
- setButtonColour(button);
-
- for (int i = 0; i < 70; i++)
+ if(_frame.Content.GetType() == typeof(LayoutPage))
{
- if (i == 53 || i == 54 || i == 59 || i == 60 || i == 62 || i == 63 || i == 64 || i == 65)
- {
- continue;
- }
- this.EditingProfile.KeyboardColours[i] = ConvertColourToInt(this.SelectedColour);
- string s = "keyboardButton" + i;
- button = (this.FindName(s) as Button);
- setButtonColour(button);
+ LayoutSyncButton(_frame.Content as LayoutPage);
}
- //set Multi selection button colors
- setButtonColour(this.FindName("WASDKeys") as Button);
- setButtonColour(this.FindName("IJKLKeys") as Button);
- setButtonColour(this.FindName("NumKeys") as Button);
- setButtonColour(this.FindName("AllKeys") as Button);
- setButtonColour(this.FindName("ModifierKeys") as Button);
-
- //this may be resource intensive, but it's the only way to gurantee that profiles get saved
- this.SaveProfiles();
- }
- private void KeyboardWASDButton_Click(object sender, RoutedEventArgs e)
- {
- Button button = (Button)sender;
- setButtonColour(button);
-
- int[] modifiers = new int[4] { 16, 29, 30, 31 };
- foreach (int i in modifiers)
+ else if (_frame.Content.GetType() == typeof(LightingPage))
{
- this.EditingProfile.KeyboardColours[i] = ConvertColourToInt(this.SelectedColour);
-
- string s = "keyboardButton" + i;
- button = (this.FindName(s) as Button);
- setButtonColour(button);
+ LightingSyncButton(_frame.Content as LightingPage);
}
-
- //this may be resource intensive, but it's the only way to gurantee that profiles get saved
- this.SaveProfiles();
}
- private void KeyboardIJKLButton_Click(object sender, RoutedEventArgs e)
+ private void LightingSyncButton(LightingPage child)
{
- Button button = (Button)sender;
- setButtonColour(button);
-
- int[] modifiers = new int[4] { 22, 35, 36, 37 };
- foreach (int i in modifiers)
+ if (!child.EditingProfile.ValidateKeyboardKeys())
{
- this.EditingProfile.KeyboardColours[i] = ConvertColourToInt(this.SelectedColour);
-
- string s = "keyboardButton" + i;
- button = (this.FindName(s) as Button);
- setButtonColour(button);
+ //this.SyncStatus.Text = "Fn or Anne keys were not found in the Standard or Fn layouts";
+ return;
}
- //this may be resource intensive, but it's the only way to gurantee that profiles get saved
- this.SaveProfiles();
- }
-
- private void KeyboardNumRowButton_Click(object sender, RoutedEventArgs e)
- {
- Button button = (Button)sender;
- setButtonColour(button);
-
- for(int i = 1; i < 11; i++) //num: 1-10 -=: 11-12
+ try
{
- this.EditingProfile.KeyboardColours[i] = ConvertColourToInt(this.SelectedColour);
- string s = "keyboardButton" + i;
- button = (this.FindName(s) as Button);
- setButtonColour(button);
+ child.SaveProfiles();
}
-
- //this may be resource intensive, but it's the only way to gurantee that profiles get saved
- this.SaveProfiles();
- }
-
- private void KeyboardModifiersButton_Click(object sender, RoutedEventArgs e)
- {
- Button button = (Button)sender;
- setButtonColour(button);
-
- int[] modifiers = new int[14] { 14, 28, 42, 56, 57, 58, 66, 67, 68, 69, 55, 41, 13, 27 }; //Tab->LCtrl->RCtrl->Bkspc: 14,28,42,56,57,58,66,67,68,69,55,41,13,27
- foreach (int i in modifiers)
+ catch (UnauthorizedAccessException)
{
- this.EditingProfile.KeyboardColours[i] = ConvertColourToInt(this.SelectedColour);
- string s = "keyboardButton" + i;
- button = (this.FindName(s) as Button);
- setButtonColour(button);
+ SyncStatus.Text = "UnAuthorizedAccessException: Unable to access file. ";
}
- //this may be resource intensive, but it's the only way to gurantee that profiles get saved
- this.SaveProfiles();
- }
-
- private void KeyboardColourPickerButton_Click(object sender, RoutedEventArgs e)
- {
- Button button = (Button)sender;
- Button wasd = this.FindName("WASDKeys") as Button;
+ ProfileSyncButton.IsEnabled = false;
- if (!matchingButtonColour)
- {
- matchingButtonColour = true;
- button.Content = "Cancel";
- //Disable multikey buttons
- disableMultiButtons();
- }
- else
+ this.SyncProfile(child.EditingProfile);
+ child.EditingProfile.SyncStatusNotify += async (object_s, events) =>
{
- matchingButtonColour = false;
- button.Content = "Match a Colour";
- //enable multikey buttons
- enableMultiButtons();
- }
- }
-
- private void enableMultiButtons()
- {
- (this.FindName("WASDKeys") as Button).IsEnabled = true;
- (this.FindName("IJKLKeys") as Button).IsEnabled = true;
- (this.FindName("NumKeys") as Button).IsEnabled = true;
- (this.FindName("AllKeys") as Button).IsEnabled = true;
- (this.FindName("ModifierKeys") as Button).IsEnabled = true;
- }
-
- private void disableMultiButtons()
- {
- (this.FindName("WASDKeys") as Button).IsEnabled = false;
- (this.FindName("IJKLKeys") as Button).IsEnabled = false;
- (this.FindName("NumKeys") as Button).IsEnabled = false;
- (this.FindName("AllKeys") as Button).IsEnabled = false;
- (this.FindName("ModifierKeys") as Button).IsEnabled = false;
- }
-
-
- private int ConvertColourToInt(Color colour)
- {
- int colour_int = colour.R;
- colour_int = (colour_int << 8) + colour.G;
- colour_int = (colour_int << 8) + colour.B;
-
- return colour_int;
- }
-
- private Color ConvertIntToColour(int coloured_int)
- {
- int red = (coloured_int >> 16) & 0xff;
- int green = (coloured_int >> 8) & 0xff;
- int blue = (coloured_int >> 0) & 0xff;
+ await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
+ {
+ this.SyncStatus.Text = (string)object_s;
- return Color.FromArgb(255, (byte)red, (byte)green, (byte)blue);
+ this.ProfileSyncButton.IsEnabled = true;
+ });
+ };
}
- private void ProfileNameChangedEvent_TextChanged(object sender, TextChangedEventArgs e)
+ private void LayoutSyncButton(LayoutPage child)
{
- TextBox profileName = (sender as TextBox);
- // update Views and KeyboardProfileItem class
- if(this.EditingProfile == RenamingProfile)
- {
- chosenProfileName.Title = profileName.Text;
- }
-
- if(this.RenamingProfile != null)
+ if (!child.EditingProfile.ValidateKeyboardKeys())
{
- this.RenamingProfile.Label = profileName.Text;
+ this.SyncStatus.Text = "Fn or Anne keys were not found in the Standard or Fn layouts";
+ return;
}
- }
-
- private void ProfileAddButton_Click(object sender, RoutedEventArgs e)
- {
- this.CreateNewKeyboardProfile();
-
- this.SaveProfiles();
- }
-
- private void ProfileEditButton_Click(object sender, RoutedEventArgs e)
- {
- Button button = (Button)sender;
- FrameworkElement parent = (FrameworkElement)button.Parent;
-
- TextBox textbox = (TextBox)parent.FindName("ProfileNameTextbox");
- textbox.IsEnabled = true;
- textbox.Visibility = Visibility.Visible;
- FocusState focus_state = FocusState.Keyboard;
- textbox.Focus(focus_state);
-
- TextBlock textblock = (TextBlock)parent.FindName("ProfileNameTextblock");
- textblock.Visibility = Visibility.Collapsed;
-
- this.RenamingProfile = this._keyboardProfiles[(int)button.Tag];
- }
-
- private void ProfileDeleteButton_Click(object sender, RoutedEventArgs e)
- {
- Button button = (Button)sender;
- FrameworkElement parent = (FrameworkElement)button.Parent;
- TextBox textbox = (TextBox)parent.FindName("ProfileNameTextbox");
- KeyboardProfileItem selected_profile = this._keyboardProfiles[(int)button.Tag];
-
- this._keyboardProfiles.Remove(selected_profile);
- // always make sure that the keyboard profiles list has 1 element in it
- if (this._keyboardProfiles.Count == 0)
+ try
{
- this.CreateNewKeyboardProfile();
+ child.SaveProfiles();
}
-
- // Change the chosen profile to the first element
- ChangeSelectedProfile(this._keyboardProfiles[0]);
-
- this.SaveProfiles();
- }
-
- private void KeyboardSyncButton_Click(object sender, RoutedEventArgs e)
- {
- if(!this.EditingProfile.ValidateKeyboardKeys())
+ catch (UnauthorizedAccessException)
{
- this.SyncStatus.Text = "Fn or Anne keys were not found in the Standard or Fn layouts";
- return;
+ SyncStatus.Text = "UnAuthorizedAccessException: Unable to access file. ";
}
-
- this.SaveProfiles();
-
- this.LayoutSyncButton.IsEnabled = false;
- this.LightSyncButton.IsEnabled = false;
+ ProfileSyncButton.IsEnabled = false;
- this.EditingProfile.SyncProfile(this.WriteGatt);
- this.EditingProfile.SyncStatusNotify += async (object_s, events) =>
+ this.SyncProfile(child.EditingProfile);
+ child.EditingProfile.SyncStatusNotify += async (object_s, events) =>
{
await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
this.SyncStatus.Text = (string)object_s;
- this.LayoutSyncButton.IsEnabled = true;
- this.LightSyncButton.IsEnabled = true;
+ this.ProfileSyncButton.IsEnabled = true;
});
};
}
-
- private void ProfileNameTextbox_LostFocus(object sender, RoutedEventArgs e)
- {
- this.SaveProfiles();
-
- TextBox textbox = (TextBox)sender;
- textbox.IsEnabled = false;
- textbox.Visibility = Visibility.Collapsed;
-
- FrameworkElement parent = (FrameworkElement)textbox.Parent;
- TextBlock textblock = (TextBlock)parent.FindName("ProfileNameTextblock");
- textblock.Visibility = Visibility.Visible;
- this.RenamingProfile = null;
- }
-
- private void colourPicker_colourChanged(object sender, EventArgs e)
+ private void HamburgerButton_Click(object sender, RoutedEventArgs e)
{
- this.SelectedColour = this.colourPicker.SelectedColor;
+ splitView.IsPaneOpen = !splitView.IsPaneOpen;
}
-
- private void KeyboardProfiles_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
+
+ private void LightingNav_Clicked(object sender, RoutedEventArgs e)
{
- if(e.Action == NotifyCollectionChangedAction.Add || e.Action == NotifyCollectionChangedAction.Remove)
+ if (!(_frame.Content.GetType() == typeof(LightingPage)))
{
- // Really inefficient, we should consider re-implementing this later
- for (int i = 0; i < this._keyboardProfiles.Count; i++)
+ _frame.Content = lightingPage;
+ lightingPage.LoadProfiles();
+ if (connectionStatusLabel.Text == "Connected")
{
- KeyboardProfileItem profile = this._keyboardProfiles[i];
- profile.ID = i;
+ ProfileSyncButton.IsEnabled = true;
}
+ pageHeader.Text = "Lighting";
+ LightingMenuButton.Background = new SolidColorBrush(Color.FromArgb(1, 0, 0, 0));
}
}
-
- private async void KeyboardLayoutButton_Click(object sender, RoutedEventArgs e)
- {
- if(this.CurrentlyEditingFnKey != null)
- {
- this.CurrentlyEditingFnKey.Visibility = Visibility.Visible;
- this.CurrentlyEditingFnKey = null;
- }
-
- if(this.CurrentlyEditingStandardKey != null)
- {
- this.CurrentlyEditingStandardKey.Visibility = Visibility.Visible;
- this.CurrentlyEditingStandardKey = null;
- }
- Button button = (Button)sender;
-
- bool fn_mode = button.Name.StartsWith("keyboardFNLayoutButton");
-
- if(fn_mode)
- {
- this.CurrentlyEditingFnKey = button;
- }
- else
+ private void LayoutNav_Clicked(object sender, RoutedEventArgs e)
+ {
+ if (!(_frame.Content.GetType() == typeof(LayoutPage)))
{
- this.CurrentlyEditingStandardKey = button;
+ _frame.Content = layoutPage;
+ layoutPage.LoadProfiles();
+ if(connectionStatusLabel.Text == "Connected")
+ {
+ ProfileSyncButton.IsEnabled = true;
+ }
+ pageHeader.Text = "Layers";
+ LayoutMenuButton.Background = new SolidColorBrush(Color.FromArgb(1, 0, 0, 0));
}
-
- // Switch parents
- RelativePanel selector_parent = (RelativePanel)keyboardLayoutSelection.Parent;
- selector_parent.Children.Remove(keyboardLayoutSelection);
-
- RelativePanel parent = (RelativePanel)button.Parent;
- parent.Children.Add(keyboardLayoutSelection);
-
- keyboardLayoutSelection.Margin = button.Margin;
- keyboardLayoutSelection.Width = button.Width;
- keyboardLayoutSelection.SelectedIndex = this.KeyboardKeyLabels.IndexOf((string)button.Content);
-
- button.Visibility = Visibility.Collapsed;
- keyboardLayoutSelection.Visibility = Visibility.Visible;
-
- await Task.Delay(1);
-
- keyboardLayoutSelection.IsDropDownOpen = true;
}
- private void KeyboardStandardLayout_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ private void AboutNav_Clicked(object sender, RoutedEventArgs e)
{
- string label = keyboardLayoutSelection.SelectedItem as string;
-
- if(String.IsNullOrEmpty(label))
- {
- label = KeyboardKey.IntKeyboardKeys[0].KeyShortLabel;
- }
-
- Button button = (this.CurrentlyEditingStandardKey != null) ? this.CurrentlyEditingStandardKey : this.CurrentlyEditingFnKey;
- int length = (this.CurrentlyEditingStandardKey != null) ? 28 : 22; // special constants
-
- int index = -1;
-
- try
- {
- Int32.TryParse(button.Name.Substring(length), out index);
- }
- catch
- {
- }
-
- if(index >= 0)
+ if (!(_frame.Content.GetType() == typeof(AboutPage)))
{
- string full_label = this.KeyboardKeyLabelTranslation[label];
-
- if(this.CurrentlyEditingFnKey != null)
+ _frame.Content = aboutPage;
+ if (connectionStatusLabel.Text == "Connected")
{
- this.EditingProfile.FnKeys[index] = KeyboardKey.StringKeyboardKeys[full_label];
-
-
- this.CurrentlyEditingFnKey.Content = label;
- this.CurrentlyEditingFnKey.Visibility = Visibility.Visible;
- }
- else
- {
- this.EditingProfile.NormalKeys[index] = KeyboardKey.StringKeyboardKeys[full_label];
-
- this.CurrentlyEditingStandardKey.Content = label;
- this.CurrentlyEditingStandardKey.Visibility = Visibility.Visible;
+ ProfileSyncButton.IsEnabled = false;
}
+ pageHeader.Text = "About";
+ LayoutMenuButton.Background = new SolidColorBrush(Color.FromArgb(1, 0, 0, 0));
}
-
- this.SaveProfiles();
}
- private void KeyboardStandardLayout_DropDownClosed(object sender, object e)
+ private void pageHeader_SelectionChanged(object sender, RoutedEventArgs e)
{
- if (this.CurrentlyEditingFnKey != null)
- {
- this.CurrentlyEditingFnKey.Visibility = Visibility.Visible;
- }
-
- if (this.CurrentlyEditingStandardKey != null)
- {
- this.CurrentlyEditingStandardKey.Visibility = Visibility.Visible;
- }
-
- this.keyboardLayoutSelection.Visibility = Visibility.Collapsed;
}
}
}
diff --git a/AnneProKeyboard/project.json b/AnneProKeyboard/project.json
index 3414aa0..2b69ecc 100644
--- a/AnneProKeyboard/project.json
+++ b/AnneProKeyboard/project.json
@@ -1,7 +1,12 @@
{
"dependencies": {
+ "Coding4Fun.Toolkit.Controls": "2.1.8",
+ "ColorPicker": "1.0.2",
"Color_Picker": "1.0.5",
- "Microsoft.NETCore.UniversalWindowsPlatform": "5.2.2"
+ "FontAwesome.UWP": "4.7.0.9",
+ "Microsoft.NETCore.UniversalWindowsPlatform": "5.2.2",
+ "Microsoft.Toolkit.Uwp": "1.5.0",
+ "Microsoft.Toolkit.Uwp.UI.Controls": "1.5.0"
},
"frameworks": {
"uap10.0": {}
diff --git a/README.md b/README.md
index 090104c..eff60c6 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
# Anne Keyboard Windows
-A Universal Windows App for controlling the an Anne Pro keyboard over Bluetooth Low Energy.
+A Universal Windows App for controlling the an Anne Pro keyboard over Bluetooth Low Energy.
## Requirements
This app has been tested against Windows 10. Other version of Windows is not supported due to Universal Windows App (UWP) platform only supporting Windows 10.
@@ -16,10 +16,15 @@ The keyboard has to be in L0 mode by: pressing ```Fn+B, Fn+0, ESC, Fn+B, +```
* Create and manage profiles
* Set keyboard backlight colours
+### Screenshots:
+
+
+
+
## Planned Features
* Support for changing keyboard layouts
* Implement keyboard macros
-* Improve changing multiple button keyboard light colours
+* ~~Improve changing multiple button keyboard light colours~~
## Known Bugs
* None so far.