Events can now be instantiated.
Action editor is now a generic object editor.
1.1 --- a/Server/Actions/ActionCecActiveSource.cs Sun Jul 31 12:03:52 2016 +0200
1.2 +++ b/Server/Actions/ActionCecActiveSource.cs Fri Aug 12 20:25:05 2016 +0200
1.3 @@ -10,7 +10,7 @@
1.4 namespace SharpDisplayManager
1.5 {
1.6 [DataContract]
1.7 - [AttributeAction(Id = "Cec.ActiveSource", Name = "CEC Active Source", Description = "Set this CEC device as active source.")]
1.8 + [AttributeObject(Id = "Cec.ActiveSource", Name = "CEC Active Source", Description = "Set this CEC device as active source.")]
1.9 class ActionCecActiveSource : ActionCecDeviceType
1.10 {
1.11 /// <summary>
2.1 --- a/Server/Actions/ActionCecClose.cs Sun Jul 31 12:03:52 2016 +0200
2.2 +++ b/Server/Actions/ActionCecClose.cs Fri Aug 12 20:25:05 2016 +0200
2.3 @@ -10,7 +10,7 @@
2.4 namespace SharpDisplayManager
2.5 {
2.6 [DataContract]
2.7 - [AttributeAction(Id = "Cec.Close", Name = "CEC Close", Description = "Close CEC connection.")]
2.8 + [AttributeObject(Id = "Cec.Close", Name = "CEC Close", Description = "Close CEC connection.")]
2.9 class ActionCecClose : SharpLib.Ear.Action
2.10 {
2.11 protected override void DoExecute()
3.1 --- a/Server/Actions/ActionCecDevice.cs Sun Jul 31 12:03:52 2016 +0200
3.2 +++ b/Server/Actions/ActionCecDevice.cs Fri Aug 12 20:25:05 2016 +0200
3.3 @@ -17,7 +17,7 @@
3.4 public abstract class ActionCecDevice: SharpLib.Ear.Action
3.5 {
3.6 [DataMember]
3.7 - [AttributeActionProperty
3.8 + [AttributeObjectProperty
3.9 (
3.10 Id = "CEC.Device",
3.11 Name = "Device",
4.1 --- a/Server/Actions/ActionCecDevicePowerOn.cs Sun Jul 31 12:03:52 2016 +0200
4.2 +++ b/Server/Actions/ActionCecDevicePowerOn.cs Fri Aug 12 20:25:05 2016 +0200
4.3 @@ -11,7 +11,7 @@
4.4 namespace SharpDisplayManager
4.5 {
4.6 [DataContract]
4.7 - [AttributeAction(Id = "Cec.Device.PowerOn", Name = "CEC Device Power On", Description = "Turns on the specified CEC device on your HDMI bus.")]
4.8 + [AttributeObject(Id = "Cec.Device.PowerOn", Name = "CEC Device Power On", Description = "Turns on the specified CEC device on your HDMI bus.")]
4.9 public class ActionCecDevicePowerOn : ActionCecDevice
4.10 {
4.11 /// <summary>
5.1 --- a/Server/Actions/ActionCecDeviceStandby.cs Sun Jul 31 12:03:52 2016 +0200
5.2 +++ b/Server/Actions/ActionCecDeviceStandby.cs Fri Aug 12 20:25:05 2016 +0200
5.3 @@ -11,7 +11,7 @@
5.4 namespace SharpDisplayManager
5.5 {
5.6 [DataContract]
5.7 - [AttributeAction(Id = "Cec.Device.Standby", Name = "CEC Device Standby", Description = "Puts on standby the specified CEC device on your HDMI bus.")]
5.8 + [AttributeObject(Id = "Cec.Device.Standby", Name = "CEC Device Standby", Description = "Puts on standby the specified CEC device on your HDMI bus.")]
5.9 public class ActionCecDeviceStandby : ActionCecDevice
5.10 {
5.11 /// <summary>
6.1 --- a/Server/Actions/ActionCecDeviceType.cs Sun Jul 31 12:03:52 2016 +0200
6.2 +++ b/Server/Actions/ActionCecDeviceType.cs Fri Aug 12 20:25:05 2016 +0200
6.3 @@ -17,7 +17,7 @@
6.4 public abstract class ActionCecDeviceType : SharpLib.Ear.Action
6.5 {
6.6 [DataMember]
6.7 - [AttributeActionProperty
6.8 + [AttributeObjectProperty
6.9 (
6.10 Id = "CEC.DeviceType",
6.11 Name = "Device Type",
7.1 --- a/Server/Actions/ActionCecInactiveSource.cs Sun Jul 31 12:03:52 2016 +0200
7.2 +++ b/Server/Actions/ActionCecInactiveSource.cs Fri Aug 12 20:25:05 2016 +0200
7.3 @@ -10,7 +10,7 @@
7.4 namespace SharpDisplayManager
7.5 {
7.6 [DataContract]
7.7 - [AttributeAction(Id = "Cec.InactiveSource", Name = "CEC Inactive Source", Description = "Set this CEC device as inactive source.")]
7.8 + [AttributeObject(Id = "Cec.InactiveSource", Name = "CEC Inactive Source", Description = "Set this CEC device as inactive source.")]
7.9 class ActionCecInactiveSource : SharpLib.Ear.Action
7.10 {
7.11 protected override void DoExecute()
8.1 --- a/Server/Actions/ActionCecOpen.cs Sun Jul 31 12:03:52 2016 +0200
8.2 +++ b/Server/Actions/ActionCecOpen.cs Fri Aug 12 20:25:05 2016 +0200
8.3 @@ -10,7 +10,7 @@
8.4 namespace SharpDisplayManager
8.5 {
8.6 [DataContract]
8.7 - [AttributeAction(Id = "Cec.Open", Name = "CEC Open", Description = "Open CEC connection.")]
8.8 + [AttributeObject(Id = "Cec.Open", Name = "CEC Open", Description = "Open CEC connection.")]
8.9 class ActionCecOpen : SharpLib.Ear.Action
8.10 {
8.11 protected override void DoExecute()
9.1 --- a/Server/Actions/ActionCecScan.cs Sun Jul 31 12:03:52 2016 +0200
9.2 +++ b/Server/Actions/ActionCecScan.cs Fri Aug 12 20:25:05 2016 +0200
9.3 @@ -11,7 +11,7 @@
9.4 {
9.5
9.6 [DataContract]
9.7 - [AttributeAction(Id = "Cec.Scan", Name = "CEC Scan", Description = "Scan devices on your CEC HDMI network.")]
9.8 + [AttributeObject(Id = "Cec.Scan", Name = "CEC Scan", Description = "Scan devices on your CEC HDMI network.")]
9.9 class ActionCecScan : SharpLib.Ear.Action
9.10 {
9.11 protected override void DoExecute()
10.1 --- a/Server/Actions/ActionCecUserControlPressed.cs Sun Jul 31 12:03:52 2016 +0200
10.2 +++ b/Server/Actions/ActionCecUserControlPressed.cs Fri Aug 12 20:25:05 2016 +0200
10.3 @@ -14,7 +14,7 @@
10.4 /// Send a user key press event to the given CEC device.
10.5 /// </summary>
10.6 [DataContract]
10.7 - [AttributeAction(Id = "Cec.UserControlPressed", Name = "CEC User Control Pressed", Description = "Send user control code to defined CEC device.")]
10.8 + [AttributeObject(Id = "Cec.UserControlPressed", Name = "CEC User Control Pressed", Description = "Send user control code to defined CEC device.")]
10.9 public class ActionCecUserControlPressed : ActionCecDevice
10.10 {
10.11
10.12 @@ -24,7 +24,7 @@
10.13 }
10.14
10.15 [DataMember]
10.16 - [AttributeActionProperty(
10.17 + [AttributeObjectProperty(
10.18 Id = "Cec.UserControlPressed.Code",
10.19 Name = "Code",
10.20 Description = "The key code used by this action."
10.21 @@ -32,7 +32,7 @@
10.22 public CecUserControlCode Code { get; set; }
10.23
10.24 [DataMember]
10.25 - [AttributeActionProperty(
10.26 + [AttributeObjectProperty(
10.27 Id = "Cec.UserControlPressed.Wait",
10.28 Name = "Wait",
10.29 Description = "Wait for that command."
11.1 --- a/Server/Actions/ActionCecUserControlReleased.cs Sun Jul 31 12:03:52 2016 +0200
11.2 +++ b/Server/Actions/ActionCecUserControlReleased.cs Fri Aug 12 20:25:05 2016 +0200
11.3 @@ -14,7 +14,7 @@
11.4 /// Send a user key press event to the given CEC device.
11.5 /// </summary>
11.6 [DataContract]
11.7 - [AttributeAction(Id = "Cec.UserControlReleased", Name = "CEC User Control Released", Description = "Send user control release opcode to a given CEC device.")]
11.8 + [AttributeObject(Id = "Cec.UserControlReleased", Name = "CEC User Control Released", Description = "Send user control release opcode to a given CEC device.")]
11.9 public class ActionCecUserControlReleased : ActionCecDevice
11.10 {
11.11
11.12 @@ -24,7 +24,7 @@
11.13 }
11.14
11.15 [DataMember]
11.16 - [AttributeActionProperty(
11.17 + [AttributeObjectProperty(
11.18 Id = "Cec.UserControlPressed.Wait",
11.19 Name = "Wait",
11.20 Description = "Wait for that command."
12.1 --- a/Server/Actions/ActionDisplayMessage.cs Sun Jul 31 12:03:52 2016 +0200
12.2 +++ b/Server/Actions/ActionDisplayMessage.cs Fri Aug 12 20:25:05 2016 +0200
12.3 @@ -13,11 +13,11 @@
12.4
12.5
12.6 [DataContract]
12.7 - [AttributeAction(Id = "Display.Message", Name = "Display Message", Description = "Shows a message on your internal display.")]
12.8 + [AttributeObject(Id = "Display.Message", Name = "Display Message", Description = "Shows a message on your internal display.")]
12.9 class ActionDisplayMessage : SharpLib.Ear.Action
12.10 {
12.11 [DataMember]
12.12 - [AttributeActionProperty(
12.13 + [AttributeObjectProperty(
12.14 Id = "Display.Message.Duration",
12.15 Name = "Duration (ms)",
12.16 Description = "Specifies the number of milliseconds this message should be displayed.",
12.17 @@ -29,7 +29,7 @@
12.18
12.19
12.20 [DataMember]
12.21 - [AttributeActionProperty(
12.22 + [AttributeObjectProperty(
12.23 Id = "Display.Message.PrimaryText",
12.24 Name = "Primary Text",
12.25 Description = "The primary text of this message."
12.26 @@ -37,7 +37,7 @@
12.27 public string PrimaryText { get; set; } = "Your message";
12.28
12.29 [DataMember]
12.30 - [AttributeActionProperty(
12.31 + [AttributeObjectProperty(
12.32 Id = "Display.Message.SecondaryText",
12.33 Name = "Secondary Text",
12.34 Description = "The secondary text of this message."
13.1 --- a/Server/ConsumerElectronicControl.cs Sun Jul 31 12:03:52 2016 +0200
13.2 +++ b/Server/ConsumerElectronicControl.cs Fri Aug 12 20:25:05 2016 +0200
13.3 @@ -82,14 +82,14 @@
13.4 {
13.5 MonitorPowerOn = true;
13.6 //Trigger corresponding event thus executing associated actions
13.7 - ManagerEventAction.Current.GetEvent<EventMonitorPowerOn>().Trigger();
13.8 + ManagerEventAction.Current.TriggerEvent<EventMonitorPowerOn>();
13.9 }
13.10
13.11 private void OnMonitorPowerOff()
13.12 {
13.13 MonitorPowerOn = false;
13.14 //Trigger corresponding event thus executing associated actions
13.15 - ManagerEventAction.Current.GetEvent<EventMonitorPowerOff>().Trigger();
13.16 + ManagerEventAction.Current.TriggerEvent<EventMonitorPowerOff>();
13.17 }
13.18
13.19 /// <summary>
14.1 --- a/Server/FormEditAction.Designer.cs Sun Jul 31 12:03:52 2016 +0200
14.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
14.3 @@ -1,152 +0,0 @@
14.4 -namespace SharpDisplayManager
14.5 -{
14.6 - partial class FormEditAction
14.7 - {
14.8 - /// <summary>
14.9 - /// Required designer variable.
14.10 - /// </summary>
14.11 - private System.ComponentModel.IContainer components = null;
14.12 -
14.13 - /// <summary>
14.14 - /// Clean up any resources being used.
14.15 - /// </summary>
14.16 - /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
14.17 - protected override void Dispose(bool disposing)
14.18 - {
14.19 - if (disposing && (components != null))
14.20 - {
14.21 - components.Dispose();
14.22 - }
14.23 - base.Dispose(disposing);
14.24 - }
14.25 -
14.26 - #region Windows Form Designer generated code
14.27 -
14.28 - /// <summary>
14.29 - /// Required method for Designer support - do not modify
14.30 - /// the contents of this method with the code editor.
14.31 - /// </summary>
14.32 - private void InitializeComponent()
14.33 - {
14.34 - this.components = new System.ComponentModel.Container();
14.35 - this.comboBoxActionType = new System.Windows.Forms.ComboBox();
14.36 - this.labelActionType = new System.Windows.Forms.Label();
14.37 - this.buttonOk = new System.Windows.Forms.Button();
14.38 - this.buttonCancel = new System.Windows.Forms.Button();
14.39 - this.iTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
14.40 - this.toolTip = new System.Windows.Forms.ToolTip(this.components);
14.41 - this.buttonTest = new System.Windows.Forms.Button();
14.42 - this.SuspendLayout();
14.43 - //
14.44 - // comboBoxActionType
14.45 - //
14.46 - this.comboBoxActionType.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
14.47 - | System.Windows.Forms.AnchorStyles.Right)));
14.48 - this.comboBoxActionType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
14.49 - this.comboBoxActionType.FormattingEnabled = true;
14.50 - this.comboBoxActionType.Location = new System.Drawing.Point(55, 12);
14.51 - this.comboBoxActionType.Name = "comboBoxActionType";
14.52 - this.comboBoxActionType.Size = new System.Drawing.Size(272, 21);
14.53 - this.comboBoxActionType.Sorted = true;
14.54 - this.comboBoxActionType.TabIndex = 18;
14.55 - this.comboBoxActionType.SelectedIndexChanged += new System.EventHandler(this.comboBoxActionType_SelectedIndexChanged);
14.56 - //
14.57 - // labelActionType
14.58 - //
14.59 - this.labelActionType.AutoSize = true;
14.60 - this.labelActionType.Location = new System.Drawing.Point(12, 15);
14.61 - this.labelActionType.Name = "labelActionType";
14.62 - this.labelActionType.Size = new System.Drawing.Size(37, 13);
14.63 - this.labelActionType.TabIndex = 20;
14.64 - this.labelActionType.Text = "Type :";
14.65 - //
14.66 - // buttonOk
14.67 - //
14.68 - this.buttonOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
14.69 - this.buttonOk.DialogResult = System.Windows.Forms.DialogResult.OK;
14.70 - this.buttonOk.Location = new System.Drawing.Point(12, 72);
14.71 - this.buttonOk.Name = "buttonOk";
14.72 - this.buttonOk.Size = new System.Drawing.Size(75, 23);
14.73 - this.buttonOk.TabIndex = 21;
14.74 - this.buttonOk.Text = "Ok";
14.75 - this.buttonOk.UseVisualStyleBackColor = true;
14.76 - this.buttonOk.Click += new System.EventHandler(this.buttonOk_Click);
14.77 - //
14.78 - // buttonCancel
14.79 - //
14.80 - this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
14.81 - this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
14.82 - this.buttonCancel.Location = new System.Drawing.Point(93, 72);
14.83 - this.buttonCancel.Name = "buttonCancel";
14.84 - this.buttonCancel.Size = new System.Drawing.Size(75, 23);
14.85 - this.buttonCancel.TabIndex = 22;
14.86 - this.buttonCancel.Text = "Cancel";
14.87 - this.buttonCancel.UseVisualStyleBackColor = true;
14.88 - //
14.89 - // iTableLayoutPanel
14.90 - //
14.91 - this.iTableLayoutPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
14.92 - | System.Windows.Forms.AnchorStyles.Left)
14.93 - | System.Windows.Forms.AnchorStyles.Right)));
14.94 - this.iTableLayoutPanel.AutoSize = true;
14.95 - this.iTableLayoutPanel.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
14.96 - this.iTableLayoutPanel.ColumnCount = 2;
14.97 - this.iTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
14.98 - this.iTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
14.99 - this.iTableLayoutPanel.Location = new System.Drawing.Point(15, 50);
14.100 - this.iTableLayoutPanel.Name = "iTableLayoutPanel";
14.101 - this.iTableLayoutPanel.RowCount = 2;
14.102 - this.iTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
14.103 - this.iTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
14.104 - this.iTableLayoutPanel.Size = new System.Drawing.Size(312, 16);
14.105 - this.iTableLayoutPanel.TabIndex = 23;
14.106 - //
14.107 - // buttonTest
14.108 - //
14.109 - this.buttonTest.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
14.110 - this.buttonTest.Location = new System.Drawing.Point(252, 72);
14.111 - this.buttonTest.Name = "buttonTest";
14.112 - this.buttonTest.Size = new System.Drawing.Size(75, 23);
14.113 - this.buttonTest.TabIndex = 24;
14.114 - this.buttonTest.Text = "Test";
14.115 - this.buttonTest.UseVisualStyleBackColor = true;
14.116 - this.buttonTest.Click += new System.EventHandler(this.buttonTest_Click);
14.117 - //
14.118 - // FormEditAction
14.119 - //
14.120 - this.AcceptButton = this.buttonOk;
14.121 - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
14.122 - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
14.123 - this.AutoSize = true;
14.124 - this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
14.125 - this.CancelButton = this.buttonCancel;
14.126 - this.ClientSize = new System.Drawing.Size(339, 107);
14.127 - this.Controls.Add(this.buttonTest);
14.128 - this.Controls.Add(this.iTableLayoutPanel);
14.129 - this.Controls.Add(this.buttonCancel);
14.130 - this.Controls.Add(this.buttonOk);
14.131 - this.Controls.Add(this.labelActionType);
14.132 - this.Controls.Add(this.comboBoxActionType);
14.133 - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
14.134 - this.MaximizeBox = false;
14.135 - this.MinimizeBox = false;
14.136 - this.Name = "FormEditAction";
14.137 - this.Text = "Edit action";
14.138 - this.Load += new System.EventHandler(this.FormEditAction_Load);
14.139 - this.Validating += new System.ComponentModel.CancelEventHandler(this.FormEditAction_Validating);
14.140 - this.ResumeLayout(false);
14.141 - this.PerformLayout();
14.142 -
14.143 - }
14.144 -
14.145 - #endregion
14.146 -
14.147 - private System.Windows.Forms.ComboBox comboBoxActionType;
14.148 - private System.Windows.Forms.Label labelActionType;
14.149 - private System.Windows.Forms.Button buttonOk;
14.150 - private System.Windows.Forms.Button buttonCancel;
14.151 - private System.Windows.Forms.TableLayoutPanel iTableLayoutPanel;
14.152 - private System.Windows.Forms.ToolTip toolTip;
14.153 - private System.Windows.Forms.Button buttonTest;
14.154 - }
14.155 -}
14.156 \ No newline at end of file
15.1 --- a/Server/FormEditAction.cs Sun Jul 31 12:03:52 2016 +0200
15.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
15.3 @@ -1,325 +0,0 @@
15.4 -using System;
15.5 -using System.Collections.Generic;
15.6 -using System.ComponentModel;
15.7 -using System.Data;
15.8 -using System.Diagnostics;
15.9 -using System.Drawing;
15.10 -using System.Linq;
15.11 -using System.Text;
15.12 -using System.Threading.Tasks;
15.13 -using System.Windows.Forms;
15.14 -using SharpLib.Display;
15.15 -using SharpLib.Ear;
15.16 -using System.Reflection;
15.17 -
15.18 -namespace SharpDisplayManager
15.19 -{
15.20 - /// <summary>
15.21 - /// Action edit dialog form.
15.22 - /// </summary>
15.23 - public partial class FormEditAction : Form
15.24 - {
15.25 - public SharpLib.Ear.Action Action = null;
15.26 -
15.27 - public FormEditAction()
15.28 - {
15.29 - InitializeComponent();
15.30 - }
15.31 -
15.32 - /// <summary>
15.33 - ///
15.34 - /// </summary>
15.35 - /// <param name="sender"></param>
15.36 - /// <param name="e"></param>
15.37 - private void FormEditAction_Load(object sender, EventArgs e)
15.38 - {
15.39 - // Populate registered actions
15.40 - foreach (string key in ManagerEventAction.Current.ActionTypes.Keys)
15.41 - {
15.42 - ItemActionType item = new ItemActionType(ManagerEventAction.Current.ActionTypes[key]);
15.43 - comboBoxActionType.Items.Add(item);
15.44 - }
15.45 -
15.46 - if (Action == null)
15.47 - {
15.48 - // Creating new issue, select our first item
15.49 - comboBoxActionType.SelectedIndex = 0;
15.50 - }
15.51 - else
15.52 - {
15.53 - // Editing existing issue
15.54 - // Look up our item in our combobox
15.55 - foreach (ItemActionType item in comboBoxActionType.Items)
15.56 - {
15.57 - if (item.Type == Action.GetType())
15.58 - {
15.59 - comboBoxActionType.SelectedItem = item;
15.60 - }
15.61 - }
15.62 - }
15.63 - }
15.64 -
15.65 - private void buttonOk_Click(object sender, EventArgs e)
15.66 - {
15.67 - FetchPropertiesValue(Action);
15.68 - }
15.69 -
15.70 - private void FormEditAction_Validating(object sender, CancelEventArgs e)
15.71 - {
15.72 -
15.73 - }
15.74 -
15.75 - private void comboBoxActionType_SelectedIndexChanged(object sender, EventArgs e)
15.76 - {
15.77 - //Instantiate an action corresponding to our type
15.78 - Type actionType = ((ItemActionType) comboBoxActionType.SelectedItem).Type;
15.79 - //Create another type of action only if needed
15.80 - if (Action == null || Action.GetType() != actionType)
15.81 - {
15.82 - Action = (SharpLib.Ear.Action)Activator.CreateInstance(actionType);
15.83 - }
15.84 -
15.85 - //Create input fields
15.86 - UpdateTableLayoutPanel(Action);
15.87 - }
15.88 -
15.89 -
15.90 - /// <summary>
15.91 - /// Get properties values from our generated input fields
15.92 - /// </summary>
15.93 - private void FetchPropertiesValue(SharpLib.Ear.Action aAction)
15.94 - {
15.95 - int ctrlIndex = 0;
15.96 - foreach (PropertyInfo pi in aAction.GetType().GetProperties())
15.97 - {
15.98 - AttributeActionProperty[] attributes =
15.99 - ((AttributeActionProperty[]) pi.GetCustomAttributes(typeof(AttributeActionProperty), true));
15.100 - if (attributes.Length != 1)
15.101 - {
15.102 - continue;
15.103 - }
15.104 -
15.105 - AttributeActionProperty attribute = attributes[0];
15.106 -
15.107 - if (!IsPropertyTypeSupported(pi))
15.108 - {
15.109 - continue;
15.110 - }
15.111 -
15.112 - GetPropertyValueFromControl(iTableLayoutPanel.Controls[ctrlIndex+1], pi, aAction); //+1 otherwise we get the label
15.113 -
15.114 - ctrlIndex+=2; //Jump over the label too
15.115 - }
15.116 - }
15.117 -
15.118 - /// <summary>
15.119 - /// Extend this function to support reading new types of properties.
15.120 - /// </summary>
15.121 - /// <param name="aAction"></param>
15.122 - private void GetPropertyValueFromControl(Control aControl, PropertyInfo aInfo, SharpLib.Ear.Action aAction)
15.123 - {
15.124 - if (aInfo.PropertyType == typeof(int))
15.125 - {
15.126 - NumericUpDown ctrl=(NumericUpDown)aControl;
15.127 - aInfo.SetValue(aAction,(int)ctrl.Value);
15.128 - }
15.129 - else if (aInfo.PropertyType.IsEnum)
15.130 - {
15.131 - // Instantiate our enum
15.132 - object enumValue= Activator.CreateInstance(aInfo.PropertyType);
15.133 - // Parse our enum from combo box
15.134 - enumValue = Enum.Parse(aInfo.PropertyType,((ComboBox)aControl).SelectedItem.ToString());
15.135 - //enumValue = ((ComboBox)aControl).SelectedValue;
15.136 - // Set enum value
15.137 - aInfo.SetValue(aAction, enumValue);
15.138 - }
15.139 - else if (aInfo.PropertyType == typeof(bool))
15.140 - {
15.141 - CheckBox ctrl = (CheckBox)aControl;
15.142 - aInfo.SetValue(aAction, ctrl.Checked);
15.143 - }
15.144 - else if (aInfo.PropertyType == typeof(string))
15.145 - {
15.146 - TextBox ctrl = (TextBox)aControl;
15.147 - aInfo.SetValue(aAction, ctrl.Text);
15.148 - }
15.149 - //TODO: add support for other types here
15.150 - }
15.151 -
15.152 - /// <summary>
15.153 - ///
15.154 - /// </summary>
15.155 - /// <param name="aInfo"></param>
15.156 - /// <param name="action"></param>
15.157 - private Control CreateControlForProperty(PropertyInfo aInfo, AttributeActionProperty aAttribute, SharpLib.Ear.Action aAction)
15.158 - {
15.159 - if (aInfo.PropertyType == typeof(int))
15.160 - {
15.161 - //Integer properties are using numeric editor
15.162 - NumericUpDown ctrl = new NumericUpDown();
15.163 - ctrl.AutoSize = true;
15.164 - ctrl.Minimum = Int32.Parse(aAttribute.Minimum);
15.165 - ctrl.Maximum = Int32.Parse(aAttribute.Maximum);
15.166 - ctrl.Increment = Int32.Parse(aAttribute.Increment);
15.167 - ctrl.Value = (int)aInfo.GetValue(aAction);
15.168 - return ctrl;
15.169 - }
15.170 - else if (aInfo.PropertyType.IsEnum)
15.171 - {
15.172 - //Enum properties are using combo box
15.173 - ComboBox ctrl = new ComboBox();
15.174 - ctrl.AutoSize = true;
15.175 - ctrl.Sorted = true;
15.176 - ctrl.DropDownStyle = ComboBoxStyle.DropDownList;
15.177 - //Data source is fine but it gives us duplicate entries for duplicated enum values
15.178 - //ctrl.DataSource = Enum.GetValues(aInfo.PropertyType);
15.179 -
15.180 - //Therefore we need to explicitly create our items
15.181 - Size cbSize = new Size(0,0);
15.182 - foreach (string name in aInfo.PropertyType.GetEnumNames())
15.183 - {
15.184 - ctrl.Items.Add(name.ToString());
15.185 - Graphics g = this.CreateGraphics();
15.186 - //Since combobox autosize would not work we need to get measure text ourselves
15.187 - SizeF size=g.MeasureString(name.ToString(), ctrl.Font);
15.188 - cbSize.Width = Math.Max(cbSize.Width,(int)size.Width);
15.189 - cbSize.Height = Math.Max(cbSize.Height, (int)size.Height);
15.190 - }
15.191 -
15.192 - //Make sure our combobox is large enough
15.193 - ctrl.MinimumSize = cbSize;
15.194 -
15.195 - // Instantiate our enum
15.196 - object enumValue = Activator.CreateInstance(aInfo.PropertyType);
15.197 - enumValue = aInfo.GetValue(aAction);
15.198 - //Set the current item
15.199 - ctrl.SelectedItem = enumValue.ToString();
15.200 -
15.201 - return ctrl;
15.202 - }
15.203 - else if (aInfo.PropertyType == typeof(bool))
15.204 - {
15.205 - CheckBox ctrl = new CheckBox();
15.206 - ctrl.AutoSize = true;
15.207 - ctrl.Text = aAttribute.Description;
15.208 - ctrl.Checked = (bool)aInfo.GetValue(aAction);
15.209 - return ctrl;
15.210 - }
15.211 - else if (aInfo.PropertyType == typeof(string))
15.212 - {
15.213 - TextBox ctrl = new TextBox();
15.214 - ctrl.AutoSize = true;
15.215 - ctrl.Text = (string)aInfo.GetValue(aAction);
15.216 - return ctrl;
15.217 - }
15.218 - //TODO: add support for other control type here
15.219 -
15.220 - return null;
15.221 - }
15.222 -
15.223 - /// <summary>
15.224 - /// Don't forget to extend that one and adding types
15.225 - /// </summary>
15.226 - /// <returns></returns>
15.227 - private bool IsPropertyTypeSupported(PropertyInfo aInfo)
15.228 - {
15.229 - if (aInfo.PropertyType == typeof(int))
15.230 - {
15.231 - return true;
15.232 - }
15.233 - else if (aInfo.PropertyType.IsEnum)
15.234 - {
15.235 - return true;
15.236 - }
15.237 - else if (aInfo.PropertyType == typeof(bool))
15.238 - {
15.239 - return true;
15.240 - }
15.241 - else if (aInfo.PropertyType == typeof(string))
15.242 - {
15.243 - return true;
15.244 - }
15.245 - //TODO: add support for other type here
15.246 -
15.247 - return false;
15.248 - }
15.249 -
15.250 - /// <summary>
15.251 - /// Update our table layout.
15.252 - /// Will instantiated every field control as defined by our action.
15.253 - /// Fields must be specified by rows from the left.
15.254 - /// </summary>
15.255 - /// <param name="aLayout"></param>
15.256 - private void UpdateTableLayoutPanel(SharpLib.Ear.Action aAction)
15.257 - {
15.258 - toolTip.RemoveAll();
15.259 - //Debug.Print("UpdateTableLayoutPanel")
15.260 - //First clean our current panel
15.261 - iTableLayoutPanel.Controls.Clear();
15.262 - iTableLayoutPanel.RowStyles.Clear();
15.263 - iTableLayoutPanel.ColumnStyles.Clear();
15.264 - iTableLayoutPanel.RowCount = 0;
15.265 -
15.266 - //We always want two columns: one for label and one for the field
15.267 - iTableLayoutPanel.ColumnCount = 2;
15.268 - iTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
15.269 - iTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
15.270 -
15.271 -
15.272 - if (aAction == null)
15.273 - {
15.274 - //Just drop it
15.275 - return;
15.276 - }
15.277 -
15.278 - //IEnumerable<PropertyInfo> properties = aAction.GetType().GetProperties().Where(
15.279 - // prop => Attribute.IsDefined(prop, typeof(AttributeActionProperty)));
15.280 -
15.281 -
15.282 - foreach (PropertyInfo pi in aAction.GetType().GetProperties())
15.283 - {
15.284 - AttributeActionProperty[] attributes = ((AttributeActionProperty[])pi.GetCustomAttributes(typeof(AttributeActionProperty), true));
15.285 - if (attributes.Length != 1)
15.286 - {
15.287 - continue;
15.288 - }
15.289 -
15.290 - AttributeActionProperty attribute = attributes[0];
15.291 -
15.292 - //Before anything we need to check if that kind of property is supported by our UI
15.293 - //Create the editor
15.294 - Control ctrl = CreateControlForProperty(pi, attribute, aAction);
15.295 - if (ctrl == null)
15.296 - {
15.297 - //Property type not supported
15.298 - continue;
15.299 - }
15.300 -
15.301 - //Add a new row
15.302 - iTableLayoutPanel.RowCount++;
15.303 - iTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
15.304 - //Create the label
15.305 - Label label = new Label();
15.306 - label.AutoSize = true;
15.307 - label.Dock = DockStyle.Fill;
15.308 - label.TextAlign = ContentAlignment.MiddleCenter;
15.309 - label.Text = attribute.Name;
15.310 - toolTip.SetToolTip(label, attribute.Description);
15.311 - iTableLayoutPanel.Controls.Add(label, 0, iTableLayoutPanel.RowCount-1);
15.312 -
15.313 - //Add our editor to our form
15.314 - iTableLayoutPanel.Controls.Add(ctrl, 1, iTableLayoutPanel.RowCount - 1);
15.315 - //Add tooltip to editor too
15.316 - toolTip.SetToolTip(ctrl, attribute.Description);
15.317 -
15.318 - }
15.319 -
15.320 - }
15.321 -
15.322 - private void buttonTest_Click(object sender, EventArgs e)
15.323 - {
15.324 - FetchPropertiesValue(Action);
15.325 - Action.Execute();
15.326 - }
15.327 - }
15.328 -}
16.1 --- a/Server/FormEditAction.resx Sun Jul 31 12:03:52 2016 +0200
16.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
16.3 @@ -1,123 +0,0 @@
16.4 -<?xml version="1.0" encoding="utf-8"?>
16.5 -<root>
16.6 - <!--
16.7 - Microsoft ResX Schema
16.8 -
16.9 - Version 2.0
16.10 -
16.11 - The primary goals of this format is to allow a simple XML format
16.12 - that is mostly human readable. The generation and parsing of the
16.13 - various data types are done through the TypeConverter classes
16.14 - associated with the data types.
16.15 -
16.16 - Example:
16.17 -
16.18 - ... ado.net/XML headers & schema ...
16.19 - <resheader name="resmimetype">text/microsoft-resx</resheader>
16.20 - <resheader name="version">2.0</resheader>
16.21 - <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
16.22 - <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
16.23 - <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
16.24 - <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
16.25 - <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
16.26 - <value>[base64 mime encoded serialized .NET Framework object]</value>
16.27 - </data>
16.28 - <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
16.29 - <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
16.30 - <comment>This is a comment</comment>
16.31 - </data>
16.32 -
16.33 - There are any number of "resheader" rows that contain simple
16.34 - name/value pairs.
16.35 -
16.36 - Each data row contains a name, and value. The row also contains a
16.37 - type or mimetype. Type corresponds to a .NET class that support
16.38 - text/value conversion through the TypeConverter architecture.
16.39 - Classes that don't support this are serialized and stored with the
16.40 - mimetype set.
16.41 -
16.42 - The mimetype is used for serialized objects, and tells the
16.43 - ResXResourceReader how to depersist the object. This is currently not
16.44 - extensible. For a given mimetype the value must be set accordingly:
16.45 -
16.46 - Note - application/x-microsoft.net.object.binary.base64 is the format
16.47 - that the ResXResourceWriter will generate, however the reader can
16.48 - read any of the formats listed below.
16.49 -
16.50 - mimetype: application/x-microsoft.net.object.binary.base64
16.51 - value : The object must be serialized with
16.52 - : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
16.53 - : and then encoded with base64 encoding.
16.54 -
16.55 - mimetype: application/x-microsoft.net.object.soap.base64
16.56 - value : The object must be serialized with
16.57 - : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
16.58 - : and then encoded with base64 encoding.
16.59 -
16.60 - mimetype: application/x-microsoft.net.object.bytearray.base64
16.61 - value : The object must be serialized into a byte array
16.62 - : using a System.ComponentModel.TypeConverter
16.63 - : and then encoded with base64 encoding.
16.64 - -->
16.65 - <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
16.66 - <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
16.67 - <xsd:element name="root" msdata:IsDataSet="true">
16.68 - <xsd:complexType>
16.69 - <xsd:choice maxOccurs="unbounded">
16.70 - <xsd:element name="metadata">
16.71 - <xsd:complexType>
16.72 - <xsd:sequence>
16.73 - <xsd:element name="value" type="xsd:string" minOccurs="0" />
16.74 - </xsd:sequence>
16.75 - <xsd:attribute name="name" use="required" type="xsd:string" />
16.76 - <xsd:attribute name="type" type="xsd:string" />
16.77 - <xsd:attribute name="mimetype" type="xsd:string" />
16.78 - <xsd:attribute ref="xml:space" />
16.79 - </xsd:complexType>
16.80 - </xsd:element>
16.81 - <xsd:element name="assembly">
16.82 - <xsd:complexType>
16.83 - <xsd:attribute name="alias" type="xsd:string" />
16.84 - <xsd:attribute name="name" type="xsd:string" />
16.85 - </xsd:complexType>
16.86 - </xsd:element>
16.87 - <xsd:element name="data">
16.88 - <xsd:complexType>
16.89 - <xsd:sequence>
16.90 - <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
16.91 - <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
16.92 - </xsd:sequence>
16.93 - <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
16.94 - <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
16.95 - <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
16.96 - <xsd:attribute ref="xml:space" />
16.97 - </xsd:complexType>
16.98 - </xsd:element>
16.99 - <xsd:element name="resheader">
16.100 - <xsd:complexType>
16.101 - <xsd:sequence>
16.102 - <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
16.103 - </xsd:sequence>
16.104 - <xsd:attribute name="name" type="xsd:string" use="required" />
16.105 - </xsd:complexType>
16.106 - </xsd:element>
16.107 - </xsd:choice>
16.108 - </xsd:complexType>
16.109 - </xsd:element>
16.110 - </xsd:schema>
16.111 - <resheader name="resmimetype">
16.112 - <value>text/microsoft-resx</value>
16.113 - </resheader>
16.114 - <resheader name="version">
16.115 - <value>2.0</value>
16.116 - </resheader>
16.117 - <resheader name="reader">
16.118 - <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
16.119 - </resheader>
16.120 - <resheader name="writer">
16.121 - <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
16.122 - </resheader>
16.123 - <metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
16.124 - <value>17, 17</value>
16.125 - </metadata>
16.126 -</root>
16.127 \ No newline at end of file
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/Server/FormEditObject.Designer.cs Fri Aug 12 20:25:05 2016 +0200
17.3 @@ -0,0 +1,152 @@
17.4 +namespace SharpDisplayManager
17.5 +{
17.6 + partial class FormEditObject<T>
17.7 + {
17.8 + /// <summary>
17.9 + /// Required designer variable.
17.10 + /// </summary>
17.11 + private System.ComponentModel.IContainer components = null;
17.12 +
17.13 + /// <summary>
17.14 + /// Clean up any resources being used.
17.15 + /// </summary>
17.16 + /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
17.17 + protected override void Dispose(bool disposing)
17.18 + {
17.19 + if (disposing && (components != null))
17.20 + {
17.21 + components.Dispose();
17.22 + }
17.23 + base.Dispose(disposing);
17.24 + }
17.25 +
17.26 + #region Windows Form Designer generated code
17.27 +
17.28 + /// <summary>
17.29 + /// Required method for Designer support - do not modify
17.30 + /// the contents of this method with the code editor.
17.31 + /// </summary>
17.32 + private void InitializeComponent()
17.33 + {
17.34 + this.components = new System.ComponentModel.Container();
17.35 + this.comboBoxActionType = new System.Windows.Forms.ComboBox();
17.36 + this.labelActionType = new System.Windows.Forms.Label();
17.37 + this.buttonOk = new System.Windows.Forms.Button();
17.38 + this.buttonCancel = new System.Windows.Forms.Button();
17.39 + this.iTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
17.40 + this.toolTip = new System.Windows.Forms.ToolTip(this.components);
17.41 + this.buttonTest = new System.Windows.Forms.Button();
17.42 + this.SuspendLayout();
17.43 + //
17.44 + // comboBoxActionType
17.45 + //
17.46 + this.comboBoxActionType.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
17.47 + | System.Windows.Forms.AnchorStyles.Right)));
17.48 + this.comboBoxActionType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
17.49 + this.comboBoxActionType.FormattingEnabled = true;
17.50 + this.comboBoxActionType.Location = new System.Drawing.Point(55, 12);
17.51 + this.comboBoxActionType.Name = "comboBoxActionType";
17.52 + this.comboBoxActionType.Size = new System.Drawing.Size(272, 21);
17.53 + this.comboBoxActionType.Sorted = true;
17.54 + this.comboBoxActionType.TabIndex = 18;
17.55 + this.comboBoxActionType.SelectedIndexChanged += new System.EventHandler(this.comboBoxActionType_SelectedIndexChanged);
17.56 + //
17.57 + // labelActionType
17.58 + //
17.59 + this.labelActionType.AutoSize = true;
17.60 + this.labelActionType.Location = new System.Drawing.Point(12, 15);
17.61 + this.labelActionType.Name = "labelActionType";
17.62 + this.labelActionType.Size = new System.Drawing.Size(37, 13);
17.63 + this.labelActionType.TabIndex = 20;
17.64 + this.labelActionType.Text = "Type :";
17.65 + //
17.66 + // buttonOk
17.67 + //
17.68 + this.buttonOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
17.69 + this.buttonOk.DialogResult = System.Windows.Forms.DialogResult.OK;
17.70 + this.buttonOk.Location = new System.Drawing.Point(12, 72);
17.71 + this.buttonOk.Name = "buttonOk";
17.72 + this.buttonOk.Size = new System.Drawing.Size(75, 23);
17.73 + this.buttonOk.TabIndex = 21;
17.74 + this.buttonOk.Text = "Ok";
17.75 + this.buttonOk.UseVisualStyleBackColor = true;
17.76 + this.buttonOk.Click += new System.EventHandler(this.buttonOk_Click);
17.77 + //
17.78 + // buttonCancel
17.79 + //
17.80 + this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
17.81 + this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
17.82 + this.buttonCancel.Location = new System.Drawing.Point(93, 72);
17.83 + this.buttonCancel.Name = "buttonCancel";
17.84 + this.buttonCancel.Size = new System.Drawing.Size(75, 23);
17.85 + this.buttonCancel.TabIndex = 22;
17.86 + this.buttonCancel.Text = "Cancel";
17.87 + this.buttonCancel.UseVisualStyleBackColor = true;
17.88 + //
17.89 + // iTableLayoutPanel
17.90 + //
17.91 + this.iTableLayoutPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
17.92 + | System.Windows.Forms.AnchorStyles.Left)
17.93 + | System.Windows.Forms.AnchorStyles.Right)));
17.94 + this.iTableLayoutPanel.AutoSize = true;
17.95 + this.iTableLayoutPanel.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
17.96 + this.iTableLayoutPanel.ColumnCount = 2;
17.97 + this.iTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
17.98 + this.iTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
17.99 + this.iTableLayoutPanel.Location = new System.Drawing.Point(15, 50);
17.100 + this.iTableLayoutPanel.Name = "iTableLayoutPanel";
17.101 + this.iTableLayoutPanel.RowCount = 2;
17.102 + this.iTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
17.103 + this.iTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
17.104 + this.iTableLayoutPanel.Size = new System.Drawing.Size(312, 16);
17.105 + this.iTableLayoutPanel.TabIndex = 23;
17.106 + //
17.107 + // buttonTest
17.108 + //
17.109 + this.buttonTest.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
17.110 + this.buttonTest.Location = new System.Drawing.Point(252, 72);
17.111 + this.buttonTest.Name = "buttonTest";
17.112 + this.buttonTest.Size = new System.Drawing.Size(75, 23);
17.113 + this.buttonTest.TabIndex = 24;
17.114 + this.buttonTest.Text = "Test";
17.115 + this.buttonTest.UseVisualStyleBackColor = true;
17.116 + this.buttonTest.Click += new System.EventHandler(this.buttonTest_Click);
17.117 + //
17.118 + // FormEditAction
17.119 + //
17.120 + this.AcceptButton = this.buttonOk;
17.121 + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
17.122 + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
17.123 + this.AutoSize = true;
17.124 + this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
17.125 + this.CancelButton = this.buttonCancel;
17.126 + this.ClientSize = new System.Drawing.Size(339, 107);
17.127 + this.Controls.Add(this.buttonTest);
17.128 + this.Controls.Add(this.iTableLayoutPanel);
17.129 + this.Controls.Add(this.buttonCancel);
17.130 + this.Controls.Add(this.buttonOk);
17.131 + this.Controls.Add(this.labelActionType);
17.132 + this.Controls.Add(this.comboBoxActionType);
17.133 + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
17.134 + this.MaximizeBox = false;
17.135 + this.MinimizeBox = false;
17.136 + this.Name = "FormEditAction";
17.137 + this.Text = "Edit action";
17.138 + this.Load += new System.EventHandler(this.FormEditAction_Load);
17.139 + this.Validating += new System.ComponentModel.CancelEventHandler(this.FormEditAction_Validating);
17.140 + this.ResumeLayout(false);
17.141 + this.PerformLayout();
17.142 +
17.143 + }
17.144 +
17.145 + #endregion
17.146 +
17.147 + private System.Windows.Forms.ComboBox comboBoxActionType;
17.148 + private System.Windows.Forms.Label labelActionType;
17.149 + private System.Windows.Forms.Button buttonOk;
17.150 + private System.Windows.Forms.Button buttonCancel;
17.151 + private System.Windows.Forms.TableLayoutPanel iTableLayoutPanel;
17.152 + private System.Windows.Forms.ToolTip toolTip;
17.153 + private System.Windows.Forms.Button buttonTest;
17.154 + }
17.155 +}
17.156 \ No newline at end of file
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/Server/FormEditObject.cs Fri Aug 12 20:25:05 2016 +0200
18.3 @@ -0,0 +1,335 @@
18.4 +using System;
18.5 +using System.Collections.Generic;
18.6 +using System.ComponentModel;
18.7 +using System.Data;
18.8 +using System.Diagnostics;
18.9 +using System.Drawing;
18.10 +using System.Linq;
18.11 +using System.Text;
18.12 +using System.Threading.Tasks;
18.13 +using System.Windows.Forms;
18.14 +using SharpLib.Display;
18.15 +using SharpLib.Ear;
18.16 +using System.Reflection;
18.17 +using Microsoft.VisualBasic.CompilerServices;
18.18 +using SharpLib.Utils;
18.19 +
18.20 +namespace SharpDisplayManager
18.21 +{
18.22 + /// <summary>
18.23 + /// Object edit dialog form.
18.24 + /// </summary>
18.25 + public partial class FormEditObject<T> : Form where T : class
18.26 + {
18.27 + public T Object = null;
18.28 +
18.29 + public FormEditObject()
18.30 + {
18.31 + InitializeComponent();
18.32 + }
18.33 +
18.34 + /// <summary>
18.35 + ///
18.36 + /// </summary>
18.37 + /// <param name="sender"></param>
18.38 + /// <param name="e"></param>
18.39 + private void FormEditAction_Load(object sender, EventArgs e)
18.40 + {
18.41 + // Populate registered actions
18.42 + IEnumerable < Type > types = Reflection.GetConcreteClassesDerivedFrom<T>();
18.43 + foreach (Type type in types)
18.44 + {
18.45 + ItemObjectType item = new ItemObjectType(type);
18.46 + comboBoxActionType.Items.Add(item);
18.47 + }
18.48 +
18.49 + if (Object == null)
18.50 + {
18.51 + // Creating new issue, select our first item
18.52 + comboBoxActionType.SelectedIndex = 0;
18.53 + }
18.54 + else
18.55 + {
18.56 + // Editing existing object
18.57 + // Look up our item in our combobox
18.58 + foreach (ItemObjectType item in comboBoxActionType.Items)
18.59 + {
18.60 + if (item.Type == Object.GetType())
18.61 + {
18.62 + comboBoxActionType.SelectedItem = item;
18.63 + }
18.64 + }
18.65 + }
18.66 + }
18.67 +
18.68 + private void buttonOk_Click(object sender, EventArgs e)
18.69 + {
18.70 + FetchPropertiesValue(Object);
18.71 + }
18.72 +
18.73 + private void FormEditAction_Validating(object sender, CancelEventArgs e)
18.74 + {
18.75 +
18.76 + }
18.77 +
18.78 + private void comboBoxActionType_SelectedIndexChanged(object sender, EventArgs e)
18.79 + {
18.80 + //Instantiate an action corresponding to our type
18.81 + Type actionType = ((ItemObjectType) comboBoxActionType.SelectedItem).Type;
18.82 + //Create another type of action only if needed
18.83 + if (Object == null || Object.GetType() != actionType)
18.84 + {
18.85 + Object = (T)Activator.CreateInstance(actionType);
18.86 + }
18.87 +
18.88 + //Create input fields
18.89 + UpdateTableLayoutPanel(Object);
18.90 + }
18.91 +
18.92 +
18.93 + /// <summary>
18.94 + /// Get properties values from our generated input fields
18.95 + /// </summary>
18.96 + private void FetchPropertiesValue(T aAction)
18.97 + {
18.98 + int ctrlIndex = 0;
18.99 + foreach (PropertyInfo pi in aAction.GetType().GetProperties())
18.100 + {
18.101 + AttributeObjectProperty[] attributes =
18.102 + ((AttributeObjectProperty[]) pi.GetCustomAttributes(typeof(AttributeObjectProperty), true));
18.103 + if (attributes.Length != 1)
18.104 + {
18.105 + continue;
18.106 + }
18.107 +
18.108 + AttributeObjectProperty attribute = attributes[0];
18.109 +
18.110 + if (!IsPropertyTypeSupported(pi))
18.111 + {
18.112 + continue;
18.113 + }
18.114 +
18.115 + GetPropertyValueFromControl(iTableLayoutPanel.Controls[ctrlIndex+1], pi, aAction); //+1 otherwise we get the label
18.116 +
18.117 + ctrlIndex+=2; //Jump over the label too
18.118 + }
18.119 + }
18.120 +
18.121 + /// <summary>
18.122 + /// Extend this function to support reading new types of properties.
18.123 + /// </summary>
18.124 + /// <param name="aAction"></param>
18.125 + private void GetPropertyValueFromControl(Control aControl, PropertyInfo aInfo, T aAction)
18.126 + {
18.127 + if (aInfo.PropertyType == typeof(int))
18.128 + {
18.129 + NumericUpDown ctrl=(NumericUpDown)aControl;
18.130 + aInfo.SetValue(aAction,(int)ctrl.Value);
18.131 + }
18.132 + else if (aInfo.PropertyType.IsEnum)
18.133 + {
18.134 + // Instantiate our enum
18.135 + object enumValue= Activator.CreateInstance(aInfo.PropertyType);
18.136 + // Parse our enum from combo box
18.137 + enumValue = Enum.Parse(aInfo.PropertyType,((ComboBox)aControl).SelectedItem.ToString());
18.138 + //enumValue = ((ComboBox)aControl).SelectedValue;
18.139 + // Set enum value
18.140 + aInfo.SetValue(aAction, enumValue);
18.141 + }
18.142 + else if (aInfo.PropertyType == typeof(bool))
18.143 + {
18.144 + CheckBox ctrl = (CheckBox)aControl;
18.145 + aInfo.SetValue(aAction, ctrl.Checked);
18.146 + }
18.147 + else if (aInfo.PropertyType == typeof(string))
18.148 + {
18.149 + TextBox ctrl = (TextBox)aControl;
18.150 + aInfo.SetValue(aAction, ctrl.Text);
18.151 + }
18.152 + //TODO: add support for other types here
18.153 + }
18.154 +
18.155 + /// <summary>
18.156 + ///
18.157 + /// </summary>
18.158 + /// <param name="aInfo"></param>
18.159 + /// <param name="action"></param>
18.160 + private Control CreateControlForProperty(PropertyInfo aInfo, AttributeObjectProperty aAttribute, T aAction)
18.161 + {
18.162 + if (aInfo.PropertyType == typeof(int))
18.163 + {
18.164 + //Integer properties are using numeric editor
18.165 + NumericUpDown ctrl = new NumericUpDown();
18.166 + ctrl.AutoSize = true;
18.167 + ctrl.Minimum = Int32.Parse(aAttribute.Minimum);
18.168 + ctrl.Maximum = Int32.Parse(aAttribute.Maximum);
18.169 + ctrl.Increment = Int32.Parse(aAttribute.Increment);
18.170 + ctrl.Value = (int)aInfo.GetValue(aAction);
18.171 + return ctrl;
18.172 + }
18.173 + else if (aInfo.PropertyType.IsEnum)
18.174 + {
18.175 + //Enum properties are using combo box
18.176 + ComboBox ctrl = new ComboBox();
18.177 + ctrl.AutoSize = true;
18.178 + ctrl.Sorted = true;
18.179 + ctrl.DropDownStyle = ComboBoxStyle.DropDownList;
18.180 + //Data source is fine but it gives us duplicate entries for duplicated enum values
18.181 + //ctrl.DataSource = Enum.GetValues(aInfo.PropertyType);
18.182 +
18.183 + //Therefore we need to explicitly create our items
18.184 + Size cbSize = new Size(0,0);
18.185 + foreach (string name in aInfo.PropertyType.GetEnumNames())
18.186 + {
18.187 + ctrl.Items.Add(name.ToString());
18.188 + Graphics g = this.CreateGraphics();
18.189 + //Since combobox autosize would not work we need to get measure text ourselves
18.190 + SizeF size=g.MeasureString(name.ToString(), ctrl.Font);
18.191 + cbSize.Width = Math.Max(cbSize.Width,(int)size.Width);
18.192 + cbSize.Height = Math.Max(cbSize.Height, (int)size.Height);
18.193 + }
18.194 +
18.195 + //Make sure our combobox is large enough
18.196 + ctrl.MinimumSize = cbSize;
18.197 +
18.198 + // Instantiate our enum
18.199 + object enumValue = Activator.CreateInstance(aInfo.PropertyType);
18.200 + enumValue = aInfo.GetValue(aAction);
18.201 + //Set the current item
18.202 + ctrl.SelectedItem = enumValue.ToString();
18.203 +
18.204 + return ctrl;
18.205 + }
18.206 + else if (aInfo.PropertyType == typeof(bool))
18.207 + {
18.208 + CheckBox ctrl = new CheckBox();
18.209 + ctrl.AutoSize = true;
18.210 + ctrl.Text = aAttribute.Description;
18.211 + ctrl.Checked = (bool)aInfo.GetValue(aAction);
18.212 + return ctrl;
18.213 + }
18.214 + else if (aInfo.PropertyType == typeof(string))
18.215 + {
18.216 + TextBox ctrl = new TextBox();
18.217 + ctrl.AutoSize = true;
18.218 + ctrl.Text = (string)aInfo.GetValue(aAction);
18.219 + return ctrl;
18.220 + }
18.221 + //TODO: add support for other control type here
18.222 +
18.223 + return null;
18.224 + }
18.225 +
18.226 + /// <summary>
18.227 + /// Don't forget to extend that one and adding types
18.228 + /// </summary>
18.229 + /// <returns></returns>
18.230 + private bool IsPropertyTypeSupported(PropertyInfo aInfo)
18.231 + {
18.232 + if (aInfo.PropertyType == typeof(int))
18.233 + {
18.234 + return true;
18.235 + }
18.236 + else if (aInfo.PropertyType.IsEnum)
18.237 + {
18.238 + return true;
18.239 + }
18.240 + else if (aInfo.PropertyType == typeof(bool))
18.241 + {
18.242 + return true;
18.243 + }
18.244 + else if (aInfo.PropertyType == typeof(string))
18.245 + {
18.246 + return true;
18.247 + }
18.248 + //TODO: add support for other type here
18.249 +
18.250 + return false;
18.251 + }
18.252 +
18.253 + /// <summary>
18.254 + /// Update our table layout.
18.255 + /// Will instantiated every field control as defined by our action.
18.256 + /// Fields must be specified by rows from the left.
18.257 + /// </summary>
18.258 + /// <param name="aLayout"></param>
18.259 + private void UpdateTableLayoutPanel(T aAction)
18.260 + {
18.261 + toolTip.RemoveAll();
18.262 + //Debug.Print("UpdateTableLayoutPanel")
18.263 + //First clean our current panel
18.264 + iTableLayoutPanel.Controls.Clear();
18.265 + iTableLayoutPanel.RowStyles.Clear();
18.266 + iTableLayoutPanel.ColumnStyles.Clear();
18.267 + iTableLayoutPanel.RowCount = 0;
18.268 +
18.269 + //We always want two columns: one for label and one for the field
18.270 + iTableLayoutPanel.ColumnCount = 2;
18.271 + iTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
18.272 + iTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
18.273 +
18.274 +
18.275 + if (aAction == null)
18.276 + {
18.277 + //Just drop it
18.278 + return;
18.279 + }
18.280 +
18.281 + //IEnumerable<PropertyInfo> properties = aAction.GetType().GetProperties().Where(
18.282 + // prop => Attribute.IsDefined(prop, typeof(AttributeObjectProperty)));
18.283 +
18.284 +
18.285 + foreach (PropertyInfo pi in aAction.GetType().GetProperties())
18.286 + {
18.287 + AttributeObjectProperty[] attributes = ((AttributeObjectProperty[])pi.GetCustomAttributes(typeof(AttributeObjectProperty), true));
18.288 + if (attributes.Length != 1)
18.289 + {
18.290 + continue;
18.291 + }
18.292 +
18.293 + AttributeObjectProperty attribute = attributes[0];
18.294 +
18.295 + //Before anything we need to check if that kind of property is supported by our UI
18.296 + //Create the editor
18.297 + Control ctrl = CreateControlForProperty(pi, attribute, aAction);
18.298 + if (ctrl == null)
18.299 + {
18.300 + //Property type not supported
18.301 + continue;
18.302 + }
18.303 +
18.304 + //Add a new row
18.305 + iTableLayoutPanel.RowCount++;
18.306 + iTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
18.307 + //Create the label
18.308 + Label label = new Label();
18.309 + label.AutoSize = true;
18.310 + label.Dock = DockStyle.Fill;
18.311 + label.TextAlign = ContentAlignment.MiddleCenter;
18.312 + label.Text = attribute.Name;
18.313 + toolTip.SetToolTip(label, attribute.Description);
18.314 + iTableLayoutPanel.Controls.Add(label, 0, iTableLayoutPanel.RowCount-1);
18.315 +
18.316 + //Add our editor to our form
18.317 + iTableLayoutPanel.Controls.Add(ctrl, 1, iTableLayoutPanel.RowCount - 1);
18.318 + //Add tooltip to editor too
18.319 + toolTip.SetToolTip(ctrl, attribute.Description);
18.320 +
18.321 + }
18.322 +
18.323 + }
18.324 +
18.325 + private void buttonTest_Click(object sender, EventArgs e)
18.326 + {
18.327 + FetchPropertiesValue(Object);
18.328 +
18.329 + //If our object has a test method with no parameters just run it then
18.330 + MethodInfo info = Object.GetType().GetMethod("Test");
18.331 + if ( info != null && info.GetParameters().Length==0)
18.332 + {
18.333 + info.Invoke(Object,null);
18.334 + }
18.335 +
18.336 + }
18.337 + }
18.338 +}
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/Server/FormEditObject.resx Fri Aug 12 20:25:05 2016 +0200
19.3 @@ -0,0 +1,123 @@
19.4 +<?xml version="1.0" encoding="utf-8"?>
19.5 +<root>
19.6 + <!--
19.7 + Microsoft ResX Schema
19.8 +
19.9 + Version 2.0
19.10 +
19.11 + The primary goals of this format is to allow a simple XML format
19.12 + that is mostly human readable. The generation and parsing of the
19.13 + various data types are done through the TypeConverter classes
19.14 + associated with the data types.
19.15 +
19.16 + Example:
19.17 +
19.18 + ... ado.net/XML headers & schema ...
19.19 + <resheader name="resmimetype">text/microsoft-resx</resheader>
19.20 + <resheader name="version">2.0</resheader>
19.21 + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
19.22 + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
19.23 + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
19.24 + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
19.25 + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
19.26 + <value>[base64 mime encoded serialized .NET Framework object]</value>
19.27 + </data>
19.28 + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
19.29 + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
19.30 + <comment>This is a comment</comment>
19.31 + </data>
19.32 +
19.33 + There are any number of "resheader" rows that contain simple
19.34 + name/value pairs.
19.35 +
19.36 + Each data row contains a name, and value. The row also contains a
19.37 + type or mimetype. Type corresponds to a .NET class that support
19.38 + text/value conversion through the TypeConverter architecture.
19.39 + Classes that don't support this are serialized and stored with the
19.40 + mimetype set.
19.41 +
19.42 + The mimetype is used for serialized objects, and tells the
19.43 + ResXResourceReader how to depersist the object. This is currently not
19.44 + extensible. For a given mimetype the value must be set accordingly:
19.45 +
19.46 + Note - application/x-microsoft.net.object.binary.base64 is the format
19.47 + that the ResXResourceWriter will generate, however the reader can
19.48 + read any of the formats listed below.
19.49 +
19.50 + mimetype: application/x-microsoft.net.object.binary.base64
19.51 + value : The object must be serialized with
19.52 + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
19.53 + : and then encoded with base64 encoding.
19.54 +
19.55 + mimetype: application/x-microsoft.net.object.soap.base64
19.56 + value : The object must be serialized with
19.57 + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
19.58 + : and then encoded with base64 encoding.
19.59 +
19.60 + mimetype: application/x-microsoft.net.object.bytearray.base64
19.61 + value : The object must be serialized into a byte array
19.62 + : using a System.ComponentModel.TypeConverter
19.63 + : and then encoded with base64 encoding.
19.64 + -->
19.65 + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
19.66 + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
19.67 + <xsd:element name="root" msdata:IsDataSet="true">
19.68 + <xsd:complexType>
19.69 + <xsd:choice maxOccurs="unbounded">
19.70 + <xsd:element name="metadata">
19.71 + <xsd:complexType>
19.72 + <xsd:sequence>
19.73 + <xsd:element name="value" type="xsd:string" minOccurs="0" />
19.74 + </xsd:sequence>
19.75 + <xsd:attribute name="name" use="required" type="xsd:string" />
19.76 + <xsd:attribute name="type" type="xsd:string" />
19.77 + <xsd:attribute name="mimetype" type="xsd:string" />
19.78 + <xsd:attribute ref="xml:space" />
19.79 + </xsd:complexType>
19.80 + </xsd:element>
19.81 + <xsd:element name="assembly">
19.82 + <xsd:complexType>
19.83 + <xsd:attribute name="alias" type="xsd:string" />
19.84 + <xsd:attribute name="name" type="xsd:string" />
19.85 + </xsd:complexType>
19.86 + </xsd:element>
19.87 + <xsd:element name="data">
19.88 + <xsd:complexType>
19.89 + <xsd:sequence>
19.90 + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
19.91 + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
19.92 + </xsd:sequence>
19.93 + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
19.94 + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
19.95 + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
19.96 + <xsd:attribute ref="xml:space" />
19.97 + </xsd:complexType>
19.98 + </xsd:element>
19.99 + <xsd:element name="resheader">
19.100 + <xsd:complexType>
19.101 + <xsd:sequence>
19.102 + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
19.103 + </xsd:sequence>
19.104 + <xsd:attribute name="name" type="xsd:string" use="required" />
19.105 + </xsd:complexType>
19.106 + </xsd:element>
19.107 + </xsd:choice>
19.108 + </xsd:complexType>
19.109 + </xsd:element>
19.110 + </xsd:schema>
19.111 + <resheader name="resmimetype">
19.112 + <value>text/microsoft-resx</value>
19.113 + </resheader>
19.114 + <resheader name="version">
19.115 + <value>2.0</value>
19.116 + </resheader>
19.117 + <resheader name="reader">
19.118 + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
19.119 + </resheader>
19.120 + <resheader name="writer">
19.121 + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
19.122 + </resheader>
19.123 + <metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
19.124 + <value>17, 17</value>
19.125 + </metadata>
19.126 +</root>
19.127 \ No newline at end of file
20.1 --- a/Server/FormMain.Designer.cs Sun Jul 31 12:03:52 2016 +0200
20.2 +++ b/Server/FormMain.Designer.cs Fri Aug 12 20:25:05 2016 +0200
20.3 @@ -110,6 +110,10 @@
20.4 this.labelHdmiPort = new System.Windows.Forms.Label();
20.5 this.comboBoxHdmiPort = new System.Windows.Forms.ComboBox();
20.6 this.tabPageEvent = new System.Windows.Forms.TabPage();
20.7 + this.buttonEventEdit = new System.Windows.Forms.Button();
20.8 + this.buttonEventDelete = new System.Windows.Forms.Button();
20.9 + this.buttonEventAdd = new System.Windows.Forms.Button();
20.10 + this.buttonEventTest = new System.Windows.Forms.Button();
20.11 this.buttonActionEdit = new System.Windows.Forms.Button();
20.12 this.buttonActionMoveUp = new System.Windows.Forms.Button();
20.13 this.buttonActionMoveDown = new System.Windows.Forms.Button();
20.14 @@ -129,7 +133,6 @@
20.15 this.labelFontHeight = new System.Windows.Forms.Label();
20.16 this.toolTip = new System.Windows.Forms.ToolTip(this.components);
20.17 this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
20.18 - this.buttonEventTest = new System.Windows.Forms.Button();
20.19 this.panelDisplay.SuspendLayout();
20.20 this.iTableLayoutPanel.SuspendLayout();
20.21 this.statusStrip.SuspendLayout();
20.22 @@ -974,6 +977,9 @@
20.23 //
20.24 // tabPageEvent
20.25 //
20.26 + this.tabPageEvent.Controls.Add(this.buttonEventEdit);
20.27 + this.tabPageEvent.Controls.Add(this.buttonEventDelete);
20.28 + this.tabPageEvent.Controls.Add(this.buttonEventAdd);
20.29 this.tabPageEvent.Controls.Add(this.buttonEventTest);
20.30 this.tabPageEvent.Controls.Add(this.buttonActionEdit);
20.31 this.tabPageEvent.Controls.Add(this.buttonActionMoveUp);
20.32 @@ -990,10 +996,53 @@
20.33 this.tabPageEvent.Text = "Events";
20.34 this.tabPageEvent.UseVisualStyleBackColor = true;
20.35 //
20.36 + // buttonEventEdit
20.37 + //
20.38 + this.buttonEventEdit.Enabled = false;
20.39 + this.buttonEventEdit.Location = new System.Drawing.Point(6, 35);
20.40 + this.buttonEventEdit.Name = "buttonEventEdit";
20.41 + this.buttonEventEdit.Size = new System.Drawing.Size(96, 23);
20.42 + this.buttonEventEdit.TabIndex = 29;
20.43 + this.buttonEventEdit.Text = "Edit Event";
20.44 + this.buttonEventEdit.UseVisualStyleBackColor = true;
20.45 + this.buttonEventEdit.Click += new System.EventHandler(this.buttonEventEdit_Click);
20.46 + //
20.47 + // buttonEventDelete
20.48 + //
20.49 + this.buttonEventDelete.Enabled = false;
20.50 + this.buttonEventDelete.Location = new System.Drawing.Point(6, 64);
20.51 + this.buttonEventDelete.Name = "buttonEventDelete";
20.52 + this.buttonEventDelete.Size = new System.Drawing.Size(96, 23);
20.53 + this.buttonEventDelete.TabIndex = 28;
20.54 + this.buttonEventDelete.Text = "Delete Event";
20.55 + this.buttonEventDelete.UseVisualStyleBackColor = true;
20.56 + this.buttonEventDelete.Click += new System.EventHandler(this.buttonEventDelete_Click);
20.57 + //
20.58 + // buttonEventAdd
20.59 + //
20.60 + this.buttonEventAdd.Location = new System.Drawing.Point(6, 6);
20.61 + this.buttonEventAdd.Name = "buttonEventAdd";
20.62 + this.buttonEventAdd.Size = new System.Drawing.Size(96, 23);
20.63 + this.buttonEventAdd.TabIndex = 27;
20.64 + this.buttonEventAdd.Text = "Add Event";
20.65 + this.buttonEventAdd.UseVisualStyleBackColor = true;
20.66 + this.buttonEventAdd.Click += new System.EventHandler(this.buttonEventAdd_Click);
20.67 + //
20.68 + // buttonEventTest
20.69 + //
20.70 + this.buttonEventTest.Enabled = false;
20.71 + this.buttonEventTest.Location = new System.Drawing.Point(6, 93);
20.72 + this.buttonEventTest.Name = "buttonEventTest";
20.73 + this.buttonEventTest.Size = new System.Drawing.Size(96, 23);
20.74 + this.buttonEventTest.TabIndex = 26;
20.75 + this.buttonEventTest.Text = "Test Event";
20.76 + this.buttonEventTest.UseVisualStyleBackColor = true;
20.77 + this.buttonEventTest.Click += new System.EventHandler(this.buttonEventTest_Click);
20.78 + //
20.79 // buttonActionEdit
20.80 //
20.81 this.buttonActionEdit.Enabled = false;
20.82 - this.buttonActionEdit.Location = new System.Drawing.Point(6, 35);
20.83 + this.buttonActionEdit.Location = new System.Drawing.Point(6, 190);
20.84 this.buttonActionEdit.Name = "buttonActionEdit";
20.85 this.buttonActionEdit.Size = new System.Drawing.Size(96, 23);
20.86 this.buttonActionEdit.TabIndex = 25;
20.87 @@ -1026,7 +1075,7 @@
20.88 // buttonActionTest
20.89 //
20.90 this.buttonActionTest.Enabled = false;
20.91 - this.buttonActionTest.Location = new System.Drawing.Point(6, 93);
20.92 + this.buttonActionTest.Location = new System.Drawing.Point(6, 248);
20.93 this.buttonActionTest.Name = "buttonActionTest";
20.94 this.buttonActionTest.Size = new System.Drawing.Size(96, 23);
20.95 this.buttonActionTest.TabIndex = 22;
20.96 @@ -1037,7 +1086,7 @@
20.97 // buttonActionDelete
20.98 //
20.99 this.buttonActionDelete.Enabled = false;
20.100 - this.buttonActionDelete.Location = new System.Drawing.Point(6, 64);
20.101 + this.buttonActionDelete.Location = new System.Drawing.Point(6, 219);
20.102 this.buttonActionDelete.Name = "buttonActionDelete";
20.103 this.buttonActionDelete.Size = new System.Drawing.Size(96, 23);
20.104 this.buttonActionDelete.TabIndex = 21;
20.105 @@ -1048,9 +1097,9 @@
20.106 // buttonActionAdd
20.107 //
20.108 this.buttonActionAdd.Enabled = false;
20.109 - this.buttonActionAdd.Location = new System.Drawing.Point(6, 6);
20.110 + this.buttonActionAdd.Location = new System.Drawing.Point(6, 157);
20.111 this.buttonActionAdd.Name = "buttonActionAdd";
20.112 - this.buttonActionAdd.Size = new System.Drawing.Size(96, 23);
20.113 + this.buttonActionAdd.Size = new System.Drawing.Size(96, 27);
20.114 this.buttonActionAdd.TabIndex = 20;
20.115 this.buttonActionAdd.Text = "Add Action";
20.116 this.buttonActionAdd.UseVisualStyleBackColor = true;
20.117 @@ -1067,6 +1116,7 @@
20.118 this.iTreeViewEvents.Size = new System.Drawing.Size(638, 376);
20.119 this.iTreeViewEvents.TabIndex = 1;
20.120 this.iTreeViewEvents.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.iTreeViewEvents_AfterSelect);
20.121 + this.iTreeViewEvents.Leave += new System.EventHandler(this.iTreeViewEvents_Leave);
20.122 //
20.123 // tabPageApp
20.124 //
20.125 @@ -1189,17 +1239,6 @@
20.126 //
20.127 this.openFileDialog.Filter = "EXE files (*.exe)|*.exe|All files (*.*)|*.*";
20.128 //
20.129 - // buttonEventTest
20.130 - //
20.131 - this.buttonEventTest.Enabled = false;
20.132 - this.buttonEventTest.Location = new System.Drawing.Point(6, 122);
20.133 - this.buttonEventTest.Name = "buttonEventTest";
20.134 - this.buttonEventTest.Size = new System.Drawing.Size(96, 23);
20.135 - this.buttonEventTest.TabIndex = 26;
20.136 - this.buttonEventTest.Text = "Test Event";
20.137 - this.buttonEventTest.UseVisualStyleBackColor = true;
20.138 - this.buttonEventTest.Click += new System.EventHandler(this.buttonEventTest_Click);
20.139 - //
20.140 // FormMain
20.141 //
20.142 this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
20.143 @@ -1344,6 +1383,9 @@
20.144 private System.Windows.Forms.Button buttonActionTest;
20.145 private System.Windows.Forms.Button buttonActionEdit;
20.146 private System.Windows.Forms.Button buttonEventTest;
20.147 + private System.Windows.Forms.Button buttonEventDelete;
20.148 + private System.Windows.Forms.Button buttonEventAdd;
20.149 + private System.Windows.Forms.Button buttonEventEdit;
20.150 }
20.151 }
20.152
21.1 --- a/Server/FormMain.cs Sun Jul 31 12:03:52 2016 +0200
21.2 +++ b/Server/FormMain.cs Fri Aug 12 20:25:05 2016 +0200
21.3 @@ -322,23 +322,33 @@
21.4 Event currentEvent = CurrentEvent();
21.5 SharpLib.Ear.Action currentAction = CurrentAction();
21.6 TreeNode treeNodeToSelect = null;
21.7 -
21.8 +
21.9 //Reset our tree
21.10 iTreeViewEvents.Nodes.Clear();
21.11 //Populate registered events
21.12 - foreach (string key in ManagerEventAction.Current.Events.Keys)
21.13 + foreach (SharpLib.Ear.Event e in ManagerEventAction.Current.Events)
21.14 {
21.15 - Event e = ManagerEventAction.Current.Events[key];
21.16 - TreeNode eventNode = iTreeViewEvents.Nodes.Add(key, e.Name);
21.17 - eventNode.Tag = e;
21.18 - eventNode.Nodes.Add(key + ".Description", e.Description);
21.19 - TreeNode actionsNodes = eventNode.Nodes.Add(key + ".Actions", "Actions");
21.20 + //Create our event node
21.21 + TreeNode eventNode = iTreeViewEvents.Nodes.Add(e.Name);
21.22 + eventNode.Tag = e; //For easy access to our event
21.23 + if (!e.Enabled)
21.24 + {
21.25 + //Dim our nodes if disabled
21.26 + eventNode.ForeColor = Color.DimGray;
21.27 + }
21.28 +
21.29 + //Add event description as child node
21.30 + eventNode.Nodes.Add(e.Description).ForeColor = eventNode.ForeColor;
21.31 + //Create child node for actions root
21.32 + TreeNode actionsNodes = eventNode.Nodes.Add("Actions");
21.33 + actionsNodes.ForeColor = eventNode.ForeColor;
21.34
21.35 // Add our actions for that event
21.36 foreach (SharpLib.Ear.Action a in e.Actions)
21.37 {
21.38 TreeNode actionNode = actionsNodes.Nodes.Add(a.Brief());
21.39 actionNode.Tag = a;
21.40 + actionNode.ForeColor = eventNode.ForeColor;
21.41 if (a == currentAction)
21.42 {
21.43 treeNodeToSelect = actionNode;
21.44 @@ -360,7 +370,14 @@
21.45 iTreeViewEvents.SelectedNode.Nodes[1].Nodes[
21.46 iTreeViewEvents.SelectedNode.Nodes[1].GetNodeCount(false) - 1];
21.47 }
21.48 -
21.49 + else if (iTreeViewEvents.SelectedNode == null && iTreeViewEvents.Nodes.Count > 0)
21.50 + {
21.51 + //Still no selected node select the first one then
21.52 + iTreeViewEvents.SelectedNode = iTreeViewEvents.Nodes[0];
21.53 + }
21.54 +
21.55 +
21.56 + UpdateEventView();
21.57 }
21.58
21.59 /// <summary>
21.60 @@ -2727,12 +2744,13 @@
21.61 return;
21.62 }
21.63
21.64 - string key = aEvent.GetType().Name;
21.65 - TreeNode[] res = iTreeViewEvents.Nodes.Find(key, false);
21.66 - if (res.Length > 0)
21.67 + foreach (TreeNode node in iTreeViewEvents.Nodes)
21.68 {
21.69 - iTreeViewEvents.SelectedNode = res[0];
21.70 - iTreeViewEvents.Focus();
21.71 + if (node.Tag == aEvent)
21.72 + {
21.73 + iTreeViewEvents.SelectedNode = node;
21.74 + iTreeViewEvents.Focus();
21.75 + }
21.76 }
21.77 }
21.78
21.79 @@ -2789,12 +2807,12 @@
21.80 return;
21.81 }
21.82
21.83 - FormEditAction ea = new FormEditAction();
21.84 + FormEditObject<SharpLib.Ear.Action> ea = new FormEditObject<SharpLib.Ear.Action>();
21.85 ea.Text = "Add action";
21.86 DialogResult res = CodeProject.Dialog.DlgBox.ShowDialog(ea);
21.87 if (res == DialogResult.OK)
21.88 {
21.89 - selectedEvent.Actions.Add(ea.Action);
21.90 + selectedEvent.Actions.Add(ea.Object);
21.91 Properties.Settings.Default.Actions = ManagerEventAction.Current;
21.92 Properties.Settings.Default.Save();
21.93 PopulateEventsTreeView();
21.94 @@ -2816,15 +2834,15 @@
21.95 return;
21.96 }
21.97
21.98 - FormEditAction ea = new FormEditAction();
21.99 + FormEditObject<SharpLib.Ear.Action> ea = new FormEditObject<SharpLib.Ear.Action>();
21.100 ea.Text = "Edit action";
21.101 - ea.Action = selectedAction;
21.102 + ea.Object = selectedAction;
21.103 int actionIndex = iTreeViewEvents.SelectedNode.Index;
21.104 DialogResult res = CodeProject.Dialog.DlgBox.ShowDialog(ea);
21.105 if (res == DialogResult.OK)
21.106 {
21.107 //Update our action
21.108 - selectedEvent.Actions[actionIndex]=ea.Action;
21.109 + selectedEvent.Actions[actionIndex]=ea.Object;
21.110 //Save and rebuild our event tree view
21.111 Properties.Settings.Default.Actions = ManagerEventAction.Current;
21.112 Properties.Settings.Default.Save();
21.113 @@ -2863,8 +2881,7 @@
21.114 SharpLib.Ear.Action a = CurrentAction();
21.115 if (a != null)
21.116 {
21.117 - Console.WriteLine("Action testing:");
21.118 - a.Execute();
21.119 + a.Test();
21.120 }
21.121 iTreeViewEvents.Focus();
21.122 }
21.123 @@ -2939,8 +2956,7 @@
21.124 Event earEvent = CurrentEvent();
21.125 if (earEvent != null)
21.126 {
21.127 - Console.WriteLine("Event testing:");
21.128 - earEvent.Trigger();
21.129 + earEvent.Test();
21.130 }
21.131 }
21.132
21.133 @@ -2951,9 +2967,22 @@
21.134 /// <param name="e"></param>
21.135 private void iTreeViewEvents_AfterSelect(object sender, TreeViewEventArgs e)
21.136 {
21.137 + UpdateEventView();
21.138 + }
21.139 +
21.140 + /// <summary>
21.141 + ///
21.142 + /// </summary>
21.143 + private void UpdateEventView()
21.144 + {
21.145 + //One can always add an event
21.146 + buttonEventAdd.Enabled = true;
21.147 +
21.148 //Enable buttons according to selected item
21.149 buttonActionAdd.Enabled =
21.150 buttonEventTest.Enabled =
21.151 + buttonEventDelete.Enabled =
21.152 + buttonEventEdit.Enabled =
21.153 CurrentEvent() != null;
21.154
21.155 SharpLib.Ear.Action currentAction = CurrentAction();
21.156 @@ -2962,7 +2991,7 @@
21.157 buttonActionDelete.Enabled =
21.158 buttonActionMoveUp.Enabled =
21.159 buttonActionMoveDown.Enabled =
21.160 - buttonActionEdit.Enabled =
21.161 + buttonActionEdit.Enabled =
21.162 currentAction != null;
21.163
21.164 if (currentAction != null)
21.165 @@ -2972,8 +3001,65 @@
21.166 buttonActionMoveDown.Enabled = iTreeViewEvents.SelectedNode.Index <
21.167 iTreeViewEvents.SelectedNode.Parent.Nodes.Count - 1;
21.168 }
21.169 -
21.170 }
21.171
21.172 + private void buttonEventAdd_Click(object sender, EventArgs e)
21.173 + {
21.174 + FormEditObject<SharpLib.Ear.Event> ea = new FormEditObject<SharpLib.Ear.Event>();
21.175 + ea.Text = "Add event";
21.176 + DialogResult res = CodeProject.Dialog.DlgBox.ShowDialog(ea);
21.177 + if (res == DialogResult.OK)
21.178 + {
21.179 + ManagerEventAction.Current.Events.Add(ea.Object);
21.180 + Properties.Settings.Default.Actions = ManagerEventAction.Current;
21.181 + Properties.Settings.Default.Save();
21.182 + PopulateEventsTreeView();
21.183 + SelectEvent(ea.Object);
21.184 + }
21.185 + }
21.186 +
21.187 + private void buttonEventDelete_Click(object sender, EventArgs e)
21.188 + {
21.189 + SharpLib.Ear.Event currentEvent = CurrentEvent();
21.190 + if (currentEvent == null)
21.191 + {
21.192 + //Must select action node
21.193 + return;
21.194 + }
21.195 +
21.196 + ManagerEventAction.Current.Events.Remove(currentEvent);
21.197 + Properties.Settings.Default.Actions = ManagerEventAction.Current;
21.198 + Properties.Settings.Default.Save();
21.199 + PopulateEventsTreeView();
21.200 + }
21.201 +
21.202 + private void buttonEventEdit_Click(object sender, EventArgs e)
21.203 + {
21.204 + Event selectedEvent = CurrentEvent();
21.205 + if (selectedEvent == null)
21.206 + {
21.207 + //We did not find a corresponding event
21.208 + return;
21.209 + }
21.210 +
21.211 + FormEditObject<SharpLib.Ear.Event> ea = new FormEditObject<SharpLib.Ear.Event>();
21.212 + ea.Text = "Edit event";
21.213 + ea.Object = selectedEvent;
21.214 + int actionIndex = iTreeViewEvents.SelectedNode.Index;
21.215 + DialogResult res = CodeProject.Dialog.DlgBox.ShowDialog(ea);
21.216 + if (res == DialogResult.OK)
21.217 + {
21.218 + //Save and rebuild our event tree view
21.219 + Properties.Settings.Default.Actions = ManagerEventAction.Current;
21.220 + Properties.Settings.Default.Save();
21.221 + PopulateEventsTreeView();
21.222 + }
21.223 + }
21.224 +
21.225 + private void iTreeViewEvents_Leave(object sender, EventArgs e)
21.226 + {
21.227 + //Make sure our event tree never looses focus
21.228 + ((TreeView) sender).Focus();
21.229 + }
21.230 }
21.231 }
22.1 --- a/Server/ItemActionType.cs Sun Jul 31 12:03:52 2016 +0200
22.2 +++ b/Server/ItemActionType.cs Fri Aug 12 20:25:05 2016 +0200
22.3 @@ -10,11 +10,11 @@
22.4 /// <summary>
22.5 /// Used to populate our action type combobox with friendly names
22.6 /// </summary>
22.7 - class ItemActionType
22.8 + class ItemObjectType
22.9 {
22.10 public Type Type;
22.11
22.12 - public ItemActionType(Type type)
22.13 + public ItemObjectType(Type type)
22.14 {
22.15 this.Type = type;
22.16 }
22.17 @@ -23,7 +23,7 @@
22.18 {
22.19 //Get friendly action name from action attribute.
22.20 //That we then show up in our combobox
22.21 - return SharpLib.Utils.Reflection.GetAttribute<AttributeAction>(Type).Name;
22.22 + return SharpLib.Utils.Reflection.GetAttribute<AttributeObject>(Type).Name;
22.23 }
22.24 }
22.25 }
23.1 --- a/Server/SharpDisplayManager.csproj Sun Jul 31 12:03:52 2016 +0200
23.2 +++ b/Server/SharpDisplayManager.csproj Fri Aug 12 20:25:05 2016 +0200
23.3 @@ -169,11 +169,11 @@
23.4 <Compile Include="CecClient.cs" />
23.5 <Compile Include="ConsumerElectronicControl.cs" />
23.6 <Compile Include="ClientData.cs" />
23.7 - <Compile Include="FormEditAction.cs">
23.8 + <Compile Include="FormEditObject.cs">
23.9 <SubType>Form</SubType>
23.10 </Compile>
23.11 - <Compile Include="FormEditAction.Designer.cs">
23.12 - <DependentUpon>FormEditAction.cs</DependentUpon>
23.13 + <Compile Include="FormEditObject.Designer.cs">
23.14 + <DependentUpon>FormEditObject.cs</DependentUpon>
23.15 </Compile>
23.16 <Compile Include="FormMain.cs">
23.17 <SubType>Form</SubType>
23.18 @@ -210,8 +210,8 @@
23.19 <Compile Include="Win32API.cs" />
23.20 <Compile Include="WindowsHook.cs" />
23.21 <Compile Include="WndProcRetHook.cs" />
23.22 - <EmbeddedResource Include="FormEditAction.resx">
23.23 - <DependentUpon>FormEditAction.cs</DependentUpon>
23.24 + <EmbeddedResource Include="FormEditObject.resx">
23.25 + <DependentUpon>FormEditObject.cs</DependentUpon>
23.26 </EmbeddedResource>
23.27 <EmbeddedResource Include="FormMain.resx">
23.28 <DependentUpon>FormMain.cs</DependentUpon>
24.1 --- a/SharpLibEar/Action.cs Sun Jul 31 12:03:52 2016 +0200
24.2 +++ b/SharpLibEar/Action.cs Fri Aug 12 20:25:05 2016 +0200
24.3 @@ -14,6 +14,15 @@
24.4 {
24.5 protected abstract void DoExecute();
24.6
24.7 + /// <summary>
24.8 + /// Allows testing from generic edit dialog.
24.9 + /// </summary>
24.10 + public void Test()
24.11 + {
24.12 + Console.WriteLine("Action test");
24.13 + Execute();
24.14 + }
24.15 +
24.16 public void Execute()
24.17 {
24.18 Console.WriteLine("Action executing: " + Brief());
24.19 @@ -22,7 +31,7 @@
24.20
24.21 public string Name {
24.22 //Get the name of this object action attribute
24.23 - get { return Utils.Reflection.GetAttribute<AttributeAction>(GetType()).Name; }
24.24 + get { return Utils.Reflection.GetAttribute<AttributeObject>(GetType()).Name; }
24.25 private set { }
24.26 }
24.27
24.28 @@ -34,7 +43,7 @@
24.29 public int CompareTo(object obj)
24.30 {
24.31 //Sort by action name
24.32 - return Utils.Reflection.GetAttribute<AttributeAction>(GetType()).Name.CompareTo(obj.GetType());
24.33 + return Utils.Reflection.GetAttribute<AttributeObject>(GetType()).Name.CompareTo(obj.GetType());
24.34 }
24.35
24.36 private static IEnumerable<Type> DerivedTypes()
25.1 --- a/SharpLibEar/ActionSleep.cs Sun Jul 31 12:03:52 2016 +0200
25.2 +++ b/SharpLibEar/ActionSleep.cs Fri Aug 12 20:25:05 2016 +0200
25.3 @@ -10,11 +10,11 @@
25.4
25.5
25.6 [DataContract]
25.7 - [AttributeAction(Id = "Thread.Sleep", Name = "Sleep", Description = "Have the current thread sleep for the specified amount of milliseconds.")]
25.8 + [AttributeObject(Id = "Thread.Sleep", Name = "Sleep", Description = "Have the current thread sleep for the specified amount of milliseconds.")]
25.9 public class ActionSleep : Action
25.10 {
25.11 [DataMember]
25.12 - [AttributeActionProperty
25.13 + [AttributeObjectProperty
25.14 (
25.15 Id = "Thread.Sleep.Timeout",
25.16 Name = "Timeout (ms)",
26.1 --- a/SharpLibEar/AttributeAction.cs Sun Jul 31 12:03:52 2016 +0200
26.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
26.3 @@ -1,22 +0,0 @@
26.4 -using System;
26.5 -using System.Collections.Generic;
26.6 -using System.Linq;
26.7 -using System.Text;
26.8 -using System.Threading.Tasks;
26.9 -
26.10 -namespace SharpLib.Ear
26.11 -{
26.12 -
26.13 - /// <summary>
26.14 - /// For action class to define name and description.
26.15 - /// </summary>
26.16 - [System.AttributeUsage(System.AttributeTargets.Class)]
26.17 - public class AttributeAction : System.Attribute
26.18 - {
26.19 - public string Id;
26.20 - public string Name;
26.21 - public string Description;
26.22 - }
26.23 -
26.24 -
26.25 -}
27.1 --- a/SharpLibEar/AttributeActionProperty.cs Sun Jul 31 12:03:52 2016 +0200
27.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
27.3 @@ -1,27 +0,0 @@
27.4 -using System;
27.5 -using System.Collections.Generic;
27.6 -using System.Linq;
27.7 -using System.Text;
27.8 -using System.Threading.Tasks;
27.9 -
27.10 -namespace SharpLib.Ear
27.11 -{
27.12 - /// <summary>
27.13 - /// To expose an action property thus enabling user to edit it.
27.14 - /// </summary>
27.15 - [System.AttributeUsage(System.AttributeTargets.Property)]
27.16 - public class AttributeActionProperty : System.Attribute
27.17 - {
27.18 - public string Id;
27.19 - public string Name;
27.20 - public string Description;
27.21 - // For numerics
27.22 - public string Minimum;
27.23 - public string Maximum;
27.24 - public string Increment;
27.25 - }
27.26 -
27.27 -
27.28 -
27.29 -
27.30 -}
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
28.2 +++ b/SharpLibEar/AttributeObject.cs Fri Aug 12 20:25:05 2016 +0200
28.3 @@ -0,0 +1,22 @@
28.4 +using System;
28.5 +using System.Collections.Generic;
28.6 +using System.Linq;
28.7 +using System.Text;
28.8 +using System.Threading.Tasks;
28.9 +
28.10 +namespace SharpLib.Ear
28.11 +{
28.12 +
28.13 + /// <summary>
28.14 + /// For action class to define name and description.
28.15 + /// </summary>
28.16 + [System.AttributeUsage(System.AttributeTargets.Class)]
28.17 + public class AttributeObject : System.Attribute
28.18 + {
28.19 + public string Id;
28.20 + public string Name;
28.21 + public string Description;
28.22 + }
28.23 +
28.24 +
28.25 +}
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
29.2 +++ b/SharpLibEar/AttributeObjectProperty.cs Fri Aug 12 20:25:05 2016 +0200
29.3 @@ -0,0 +1,27 @@
29.4 +using System;
29.5 +using System.Collections.Generic;
29.6 +using System.Linq;
29.7 +using System.Text;
29.8 +using System.Threading.Tasks;
29.9 +
29.10 +namespace SharpLib.Ear
29.11 +{
29.12 + /// <summary>
29.13 + /// To expose an action property thus enabling user to edit it.
29.14 + /// </summary>
29.15 + [System.AttributeUsage(System.AttributeTargets.Property)]
29.16 + public class AttributeObjectProperty : System.Attribute
29.17 + {
29.18 + public string Id;
29.19 + public string Name;
29.20 + public string Description;
29.21 + // For numerics
29.22 + public string Minimum;
29.23 + public string Maximum;
29.24 + public string Increment;
29.25 + }
29.26 +
29.27 +
29.28 +
29.29 +
29.30 +}
30.1 --- a/SharpLibEar/Event.cs Sun Jul 31 12:03:52 2016 +0200
30.2 +++ b/SharpLibEar/Event.cs Fri Aug 12 20:25:05 2016 +0200
30.3 @@ -8,26 +8,54 @@
30.4 namespace SharpLib.Ear
30.5 {
30.6 [DataContract]
30.7 - public abstract class MEvent
30.8 + [KnownType("DerivedTypes")]
30.9 + public abstract class Event
30.10 {
30.11 - public string Name { get; protected set; }
30.12 - public string Description { get; protected set; }
30.13 + [DataMember]
30.14 + [AttributeObjectProperty
30.15 + (
30.16 + Id = "Event.Enabled",
30.17 + Name = "Enabled",
30.18 + Description = "When enabled an event instance can be triggered."
30.19 + )
30.20 + ]
30.21 + public bool Enabled { get; set; }
30.22
30.23 - public abstract void Trigger();
30.24 - };
30.25 -
30.26 - [DataContract]
30.27 - public abstract class Event : MEvent
30.28 - {
30.29 [DataMember]
30.30 public List<Action> Actions = new List<Action>();
30.31
30.32 + public string Name
30.33 + {
30.34 + //Get the name of this object attribute
30.35 + get { return Utils.Reflection.GetAttribute<AttributeObject>(GetType()).Name; }
30.36 + private set { }
30.37 + }
30.38 +
30.39 + public string Description
30.40 + {
30.41 + //Get the description of this object attribute
30.42 + get { return Utils.Reflection.GetAttribute<AttributeObject>(GetType()).Description; }
30.43 + private set { }
30.44 + }
30.45 +
30.46 +
30.47 protected Event()
30.48 {
30.49 -
30.50 + Enabled = true;
30.51 }
30.52
30.53 - public override void Trigger()
30.54 +
30.55 + /// <summary>
30.56 + /// Allows testing from generic edit dialog.
30.57 + /// </summary>
30.58 + public void Test()
30.59 + {
30.60 + Console.WriteLine("Event test");
30.61 + Trigger();
30.62 + }
30.63 +
30.64 +
30.65 + public void Trigger()
30.66 {
30.67 Console.WriteLine("Event triggered: " + Name);
30.68 foreach (Action action in Actions)
30.69 @@ -35,6 +63,15 @@
30.70 action.Execute();
30.71 }
30.72 }
30.73 - }
30.74 +
30.75 + /// <summary>
30.76 + /// So that data contract knows all our types.
30.77 + /// </summary>
30.78 + /// <returns></returns>
30.79 + private static IEnumerable<Type> DerivedTypes()
30.80 + {
30.81 + return SharpLib.Utils.Reflection.GetDerivedTypes<Event>();
30.82 + }
30.83 + };
30.84
30.85 }
30.86 \ No newline at end of file
31.1 --- a/SharpLibEar/EventMonitorPowerOff.cs Sun Jul 31 12:03:52 2016 +0200
31.2 +++ b/SharpLibEar/EventMonitorPowerOff.cs Fri Aug 12 20:25:05 2016 +0200
31.3 @@ -6,12 +6,11 @@
31.4 namespace SharpLib.Ear
31.5 {
31.6 [DataContract]
31.7 + [AttributeObject(Id = "Event.Monitor.PowerOff", Name = "Monitor Power Off", Description = "Windows is powering off your monitor.")]
31.8 public class EventMonitorPowerOff : Event
31.9 {
31.10 public EventMonitorPowerOff()
31.11 {
31.12 - Name = "Monitor Power Off";
31.13 - Description = "Windows is powering off your monitor.";
31.14 }
31.15 }
31.16
32.1 --- a/SharpLibEar/EventMonitorPowerOn.cs Sun Jul 31 12:03:52 2016 +0200
32.2 +++ b/SharpLibEar/EventMonitorPowerOn.cs Fri Aug 12 20:25:05 2016 +0200
32.3 @@ -6,12 +6,11 @@
32.4 namespace SharpLib.Ear
32.5 {
32.6 [DataContract]
32.7 + [AttributeObject(Id = "Event.Monitor.PowerOn", Name = "Monitor Power On", Description = "Windows is powering on your monitor.")]
32.8 public class EventMonitorPowerOn : Event
32.9 {
32.10 public EventMonitorPowerOn()
32.11 {
32.12 - Name = "Monitor Power On";
32.13 - Description = "Windows is powering on your monitor.";
32.14 }
32.15
32.16 }
33.1 --- a/SharpLibEar/ManagerEventAction.cs Sun Jul 31 12:03:52 2016 +0200
33.2 +++ b/SharpLibEar/ManagerEventAction.cs Fri Aug 12 20:25:05 2016 +0200
33.3 @@ -16,10 +16,16 @@
33.4 public class ManagerEventAction
33.5 {
33.6 public static ManagerEventAction Current = null;
33.7 - public IDictionary<string, Type> ActionTypes;
33.8 - public IDictionary<string, Event> Events;
33.9 + //public IDictionary<string, Type> ActionTypes;
33.10 + //public IDictionary<string, Type> EventTypes;
33.11 +
33.12 + /// <summary>
33.13 + /// Our events instances.
33.14 + /// </summary>
33.15 [DataMember]
33.16 - public Dictionary<string, List<Action>> ActionsByEvents = new Dictionary<string, List<Action>>();
33.17 + public List<Event> Events;
33.18 +
33.19 +
33.20
33.21
33.22 public ManagerEventAction()
33.23 @@ -28,47 +34,30 @@
33.24 }
33.25
33.26 /// <summary>
33.27 - ///
33.28 + /// Executes after internalization took place.
33.29 /// </summary>
33.30 public void Init()
33.31 {
33.32 - //Create our list of supported actions
33.33 - ActionTypes = Utils.Reflection.GetConcreteClassesDerivedFromByName<Action>();
33.34 - //Create our list or support events
33.35 - Events = Utils.Reflection.GetConcreteClassesInstanceDerivedFromByName<Event>();
33.36 + if (Events == null)
33.37 + {
33.38 + Events = new List<Event>();
33.39 + }
33.40 +
33.41 + }
33.42
33.43 - if (ActionsByEvents == null)
33.44 - {
33.45 - ActionsByEvents = new Dictionary<string, List<Action>>();
33.46 - }
33.47 -
33.48 - //Hook in loaded actions with corresponding events
33.49 - foreach (string key in Events.Keys)
33.50 + /// <summary>
33.51 + ///
33.52 + /// </summary>
33.53 + /// <param name="aEventType"></param>
33.54 + public void TriggerEvent<T>() where T: class
33.55 + {
33.56 + //Only trigger enabled events matching the desired type
33.57 + foreach (Event e in Events.Where(e => e.GetType() == typeof(T) && e.Enabled))
33.58 {
33.59 - Event e = Events[key];
33.60 - if (ActionsByEvents.ContainsKey(key))
33.61 - {
33.62 - //We have actions for that event, hook them in then
33.63 - e.Actions = ActionsByEvents[key];
33.64 - }
33.65 - else
33.66 - {
33.67 - //We do not have actions for that event yet, create empty action list
33.68 - e.Actions = new List<Action>();
33.69 - ActionsByEvents[key] = e.Actions;
33.70 - }
33.71 + e.Trigger();
33.72 }
33.73 }
33.74
33.75 - /// <summary>
33.76 - /// Get and event instance from its type.
33.77 - /// </summary>
33.78 - /// <typeparam name="T"></typeparam>
33.79 - /// <returns></returns>
33.80 - public Event GetEvent<T>() where T : class
33.81 - {
33.82 - return Events[typeof(T).Name];
33.83 - }
33.84
33.85 /// <summary>
33.86 ///
33.87 @@ -76,17 +65,14 @@
33.88 /// <param name="aAction"></param>
33.89 public void RemoveAction(Action aAction)
33.90 {
33.91 - foreach (string key in Events.Keys)
33.92 + foreach (Event e in Events)
33.93 {
33.94 - Event e = Events[key];
33.95 if (e.Actions.Remove(aAction))
33.96 {
33.97 //We removed our action, we are done here.
33.98 return;
33.99 }
33.100 -
33.101 }
33.102 }
33.103 -
33.104 }
33.105 }
33.106 \ No newline at end of file
34.1 --- a/SharpLibEar/SharpLibEar.csproj Sun Jul 31 12:03:52 2016 +0200
34.2 +++ b/SharpLibEar/SharpLibEar.csproj Fri Aug 12 20:25:05 2016 +0200
34.3 @@ -45,8 +45,8 @@
34.4 <Compile Include="ActionCallback.cs" />
34.5 <Compile Include="ActionSleep.cs" />
34.6 <Compile Include="ActionType.cs" />
34.7 - <Compile Include="AttributeAction.cs" />
34.8 - <Compile Include="AttributeActionProperty.cs" />
34.9 + <Compile Include="AttributeObject.cs" />
34.10 + <Compile Include="AttributeObjectProperty.cs" />
34.11 <Compile Include="Event.cs" />
34.12 <Compile Include="EventMonitorPowerOff.cs" />
34.13 <Compile Include="EventMonitorPowerOn.cs" />