Fixed the GadgetWindow AlwaysOnTop option (could be lost by tracking "Show Desktop" events even when AlwaysOnTop = true).
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) 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;
41 using System.Windows.Forms;
42 using OpenHardwareMonitor.Hardware;
44 namespace OpenHardwareMonitor.GUI {
45 public class SensorGadget : Gadget {
47 private UnitManager unitManager;
49 private Image back = Utilities.EmbeddedResources.GetImage("gadget.png");
50 private Image barBack = Utilities.EmbeddedResources.GetImage("barback.png");
51 private Image barblue = Utilities.EmbeddedResources.GetImage("barblue.png");
52 private const int topBorder = 4;
53 private const int bottomBorder = 6;
54 private const int leftBorder = 6;
55 private const int rightBorder = 6;
56 private const int iconSize = 11;
57 private const int hardwareLineHeight = 13;
58 private const int sensorLineHeight = 11;
60 private IDictionary<IHardware, IList<ISensor>> sensors =
61 new SortedDictionary<IHardware, IList<ISensor>>(new HardwareComparer());
63 private PersistentSettings settings;
64 private UserOption alwaysOnTop;
65 private UserOption lockPosition;
67 private Font largeFont;
68 private Font smallFont;
69 private Brush darkWhite = new SolidBrush(Color.FromArgb(0xF0, 0xF0, 0xF0));
71 public SensorGadget(IComputer computer, PersistentSettings settings,
72 UnitManager unitManager)
74 this.unitManager = unitManager;
75 this.settings = settings;
76 computer.HardwareAdded += new HardwareEventHandler(HardwareAdded);
77 computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved);
79 this.largeFont = new Font(SystemFonts.MessageBoxFont.FontFamily, 7.5f,
81 this.smallFont = new Font(SystemFonts.MessageBoxFont.FontFamily, 6.5f);
83 this.Location = new Point(
84 settings.GetValue("sensorGadget.Location.X", 100),
85 settings.GetValue("sensorGadget.Location.Y", 100));
86 LocationChanged += delegate(object sender, EventArgs e) {
87 settings.SetValue("sensorGadget.Location.X", Location.X);
88 settings.SetValue("sensorGadget.Location.Y", Location.Y);
91 ContextMenu contextMenu = new ContextMenu();
92 MenuItem lockItem = new MenuItem("Lock Position");
93 contextMenu.MenuItems.Add(lockItem);
94 contextMenu.MenuItems.Add(new MenuItem("-"));
95 MenuItem alwaysOnTopItem = new MenuItem("Always on Top");
96 contextMenu.MenuItems.Add(alwaysOnTopItem);
97 MenuItem opacityMenu = new MenuItem("Opacity");
98 contextMenu.MenuItems.Add(opacityMenu);
99 Opacity = (byte)settings.GetValue("sensorGadget.Opacity", 255);
100 for (int i = 0; i < 5; i++) {
101 MenuItem item = new MenuItem((20 * (i + 1)).ToString() + " %");
102 byte o = (byte)(51 * (i + 1));
103 item.Checked = Opacity == o;
104 item.Click += delegate(object sender, EventArgs e) {
106 settings.SetValue("sensorGadget.Opacity", Opacity);
107 foreach (MenuItem mi in opacityMenu.MenuItems)
108 mi.Checked = mi == item;
110 opacityMenu.MenuItems.Add(item);
112 this.ContextMenu = contextMenu;
114 alwaysOnTop = new UserOption("sensorGadget.AlwaysOnTop", false,
115 alwaysOnTopItem, settings);
116 alwaysOnTop.Changed += delegate(object sender, EventArgs e) {
117 this.AlwaysOnTop = alwaysOnTop.Value;
119 lockPosition = new UserOption("sensorGadget.LockPosition", false,
121 lockPosition.Changed += delegate(object sender, EventArgs e) {
122 this.LockPosition = lockPosition.Value;
128 private void HardwareRemoved(IHardware hardware) {
129 hardware.SensorAdded -= new SensorEventHandler(SensorAdded);
130 hardware.SensorRemoved -= new SensorEventHandler(SensorRemoved);
131 foreach (ISensor sensor in hardware.Sensors)
132 SensorRemoved(sensor);
133 foreach (IHardware subHardware in hardware.SubHardware)
134 HardwareRemoved(subHardware);
137 private void HardwareAdded(IHardware hardware) {
138 foreach (ISensor sensor in hardware.Sensors)
140 hardware.SensorAdded += new SensorEventHandler(SensorAdded);
141 hardware.SensorRemoved += new SensorEventHandler(SensorRemoved);
142 foreach (IHardware subHardware in hardware.SubHardware)
143 HardwareAdded(subHardware);
146 private void SensorAdded(ISensor sensor) {
147 if (settings.GetValue(new Identifier(sensor.Identifier,
148 "gadget").ToString(), false))
152 private void SensorRemoved(ISensor sensor) {
153 if (Contains(sensor))
154 Remove(sensor, false);
157 public bool Contains(ISensor sensor) {
158 foreach (IList<ISensor> list in sensors.Values)
159 if (list.Contains(sensor))
164 public void Add(ISensor sensor) {
165 if (Contains(sensor)) {
168 // get the right hardware
169 IHardware hardware = sensor.Hardware;
170 while (hardware.Parent != null)
171 hardware = hardware.Parent;
173 // get the sensor list associated with the hardware
175 if (!sensors.TryGetValue(hardware, out list)) {
176 list = new List<ISensor>();
177 sensors.Add(hardware, list);
180 // insert the sensor at the right position
182 while (i < list.Count && (list[i].SensorType < sensor.SensorType ||
183 (list[i].SensorType == sensor.SensorType &&
184 list[i].Index < sensor.Index))) i++;
185 list.Insert(i, sensor);
188 new Identifier(sensor.Identifier, "gadget").ToString(), true);
195 public void Remove(ISensor sensor) {
196 Remove(sensor, true);
199 private void Remove(ISensor sensor, bool deleteConfig) {
201 settings.Remove(new Identifier(sensor.Identifier, "gadget").ToString());
203 foreach (KeyValuePair<IHardware, IList<ISensor>> keyValue in sensors)
204 if (keyValue.Value.Contains(sensor)) {
205 keyValue.Value.Remove(sensor);
206 if (keyValue.Value.Count == 0) {
207 sensors.Remove(keyValue.Key);
215 private void Resize() {
216 int y = topBorder + 1;
217 foreach (KeyValuePair<IHardware, IList<ISensor>> pair in sensors) {
218 y += hardwareLineHeight;
219 y += pair.Value.Count * sensorLineHeight;
221 y += bottomBorder + 2;
222 y = Math.Max(y, topBorder + bottomBorder + 10);
223 this.Size = new Size(130, y);
226 private void DrawBackground(Graphics g) {
230 int b = bottomBorder;
233 GraphicsUnit u = GraphicsUnit.Pixel;
235 g.DrawImage(back, new Rectangle(0, 0, l, t),
236 new Rectangle(0, 0, l, t), u);
237 g.DrawImage(back, new Rectangle(l, 0, w - l - r, t),
238 new Rectangle(l, 0, back.Width - l - r, t), u);
239 g.DrawImage(back, new Rectangle(w - r, 0, r, t),
240 new Rectangle(back.Width - r, 0, r, t), u);
242 g.DrawImage(back, new Rectangle(0, t, l, h - t - b),
243 new Rectangle(0, t, l, back.Height - t - b), u);
244 g.DrawImage(back, new Rectangle(l, t, w - l - r, h - t - b),
245 new Rectangle(l, t, back.Width - l - r, back.Height - t - b), u);
246 g.DrawImage(back, new Rectangle(w - r, t, r, h - t - b),
247 new Rectangle(back.Width - r, t, r, back.Height - t - b), u);
249 g.DrawImage(back, new Rectangle(0, h - b, l, b),
250 new Rectangle(0, back.Height - b, l, b), u);
251 g.DrawImage(back, new Rectangle(l, h - b, w - l - r, b),
252 new Rectangle(l, back.Height - b, back.Width - l - r, b), u);
253 g.DrawImage(back, new Rectangle(w - r, h - b, r, b),
254 new Rectangle(back.Width - r, back.Height - b, r, b), u);
257 private void DrawProgress(Graphics g, int x, int y, int width, int height,
261 new RectangleF(x + width * progress, y, width * (1 - progress), height),
262 new RectangleF(barBack.Width * progress, 0,
263 (1 - progress) * barBack.Width, barBack.Height),
266 new RectangleF(x, y, width * progress, height),
267 new RectangleF(0, 0, progress * barblue.Width, barblue.Height),
271 protected override void OnPaint(PaintEventArgs e) {
272 Graphics g = e.Graphics;
276 g.Clear(Color.Transparent);
280 StringFormat stringFormat = new StringFormat();
281 stringFormat.Alignment = StringAlignment.Far;
284 int y = topBorder + 1;
285 foreach (KeyValuePair<IHardware, IList<ISensor>> pair in sensors) {
287 g.DrawImage(HardwareTypeImage.Instance.GetImage(pair.Key.HardwareType),
288 new Rectangle(x, y + 2, iconSize, iconSize));
290 g.DrawString(pair.Key.Name, largeFont, Brushes.White,
291 new Rectangle(x, y, w - rightBorder - x, 15));
292 y += hardwareLineHeight;
294 foreach (ISensor sensor in pair.Value) {
296 g.DrawString(sensor.Name + ":", smallFont, darkWhite,
297 new Rectangle(9, y, 64, 15));
299 if (sensor.SensorType != SensorType.Load &&
300 sensor.SensorType != SensorType.Control)
303 switch (sensor.SensorType) {
304 case SensorType.Voltage:
307 case SensorType.Clock:
308 format = "{0:F0} MHz";
310 case SensorType.Temperature:
311 format = "{0:F1} °C";
314 format = "{0:F0} RPM";
316 case SensorType.Flow:
317 format = "{0:F0} L/h";
321 string formattedValue;
322 if (sensor.SensorType == SensorType.Temperature &&
323 unitManager.TemperatureUnit == TemperatureUnit.Fahrenheit) {
324 formattedValue = string.Format("{0:F1} °F",
325 sensor.Value * 1.8 + 32);
327 formattedValue = string.Format(format, sensor.Value);
331 g.DrawString(formattedValue, smallFont, darkWhite,
332 new RectangleF(x, y, w - x - 9, 15), stringFormat);
335 DrawProgress(g, x, y + 4, w - x - 9, 6, 0.01f * sensor.Value.Value);
338 y += sensorLineHeight;
343 private class HardwareComparer : IComparer<IHardware> {
344 public int Compare(IHardware x, IHardware y) {
345 if (x == null && y == null)
352 if (x.HardwareType != y.HardwareType)
353 return x.HardwareType.CompareTo(y.HardwareType);
355 return x.Name.CompareTo(y.Name);