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