GUI/MainForm.cs
author moel.mich
Sat, 24 Jul 2010 20:15:49 +0000
changeset 158 119693c3b7d1
parent 156 3e2ab626531c
child 159 eda3e3458cf4
permissions -rw-r--r--
Replaced the SplitContainer with SplitContainerAdv. Now the panels are directly resized and the splitter can be drawn nicely.
     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 SystemTray systemTray;    
    61     private StartupManager startupManager = new StartupManager();
    62     private UpdateVisitor updateVisitor = new UpdateVisitor();
    63 
    64     private UserOption showHiddenSensors;
    65     private UserOption showPlot;
    66     private UserOption showValue;
    67     private UserOption showMin;
    68     private UserOption showMax;
    69     private UserOption startMinimized;
    70     private UserOption minimizeToTray;
    71     private UserOption autoStart;
    72     private UserOption readHddSensors;
    73 
    74     public MainForm() {      
    75       InitializeComponent();
    76 
    77       // set the DockStyle here, to avoid conflicts with the MainMenu
    78       this.splitContainer.Dock = DockStyle.Fill;
    79       
    80       this.Font = SystemFonts.MessageBoxFont;
    81       treeView.Font = SystemFonts.MessageBoxFont;
    82       plotPanel.Font = SystemFonts.MessageBoxFont;
    83       
    84       nodeCheckBox.IsVisibleValueNeeded += nodeCheckBox_IsVisibleValueNeeded;
    85       nodeCheckBox.CheckStateChanged += UpdatePlotSelection;
    86       nodeTextBoxText.DrawText += nodeTextBoxText_DrawText;
    87       nodeTextBoxValue.DrawText += nodeTextBoxText_DrawText;
    88       nodeTextBoxMin.DrawText += nodeTextBoxText_DrawText;
    89       nodeTextBoxMax.DrawText += nodeTextBoxText_DrawText;
    90       nodeTextBoxText.EditorShowing += nodeTextBoxText_EditorShowing;
    91 
    92       if (Utilities.Config.Contains("mainForm.Location.X")) {
    93         int x = Utilities.Config.Get("mainForm.Location.X", Location.X);
    94         x = x < 0 ? 0 : x;
    95         int y = Utilities.Config.Get("mainForm.Location.Y", Location.Y);
    96         y = y < 0 ? 0 : y;
    97         this.Location = new Point(x, y);
    98       } else {
    99         StartPosition = FormStartPosition.CenterScreen;
   100       }
   101 
   102       ClientSize = new Size(
   103         Utilities.Config.Get("mainForm.Width", 470),
   104         Utilities.Config.Get("mainForm.Height", 640));
   105 
   106       foreach (TreeColumn column in treeView.Columns) 
   107         column.Width = Math.Max(20, Math.Min(400, 
   108           Config.Get("treeView.Columns." + column.Header + ".Width",
   109           column.Width)));
   110 
   111       treeModel = new TreeModel();
   112       root = new Node(System.Environment.MachineName);
   113       root.Image = Utilities.EmbeddedResources.GetImage("computer.png");
   114       
   115       treeModel.Nodes.Add(root);
   116       treeView.Model = treeModel;     
   117 
   118       systemTray = new SystemTray(computer);
   119       systemTray.HideShowCommand += hideShowClick;
   120       systemTray.ExitCommand += exitClick;
   121 
   122       computer.HardwareAdded += new HardwareEventHandler(HardwareAdded);
   123       computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved);
   124       computer.Open();
   125 
   126       timer.Enabled = true;
   127 
   128       plotColorPalette = new Color[13];
   129       plotColorPalette[0] = Color.Blue;
   130       plotColorPalette[1] = Color.OrangeRed;
   131       plotColorPalette[2] = Color.Green;
   132       plotColorPalette[3] = Color.LightSeaGreen;
   133       plotColorPalette[4] = Color.Goldenrod;
   134       plotColorPalette[5] = Color.DarkViolet;
   135       plotColorPalette[6] = Color.YellowGreen;
   136       plotColorPalette[7] = Color.SaddleBrown;
   137       plotColorPalette[8] = Color.RoyalBlue;
   138       plotColorPalette[9] = Color.DeepPink;
   139       plotColorPalette[10] = Color.MediumSeaGreen;
   140       plotColorPalette[11] = Color.Olive;
   141       plotColorPalette[12] = Color.Firebrick;
   142 
   143       showHiddenSensors = new UserOption("hiddenMenuItem", false, hiddenMenuItem);
   144       showHiddenSensors.Changed += delegate(object sender, EventArgs e) {
   145         treeModel.ForceVisible = showHiddenSensors.Value;
   146       };
   147 
   148       showPlot = new UserOption("plotMenuItem", false, plotMenuItem);
   149       showPlot.Changed += delegate(object sender, EventArgs e) {
   150         splitContainer.Panel2Collapsed = !showPlot.Value;
   151         treeView.Invalidate();
   152       };
   153 
   154       showValue = new UserOption("valueMenuItem", true, valueMenuItem);
   155       showValue.Changed += delegate(object sender, EventArgs e) {
   156         treeView.Columns[1].IsVisible = showValue.Value;
   157       };
   158 
   159       showMin = new UserOption("minMenuItem", false, minMenuItem);
   160       showMin.Changed += delegate(object sender, EventArgs e) {
   161         treeView.Columns[2].IsVisible = showMin.Value;
   162       };
   163 
   164       showMax = new UserOption("maxMenuItem", true, maxMenuItem);
   165       showMax.Changed += delegate(object sender, EventArgs e) {
   166         treeView.Columns[3].IsVisible = showMax.Value;
   167       };
   168 
   169       startMinimized = new UserOption("startMinMenuItem", false, startMinMenuItem);
   170 
   171       minimizeToTray = new UserOption("minTrayMenuItem", true, minTrayMenuItem);
   172       minimizeToTray.Changed += delegate(object sender, EventArgs e) {
   173         systemTray.IsMainIconEnabled = minimizeToTray.Value;
   174       };
   175 
   176       autoStart = new UserOption(null, startupManager.Startup, startupMenuItem);
   177       autoStart.Changed += delegate(object sender, EventArgs e) {
   178         startupManager.Startup = autoStart.Value; ;
   179       };
   180 
   181       readHddSensors = new UserOption("hddMenuItem", true, hddMenuItem);
   182       readHddSensors.Changed += delegate(object sender, EventArgs e) {
   183         computer.HDDEnabled = readHddSensors.Value;
   184         UpdatePlotSelection(null, null);
   185       };
   186 
   187       celciusMenuItem.Checked = 
   188         UnitManager.TemperatureUnit == TemperatureUnit.Celcius;
   189       fahrenheitMenuItem.Checked = !celciusMenuItem.Checked;
   190 
   191       startupMenuItem.Visible = startupManager.IsAvailable;
   192       
   193       if (startMinMenuItem.Checked) {
   194         if (!minTrayMenuItem.Checked) {
   195           WindowState = FormWindowState.Minimized;
   196           Show();
   197         }
   198       } else {
   199         Show();
   200       }
   201 
   202       // Create a handle, otherwise calling Close() does not fire FormClosed     
   203       IntPtr handle = Handle;
   204 
   205       // Make sure the settings are saved when the user logs off
   206       Microsoft.Win32.SystemEvents.SessionEnded +=
   207         delegate(object sender, Microsoft.Win32.SessionEndedEventArgs e) {
   208           SaveConfiguration();
   209         };
   210     }
   211     
   212     private void SubHardwareAdded(IHardware hardware, Node node) {
   213       Node hardwareNode = new HardwareNode(hardware);
   214       node.Nodes.Add(hardwareNode);
   215       foreach (IHardware subHardware in hardware.SubHardware)
   216         SubHardwareAdded(subHardware, hardwareNode);  
   217     }
   218 
   219     private void HardwareAdded(IHardware hardware) {
   220       Node hardwareNode = new HardwareNode(hardware);
   221       root.Nodes.Add(hardwareNode);
   222       foreach (IHardware subHardware in hardware.SubHardware)
   223         SubHardwareAdded(subHardware, hardwareNode);     
   224     }
   225 
   226     private void HardwareRemoved(IHardware hardware) {      
   227       List<Node> nodesToRemove = new List<Node>();
   228       foreach (Node node in root.Nodes) {
   229         HardwareNode hardwareNode = node as HardwareNode;
   230         if (hardwareNode != null && hardwareNode.Hardware == hardware)
   231           nodesToRemove.Add(node);
   232       }
   233       foreach (Node node in nodesToRemove)
   234         root.Nodes.Remove(node);
   235     }
   236 
   237     private void nodeTextBoxText_DrawText(object sender, DrawEventArgs e) {       
   238       Node node = e.Node.Tag as Node;
   239       if (node != null) {
   240         Color color;
   241         if (node.IsVisible) {
   242           SensorNode sensorNode = node as SensorNode;
   243           if (plotMenuItem.Checked && sensorNode != null &&
   244             sensorPlotColors.TryGetValue(sensorNode.Sensor, out color))
   245             e.TextColor = color;
   246         } else {
   247           e.TextColor = Color.DarkGray;
   248         }
   249       }
   250     }
   251 
   252     private void UpdatePlotSelection(object sender, 
   253       TreePathEventArgs e) 
   254     {
   255       List<ISensor> selected = new List<ISensor>();
   256       IDictionary<ISensor, Color> colors = new Dictionary<ISensor, Color>();
   257       int colorIndex = 0;
   258       foreach (TreeNodeAdv node in treeView.AllNodes) {
   259         SensorNode sensorNode = node.Tag as SensorNode;
   260         if (sensorNode != null && 
   261           sensorNode.Sensor.SensorType == SensorType.Temperature) {
   262           if (sensorNode.Plot) {
   263             colors.Add(sensorNode.Sensor,
   264               plotColorPalette[colorIndex % plotColorPalette.Length]);
   265             selected.Add(sensorNode.Sensor);
   266           }
   267           colorIndex++;
   268         }
   269       }
   270       sensorPlotColors = colors;
   271       plotPanel.SetSensors(selected, colors);
   272     }
   273 
   274     private void nodeTextBoxText_EditorShowing(object sender, CancelEventArgs e) 
   275     {
   276       e.Cancel = !(treeView.CurrentNode != null &&
   277         treeView.CurrentNode.Tag is SensorNode);
   278     }
   279 
   280     private void nodeCheckBox_IsVisibleValueNeeded(object sender, 
   281       NodeControlValueEventArgs e) {
   282       SensorNode node = e.Node.Tag as SensorNode;
   283       e.Value = (node != null) && 
   284         (node.Sensor.SensorType == SensorType.Temperature) && 
   285         plotMenuItem.Checked;
   286     }
   287 
   288     private void exitClick(object sender, EventArgs e) {
   289       Close();      
   290     }
   291 
   292     private void timer_Tick(object sender, EventArgs e) {
   293       computer.Accept(updateVisitor);
   294       treeView.Invalidate();
   295       plotPanel.Invalidate();
   296       systemTray.Redraw();
   297     }
   298 
   299     private void SaveConfiguration() {
   300       if (WindowState != FormWindowState.Minimized) {
   301         Config.Set("mainForm.Location.X", Location.X);
   302         Config.Set("mainForm.Location.Y", Location.Y);
   303         Config.Set("mainForm.Width", ClientSize.Width);
   304         Config.Set("mainForm.Height", ClientSize.Height);
   305       }
   306 
   307       foreach (TreeColumn column in treeView.Columns)
   308         Config.Set("treeView.Columns." + column.Header + ".Width",
   309           column.Width);
   310 
   311       Config.Save();
   312     }
   313 
   314     private void MainForm_FormClosed(object sender, FormClosedEventArgs e) {
   315       Visible = false;
   316       SaveConfiguration();
   317 
   318       timer.Enabled = false;
   319       systemTray.Dispose();      
   320       computer.Close();
   321     }
   322 
   323     private void aboutMenuItem_Click(object sender, EventArgs e) {
   324       new AboutBox().ShowDialog();
   325     }
   326 
   327     private void treeView_Click(object sender, EventArgs e) {
   328       
   329       MouseEventArgs m = e as MouseEventArgs;
   330       if (m == null || m.Button != MouseButtons.Right)
   331         return;
   332 
   333       NodeControlInfo info = treeView.GetNodeControlInfoAt(new Point(m.X, m.Y));
   334       treeView.SelectedNode = info.Node;
   335       if (info.Node != null) {
   336         SensorNode node = info.Node.Tag as SensorNode;
   337         if (node != null && node.Sensor != null) {
   338           sensorContextMenu.MenuItems.Clear();
   339           if (node.Sensor.Parameters.Length > 0) {
   340             MenuItem item = new MenuItem("Parameters...");
   341             item.Click += delegate(object obj, EventArgs args) {
   342               ShowParameterForm(node.Sensor);
   343             };
   344             sensorContextMenu.MenuItems.Add(item);
   345           }
   346           if (nodeTextBoxText.EditEnabled) {
   347             MenuItem item = new MenuItem("Rename");
   348             item.Click += delegate(object obj, EventArgs args) {
   349               nodeTextBoxText.BeginEdit();
   350             };
   351             sensorContextMenu.MenuItems.Add(item);
   352           }          
   353           if (node.IsVisible) {
   354             MenuItem item = new MenuItem("Hide");
   355             item.Click += delegate(object obj, EventArgs args) {
   356               node.IsVisible = false;
   357             };
   358             sensorContextMenu.MenuItems.Add(item);
   359           } else {
   360             MenuItem item = new MenuItem("Unhide");
   361             item.Click += delegate(object obj, EventArgs args) {
   362               node.IsVisible = true;
   363             };
   364             sensorContextMenu.MenuItems.Add(item);
   365           }         
   366           if (systemTray.Contains(node.Sensor)) {
   367             MenuItem item = new MenuItem("Remove From Tray");
   368             item.Click += delegate(object obj, EventArgs args) {
   369               systemTray.Remove(node.Sensor);
   370             };
   371             sensorContextMenu.MenuItems.Add(item);
   372           } else {
   373             MenuItem item = new MenuItem("Add To Tray");
   374             item.Click += delegate(object obj, EventArgs args) {
   375               systemTray.Add(node.Sensor, true);
   376             };
   377             sensorContextMenu.MenuItems.Add(item);
   378           }
   379           sensorContextMenu.Show(treeView, new Point(m.X, m.Y));
   380         }
   381       }
   382     }
   383 
   384     private void saveReportMenuItem_Click(object sender, EventArgs e) {
   385       string report = computer.GetReport();
   386       if (saveFileDialog.ShowDialog() == DialogResult.OK) {
   387         using (TextWriter w = new StreamWriter(saveFileDialog.FileName)) {
   388           w.Write(report);
   389         }
   390       }
   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 (minimizeToTray.Value && 
   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 removeMenuItem_Click(object sender, EventArgs e) {
   415       MenuItem item = sender as MenuItem;
   416       if (item == null)
   417         return;
   418 
   419       ISensor sensor = item.Parent.Tag as ISensor;
   420       if (sensor == null)
   421         return;
   422 
   423       systemTray.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 celciusMenuItem_Click(object sender, EventArgs e) {
   443       celciusMenuItem.Checked = true;
   444       fahrenheitMenuItem.Checked = false;
   445       UnitManager.TemperatureUnit = TemperatureUnit.Celcius;
   446     }
   447 
   448     private void fahrenheitMenuItem_Click(object sender, EventArgs e) {
   449       celciusMenuItem.Checked = false;
   450       fahrenheitMenuItem.Checked = true;
   451       UnitManager.TemperatureUnit = TemperatureUnit.Fahrenheit;
   452     }
   453 
   454     private void sumbitReportMenuItem_Click(object sender, EventArgs e) 
   455     {
   456       ReportForm form = new ReportForm();
   457       form.Report = computer.GetReport();
   458       form.ShowDialog();      
   459     }
   460 
   461     private void resetMinMaxMenuItem_Click(object sender, EventArgs e) {
   462       IVisitor visitor = new ResetMinMaxVisitor();
   463       computer.Accept(visitor);
   464     }
   465   }
   466 }