Added a first implementation for the Heatmaster fan controller.
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 PersistentSettings settings;
55 private UnitManager unitManager;
56 private Computer computer;
58 private TreeModel treeModel;
59 private IDictionary<ISensor, Color> sensorPlotColors =
60 new Dictionary<ISensor, Color>();
61 private Color[] plotColorPalette;
62 private SystemTray systemTray;
63 private StartupManager startupManager = new StartupManager();
64 private UpdateVisitor updateVisitor = new UpdateVisitor();
66 private UserOption showHiddenSensors;
67 private UserOption showPlot;
68 private UserOption showValue;
69 private UserOption showMin;
70 private UserOption showMax;
71 private UserOption startMinimized;
72 private UserOption minimizeToTray;
73 private UserOption autoStart;
74 private UserOption readHddSensors;
77 InitializeComponent();
79 this.settings = new PersistentSettings();
80 this.settings.Load(Path.ChangeExtension(
81 System.Windows.Forms.Application.ExecutablePath, ".config"));
83 this.unitManager = new UnitManager(settings);
85 // set the DockStyle here, to avoid conflicts with the MainMenu
86 this.splitContainer.Dock = DockStyle.Fill;
88 int p = (int)System.Environment.OSVersion.Platform;
89 if ((p == 4) || (p == 128)) {
90 splitContainer.BorderStyle = BorderStyle.None;
91 splitContainer.Border3DStyle = Border3DStyle.Adjust;
92 splitContainer.SplitterWidth = 4;
93 treeView.BorderStyle = BorderStyle.Fixed3D;
94 plotPanel.BorderStyle = BorderStyle.Fixed3D;
97 this.Font = SystemFonts.MessageBoxFont;
98 treeView.Font = SystemFonts.MessageBoxFont;
99 plotPanel.Font = SystemFonts.MessageBoxFont;
101 nodeCheckBox.IsVisibleValueNeeded += nodeCheckBox_IsVisibleValueNeeded;
102 nodeCheckBox.CheckStateChanged += UpdatePlotSelection;
103 nodeTextBoxText.DrawText += nodeTextBoxText_DrawText;
104 nodeTextBoxValue.DrawText += nodeTextBoxText_DrawText;
105 nodeTextBoxMin.DrawText += nodeTextBoxText_DrawText;
106 nodeTextBoxMax.DrawText += nodeTextBoxText_DrawText;
107 nodeTextBoxText.EditorShowing += nodeTextBoxText_EditorShowing;
109 if (settings.Contains("mainForm.Location.X")) {
110 int x = settings.GetValue("mainForm.Location.X", Location.X);
112 int y = settings.GetValue("mainForm.Location.Y", Location.Y);
114 this.Location = new Point(x, y);
116 StartPosition = FormStartPosition.CenterScreen;
119 ClientSize = new Size(
120 settings.GetValue("mainForm.Width", 470),
121 settings.GetValue("mainForm.Height", 640));
123 foreach (TreeColumn column in treeView.Columns)
124 column.Width = Math.Max(20, Math.Min(400,
125 settings.GetValue("treeView.Columns." + column.Header + ".Width",
128 treeModel = new TreeModel();
129 root = new Node(System.Environment.MachineName);
130 root.Image = Utilities.EmbeddedResources.GetImage("computer.png");
132 treeModel.Nodes.Add(root);
133 treeView.Model = treeModel;
135 this.computer = new Computer(settings);
137 systemTray = new SystemTray(computer, settings);
138 systemTray.HideShowCommand += hideShowClick;
139 systemTray.ExitCommand += exitClick;
141 computer.HardwareAdded += new HardwareEventHandler(HardwareAdded);
142 computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved);
145 timer.Enabled = true;
147 plotColorPalette = new Color[13];
148 plotColorPalette[0] = Color.Blue;
149 plotColorPalette[1] = Color.OrangeRed;
150 plotColorPalette[2] = Color.Green;
151 plotColorPalette[3] = Color.LightSeaGreen;
152 plotColorPalette[4] = Color.Goldenrod;
153 plotColorPalette[5] = Color.DarkViolet;
154 plotColorPalette[6] = Color.YellowGreen;
155 plotColorPalette[7] = Color.SaddleBrown;
156 plotColorPalette[8] = Color.RoyalBlue;
157 plotColorPalette[9] = Color.DeepPink;
158 plotColorPalette[10] = Color.MediumSeaGreen;
159 plotColorPalette[11] = Color.Olive;
160 plotColorPalette[12] = Color.Firebrick;
162 showHiddenSensors = new UserOption("hiddenMenuItem", false, hiddenMenuItem, settings);
163 showHiddenSensors.Changed += delegate(object sender, EventArgs e) {
164 treeModel.ForceVisible = showHiddenSensors.Value;
167 showPlot = new UserOption("plotMenuItem", false, plotMenuItem, settings);
168 showPlot.Changed += delegate(object sender, EventArgs e) {
169 splitContainer.Panel2Collapsed = !showPlot.Value;
170 treeView.Invalidate();
173 showValue = new UserOption("valueMenuItem", true, valueMenuItem, settings);
174 showValue.Changed += delegate(object sender, EventArgs e) {
175 treeView.Columns[1].IsVisible = showValue.Value;
178 showMin = new UserOption("minMenuItem", false, minMenuItem, settings);
179 showMin.Changed += delegate(object sender, EventArgs e) {
180 treeView.Columns[2].IsVisible = showMin.Value;
183 showMax = new UserOption("maxMenuItem", true, maxMenuItem, settings);
184 showMax.Changed += delegate(object sender, EventArgs e) {
185 treeView.Columns[3].IsVisible = showMax.Value;
188 startMinimized = new UserOption("startMinMenuItem", false, startMinMenuItem, settings);
190 minimizeToTray = new UserOption("minTrayMenuItem", true, minTrayMenuItem, settings);
191 minimizeToTray.Changed += delegate(object sender, EventArgs e) {
192 systemTray.IsMainIconEnabled = minimizeToTray.Value;
195 autoStart = new UserOption(null, startupManager.Startup, startupMenuItem, settings);
196 autoStart.Changed += delegate(object sender, EventArgs e) {
197 startupManager.Startup = autoStart.Value; ;
200 readHddSensors = new UserOption("hddMenuItem", true, hddMenuItem, settings);
201 readHddSensors.Changed += delegate(object sender, EventArgs e) {
202 computer.HDDEnabled = readHddSensors.Value;
203 UpdatePlotSelection(null, null);
206 celciusMenuItem.Checked =
207 unitManager.TemperatureUnit == TemperatureUnit.Celcius;
208 fahrenheitMenuItem.Checked = !celciusMenuItem.Checked;
210 startupMenuItem.Visible = startupManager.IsAvailable;
212 if (startMinMenuItem.Checked) {
213 if (!minTrayMenuItem.Checked) {
214 WindowState = FormWindowState.Minimized;
221 // Create a handle, otherwise calling Close() does not fire FormClosed
222 IntPtr handle = Handle;
224 // Make sure the settings are saved when the user logs off
225 Microsoft.Win32.SystemEvents.SessionEnded +=
226 delegate(object sender, Microsoft.Win32.SessionEndedEventArgs e) {
231 private void SubHardwareAdded(IHardware hardware, Node node) {
232 Node hardwareNode = new HardwareNode(hardware, settings, unitManager);
233 node.Nodes.Add(hardwareNode);
234 foreach (IHardware subHardware in hardware.SubHardware)
235 SubHardwareAdded(subHardware, hardwareNode);
238 private void HardwareAdded(IHardware hardware) {
239 Node hardwareNode = new HardwareNode(hardware, settings, unitManager);
240 root.Nodes.Add(hardwareNode);
241 foreach (IHardware subHardware in hardware.SubHardware)
242 SubHardwareAdded(subHardware, hardwareNode);
245 private void HardwareRemoved(IHardware hardware) {
246 List<Node> nodesToRemove = new List<Node>();
247 foreach (Node node in root.Nodes) {
248 HardwareNode hardwareNode = node as HardwareNode;
249 if (hardwareNode != null && hardwareNode.Hardware == hardware)
250 nodesToRemove.Add(node);
252 foreach (Node node in nodesToRemove)
253 root.Nodes.Remove(node);
256 private void nodeTextBoxText_DrawText(object sender, DrawEventArgs e) {
257 Node node = e.Node.Tag as Node;
260 if (node.IsVisible) {
261 SensorNode sensorNode = node as SensorNode;
262 if (plotMenuItem.Checked && sensorNode != null &&
263 sensorPlotColors.TryGetValue(sensorNode.Sensor, out color))
266 e.TextColor = Color.DarkGray;
271 private void UpdatePlotSelection(object sender,
274 List<ISensor> selected = new List<ISensor>();
275 IDictionary<ISensor, Color> colors = new Dictionary<ISensor, Color>();
277 foreach (TreeNodeAdv node in treeView.AllNodes) {
278 SensorNode sensorNode = node.Tag as SensorNode;
279 if (sensorNode != null &&
280 sensorNode.Sensor.SensorType == SensorType.Temperature) {
281 if (sensorNode.Plot) {
282 colors.Add(sensorNode.Sensor,
283 plotColorPalette[colorIndex % plotColorPalette.Length]);
284 selected.Add(sensorNode.Sensor);
289 sensorPlotColors = colors;
290 plotPanel.SetSensors(selected, colors);
293 private void nodeTextBoxText_EditorShowing(object sender, CancelEventArgs e)
295 e.Cancel = !(treeView.CurrentNode != null &&
296 treeView.CurrentNode.Tag is SensorNode);
299 private void nodeCheckBox_IsVisibleValueNeeded(object sender,
300 NodeControlValueEventArgs e) {
301 SensorNode node = e.Node.Tag as SensorNode;
302 e.Value = (node != null) &&
303 (node.Sensor.SensorType == SensorType.Temperature) &&
304 plotMenuItem.Checked;
307 private void exitClick(object sender, EventArgs e) {
311 private void timer_Tick(object sender, EventArgs e) {
312 computer.Accept(updateVisitor);
313 treeView.Invalidate();
314 plotPanel.Invalidate();
318 private void SaveConfiguration() {
319 if (WindowState != FormWindowState.Minimized) {
320 settings.SetValue("mainForm.Location.X", Location.X);
321 settings.SetValue("mainForm.Location.Y", Location.Y);
322 settings.SetValue("mainForm.Width", ClientSize.Width);
323 settings.SetValue("mainForm.Height", ClientSize.Height);
326 foreach (TreeColumn column in treeView.Columns)
327 settings.SetValue("treeView.Columns." + column.Header + ".Width",
330 settings.Save(Path.ChangeExtension(
331 System.Windows.Forms.Application.ExecutablePath, ".config"));
334 private void MainForm_FormClosed(object sender, FormClosedEventArgs e) {
338 timer.Enabled = false;
339 systemTray.Dispose();
343 private void aboutMenuItem_Click(object sender, EventArgs e) {
344 new AboutBox().ShowDialog();
347 private void treeView_Click(object sender, EventArgs e) {
349 MouseEventArgs m = e as MouseEventArgs;
350 if (m == null || m.Button != MouseButtons.Right)
353 NodeControlInfo info = treeView.GetNodeControlInfoAt(new Point(m.X, m.Y));
354 treeView.SelectedNode = info.Node;
355 if (info.Node != null) {
356 SensorNode node = info.Node.Tag as SensorNode;
357 if (node != null && node.Sensor != null) {
358 sensorContextMenu.MenuItems.Clear();
359 if (node.Sensor.Parameters.Length > 0) {
360 MenuItem item = new MenuItem("Parameters...");
361 item.Click += delegate(object obj, EventArgs args) {
362 ShowParameterForm(node.Sensor);
364 sensorContextMenu.MenuItems.Add(item);
366 if (nodeTextBoxText.EditEnabled) {
367 MenuItem item = new MenuItem("Rename");
368 item.Click += delegate(object obj, EventArgs args) {
369 nodeTextBoxText.BeginEdit();
371 sensorContextMenu.MenuItems.Add(item);
373 if (node.IsVisible) {
374 MenuItem item = new MenuItem("Hide");
375 item.Click += delegate(object obj, EventArgs args) {
376 node.IsVisible = false;
378 sensorContextMenu.MenuItems.Add(item);
380 MenuItem item = new MenuItem("Unhide");
381 item.Click += delegate(object obj, EventArgs args) {
382 node.IsVisible = true;
384 sensorContextMenu.MenuItems.Add(item);
386 if (systemTray.Contains(node.Sensor)) {
387 MenuItem item = new MenuItem("Remove From Tray");
388 item.Click += delegate(object obj, EventArgs args) {
389 systemTray.Remove(node.Sensor);
391 sensorContextMenu.MenuItems.Add(item);
393 MenuItem item = new MenuItem("Add To Tray");
394 item.Click += delegate(object obj, EventArgs args) {
395 systemTray.Add(node.Sensor, true);
397 sensorContextMenu.MenuItems.Add(item);
399 sensorContextMenu.Show(treeView, new Point(m.X, m.Y));
404 private void saveReportMenuItem_Click(object sender, EventArgs e) {
405 string report = computer.GetReport();
406 if (saveFileDialog.ShowDialog() == DialogResult.OK) {
407 using (TextWriter w = new StreamWriter(saveFileDialog.FileName)) {
413 private void SysTrayHideShow() {
419 protected override void WndProc(ref Message m) {
420 const int WM_SYSCOMMAND = 0x112;
421 const int SC_MINIMIZE = 0xF020;
422 if (minimizeToTray.Value &&
423 m.Msg == WM_SYSCOMMAND && m.WParam.ToInt32() == SC_MINIMIZE) {
430 private void hideShowClick(object sender, EventArgs e) {
434 private void removeMenuItem_Click(object sender, EventArgs e) {
435 MenuItem item = sender as MenuItem;
439 ISensor sensor = item.Parent.Tag as ISensor;
443 systemTray.Remove(sensor);
446 private void ShowParameterForm(ISensor sensor) {
447 ParameterForm form = new ParameterForm();
448 form.Parameters = sensor.Parameters;
449 form.captionLabel.Text = sensor.Name;
453 private void treeView_NodeMouseDoubleClick(object sender,
454 TreeNodeAdvMouseEventArgs e) {
455 SensorNode node = e.Node.Tag as SensorNode;
456 if (node != null && node.Sensor != null &&
457 node.Sensor.Parameters.Length > 0) {
458 ShowParameterForm(node.Sensor);
462 private void celciusMenuItem_Click(object sender, EventArgs e) {
463 celciusMenuItem.Checked = true;
464 fahrenheitMenuItem.Checked = false;
465 unitManager.TemperatureUnit = TemperatureUnit.Celcius;
468 private void fahrenheitMenuItem_Click(object sender, EventArgs e) {
469 celciusMenuItem.Checked = false;
470 fahrenheitMenuItem.Checked = true;
471 unitManager.TemperatureUnit = TemperatureUnit.Fahrenheit;
474 private void sumbitReportMenuItem_Click(object sender, EventArgs e)
476 ReportForm form = new ReportForm();
477 form.Report = computer.GetReport();
481 private void resetMinMaxMenuItem_Click(object sender, EventArgs e) {
482 computer.Accept(new SensorVisitor(delegate(ISensor sensor) {