Generic HID event with key recognition functional.
1.1 --- a/Server/Events/EventHid.cs Fri Aug 19 19:28:03 2016 +0200
1.2 +++ b/Server/Events/EventHid.cs Sat Aug 20 21:00:35 2016 +0200
1.3 @@ -41,13 +41,13 @@
1.4 public bool IsKeyUp { get; set; } = false;
1.5
1.6 [DataMember]
1.7 - public bool IsMouse { get; set; }
1.8 + public bool IsMouse { get; set; } = false;
1.9
1.10 [DataMember]
1.11 - public bool IsKeyboard { get; set; }
1.12 + public bool IsKeyboard { get; set; } = false;
1.13
1.14 [DataMember]
1.15 - public bool IsGeneric { get; set; }
1.16 + public bool IsGeneric { get; set; } = false;
1.17
1.18 [DataMember]
1.19 public bool HasModifierShift { get; set; } = false;
1.20 @@ -61,6 +61,10 @@
1.21 [DataMember]
1.22 public bool HasModifierWindows { get; set; } = false;
1.23
1.24 + [DataMember]
1.25 + public string PersistedBrief { get; set; } = "Press a key";
1.26 +
1.27 +
1.28
1.29 protected override void DoConstruct()
1.30 {
1.31 @@ -73,7 +77,6 @@
1.32
1.33 }
1.34
1.35 -
1.36 /// <summary>
1.37 /// Make sure we distinguish between various configuration of this event
1.38 /// </summary>
1.39 @@ -108,7 +111,7 @@
1.40 }
1.41 else if (IsGeneric)
1.42 {
1.43 -
1.44 + brief += PersistedBrief;
1.45 }
1.46
1.47 if (IsKeyUp)
1.48 @@ -143,5 +146,111 @@
1.49
1.50 return false;
1.51 }
1.52 +
1.53 +
1.54 + /// <summary>
1.55 + ///
1.56 + /// </summary>
1.57 + protected override void OnStateLeave()
1.58 + {
1.59 + if (CurrentState == State.Edit)
1.60 + {
1.61 + // Leaving edit mode
1.62 + // Unhook HID events
1.63 + Program.HidHandler.OnHidEvent -= HandleHidEvent;
1.64 +
1.65 + }
1.66 + }
1.67 +
1.68 + /// <summary>
1.69 + ///
1.70 + /// </summary>
1.71 + protected override void OnStateEnter()
1.72 + {
1.73 + if (CurrentState == State.Edit)
1.74 + {
1.75 + // Enter edit mode
1.76 + // Hook-in HID events
1.77 + Program.HidHandler.OnHidEvent += HandleHidEvent;
1.78 +
1.79 + }
1.80 + }
1.81 +
1.82 + /// <summary>
1.83 + /// Here we receive HID events from our HID library.
1.84 + /// </summary>
1.85 + /// <param name="aSender"></param>
1.86 + /// <param name="aHidEvent"></param>
1.87 + public void HandleHidEvent(object aSender, SharpLib.Hid.Event aHidEvent)
1.88 + {
1.89 + if (CurrentState != State.Edit
1.90 + || aHidEvent.IsMouse
1.91 + || aHidEvent.IsButtonUp
1.92 + || !aHidEvent.IsValid
1.93 + || aHidEvent.IsBackground
1.94 + || aHidEvent.IsRepeat
1.95 + || aHidEvent.IsStray)
1.96 + {
1.97 + return;
1.98 + }
1.99 +
1.100 + PrivateCopy(aHidEvent);
1.101 + //
1.102 +
1.103 + //Tell observer the object itself changed
1.104 + OnPropertyChanged("Brief");
1.105 + }
1.106 +
1.107 + /// <summary>
1.108 + ///
1.109 + /// </summary>
1.110 + /// <param name="aHidEvent"></param>
1.111 + public void Copy(Hid.Event aHidEvent)
1.112 + {
1.113 + PrivateCopy(aHidEvent);
1.114 + //We need the key up/down too here
1.115 + IsKeyUp = aHidEvent.IsButtonUp;
1.116 + }
1.117 +
1.118 + /// <summary>
1.119 + ///
1.120 + /// </summary>
1.121 + /// <param name="aHidEvent"></param>
1.122 + private void PrivateCopy(Hid.Event aHidEvent)
1.123 + {
1.124 + //Copy for scan
1.125 + UsagePage = aHidEvent.UsagePage;
1.126 + UsageCollection = aHidEvent.UsageCollection;
1.127 + IsGeneric = aHidEvent.IsGeneric;
1.128 + IsKeyboard = aHidEvent.IsKeyboard;
1.129 + IsMouse = aHidEvent.IsMouse;
1.130 +
1.131 + if (IsGeneric)
1.132 + {
1.133 + if (aHidEvent.Usages.Count > 0)
1.134 + {
1.135 + Usage = aHidEvent.Usages[0];
1.136 + PersistedBrief = aHidEvent.UsageName(0);
1.137 + }
1.138 +
1.139 + Key = Keys.None;
1.140 + HasModifierAlt = false;
1.141 + HasModifierControl = false;
1.142 + HasModifierShift = false;
1.143 + HasModifierWindows = false;
1.144 + }
1.145 + else if (IsKeyboard)
1.146 + {
1.147 + Usage = 0;
1.148 + Key = aHidEvent.VirtualKey;
1.149 + HasModifierAlt = aHidEvent.HasModifierAlt;
1.150 + HasModifierControl = aHidEvent.HasModifierControl;
1.151 + HasModifierShift = aHidEvent.HasModifierShift;
1.152 + HasModifierWindows = aHidEvent.HasModifierWindows;
1.153 + }
1.154 +
1.155 + }
1.156 +
1.157 +
1.158 }
1.159 }
2.1 --- a/Server/FormEditObject.Designer.cs Fri Aug 19 19:28:03 2016 +0200
2.2 +++ b/Server/FormEditObject.Designer.cs Sat Aug 20 21:00:35 2016 +0200
2.3 @@ -36,6 +36,7 @@
2.4 this.iTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
2.5 this.toolTip = new System.Windows.Forms.ToolTip(this.components);
2.6 this.buttonTest = new System.Windows.Forms.Button();
2.7 + this.labelBrief = new System.Windows.Forms.Label();
2.8 this.SuspendLayout();
2.9 //
2.10 // comboBoxActionType
2.11 @@ -64,7 +65,7 @@
2.12 //
2.13 this.buttonOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
2.14 this.buttonOk.DialogResult = System.Windows.Forms.DialogResult.OK;
2.15 - this.buttonOk.Location = new System.Drawing.Point(12, 72);
2.16 + this.buttonOk.Location = new System.Drawing.Point(12, 151);
2.17 this.buttonOk.Name = "buttonOk";
2.18 this.buttonOk.Size = new System.Drawing.Size(75, 23);
2.19 this.buttonOk.TabIndex = 21;
2.20 @@ -76,7 +77,7 @@
2.21 //
2.22 this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
2.23 this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
2.24 - this.buttonCancel.Location = new System.Drawing.Point(93, 72);
2.25 + this.buttonCancel.Location = new System.Drawing.Point(93, 151);
2.26 this.buttonCancel.Name = "buttonCancel";
2.27 this.buttonCancel.Size = new System.Drawing.Size(75, 23);
2.28 this.buttonCancel.TabIndex = 22;
2.29 @@ -93,18 +94,18 @@
2.30 this.iTableLayoutPanel.ColumnCount = 2;
2.31 this.iTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
2.32 this.iTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
2.33 - this.iTableLayoutPanel.Location = new System.Drawing.Point(15, 50);
2.34 + this.iTableLayoutPanel.Location = new System.Drawing.Point(15, 72);
2.35 this.iTableLayoutPanel.Name = "iTableLayoutPanel";
2.36 this.iTableLayoutPanel.RowCount = 2;
2.37 this.iTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
2.38 this.iTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
2.39 - this.iTableLayoutPanel.Size = new System.Drawing.Size(312, 16);
2.40 + this.iTableLayoutPanel.Size = new System.Drawing.Size(312, 60);
2.41 this.iTableLayoutPanel.TabIndex = 23;
2.42 //
2.43 // buttonTest
2.44 //
2.45 this.buttonTest.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
2.46 - this.buttonTest.Location = new System.Drawing.Point(252, 72);
2.47 + this.buttonTest.Location = new System.Drawing.Point(252, 151);
2.48 this.buttonTest.Name = "buttonTest";
2.49 this.buttonTest.Size = new System.Drawing.Size(75, 23);
2.50 this.buttonTest.TabIndex = 24;
2.51 @@ -112,6 +113,17 @@
2.52 this.buttonTest.UseVisualStyleBackColor = true;
2.53 this.buttonTest.Click += new System.EventHandler(this.buttonTest_Click);
2.54 //
2.55 + // labelBrief
2.56 + //
2.57 + this.labelBrief.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
2.58 + | System.Windows.Forms.AnchorStyles.Right)));
2.59 + this.labelBrief.AutoSize = true;
2.60 + this.labelBrief.Location = new System.Drawing.Point(12, 45);
2.61 + this.labelBrief.Name = "labelBrief";
2.62 + this.labelBrief.Size = new System.Drawing.Size(28, 13);
2.63 + this.labelBrief.TabIndex = 25;
2.64 + this.labelBrief.Text = "Brief";
2.65 + //
2.66 // FormEditObject
2.67 //
2.68 this.AcceptButton = this.buttonOk;
2.69 @@ -120,13 +132,14 @@
2.70 this.AutoSize = true;
2.71 this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
2.72 this.CancelButton = this.buttonCancel;
2.73 - this.ClientSize = new System.Drawing.Size(339, 107);
2.74 + this.ClientSize = new System.Drawing.Size(339, 186);
2.75 + this.Controls.Add(this.labelBrief);
2.76 this.Controls.Add(this.buttonTest);
2.77 - this.Controls.Add(this.iTableLayoutPanel);
2.78 this.Controls.Add(this.buttonCancel);
2.79 this.Controls.Add(this.buttonOk);
2.80 this.Controls.Add(this.labelActionType);
2.81 this.Controls.Add(this.comboBoxActionType);
2.82 + this.Controls.Add(this.iTableLayoutPanel);
2.83 this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
2.84 this.MaximizeBox = false;
2.85 this.MinimizeBox = false;
2.86 @@ -148,5 +161,6 @@
2.87 private System.Windows.Forms.TableLayoutPanel iTableLayoutPanel;
2.88 private System.Windows.Forms.ToolTip toolTip;
2.89 private System.Windows.Forms.Button buttonTest;
2.90 + private System.Windows.Forms.Label labelBrief;
2.91 }
2.92 }
2.93 \ No newline at end of file
3.1 --- a/Server/FormEditObject.cs Fri Aug 19 19:28:03 2016 +0200
3.2 +++ b/Server/FormEditObject.cs Sat Aug 20 21:00:35 2016 +0200
3.3 @@ -53,7 +53,7 @@
3.4 else
3.5 {
3.6 // Editing existing object
3.7 - // Look up our item in our combobox
3.8 + // Look up our item in our object type combobox
3.9 foreach (ItemObjectType item in comboBoxActionType.Items)
3.10 {
3.11 if (item.Type == Object.GetType())
3.12 @@ -61,6 +61,7 @@
3.13 comboBoxActionType.SelectedItem = item;
3.14 }
3.15 }
3.16 +
3.17 }
3.18 }
3.19
3.20 @@ -78,6 +79,13 @@
3.21 private void FormEditObject_FormClosing(object sender, FormClosingEventArgs e)
3.22 {
3.23 e.Cancel = DialogResult == DialogResult.None;
3.24 +
3.25 + if (!e.Cancel)
3.26 + {
3.27 + //Exit edit mode
3.28 + Object.CurrentState = SharpLib.Ear.Object.State.Rest;
3.29 + Object.PropertyChanged -= PropertyChangedEventHandlerThreadSafe;
3.30 + }
3.31 }
3.32
3.33 private void comboBoxActionType_SelectedIndexChanged(object sender, EventArgs e)
3.34 @@ -338,8 +346,7 @@
3.35
3.36 /// <summary>
3.37 /// Update our table layout.
3.38 - /// Will instantiated every field control as defined by our action.
3.39 - /// Fields must be specified by rows from the left.
3.40 + /// Will instantiated every field control as defined by our object.
3.41 /// </summary>
3.42 /// <param name="aLayout"></param>
3.43 private void UpdateTableLayoutPanel(T aObject)
3.44 @@ -363,10 +370,13 @@
3.45 //Just drop it
3.46 return;
3.47 }
3.48 -
3.49 +
3.50 //IEnumerable<PropertyInfo> properties = aObject.GetType().GetProperties().Where(
3.51 // prop => Attribute.IsDefined(prop, typeof(AttributeObjectProperty)));
3.52
3.53 + //TODO: Do this whenever a field changes
3.54 + labelBrief.Text = Object.Brief();
3.55 +
3.56
3.57 foreach (PropertyInfo pi in aObject.GetType().GetProperties())
3.58 {
3.59 @@ -404,8 +414,34 @@
3.60 //Add tooltip to editor too
3.61 toolTip.SetToolTip(ctrl, attribute.Description);
3.62
3.63 - }
3.64 + }
3.65
3.66 + //Entrer object edit mode
3.67 + Object.CurrentState = SharpLib.Ear.Object.State.Edit;
3.68 + Object.PropertyChanged += PropertyChangedEventHandlerThreadSafe;
3.69 + }
3.70 +
3.71 + void PropertyChangedEventHandlerThreadSafe(object sender, PropertyChangedEventArgs e)
3.72 + {
3.73 + if (this.InvokeRequired)
3.74 + {
3.75 + //Not in the proper thread, invoke ourselves
3.76 + PropertyChangedEventHandler d = new PropertyChangedEventHandler(PropertyChangedEventHandlerThreadSafe);
3.77 + this.Invoke(d, new object[] { sender, e });
3.78 + }
3.79 + else
3.80 + {
3.81 + //Disable ok button if our object is not valid
3.82 + buttonOk.Enabled = Object.IsValid();
3.83 +
3.84 + if (e.PropertyName == "Brief")
3.85 + {
3.86 + labelBrief.Text = Object.Brief();
3.87 + }
3.88 +
3.89 + //Create input fields
3.90 + //UpdateTableLayoutPanel(Object);
3.91 + }
3.92 }
3.93
3.94 private void buttonTest_Click(object sender, EventArgs e)
4.1 --- a/Server/FormMain.Hid.cs Fri Aug 19 19:28:03 2016 +0200
4.2 +++ b/Server/FormMain.Hid.cs Sat Aug 20 21:00:35 2016 +0200
4.3 @@ -24,10 +24,6 @@
4.4 //
4.5 public delegate void OnHidEventDelegate(object aSender, Hid.Event aHidEvent);
4.6
4.7 - /// <summary>
4.8 - /// Use notably to handle green start key from IR remote control
4.9 - /// </summary>
4.10 - private Hid.Handler iHidHandler;
4.11
4.12 /// <summary>
4.13 /// Register HID devices so that we receive corresponding WM_INPUT messages.
4.14 @@ -89,12 +85,12 @@
4.15 //rid[i].hwndTarget = aHWND;
4.16
4.17
4.18 - iHidHandler = new SharpLib.Hid.Handler(rid);
4.19 - if (!iHidHandler.IsRegistered)
4.20 + Program.HidHandler = new SharpLib.Hid.Handler(rid);
4.21 + if (!Program.HidHandler.IsRegistered)
4.22 {
4.23 Debug.WriteLine("Failed to register raw input devices: " + Marshal.GetLastWin32Error().ToString());
4.24 }
4.25 - iHidHandler.OnHidEvent += HandleHidEventThreadSafe;
4.26 + Program.HidHandler.OnHidEvent += HandleHidEventThreadSafe;
4.27
4.28 }
4.29
4.30 @@ -184,7 +180,7 @@
4.31 case Const.WM_INPUT:
4.32 //Returning zero means we processed that message.
4.33 message.Result = new IntPtr(0);
4.34 - iHidHandler.ProcessInput(ref message);
4.35 + Program.HidHandler.ProcessInput(ref message);
4.36 break;
4.37 }
4.38
5.1 --- a/Server/Program.cs Fri Aug 19 19:28:03 2016 +0200
5.2 +++ b/Server/Program.cs Sat Aug 20 21:00:35 2016 +0200
5.3 @@ -20,6 +20,7 @@
5.4 using System;
5.5 using System.Windows.Forms;
5.6 using System.Security.Principal;
5.7 +using Hid = SharpLib.Hid;
5.8
5.9
5.10 namespace SharpDisplayManager
5.11 @@ -42,6 +43,11 @@
5.12
5.13
5.14 /// <summary>
5.15 + /// Use notably to handle green start key from IR remote control
5.16 + /// </summary>
5.17 + public static Hid.Handler HidHandler;
5.18 +
5.19 + /// <summary>
5.20 /// The main entry point for the application.
5.21 /// </summary>
5.22 [STAThread]
6.1 --- a/SharpLibEar/Object.cs Fri Aug 19 19:28:03 2016 +0200
6.2 +++ b/SharpLibEar/Object.cs Sat Aug 20 21:00:35 2016 +0200
6.3 @@ -48,6 +48,32 @@
6.4
6.5 }
6.6
6.7 +
6.8 + public enum State
6.9 + {
6.10 + Rest=0,
6.11 + Edit
6.12 + }
6.13 +
6.14 + State iCurrentState = State.Rest;
6.15 + public State CurrentState { get { return iCurrentState; } set { OnStateLeave(); iCurrentState = value; OnStateEnter(); } }
6.16 +
6.17 + /// <summary>
6.18 + ///
6.19 + /// </summary>
6.20 + protected virtual void OnStateLeave()
6.21 + {
6.22 +
6.23 + }
6.24 +
6.25 + /// <summary>
6.26 + ///
6.27 + /// </summary>
6.28 + protected virtual void OnStateEnter()
6.29 + {
6.30 +
6.31 + }
6.32 +
6.33 /// <summary>
6.34 /// Static object name.
6.35 /// </summary>
6.36 @@ -111,6 +137,7 @@
6.37 /// </summary>
6.38 public event PropertyChangedEventHandler PropertyChanged;
6.39
6.40 +
6.41 /// <summary>
6.42 /// Invoke our event.
6.43 /// </summary>