GUI/MainForm.cs
author moel.mich
Sun, 09 May 2010 16:22:13 +0000
changeset 110 411b72b73d8f
parent 86 b4f0f206173d
child 111 2b8a8cf92c3a
permissions -rw-r--r--
Refactored the hardware code and added the visitor pattern for operations on the computer/hardware/sensor/parameter tree.
     1 /*
     2   
     3   Version: MPL 1.1/GPL 2.0/LGPL 2.1
     4 
     5   The contents of this file are subject to the Mozilla Public License Version
     6   1.1 (the "License"); you may not use this file except in compliance with
     7   the License. You may obtain a copy of the License at
     8  
     9   http://www.mozilla.org/MPL/
    10 
    11   Software distributed under the License is distributed on an "AS IS" basis,
    12   WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    13   for the specific language governing rights and limitations under the License.
    14 
    15   The Original Code is the Open Hardware Monitor code.
    16 
    17   The Initial Developer of the Original Code is 
    18   Michael Möller <m.moeller@gmx.ch>.
    19   Portions created by the Initial Developer are Copyright (C) 2009-2010
    20   the Initial Developer. All Rights Reserved.
    21 
    22   Contributor(s):
    23 
    24   Alternatively, the contents of this file may be used under the terms of
    25   either the GNU General Public License Version 2 or later (the "GPL"), or
    26   the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    27   in which case the provisions of the GPL or the LGPL are applicable instead
    28   of those above. If you wish to allow use of your version of this file only
    29   under the terms of either the GPL or the LGPL, and not to allow others to
    30   use your version of this file under the terms of the MPL, indicate your
    31   decision by deleting the provisions above and replace them with the notice
    32   and other provisions required by the GPL or the LGPL. If you do not delete
    33   the provisions above, a recipient may use your version of this file under
    34   the terms of any one of the MPL, the GPL or the LGPL.
    35  
    36 */
    37 
    38 using System;
    39 using System.Collections.Generic;
    40 using System.ComponentModel;
    41 using System.Configuration;
    42 using System.Drawing;
    43 using System.IO;
    44 using System.Text;
    45 using System.Windows.Forms;
    46 using Aga.Controls.Tree;
    47 using Aga.Controls.Tree.NodeControls;
    48 using OpenHardwareMonitor.Hardware;
    49 using OpenHardwareMonitor.Utilities;
    50 
    51 namespace OpenHardwareMonitor.GUI {
    52   public partial class MainForm : Form {
    53 
    54     private Computer computer = new Computer();
    55     private Node root;
    56     private TreeModel treeModel;
    57     private IDictionary<ISensor, Color> sensorPlotColors = 
    58       new Dictionary<ISensor, Color>();
    59     private Color[] plotColorPalette;
    60     private SensorSystemTray sensorSystemTray;
    61     private NotifyIcon notifyIcon;
    62     private StartupManager startupManager = new StartupManager();
    63     private SensorProperties sensorProperties = new SensorProperties();
    64     private UpdateVisitor updateVisitor = new UpdateVisitor();
    65 
    66     public MainForm() {      
    67       InitializeComponent();
    68       this.Font = SystemFonts.MessageBoxFont;
    69       treeView.Font = SystemFonts.MessageBoxFont;
    70       plotPanel.Font = SystemFonts.MessageBoxFont;
    71       
    72       nodeCheckBox.IsVisibleValueNeeded += 
    73         new EventHandler<NodeControlValueEventArgs>(
    74           nodeCheckBox_IsVisibleValueNeeded);
    75       nodeCheckBox.CheckStateChanged += 
    76         new EventHandler<TreePathEventArgs>(UpdatePlotSelection);
    77       nodeTextBoxText.DrawText += 
    78         new EventHandler<DrawEventArgs>(nodeTextBoxText_DrawText);
    79       nodeTextBoxValue.DrawText +=
    80         new EventHandler<DrawEventArgs>(nodeTextBoxText_DrawText);
    81       nodeTextBoxMin.DrawText +=
    82         new EventHandler<DrawEventArgs>(nodeTextBoxText_DrawText);
    83       nodeTextBoxMax.DrawText +=
    84         new EventHandler<DrawEventArgs>(nodeTextBoxText_DrawText);
    85       nodeTextBoxLimit.DrawText += 
    86         new EventHandler<DrawEventArgs>(nodeTextBoxLimit_DrawText);
    87 
    88       if (Utilities.Config.Contains("mainForm.Location.X")) {
    89         int x = Utilities.Config.Get("mainForm.Location.X", Location.X);
    90         x = x < 0 ? 0 : x;
    91         int y = Utilities.Config.Get("mainForm.Location.Y", Location.Y);
    92         y = y < 0 ? 0 : y;
    93         this.Location = new Point(x, y);
    94       } else {
    95         StartPosition = FormStartPosition.CenterScreen;
    96       }
    97 
    98       Width = Utilities.Config.Get("mainForm.Width", Width);
    99       Height = Utilities.Config.Get("mainForm.Height", Height);
   100          
   101       treeModel = new TreeModel();
   102       root = new Node(System.Environment.MachineName);
   103       root.Image = Utilities.EmbeddedResources.GetImage("computer.png");
   104       
   105       treeModel.Nodes.Add(root);
   106       treeView.Model = treeModel;
   107       
   108       notifyIcon = new NotifyIcon();
   109       notifyIcon.ContextMenuStrip = this.notifyContextMenuStrip;
   110       notifyIcon.Icon = EmbeddedResources.GetIcon("smallicon.ico");
   111       notifyIcon.Text = "Open Hardware Monitor";      
   112       notifyIcon.DoubleClick += new EventHandler(this.hideShowClick);
   113 
   114       sensorSystemTray = new SensorSystemTray(computer);
   115 
   116       computer.HardwareAdded += new HardwareEventHandler(HardwareAdded);
   117       computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved);
   118       computer.Open();
   119 
   120       timer.Enabled = true;
   121 
   122       plotColorPalette = new Color[14];
   123       plotColorPalette[0] = Color.Blue;
   124       plotColorPalette[1] = Color.OrangeRed;
   125       plotColorPalette[2] = Color.Green;
   126       plotColorPalette[3] = Color.LightSeaGreen;
   127       plotColorPalette[4] = Color.Goldenrod;
   128       plotColorPalette[5] = Color.DarkViolet;
   129       plotColorPalette[6] = Color.YellowGreen;
   130       plotColorPalette[7] = Color.SaddleBrown;
   131       plotColorPalette[8] = Color.Gray;
   132       plotColorPalette[9] = Color.RoyalBlue;
   133       plotColorPalette[10] = Color.DeepPink;
   134       plotColorPalette[11] = Color.MediumSeaGreen;
   135       plotColorPalette[12] = Color.Olive;
   136       plotColorPalette[13] = Color.Firebrick;
   137 
   138       plotMenuItem.Checked = Config.Get(plotMenuItem.Name, false);
   139       minMenuItem.Checked = Config.Get(minMenuItem.Name, false);
   140       maxMenuItem.Checked = Config.Get(maxMenuItem.Name, true);
   141       limitMenuItem.Checked = Config.Get(limitMenuItem.Name, false);
   142 
   143       startMinMenuItem.Checked = Config.Get(startMinMenuItem.Name, false); 
   144       minTrayMenuItem.Checked = Config.Get(minTrayMenuItem.Name, true);
   145       startupMenuItem.Checked = startupManager.Startup;
   146       hddMenuItem.Checked = Config.Get(hddMenuItem.Name, true);
   147 
   148       voltMenuItem.Checked = Config.Get(voltMenuItem.Name, true);
   149       clocksMenuItem.Checked = Config.Get(clocksMenuItem.Name, true);
   150       loadMenuItem.Checked = Config.Get(loadMenuItem.Name, true);
   151       tempMenuItem.Checked = Config.Get(tempMenuItem.Name, true);
   152       fansMenuItem.Checked = Config.Get(fansMenuItem.Name, true);
   153       flowsMenuItem.Checked = Config.Get(flowsMenuItem.Name, true);    
   154 
   155       if (startMinMenuItem.Checked) {
   156         if (!minTrayMenuItem.Checked) {
   157           WindowState = FormWindowState.Minimized;
   158           Show();
   159         }
   160       } else {
   161         Show();
   162       }
   163 
   164       // Create a handle, otherwise calling Close() does not fire FormClosed     
   165       IntPtr handle = Handle;
   166     }
   167 
   168     private void SubHardwareAdded(IHardware hardware, Node node) {
   169       Node hardwareNode = new HardwareNode(hardware);
   170       node.Nodes.Add(hardwareNode);
   171       foreach (IHardware subHardware in hardware.SubHardware)
   172         SubHardwareAdded(subHardware, hardwareNode);  
   173     }
   174 
   175     private void HardwareAdded(IHardware hardware) {
   176       Node hardwareNode = new HardwareNode(hardware);
   177       root.Nodes.Add(hardwareNode);
   178       foreach (IHardware subHardware in hardware.SubHardware)
   179         SubHardwareAdded(subHardware, hardwareNode);     
   180     }
   181 
   182     private void HardwareRemoved(IHardware hardware) {      
   183       List<Node> nodesToRemove = new List<Node>();
   184       foreach (Node node in root.Nodes) {
   185         HardwareNode hardwareNode = node as HardwareNode;
   186         if (hardwareNode != null && hardwareNode.Hardware == hardware)
   187           nodesToRemove.Add(node);
   188       }
   189       foreach (Node node in nodesToRemove)
   190         root.Nodes.Remove(node);
   191     }
   192 
   193     private void nodeTextBoxLimit_DrawText(object sender, DrawEventArgs e) {
   194       SensorNode sensorNode = e.Node.Tag as SensorNode;
   195       if (sensorNode != null) 
   196         e.Text = sensorNode.ValueToString(sensorNode.Sensor.Limit);
   197     }
   198 
   199     private void nodeTextBoxText_DrawText(object sender, DrawEventArgs e) {
   200       if (!plotMenuItem.Checked)
   201         return;      
   202 
   203       SensorNode sensorNode = e.Node.Tag as SensorNode;
   204       if (sensorNode != null) {
   205         Color color;
   206         if (sensorPlotColors.TryGetValue(sensorNode.Sensor, out color)) 
   207           e.TextColor = color;        
   208       }
   209     }
   210 
   211     private void UpdatePlotSelection(object sender, 
   212       TreePathEventArgs e) 
   213     {
   214       List<ISensor> selected = new List<ISensor>();
   215       IDictionary<ISensor, Color> colors = new Dictionary<ISensor, Color>();
   216       int colorIndex = 0;
   217       foreach (TreeNodeAdv node in treeView.AllNodes) {
   218         SensorNode sensorNode = node.Tag as SensorNode;
   219         if (sensorNode != null && 
   220           sensorNode.Sensor.SensorType == SensorType.Temperature) {
   221           if (sensorNode.Plot) {
   222             colors.Add(sensorNode.Sensor,
   223               plotColorPalette[colorIndex % plotColorPalette.Length]);
   224             selected.Add(sensorNode.Sensor);
   225           }
   226           colorIndex++;
   227         }
   228       }
   229       sensorPlotColors = colors;
   230       plotPanel.SetSensors(selected, colors);
   231     }
   232 
   233     private void nodeCheckBox_IsVisibleValueNeeded(object sender, 
   234       NodeControlValueEventArgs e) {
   235       SensorNode node = e.Node.Tag as SensorNode;
   236       e.Value = (node != null) && 
   237         (node.Sensor.SensorType == SensorType.Temperature) && 
   238         plotMenuItem.Checked;
   239     }
   240 
   241     private void exitToolStripMenuItem_Click(object sender, EventArgs e) {
   242       Close();      
   243     }
   244 
   245     private void timer_Tick(object sender, EventArgs e) {
   246       computer.Accept(updateVisitor);
   247       treeView.Invalidate();
   248       plotPanel.Invalidate();
   249       sensorSystemTray.Redraw();
   250     }
   251 
   252     private void MainForm_FormClosed(object sender, FormClosedEventArgs e) {
   253             
   254       Config.Set(plotMenuItem.Name, plotMenuItem.Checked);
   255       Config.Set(minMenuItem.Name, minMenuItem.Checked);
   256       Config.Set(maxMenuItem.Name, maxMenuItem.Checked);
   257       Config.Set(limitMenuItem.Name, limitMenuItem.Checked);
   258 
   259       Config.Set(startMinMenuItem.Name, startMinMenuItem.Checked);
   260       Config.Set(minTrayMenuItem.Name, minTrayMenuItem.Checked);
   261       Config.Set(hddMenuItem.Name, hddMenuItem.Checked);
   262 
   263       Config.Set(voltMenuItem.Name, voltMenuItem.Checked);
   264       Config.Set(clocksMenuItem.Name, clocksMenuItem.Checked);
   265       Config.Set(loadMenuItem.Name, loadMenuItem.Checked);
   266       Config.Set(tempMenuItem.Name, tempMenuItem.Checked);
   267       Config.Set(fansMenuItem.Name, fansMenuItem.Checked);
   268       Config.Set(flowsMenuItem.Name, flowsMenuItem.Checked);      
   269 
   270       if (WindowState != FormWindowState.Minimized) {
   271         Config.Set("mainForm.Location.X", Location.X);
   272         Config.Set("mainForm.Location.Y", Location.Y);
   273         Config.Set("mainForm.Width", Width);
   274         Config.Set("mainForm.Height", Height);
   275       }
   276 
   277       timer.Enabled = false;
   278 
   279       sensorSystemTray.Dispose();
   280       notifyIcon.Dispose();
   281       computer.Close();
   282     }
   283 
   284     private void aboutToolStripMenuItem_Click(object sender, EventArgs e) {
   285       new AboutBox().ShowDialog();
   286     }
   287 
   288     private void plotToolStripMenuItem_CheckedChanged(object sender, 
   289       EventArgs e) 
   290     {
   291       splitContainer.Panel2Collapsed = !plotMenuItem.Checked;
   292       treeView.Invalidate();
   293     }
   294 
   295     private void valueToolStripMenuItem_CheckedChanged(object sender, 
   296       EventArgs e) 
   297     {
   298       treeView.Columns[1].IsVisible = valueToolStripMenuItem.Checked;
   299     }
   300 
   301     private void minToolStripMenuItem_CheckedChanged(object sender, EventArgs e) 
   302     {
   303       treeView.Columns[2].IsVisible = minMenuItem.Checked;
   304     }
   305 
   306     private void maxToolStripMenuItem_CheckedChanged(object sender, EventArgs e) 
   307     {
   308       treeView.Columns[3].IsVisible = maxMenuItem.Checked;
   309     }
   310 
   311     private void limitToolStripMenuItem_CheckedChanged(object sender, 
   312       EventArgs e) {
   313       treeView.Columns[4].IsVisible = limitMenuItem.Checked;
   314     }
   315 
   316     private void treeView_Click(object sender, EventArgs e) {
   317       
   318       MouseEventArgs m = e as MouseEventArgs;
   319       if (m == null || m.Button != MouseButtons.Right)
   320         return;
   321 
   322       NodeControlInfo info = treeView.GetNodeControlInfoAt(new Point(m.X, m.Y));
   323       if (info.Control == null) {
   324         columnsContextMenuStrip.Show(treeView, m.X, m.Y);
   325       } else {
   326         SensorNode node = info.Node.Tag as SensorNode;
   327         if (node != null && node.Sensor != null) {
   328 
   329           sensorContextMenuStrip.Items.Clear();
   330           if (node.Sensor.Parameters.Length > 0) {
   331             ToolStripMenuItem item = new ToolStripMenuItem("Parameters...");
   332             item.Click += delegate(object obj, EventArgs args) {
   333               ShowParameterForm(node.Sensor);
   334             };
   335             sensorContextMenuStrip.Items.Add(item);
   336           }
   337           if (sensorSystemTray.Contains(node.Sensor)) {
   338             ToolStripMenuItem item = new ToolStripMenuItem("Remove From Tray");
   339             item.Click += delegate(object obj, EventArgs args) {
   340               sensorSystemTray.Remove(node.Sensor);
   341             };
   342             sensorContextMenuStrip.Items.Add(item);
   343           } else {
   344             ToolStripMenuItem item = new ToolStripMenuItem("Add To Tray");
   345             item.Click += delegate(object obj, EventArgs args) {
   346               sensorSystemTray.Add(node.Sensor, true);
   347             };
   348             sensorContextMenuStrip.Items.Add(item);
   349           }
   350           sensorContextMenuStrip.Show(treeView, m.X, m.Y);
   351         }
   352       }
   353     }
   354 
   355     private void saveReportToolStripMenuItem_Click(object sender, EventArgs e) {
   356       string report = computer.GetReport();
   357       if (saveFileDialog.ShowDialog() == DialogResult.OK) {
   358         using (TextWriter w = new StreamWriter(saveFileDialog.FileName)) {
   359           w.Write(report);
   360         }
   361       }
   362     }
   363 
   364     private void hddsensorsToolStripMenuItem_CheckedChanged(object sender, 
   365       EventArgs e) 
   366     {
   367       computer.HDDEnabled = hddMenuItem.Checked;
   368       UpdateSensorTypeChecked(null, null);
   369       UpdatePlotSelection(null, null);      
   370     }
   371 
   372     private void UpdateSensorTypeVisible(Node node) {
   373       HardwareNode hardwareNode = node as HardwareNode;
   374       if (hardwareNode == null)
   375         return;
   376 
   377       hardwareNode.SetVisible(SensorType.Voltage, voltMenuItem.Checked);
   378       hardwareNode.SetVisible(SensorType.Clock, clocksMenuItem.Checked);
   379       hardwareNode.SetVisible(SensorType.Load, loadMenuItem.Checked);
   380       hardwareNode.SetVisible(SensorType.Temperature, tempMenuItem.Checked);
   381       hardwareNode.SetVisible(SensorType.Fan, fansMenuItem.Checked);
   382       hardwareNode.SetVisible(SensorType.Flow, flowsMenuItem.Checked);
   383 
   384       foreach (Node n in node.Nodes)
   385         UpdateSensorTypeVisible(n);
   386     }
   387 
   388     private void UpdateSensorTypeChecked(object sender, EventArgs e) {          
   389       foreach (HardwareNode node in root.Nodes) 
   390         UpdateSensorTypeVisible(node);
   391     }
   392 
   393     private void SysTrayHideShow() {
   394       Visible = !Visible;
   395       if (Visible)
   396         Activate();    
   397     }
   398 
   399     protected override void WndProc(ref Message m) {
   400       const int WM_SYSCOMMAND = 0x112;
   401       const int SC_MINIMIZE = 0xF020;
   402       if (minTrayMenuItem.Checked && 
   403         m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_MINIMIZE) {
   404         SysTrayHideShow();
   405       } else {      
   406         base.WndProc(ref m);
   407       }
   408     }
   409 
   410     private void hideShowClick(object sender, EventArgs e) {
   411       SysTrayHideShow();
   412     }
   413 
   414     private void removeToolStripMenuItem_Click(object sender, EventArgs e) {
   415       ToolStripMenuItem item = sender as ToolStripMenuItem;
   416       if (item == null)
   417         return;
   418 
   419       ISensor sensor = item.Owner.Tag as ISensor;
   420       if (sensor == null)
   421         return;
   422 
   423       sensorSystemTray.Remove(sensor);
   424     }
   425 
   426     private void ShowParameterForm(ISensor sensor) {
   427       ParameterForm form = new ParameterForm();
   428       form.Parameters = sensor.Parameters;
   429       form.captionLabel.Text = sensor.Name;
   430       form.ShowDialog();
   431     }
   432 
   433     private void treeView_NodeMouseDoubleClick(object sender, 
   434       TreeNodeAdvMouseEventArgs e) {
   435       SensorNode node = e.Node.Tag as SensorNode;
   436       if (node != null && node.Sensor != null && 
   437         node.Sensor.Parameters.Length > 0) {
   438         ShowParameterForm(node.Sensor);
   439       }
   440     }
   441 
   442     private void runOnWindowsStartupToolStripMenuItem_CheckedChanged(
   443       object sender, EventArgs e) 
   444     {
   445       startupManager.Startup = startupMenuItem.Checked;
   446     }
   447 
   448     private void minTrayMenuItem_CheckedChanged(object sender, EventArgs e) {
   449       notifyIcon.Visible = minTrayMenuItem.Checked;
   450     }
   451   }
   452 }