Server/FormEditAction.cs
author StephaneLenclud
Thu, 28 Jul 2016 19:32:40 +0200
changeset 225 6ccaa430aa23
parent 224 471cb4c8a09a
child 227 4a03cc6f41b0
permissions -rw-r--r--
Adding support for Display Messages.
     1 using System;
     2 using System.Collections.Generic;
     3 using System.ComponentModel;
     4 using System.Data;
     5 using System.Diagnostics;
     6 using System.Drawing;
     7 using System.Linq;
     8 using System.Text;
     9 using System.Threading.Tasks;
    10 using System.Windows.Forms;
    11 using SharpLib.Display;
    12 using SharpLib.Ear;
    13 using System.Reflection;
    14 
    15 namespace SharpDisplayManager
    16 {
    17     /// <summary>
    18     /// Action edit dialog form.
    19     /// </summary>
    20     public partial class FormEditAction : Form
    21     {
    22         public SharpLib.Ear.Action Action = null;
    23 
    24         public FormEditAction()
    25         {
    26             InitializeComponent();
    27         }
    28 
    29         private void FormEditAction_Load(object sender, EventArgs e)
    30         {
    31             //Populate registered actions
    32             foreach (string key in ManagerEventAction.Current.ActionTypes.Keys)
    33             {
    34                 ItemActionType item = new ItemActionType(ManagerEventAction.Current.ActionTypes[key]);
    35                 comboBoxActionType.Items.Add(item);
    36             }
    37 
    38             comboBoxActionType.SelectedIndex = 0;
    39         }
    40 
    41         private void buttonOk_Click(object sender, EventArgs e)
    42         {
    43             FetchPropertiesValue(Action);
    44         }
    45 
    46         private void FormEditAction_Validating(object sender, CancelEventArgs e)
    47         {
    48 
    49         }
    50 
    51         private void comboBoxActionType_SelectedIndexChanged(object sender, EventArgs e)
    52         {
    53             //Instantiate an action corresponding to our type
    54             Action = (SharpLib.Ear.Action)Activator.CreateInstance(((ItemActionType)comboBoxActionType.SelectedItem).Type);
    55 
    56             //Create input fields
    57             UpdateTableLayoutPanel(Action);
    58         }
    59 
    60 
    61         /// <summary>
    62         /// Get properties values from our generated input fields
    63         /// </summary>
    64         private void FetchPropertiesValue(SharpLib.Ear.Action aAction)
    65         {
    66             int ctrlIndex = 0;
    67             foreach (PropertyInfo pi in aAction.GetType().GetProperties())
    68             {
    69                 AttributeActionProperty[] attributes =
    70                     ((AttributeActionProperty[]) pi.GetCustomAttributes(typeof(AttributeActionProperty), true));
    71                 if (attributes.Length != 1)
    72                 {
    73                     continue;
    74                 }
    75 
    76                 AttributeActionProperty attribute = attributes[0];
    77 
    78                 if (!IsPropertyTypeSupported(pi))
    79                 {
    80                     continue;
    81                 }
    82 
    83                 GetPropertyValueFromControl(iTableLayoutPanel.Controls[ctrlIndex+1], pi, aAction); //+1 otherwise we get the label
    84 
    85                 ctrlIndex+=2; //Jump over the label too
    86             }
    87         }
    88 
    89         /// <summary>
    90         /// Extend this function to support reading new types of properties.
    91         /// </summary>
    92         /// <param name="aAction"></param>
    93         private void GetPropertyValueFromControl(Control aControl, PropertyInfo aInfo, SharpLib.Ear.Action aAction)
    94         {
    95             if (aInfo.PropertyType == typeof(int))
    96             {
    97                 NumericUpDown ctrl=(NumericUpDown)aControl;
    98                 aInfo.SetValue(aAction,(int)ctrl.Value);
    99             }
   100             else if (aInfo.PropertyType.IsEnum)
   101             {
   102                 // Instantiate our enum
   103                 object enumValue= Activator.CreateInstance(aInfo.PropertyType);
   104                 // Parse our enum from combo box
   105                 enumValue = Enum.Parse(aInfo.PropertyType,((ComboBox)aControl).SelectedItem.ToString());
   106                 //enumValue = ((ComboBox)aControl).SelectedValue;
   107                 // Set enum value
   108                 aInfo.SetValue(aAction, enumValue);
   109             }
   110             else if (aInfo.PropertyType == typeof(bool))
   111             {
   112                 CheckBox ctrl = (CheckBox)aControl;
   113                 aInfo.SetValue(aAction, ctrl.Checked);
   114             }
   115             else if (aInfo.PropertyType == typeof(string))
   116             {
   117                 TextBox ctrl = (TextBox)aControl;
   118                 aInfo.SetValue(aAction, ctrl.Text);
   119             }
   120             //TODO: add support for other types here
   121         }
   122 
   123         /// <summary>
   124         /// 
   125         /// </summary>
   126         /// <param name="aInfo"></param>
   127         /// <param name="action"></param>
   128         private Control CreateControlForProperty(PropertyInfo aInfo, AttributeActionProperty aAttribute, SharpLib.Ear.Action aAction)
   129         {
   130             if (aInfo.PropertyType == typeof(int))
   131             {
   132                 //Integer properties are using numeric editor
   133                 NumericUpDown ctrl = new NumericUpDown();
   134                 ctrl.AutoSize = true;
   135                 ctrl.Minimum = Int32.Parse(aAttribute.Minimum);
   136                 ctrl.Maximum = Int32.Parse(aAttribute.Maximum);
   137                 ctrl.Increment = Int32.Parse(aAttribute.Increment);
   138                 ctrl.Value = (int)aInfo.GetValue(aAction);
   139                 return ctrl;
   140             }
   141             else if (aInfo.PropertyType.IsEnum)
   142             {
   143                 //Enum properties are using combo box
   144                 ComboBox ctrl = new ComboBox();
   145                 ctrl.AutoSize = true;                
   146                 ctrl.Sorted = true;                
   147                 ctrl.DropDownStyle = ComboBoxStyle.DropDownList;
   148                 //Data source is fine but it gives us duplicate entries for duplicated enum values
   149                 //ctrl.DataSource = Enum.GetValues(aInfo.PropertyType);
   150 
   151                 //Therefore we need to explicitly create our items
   152                 Size cbSize = new Size(0,0);
   153                 foreach (string name in aInfo.PropertyType.GetEnumNames())
   154                 {
   155                     ctrl.Items.Add(name.ToString());
   156                     Graphics g = this.CreateGraphics();
   157                     //Since combobox autosize would not work we need to get measure text ourselves
   158                     SizeF size=g.MeasureString(name.ToString(), ctrl.Font);
   159                     cbSize.Width = Math.Max(cbSize.Width,(int)size.Width);
   160                     cbSize.Height = Math.Max(cbSize.Height, (int)size.Height);
   161                 }
   162 
   163                 //Make sure our combobox is large enough
   164                 ctrl.MinimumSize = cbSize;
   165 
   166                 // Instantiate our enum
   167                 object enumValue = Activator.CreateInstance(aInfo.PropertyType);
   168                 enumValue = aInfo.GetValue(aAction);
   169                 //Set the current item
   170                 ctrl.SelectedItem = enumValue.ToString();
   171 
   172                 return ctrl;
   173             }
   174             else if (aInfo.PropertyType == typeof(bool))
   175             {
   176                 CheckBox ctrl = new CheckBox();
   177                 ctrl.AutoSize = true;
   178                 ctrl.Text = aAttribute.Description;
   179                 ctrl.Checked = (bool)aInfo.GetValue(aAction);                
   180                 return ctrl;
   181             }
   182             else if (aInfo.PropertyType == typeof(string))
   183             {
   184                 TextBox ctrl = new TextBox();
   185                 ctrl.AutoSize = true;
   186                 ctrl.Text = (string)aInfo.GetValue(aAction);
   187                 return ctrl;
   188             }
   189             //TODO: add support for other control type here
   190 
   191             return null;
   192         }
   193 
   194         /// <summary>
   195         /// Don't forget to extend that one and adding types
   196         /// </summary>
   197         /// <returns></returns>
   198         private bool IsPropertyTypeSupported(PropertyInfo aInfo)
   199         {
   200             if (aInfo.PropertyType == typeof(int))
   201             {
   202                 return true;
   203             }
   204             else if (aInfo.PropertyType.IsEnum)
   205             {
   206                 return true;
   207             }
   208             else if (aInfo.PropertyType == typeof(bool))
   209             {
   210                 return true;
   211             }
   212             else if (aInfo.PropertyType == typeof(string))
   213             {
   214                 return true;
   215             }
   216             //TODO: add support for other type here
   217 
   218             return false;
   219         }
   220 
   221         /// <summary>
   222         /// Update our table layout.
   223         /// Will instantiated every field control as defined by our action.
   224         /// Fields must be specified by rows from the left.
   225         /// </summary>
   226         /// <param name="aLayout"></param>
   227         private void UpdateTableLayoutPanel(SharpLib.Ear.Action aAction)
   228         {
   229             toolTip.RemoveAll();
   230             //Debug.Print("UpdateTableLayoutPanel")
   231             //First clean our current panel
   232             iTableLayoutPanel.Controls.Clear();
   233             iTableLayoutPanel.RowStyles.Clear();
   234             iTableLayoutPanel.ColumnStyles.Clear();
   235             iTableLayoutPanel.RowCount = 0;
   236 
   237             //We always want two columns: one for label and one for the field
   238             iTableLayoutPanel.ColumnCount = 2;
   239             iTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
   240             iTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
   241 
   242 
   243             if (aAction == null)
   244             {
   245                 //Just drop it
   246                 return;
   247             }
   248             
   249             //IEnumerable<PropertyInfo> properties = aAction.GetType().GetProperties().Where(
   250             //    prop => Attribute.IsDefined(prop, typeof(AttributeActionProperty)));
   251 
   252 
   253             foreach (PropertyInfo pi in aAction.GetType().GetProperties())
   254             {
   255                 AttributeActionProperty[] attributes = ((AttributeActionProperty[])pi.GetCustomAttributes(typeof(AttributeActionProperty), true));
   256                 if (attributes.Length != 1)
   257                 {
   258                     continue;
   259                 }
   260 
   261                 AttributeActionProperty attribute = attributes[0];
   262 
   263                 //Before anything we need to check if that kind of property is supported by our UI
   264                 //Create the editor
   265                 Control ctrl = CreateControlForProperty(pi, attribute, aAction);
   266                 if (ctrl == null)
   267                 {
   268                     //Property type not supported
   269                     continue;
   270                 }
   271 
   272                 //Add a new row
   273                 iTableLayoutPanel.RowCount++;
   274                 iTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
   275                 //Create the label
   276                 Label label = new Label();
   277                 label.AutoSize = true;
   278                 label.Dock = DockStyle.Fill;
   279                 label.TextAlign = ContentAlignment.MiddleCenter;
   280                 label.Text = attribute.Name;
   281                 toolTip.SetToolTip(label, attribute.Description);
   282                 iTableLayoutPanel.Controls.Add(label, 0, iTableLayoutPanel.RowCount-1);
   283 
   284                 //Add our editor to our form
   285                 iTableLayoutPanel.Controls.Add(ctrl, 1, iTableLayoutPanel.RowCount - 1);
   286                 //Add tooltip to editor too
   287                 toolTip.SetToolTip(ctrl, attribute.Description);
   288 
   289             }        
   290 
   291         }
   292 
   293     }
   294 }