1.1 --- a/Client/Client.cs Sat Dec 27 21:50:15 2014 +0100
1.2 +++ b/Client/Client.cs Sat Dec 27 21:52:14 2014 +0100
1.3 @@ -96,14 +96,16 @@
1.4
1.5
1.6 /// <summary>
1.7 - ///
1.8 + /// Handle connection with our Sharp Display Server.
1.9 + /// If the connection is faulted it will attempt to restart it.
1.10 /// </summary>
1.11 public class DisplayClient
1.12 {
1.13 - Client iClient;
1.14 - Callback iCallback;
1.15 + private Client iClient;
1.16 + private Callback iCallback;
1.17 + private bool resetingConnection = false;
1.18 +
1.19 private MainForm MainForm { get; set; }
1.20 -
1.21 public string SessionId { get { return iClient.SessionId; } }
1.22 public string Name { get; private set; }
1.23 private TableLayout Layout { get; set; }
1.24 @@ -117,12 +119,18 @@
1.25 Fields = new DataField[]{};
1.26 }
1.27
1.28 + /// <summary>
1.29 + /// Initialize our server connection.
1.30 + /// </summary>
1.31 public void Open()
1.32 {
1.33 iCallback = new Callback(MainForm);
1.34 iClient = new Client(iCallback);
1.35 }
1.36
1.37 + /// <summary>
1.38 + /// Terminate our server connection.
1.39 + /// </summary>
1.40 public void Close()
1.41 {
1.42 iClient.Close();
1.43 @@ -131,26 +139,45 @@
1.44 iCallback = null;
1.45 }
1.46
1.47 + /// <summary>
1.48 + /// Tells whether a server connection is available.
1.49 + /// </summary>
1.50 + /// <returns>True if a server connection is available. False otherwise.</returns>
1.51 public bool IsReady()
1.52 {
1.53 return (iClient != null && iCallback != null && iClient.IsReady());
1.54 }
1.55
1.56 + /// <summary>
1.57 + /// Check if our server connection is available and attempt reset it if it isn't.
1.58 + /// This is notably dealing with timed out connections.
1.59 + /// </summary>
1.60 public void CheckConnection()
1.61 {
1.62 - if (!IsReady())
1.63 + if (!IsReady() && !resetingConnection)
1.64 {
1.65 //Try to reconnect
1.66 Open();
1.67
1.68 - //On reconnect there is a bunch of properties we need to set
1.69 - if (Name != "")
1.70 + //Avoid stack overflow in case of persisting failure
1.71 + resetingConnection = true;
1.72 +
1.73 + try
1.74 {
1.75 - iClient.SetName(Name);
1.76 + //On reconnect there is a bunch of properties we need to reset
1.77 + if (Name != "")
1.78 + {
1.79 + iClient.SetName(Name);
1.80 + }
1.81 +
1.82 + SetLayout(Layout);
1.83 + iClient.SetFields(Fields);
1.84 }
1.85 -
1.86 - SetLayout(Layout);
1.87 - SetFields(Fields);
1.88 + finally
1.89 + {
1.90 + //Make sure our this state does not get out of sync
1.91 + resetingConnection = true;
1.92 + }
1.93 }
1.94 }
1.95
1.96 @@ -169,34 +196,85 @@
1.97 iClient.SetLayout(aLayout);
1.98 }
1.99
1.100 -
1.101 - public void SetField(DataField aField)
1.102 + /// <summary>
1.103 + /// Set the specified field.
1.104 + /// </summary>
1.105 + /// <param name="aField"></param>
1.106 + /// <returns>True if the specified field was set client side. False means you need to redefine all your fields using CreateFields.</returns>
1.107 + public bool SetField(DataField aField)
1.108 {
1.109 - //TODO: Create fields if not present
1.110 int i = 0;
1.111 + bool fieldFound = false;
1.112 foreach (DataField field in Fields)
1.113 {
1.114 if (field.Index == aField.Index)
1.115 {
1.116 //Update our field then
1.117 Fields[i] = aField;
1.118 + fieldFound = true;
1.119 break;
1.120 }
1.121 i++;
1.122 }
1.123
1.124 + if (!fieldFound)
1.125 + {
1.126 + //Field not found, make to use SetFields with all your fields at least once after setting your layout.
1.127 + return false;
1.128 + }
1.129 +
1.130 CheckConnection();
1.131 iClient.SetField(aField);
1.132 + return true;
1.133 }
1.134
1.135 - public void SetFields(System.Collections.Generic.IList<DataField> aFields)
1.136 + /// <summary>
1.137 + /// Use this function when updating existing fields.
1.138 + /// </summary>
1.139 + /// <param name="aFields"></param>
1.140 + public bool SetFields(System.Collections.Generic.IList<DataField> aFields)
1.141 + {
1.142 + int fieldFoundCount = 0;
1.143 + foreach (DataField fieldUpdate in aFields)
1.144 + {
1.145 + int i = 0;
1.146 + foreach (DataField existingField in Fields)
1.147 + {
1.148 + if (existingField.Index == fieldUpdate.Index)
1.149 + {
1.150 + //Update our field then
1.151 + Fields[i] = fieldUpdate;
1.152 + fieldFoundCount++;
1.153 + //Move on to the next field
1.154 + break;
1.155 + }
1.156 + i++;
1.157 + }
1.158 + }
1.159 +
1.160 + //
1.161 + if (fieldFoundCount!=aFields.Count)
1.162 + {
1.163 + //Field not found, make sure to use SetFields with all your fields at least once after setting your layout.
1.164 + return false;
1.165 + }
1.166 +
1.167 + CheckConnection();
1.168 + iClient.SetFields(aFields);
1.169 + return true;
1.170 + }
1.171 +
1.172 + /// <summary>
1.173 + /// Use this function when creating your fields.
1.174 + /// </summary>
1.175 + /// <param name="aFields"></param>
1.176 + public void CreateFields(System.Collections.Generic.IList<DataField> aFields)
1.177 {
1.178 Fields = aFields;
1.179 CheckConnection();
1.180 iClient.SetFields(aFields);
1.181 }
1.182
1.183 -
1.184 public int ClientCount()
1.185 {
1.186 CheckConnection();
2.1 --- a/Client/MainForm.Designer.cs Sat Dec 27 21:50:15 2014 +0100
2.2 +++ b/Client/MainForm.Designer.cs Sat Dec 27 21:52:14 2014 +0100
2.3 @@ -38,6 +38,8 @@
2.4 this.buttonLayoutUpdate = new System.Windows.Forms.Button();
2.5 this.buttonSetBitmap = new System.Windows.Forms.Button();
2.6 this.buttonBitmapLayout = new System.Windows.Forms.Button();
2.7 + this.buttonIndicatorsLayout = new System.Windows.Forms.Button();
2.8 + this.buttonUpdateTexts = new System.Windows.Forms.Button();
2.9 this.SuspendLayout();
2.10 //
2.11 // buttonSetText
2.12 @@ -134,11 +136,33 @@
2.13 this.buttonBitmapLayout.UseVisualStyleBackColor = true;
2.14 this.buttonBitmapLayout.Click += new System.EventHandler(this.buttonBitmapLayout_Click);
2.15 //
2.16 + // buttonIndicatorsLayout
2.17 + //
2.18 + this.buttonIndicatorsLayout.Location = new System.Drawing.Point(94, 189);
2.19 + this.buttonIndicatorsLayout.Name = "buttonIndicatorsLayout";
2.20 + this.buttonIndicatorsLayout.Size = new System.Drawing.Size(75, 35);
2.21 + this.buttonIndicatorsLayout.TabIndex = 28;
2.22 + this.buttonIndicatorsLayout.Text = "Indicators Layout ";
2.23 + this.buttonIndicatorsLayout.UseVisualStyleBackColor = true;
2.24 + this.buttonIndicatorsLayout.Click += new System.EventHandler(this.buttonIndicatorsLayout_Click);
2.25 + //
2.26 + // buttonUpdateTexts
2.27 + //
2.28 + this.buttonUpdateTexts.Location = new System.Drawing.Point(257, 189);
2.29 + this.buttonUpdateTexts.Name = "buttonUpdateTexts";
2.30 + this.buttonUpdateTexts.Size = new System.Drawing.Size(75, 35);
2.31 + this.buttonUpdateTexts.TabIndex = 29;
2.32 + this.buttonUpdateTexts.Text = "Update Texts";
2.33 + this.buttonUpdateTexts.UseVisualStyleBackColor = true;
2.34 + this.buttonUpdateTexts.Click += new System.EventHandler(this.buttonUpdateTexts_Click);
2.35 + //
2.36 // MainForm
2.37 //
2.38 this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
2.39 this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
2.40 this.ClientSize = new System.Drawing.Size(443, 252);
2.41 + this.Controls.Add(this.buttonUpdateTexts);
2.42 + this.Controls.Add(this.buttonIndicatorsLayout);
2.43 this.Controls.Add(this.buttonBitmapLayout);
2.44 this.Controls.Add(this.buttonSetBitmap);
2.45 this.Controls.Add(this.buttonLayoutUpdate);
2.46 @@ -170,6 +194,8 @@
2.47 private System.Windows.Forms.Button buttonLayoutUpdate;
2.48 private System.Windows.Forms.Button buttonSetBitmap;
2.49 private System.Windows.Forms.Button buttonBitmapLayout;
2.50 + private System.Windows.Forms.Button buttonIndicatorsLayout;
2.51 + private System.Windows.Forms.Button buttonUpdateTexts;
2.52 }
2.53 }
2.54
3.1 --- a/Client/MainForm.cs Sat Dec 27 21:50:15 2014 +0100
3.2 +++ b/Client/MainForm.cs Sat Dec 27 21:52:14 2014 +0100
3.3 @@ -134,16 +134,24 @@
3.4 //TextField top = new TextField(0, textBoxTop.Text, ContentAlignment.MiddleLeft);
3.5 iTextFieldTop.Text = textBoxTop.Text;
3.6 iTextFieldTop.Alignment = Alignment;
3.7 - iClient.SetField(iTextFieldTop);
3.8 + bool res = iClient.SetField(iTextFieldTop);
3.9 +
3.10 + if (!res)
3.11 + {
3.12 + MessageBox.Show("Create you fields first", "Field update error", MessageBoxButtons.OK, MessageBoxIcon.Error);
3.13 + }
3.14 +
3.15 +
3.16 }
3.17
3.18 private void buttonSetText_Click(object sender, EventArgs e)
3.19 {
3.20 - //iClient.SetText(0,"Top");
3.21 - //iClient.SetText(1, "Bottom");
3.22 - //TextField top = new TextField(0, textBoxTop.Text, ContentAlignment.MiddleLeft);
3.23 + //Set one column two lines layout
3.24 + TableLayout layout = new TableLayout(1, 2);
3.25 + iClient.SetLayout(layout);
3.26
3.27 - iClient.SetFields(new DataField[]
3.28 + //Set our fields
3.29 + iClient.CreateFields(new DataField[]
3.30 {
3.31 new DataField(0, textBoxTop.Text, Alignment),
3.32 new DataField(1, textBoxBottom.Text, Alignment)
3.33 @@ -178,7 +186,7 @@
3.34 }
3.35
3.36 DataField field = new DataField(0, bitmap);
3.37 - field.ColumnSpan = 2;
3.38 + //field.ColumnSpan = 2;
3.39 iClient.SetField(field);
3.40 }
3.41
3.42 @@ -221,10 +229,9 @@
3.43 DataField field = new DataField(0, bitmap);
3.44 //We want our bitmap field to span across two rows
3.45 field.RowSpan = 2;
3.46 - iClient.SetField(field);
3.47
3.48 //Set texts
3.49 - iClient.SetFields(new DataField[]
3.50 + iClient.CreateFields(new DataField[]
3.51 {
3.52 field,
3.53 new DataField(1, textBoxTop.Text, Alignment),
3.54 @@ -232,5 +239,78 @@
3.55 });
3.56
3.57 }
3.58 +
3.59 + private void buttonIndicatorsLayout_Click(object sender, EventArgs e)
3.60 + {
3.61 + //Define a 2 by 4 layout
3.62 + TableLayout layout = new TableLayout(2, 4);
3.63 + //First column
3.64 + layout.Columns[0].Width = 87.5F;
3.65 + //Second column
3.66 + layout.Columns[1].Width = 12.5F;
3.67 + //Send layout to server
3.68 + iClient.SetLayout(layout);
3.69 +
3.70 + //Create a bitmap for our indicators field
3.71 + int x1 = 0;
3.72 + int y1 = 0;
3.73 + int x2 = 32;
3.74 + int y2 = 16;
3.75 +
3.76 + Bitmap bitmap = new Bitmap(x2, y2);
3.77 + Pen blackPen = new Pen(Color.Black, 3);
3.78 +
3.79 + // Draw line to screen.
3.80 + using (var graphics = Graphics.FromImage(bitmap))
3.81 + {
3.82 + graphics.DrawLine(blackPen, x1, y1, x2, y2);
3.83 + graphics.DrawLine(blackPen, x1, y2, x2, y1);
3.84 + }
3.85 +
3.86 + //Create a bitmap field from the bitmap we just created
3.87 + DataField indicator1 = new DataField(2, bitmap);
3.88 + //Create a bitmap field from the bitmap we just created
3.89 + DataField indicator2 = new DataField(3, bitmap);
3.90 + //Create a bitmap field from the bitmap we just created
3.91 + DataField indicator3 = new DataField(4, bitmap);
3.92 + //Create a bitmap field from the bitmap we just created
3.93 + DataField indicator4 = new DataField(5, bitmap);
3.94 +
3.95 + //
3.96 + DataField textFieldTop = new DataField(0, textBoxTop.Text, Alignment);
3.97 + textFieldTop.RowSpan = 2;
3.98 +
3.99 + DataField textFieldBottom = new DataField(1, textBoxBottom.Text, Alignment);
3.100 + textFieldBottom.RowSpan = 2;
3.101 +
3.102 +
3.103 + //Set texts
3.104 + iClient.CreateFields(new DataField[]
3.105 + {
3.106 + textFieldTop,
3.107 + indicator1,
3.108 + indicator2,
3.109 + textFieldBottom,
3.110 + indicator3,
3.111 + indicator4
3.112 + });
3.113 +
3.114 + }
3.115 +
3.116 + private void buttonUpdateTexts_Click(object sender, EventArgs e)
3.117 + {
3.118 +
3.119 + bool res = iClient.SetFields(new DataField[]
3.120 + {
3.121 + new DataField(0, textBoxTop.Text, Alignment),
3.122 + new DataField(1, textBoxBottom.Text, Alignment)
3.123 + });
3.124 +
3.125 + if (!res)
3.126 + {
3.127 + MessageBox.Show("Create you fields first", "Field update error", MessageBoxButtons.OK, MessageBoxIcon.Error);
3.128 + }
3.129 +
3.130 + }
3.131 }
3.132 }
4.1 --- a/Server/MainForm.cs Sat Dec 27 21:50:15 2014 +0100
4.2 +++ b/Server/MainForm.cs Sat Dec 27 21:52:14 2014 +0100
4.3 @@ -25,9 +25,9 @@
4.4 //Delegates are used for our thread safe method
4.5 public delegate void AddClientDelegate(string aSessionId, ICallback aCallback);
4.6 public delegate void RemoveClientDelegate(string aSessionId);
4.7 - public delegate void SetTextDelegate(string SessionId, DataField aField);
4.8 + public delegate void SetFieldDelegate(string SessionId, DataField aField);
4.9 + public delegate void SetFieldsDelegate(string SessionId, System.Collections.Generic.IList<DataField> aFields);
4.10 public delegate void SetLayoutDelegate(string SessionId, TableLayout aLayout);
4.11 - public delegate void SetFieldsDelegate(string SessionId, System.Collections.Generic.IList<DataField> aFields);
4.12 public delegate void SetClientNameDelegate(string aSessionId, string aName);
4.13
4.14
4.15 @@ -807,7 +807,7 @@
4.16 if (this.InvokeRequired)
4.17 {
4.18 //Not in the proper thread, invoke ourselves
4.19 - SetTextDelegate d = new SetTextDelegate(SetClientFieldThreadSafe);
4.20 + SetFieldDelegate d = new SetFieldDelegate(SetClientFieldThreadSafe);
4.21 this.Invoke(d, new object[] { aSessionId, aField });
4.22 }
4.23 else
4.24 @@ -819,12 +819,12 @@
4.25 }
4.26
4.27 /// <summary>
4.28 - ///
4.29 + ///
4.30 /// </summary>
4.31 /// <param name="aSessionId"></param>
4.32 /// <param name="aField"></param>
4.33 private void SetClientField(string aSessionId, DataField aField)
4.34 - {
4.35 + {
4.36 SetCurrentClient(aSessionId);
4.37 ClientData client = iClients[aSessionId];
4.38 if (client != null)
4.39 @@ -845,7 +845,7 @@
4.40 client.Fields[aField.Index] = aField;
4.41 //
4.42 if (aField.IsText && tableLayoutPanel.Controls[aField.Index] is MarqueeLabel)
4.43 - {
4.44 + {
4.45 //Text field control already in place, just change the text
4.46 MarqueeLabel label = (MarqueeLabel)tableLayoutPanel.Controls[aField.Index];
4.47 somethingChanged = (label.Text != aField.Text || label.TextAlign != aField.Alignment);