Server/MainForm.cs
author sl
Fri, 15 Aug 2014 13:26:38 +0200
changeset 32 4c416d2878dd
parent 31 f19b04646b6a
child 33 1363bda20171
permissions -rw-r--r--
Reworking our protocols. Client name now displayed in our clients tab.
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@22
    17
using SharpDisplayInterface;
sl@25
    18
using SharpDisplayClient;
sl@14
    19
sl@0
    20
sl@0
    21
namespace SharpDisplayManager
sl@0
    22
{
sl@0
    23
    public partial class MainForm : Form
sl@0
    24
    {
sl@2
    25
        DateTime LastTickTime;
sl@3
    26
        Display iDisplay;
sl@14
    27
        System.Drawing.Bitmap iBmp;
sl@14
    28
        bool iCreateBitmap; //Workaround render to bitmap issues when minimized
sl@17
    29
        ServiceHost iServiceHost;
sl@21
    30
        /// <summary>
sl@21
    31
        /// Our collection of clients
sl@21
    32
        /// </summary>
sl@21
    33
        public Dictionary<string, IDisplayServiceCallback> iClients;
sl@29
    34
        public bool iClosing;
sl@2
    35
sl@0
    36
        public MainForm()
sl@0
    37
        {
sl@2
    38
            LastTickTime = DateTime.Now;
sl@3
    39
            iDisplay = new Display();
sl@21
    40
            iClients = new Dictionary<string, IDisplayServiceCallback>();
sl@2
    41
sl@0
    42
            InitializeComponent();
sl@7
    43
            UpdateStatus();
sl@13
    44
sl@8
    45
            //Load settings
sl@8
    46
            marqueeLabelTop.Font = Properties.Settings.Default.DisplayFont;
sl@8
    47
            marqueeLabelBottom.Font = Properties.Settings.Default.DisplayFont;
sl@9
    48
            checkBoxShowBorders.Checked = Properties.Settings.Default.DisplayShowBorders;
sl@13
    49
            checkBoxConnectOnStartup.Checked = Properties.Settings.Default.DisplayConnectOnStartup;
sl@16
    50
            checkBoxReverseScreen.Checked = Properties.Settings.Default.DisplayReverseScreen;
sl@13
    51
            //
sl@13
    52
            tableLayoutPanel.CellBorderStyle = (checkBoxShowBorders.Checked ? TableLayoutPanelCellBorderStyle.Single : TableLayoutPanelCellBorderStyle.None);
sl@14
    53
            //We have a bug when drawing minimized and reusing our bitmap
sl@14
    54
            iBmp = new System.Drawing.Bitmap(tableLayoutPanel.Width, tableLayoutPanel.Height, PixelFormat.Format32bppArgb);
sl@14
    55
            iCreateBitmap = false;
sl@0
    56
        }
sl@0
    57
sl@13
    58
        private void MainForm_Load(object sender, EventArgs e)
sl@13
    59
        {
sl@17
    60
            StartServer();
sl@17
    61
sl@13
    62
            if (Properties.Settings.Default.DisplayConnectOnStartup)
sl@13
    63
            {
sl@13
    64
                iDisplay.Open();
sl@13
    65
                UpdateStatus();
sl@13
    66
            }
sl@13
    67
        }
sl@13
    68
sl@13
    69
sl@0
    70
        private void buttonFont_Click(object sender, EventArgs e)
sl@0
    71
        {
sl@0
    72
            //fontDialog.ShowColor = true;
sl@0
    73
            //fontDialog.ShowApply = true;
sl@0
    74
            fontDialog.ShowEffects = true;
sl@11
    75
            fontDialog.Font = marqueeLabelTop.Font;
sl@28
    76
sl@28
    77
            fontDialog.FixedPitchOnly = checkBoxFixedPitchFontOnly.Checked;
sl@28
    78
sl@0
    79
            //fontDialog.ShowHelp = true;
sl@0
    80
sl@0
    81
            //fontDlg.MaxSize = 40;
sl@0
    82
            //fontDlg.MinSize = 22;
sl@0
    83
sl@0
    84
            //fontDialog.Parent = this;
sl@0
    85
            //fontDialog.StartPosition = FormStartPosition.CenterParent;
sl@0
    86
sl@0
    87
            //DlgBox.ShowDialog(fontDialog);
sl@0
    88
sl@0
    89
            //if (fontDialog.ShowDialog(this) != DialogResult.Cancel)
sl@0
    90
            if (DlgBox.ShowDialog(fontDialog) != DialogResult.Cancel)
sl@0
    91
            {
sl@0
    92
sl@4
    93
                //MsgBox.Show("MessageBox MsgBox", "MsgBox caption");
sl@0
    94
sl@0
    95
                //MessageBox.Show("Ok");
sl@4
    96
                marqueeLabelTop.Font = fontDialog.Font;
sl@4
    97
                marqueeLabelBottom.Font = fontDialog.Font;
sl@8
    98
                Properties.Settings.Default.DisplayFont = fontDialog.Font;
sl@8
    99
                Properties.Settings.Default.Save();
sl@0
   100
                //label1.Font = fontDlg.Font;
sl@0
   101
                //textBox1.BackColor = fontDlg.Color;
sl@0
   102
                //label1.ForeColor = fontDlg.Color;
sl@0
   103
            }
sl@0
   104
        }
sl@0
   105
sl@0
   106
        private void buttonCapture_Click(object sender, EventArgs e)
sl@0
   107
        {
sl@0
   108
            System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(tableLayoutPanel.Width, tableLayoutPanel.Height);
sl@0
   109
            tableLayoutPanel.DrawToBitmap(bmp, tableLayoutPanel.ClientRectangle);
sl@14
   110
            //Bitmap bmpToSave = new Bitmap(bmp);
sl@14
   111
            bmp.Save("D:\\capture.png");
sl@14
   112
sl@17
   113
            marqueeLabelTop.Text = "Sweet";
sl@17
   114
sl@14
   115
            /*
sl@14
   116
            string outputFileName = "d:\\capture.png";
sl@14
   117
            using (MemoryStream memory = new MemoryStream())
sl@14
   118
            {
sl@14
   119
                using (FileStream fs = new FileStream(outputFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite))
sl@14
   120
                {
sl@14
   121
                    bmp.Save(memory, System.Drawing.Imaging.ImageFormat.Png);
sl@14
   122
                    byte[] bytes = memory.ToArray();
sl@14
   123
                    fs.Write(bytes, 0, bytes.Length);
sl@14
   124
                }
sl@14
   125
            }
sl@14
   126
             */
sl@14
   127
sl@0
   128
        }
sl@2
   129
sl@12
   130
        private void CheckForRequestResults()
sl@12
   131
        {
sl@12
   132
            if (iDisplay.IsRequestPending())
sl@12
   133
            {
sl@12
   134
                switch (iDisplay.AttemptRequestCompletion())
sl@12
   135
                {
sl@12
   136
                    case Display.TMiniDisplayRequest.EMiniDisplayRequestPowerSupplyStatus:
sl@12
   137
                        if (iDisplay.PowerSupplyStatus())
sl@12
   138
                        {
sl@12
   139
                            toolStripStatusLabelPower.Text = "ON";
sl@12
   140
                        }
sl@12
   141
                        else
sl@12
   142
                        {
sl@12
   143
                            toolStripStatusLabelPower.Text = "OFF";
sl@12
   144
                        }
sl@12
   145
                        //Issue next request then
sl@12
   146
                        iDisplay.RequestDeviceId();
sl@12
   147
                        break;
sl@12
   148
sl@12
   149
                    case Display.TMiniDisplayRequest.EMiniDisplayRequestDeviceId:
sl@12
   150
                        toolStripStatusLabelConnect.Text += " - " + iDisplay.DeviceId();
sl@12
   151
                        //Issue next request then
sl@12
   152
                        iDisplay.RequestFirmwareRevision();
sl@12
   153
                        break;
sl@12
   154
sl@12
   155
                    case Display.TMiniDisplayRequest.EMiniDisplayRequestFirmwareRevision:
sl@12
   156
                        toolStripStatusLabelConnect.Text += " v" + iDisplay.FirmwareRevision();
sl@12
   157
                        //No more request to issue
sl@12
   158
                        break;
sl@12
   159
                }
sl@12
   160
            }
sl@12
   161
        }
sl@12
   162
sl@16
   163
sl@16
   164
        public delegate int CoordinateTranslationDelegate(System.Drawing.Bitmap aBmp, int aInt);
sl@16
   165
sl@16
   166
sl@16
   167
        public static int ScreenReversedX(System.Drawing.Bitmap aBmp, int aX)
sl@16
   168
        {
sl@16
   169
            return aBmp.Width - aX - 1;
sl@16
   170
        }
sl@16
   171
sl@16
   172
        public int ScreenReversedY(System.Drawing.Bitmap aBmp, int aY)
sl@16
   173
        {
sl@16
   174
            return iBmp.Height - aY - 1;
sl@16
   175
        }
sl@16
   176
sl@16
   177
        public int ScreenX(System.Drawing.Bitmap aBmp, int aX)
sl@16
   178
        {
sl@16
   179
            return aX;
sl@16
   180
        }
sl@16
   181
sl@16
   182
        public int ScreenY(System.Drawing.Bitmap aBmp, int aY)
sl@16
   183
        {
sl@16
   184
            return aY;
sl@16
   185
        }
sl@16
   186
sl@16
   187
sl@16
   188
        //This is our timer tick responsible to perform our render
sl@2
   189
        private void timer_Tick(object sender, EventArgs e)
sl@14
   190
        {
sl@2
   191
            //Update our animations
sl@2
   192
            DateTime NewTickTime = DateTime.Now;
sl@2
   193
sl@2
   194
            marqueeLabelTop.UpdateAnimation(LastTickTime, NewTickTime);
sl@2
   195
            marqueeLabelBottom.UpdateAnimation(LastTickTime, NewTickTime);
sl@2
   196
sl@4
   197
            //Update our display
sl@4
   198
            if (iDisplay.IsOpen())
sl@4
   199
            {
sl@12
   200
                CheckForRequestResults();
sl@12
   201
sl@22
   202
                //Draw to bitmap
sl@14
   203
                if (iCreateBitmap)
sl@14
   204
                {
sl@14
   205
                    iBmp = new System.Drawing.Bitmap(tableLayoutPanel.Width, tableLayoutPanel.Height, PixelFormat.Format32bppArgb);
sl@14
   206
                }
sl@14
   207
                tableLayoutPanel.DrawToBitmap(iBmp, tableLayoutPanel.ClientRectangle);
sl@14
   208
                //iBmp.Save("D:\\capture.png");
sl@16
   209
sl@16
   210
                //Select proper coordinate translation functions
sl@16
   211
                //We used delegate/function pointer to support reverse screen without doing an extra test on each pixels
sl@16
   212
                CoordinateTranslationDelegate screenX;
sl@16
   213
                CoordinateTranslationDelegate screenY;
sl@16
   214
sl@16
   215
                if (Properties.Settings.Default.DisplayReverseScreen)
sl@16
   216
                {
sl@16
   217
                    screenX = ScreenReversedX;
sl@16
   218
                    screenY = ScreenReversedY;
sl@16
   219
                }
sl@16
   220
                else
sl@16
   221
                {
sl@16
   222
                    screenX = ScreenX;
sl@16
   223
                    screenY = ScreenY;
sl@16
   224
                }
sl@22
   225
sl@7
   226
                //Send it to our display
sl@14
   227
                for (int i = 0; i < iBmp.Width; i++)
sl@4
   228
                {
sl@14
   229
                    for (int j = 0; j < iBmp.Height; j++)
sl@4
   230
                    {
sl@4
   231
                        unchecked
sl@4
   232
                        {
sl@14
   233
                            uint color = (uint)iBmp.GetPixel(i, j).ToArgb();
sl@14
   234
                            //For some reason when the app is minimized in the task bar only the alpha of our color is set.
sl@14
   235
                            //Thus that strange test for rendering to work both when the app is in the task bar and when it isn't.
sl@16
   236
                            iDisplay.SetPixel(screenX(iBmp, i), screenY(iBmp, j), Convert.ToInt32(!(color != 0xFF000000)));
sl@4
   237
                        }
sl@4
   238
                    }
sl@4
   239
                }
sl@4
   240
sl@4
   241
                iDisplay.SwapBuffers();
sl@4
   242
sl@4
   243
            }
sl@8
   244
sl@8
   245
            //Compute instant FPS
sl@8
   246
            toolStripStatusLabelFps.Text = (1.0/NewTickTime.Subtract(LastTickTime).TotalSeconds).ToString("F0") + " FPS";
sl@8
   247
sl@8
   248
            LastTickTime = NewTickTime;
sl@8
   249
sl@2
   250
        }
sl@3
   251
sl@3
   252
        private void buttonOpen_Click(object sender, EventArgs e)
sl@3
   253
        {
sl@3
   254
            if (iDisplay.Open())
sl@3
   255
            {
sl@7
   256
                UpdateStatus();
sl@12
   257
                iDisplay.RequestPowerSupplyStatus();
sl@3
   258
            }
sl@7
   259
            else
sl@7
   260
            {
sl@7
   261
                UpdateStatus();
sl@7
   262
                toolStripStatusLabelConnect.Text = "Connection error";
sl@7
   263
            }
sl@7
   264
sl@3
   265
        }
sl@3
   266
sl@3
   267
        private void buttonClose_Click(object sender, EventArgs e)
sl@3
   268
        {
sl@3
   269
            iDisplay.Close();
sl@9
   270
            UpdateStatus();
sl@3
   271
        }
sl@3
   272
sl@3
   273
        private void buttonClear_Click(object sender, EventArgs e)
sl@3
   274
        {
sl@3
   275
            iDisplay.Clear();
sl@3
   276
            iDisplay.SwapBuffers();
sl@3
   277
        }
sl@3
   278
sl@3
   279
        private void buttonFill_Click(object sender, EventArgs e)
sl@3
   280
        {
sl@3
   281
            iDisplay.Fill();
sl@3
   282
            iDisplay.SwapBuffers();
sl@3
   283
        }
sl@3
   284
sl@3
   285
        private void trackBarBrightness_Scroll(object sender, EventArgs e)
sl@3
   286
        {
sl@9
   287
            Properties.Settings.Default.DisplayBrightness = trackBarBrightness.Value;
sl@9
   288
            Properties.Settings.Default.Save();
sl@3
   289
            iDisplay.SetBrightness(trackBarBrightness.Value);
sl@9
   290
sl@3
   291
        }
sl@7
   292
sl@7
   293
        private void UpdateStatus()
sl@7
   294
        {
sl@7
   295
            if (iDisplay.IsOpen())
sl@7
   296
            {
sl@7
   297
                buttonFill.Enabled = true;
sl@7
   298
                buttonClear.Enabled = true;
sl@7
   299
                buttonOpen.Enabled = false;
sl@7
   300
                buttonClose.Enabled = true;
sl@7
   301
                trackBarBrightness.Enabled = true;
sl@7
   302
                trackBarBrightness.Minimum = iDisplay.MinBrightness();
sl@11
   303
                trackBarBrightness.Maximum = iDisplay.MaxBrightness();
sl@9
   304
                trackBarBrightness.Value = Properties.Settings.Default.DisplayBrightness;
sl@9
   305
                trackBarBrightness.LargeChange = Math.Max(1,(iDisplay.MaxBrightness() - iDisplay.MinBrightness())/5);
sl@9
   306
                trackBarBrightness.SmallChange = 1;
sl@9
   307
                iDisplay.SetBrightness(Properties.Settings.Default.DisplayBrightness);
sl@9
   308
sl@10
   309
                toolStripStatusLabelConnect.Text = "Connected - " + iDisplay.Vendor() + " - " + iDisplay.Product();
sl@10
   310
                //+ " - " + iDisplay.SerialNumber();
sl@7
   311
            }
sl@7
   312
            else
sl@7
   313
            {
sl@7
   314
                buttonFill.Enabled = false;
sl@7
   315
                buttonClear.Enabled = false;
sl@7
   316
                buttonOpen.Enabled = true;
sl@7
   317
                buttonClose.Enabled = false;
sl@7
   318
                trackBarBrightness.Enabled = false;
sl@9
   319
                toolStripStatusLabelConnect.Text = "Disconnected";
sl@7
   320
            }
sl@7
   321
        }
sl@9
   322
sl@13
   323
sl@13
   324
sl@9
   325
        private void checkBoxShowBorders_CheckedChanged(object sender, EventArgs e)
sl@9
   326
        {
sl@16
   327
            //Save our show borders setting
sl@13
   328
            tableLayoutPanel.CellBorderStyle = (checkBoxShowBorders.Checked ? TableLayoutPanelCellBorderStyle.Single : TableLayoutPanelCellBorderStyle.None);
sl@9
   329
            Properties.Settings.Default.DisplayShowBorders = checkBoxShowBorders.Checked;
sl@9
   330
            Properties.Settings.Default.Save();
sl@9
   331
        }
sl@13
   332
sl@13
   333
        private void checkBoxConnectOnStartup_CheckedChanged(object sender, EventArgs e)
sl@13
   334
        {
sl@16
   335
            //Save our connect on startup setting
sl@13
   336
            Properties.Settings.Default.DisplayConnectOnStartup = checkBoxConnectOnStartup.Checked;
sl@13
   337
            Properties.Settings.Default.Save();
sl@13
   338
        }
sl@13
   339
sl@16
   340
        private void checkBoxReverseScreen_CheckedChanged(object sender, EventArgs e)
sl@16
   341
        {
sl@16
   342
            //Save our reverse screen setting
sl@16
   343
            Properties.Settings.Default.DisplayReverseScreen = checkBoxReverseScreen.Checked;
sl@16
   344
            Properties.Settings.Default.Save();
sl@16
   345
        }
sl@16
   346
sl@14
   347
        private void MainForm_Resize(object sender, EventArgs e)
sl@14
   348
        {
sl@14
   349
            if (WindowState == FormWindowState.Minimized)
sl@14
   350
            {
sl@14
   351
                // Do some stuff
sl@14
   352
                //iBmp = new System.Drawing.Bitmap(tableLayoutPanel.Width, tableLayoutPanel.Height, PixelFormat.Format32bppArgb);
sl@14
   353
                iCreateBitmap = true;
sl@14
   354
            }
sl@14
   355
        }
sl@14
   356
sl@17
   357
        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
sl@17
   358
        {
sl@17
   359
            StopServer();
sl@32
   360
            e.Cancel = iClosing;
sl@17
   361
        }
sl@17
   362
sl@17
   363
        public void StartServer()
sl@17
   364
        {
sl@17
   365
            iServiceHost = new ServiceHost
sl@17
   366
                (
sl@17
   367
                    typeof(DisplayServer),
sl@20
   368
                    new Uri[] { new Uri("net.tcp://localhost:8001/") }
sl@17
   369
                );
sl@17
   370
sl@30
   371
            iServiceHost.AddServiceEndpoint(typeof(IDisplayService), new NetTcpBinding(SecurityMode.None,true), "DisplayService");
sl@17
   372
            iServiceHost.Open();
sl@17
   373
        }
sl@17
   374
sl@17
   375
        public void StopServer()
sl@17
   376
        {
sl@32
   377
            if (iClients.Count > 0 && !iClosing)
sl@29
   378
            {
sl@29
   379
                //Tell our clients
sl@32
   380
                iClosing = true;
sl@29
   381
                BroadcastCloseEvent();
sl@29
   382
            }
sl@32
   383
            else if (iClosing)
sl@32
   384
            {
sl@32
   385
                if (MessageBox.Show("Force exit?", "Waiting for clients...", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
sl@32
   386
                {
sl@32
   387
                    iClosing = false; //We make sure we force close if asked twice
sl@32
   388
                }
sl@32
   389
            }
sl@32
   390
            else
sl@32
   391
            {                
sl@32
   392
                //We removed that as it often lags for some reason
sl@32
   393
                //iServiceHost.Close();
sl@32
   394
            }
sl@17
   395
        }
sl@17
   396
sl@21
   397
        public void BroadcastCloseEvent()
sl@21
   398
        {
sl@31
   399
            Trace.TraceInformation("BroadcastCloseEvent - start");
sl@31
   400
sl@21
   401
            var inactiveClients = new List<string>();
sl@21
   402
            foreach (var client in iClients)
sl@21
   403
            {
sl@21
   404
                //if (client.Key != eventData.ClientName)
sl@21
   405
                {
sl@21
   406
                    try
sl@21
   407
                    {
sl@31
   408
                        Trace.TraceInformation("BroadcastCloseEvent - " + client.Key);
sl@32
   409
                        client.Value.OnCloseOrder(/*eventData*/);
sl@21
   410
                    }
sl@21
   411
                    catch (Exception ex)
sl@21
   412
                    {
sl@21
   413
                        inactiveClients.Add(client.Key);
sl@21
   414
                    }
sl@21
   415
                }
sl@21
   416
            }
sl@21
   417
sl@21
   418
            if (inactiveClients.Count > 0)
sl@21
   419
            {
sl@21
   420
                foreach (var client in inactiveClients)
sl@21
   421
                {
sl@21
   422
                    iClients.Remove(client);
sl@30
   423
                    Program.iMainForm.treeViewClients.Nodes.Remove(Program.iMainForm.treeViewClients.Nodes.Find(client, false)[0]);
sl@21
   424
                }
sl@21
   425
            }
sl@21
   426
        }
sl@21
   427
sl@25
   428
        private void buttonStartClient_Click(object sender, EventArgs e)
sl@25
   429
        {
sl@25
   430
            Thread clientThread = new Thread(SharpDisplayClient.Program.Main);
sl@25
   431
            clientThread.Start();
sl@25
   432
        }
sl@25
   433
sl@27
   434
        private void buttonSuspend_Click(object sender, EventArgs e)
sl@27
   435
        {
sl@27
   436
            timer.Enabled = !timer.Enabled;
sl@27
   437
            if (!timer.Enabled)
sl@27
   438
            {
sl@27
   439
                buttonSuspend.Text = "Suspend";
sl@27
   440
            }
sl@27
   441
            else
sl@27
   442
            {
sl@27
   443
                buttonSuspend.Text = "Pause";
sl@27
   444
            }
sl@27
   445
        }
sl@27
   446
sl@29
   447
        private void buttonCloseClients_Click(object sender, EventArgs e)
sl@29
   448
        {
sl@29
   449
            BroadcastCloseEvent();
sl@29
   450
        }
sl@29
   451
sl@30
   452
        private void treeViewClients_AfterSelect(object sender, TreeViewEventArgs e)
sl@30
   453
        {
sl@21
   454
sl@30
   455
        }
sl@30
   456
sl@30
   457
        public delegate void AddClientDelegate(string aSessionId, IDisplayServiceCallback aCallback);
sl@30
   458
        public delegate void RemoveClientDelegate(string aSessionId);
sl@30
   459
        public delegate void SetTextDelegate(int aLineIndex, string aText);
sl@30
   460
        public delegate void SetTextsDelegate(System.Collections.Generic.IList<string> aTexts);
sl@32
   461
        public delegate void SetClientNameDelegate(string aSessionId, string aName);
sl@30
   462
sl@30
   463
       
sl@30
   464
        /// <summary>
sl@30
   465
        /// 
sl@30
   466
        /// </summary>
sl@30
   467
        /// <param name="aSessionId"></param>
sl@30
   468
        /// <param name="aCallback"></param>
sl@30
   469
        public void AddClientThreadSafe(string aSessionId, IDisplayServiceCallback aCallback)
sl@30
   470
        {
sl@30
   471
            if (this.treeViewClients.InvokeRequired)
sl@30
   472
            {
sl@30
   473
                //Not in the proper thread, invoke ourselves
sl@30
   474
                AddClientDelegate d = new AddClientDelegate(AddClientThreadSafe);
sl@30
   475
                this.Invoke(d, new object[] { aSessionId, aCallback });
sl@30
   476
            }
sl@30
   477
            else
sl@30
   478
            {
sl@30
   479
                //We are in the proper thread
sl@30
   480
                //Add this session to our collection of clients
sl@30
   481
                Program.iMainForm.iClients.Add(aSessionId, aCallback);
sl@30
   482
                //Add this session to our UI
sl@30
   483
                Program.iMainForm.treeViewClients.Nodes.Add(aSessionId, aSessionId);
sl@30
   484
            }
sl@30
   485
        }
sl@30
   486
sl@30
   487
        /// <summary>
sl@30
   488
        /// 
sl@30
   489
        /// </summary>
sl@30
   490
        /// <param name="aSessionId"></param>
sl@30
   491
        public void RemoveClientThreadSafe(string aSessionId)
sl@30
   492
        {
sl@30
   493
            if (this.treeViewClients.InvokeRequired)
sl@30
   494
            {
sl@30
   495
                //Not in the proper thread, invoke ourselves
sl@30
   496
                RemoveClientDelegate d = new RemoveClientDelegate(RemoveClientThreadSafe);
sl@30
   497
                this.Invoke(d, new object[] { aSessionId });
sl@30
   498
            }
sl@30
   499
            else
sl@30
   500
            {
sl@30
   501
                //We are in the proper thread
sl@30
   502
                            //Remove this session from both client collection and UI tree view
sl@30
   503
                if (Program.iMainForm.iClients.Keys.Contains(aSessionId))
sl@30
   504
                {
sl@30
   505
                    Program.iMainForm.iClients.Remove(aSessionId);
sl@30
   506
                    Program.iMainForm.treeViewClients.Nodes.Remove(Program.iMainForm.treeViewClients.Nodes.Find(aSessionId, false)[0]);
sl@32
   507
                }
sl@32
   508
sl@32
   509
                if (iClosing && iClients.Count == 0)
sl@32
   510
                {
sl@32
   511
                    //We were closing our form
sl@32
   512
                    //All clients are now closed
sl@32
   513
                    //Just resume our close operation
sl@32
   514
                    iClosing = false;
sl@32
   515
                    Close();
sl@32
   516
                }
sl@30
   517
            }
sl@30
   518
        }
sl@30
   519
sl@30
   520
        /// <summary>
sl@30
   521
        /// 
sl@30
   522
        /// </summary>
sl@30
   523
        /// <param name="aLineIndex"></param>
sl@30
   524
        /// <param name="aText"></param>
sl@30
   525
        public void SetTextThreadSafe(int aLineIndex, string aText)
sl@30
   526
        {
sl@30
   527
            if (this.treeViewClients.InvokeRequired)
sl@30
   528
            {
sl@30
   529
                //Not in the proper thread, invoke ourselves
sl@30
   530
                SetTextDelegate d = new SetTextDelegate(SetTextThreadSafe);
sl@30
   531
                this.Invoke(d, new object[] { aLineIndex, aText });
sl@30
   532
            }
sl@30
   533
            else
sl@30
   534
            {
sl@30
   535
                //We are in the proper thread
sl@30
   536
                //Only support two lines for now
sl@30
   537
                if (aLineIndex == 0)
sl@30
   538
                {
sl@30
   539
                    Program.iMainForm.marqueeLabelTop.Text = aText;
sl@30
   540
                }
sl@30
   541
                else if (aLineIndex == 1)
sl@30
   542
                {
sl@30
   543
                    Program.iMainForm.marqueeLabelBottom.Text = aText;
sl@30
   544
                }
sl@30
   545
            }
sl@30
   546
        }
sl@30
   547
sl@30
   548
        /// <summary>
sl@30
   549
        /// 
sl@30
   550
        /// </summary>
sl@30
   551
        /// <param name="aTexts"></param>
sl@30
   552
        public void SetTextsThreadSafe(System.Collections.Generic.IList<string> aTexts)
sl@30
   553
        {
sl@30
   554
            if (this.treeViewClients.InvokeRequired)
sl@30
   555
            {
sl@30
   556
                //Not in the proper thread, invoke ourselves
sl@30
   557
                SetTextsDelegate d = new SetTextsDelegate(SetTextsThreadSafe);
sl@30
   558
                this.Invoke(d, new object[] { aTexts });
sl@30
   559
            }
sl@30
   560
            else
sl@30
   561
            {
sl@30
   562
                //We are in the proper thread
sl@30
   563
                //Only support two lines for now
sl@30
   564
                for (int i = 0; i < aTexts.Count; i++)
sl@30
   565
                {
sl@30
   566
                    if (i == 0)
sl@30
   567
                    {
sl@30
   568
                        Program.iMainForm.marqueeLabelTop.Text = aTexts[i];
sl@30
   569
                    }
sl@30
   570
                    else if (i == 1)
sl@30
   571
                    {
sl@30
   572
                        Program.iMainForm.marqueeLabelBottom.Text = aTexts[i];
sl@30
   573
                    }
sl@30
   574
                }
sl@30
   575
            }
sl@32
   576
        }
sl@30
   577
sl@32
   578
sl@32
   579
        /// <summary>
sl@32
   580
        /// 
sl@32
   581
        /// </summary>
sl@32
   582
        /// <param name="aSessionId"></param>
sl@32
   583
        /// <param name="aName"></param>
sl@32
   584
        public void SetClientNameThreadSafe(string aSessionId, string aName)
sl@32
   585
        {
sl@32
   586
            if (this.InvokeRequired)
sl@32
   587
            {
sl@32
   588
                //Not in the proper thread, invoke ourselves
sl@32
   589
                SetClientNameDelegate d = new SetClientNameDelegate(SetClientNameThreadSafe);
sl@32
   590
                this.Invoke(d, new object[] { aSessionId, aName });
sl@32
   591
            }
sl@32
   592
            else
sl@32
   593
            {
sl@32
   594
                //We are in the proper thread
sl@32
   595
                //Remove this session from both client collection and UI tree view
sl@32
   596
                if (Program.iMainForm.iClients.Keys.Contains(aSessionId))
sl@32
   597
                {
sl@32
   598
                    //Change our session node text 
sl@32
   599
                    TreeNode node = Program.iMainForm.treeViewClients.Nodes.Find(aSessionId, false)[0];
sl@32
   600
                    node.Text = aName;
sl@32
   601
                    //Add a child with SessionId
sl@32
   602
                    node.Nodes.Add(new TreeNode(aSessionId));
sl@32
   603
sl@32
   604
                    //Program.iMainForm.iClients.Remove(aSessionId);
sl@32
   605
                    //Program.iMainForm.treeViewClients.Nodes.Remove(Program.iMainForm.treeViewClients.Nodes.Find(aSessionId, false)[0]);
sl@32
   606
                }
sl@32
   607
            }
sl@30
   608
        }
sl@17
   609
sl@0
   610
    }
sl@0
   611
}