Adding SoundGraphDisplay and SensorFrontView classes.
They were respectively based on SystemTray and SensorNotifyIcon.
SoundGraphDisplay is now able to load iMONDisplay.dll providing it lives on your PATH.
Adding option to sensor context menu for adding it into FrontView.
3 This Source Code Form is subject to the terms of the Mozilla Public
4 License, v. 2.0. If a copy of the MPL was not distributed with this
5 file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 Copyright (C) 2009-2012 Michael Möller <mmoeller@openhardwaremonitor.org>
13 using System.Drawing.Drawing2D;
14 using System.Drawing.Imaging;
15 using System.Drawing.Text;
16 using System.Runtime.InteropServices;
17 using System.Windows.Forms;
18 using OpenHardwareMonitor.Hardware;
19 using OpenHardwareMonitor.Utilities;
21 namespace OpenHardwareMonitor.GUI
23 public class SensorFrontView : IDisposable
26 private UnitManager unitManager;
28 private ISensor sensor;
29 private Bitmap bitmap;
30 private Graphics graphics;
32 private Color darkColor;
34 private Brush darkBrush;
37 private Font smallFont;
39 public SensorFrontView(SoundGraphDisplay soundGraphDisplay, ISensor sensor,
40 bool balloonTip, PersistentSettings settings, UnitManager unitManager)
42 this.unitManager = unitManager;
45 // get the default dpi to create an icon with the correct size
47 using (Bitmap b = new Bitmap(1, 1, PixelFormat.Format32bppArgb))
49 dpiX = b.HorizontalResolution;
50 dpiY = b.VerticalResolution;
53 // adjust the size of the icon to current dpi (default is 16x16 at 96 dpi)
54 int width = (int)Math.Round(16 * dpiX / 96);
55 int height = (int)Math.Round(16 * dpiY / 96);
57 // make sure it does never get smaller than 16x16
58 width = width < 16 ? 16 : width;
59 height = height < 16 ? 16 : height;
61 // adjust the font size to the icon size
62 FontFamily family = SystemFonts.MessageBoxFont.FontFamily;
66 case "Segoe UI": baseSize = 12; break;
67 case "Tahoma": baseSize = 11; break;
68 default: baseSize = 12; break;
71 this.font = new Font(family,
72 baseSize * width / 16.0f, GraphicsUnit.Pixel);
73 this.smallFont = new Font(family,
74 0.75f * baseSize * width / 16.0f, GraphicsUnit.Pixel);
76 this.bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
77 this.graphics = Graphics.FromImage(this.bitmap);
79 if (Environment.OSVersion.Version.Major > 5)
81 this.graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
82 this.graphics.SmoothingMode = SmoothingMode.HighQuality;
88 get { return sensor; }
97 this.darkColor = Color.FromArgb(255,
101 Brush brush = this.brush;
102 this.brush = new SolidBrush(this.color);
105 Brush darkBrush = this.darkBrush;
106 this.darkBrush = new SolidBrush(this.darkColor);
107 if (darkBrush != null)
112 public void Dispose()
117 if (darkBrush != null)
126 private string GetString()
128 if (!sensor.Value.HasValue)
131 switch (sensor.SensorType)
133 case SensorType.Voltage:
134 return string.Format("{0:F1}", sensor.Value);
135 case SensorType.Clock:
136 return string.Format("{0:F1}", 1e-3f * sensor.Value);
137 case SensorType.Load:
138 return string.Format("{0:F0}", sensor.Value);
139 case SensorType.Temperature:
140 if (unitManager.TemperatureUnit == TemperatureUnit.Fahrenheit)
141 return string.Format("{0:F0}",
142 UnitManager.CelsiusToFahrenheit(sensor.Value));
144 return string.Format("{0:F0}", sensor.Value);
146 return string.Format("{0:F1}", 1e-3f * sensor.Value);
147 case SensorType.Flow:
148 return string.Format("{0:F1}", 1e-3f * sensor.Value);
149 case SensorType.Control:
150 return string.Format("{0:F0}", sensor.Value);
151 case SensorType.Level:
152 return string.Format("{0:F0}", sensor.Value);
153 case SensorType.Power:
154 return string.Format("{0:F0}", sensor.Value);
155 case SensorType.Data:
156 return string.Format("{0:F0}", sensor.Value);
157 case SensorType.Factor:
158 return string.Format("{0:F1}", sensor.Value);
163 private Icon CreateTransparentIcon()
165 string text = GetString();
167 for (int i = 0; i < text.Length; i++)
168 if ((text[i] >= '0' && text[i] <= '9') || text[i] == '-')
170 bool small = count > 2;
172 graphics.Clear(Color.Black);
173 TextRenderer.DrawText(graphics, text, small ? smallFont : font,
174 new Point(-2, small ? 1 : 0), Color.White, Color.Black);
176 BitmapData data = bitmap.LockBits(
177 new Rectangle(0, 0, bitmap.Width, bitmap.Height),
178 ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
180 IntPtr Scan0 = data.Scan0;
182 int numBytes = bitmap.Width * bitmap.Height * 4;
183 byte[] bytes = new byte[numBytes];
184 Marshal.Copy(Scan0, bytes, 0, numBytes);
185 bitmap.UnlockBits(data);
187 byte red, green, blue;
188 for (int i = 0; i < bytes.Length; i += 4)
191 green = bytes[i + 1];
195 bytes[i + 1] = color.G;
196 bytes[i + 2] = color.R;
197 bytes[i + 3] = (byte)(0.3 * red + 0.59 * green + 0.11 * blue);
200 return IconFactory.Create(bytes, bitmap.Width, bitmap.Height,
201 PixelFormat.Format32bppArgb);
204 private Icon CreatePercentageIcon()
208 graphics.Clear(Color.Transparent);
210 catch (ArgumentException)
212 graphics.Clear(Color.Black);
214 graphics.FillRectangle(darkBrush, 0.5f, -0.5f, bitmap.Width - 2, bitmap.Height);
215 float value = sensor.Value.GetValueOrDefault();
216 float y = 0.16f * (100 - value);
217 graphics.FillRectangle(brush, 0.5f, -0.5f + y, bitmap.Width - 2, bitmap.Height - y);
218 graphics.DrawRectangle(pen, 1, 0, bitmap.Width - 3, bitmap.Height - 1);
220 BitmapData data = bitmap.LockBits(
221 new Rectangle(0, 0, bitmap.Width, bitmap.Height),
222 ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
223 byte[] bytes = new byte[bitmap.Width * bitmap.Height * 4];
224 Marshal.Copy(data.Scan0, bytes, 0, bytes.Length);
225 bitmap.UnlockBits(data);
227 return IconFactory.Create(bytes, bitmap.Width, bitmap.Height,
228 PixelFormat.Format32bppArgb);
235 switch (sensor.SensorType)
237 case SensorType.Load:
238 case SensorType.Control:
239 case SensorType.Level:
240 //notifyIcon.Icon = CreatePercentageIcon();
243 //notifyIcon.Icon = CreateTransparentIcon();
249 switch (sensor.SensorType)
251 case SensorType.Voltage: format = "\n{0}: {1:F2} V"; break;
252 case SensorType.Clock: format = "\n{0}: {1:F0} MHz"; break;
253 case SensorType.Load: format = "\n{0}: {1:F1} %"; break;
254 case SensorType.Temperature: format = "\n{0}: {1:F1} °C"; break;
255 case SensorType.Fan: format = "\n{0}: {1:F0} RPM"; break;
256 case SensorType.Flow: format = "\n{0}: {1:F0} L/h"; break;
257 case SensorType.Control: format = "\n{0}: {1:F1} %"; break;
258 case SensorType.Level: format = "\n{0}: {1:F1} %"; break;
259 case SensorType.Power: format = "\n{0}: {1:F0} W"; break;
260 case SensorType.Data: format = "\n{0}: {1:F0} GB"; break;
261 case SensorType.Factor: format = "\n{0}: {1:F3} GB"; break;
263 string formattedValue = string.Format(format, sensor.Name, sensor.Value);
265 if (sensor.SensorType == SensorType.Temperature &&
266 unitManager.TemperatureUnit == TemperatureUnit.Fahrenheit)
268 format = "\n{0}: {1:F1} °F";
269 formattedValue = string.Format(format, sensor.Name,
270 UnitManager.CelsiusToFahrenheit(sensor.Value));
273 string hardwareName = sensor.Hardware.Name;
274 hardwareName = hardwareName.Substring(0,
275 Math.Min(63 - formattedValue.Length, hardwareName.Length));
276 string text = hardwareName + formattedValue;
277 if (text.Length > 63)