Server/MainForm.cs
author sl
Mon, 22 Sep 2014 13:21:00 +0200
changeset 61 5a24e79384be
parent 60 4f2a73683adc
child 62 ac698f4e1b36
permissions -rw-r--r--
Implement generic function to regenerate our display table layout.
Add and remove column now working.
sl@0
     1
using System;
sl@0
     2
using System.Collections.Generic;
sl@0
     3
using System.ComponentModel;
sl@0
     4
using System.Data;
sl@0
     5
using System.Drawing;
sl@0
     6
using System.Linq;
sl@0
     7
using System.Text;
sl@0
     8
using System.Threading.Tasks;
sl@0
     9
using System.Windows.Forms;
sl@14
    10
using System.IO;
sl@0
    11
using CodeProject.Dialog;
sl@14
    12
using System.Drawing.Imaging;
sl@17
    13
using System.ServiceModel;
sl@25
    14
using System.Threading;
sl@31
    15
using System.Diagnostics;
sl@25
    16
//
sl@25
    17
using SharpDisplayClient;
sl@55
    18
using SharpDisplay;
sl@0
    19
sl@0
    20
namespace SharpDisplayManager
sl@0
    21
{
sl@58
    22
    //Types declarations
sl@58
    23
    public delegate uint ColorProcessingDelegate(int aX, int aY, uint aPixel);
sl@58
    24
    public delegate int CoordinateTranslationDelegate(System.Drawing.Bitmap aBmp, int aInt);
sl@58
    25
sl@58
    26
    /// <summary>
sl@58
    27
    /// Our Display manager main form
sl@58
    28
    /// </summary>
sl@0
    29
    public partial class MainForm : Form
sl@0
    30
    {
sl@58
    31
sl@2
    32
        DateTime LastTickTime;
sl@3
    33
        Display iDisplay;
sl@14
    34
        System.Drawing.Bitmap iBmp;
sl@14
    35
        bool iCreateBitmap; //Workaround render to bitmap issues when minimized
sl@17
    36
        ServiceHost iServiceHost;
sl@21
    37
        /// <summary>
sl@21
    38
        /// Our collection of clients
sl@21
    39
        /// </summary>
sl@33
    40
        public Dictionary<string, ClientData> iClients;
sl@29
    41
        public bool iClosing;
sl@58
    42
        ColorProcessingDelegate iColorFx;
sl@58
    43
        CoordinateTranslationDelegate iScreenX;
sl@58
    44
        CoordinateTranslationDelegate iScreenY;
sl@2
    45
sl@0
    46
        public MainForm()
sl@0
    47
        {
sl@2
    48
            LastTickTime = DateTime.Now;
sl@3
    49
            iDisplay = new Display();
sl@33
    50
            iClients = new Dictionary<string, ClientData>();
sl@2
    51
sl@0
    52
            InitializeComponent();
sl@7
    53
            UpdateStatus();
sl@14
    54
            //We have a bug when drawing minimized and reusing our bitmap
sl@14
    55
            iBmp = new System.Drawing.Bitmap(tableLayoutPanel.Width, tableLayoutPanel.Height, PixelFormat.Format32bppArgb);
sl@14
    56
            iCreateBitmap = false;
sl@57
    57
            //
sl@57
    58
            //this.tableLayoutPanel.CellPaint += new TableLayoutCellPaintEventHandler(tableLayoutPanel_CellPaint);
sl@0
    59
        }
sl@0
    60
sl@13
    61
        private void MainForm_Load(object sender, EventArgs e)
sl@13
    62
        {
sl@17
    63
            StartServer();
sl@17
    64
sl@13
    65
            if (Properties.Settings.Default.DisplayConnectOnStartup)
sl@13
    66
            {
sl@46
    67
                OpenDisplayConnection();
sl@13
    68
            }
sl@13
    69
        }
sl@13
    70
sl@57
    71
        //Testing that stuff
sl@57
    72
        private void tableLayoutPanel_CellPaint(object sender, TableLayoutCellPaintEventArgs e)
sl@57
    73
        {
sl@57
    74
            var panel = sender as TableLayoutPanel;
sl@57
    75
            //e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
sl@57
    76
            var rectangle = e.CellBounds;
sl@57
    77
            using (var pen = new Pen(Color.Black, 1))
sl@57
    78
            {
sl@57
    79
                pen.Alignment = System.Drawing.Drawing2D.PenAlignment.Center;
sl@57
    80
                pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
sl@57
    81
sl@57
    82
                if (e.Row == (panel.RowCount - 1))
sl@57
    83
                {
sl@57
    84
                    rectangle.Height -= 1;
sl@57
    85
                }
sl@57
    86
sl@57
    87
                if (e.Column == (panel.ColumnCount - 1))
sl@57
    88
                {
sl@57
    89
                    rectangle.Width -= 1;
sl@57
    90
                }
sl@57
    91
sl@57
    92
                e.Graphics.DrawRectangle(pen, rectangle);
sl@57
    93
            }
sl@57
    94
        }
sl@57
    95
sl@13
    96
sl@0
    97
        private void buttonFont_Click(object sender, EventArgs e)
sl@0
    98
        {
sl@0
    99
            //fontDialog.ShowColor = true;
sl@0
   100
            //fontDialog.ShowApply = true;
sl@0
   101
            fontDialog.ShowEffects = true;
sl@60
   102
            MarqueeLabel label = (MarqueeLabel)tableLayoutPanel.Controls[0];
sl@60
   103
            fontDialog.Font = label.Font;
sl@28
   104
sl@28
   105
            fontDialog.FixedPitchOnly = checkBoxFixedPitchFontOnly.Checked;
sl@28
   106
sl@0
   107
            //fontDialog.ShowHelp = true;
sl@0
   108
sl@0
   109
            //fontDlg.MaxSize = 40;
sl@0
   110
            //fontDlg.MinSize = 22;
sl@0
   111
sl@0
   112
            //fontDialog.Parent = this;
sl@0
   113
            //fontDialog.StartPosition = FormStartPosition.CenterParent;
sl@0
   114
sl@0
   115
            //DlgBox.ShowDialog(fontDialog);
sl@0
   116
sl@0
   117
            //if (fontDialog.ShowDialog(this) != DialogResult.Cancel)
sl@0
   118
            if (DlgBox.ShowDialog(fontDialog) != DialogResult.Cancel)
sl@0
   119
            {
sl@0
   120
sl@4
   121
                //MsgBox.Show("MessageBox MsgBox", "MsgBox caption");
sl@0
   122
sl@0
   123
                //MessageBox.Show("Ok");
sl@60
   124
                foreach (MarqueeLabel ctrl in tableLayoutPanel.Controls)
sl@60
   125
                {
sl@60
   126
                    ctrl.Font = fontDialog.Font;
sl@60
   127
                }
sl@48
   128
                cds.Font = fontDialog.Font;
sl@8
   129
                Properties.Settings.Default.Save();
sl@36
   130
                //
sl@37
   131
                CheckFontHeight();
sl@37
   132
            }
sl@37
   133
        }
sl@36
   134
sl@37
   135
        /// <summary>
sl@38
   136
        ///
sl@37
   137
        /// </summary>
sl@37
   138
        void CheckFontHeight()
sl@37
   139
        {
sl@54
   140
            //Show font height and width
sl@54
   141
            labelFontHeight.Text = "Font height: " + cds.Font.Height;
sl@54
   142
            float charWidth = IsFixedWidth(cds.Font);
sl@54
   143
            if (charWidth == 0.0f)
sl@54
   144
            {
sl@54
   145
                labelFontWidth.Visible = false;
sl@54
   146
            }
sl@54
   147
            else
sl@54
   148
            {
sl@54
   149
                labelFontWidth.Visible = true;
sl@54
   150
                labelFontWidth.Text = "Font width: " + charWidth;
sl@54
   151
            }
sl@54
   152
sl@54
   153
            //Now check font height and show a warning if needed.
sl@60
   154
            MarqueeLabel label = (MarqueeLabel)tableLayoutPanel.Controls[0];
sl@60
   155
            if (label.Font.Height > label.Height)
sl@37
   156
            {
sl@60
   157
                labelWarning.Text = "WARNING: Selected font is too height by " + (label.Font.Height - label.Height) + " pixels!";
sl@37
   158
                labelWarning.Visible = true;
sl@0
   159
            }
sl@37
   160
            else
sl@37
   161
            {
sl@37
   162
                labelWarning.Visible = false;
sl@37
   163
            }
sl@37
   164
sl@0
   165
        }
sl@0
   166
sl@0
   167
        private void buttonCapture_Click(object sender, EventArgs e)
sl@0
   168
        {
sl@0
   169
            System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(tableLayoutPanel.Width, tableLayoutPanel.Height);
sl@0
   170
            tableLayoutPanel.DrawToBitmap(bmp, tableLayoutPanel.ClientRectangle);
sl@14
   171
            //Bitmap bmpToSave = new Bitmap(bmp);
sl@14
   172
            bmp.Save("D:\\capture.png");
sl@14
   173
sl@60
   174
            ((MarqueeLabel)tableLayoutPanel.Controls[0]).Text = "Captured";
sl@17
   175
sl@14
   176
            /*
sl@14
   177
            string outputFileName = "d:\\capture.png";
sl@14
   178
            using (MemoryStream memory = new MemoryStream())
sl@14
   179
            {
sl@14
   180
                using (FileStream fs = new FileStream(outputFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite))
sl@14
   181
                {
sl@14
   182
                    bmp.Save(memory, System.Drawing.Imaging.ImageFormat.Png);
sl@14
   183
                    byte[] bytes = memory.ToArray();
sl@14
   184
                    fs.Write(bytes, 0, bytes.Length);
sl@14
   185
                }
sl@14
   186
            }
sl@14
   187
             */
sl@14
   188
sl@0
   189
        }
sl@2
   190
sl@12
   191
        private void CheckForRequestResults()
sl@12
   192
        {
sl@12
   193
            if (iDisplay.IsRequestPending())
sl@12
   194
            {
sl@12
   195
                switch (iDisplay.AttemptRequestCompletion())
sl@12
   196
                {
sl@51
   197
                    case Display.TMiniDisplayRequest.EMiniDisplayRequestFirmwareRevision:
sl@51
   198
                        toolStripStatusLabelConnect.Text += " v" + iDisplay.FirmwareRevision();
sl@51
   199
                        //Issue next request then
sl@51
   200
                        iDisplay.RequestPowerSupplyStatus();
sl@51
   201
                        break;
sl@51
   202
sl@12
   203
                    case Display.TMiniDisplayRequest.EMiniDisplayRequestPowerSupplyStatus:
sl@12
   204
                        if (iDisplay.PowerSupplyStatus())
sl@12
   205
                        {
sl@12
   206
                            toolStripStatusLabelPower.Text = "ON";
sl@12
   207
                        }
sl@12
   208
                        else
sl@12
   209
                        {
sl@12
   210
                            toolStripStatusLabelPower.Text = "OFF";
sl@12
   211
                        }
sl@12
   212
                        //Issue next request then
sl@12
   213
                        iDisplay.RequestDeviceId();
sl@12
   214
                        break;
sl@12
   215
sl@12
   216
                    case Display.TMiniDisplayRequest.EMiniDisplayRequestDeviceId:
sl@12
   217
                        toolStripStatusLabelConnect.Text += " - " + iDisplay.DeviceId();
sl@12
   218
                        //No more request to issue
sl@12
   219
                        break;
sl@12
   220
                }
sl@12
   221
            }
sl@12
   222
        }
sl@12
   223
sl@58
   224
        public static uint ColorWhiteIsOn(int aX, int aY, uint aPixel)
sl@58
   225
        {
sl@58
   226
            if ((aPixel & 0x00FFFFFF) == 0x00FFFFFF)
sl@58
   227
            {
sl@58
   228
                return 0xFFFFFFFF;
sl@58
   229
            }
sl@58
   230
            return 0x00000000;
sl@58
   231
        }
sl@16
   232
sl@58
   233
        public static uint ColorUntouched(int aX, int aY, uint aPixel)
sl@57
   234
        {
sl@57
   235
            return aPixel;
sl@57
   236
        }
sl@57
   237
sl@58
   238
        public static uint ColorInversed(int aX, int aY, uint aPixel)
sl@57
   239
        {
sl@57
   240
            return ~aPixel;
sl@57
   241
        }
sl@57
   242
sl@58
   243
        public static uint ColorChessboard(int aX, int aY, uint aPixel)
sl@58
   244
        {
sl@58
   245
            if ((aX % 2 == 0) && (aY % 2 == 0))
sl@58
   246
            {
sl@58
   247
                return ~aPixel;
sl@58
   248
            }
sl@58
   249
            else if ((aX % 2 != 0) && (aY % 2 != 0))
sl@58
   250
            {
sl@58
   251
                return ~aPixel;
sl@58
   252
            }
sl@58
   253
            return 0x00000000;
sl@58
   254
        }
sl@58
   255
sl@16
   256
sl@16
   257
        public static int ScreenReversedX(System.Drawing.Bitmap aBmp, int aX)
sl@16
   258
        {
sl@16
   259
            return aBmp.Width - aX - 1;
sl@16
   260
        }
sl@16
   261
sl@16
   262
        public int ScreenReversedY(System.Drawing.Bitmap aBmp, int aY)
sl@16
   263
        {
sl@16
   264
            return iBmp.Height - aY - 1;
sl@16
   265
        }
sl@16
   266
sl@16
   267
        public int ScreenX(System.Drawing.Bitmap aBmp, int aX)
sl@16
   268
        {
sl@16
   269
            return aX;
sl@16
   270
        }
sl@16
   271
sl@16
   272
        public int ScreenY(System.Drawing.Bitmap aBmp, int aY)
sl@16
   273
        {
sl@16
   274
            return aY;
sl@16
   275
        }
sl@16
   276
sl@58
   277
        /// <summary>
sl@58
   278
        /// Select proper pixel delegates according to our current settings.
sl@58
   279
        /// </summary>
sl@58
   280
        private void SetupPixelDelegates()
sl@58
   281
        {
sl@59
   282
            //Select our pixel processing routine
sl@58
   283
            if (cds.InverseColors)
sl@58
   284
            {
sl@58
   285
                //iColorFx = ColorChessboard;
sl@58
   286
                iColorFx = ColorInversed;
sl@58
   287
            }
sl@58
   288
            else
sl@58
   289
            {
sl@58
   290
                iColorFx = ColorWhiteIsOn;
sl@58
   291
            }
sl@58
   292
sl@58
   293
            //Select proper coordinate translation functions
sl@58
   294
            //We used delegate/function pointer to support reverse screen without doing an extra test on each pixels
sl@58
   295
            if (cds.ReverseScreen)
sl@58
   296
            {
sl@58
   297
                iScreenX = ScreenReversedX;
sl@58
   298
                iScreenY = ScreenReversedY;
sl@58
   299
            }
sl@58
   300
            else
sl@58
   301
            {
sl@58
   302
                iScreenX = ScreenX;
sl@58
   303
                iScreenY = ScreenY;
sl@58
   304
            }
sl@58
   305
sl@58
   306
        }
sl@16
   307
sl@16
   308
        //This is our timer tick responsible to perform our render
sl@2
   309
        private void timer_Tick(object sender, EventArgs e)
sl@14
   310
        {
sl@2
   311
            //Update our animations
sl@2
   312
            DateTime NewTickTime = DateTime.Now;
sl@2
   313
sl@60
   314
            //Update animation for all our marquees
sl@60
   315
            foreach (MarqueeLabel ctrl in tableLayoutPanel.Controls)
sl@60
   316
            {
sl@60
   317
                ctrl.UpdateAnimation(LastTickTime, NewTickTime);
sl@60
   318
            }
sl@60
   319
sl@2
   320
sl@4
   321
            //Update our display
sl@4
   322
            if (iDisplay.IsOpen())
sl@4
   323
            {
sl@12
   324
                CheckForRequestResults();
sl@12
   325
sl@22
   326
                //Draw to bitmap
sl@14
   327
                if (iCreateBitmap)
sl@14
   328
                {
sl@14
   329
                    iBmp = new System.Drawing.Bitmap(tableLayoutPanel.Width, tableLayoutPanel.Height, PixelFormat.Format32bppArgb);
sl@14
   330
                }
sl@14
   331
                tableLayoutPanel.DrawToBitmap(iBmp, tableLayoutPanel.ClientRectangle);
sl@14
   332
                //iBmp.Save("D:\\capture.png");
sl@16
   333
sl@7
   334
                //Send it to our display
sl@14
   335
                for (int i = 0; i < iBmp.Width; i++)
sl@4
   336
                {
sl@14
   337
                    for (int j = 0; j < iBmp.Height; j++)
sl@4
   338
                    {
sl@4
   339
                        unchecked
sl@4
   340
                        {
sl@58
   341
                            //Get our processed pixel coordinates
sl@58
   342
                            int x = iScreenX(iBmp, i);
sl@58
   343
                            int y = iScreenY(iBmp, j);
sl@58
   344
                            //Get pixel color
sl@14
   345
                            uint color = (uint)iBmp.GetPixel(i, j).ToArgb();
sl@57
   346
                            //Apply color effects
sl@58
   347
                            color = iColorFx(x,y,color);
sl@58
   348
                            //Now set our pixel
sl@58
   349
                            iDisplay.SetPixel(x, y, color);
sl@4
   350
                        }
sl@4
   351
                    }
sl@4
   352
                }
sl@4
   353
sl@4
   354
                iDisplay.SwapBuffers();
sl@4
   355
sl@4
   356
            }
sl@8
   357
sl@8
   358
            //Compute instant FPS
sl@47
   359
            toolStripStatusLabelFps.Text = (1.0/NewTickTime.Subtract(LastTickTime).TotalSeconds).ToString("F0") + " / " + (1000/timer.Interval).ToString() + " FPS";
sl@8
   360
sl@8
   361
            LastTickTime = NewTickTime;
sl@8
   362
sl@2
   363
        }
sl@3
   364
sl@46
   365
        private void OpenDisplayConnection()
sl@3
   366
        {
sl@46
   367
            CloseDisplayConnection();
sl@46
   368
sl@48
   369
            if (iDisplay.Open((Display.TMiniDisplayType)cds.DisplayType))
sl@3
   370
            {
sl@7
   371
                UpdateStatus();
sl@51
   372
                iDisplay.RequestFirmwareRevision();
sl@3
   373
            }
sl@7
   374
            else
sl@7
   375
            {
sl@7
   376
                UpdateStatus();
sl@7
   377
                toolStripStatusLabelConnect.Text = "Connection error";
sl@7
   378
            }
sl@46
   379
        }
sl@7
   380
sl@46
   381
        private void CloseDisplayConnection()
sl@46
   382
        {
sl@46
   383
            iDisplay.Close();
sl@46
   384
            UpdateStatus();
sl@46
   385
        }
sl@46
   386
sl@46
   387
        private void buttonOpen_Click(object sender, EventArgs e)
sl@46
   388
        {
sl@46
   389
            OpenDisplayConnection();
sl@3
   390
        }
sl@3
   391
sl@3
   392
        private void buttonClose_Click(object sender, EventArgs e)
sl@3
   393
        {
sl@46
   394
            CloseDisplayConnection();
sl@3
   395
        }
sl@3
   396
sl@3
   397
        private void buttonClear_Click(object sender, EventArgs e)
sl@3
   398
        {
sl@3
   399
            iDisplay.Clear();
sl@3
   400
            iDisplay.SwapBuffers();
sl@3
   401
        }
sl@3
   402
sl@3
   403
        private void buttonFill_Click(object sender, EventArgs e)
sl@3
   404
        {
sl@3
   405
            iDisplay.Fill();
sl@3
   406
            iDisplay.SwapBuffers();
sl@3
   407
        }
sl@3
   408
sl@3
   409
        private void trackBarBrightness_Scroll(object sender, EventArgs e)
sl@3
   410
        {
sl@48
   411
            cds.Brightness = trackBarBrightness.Value;
sl@9
   412
            Properties.Settings.Default.Save();
sl@3
   413
            iDisplay.SetBrightness(trackBarBrightness.Value);
sl@9
   414
sl@3
   415
        }
sl@7
   416
sl@48
   417
sl@48
   418
        /// <summary>
sl@48
   419
        /// CDS stands for Current Display Settings
sl@48
   420
        /// </summary>
sl@50
   421
        private DisplaySettings cds
sl@48
   422
        {
sl@48
   423
            get
sl@48
   424
            {
sl@50
   425
                DisplaysSettings settings = Properties.Settings.Default.DisplaySettings;
sl@51
   426
                if (settings == null)
sl@51
   427
                {
sl@51
   428
                    settings = new DisplaysSettings();
sl@51
   429
                    settings.Init();
sl@51
   430
                    Properties.Settings.Default.DisplaySettings = settings;
sl@51
   431
                }
sl@48
   432
sl@48
   433
                //Make sure all our settings have been created
sl@48
   434
                while (settings.Displays.Count <= Properties.Settings.Default.CurrentDisplayIndex)
sl@48
   435
                {
sl@50
   436
                    settings.Displays.Add(new DisplaySettings());
sl@48
   437
                }
sl@48
   438
sl@50
   439
                DisplaySettings displaySettings = settings.Displays[Properties.Settings.Default.CurrentDisplayIndex];
sl@48
   440
                return displaySettings;
sl@48
   441
            }
sl@48
   442
        }
sl@48
   443
sl@54
   444
        /// <summary>
sl@54
   445
        /// Check if the given font has a fixed character pitch.
sl@54
   446
        /// </summary>
sl@54
   447
        /// <param name="ft"></param>
sl@54
   448
        /// <returns>0.0f if this is not a monospace font, otherwise returns the character width.</returns>
sl@54
   449
        public float IsFixedWidth(Font ft)
sl@54
   450
        {
sl@54
   451
            Graphics g = CreateGraphics();
sl@54
   452
            char[] charSizes = new char[] { 'i', 'a', 'Z', '%', '#', 'a', 'B', 'l', 'm', ',', '.' };
sl@54
   453
            float charWidth = g.MeasureString("I", ft, Int32.MaxValue, StringFormat.GenericTypographic).Width;
sl@54
   454
sl@54
   455
            bool fixedWidth = true;
sl@54
   456
sl@54
   457
            foreach (char c in charSizes)
sl@54
   458
                if (g.MeasureString(c.ToString(), ft, Int32.MaxValue, StringFormat.GenericTypographic).Width != charWidth)
sl@54
   459
                    fixedWidth = false;
sl@54
   460
sl@54
   461
            if (fixedWidth)
sl@54
   462
            {
sl@54
   463
                return charWidth;
sl@54
   464
            }
sl@54
   465
sl@54
   466
            return 0.0f;
sl@54
   467
        }
sl@54
   468
sl@7
   469
        private void UpdateStatus()
sl@7
   470
        {
sl@48
   471
            //Synchronize UI with settings
sl@48
   472
            //Load settings
sl@54
   473
            checkBoxShowBorders.Checked = cds.ShowBorders;
sl@54
   474
            tableLayoutPanel.CellBorderStyle = (cds.ShowBorders ? TableLayoutPanelCellBorderStyle.Single : TableLayoutPanelCellBorderStyle.None);
sl@60
   475
sl@60
   476
            //Set the proper font to each of our labels
sl@60
   477
            foreach (MarqueeLabel ctrl in tableLayoutPanel.Controls)
sl@60
   478
            {
sl@60
   479
                ctrl.Font = cds.Font;
sl@60
   480
            }
sl@60
   481
sl@54
   482
            CheckFontHeight();
sl@48
   483
            checkBoxConnectOnStartup.Checked = Properties.Settings.Default.DisplayConnectOnStartup;
sl@48
   484
            checkBoxReverseScreen.Checked = cds.ReverseScreen;
sl@57
   485
            checkBoxInverseColors.Checked = cds.InverseColors;
sl@48
   486
            comboBoxDisplayType.SelectedIndex = cds.DisplayType;
sl@48
   487
            timer.Interval = cds.TimerInterval;
sl@48
   488
            maskedTextBoxTimerInterval.Text = cds.TimerInterval.ToString();
sl@58
   489
            //
sl@58
   490
            SetupPixelDelegates();
sl@48
   491
sl@7
   492
            if (iDisplay.IsOpen())
sl@7
   493
            {
sl@48
   494
                //Only setup brightness if display is open
sl@48
   495
                trackBarBrightness.Minimum = iDisplay.MinBrightness();
sl@48
   496
                trackBarBrightness.Maximum = iDisplay.MaxBrightness();
sl@48
   497
                trackBarBrightness.Value = cds.Brightness;
sl@48
   498
                trackBarBrightness.LargeChange = Math.Max(1, (iDisplay.MaxBrightness() - iDisplay.MinBrightness()) / 5);
sl@48
   499
                trackBarBrightness.SmallChange = 1;
sl@48
   500
                iDisplay.SetBrightness(cds.Brightness);
sl@48
   501
                //
sl@7
   502
                buttonFill.Enabled = true;
sl@7
   503
                buttonClear.Enabled = true;
sl@7
   504
                buttonOpen.Enabled = false;
sl@7
   505
                buttonClose.Enabled = true;
sl@7
   506
                trackBarBrightness.Enabled = true;
sl@10
   507
                toolStripStatusLabelConnect.Text = "Connected - " + iDisplay.Vendor() + " - " + iDisplay.Product();
sl@10
   508
                //+ " - " + iDisplay.SerialNumber();
sl@52
   509
sl@52
   510
                if (iDisplay.SupportPowerOnOff())
sl@52
   511
                {
sl@52
   512
                    buttonPowerOn.Enabled = true;
sl@52
   513
                    buttonPowerOff.Enabled = true;
sl@52
   514
                }
sl@52
   515
                else
sl@52
   516
                {
sl@52
   517
                    buttonPowerOn.Enabled = false;
sl@52
   518
                    buttonPowerOff.Enabled = false;
sl@52
   519
                }
sl@53
   520
sl@53
   521
                if (iDisplay.SupportClock())
sl@53
   522
                {
sl@53
   523
                    buttonShowClock.Enabled = true;
sl@53
   524
                    buttonHideClock.Enabled = true;
sl@53
   525
                }
sl@53
   526
                else
sl@53
   527
                {
sl@53
   528
                    buttonShowClock.Enabled = false;
sl@53
   529
                    buttonHideClock.Enabled = false;
sl@53
   530
                }
sl@7
   531
            }
sl@7
   532
            else
sl@7
   533
            {
sl@7
   534
                buttonFill.Enabled = false;
sl@7
   535
                buttonClear.Enabled = false;
sl@7
   536
                buttonOpen.Enabled = true;
sl@7
   537
                buttonClose.Enabled = false;
sl@7
   538
                trackBarBrightness.Enabled = false;
sl@52
   539
                buttonPowerOn.Enabled = false;
sl@52
   540
                buttonPowerOff.Enabled = false;
sl@53
   541
                buttonShowClock.Enabled = false;
sl@53
   542
                buttonHideClock.Enabled = false;
sl@9
   543
                toolStripStatusLabelConnect.Text = "Disconnected";
sl@48
   544
                toolStripStatusLabelPower.Text = "N/A";
sl@7
   545
            }
sl@7
   546
        }
sl@9
   547
sl@13
   548
sl@13
   549
sl@9
   550
        private void checkBoxShowBorders_CheckedChanged(object sender, EventArgs e)
sl@9
   551
        {
sl@16
   552
            //Save our show borders setting
sl@13
   553
            tableLayoutPanel.CellBorderStyle = (checkBoxShowBorders.Checked ? TableLayoutPanelCellBorderStyle.Single : TableLayoutPanelCellBorderStyle.None);
sl@48
   554
            cds.ShowBorders = checkBoxShowBorders.Checked;
sl@9
   555
            Properties.Settings.Default.Save();
sl@57
   556
            CheckFontHeight();
sl@9
   557
        }
sl@13
   558
sl@13
   559
        private void checkBoxConnectOnStartup_CheckedChanged(object sender, EventArgs e)
sl@13
   560
        {
sl@16
   561
            //Save our connect on startup setting
sl@13
   562
            Properties.Settings.Default.DisplayConnectOnStartup = checkBoxConnectOnStartup.Checked;
sl@13
   563
            Properties.Settings.Default.Save();
sl@13
   564
        }
sl@13
   565
sl@16
   566
        private void checkBoxReverseScreen_CheckedChanged(object sender, EventArgs e)
sl@16
   567
        {
sl@16
   568
            //Save our reverse screen setting
sl@48
   569
            cds.ReverseScreen = checkBoxReverseScreen.Checked;
sl@16
   570
            Properties.Settings.Default.Save();
sl@58
   571
            SetupPixelDelegates();
sl@16
   572
        }
sl@16
   573
sl@57
   574
        private void checkBoxInverseColors_CheckedChanged(object sender, EventArgs e)
sl@57
   575
        {
sl@57
   576
            //Save our inverse colors setting
sl@57
   577
            cds.InverseColors = checkBoxInverseColors.Checked;
sl@57
   578
            Properties.Settings.Default.Save();
sl@58
   579
            SetupPixelDelegates();
sl@57
   580
        }
sl@57
   581
sl@14
   582
        private void MainForm_Resize(object sender, EventArgs e)
sl@14
   583
        {
sl@14
   584
            if (WindowState == FormWindowState.Minimized)
sl@14
   585
            {
sl@14
   586
                // Do some stuff
sl@14
   587
                //iBmp = new System.Drawing.Bitmap(tableLayoutPanel.Width, tableLayoutPanel.Height, PixelFormat.Format32bppArgb);
sl@14
   588
                iCreateBitmap = true;
sl@14
   589
            }
sl@14
   590
        }
sl@14
   591
sl@17
   592
        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
sl@17
   593
        {
sl@17
   594
            StopServer();
sl@32
   595
            e.Cancel = iClosing;
sl@17
   596
        }
sl@17
   597
sl@17
   598
        public void StartServer()
sl@17
   599
        {
sl@17
   600
            iServiceHost = new ServiceHost
sl@17
   601
                (
sl@55
   602
                    typeof(Session),
sl@20
   603
                    new Uri[] { new Uri("net.tcp://localhost:8001/") }
sl@17
   604
                );
sl@17
   605
sl@55
   606
            iServiceHost.AddServiceEndpoint(typeof(IService), new NetTcpBinding(SecurityMode.None, true), "DisplayService");
sl@17
   607
            iServiceHost.Open();
sl@17
   608
        }
sl@17
   609
sl@17
   610
        public void StopServer()
sl@17
   611
        {
sl@32
   612
            if (iClients.Count > 0 && !iClosing)
sl@29
   613
            {
sl@29
   614
                //Tell our clients
sl@32
   615
                iClosing = true;
sl@29
   616
                BroadcastCloseEvent();
sl@29
   617
            }
sl@32
   618
            else if (iClosing)
sl@32
   619
            {
sl@32
   620
                if (MessageBox.Show("Force exit?", "Waiting for clients...", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
sl@32
   621
                {
sl@32
   622
                    iClosing = false; //We make sure we force close if asked twice
sl@32
   623
                }
sl@32
   624
            }
sl@32
   625
            else
sl@36
   626
            {
sl@32
   627
                //We removed that as it often lags for some reason
sl@32
   628
                //iServiceHost.Close();
sl@32
   629
            }
sl@17
   630
        }
sl@17
   631
sl@21
   632
        public void BroadcastCloseEvent()
sl@21
   633
        {
sl@31
   634
            Trace.TraceInformation("BroadcastCloseEvent - start");
sl@31
   635
sl@21
   636
            var inactiveClients = new List<string>();
sl@21
   637
            foreach (var client in iClients)
sl@21
   638
            {
sl@21
   639
                //if (client.Key != eventData.ClientName)
sl@21
   640
                {
sl@21
   641
                    try
sl@21
   642
                    {
sl@31
   643
                        Trace.TraceInformation("BroadcastCloseEvent - " + client.Key);
sl@33
   644
                        client.Value.Callback.OnCloseOrder(/*eventData*/);
sl@21
   645
                    }
sl@21
   646
                    catch (Exception ex)
sl@21
   647
                    {
sl@21
   648
                        inactiveClients.Add(client.Key);
sl@21
   649
                    }
sl@21
   650
                }
sl@21
   651
            }
sl@21
   652
sl@21
   653
            if (inactiveClients.Count > 0)
sl@21
   654
            {
sl@21
   655
                foreach (var client in inactiveClients)
sl@21
   656
                {
sl@21
   657
                    iClients.Remove(client);
sl@30
   658
                    Program.iMainForm.treeViewClients.Nodes.Remove(Program.iMainForm.treeViewClients.Nodes.Find(client, false)[0]);
sl@21
   659
                }
sl@21
   660
            }
sl@21
   661
        }
sl@21
   662
sl@25
   663
        private void buttonStartClient_Click(object sender, EventArgs e)
sl@25
   664
        {
sl@25
   665
            Thread clientThread = new Thread(SharpDisplayClient.Program.Main);
sl@25
   666
            clientThread.Start();
sl@36
   667
            BringToFront();
sl@25
   668
        }
sl@25
   669
sl@27
   670
        private void buttonSuspend_Click(object sender, EventArgs e)
sl@27
   671
        {
sl@52
   672
            LastTickTime = DateTime.Now; //Reset timer to prevent jump
sl@27
   673
            timer.Enabled = !timer.Enabled;
sl@27
   674
            if (!timer.Enabled)
sl@27
   675
            {
sl@52
   676
                buttonSuspend.Text = "Run";
sl@27
   677
            }
sl@27
   678
            else
sl@27
   679
            {
sl@27
   680
                buttonSuspend.Text = "Pause";
sl@27
   681
            }
sl@27
   682
        }
sl@27
   683
sl@29
   684
        private void buttonCloseClients_Click(object sender, EventArgs e)
sl@29
   685
        {
sl@29
   686
            BroadcastCloseEvent();
sl@29
   687
        }
sl@29
   688
sl@30
   689
        private void treeViewClients_AfterSelect(object sender, TreeViewEventArgs e)
sl@30
   690
        {
sl@21
   691
sl@30
   692
        }
sl@30
   693
sl@36
   694
        //Delegates are used for our thread safe method
sl@55
   695
        public delegate void AddClientDelegate(string aSessionId, ICallback aCallback);
sl@30
   696
        public delegate void RemoveClientDelegate(string aSessionId);
sl@43
   697
        public delegate void SetTextDelegate(string SessionId, TextField aTextField);
sl@43
   698
        public delegate void SetTextsDelegate(string SessionId, System.Collections.Generic.IList<TextField> aTextFields);
sl@32
   699
        public delegate void SetClientNameDelegate(string aSessionId, string aName);
sl@30
   700
sl@36
   701
sl@30
   702
        /// <summary>
sl@36
   703
        ///
sl@30
   704
        /// </summary>
sl@30
   705
        /// <param name="aSessionId"></param>
sl@30
   706
        /// <param name="aCallback"></param>
sl@55
   707
        public void AddClientThreadSafe(string aSessionId, ICallback aCallback)
sl@30
   708
        {
sl@33
   709
            if (this.InvokeRequired)
sl@30
   710
            {
sl@30
   711
                //Not in the proper thread, invoke ourselves
sl@30
   712
                AddClientDelegate d = new AddClientDelegate(AddClientThreadSafe);
sl@30
   713
                this.Invoke(d, new object[] { aSessionId, aCallback });
sl@30
   714
            }
sl@30
   715
            else
sl@30
   716
            {
sl@30
   717
                //We are in the proper thread
sl@30
   718
                //Add this session to our collection of clients
sl@33
   719
                ClientData newClient = new ClientData(aSessionId, aCallback);
sl@33
   720
                Program.iMainForm.iClients.Add(aSessionId, newClient);
sl@30
   721
                //Add this session to our UI
sl@33
   722
                UpdateClientTreeViewNode(newClient);
sl@30
   723
            }
sl@30
   724
        }
sl@30
   725
sl@30
   726
        /// <summary>
sl@36
   727
        ///
sl@30
   728
        /// </summary>
sl@30
   729
        /// <param name="aSessionId"></param>
sl@30
   730
        public void RemoveClientThreadSafe(string aSessionId)
sl@30
   731
        {
sl@33
   732
            if (this.InvokeRequired)
sl@30
   733
            {
sl@30
   734
                //Not in the proper thread, invoke ourselves
sl@30
   735
                RemoveClientDelegate d = new RemoveClientDelegate(RemoveClientThreadSafe);
sl@30
   736
                this.Invoke(d, new object[] { aSessionId });
sl@30
   737
            }
sl@30
   738
            else
sl@30
   739
            {
sl@30
   740
                //We are in the proper thread
sl@33
   741
                //Remove this session from both client collection and UI tree view
sl@30
   742
                if (Program.iMainForm.iClients.Keys.Contains(aSessionId))
sl@30
   743
                {
sl@30
   744
                    Program.iMainForm.iClients.Remove(aSessionId);
sl@30
   745
                    Program.iMainForm.treeViewClients.Nodes.Remove(Program.iMainForm.treeViewClients.Nodes.Find(aSessionId, false)[0]);
sl@32
   746
                }
sl@32
   747
sl@32
   748
                if (iClosing && iClients.Count == 0)
sl@32
   749
                {
sl@32
   750
                    //We were closing our form
sl@32
   751
                    //All clients are now closed
sl@32
   752
                    //Just resume our close operation
sl@32
   753
                    iClosing = false;
sl@32
   754
                    Close();
sl@32
   755
                }
sl@30
   756
            }
sl@30
   757
        }
sl@30
   758
sl@30
   759
        /// <summary>
sl@36
   760
        ///
sl@30
   761
        /// </summary>
sl@30
   762
        /// <param name="aLineIndex"></param>
sl@30
   763
        /// <param name="aText"></param>
sl@43
   764
        public void SetTextThreadSafe(string aSessionId, TextField aTextField)
sl@30
   765
        {
sl@33
   766
            if (this.InvokeRequired)
sl@30
   767
            {
sl@30
   768
                //Not in the proper thread, invoke ourselves
sl@30
   769
                SetTextDelegate d = new SetTextDelegate(SetTextThreadSafe);
sl@43
   770
                this.Invoke(d, new object[] { aSessionId, aTextField });
sl@30
   771
            }
sl@30
   772
            else
sl@30
   773
            {
sl@34
   774
                ClientData client = iClients[aSessionId];
sl@34
   775
                if (client != null)
sl@30
   776
                {
sl@34
   777
                    //Make sure all our texts are in place
sl@43
   778
                    while (client.Texts.Count < (aTextField.Index + 1))
sl@34
   779
                    {
sl@43
   780
                        //Add a text field with proper index
sl@43
   781
                        client.Texts.Add(new TextField(client.Texts.Count));
sl@34
   782
                    }
sl@43
   783
                    client.Texts[aTextField.Index] = aTextField;
sl@34
   784
sl@34
   785
                    //We are in the proper thread
sl@60
   786
                    MarqueeLabel label = (MarqueeLabel)tableLayoutPanel.Controls[aTextField.Index];
sl@60
   787
                    label.Text = aTextField.Text;
sl@60
   788
                    label.TextAlign = aTextField.Alignment;
sl@60
   789
                    //
sl@34
   790
                    UpdateClientTreeViewNode(client);
sl@30
   791
                }
sl@30
   792
            }
sl@30
   793
        }
sl@30
   794
sl@30
   795
        /// <summary>
sl@36
   796
        ///
sl@30
   797
        /// </summary>
sl@30
   798
        /// <param name="aTexts"></param>
sl@43
   799
        public void SetTextsThreadSafe(string aSessionId, System.Collections.Generic.IList<TextField> aTextFields)
sl@30
   800
        {
sl@33
   801
            if (this.InvokeRequired)
sl@30
   802
            {
sl@30
   803
                //Not in the proper thread, invoke ourselves
sl@30
   804
                SetTextsDelegate d = new SetTextsDelegate(SetTextsThreadSafe);
sl@43
   805
                this.Invoke(d, new object[] { aSessionId, aTextFields });
sl@30
   806
            }
sl@30
   807
            else
sl@30
   808
            {
sl@43
   809
                //We are in the proper thread
sl@34
   810
                ClientData client = iClients[aSessionId];
sl@34
   811
                if (client != null)
sl@30
   812
                {
sl@43
   813
                    //Populate our client with the given text fields
sl@34
   814
                    int j = 0;
sl@43
   815
                    foreach (TextField textField in aTextFields)
sl@30
   816
                    {
sl@34
   817
                        if (client.Texts.Count < (j + 1))
sl@34
   818
                        {
sl@43
   819
                            client.Texts.Add(textField);
sl@34
   820
                        }
sl@34
   821
                        else
sl@34
   822
                        {
sl@43
   823
                            client.Texts[j] = textField;
sl@34
   824
                        }
sl@34
   825
                        j++;
sl@54
   826
                    }
sl@34
   827
                    //Only support two lines for now
sl@43
   828
                    for (int i = 0; i < aTextFields.Count; i++)
sl@30
   829
                    {
sl@60
   830
                        MarqueeLabel label = (MarqueeLabel)tableLayoutPanel.Controls[aTextFields[i].Index];
sl@60
   831
                        label.Text = aTextFields[i].Text;
sl@60
   832
                        label.TextAlign = aTextFields[i].Alignment;
sl@30
   833
                    }
sl@34
   834
sl@34
   835
sl@34
   836
                    UpdateClientTreeViewNode(client);
sl@30
   837
                }
sl@30
   838
            }
sl@32
   839
        }
sl@30
   840
sl@32
   841
sl@32
   842
        /// <summary>
sl@36
   843
        ///
sl@32
   844
        /// </summary>
sl@32
   845
        /// <param name="aSessionId"></param>
sl@32
   846
        /// <param name="aName"></param>
sl@32
   847
        public void SetClientNameThreadSafe(string aSessionId, string aName)
sl@32
   848
        {
sl@32
   849
            if (this.InvokeRequired)
sl@32
   850
            {
sl@32
   851
                //Not in the proper thread, invoke ourselves
sl@32
   852
                SetClientNameDelegate d = new SetClientNameDelegate(SetClientNameThreadSafe);
sl@32
   853
                this.Invoke(d, new object[] { aSessionId, aName });
sl@32
   854
            }
sl@32
   855
            else
sl@32
   856
            {
sl@32
   857
                //We are in the proper thread
sl@33
   858
                //Get our client
sl@33
   859
                ClientData client = iClients[aSessionId];
sl@33
   860
                if (client != null)
sl@32
   861
                {
sl@33
   862
                    //Set its name
sl@33
   863
                    client.Name = aName;
sl@33
   864
                    //Update our tree-view
sl@33
   865
                    UpdateClientTreeViewNode(client);
sl@33
   866
                }
sl@33
   867
            }
sl@33
   868
        }
sl@33
   869
sl@33
   870
        /// <summary>
sl@36
   871
        ///
sl@33
   872
        /// </summary>
sl@33
   873
        /// <param name="aClient"></param>
sl@33
   874
        private void UpdateClientTreeViewNode(ClientData aClient)
sl@33
   875
        {
sl@33
   876
            if (aClient == null)
sl@33
   877
            {
sl@33
   878
                return;
sl@33
   879
            }
sl@33
   880
sl@33
   881
            TreeNode node = null;
sl@33
   882
            //Check that our client node already exists
sl@33
   883
            //Get our client root node using its key which is our session ID
sl@33
   884
            TreeNode[] nodes = treeViewClients.Nodes.Find(aClient.SessionId, false);
sl@33
   885
            if (nodes.Count()>0)
sl@33
   886
            {
sl@33
   887
                //We already have a node for that client
sl@33
   888
                node = nodes[0];
sl@33
   889
                //Clear children as we are going to recreate them below
sl@33
   890
                node.Nodes.Clear();
sl@33
   891
            }
sl@33
   892
            else
sl@33
   893
            {
sl@33
   894
                //Client node does not exists create a new one
sl@33
   895
                treeViewClients.Nodes.Add(aClient.SessionId, aClient.SessionId);
sl@33
   896
                node = treeViewClients.Nodes.Find(aClient.SessionId, false)[0];
sl@33
   897
            }
sl@33
   898
sl@33
   899
            if (node != null)
sl@33
   900
            {
sl@33
   901
                //Change its name
sl@33
   902
                if (aClient.Name != "")
sl@33
   903
                {
sl@33
   904
                    //We have a name, us it as text for our root node
sl@33
   905
                    node.Text = aClient.Name;
sl@32
   906
                    //Add a child with SessionId
sl@33
   907
                    node.Nodes.Add(new TreeNode(aClient.SessionId));
sl@33
   908
                }
sl@33
   909
                else
sl@33
   910
                {
sl@33
   911
                    //No name, use session ID instead
sl@33
   912
                    node.Text = aClient.SessionId;
sl@33
   913
                }
sl@36
   914
sl@33
   915
                if (aClient.Texts.Count > 0)
sl@33
   916
                {
sl@33
   917
                    //Create root node for our texts
sl@33
   918
                    TreeNode textsRoot = new TreeNode("Text");
sl@33
   919
                    node.Nodes.Add(textsRoot);
sl@33
   920
                    //For each text add a new entry
sl@43
   921
                    foreach (TextField field in aClient.Texts)
sl@33
   922
                    {
sl@43
   923
                        textsRoot.Nodes.Add(new TreeNode(field.Text));
sl@33
   924
                    }
sl@32
   925
                }
sl@34
   926
sl@34
   927
                node.ExpandAll();
sl@32
   928
            }
sl@30
   929
        }
sl@17
   930
sl@38
   931
        private void buttonAddRow_Click(object sender, EventArgs e)
sl@38
   932
        {
sl@38
   933
            if (tableLayoutPanel.RowCount < 6)
sl@38
   934
            {
sl@61
   935
                RecreateTableLayoutPanel(tableLayoutPanel.ColumnCount, tableLayoutPanel.RowCount + 1);
sl@38
   936
                CheckFontHeight();
sl@38
   937
            }
sl@38
   938
        }
sl@38
   939
sl@38
   940
        private void buttonRemoveRow_Click(object sender, EventArgs e)
sl@38
   941
        {
sl@38
   942
            if (tableLayoutPanel.RowCount > 1)
sl@38
   943
            {
sl@61
   944
                RecreateTableLayoutPanel(tableLayoutPanel.ColumnCount, tableLayoutPanel.RowCount - 1);
sl@38
   945
                CheckFontHeight();
sl@38
   946
            }
sl@60
   947
sl@60
   948
            UpdateTableLayoutRowStyles();
sl@60
   949
        }
sl@60
   950
sl@60
   951
        /// <summary>
sl@60
   952
        /// Update our table layout row styles to make sure each rows have similar height
sl@60
   953
        /// </summary>
sl@60
   954
        private void UpdateTableLayoutRowStyles()
sl@60
   955
        {
sl@60
   956
            foreach (RowStyle rowStyle in tableLayoutPanel.RowStyles)
sl@60
   957
            {
sl@60
   958
                rowStyle.SizeType = SizeType.Percent;
sl@60
   959
                rowStyle.Height = 100 / tableLayoutPanel.RowCount;
sl@60
   960
            }
sl@60
   961
        }
sl@60
   962
sl@60
   963
        /// <summary>
sl@61
   964
        /// Empty and recreate our table layout with the given number of columns and rows.
sl@61
   965
        /// Sizes of rows and columns are uniform.
sl@60
   966
        /// </summary>
sl@60
   967
        /// <param name="aColumn"></param>
sl@60
   968
        /// <param name="aRow"></param>
sl@61
   969
        private void RecreateTableLayoutPanel(int aColumn, int aRow)
sl@60
   970
        {
sl@61
   971
            tableLayoutPanel.Controls.Clear();
sl@61
   972
            tableLayoutPanel.RowStyles.Clear();
sl@61
   973
            tableLayoutPanel.ColumnStyles.Clear();
sl@61
   974
            tableLayoutPanel.RowCount = 0;
sl@61
   975
            tableLayoutPanel.ColumnCount = 0;
sl@60
   976
sl@61
   977
            while (tableLayoutPanel.RowCount < aRow)
sl@61
   978
            {
sl@61
   979
                tableLayoutPanel.RowCount++;
sl@61
   980
            }
sl@60
   981
sl@61
   982
            while (tableLayoutPanel.ColumnCount < aColumn)
sl@61
   983
            {
sl@61
   984
                tableLayoutPanel.ColumnCount++;
sl@61
   985
            }
sl@61
   986
sl@61
   987
            for (int i = 0; i < tableLayoutPanel.ColumnCount; i++)
sl@61
   988
            {
sl@61
   989
                //Create our column styles
sl@61
   990
                this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100 / tableLayoutPanel.ColumnCount));
sl@61
   991
sl@61
   992
                for (int j = 0; j < tableLayoutPanel.RowCount; j++)
sl@61
   993
                {
sl@61
   994
                    if (i == 0)
sl@61
   995
                    {
sl@61
   996
                        //Create our row styles
sl@61
   997
                        this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100 / tableLayoutPanel.RowCount));
sl@61
   998
                    }
sl@61
   999
sl@61
  1000
                    MarqueeLabel control = new SharpDisplayManager.MarqueeLabel();
sl@61
  1001
                    control.AutoEllipsis = true;
sl@61
  1002
                    control.AutoSize = true;
sl@61
  1003
                    control.BackColor = System.Drawing.Color.Transparent;
sl@61
  1004
                    control.Dock = System.Windows.Forms.DockStyle.Fill;
sl@61
  1005
                    control.Location = new System.Drawing.Point(1, 1);
sl@61
  1006
                    control.Margin = new System.Windows.Forms.Padding(0);
sl@61
  1007
                    control.Name = "marqueeLabelCol" + aColumn + "Row" + aRow;
sl@61
  1008
                    control.OwnTimer = false;
sl@61
  1009
                    control.PixelsPerSecond = 64;
sl@61
  1010
                    control.Separator = "|";
sl@61
  1011
                    //control.Size = new System.Drawing.Size(254, 30);
sl@61
  1012
                    //control.TabIndex = 2;
sl@61
  1013
                    control.Font = cds.Font;
sl@61
  1014
                    control.Text = "ABCDEFGHIJKLMNOPQRST-0123456789";
sl@61
  1015
                    control.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
sl@61
  1016
                    control.UseCompatibleTextRendering = true;
sl@61
  1017
                    //
sl@61
  1018
                    tableLayoutPanel.Controls.Add(control, i, j);
sl@61
  1019
                }
sl@61
  1020
            }
sl@38
  1021
        }
sl@38
  1022
sl@38
  1023
        private void buttonAddColumn_Click(object sender, EventArgs e)
sl@38
  1024
        {
sl@38
  1025
            if (tableLayoutPanel.ColumnCount < 8)
sl@38
  1026
            {
sl@61
  1027
                RecreateTableLayoutPanel(tableLayoutPanel.ColumnCount + 1, tableLayoutPanel.RowCount);
sl@38
  1028
                //CheckFontHeight();
sl@38
  1029
            }
sl@38
  1030
        }
sl@38
  1031
sl@38
  1032
        private void buttonRemoveColumn_Click(object sender, EventArgs e)
sl@38
  1033
        {
sl@38
  1034
            if (tableLayoutPanel.ColumnCount > 1)
sl@38
  1035
            {
sl@61
  1036
                RecreateTableLayoutPanel(tableLayoutPanel.ColumnCount - 1, tableLayoutPanel.RowCount);
sl@38
  1037
                //CheckFontHeight();
sl@38
  1038
            }
sl@38
  1039
        }
sl@38
  1040
sl@41
  1041
        private void buttonAlignLeft_Click(object sender, EventArgs e)
sl@41
  1042
        {
sl@60
  1043
            foreach (MarqueeLabel ctrl in tableLayoutPanel.Controls)
sl@60
  1044
            {
sl@60
  1045
                ctrl.TextAlign = ContentAlignment.MiddleLeft;
sl@60
  1046
            }
sl@41
  1047
        }
sl@41
  1048
sl@41
  1049
        private void buttonAlignCenter_Click(object sender, EventArgs e)
sl@41
  1050
        {
sl@60
  1051
            foreach (MarqueeLabel ctrl in tableLayoutPanel.Controls)
sl@60
  1052
            {
sl@60
  1053
                ctrl.TextAlign = ContentAlignment.MiddleCenter;
sl@60
  1054
            }
sl@41
  1055
        }
sl@41
  1056
sl@41
  1057
        private void buttonAlignRight_Click(object sender, EventArgs e)
sl@41
  1058
        {
sl@60
  1059
            foreach (MarqueeLabel ctrl in tableLayoutPanel.Controls)
sl@60
  1060
            {
sl@60
  1061
                ctrl.TextAlign = ContentAlignment.MiddleRight;
sl@60
  1062
            }
sl@41
  1063
        }
sl@36
  1064
sl@46
  1065
        private void comboBoxDisplayType_SelectedIndexChanged(object sender, EventArgs e)
sl@46
  1066
        {
sl@48
  1067
            Properties.Settings.Default.CurrentDisplayIndex = comboBoxDisplayType.SelectedIndex;
sl@48
  1068
            cds.DisplayType = comboBoxDisplayType.SelectedIndex;
sl@46
  1069
            Properties.Settings.Default.Save();
sl@51
  1070
            if (iDisplay.IsOpen())
sl@51
  1071
            {
sl@51
  1072
                OpenDisplayConnection();
sl@51
  1073
            }
sl@51
  1074
            else
sl@51
  1075
            {
sl@51
  1076
                UpdateStatus();
sl@51
  1077
            }
sl@46
  1078
        }
sl@46
  1079
sl@47
  1080
sl@47
  1081
        private void maskedTextBoxTimerInterval_TextChanged(object sender, EventArgs e)
sl@47
  1082
        {
sl@47
  1083
            if (maskedTextBoxTimerInterval.Text != "")
sl@47
  1084
            {
sl@51
  1085
                int interval = Convert.ToInt32(maskedTextBoxTimerInterval.Text);
sl@51
  1086
sl@51
  1087
                if (interval > 0)
sl@51
  1088
                {
sl@51
  1089
                    timer.Interval = interval;
sl@51
  1090
                    cds.TimerInterval = timer.Interval;
sl@51
  1091
                    Properties.Settings.Default.Save();
sl@51
  1092
                }
sl@47
  1093
            }
sl@47
  1094
        }
sl@47
  1095
sl@52
  1096
        private void buttonPowerOn_Click(object sender, EventArgs e)
sl@52
  1097
        {
sl@52
  1098
            iDisplay.PowerOn();
sl@52
  1099
        }
sl@52
  1100
sl@52
  1101
        private void buttonPowerOff_Click(object sender, EventArgs e)
sl@52
  1102
        {
sl@52
  1103
            iDisplay.PowerOff();
sl@52
  1104
        }
sl@52
  1105
sl@53
  1106
        private void buttonShowClock_Click(object sender, EventArgs e)
sl@53
  1107
        {
sl@53
  1108
            iDisplay.ShowClock();
sl@53
  1109
        }
sl@53
  1110
sl@53
  1111
        private void buttonHideClock_Click(object sender, EventArgs e)
sl@53
  1112
        {
sl@53
  1113
            iDisplay.HideClock();
sl@53
  1114
        }
sl@0
  1115
    }
sl@34
  1116
sl@34
  1117
    /// <summary>
sl@34
  1118
    /// A UI thread copy of a client relevant data.
sl@34
  1119
    /// Keeping this copy in the UI thread helps us deal with threading issues.
sl@34
  1120
    /// </summary>
sl@34
  1121
    public class ClientData
sl@34
  1122
    {
sl@55
  1123
        public ClientData(string aSessionId, ICallback aCallback)
sl@34
  1124
        {
sl@34
  1125
            SessionId = aSessionId;
sl@34
  1126
            Name = "";
sl@43
  1127
            Texts = new List<TextField>();
sl@34
  1128
            Callback = aCallback;
sl@34
  1129
        }
sl@34
  1130
sl@34
  1131
        public string SessionId { get; set; }
sl@34
  1132
        public string Name { get; set; }
sl@43
  1133
        public List<TextField> Texts { get; set; }
sl@55
  1134
        public ICallback Callback { get; set; }
sl@34
  1135
    }
sl@0
  1136
}