# HG changeset patch
# User StephaneLenclud
# Date 1411415951 -7200
# Node ID 7b7fad7081594546f1efb21171d0ef95d7404819
# Parent  1d10b3a8a235095365652ec3f41bf18acfbc4f18
Quick and dearty usage of our new SharpDisplay layout for packed mode.

diff -r 1d10b3a8a235 -r 7b7fad708159 GUI/SensorSharpDisplay.cs
--- a/GUI/SensorSharpDisplay.cs	Sun Sep 21 21:55:36 2014 +0200
+++ b/GUI/SensorSharpDisplay.cs	Mon Sep 22 21:59:11 2014 +0200
@@ -160,7 +160,7 @@
                 case SensorType.Load: format = "{0:F0}%"; break;
                 //iMON VFD escape sequence for Celsius
                 case SensorType.Temperature: format = "{0:F0}°C"; break;
-                case SensorType.Fan: format = "{0:F0}*"; break; //RPM
+                case SensorType.Fan: format = "{0:F0}R"; break; //RPM
                 case SensorType.Flow: format = "{0:F0}L/h"; break;
                 case SensorType.Control: format = "{0:F0}%"; break;
                 case SensorType.Level: format = "{0:F0}%"; break;
diff -r 1d10b3a8a235 -r 7b7fad708159 GUI/SharpDisplay.cs
--- a/GUI/SharpDisplay.cs	Sun Sep 21 21:55:36 2014 +0200
+++ b/GUI/SharpDisplay.cs	Mon Sep 22 21:59:11 2014 +0200
@@ -30,15 +30,18 @@
         private IComputer computer;
         private PersistentSettings settings;
         private UnitManager unitManager;
-        private List<SensorSharpDisplay> list = new List<SensorSharpDisplay>();
+        private List<SensorSharpDisplay> iSensors = new List<SensorSharpDisplay>();
         private global::SharpDisplay.Client iClient;
         TextField iTextFieldTop;
         TextField iTextFieldBottom;
+        TextField iTextFieldTopRight;
+        TextField iTextFieldBottomRight;
+
         TextField[] iTextFields;
 
         private int iNextSensorToDisplay = 0;
         private int iTickCounter = 0;
-
+        bool iPacked = false;
 
         public SharpDisplay(IComputer computer, PersistentSettings settings, UnitManager unitManager)
         {
@@ -54,6 +57,9 @@
             //
             iTextFieldTop = new TextField(0);
             iTextFieldBottom = new TextField(1);
+            iTextFieldTopRight = new TextField(2, "", ContentAlignment.MiddleRight);
+            iTextFieldBottomRight = new TextField(3, "", ContentAlignment.MiddleRight);
+
             iTextFields = new TextField[] { iTextFieldTop, iTextFieldBottom };
 
         }
@@ -108,7 +114,7 @@
 
         public void Dispose()
         {
-            foreach (SensorSharpDisplay icon in list)
+            foreach (SensorSharpDisplay icon in iSensors)
                 icon.Dispose();
 
             Quit();            
@@ -125,19 +131,45 @@
             string packedSecondLine = "";
             int count = 0;
 
-            string time = DateTime.Now.ToShortTimeString();
+            //string time = DateTime.Now.ToShortTimeString();
+            string time = DateTime.Now.ToLongTimeString();
+
+            if (iSensors.Count > 0)
+            {
+                if (iPacked != aPacked)
+                {
+                    //Remember mode
+                    iPacked = aPacked;
+
+                    if (iPacked)
+                    {
+                        //We just switched to packed mode                    
+                        //Make sure our layout is proper
+                        TableLayout layout = new TableLayout(2, 2);
+                        iClient.SetLayout(layout);
+                    }
+                    else
+                    {
+                        //Non packed mode
+                        TableLayout layout = new TableLayout(1, 2);
+                        iClient.SetLayout(layout);
+                    }
+                }
+            }
+
 
             //Update all sensors from our front view
-            foreach (SensorSharpDisplay sensor in list)
+            foreach (SensorSharpDisplay sensor in iSensors)
             {
                 count++;
                 sensor.Update();
 
                 if (aDisplayTime && count == 1)
                 {
-                    //First slot is take by time display
+                    //First slot is taken by time display
                     count++;
-                    packedFirstLine = time + " ";
+                    iTextFieldTop.Text = time;
+                    iClient.SetText(iTextFieldTop);
                 }
 
                 if (aPacked)
@@ -147,39 +179,33 @@
                     packedText = sensor.iFirstLine.Substring(0, 3) + ":" + sensor.iSecondLine;
                     if (count == 1)
                     {
-                        packedFirstLine = packedText + " "; //Minimum one space to separate sensors on the same line
+                        iTextFieldTop.Text = packedText;
+                        iClient.SetText(iTextFieldTop);
                     }
                     else if (count == 2)
                     {
-                        //Add enough spaces to align to right hand side
-                        while (packedFirstLine.Length + packedText.Length < KMaxCharacterPerLine)
-                        {
-                            packedFirstLine += " ";
-                        }
-                        packedFirstLine += packedText;
+                        iTextFieldBottom.Text = packedText;
+                        iClient.SetText(iTextFieldBottom);
                     }
                     else if (count == 3)
                     {
-                        packedSecondLine = packedText + " "; //Minimum one space to separate sensors on the same line
+                        iTextFieldTopRight.Text = packedText;
+                        iClient.SetText(iTextFieldTopRight);
                     }
                     else if (count == 4)
                     {
-                        //Add enough spaces to align to right hand side
-                        while (packedSecondLine.Length + packedText.Length < KMaxCharacterPerLine)
-                        {
-                            packedSecondLine += " ";
-                        }
-                        packedSecondLine += packedText;
+                        iTextFieldBottomRight.Text = packedText;
+                        iClient.SetText(iTextFieldBottomRight);
                     }
                 }
-                //SetText(sensor.iFirstLine, sensor.iSecondLine);
             }
 
             //Alternate between sensors 
-            if (list.Count > 0)
+            if (iSensors.Count > 0)
             {
                 if (aPacked)
                 {
+                    //Review that stuff cause as it is it's probably useless
                     //string packedLine = "";
                     iTickCounter++;
                     if (iTickCounter == KNumberOfTickBeforeSwitch) //Move to the next sensor only every so many tick
@@ -194,16 +220,10 @@
                             iNextSensorToDisplay = 1;
                         }
                     }
-
-                    //TODO: Do something like that to cycle lines if ever we want to
-                    //SetText(time, (iNextSensorToDisplay == 1 && packedSecondLine.Length > 0 ? packedSecondLine : packedFirstLine));
-
-                    //Display packed sensors on our FrontView display
-                    SetText(packedFirstLine, packedSecondLine);
                 }
                 else
                 {
-                    string secondLine = list[iNextSensorToDisplay].iSecondLine;
+                    string secondLine = iSensors[iNextSensorToDisplay].iSecondLine;
                     if (aDisplayTime)
                     {
                         //Add enough spaces
@@ -214,7 +234,7 @@
                         secondLine += time;
                     }
                     //Display current sensor on our FrontView display
-                    SetText(list[iNextSensorToDisplay].iFirstLine, secondLine);
+                    SetText(iSensors[iNextSensorToDisplay].iFirstLine, secondLine);
                     iTickCounter++;
                     if (iTickCounter == KNumberOfTickBeforeSwitch) //Move to the next sensor only every so many tick
                     {
@@ -224,7 +244,7 @@
                 }
             }
 
-            if (iNextSensorToDisplay == list.Count)
+            if (iNextSensorToDisplay == iSensors.Count)
             {
                 //Go back to first sensor
                 iNextSensorToDisplay = 0;
@@ -235,7 +255,7 @@
 
         public bool Contains(ISensor sensor)
         {
-            foreach (SensorSharpDisplay icon in list)
+            foreach (SensorSharpDisplay icon in iSensors)
                 if (icon.Sensor == sensor)
                     return true;
             return false;
@@ -250,11 +270,11 @@
             else
             {
                 //SL:
-                list.Add(new SensorSharpDisplay(this, sensor, balloonTip, settings, unitManager));
+                iSensors.Add(new SensorSharpDisplay(this, sensor, balloonTip, settings, unitManager));
                 //UpdateMainIconVisibilty();
                 settings.SetValue(new Identifier(sensor.Identifier, "SharpDisplay").ToString(), true);
                 iNextSensorToDisplay = 0;
-                if (list.Count == 1)
+                if (iSensors.Count == 1)
                 {
                     //Just added first sensor in FrontView, unable FrontView plug-in mode
                     Init();
@@ -267,7 +287,7 @@
         {
             Remove(sensor, true);
             iNextSensorToDisplay = 0;
-            if (list.Count == 0)
+            if (iSensors.Count == 0)
             {
                 //No sensor to display in FrontView, just disable FrontView plug-in mode
                 Uninit();
@@ -283,12 +303,12 @@
                   new Identifier(sensor.Identifier, "SharpDisplay").ToString());
             }
             SensorSharpDisplay instance = null;
-            foreach (SensorSharpDisplay icon in list)
+            foreach (SensorSharpDisplay icon in iSensors)
                 if (icon.Sensor == sensor)
                     instance = icon;
             if (instance != null)
             {
-                list.Remove(instance);
+                iSensors.Remove(instance);
                 //UpdateMainIconVisibilty();
                 instance.Dispose();
             }
diff -r 1d10b3a8a235 -r 7b7fad708159 GUI/SharpDisplayClient.cs
--- a/GUI/SharpDisplayClient.cs	Sun Sep 21 21:55:36 2014 +0200
+++ b/GUI/SharpDisplayClient.cs	Mon Sep 22 21:59:11 2014 +0200
@@ -26,11 +26,75 @@
 
 namespace SharpDisplay
 {
-    //That contract need to be in the same namespace than the original assembly
-    //otherwise our parameter won't make to the server.
-    //See: http://stackoverflow.com/questions/14956377/passing-an-object-using-datacontract-in-wcf/25455292#25455292
+
+
+
+    /// <summary>
+    /// For client to specify a specific layout.
+    /// </summary>
     [DataContract]
-    public class TextField
+    public class TableLayout
+    {
+        public TableLayout()
+        {
+            Columns = new List<ColumnStyle>();
+            Rows = new List<RowStyle>();
+            Cells = new List<DataField>();
+        }
+
+        public TableLayout(int aColumnCount, int aRowCount)
+        {
+            Columns = new List<ColumnStyle>();
+            Rows = new List<RowStyle>();
+
+            for (int i = 0; i < aColumnCount; i++)
+            {
+                Columns.Add(new ColumnStyle(SizeType.Percent, 100 / aColumnCount));
+            }
+
+            for (int i = 0; i < aRowCount; i++)
+            {
+                Rows.Add(new RowStyle(SizeType.Percent, 100 / aRowCount));
+            }
+        }
+
+        [DataMember]
+        public List<DataField> Cells { get; set; }
+
+        [DataMember]
+        public List<ColumnStyle> Columns { get; set; }
+
+        [DataMember]
+        public List<RowStyle> Rows { get; set; }
+
+    }
+
+    /// <summary>
+    ///
+    /// </summary>
+    [DataContract]
+    public class DataField
+    {
+        [DataMember]
+        public int Column { get; set; }
+
+        [DataMember]
+        public int Row { get; set; }
+
+        [DataMember]
+        public int ColumnSpan { get; set; }
+
+        [DataMember]
+        public int RowSpan { get; set; }
+
+    }
+
+
+    /// <summary>
+    /// TextField can be send to our server to be displayed on the screen.
+    /// </summary>
+    [DataContract]
+    public class TextField : DataField
     {
         public TextField()
         {
@@ -56,7 +120,12 @@
         public ContentAlignment Alignment { get; set; }
     }
 
-
+    /// <summary>
+    /// Define our SharpDisplay service.
+    /// Clients and servers must implement it to communicate with one another.
+    /// Through this service clients can send requests to a server.
+    /// Through this service a server session can receive requests from a client.
+    /// </summary>
     [ServiceContract(CallbackContract = typeof(ICallback), SessionMode = SessionMode.Required)]
     public interface IService
     {
@@ -70,6 +139,13 @@
         [OperationContract(IsOneWay = true)]
         void SetName(string aClientName);
 
+
+        /// <summary>
+        /// </summary>
+        /// <param name="aLayout"></param>
+        [OperationContract(IsOneWay = true)]
+        void SetLayout(TableLayout aLayout);
+
         /// <summary>
         /// Put the given text in the given field on your display.
         /// Fields are often just lines of text.
@@ -94,7 +170,9 @@
 
     }
 
-
+    /// <summary>
+    /// SharDisplay callback provides a means for a server to notify its clients.
+    /// </summary>
     public interface ICallback
     {
         [OperationContract(IsOneWay = true)]
@@ -107,6 +185,9 @@
         [OperationContract(IsOneWay = true)]
         void OnCloseOrder();
     }
+
+
+
 }
 
 
@@ -133,6 +214,11 @@
             Channel.SetName(aClientName);
         }
 
+        public void SetLayout(TableLayout aLayout)
+        {
+            Channel.SetLayout(aLayout);
+        }
+
         public void SetText(TextField aTextField)
         {
             Channel.SetText(aTextField);