GUI/MainForm.cs
author moel.mich
Sat, 24 Apr 2010 19:59:52 +0000
changeset 90 3333b29a1746
parent 83 3fdadd4a830f
child 110 411b72b73d8f
permissions -rw-r--r--
Implemented APIC based CPU enumeration (Issue 41).
     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 
    64     public MainForm() {      
    65       InitializeComponent();
    66       this.Font = SystemFonts.MessageBoxFont;
    67       treeView.Font = SystemFonts.MessageBoxFont;
    68       plotPanel.Font = SystemFonts.MessageBoxFont;
    69       
    70       nodeCheckBox.IsVisibleValueNeeded += 
    71         new EventHandler<NodeControlValueEventArgs>(
    72           nodeCheckBox_IsVisibleValueNeeded);
    73       nodeCheckBox.CheckStateChanged += 
    74         new EventHandler<TreePathEventArgs>(UpdatePlotSelection);
    75       nodeTextBoxText.DrawText += 
    76         new EventHandler<DrawEventArgs>(nodeTextBoxText_DrawText);
    77       nodeTextBoxValue.DrawText +=
    78         new EventHandler<DrawEventArgs>(nodeTextBoxText_DrawText);
    79       nodeTextBoxMin.DrawText +=
    80         new EventHandler<DrawEventArgs>(nodeTextBoxText_DrawText);
    81       nodeTextBoxMax.DrawText +=
    82         new EventHandler<DrawEventArgs>(nodeTextBoxText_DrawText);
    83       nodeTextBoxLimit.DrawText += 
    84         new EventHandler<DrawEventArgs>(nodeTextBoxLimit_DrawText);
    85 
    86       if (Utilities.Config.Contains("mainForm.Location.X")) {
    87         int x = Utilities.Config.Get("mainForm.Location.X", Location.X);
    88         x = x < 0 ? 0 : x;
    89         int y = Utilities.Config.Get("mainForm.Location.Y", Location.Y);
    90         y = y < 0 ? 0 : y;
    91         this.Location = new Point(x, y);
    92       } else {
    93         StartPosition = FormStartPosition.CenterScreen;
    94       }
    95 
    96       Width = Utilities.Config.Get("mainForm.Width", Width);
    97       Height = Utilities.Config.Get("mainForm.Height", Height);
    98          
    99       treeModel = new TreeModel();
   100       root = new Node(System.Environment.MachineName);
   101       root.Image = Utilities.EmbeddedResources.GetImage("computer.png");
   102       
   103       treeModel.Nodes.Add(root);
   104       treeView.Model = treeModel;
   105       
   106       notifyIcon = new NotifyIcon();
   107       notifyIcon.ContextMenuStrip = this.notifyContextMenuStrip;
   108       notifyIcon.Icon = EmbeddedResources.GetIcon("smallicon.ico");
   109       notifyIcon.Text = "Open Hardware Monitor";      
   110       notifyIcon.DoubleClick += new EventHandler(this.hideShowClick);
   111 
   112       sensorSystemTray = new SensorSystemTray(computer);
   113 
   114       computer.HardwareAdded += new HardwareEventHandler(HardwareAdded);
   115       computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved);
   116       computer.Open();
   117 
   118       timer.Enabled = true;
   119 
   120       plotColorPalette = new Color[14];
   121       plotColorPalette[0] = Color.Blue;
   122       plotColorPalette[1] = Color.OrangeRed;
   123       plotColorPalette[2] = Color.Green;
   124       plotColorPalette[3] = Color.LightSeaGreen;
   125       plotColorPalette[4] = Color.Goldenrod;
   126       plotColorPalette[5] = Color.DarkViolet;
   127       plotColorPalette[6] = Color.YellowGreen;
   128       plotColorPalette[7] = Color.SaddleBrown;
   129       plotColorPalette[8] = Color.Gray;
   130       plotColorPalette[9] = Color.RoyalBlue;
   131       plotColorPalette[10] = Color.DeepPink;
   132       plotColorPalette[11] = Color.MediumSeaGreen;
   133       plotColorPalette[12] = Color.Olive;
   134       plotColorPalette[13] = Color.Firebrick;
   135 
   136       plotMenuItem.Checked = Config.Get(plotMenuItem.Name, false);
   137       minMenuItem.Checked = Config.Get(minMenuItem.Name, false);
   138       maxMenuItem.Checked = Config.Get(maxMenuItem.Name, true);
   139       limitMenuItem.Checked = Config.Get(limitMenuItem.Name, false);
   140 
   141       startMinMenuItem.Checked = Config.Get(startMinMenuItem.Name, false); 
   142       minTrayMenuItem.Checked = Config.Get(minTrayMenuItem.Name, true);
   143       startupMenuItem.Checked = startupManager.Startup;
   144       hddMenuItem.Checked = Config.Get(hddMenuItem.Name, true);
   145 
   146       voltMenuItem.Checked = Config.Get(voltMenuItem.Name, true);
   147       clocksMenuItem.Checked = Config.Get(clocksMenuItem.Name, true);
   148       loadMenuItem.Checked = Config.Get(loadMenuItem.Name, true);
   149       tempMenuItem.Checked = Config.Get(tempMenuItem.Name, true);
   150       fansMenuItem.Checked = Config.Get(fansMenuItem.Name, true);
   151       flowsMenuItem.Checked = Config.Get(flowsMenuItem.Name, true);    
   152 
   153       if (startMinMenuItem.Checked) {
   154         if (!minTrayMenuItem.Checked) {
   155           WindowState = FormWindowState.Minimized;
   156           Show();
   157         }
   158       } else {
   159         Show();
   160       }
   161 
   162       // Create a handle, otherwise calling Close() does not fire FormClosed     
   163       IntPtr handle = Handle;
   164     }
   165 
   166     private void SubHardwareAdded(IHardware hardware, Node node) {
   167       Node hardwareNode = new HardwareNode(hardware);
   168       node.Nodes.Add(hardwareNode);
   169       foreach (IHardware subHardware in hardware.SubHardware)
   170         SubHardwareAdded(subHardware, hardwareNode);  
   171     }
   172 
   173     private void HardwareAdded(IHardware hardware) {
   174       Node hardwareNode = new HardwareNode(hardware);
   175       root.Nodes.Add(hardwareNode);
   176       foreach (IHardware subHardware in hardware.SubHardware)
   177         SubHardwareAdded(subHardware, hardwareNode);     
   178     }
   179 
   180     private void HardwareRemoved(IHardware hardware) {      
   181       List<Node> nodesToRemove = new List<Node>();
   182       foreach (Node node in root.Nodes) {
   183         HardwareNode hardwareNode = node as HardwareNode;
   184         if (hardwareNode != null && hardwareNode.Hardware == hardware)
   185           nodesToRemove.Add(node);
   186       }
   187       foreach (Node node in nodesToRemove)
   188         root.Nodes.Remove(node);
   189     }
   190 
   191     private void nodeTextBoxLimit_DrawText(object sender, DrawEventArgs e) {
   192       SensorNode sensorNode = e.Node.Tag as SensorNode;
   193       if (sensorNode != null) 
   194         e.Text = sensorNode.ValueToString(sensorNode.Sensor.Limit);
   195     }
   196 
   197     private void nodeTextBoxText_DrawText(object sender, DrawEventArgs e) {
   198       if (!plotMenuItem.Checked)
   199         return;      
   200 
   201       SensorNode sensorNode = e.Node.Tag as SensorNode;
   202       if (sensorNode != null) {
   203         Color color;
   204         if (sensorPlotColors.TryGetValue(sensorNode.Sensor, out color)) 
   205           e.TextColor = color;        
   206       }
   207     }
   208 
   209     private void UpdatePlotSelection(object sender, 
   210       TreePathEventArgs e) 
   211     {
   212       List<ISensor> selected = new List<ISensor>();
   213       IDictionary<ISensor, Color> colors = new Dictionary<ISensor, Color>();
   214       int colorIndex = 0;
   215       foreach (TreeNodeAdv node in treeView.AllNodes) {
   216         SensorNode sensorNode = node.Tag as SensorNode;
   217         if (sensorNode != null && 
   218           sensorNode.Sensor.SensorType == SensorType.Temperature) {
   219           if (sensorNode.Plot) {
   220             colors.Add(sensorNode.Sensor,
   221               plotColorPalette[colorIndex % plotColorPalette.Length]);
   222             selected.Add(sensorNode.Sensor);
   223           }
   224           colorIndex++;
   225         }
   226       }
   227       sensorPlotColors = colors;
   228       plotPanel.SetSensors(selected, colors);
   229     }
   230 
   231     private void nodeCheckBox_IsVisibleValueNeeded(object sender, 
   232       NodeControlValueEventArgs e) {
   233       SensorNode node = e.Node.Tag as SensorNode;
   234       e.Value = (node != null) && 
   235         (node.Sensor.SensorType == SensorType.Temperature) && 
   236         plotMenuItem.Checked;
   237     }
   238 
   239     private void exitToolStripMenuItem_Click(object sender, EventArgs e) {
   240       Close();      
   241     }
   242 
   243     private void timer_Tick(object sender, EventArgs e) {
   244       computer.Update();  
   245       treeView.Invalidate();
   246       plotPanel.Invalidate();
   247       sensorSystemTray.Redraw();
   248     }
   249 
   250     private void MainForm_FormClosed(object sender, FormClosedEventArgs e) {
   251             
   252       Config.Set(plotMenuItem.Name, plotMenuItem.Checked);
   253       Config.Set(minMenuItem.Name, minMenuItem.Checked);
   254       Config.Set(maxMenuItem.Name, maxMenuItem.Checked);
   255       Config.Set(limitMenuItem.Name, limitMenuItem.Checked);
   256 
   257       Config.Set(startMinMenuItem.Name, startMinMenuItem.Checked);
   258       Config.Set(minTrayMenuItem.Name, minTrayMenuItem.Checked);
   259       Config.Set(hddMenuItem.Name, hddMenuItem.Checked);
   260 
   261       Config.Set(voltMenuItem.Name, voltMenuItem.Checked);
   262       Config.Set(clocksMenuItem.Name, clocksMenuItem.Checked);
   263       Config.Set(loadMenuItem.Name, loadMenuItem.Checked);
   264       Config.Set(tempMenuItem.Name, tempMenuItem.Checked);
   265       Config.Set(fansMenuItem.Name, fansMenuItem.Checked);
   266       Config.Set(flowsMenuItem.Name, flowsMenuItem.Checked);      
   267 
   268       if (WindowState != FormWindowState.Minimized) {
   269         Config.Set("mainForm.Location.X", Location.X);
   270         Config.Set("mainForm.Location.Y", Location.Y);
   271         Config.Set("mainForm.Width", Width);
   272         Config.Set("mainForm.Height", Height);
   273       }
   274 
   275       timer.Enabled = false;
   276 
   277       sensorSystemTray.Dispose();
   278       notifyIcon.Dispose();
   279       computer.Close();
   280     }
   281 
   282     private void aboutToolStripMenuItem_Click(object sender, EventArgs e) {
   283       new AboutBox().ShowDialog();
   284     }
   285 
   286     private void plotToolStripMenuItem_CheckedChanged(object sender, 
   287       EventArgs e) 
   288     {
   289       splitContainer.Panel2Collapsed = !plotMenuItem.Checked;
   290       treeView.Invalidate();
   291     }
   292 
   293     private void valueToolStripMenuItem_CheckedChanged(object sender, 
   294       EventArgs e) 
   295     {
   296       treeView.Columns[1].IsVisible = valueToolStripMenuItem.Checked;
   297     }
   298 
   299     private void minToolStripMenuItem_CheckedChanged(object sender, EventArgs e) 
   300     {
   301       treeView.Columns[2].IsVisible = minMenuItem.Checked;
   302     }
   303 
   304     private void maxToolStripMenuItem_CheckedChanged(object sender, EventArgs e) 
   305     {
   306       treeView.Columns[3].IsVisible = maxMenuItem.Checked;
   307     }
   308 
   309     private void limitToolStripMenuItem_CheckedChanged(object sender, 
   310       EventArgs e) {
   311       treeView.Columns[4].IsVisible = limitMenuItem.Checked;
   312     }
   313 
   314     private void treeView_Click(object sender, EventArgs e) {
   315       
   316       MouseEventArgs m = e as MouseEventArgs;
   317       if (m == null || m.Button != MouseButtons.Right)
   318         return;
   319 
   320       NodeControlInfo info = treeView.GetNodeControlInfoAt(new Point(m.X, m.Y));
   321       if (info.Control == null) {
   322         columnsContextMenuStrip.Show(treeView, m.X, m.Y);
   323       } else {
   324         SensorNode node = info.Node.Tag as SensorNode;
   325         if (node != null && node.Sensor != null) {
   326 
   327           sensorContextMenuStrip.Items.Clear();
   328           if (node.Sensor.Parameters.Length > 0) {
   329             ToolStripMenuItem item = new ToolStripMenuItem("Parameters...");
   330             item.Click += delegate(object obj, EventArgs args) {
   331               ShowParameterForm(node.Sensor);
   332             };
   333             sensorContextMenuStrip.Items.Add(item);
   334           }
   335           if (sensorSystemTray.Contains(node.Sensor)) {
   336             ToolStripMenuItem item = new ToolStripMenuItem("Remove From Tray");
   337             item.Click += delegate(object obj, EventArgs args) {
   338               sensorSystemTray.Remove(node.Sensor);
   339             };
   340             sensorContextMenuStrip.Items.Add(item);
   341           } else {
   342             ToolStripMenuItem item = new ToolStripMenuItem("Add To Tray");
   343             item.Click += delegate(object obj, EventArgs args) {
   344               sensorSystemTray.Add(node.Sensor, true);
   345             };
   346             sensorContextMenuStrip.Items.Add(item);
   347           }
   348           sensorContextMenuStrip.Show(treeView, m.X, m.Y);
   349         }
   350       }
   351     }
   352 
   353     private void saveReportToolStripMenuItem_Click(object sender, EventArgs e) {
   354       string report = computer.GetReport();
   355       if (saveFileDialog.ShowDialog() == DialogResult.OK) {
   356         using (TextWriter w = new StreamWriter(saveFileDialog.FileName)) {
   357           w.Write(report);
   358         }
   359       }
   360     }
   361 
   362     private void hddsensorsToolStripMenuItem_CheckedChanged(object sender, 
   363       EventArgs e) 
   364     {
   365       computer.HDDEnabled = hddMenuItem.Checked;
   366       UpdateSensorTypeChecked(null, null);
   367       UpdatePlotSelection(null, null);      
   368     }
   369 
   370     private void UpdateSensorTypeVisible(Node node) {
   371       HardwareNode hardwareNode = node as HardwareNode;
   372       if (hardwareNode == null)
   373         return;
   374 
   375       hardwareNode.SetVisible(SensorType.Voltage, voltMenuItem.Checked);
   376       hardwareNode.SetVisible(SensorType.Clock, clocksMenuItem.Checked);
   377       hardwareNode.SetVisible(SensorType.Load, loadMenuItem.Checked);
   378       hardwareNode.SetVisible(SensorType.Temperature, tempMenuItem.Checked);
   379       hardwareNode.SetVisible(SensorType.Fan, fansMenuItem.Checked);
   380       hardwareNode.SetVisible(SensorType.Flow, flowsMenuItem.Checked);
   381 
   382       foreach (Node n in node.Nodes)
   383         UpdateSensorTypeVisible(n);
   384     }
   385 
   386     private void UpdateSensorTypeChecked(object sender, EventArgs e) {          
   387       foreach (HardwareNode node in root.Nodes) 
   388         UpdateSensorTypeVisible(node);
   389     }
   390 
   391     private void SysTrayHideShow() {
   392       Visible = !Visible;
   393       if (Visible)
   394         Activate();    
   395     }
   396 
   397     protected override void WndProc(ref Message m) {
   398       const int WM_SYSCOMMAND = 0x112;
   399       const int SC_MINIMIZE = 0xF020;
   400       if (minTrayMenuItem.Checked && 
   401         m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_MINIMIZE) {
   402         SysTrayHideShow();
   403       } else {      
   404         base.WndProc(ref m);
   405       }
   406     }
   407 
   408     private void hideShowClick(object sender, EventArgs e) {
   409       SysTrayHideShow();
   410     }
   411 
   412     private void removeToolStripMenuItem_Click(object sender, EventArgs e) {
   413       ToolStripMenuItem item = sender as ToolStripMenuItem;
   414       if (item == null)
   415         return;
   416 
   417       ISensor sensor = item.Owner.Tag as ISensor;
   418       if (sensor == null)
   419         return;
   420 
   421       sensorSystemTray.Remove(sensor);
   422     }
   423 
   424     private void ShowParameterForm(ISensor sensor) {
   425       ParameterForm form = new ParameterForm();
   426       form.Parameters = sensor.Parameters;
   427       form.captionLabel.Text = sensor.Name;
   428       form.ShowDialog();
   429     }
   430 
   431     private void treeView_NodeMouseDoubleClick(object sender, 
   432       TreeNodeAdvMouseEventArgs e) {
   433       SensorNode node = e.Node.Tag as SensorNode;
   434       if (node != null && node.Sensor != null && 
   435         node.Sensor.Parameters.Length > 0) {
   436         ShowParameterForm(node.Sensor);
   437       }
   438     }
   439 
   440     private void runOnWindowsStartupToolStripMenuItem_CheckedChanged(
   441       object sender, EventArgs e) 
   442     {
   443       startupManager.Startup = startupMenuItem.Checked;
   444     }
   445 
   446     private void minTrayMenuItem_CheckedChanged(object sender, EventArgs e) {
   447       notifyIcon.Visible = minTrayMenuItem.Checked;
   448     }
   449   }
   450 }