1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/GUI/SensorGadget.cs Mon Sep 06 19:53:13 2010 +0000
1.3 @@ -0,0 +1,361 @@
1.4 +/*
1.5 +
1.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
1.7 +
1.8 + The contents of this file are subject to the Mozilla Public License Version
1.9 + 1.1 (the "License"); you may not use this file except in compliance with
1.10 + the License. You may obtain a copy of the License at
1.11 +
1.12 + http://www.mozilla.org/MPL/
1.13 +
1.14 + Software distributed under the License is distributed on an "AS IS" basis,
1.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
1.16 + for the specific language governing rights and limitations under the License.
1.17 +
1.18 + The Original Code is the Open Hardware Monitor code.
1.19 +
1.20 + The Initial Developer of the Original Code is
1.21 + Michael Möller <m.moeller@gmx.ch>.
1.22 + Portions created by the Initial Developer are Copyright (C) 2010
1.23 + the Initial Developer. All Rights Reserved.
1.24 +
1.25 + Contributor(s):
1.26 +
1.27 + Alternatively, the contents of this file may be used under the terms of
1.28 + either the GNU General Public License Version 2 or later (the "GPL"), or
1.29 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
1.30 + in which case the provisions of the GPL or the LGPL are applicable instead
1.31 + of those above. If you wish to allow use of your version of this file only
1.32 + under the terms of either the GPL or the LGPL, and not to allow others to
1.33 + use your version of this file under the terms of the MPL, indicate your
1.34 + decision by deleting the provisions above and replace them with the notice
1.35 + and other provisions required by the GPL or the LGPL. If you do not delete
1.36 + the provisions above, a recipient may use your version of this file under
1.37 + the terms of any one of the MPL, the GPL or the LGPL.
1.38 +
1.39 +*/
1.40 +
1.41 +using System;
1.42 +using System.Collections.Generic;
1.43 +using System.Drawing;
1.44 +using System.Windows.Forms;
1.45 +using OpenHardwareMonitor.Hardware;
1.46 +
1.47 +namespace OpenHardwareMonitor.GUI {
1.48 + public class SensorGadget : Gadget {
1.49 +
1.50 + private UnitManager unitManager;
1.51 +
1.52 + private Image back = Utilities.EmbeddedResources.GetImage("gadget.png");
1.53 + private Image barBack = Utilities.EmbeddedResources.GetImage("barback.png");
1.54 + private Image barblue = Utilities.EmbeddedResources.GetImage("barblue.png");
1.55 + private const int topBorder = 4;
1.56 + private const int bottomBorder = 6;
1.57 + private const int leftBorder = 6;
1.58 + private const int rightBorder = 6;
1.59 + private const int iconSize = 11;
1.60 + private const int hardwareLineHeight = 13;
1.61 + private const int sensorLineHeight = 11;
1.62 +
1.63 + private IDictionary<IHardware, IList<ISensor>> sensors =
1.64 + new SortedDictionary<IHardware, IList<ISensor>>(new HardwareComparer());
1.65 +
1.66 + private PersistentSettings settings;
1.67 + private UserOption alwaysOnTop;
1.68 + private UserOption lockPosition;
1.69 +
1.70 + private Font largeFont;
1.71 + private Font smallFont;
1.72 + private Brush darkWhite = new SolidBrush(Color.FromArgb(0xF0, 0xF0, 0xF0));
1.73 +
1.74 + public SensorGadget(IComputer computer, PersistentSettings settings,
1.75 + UnitManager unitManager)
1.76 + {
1.77 + this.unitManager = unitManager;
1.78 + this.settings = settings;
1.79 + computer.HardwareAdded += new HardwareEventHandler(HardwareAdded);
1.80 + computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved);
1.81 +
1.82 + this.largeFont = new Font(SystemFonts.MessageBoxFont.FontFamily, 7.5f,
1.83 + FontStyle.Bold);
1.84 + this.smallFont = new Font(SystemFonts.MessageBoxFont.FontFamily, 6.5f);
1.85 +
1.86 + this.Location = new Point(
1.87 + settings.GetValue("sensorGadget.Location.X", 100),
1.88 + settings.GetValue("sensorGadget.Location.Y", 100));
1.89 + LocationChanged += delegate(object sender, EventArgs e) {
1.90 + settings.SetValue("sensorGadget.Location.X", Location.X);
1.91 + settings.SetValue("sensorGadget.Location.Y", Location.Y);
1.92 + };
1.93 +
1.94 + ContextMenu contextMenu = new ContextMenu();
1.95 + MenuItem lockItem = new MenuItem("Lock Position");
1.96 + contextMenu.MenuItems.Add(lockItem);
1.97 + contextMenu.MenuItems.Add(new MenuItem("-"));
1.98 + MenuItem alwaysOnTopItem = new MenuItem("Always on Top");
1.99 + contextMenu.MenuItems.Add(alwaysOnTopItem);
1.100 + MenuItem opacityMenu = new MenuItem("Opacity");
1.101 + contextMenu.MenuItems.Add(opacityMenu);
1.102 + Opacity = (byte)settings.GetValue("sensorGadget.Opacity", 255);
1.103 + for (int i = 0; i < 5; i++) {
1.104 + MenuItem item = new MenuItem((20 * (i + 1)).ToString() + " %");
1.105 + byte o = (byte)(51 * (i + 1));
1.106 + item.Tag = o;
1.107 + item.Checked = Opacity == o;
1.108 + item.Click += delegate(object sender, EventArgs e) {
1.109 + Opacity = (byte)item.Tag;
1.110 + settings.SetValue("sensorGadget.Opacity", Opacity);
1.111 + foreach (MenuItem mi in opacityMenu.MenuItems)
1.112 + mi.Checked = (byte)mi.Tag == Opacity;
1.113 + };
1.114 + opacityMenu.MenuItems.Add(item);
1.115 + }
1.116 + this.ContextMenu = contextMenu;
1.117 +
1.118 + alwaysOnTop = new UserOption("sensorGadget.AlwaysOnTop", false,
1.119 + alwaysOnTopItem, settings);
1.120 + alwaysOnTop.Changed += delegate(object sender, EventArgs e) {
1.121 + this.AlwaysOnTop = alwaysOnTop.Value;
1.122 + };
1.123 + lockPosition = new UserOption("sensorGadget.LockPosition", false,
1.124 + lockItem, settings);
1.125 + lockPosition.Changed += delegate(object sender, EventArgs e) {
1.126 + this.LockPosition = lockPosition.Value;
1.127 + };
1.128 +
1.129 + Resize();
1.130 + }
1.131 +
1.132 + private void HardwareRemoved(IHardware hardware) {
1.133 + hardware.SensorAdded -= new SensorEventHandler(SensorAdded);
1.134 + hardware.SensorRemoved -= new SensorEventHandler(SensorRemoved);
1.135 + foreach (ISensor sensor in hardware.Sensors)
1.136 + SensorRemoved(sensor);
1.137 + foreach (IHardware subHardware in hardware.SubHardware)
1.138 + HardwareRemoved(subHardware);
1.139 + }
1.140 +
1.141 + private void HardwareAdded(IHardware hardware) {
1.142 + foreach (ISensor sensor in hardware.Sensors)
1.143 + SensorAdded(sensor);
1.144 + hardware.SensorAdded += new SensorEventHandler(SensorAdded);
1.145 + hardware.SensorRemoved += new SensorEventHandler(SensorRemoved);
1.146 + foreach (IHardware subHardware in hardware.SubHardware)
1.147 + HardwareAdded(subHardware);
1.148 + }
1.149 +
1.150 + private void SensorAdded(ISensor sensor) {
1.151 + if (settings.GetValue(new Identifier(sensor.Identifier,
1.152 + "gadget").ToString(), false))
1.153 + Add(sensor);
1.154 + }
1.155 +
1.156 + private void SensorRemoved(ISensor sensor) {
1.157 + if (Contains(sensor))
1.158 + Remove(sensor, false);
1.159 + }
1.160 +
1.161 + public bool Contains(ISensor sensor) {
1.162 + foreach (IList<ISensor> list in sensors.Values)
1.163 + if (list.Contains(sensor))
1.164 + return true;
1.165 + return false;
1.166 + }
1.167 +
1.168 + public void Add(ISensor sensor) {
1.169 + if (Contains(sensor)) {
1.170 + return;
1.171 + } else {
1.172 + // get the right hardware
1.173 + IHardware hardware = sensor.Hardware;
1.174 + while (hardware.Parent != null)
1.175 + hardware = hardware.Parent;
1.176 +
1.177 + // get the sensor list associated with the hardware
1.178 + IList<ISensor> list;
1.179 + if (!sensors.TryGetValue(hardware, out list)) {
1.180 + list = new List<ISensor>();
1.181 + sensors.Add(hardware, list);
1.182 + }
1.183 +
1.184 + // insert the sensor at the right position
1.185 + int i = 0;
1.186 + while (i < list.Count && (list[i].SensorType < sensor.SensorType ||
1.187 + (list[i].SensorType == sensor.SensorType &&
1.188 + list[i].Index < sensor.Index))) i++;
1.189 + list.Insert(i, sensor);
1.190 +
1.191 + settings.SetValue(
1.192 + new Identifier(sensor.Identifier, "gadget").ToString(), true);
1.193 +
1.194 + Resize();
1.195 + Redraw();
1.196 + }
1.197 + }
1.198 +
1.199 + public void Remove(ISensor sensor) {
1.200 + Remove(sensor, true);
1.201 + }
1.202 +
1.203 + private void Remove(ISensor sensor, bool deleteConfig) {
1.204 + if (deleteConfig)
1.205 + settings.Remove(new Identifier(sensor.Identifier, "gadget").ToString());
1.206 +
1.207 + foreach (KeyValuePair<IHardware, IList<ISensor>> keyValue in sensors)
1.208 + if (keyValue.Value.Contains(sensor)) {
1.209 + keyValue.Value.Remove(sensor);
1.210 + if (keyValue.Value.Count == 0) {
1.211 + sensors.Remove(keyValue.Key);
1.212 + break;
1.213 + }
1.214 + }
1.215 + Resize();
1.216 + Redraw();
1.217 + }
1.218 +
1.219 + private void Resize() {
1.220 + int y = topBorder + 1;
1.221 + foreach (KeyValuePair<IHardware, IList<ISensor>> pair in sensors) {
1.222 + y += hardwareLineHeight;
1.223 + y += pair.Value.Count * sensorLineHeight;
1.224 + }
1.225 + y += bottomBorder + 2;
1.226 + y = Math.Max(y, topBorder + bottomBorder + 10);
1.227 + this.Size = new Size(130, y);
1.228 + }
1.229 +
1.230 + private void DrawBackground(Graphics g) {
1.231 + int w = Size.Width;
1.232 + int h = Size.Height;
1.233 + int t = topBorder;
1.234 + int b = bottomBorder;
1.235 + int l = leftBorder;
1.236 + int r = rightBorder;
1.237 + GraphicsUnit u = GraphicsUnit.Pixel;
1.238 +
1.239 + g.DrawImage(back, new Rectangle(0, 0, l, t),
1.240 + new Rectangle(0, 0, l, t), u);
1.241 + g.DrawImage(back, new Rectangle(l, 0, w - l - r, t),
1.242 + new Rectangle(l, 0, back.Width - l - r, t), u);
1.243 + g.DrawImage(back, new Rectangle(w - r, 0, r, t),
1.244 + new Rectangle(back.Width - r, 0, r, t), u);
1.245 +
1.246 + g.DrawImage(back, new Rectangle(0, t, l, h - t - b),
1.247 + new Rectangle(0, t, l, back.Height - t - b), u);
1.248 + g.DrawImage(back, new Rectangle(l, t, w - l - r, h - t - b),
1.249 + new Rectangle(l, t, back.Width - l - r, back.Height - t - b), u);
1.250 + g.DrawImage(back, new Rectangle(w - r, t, r, h - t - b),
1.251 + new Rectangle(back.Width - r, t, r, back.Height - t - b), u);
1.252 +
1.253 + g.DrawImage(back, new Rectangle(0, h - b, l, b),
1.254 + new Rectangle(0, back.Height - b, l, b), u);
1.255 + g.DrawImage(back, new Rectangle(l, h - b, w - l - r, b),
1.256 + new Rectangle(l, back.Height - b, back.Width - l - r, b), u);
1.257 + g.DrawImage(back, new Rectangle(w - r, h - b, r, b),
1.258 + new Rectangle(back.Width - r, back.Height - b, r, b), u);
1.259 + }
1.260 +
1.261 + private void DrawProgress(Graphics g, int x, int y, int width, int height,
1.262 + float progress)
1.263 + {
1.264 + g.DrawImage(barBack,
1.265 + new RectangleF(x + width * progress, y, width * (1 - progress), height),
1.266 + new RectangleF(barBack.Width * progress, 0,
1.267 + (1 - progress) * barBack.Width, barBack.Height),
1.268 + GraphicsUnit.Pixel);
1.269 + g.DrawImage(barblue,
1.270 + new RectangleF(x, y, width * progress, height),
1.271 + new RectangleF(0, 0, progress * barblue.Width, barblue.Height),
1.272 + GraphicsUnit.Pixel);
1.273 + }
1.274 +
1.275 + protected override void OnPaint(PaintEventArgs e) {
1.276 + Graphics g = e.Graphics;
1.277 + int w = Size.Width;
1.278 + int h = Size.Height;
1.279 +
1.280 + g.Clear(Color.Transparent);
1.281 +
1.282 + DrawBackground(g);
1.283 +
1.284 + StringFormat stringFormat = new StringFormat();
1.285 + stringFormat.Alignment = StringAlignment.Far;
1.286 +
1.287 + int x;
1.288 + int y = topBorder + 1;
1.289 + foreach (KeyValuePair<IHardware, IList<ISensor>> pair in sensors) {
1.290 + x = leftBorder + 1;
1.291 + g.DrawImage(HardwareTypeImage.Instance.GetImage(pair.Key.HardwareType),
1.292 + new Rectangle(x, y + 2, iconSize, iconSize));
1.293 + x += iconSize + 1;
1.294 + g.DrawString(pair.Key.Name, largeFont, Brushes.White,
1.295 + new Rectangle(x, y, w - rightBorder - x, 15));
1.296 + y += hardwareLineHeight;
1.297 +
1.298 + foreach (ISensor sensor in pair.Value) {
1.299 +
1.300 + g.DrawString(sensor.Name + ":", smallFont, darkWhite,
1.301 + new Rectangle(9, y, 64, 15));
1.302 +
1.303 + if (sensor.SensorType != SensorType.Load &&
1.304 + sensor.SensorType != SensorType.Control)
1.305 + {
1.306 + string format = "";
1.307 + switch (sensor.SensorType) {
1.308 + case SensorType.Voltage:
1.309 + format = "{0:F2} V";
1.310 + break;
1.311 + case SensorType.Clock:
1.312 + format = "{0:F0} MHz";
1.313 + break;
1.314 + case SensorType.Temperature:
1.315 + format = "{0:F1} °C";
1.316 + break;
1.317 + case SensorType.Fan:
1.318 + format = "{0:F0} RPM";
1.319 + break;
1.320 + case SensorType.Flow:
1.321 + format = "{0:F0} L/h";
1.322 + break;
1.323 + }
1.324 +
1.325 + string formattedValue;
1.326 + if (sensor.SensorType == SensorType.Temperature &&
1.327 + unitManager.TemperatureUnit == TemperatureUnit.Fahrenheit) {
1.328 + formattedValue = string.Format("{0:F1} °F",
1.329 + sensor.Value * 1.8 + 32);
1.330 + } else {
1.331 + formattedValue = string.Format(format, sensor.Value);
1.332 + }
1.333 +
1.334 + x = 75;
1.335 + g.DrawString(formattedValue, smallFont, darkWhite,
1.336 + new RectangleF(x, y, w - x - 9, 15), stringFormat);
1.337 + } else {
1.338 + x = 80;
1.339 + DrawProgress(g, x, y + 4, w - x - 9, 6, 0.01f * sensor.Value.Value);
1.340 + }
1.341 +
1.342 + y += sensorLineHeight;
1.343 + }
1.344 + }
1.345 + }
1.346 +
1.347 + private class HardwareComparer : IComparer<IHardware> {
1.348 + public int Compare(IHardware x, IHardware y) {
1.349 + if (x == null && y == null)
1.350 + return 0;
1.351 + if (x == null)
1.352 + return -1;
1.353 + if (y == null)
1.354 + return 1;
1.355 +
1.356 + if (x.HardwareType != y.HardwareType)
1.357 + return x.HardwareType.CompareTo(y.HardwareType);
1.358 +
1.359 + return x.Name.CompareTo(y.Name);
1.360 + }
1.361 + }
1.362 + }
1.363 +}
1.364 +