Refactored the hardware code and added the visitor pattern for operations on the computer/hardware/sensor/parameter tree.
3 Version: MPL 1.1/GPL 2.0/LGPL 2.1
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
9 http://www.mozilla.org/MPL/
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.
15 The Original Code is the Open Hardware Monitor code.
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.
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.
39 using System.Collections.Generic;
40 using System.ComponentModel;
41 using System.Configuration;
45 using System.Windows.Forms;
46 using Aga.Controls.Tree;
47 using Aga.Controls.Tree.NodeControls;
48 using OpenHardwareMonitor.Hardware;
49 using OpenHardwareMonitor.Utilities;
51 namespace OpenHardwareMonitor.GUI {
52 public partial class MainForm : Form {
54 private Computer computer = new Computer();
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();
67 InitializeComponent();
68 this.Font = SystemFonts.MessageBoxFont;
69 treeView.Font = SystemFonts.MessageBoxFont;
70 plotPanel.Font = SystemFonts.MessageBoxFont;
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);
88 if (Utilities.Config.Contains("mainForm.Location.X")) {
89 int x = Utilities.Config.Get("mainForm.Location.X", Location.X);
91 int y = Utilities.Config.Get("mainForm.Location.Y", Location.Y);
93 this.Location = new Point(x, y);
95 StartPosition = FormStartPosition.CenterScreen;
98 Width = Utilities.Config.Get("mainForm.Width", Width);
99 Height = Utilities.Config.Get("mainForm.Height", Height);
101 treeModel = new TreeModel();
102 root = new Node(System.Environment.MachineName);
103 root.Image = Utilities.EmbeddedResources.GetImage("computer.png");
105 treeModel.Nodes.Add(root);
106 treeView.Model = treeModel;
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);
114 sensorSystemTray = new SensorSystemTray(computer);
116 computer.HardwareAdded += new HardwareEventHandler(HardwareAdded);
117 computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved);
120 timer.Enabled = true;
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;
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);
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);
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);
155 if (startMinMenuItem.Checked) {
156 if (!minTrayMenuItem.Checked) {
157 WindowState = FormWindowState.Minimized;
164 // Create a handle, otherwise calling Close() does not fire FormClosed
165 IntPtr handle = Handle;
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);
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);
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);
189 foreach (Node node in nodesToRemove)
190 root.Nodes.Remove(node);
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);
199 private void nodeTextBoxText_DrawText(object sender, DrawEventArgs e) {
200 if (!plotMenuItem.Checked)
203 SensorNode sensorNode = e.Node.Tag as SensorNode;
204 if (sensorNode != null) {
206 if (sensorPlotColors.TryGetValue(sensorNode.Sensor, out color))
211 private void UpdatePlotSelection(object sender,
214 List<ISensor> selected = new List<ISensor>();
215 IDictionary<ISensor, Color> colors = new Dictionary<ISensor, Color>();
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);
229 sensorPlotColors = colors;
230 plotPanel.SetSensors(selected, colors);
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;
241 private void exitToolStripMenuItem_Click(object sender, EventArgs e) {
245 private void timer_Tick(object sender, EventArgs e) {
246 computer.Accept(updateVisitor);
247 treeView.Invalidate();
248 plotPanel.Invalidate();
249 sensorSystemTray.Redraw();
252 private void MainForm_FormClosed(object sender, FormClosedEventArgs e) {
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);
259 Config.Set(startMinMenuItem.Name, startMinMenuItem.Checked);
260 Config.Set(minTrayMenuItem.Name, minTrayMenuItem.Checked);
261 Config.Set(hddMenuItem.Name, hddMenuItem.Checked);
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);
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);
277 timer.Enabled = false;
279 sensorSystemTray.Dispose();
280 notifyIcon.Dispose();
284 private void aboutToolStripMenuItem_Click(object sender, EventArgs e) {
285 new AboutBox().ShowDialog();
288 private void plotToolStripMenuItem_CheckedChanged(object sender,
291 splitContainer.Panel2Collapsed = !plotMenuItem.Checked;
292 treeView.Invalidate();
295 private void valueToolStripMenuItem_CheckedChanged(object sender,
298 treeView.Columns[1].IsVisible = valueToolStripMenuItem.Checked;
301 private void minToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
303 treeView.Columns[2].IsVisible = minMenuItem.Checked;
306 private void maxToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
308 treeView.Columns[3].IsVisible = maxMenuItem.Checked;
311 private void limitToolStripMenuItem_CheckedChanged(object sender,
313 treeView.Columns[4].IsVisible = limitMenuItem.Checked;
316 private void treeView_Click(object sender, EventArgs e) {
318 MouseEventArgs m = e as MouseEventArgs;
319 if (m == null || m.Button != MouseButtons.Right)
322 NodeControlInfo info = treeView.GetNodeControlInfoAt(new Point(m.X, m.Y));
323 if (info.Control == null) {
324 columnsContextMenuStrip.Show(treeView, m.X, m.Y);
326 SensorNode node = info.Node.Tag as SensorNode;
327 if (node != null && node.Sensor != null) {
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);
335 sensorContextMenuStrip.Items.Add(item);
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);
342 sensorContextMenuStrip.Items.Add(item);
344 ToolStripMenuItem item = new ToolStripMenuItem("Add To Tray");
345 item.Click += delegate(object obj, EventArgs args) {
346 sensorSystemTray.Add(node.Sensor, true);
348 sensorContextMenuStrip.Items.Add(item);
350 sensorContextMenuStrip.Show(treeView, m.X, m.Y);
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)) {
364 private void hddsensorsToolStripMenuItem_CheckedChanged(object sender,
367 computer.HDDEnabled = hddMenuItem.Checked;
368 UpdateSensorTypeChecked(null, null);
369 UpdatePlotSelection(null, null);
372 private void UpdateSensorTypeVisible(Node node) {
373 HardwareNode hardwareNode = node as HardwareNode;
374 if (hardwareNode == null)
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);
384 foreach (Node n in node.Nodes)
385 UpdateSensorTypeVisible(n);
388 private void UpdateSensorTypeChecked(object sender, EventArgs e) {
389 foreach (HardwareNode node in root.Nodes)
390 UpdateSensorTypeVisible(node);
393 private void SysTrayHideShow() {
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) {
410 private void hideShowClick(object sender, EventArgs e) {
414 private void removeToolStripMenuItem_Click(object sender, EventArgs e) {
415 ToolStripMenuItem item = sender as ToolStripMenuItem;
419 ISensor sensor = item.Owner.Tag as ISensor;
423 sensorSystemTray.Remove(sensor);
426 private void ShowParameterForm(ISensor sensor) {
427 ParameterForm form = new ParameterForm();
428 form.Parameters = sensor.Parameters;
429 form.captionLabel.Text = sensor.Name;
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);
442 private void runOnWindowsStartupToolStripMenuItem_CheckedChanged(
443 object sender, EventArgs e)
445 startupManager.Startup = startupMenuItem.Checked;
448 private void minTrayMenuItem_CheckedChanged(object sender, EventArgs e) {
449 notifyIcon.Visible = minTrayMenuItem.Checked;