Basis for action property edition support.
authorStephaneLenclud
Tue, 26 Jul 2016 11:51:50 +0200
changeset 21999c407831232
parent 218 c466f72a834f
child 220 e5910d7b6a81
Basis for action property edition support.
Server/FormEditAction.Designer.cs
Server/FormEditAction.cs
Server/FormEditAction.resx
Server/ItemActionType.cs
Server/MainForm.cs
Server/SharpDisplayManager.csproj
SharpLibEar/ActionSleep.cs
SharpLibEar/AttributeAction.cs
SharpLibEar/AttributeActionProperty.cs
SharpLibEar/SharpLibEar.csproj
     1.1 --- a/Server/FormEditAction.Designer.cs	Mon Jul 25 17:48:12 2016 +0200
     1.2 +++ b/Server/FormEditAction.Designer.cs	Tue Jul 26 11:51:50 2016 +0200
     1.3 @@ -28,10 +28,13 @@
     1.4          /// </summary>
     1.5          private void InitializeComponent()
     1.6          {
     1.7 +            this.components = new System.ComponentModel.Container();
     1.8              this.comboBoxActionType = new System.Windows.Forms.ComboBox();
     1.9              this.labelActionType = new System.Windows.Forms.Label();
    1.10              this.buttonOk = new System.Windows.Forms.Button();
    1.11              this.buttonCancel = new System.Windows.Forms.Button();
    1.12 +            this.iTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
    1.13 +            this.toolTip = new System.Windows.Forms.ToolTip(this.components);
    1.14              this.SuspendLayout();
    1.15              // 
    1.16              // comboBoxActionType
    1.17 @@ -42,6 +45,7 @@
    1.18              this.comboBoxActionType.Name = "comboBoxActionType";
    1.19              this.comboBoxActionType.Size = new System.Drawing.Size(333, 21);
    1.20              this.comboBoxActionType.TabIndex = 18;
    1.21 +            this.comboBoxActionType.SelectedIndexChanged += new System.EventHandler(this.comboBoxActionType_SelectedIndexChanged);
    1.22              // 
    1.23              // labelActionType
    1.24              // 
    1.25 @@ -54,8 +58,9 @@
    1.26              // 
    1.27              // buttonOk
    1.28              // 
    1.29 +            this.buttonOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
    1.30              this.buttonOk.DialogResult = System.Windows.Forms.DialogResult.OK;
    1.31 -            this.buttonOk.Location = new System.Drawing.Point(12, 55);
    1.32 +            this.buttonOk.Location = new System.Drawing.Point(12, 347);
    1.33              this.buttonOk.Name = "buttonOk";
    1.34              this.buttonOk.Size = new System.Drawing.Size(75, 23);
    1.35              this.buttonOk.TabIndex = 21;
    1.36 @@ -65,19 +70,36 @@
    1.37              // 
    1.38              // buttonCancel
    1.39              // 
    1.40 +            this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
    1.41              this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
    1.42 -            this.buttonCancel.Location = new System.Drawing.Point(93, 55);
    1.43 +            this.buttonCancel.Location = new System.Drawing.Point(93, 347);
    1.44              this.buttonCancel.Name = "buttonCancel";
    1.45              this.buttonCancel.Size = new System.Drawing.Size(75, 23);
    1.46              this.buttonCancel.TabIndex = 22;
    1.47              this.buttonCancel.Text = "Cancel";
    1.48              this.buttonCancel.UseVisualStyleBackColor = true;
    1.49              // 
    1.50 +            // iTableLayoutPanel
    1.51 +            // 
    1.52 +            this.iTableLayoutPanel.ColumnCount = 2;
    1.53 +            this.iTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
    1.54 +            this.iTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
    1.55 +            this.iTableLayoutPanel.Location = new System.Drawing.Point(15, 50);
    1.56 +            this.iTableLayoutPanel.Name = "iTableLayoutPanel";
    1.57 +            this.iTableLayoutPanel.RowCount = 2;
    1.58 +            this.iTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
    1.59 +            this.iTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
    1.60 +            this.iTableLayoutPanel.Size = new System.Drawing.Size(373, 114);
    1.61 +            this.iTableLayoutPanel.TabIndex = 23;
    1.62 +            // 
    1.63              // FormEditAction
    1.64              // 
    1.65 +            this.AcceptButton = this.buttonOk;
    1.66              this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
    1.67              this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
    1.68 -            this.ClientSize = new System.Drawing.Size(400, 86);
    1.69 +            this.CancelButton = this.buttonCancel;
    1.70 +            this.ClientSize = new System.Drawing.Size(400, 382);
    1.71 +            this.Controls.Add(this.iTableLayoutPanel);
    1.72              this.Controls.Add(this.buttonCancel);
    1.73              this.Controls.Add(this.buttonOk);
    1.74              this.Controls.Add(this.labelActionType);
    1.75 @@ -100,5 +122,7 @@
    1.76          private System.Windows.Forms.Label labelActionType;
    1.77          private System.Windows.Forms.Button buttonOk;
    1.78          private System.Windows.Forms.Button buttonCancel;
    1.79 +        private System.Windows.Forms.TableLayoutPanel iTableLayoutPanel;
    1.80 +        private System.Windows.Forms.ToolTip toolTip;
    1.81      }
    1.82  }
    1.83 \ No newline at end of file
     2.1 --- a/Server/FormEditAction.cs	Mon Jul 25 17:48:12 2016 +0200
     2.2 +++ b/Server/FormEditAction.cs	Tue Jul 26 11:51:50 2016 +0200
     2.3 @@ -2,38 +2,19 @@
     2.4  using System.Collections.Generic;
     2.5  using System.ComponentModel;
     2.6  using System.Data;
     2.7 +using System.Diagnostics;
     2.8  using System.Drawing;
     2.9  using System.Linq;
    2.10  using System.Text;
    2.11  using System.Threading.Tasks;
    2.12  using System.Windows.Forms;
    2.13 +using SharpLib.Display;
    2.14  using SharpLib.Ear;
    2.15 +using System.Reflection;
    2.16  
    2.17  namespace SharpDisplayManager
    2.18  {
    2.19      /// <summary>
    2.20 -    /// Used to populate our action type combobox with friendly names
    2.21 -    /// </summary>
    2.22 -    class ItemActionType
    2.23 -    {
    2.24 -        public Type Type;
    2.25 -
    2.26 -        public ItemActionType(Type type)
    2.27 -        {
    2.28 -            this.Type = type;
    2.29 -        }
    2.30 -
    2.31 -        public override string ToString()
    2.32 -        {
    2.33 -            //Get friendly action name from action attribute.
    2.34 -            //That we then show up in our combobox
    2.35 -            return SharpLib.Utils.Reflection.GetAttribute<AttributeAction>(Type).Name;
    2.36 -        }
    2.37 -    }
    2.38 -
    2.39 -
    2.40 -
    2.41 -    /// <summary>
    2.42      /// Action edit dialog form.
    2.43      /// </summary>
    2.44      public partial class FormEditAction : Form
    2.45 @@ -59,12 +40,136 @@
    2.46  
    2.47          private void buttonOk_Click(object sender, EventArgs e)
    2.48          {
    2.49 -            Action = (SharpLib.Ear.Action)Activator.CreateInstance(((ItemActionType)comboBoxActionType.SelectedItem).Type);
    2.50 +            
    2.51          }
    2.52  
    2.53          private void FormEditAction_Validating(object sender, CancelEventArgs e)
    2.54          {
    2.55  
    2.56          }
    2.57 +
    2.58 +        private void comboBoxActionType_SelectedIndexChanged(object sender, EventArgs e)
    2.59 +        {
    2.60 +            //Instantiate an action corresponding to our type
    2.61 +            Action = (SharpLib.Ear.Action)Activator.CreateInstance(((ItemActionType)comboBoxActionType.SelectedItem).Type);
    2.62 +
    2.63 +            //Create input fields
    2.64 +            UpdateTableLayoutPanel(Action);
    2.65 +        }
    2.66 +
    2.67 +        /// <summary>
    2.68 +        /// Update our table layout.
    2.69 +        /// Will instantiated every field control as defined by our action.
    2.70 +        /// Fields must be specified by rows from the left.
    2.71 +        /// </summary>
    2.72 +        /// <param name="aLayout"></param>
    2.73 +        private void UpdateTableLayoutPanel(SharpLib.Ear.Action aAction)
    2.74 +        {
    2.75 +            toolTip.RemoveAll();
    2.76 +            //Debug.Print("UpdateTableLayoutPanel")
    2.77 +            //First clean our current panel
    2.78 +            iTableLayoutPanel.Controls.Clear();
    2.79 +            iTableLayoutPanel.RowStyles.Clear();
    2.80 +            iTableLayoutPanel.ColumnStyles.Clear();
    2.81 +            iTableLayoutPanel.RowCount = 0;
    2.82 +
    2.83 +            //We always want two columns: one for label and one for the field
    2.84 +            iTableLayoutPanel.ColumnCount = 2;
    2.85 +            iTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
    2.86 +            iTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
    2.87 +
    2.88 +
    2.89 +            if (aAction == null)
    2.90 +            {
    2.91 +                //Just drop it
    2.92 +                return;
    2.93 +            }
    2.94 +            
    2.95 +            //IEnumerable<PropertyInfo> properties = aAction.GetType().GetProperties().Where(
    2.96 +            //    prop => Attribute.IsDefined(prop, typeof(AttributeActionProperty)));
    2.97 +
    2.98 +
    2.99 +            foreach (PropertyInfo pi in aAction.GetType().GetProperties())
   2.100 +            {
   2.101 +                AttributeActionProperty[] attributes = ((AttributeActionProperty[])pi.GetCustomAttributes(typeof(AttributeActionProperty), true));
   2.102 +                if (attributes.Length != 1)
   2.103 +                {
   2.104 +                    continue;
   2.105 +                }
   2.106 +
   2.107 +                AttributeActionProperty attribute = attributes[0];
   2.108 +                //Add a new row
   2.109 +                iTableLayoutPanel.RowCount++;
   2.110 +                iTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
   2.111 +                //Create the label
   2.112 +                Label label = new Label();
   2.113 +                label.Text = attribute.Name;
   2.114 +                toolTip.SetToolTip(label, attribute.Description);
   2.115 +                iTableLayoutPanel.Controls.Add(label, 0, iTableLayoutPanel.RowCount-1);
   2.116 +
   2.117 +
   2.118 +                //Create the editor
   2.119 +
   2.120 +            }
   2.121 +
   2.122 +
   2.123 +            /*
   2.124 +            //Then recreate our rows...
   2.125 +            while (iTableLayoutPanel.RowCount < layout.Rows.Count)
   2.126 +            {
   2.127 +                iTableLayoutPanel.RowCount++;
   2.128 +            }
   2.129 +
   2.130 +            // ...and columns 
   2.131 +            while (iTableLayoutPanel.ColumnCount < layout.Columns.Count)
   2.132 +            {
   2.133 +                iTableLayoutPanel.ColumnCount++;
   2.134 +            }
   2.135 +
   2.136 +            //For each column
   2.137 +            for (int i = 0; i < iTableLayoutPanel.ColumnCount; i++)
   2.138 +            {
   2.139 +                //Create our column styles
   2.140 +                this.iTableLayoutPanel.ColumnStyles.Add(layout.Columns[i]);
   2.141 +
   2.142 +                //For each rows
   2.143 +                for (int j = 0; j < iTableLayoutPanel.RowCount; j++)
   2.144 +                {
   2.145 +                    if (i == 0)
   2.146 +                    {
   2.147 +                        //Create our row styles
   2.148 +                        this.iTableLayoutPanel.RowStyles.Add(layout.Rows[j]);
   2.149 +                    }
   2.150 +                    else
   2.151 +                    {
   2.152 +                        continue;
   2.153 +                    }
   2.154 +                }
   2.155 +            }
   2.156 +
   2.157 +            //For each field
   2.158 +            foreach (DataField field in aClient.Fields)
   2.159 +            {
   2.160 +                if (!field.IsTableField)
   2.161 +                {
   2.162 +                    //That field is not taking part in our table layout skip it
   2.163 +                    continue;
   2.164 +                }
   2.165 +
   2.166 +                TableField tableField = (TableField)field;
   2.167 +
   2.168 +                //Create a control corresponding to the field specified for that cell
   2.169 +                Control control = CreateControlForDataField(tableField);
   2.170 +
   2.171 +                //Add newly created control to our table layout at the specified row and column
   2.172 +                iTableLayoutPanel.Controls.Add(control, tableField.Column, tableField.Row);
   2.173 +                //Make sure we specify column and row span for that new control
   2.174 +                iTableLayoutPanel.SetColumnSpan(control, tableField.ColumnSpan);
   2.175 +                iTableLayoutPanel.SetRowSpan(control, tableField.RowSpan);
   2.176 +            }
   2.177 +            */
   2.178 +
   2.179 +        }
   2.180 +
   2.181      }
   2.182  }
     3.1 --- a/Server/FormEditAction.resx	Mon Jul 25 17:48:12 2016 +0200
     3.2 +++ b/Server/FormEditAction.resx	Tue Jul 26 11:51:50 2016 +0200
     3.3 @@ -117,4 +117,7 @@
     3.4    <resheader name="writer">
     3.5      <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
     3.6    </resheader>
     3.7 +  <metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     3.8 +    <value>17, 17</value>
     3.9 +  </metadata>
    3.10  </root>
    3.11 \ No newline at end of file
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/Server/ItemActionType.cs	Tue Jul 26 11:51:50 2016 +0200
     4.3 @@ -0,0 +1,29 @@
     4.4 +using SharpLib.Ear;
     4.5 +using System;
     4.6 +using System.Collections.Generic;
     4.7 +using System.Linq;
     4.8 +using System.Text;
     4.9 +using System.Threading.Tasks;
    4.10 +
    4.11 +namespace SharpDisplayManager
    4.12 +{
    4.13 +    /// <summary>
    4.14 +    /// Used to populate our action type combobox with friendly names
    4.15 +    /// </summary>
    4.16 +    class ItemActionType
    4.17 +    {
    4.18 +        public Type Type;
    4.19 +
    4.20 +        public ItemActionType(Type type)
    4.21 +        {
    4.22 +            this.Type = type;
    4.23 +        }
    4.24 +
    4.25 +        public override string ToString()
    4.26 +        {
    4.27 +            //Get friendly action name from action attribute.
    4.28 +            //That we then show up in our combobox
    4.29 +            return SharpLib.Utils.Reflection.GetAttribute<AttributeAction>(Type).Name;
    4.30 +        }
    4.31 +    }
    4.32 +}
     5.1 --- a/Server/MainForm.cs	Mon Jul 25 17:48:12 2016 +0200
     5.2 +++ b/Server/MainForm.cs	Tue Jul 26 11:51:50 2016 +0200
     5.3 @@ -223,7 +223,7 @@
     5.4              ResetCec();
     5.5  
     5.6              //Setup Events
     5.7 -            SetupEvents();
     5.8 +            PopulateEventsTreeView();
     5.9  
    5.10              //Setup notification icon
    5.11              SetupTrayIcon();
    5.12 @@ -302,7 +302,7 @@
    5.13          /// <summary>
    5.14          /// Populate tree view with events and actions
    5.15          /// </summary>
    5.16 -        private void SetupEvents()
    5.17 +        private void PopulateEventsTreeView()
    5.18          {
    5.19              //Disable action buttons
    5.20              buttonAddAction.Enabled = false;
    5.21 @@ -331,6 +331,11 @@
    5.22  
    5.23              iTreeViewEvents.ExpandAll();
    5.24              SelectEvent(currentEvent);
    5.25 +            //Select the last action if any 
    5.26 +            if (iTreeViewEvents.SelectedNode!= null && iTreeViewEvents.SelectedNode.Nodes[1].GetNodeCount(false) > 0)
    5.27 +            {
    5.28 +                iTreeViewEvents.SelectedNode = iTreeViewEvents.SelectedNode.Nodes[1].Nodes[iTreeViewEvents.SelectedNode.Nodes[1].GetNodeCount(false)-1];
    5.29 +            }
    5.30  
    5.31          }
    5.32  
    5.33 @@ -2666,8 +2671,10 @@
    5.34              }
    5.35          }
    5.36  
    5.37 +
    5.38 +
    5.39          /// <summary>
    5.40 -        /// 
    5.41 +        /// Get the current event based on event tree view selection.
    5.42          /// </summary>
    5.43          /// <returns></returns>
    5.44          private Event CurrentEvent()
    5.45 @@ -2689,7 +2696,7 @@
    5.46          }
    5.47  
    5.48          /// <summary>
    5.49 -        /// 
    5.50 +        /// Get the current action based on event tree view selection
    5.51          /// </summary>
    5.52          /// <returns></returns>
    5.53          private SharpLib.Ear.Action CurrentAction()
    5.54 @@ -2724,7 +2731,7 @@
    5.55                  selectedEvent.Actions.Add(ea.Action);                
    5.56                  Properties.Settings.Default.Actions = ManagerEventAction.Current;
    5.57                  Properties.Settings.Default.Save();
    5.58 -                SetupEvents();
    5.59 +                PopulateEventsTreeView();
    5.60              }
    5.61          }
    5.62  
    5.63 @@ -2746,7 +2753,7 @@
    5.64              ManagerEventAction.Current.RemoveAction(action);
    5.65              Properties.Settings.Default.Actions = ManagerEventAction.Current;
    5.66              Properties.Settings.Default.Save();
    5.67 -            SetupEvents();
    5.68 +            PopulateEventsTreeView();
    5.69          }
    5.70  
    5.71          private void iTreeViewEvents_AfterSelect(object sender, TreeViewEventArgs e)
     6.1 --- a/Server/SharpDisplayManager.csproj	Mon Jul 25 17:48:12 2016 +0200
     6.2 +++ b/Server/SharpDisplayManager.csproj	Tue Jul 26 11:51:50 2016 +0200
     6.3 @@ -166,7 +166,9 @@
     6.4      <Compile Include="CecClient.cs" />
     6.5      <Compile Include="ConsumerElectronicControl.cs" />
     6.6      <Compile Include="ClientData.cs" />
     6.7 -    <Compile Include="FormEditAction.cs" />
     6.8 +    <Compile Include="FormEditAction.cs">
     6.9 +      <SubType>Form</SubType>
    6.10 +    </Compile>
    6.11      <Compile Include="FormEditAction.Designer.cs">
    6.12        <DependentUpon>FormEditAction.cs</DependentUpon>
    6.13      </Compile>
    6.14 @@ -176,6 +178,7 @@
    6.15      <Compile Include="FxControl.Designer.cs">
    6.16        <DependentUpon>FxControl.cs</DependentUpon>
    6.17      </Compile>
    6.18 +    <Compile Include="ItemActionType.cs" />
    6.19      <Compile Include="MainForm.Hid.cs">
    6.20        <DependentUpon>MainForm.cs</DependentUpon>
    6.21      </Compile>
     7.1 --- a/SharpLibEar/ActionSleep.cs	Mon Jul 25 17:48:12 2016 +0200
     7.2 +++ b/SharpLibEar/ActionSleep.cs	Tue Jul 26 11:51:50 2016 +0200
     7.3 @@ -14,22 +14,24 @@
     7.4      public class ActionSleep : Action
     7.5      {
     7.6          [DataMember]
     7.7 -        private readonly int iMillisecondsTimeout;
     7.8 +        [AttributeActionProperty(Id = "Thread.Sleep.Timeout", Name = "Timeout",
     7.9 +            Description = "Specifies the number of milliseconds this action will sleep for.")]
    7.10 +        public int TimeoutInMilliseconds { get; set; }
    7.11  
    7.12          public ActionSleep()
    7.13          {
    7.14 -            iMillisecondsTimeout = 1000;
    7.15 +            TimeoutInMilliseconds = 1000;
    7.16          }
    7.17  
    7.18  
    7.19          public ActionSleep(int aMillisecondsTimeout)
    7.20          {
    7.21 -            iMillisecondsTimeout = aMillisecondsTimeout;
    7.22 +            TimeoutInMilliseconds = aMillisecondsTimeout;
    7.23          }
    7.24  
    7.25          public override void Execute()
    7.26          {
    7.27 -            Thread.Sleep(iMillisecondsTimeout);
    7.28 +            Thread.Sleep(TimeoutInMilliseconds);
    7.29          }
    7.30  
    7.31      }
     8.1 --- a/SharpLibEar/AttributeAction.cs	Mon Jul 25 17:48:12 2016 +0200
     8.2 +++ b/SharpLibEar/AttributeAction.cs	Tue Jul 26 11:51:50 2016 +0200
     8.3 @@ -7,7 +7,9 @@
     8.4  namespace SharpLib.Ear
     8.5  {
     8.6  
     8.7 -    // Multiuse attribute.
     8.8 +    /// <summary>
     8.9 +    /// For action class to define name and description.
    8.10 +    /// </summary>
    8.11      [System.AttributeUsage(System.AttributeTargets.Class)]
    8.12      public class AttributeAction : System.Attribute
    8.13      {
    8.14 @@ -16,4 +18,5 @@
    8.15          public string Description;
    8.16      }
    8.17  
    8.18 +
    8.19  }
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/SharpLibEar/AttributeActionProperty.cs	Tue Jul 26 11:51:50 2016 +0200
     9.3 @@ -0,0 +1,19 @@
     9.4 +using System;
     9.5 +using System.Collections.Generic;
     9.6 +using System.Linq;
     9.7 +using System.Text;
     9.8 +using System.Threading.Tasks;
     9.9 +
    9.10 +namespace SharpLib.Ear
    9.11 +{
    9.12 +    /// <summary>
    9.13 +    /// To expose an action property thus enabling user to edit it.
    9.14 +    /// </summary>
    9.15 +    [System.AttributeUsage(System.AttributeTargets.Property)]
    9.16 +    public class AttributeActionProperty : System.Attribute
    9.17 +    {
    9.18 +        public string Id;
    9.19 +        public string Name;
    9.20 +        public string Description;
    9.21 +    }
    9.22 +}
    10.1 --- a/SharpLibEar/SharpLibEar.csproj	Mon Jul 25 17:48:12 2016 +0200
    10.2 +++ b/SharpLibEar/SharpLibEar.csproj	Tue Jul 26 11:51:50 2016 +0200
    10.3 @@ -46,6 +46,7 @@
    10.4      <Compile Include="ActionSleep.cs" />
    10.5      <Compile Include="ActionType.cs" />
    10.6      <Compile Include="AttributeAction.cs" />
    10.7 +    <Compile Include="AttributeActionProperty.cs" />
    10.8      <Compile Include="Event.cs" />
    10.9      <Compile Include="EventMonitorPowerOff.cs" />
   10.10      <Compile Include="EventMonitorPowerOn.cs" />