moel@202
|
1 |
/*
|
moel@176
|
2 |
|
moel@176
|
3 |
Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
moel@176
|
4 |
|
moel@176
|
5 |
The contents of this file are subject to the Mozilla Public License Version
|
moel@176
|
6 |
1.1 (the "License"); you may not use this file except in compliance with
|
moel@176
|
7 |
the License. You may obtain a copy of the License at
|
moel@176
|
8 |
|
moel@176
|
9 |
http://www.mozilla.org/MPL/
|
moel@176
|
10 |
|
moel@176
|
11 |
Software distributed under the License is distributed on an "AS IS" basis,
|
moel@176
|
12 |
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
moel@176
|
13 |
for the specific language governing rights and limitations under the License.
|
moel@176
|
14 |
|
moel@176
|
15 |
The Original Code is the Open Hardware Monitor code.
|
moel@176
|
16 |
|
moel@176
|
17 |
The Initial Developer of the Original Code is
|
moel@176
|
18 |
Michael Möller <m.moeller@gmx.ch>.
|
moel@300
|
19 |
Portions created by the Initial Developer are Copyright (C) 2010-2011
|
moel@176
|
20 |
the Initial Developer. All Rights Reserved.
|
moel@176
|
21 |
|
moel@176
|
22 |
Contributor(s):
|
moel@176
|
23 |
|
moel@176
|
24 |
Alternatively, the contents of this file may be used under the terms of
|
moel@176
|
25 |
either the GNU General Public License Version 2 or later (the "GPL"), or
|
moel@176
|
26 |
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
moel@176
|
27 |
in which case the provisions of the GPL or the LGPL are applicable instead
|
moel@176
|
28 |
of those above. If you wish to allow use of your version of this file only
|
moel@176
|
29 |
under the terms of either the GPL or the LGPL, and not to allow others to
|
moel@176
|
30 |
use your version of this file under the terms of the MPL, indicate your
|
moel@176
|
31 |
decision by deleting the provisions above and replace them with the notice
|
moel@176
|
32 |
and other provisions required by the GPL or the LGPL. If you do not delete
|
moel@176
|
33 |
the provisions above, a recipient may use your version of this file under
|
moel@176
|
34 |
the terms of any one of the MPL, the GPL or the LGPL.
|
moel@176
|
35 |
|
moel@176
|
36 |
*/
|
moel@176
|
37 |
|
moel@176
|
38 |
using System;
|
moel@176
|
39 |
using System.Collections.Generic;
|
moel@176
|
40 |
using System.Drawing;
|
moel@176
|
41 |
using System.Windows.Forms;
|
moel@176
|
42 |
using OpenHardwareMonitor.Hardware;
|
moel@176
|
43 |
|
moel@176
|
44 |
namespace OpenHardwareMonitor.GUI {
|
moel@176
|
45 |
public class SensorGadget : Gadget {
|
moel@176
|
46 |
|
moel@176
|
47 |
private UnitManager unitManager;
|
moel@176
|
48 |
|
moel@176
|
49 |
private Image back = Utilities.EmbeddedResources.GetImage("gadget.png");
|
moel@176
|
50 |
private Image barBack = Utilities.EmbeddedResources.GetImage("barback.png");
|
moel@176
|
51 |
private Image barblue = Utilities.EmbeddedResources.GetImage("barblue.png");
|
moel@183
|
52 |
private const int topBorder = 6;
|
moel@183
|
53 |
private const int bottomBorder = 7;
|
moel@176
|
54 |
private const int leftBorder = 6;
|
moel@183
|
55 |
private const int rightBorder = 7;
|
moel@183
|
56 |
|
moel@252
|
57 |
private readonly float scale;
|
moel@183
|
58 |
private float fontSize;
|
moel@183
|
59 |
private int iconSize;
|
moel@183
|
60 |
private int hardwareLineHeight;
|
moel@183
|
61 |
private int sensorLineHeight;
|
moel@183
|
62 |
private int rightMargin;
|
moel@183
|
63 |
private int leftMargin;
|
moel@183
|
64 |
private int topMargin;
|
moel@183
|
65 |
private int bottomMargin;
|
moel@183
|
66 |
private int progressWidth;
|
moel@176
|
67 |
|
moel@176
|
68 |
private IDictionary<IHardware, IList<ISensor>> sensors =
|
moel@176
|
69 |
new SortedDictionary<IHardware, IList<ISensor>>(new HardwareComparer());
|
moel@176
|
70 |
|
moel@176
|
71 |
private PersistentSettings settings;
|
moel@181
|
72 |
private UserOption hardwareNames;
|
moel@176
|
73 |
private UserOption alwaysOnTop;
|
moel@183
|
74 |
private UserOption lockPositionAndSize;
|
moel@176
|
75 |
|
moel@176
|
76 |
private Font largeFont;
|
moel@176
|
77 |
private Font smallFont;
|
moel@181
|
78 |
private Brush darkWhite;
|
moel@183
|
79 |
private StringFormat stringFormat;
|
moel@181
|
80 |
private StringFormat trimStringFormat;
|
moel@181
|
81 |
private StringFormat alignRightStringFormat;
|
moel@176
|
82 |
|
moel@176
|
83 |
public SensorGadget(IComputer computer, PersistentSettings settings,
|
moel@176
|
84 |
UnitManager unitManager)
|
moel@176
|
85 |
{
|
moel@176
|
86 |
this.unitManager = unitManager;
|
moel@176
|
87 |
this.settings = settings;
|
moel@176
|
88 |
computer.HardwareAdded += new HardwareEventHandler(HardwareAdded);
|
moel@183
|
89 |
computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved);
|
moel@176
|
90 |
|
moel@181
|
91 |
this.darkWhite = new SolidBrush(Color.FromArgb(0xF0, 0xF0, 0xF0));
|
moel@181
|
92 |
|
moel@183
|
93 |
this.stringFormat = new StringFormat();
|
moel@183
|
94 |
this.stringFormat.FormatFlags = StringFormatFlags.NoWrap;
|
moel@183
|
95 |
|
moel@181
|
96 |
this.trimStringFormat = new StringFormat();
|
moel@181
|
97 |
this.trimStringFormat.Trimming = StringTrimming.EllipsisCharacter;
|
moel@183
|
98 |
this.trimStringFormat.FormatFlags = StringFormatFlags.NoWrap;
|
moel@181
|
99 |
|
moel@181
|
100 |
this.alignRightStringFormat = new StringFormat();
|
moel@181
|
101 |
this.alignRightStringFormat.Alignment = StringAlignment.Far;
|
moel@183
|
102 |
this.alignRightStringFormat.FormatFlags = StringFormatFlags.NoWrap;
|
moel@176
|
103 |
|
moel@176
|
104 |
this.Location = new Point(
|
moel@176
|
105 |
settings.GetValue("sensorGadget.Location.X", 100),
|
moel@176
|
106 |
settings.GetValue("sensorGadget.Location.Y", 100));
|
moel@176
|
107 |
LocationChanged += delegate(object sender, EventArgs e) {
|
moel@176
|
108 |
settings.SetValue("sensorGadget.Location.X", Location.X);
|
moel@176
|
109 |
settings.SetValue("sensorGadget.Location.Y", Location.Y);
|
moel@176
|
110 |
};
|
moel@183
|
111 |
|
moel@252
|
112 |
// get the custom to default dpi ratio
|
moel@252
|
113 |
using (Bitmap b = new Bitmap(1, 1)) {
|
moel@252
|
114 |
scale = b.HorizontalResolution / 96.0f;
|
moel@252
|
115 |
}
|
moel@252
|
116 |
|
moel@183
|
117 |
SetFontSize(settings.GetValue("sensorGadget.FontSize", 7.5f));
|
moel@183
|
118 |
Resize(settings.GetValue("sensorGadget.Width", Size.Width));
|
moel@176
|
119 |
|
moel@176
|
120 |
ContextMenu contextMenu = new ContextMenu();
|
moel@181
|
121 |
MenuItem hardwareNamesItem = new MenuItem("Hardware Names");
|
moel@181
|
122 |
contextMenu.MenuItems.Add(hardwareNamesItem);
|
moel@183
|
123 |
MenuItem fontSizeMenu = new MenuItem("Font Size");
|
moel@183
|
124 |
for (int i = 0; i < 4; i++) {
|
moel@183
|
125 |
float size;
|
moel@183
|
126 |
string name;
|
moel@183
|
127 |
switch (i) {
|
moel@183
|
128 |
case 0: size = 6.5f; name = "Small"; break;
|
moel@183
|
129 |
case 1: size = 7.5f; name = "Medium"; break;
|
moel@183
|
130 |
case 2: size = 9f; name = "Large"; break;
|
moel@183
|
131 |
case 3: size = 11f; name = "Very Large"; break;
|
moel@183
|
132 |
default: throw new NotImplementedException();
|
moel@183
|
133 |
}
|
moel@183
|
134 |
MenuItem item = new MenuItem(name);
|
moel@183
|
135 |
item.Checked = fontSize == size;
|
moel@183
|
136 |
item.Click += delegate(object sender, EventArgs e) {
|
moel@183
|
137 |
SetFontSize(size);
|
moel@183
|
138 |
settings.SetValue("sensorGadget.FontSize", size);
|
moel@183
|
139 |
foreach (MenuItem mi in fontSizeMenu.MenuItems)
|
moel@183
|
140 |
mi.Checked = mi == item;
|
moel@183
|
141 |
};
|
moel@183
|
142 |
fontSizeMenu.MenuItems.Add(item);
|
moel@183
|
143 |
}
|
moel@183
|
144 |
contextMenu.MenuItems.Add(fontSizeMenu);
|
moel@181
|
145 |
contextMenu.MenuItems.Add(new MenuItem("-"));
|
moel@183
|
146 |
MenuItem lockItem = new MenuItem("Lock Position and Size");
|
moel@176
|
147 |
contextMenu.MenuItems.Add(lockItem);
|
moel@176
|
148 |
contextMenu.MenuItems.Add(new MenuItem("-"));
|
moel@176
|
149 |
MenuItem alwaysOnTopItem = new MenuItem("Always on Top");
|
moel@176
|
150 |
contextMenu.MenuItems.Add(alwaysOnTopItem);
|
moel@176
|
151 |
MenuItem opacityMenu = new MenuItem("Opacity");
|
moel@176
|
152 |
contextMenu.MenuItems.Add(opacityMenu);
|
moel@176
|
153 |
Opacity = (byte)settings.GetValue("sensorGadget.Opacity", 255);
|
moel@176
|
154 |
for (int i = 0; i < 5; i++) {
|
moel@176
|
155 |
MenuItem item = new MenuItem((20 * (i + 1)).ToString() + " %");
|
moel@176
|
156 |
byte o = (byte)(51 * (i + 1));
|
moel@176
|
157 |
item.Checked = Opacity == o;
|
moel@176
|
158 |
item.Click += delegate(object sender, EventArgs e) {
|
moel@178
|
159 |
Opacity = o;
|
moel@176
|
160 |
settings.SetValue("sensorGadget.Opacity", Opacity);
|
moel@176
|
161 |
foreach (MenuItem mi in opacityMenu.MenuItems)
|
moel@178
|
162 |
mi.Checked = mi == item;
|
moel@176
|
163 |
};
|
moel@176
|
164 |
opacityMenu.MenuItems.Add(item);
|
moel@176
|
165 |
}
|
moel@176
|
166 |
this.ContextMenu = contextMenu;
|
moel@176
|
167 |
|
moel@181
|
168 |
hardwareNames = new UserOption("sensorGadget.Hardwarenames", true,
|
moel@181
|
169 |
hardwareNamesItem, settings);
|
moel@181
|
170 |
hardwareNames.Changed += delegate(object sender, EventArgs e) {
|
moel@181
|
171 |
Resize();
|
moel@181
|
172 |
};
|
moel@181
|
173 |
|
moel@176
|
174 |
alwaysOnTop = new UserOption("sensorGadget.AlwaysOnTop", false,
|
moel@176
|
175 |
alwaysOnTopItem, settings);
|
moel@176
|
176 |
alwaysOnTop.Changed += delegate(object sender, EventArgs e) {
|
moel@176
|
177 |
this.AlwaysOnTop = alwaysOnTop.Value;
|
moel@176
|
178 |
};
|
moel@183
|
179 |
lockPositionAndSize = new UserOption("sensorGadget.LockPositionAndSize",
|
moel@183
|
180 |
false, lockItem, settings);
|
moel@183
|
181 |
lockPositionAndSize.Changed += delegate(object sender, EventArgs e) {
|
moel@183
|
182 |
this.LockPositionAndSize = lockPositionAndSize.Value;
|
moel@176
|
183 |
};
|
moel@176
|
184 |
|
moel@183
|
185 |
HitTest += delegate(object sender, HitTestEventArgs e) {
|
moel@183
|
186 |
if (lockPositionAndSize.Value)
|
moel@183
|
187 |
return;
|
moel@183
|
188 |
|
moel@183
|
189 |
if (e.Location.X < leftBorder) {
|
moel@183
|
190 |
e.HitResult = HitResult.Left;
|
moel@183
|
191 |
return;
|
moel@183
|
192 |
}
|
moel@183
|
193 |
if (e.Location.X > Size.Width - 1 - rightBorder) {
|
moel@183
|
194 |
e.HitResult = HitResult.Right;
|
moel@183
|
195 |
return;
|
moel@183
|
196 |
}
|
moel@183
|
197 |
};
|
moel@183
|
198 |
|
moel@183
|
199 |
SizeChanged += delegate(object sender, EventArgs e) {
|
moel@183
|
200 |
settings.SetValue("sensorGadget.Width", Size.Width);
|
moel@183
|
201 |
Redraw();
|
moel@183
|
202 |
};
|
moel@244
|
203 |
|
moel@289
|
204 |
VisibleChanged += delegate(object sender, EventArgs e) {
|
moel@289
|
205 |
Rectangle bounds = new Rectangle(Location, Size);
|
moel@289
|
206 |
Screen screen = Screen.FromRectangle(bounds);
|
moel@289
|
207 |
Rectangle intersection =
|
moel@289
|
208 |
Rectangle.Intersect(screen.WorkingArea, bounds);
|
moel@289
|
209 |
if (intersection.Width < Math.Min(16, bounds.Width) ||
|
moel@289
|
210 |
intersection.Height < Math.Min(16, bounds.Height))
|
moel@289
|
211 |
{
|
moel@289
|
212 |
Location = new Point(
|
moel@289
|
213 |
screen.WorkingArea.Width / 2 - bounds.Width / 2,
|
moel@289
|
214 |
screen.WorkingArea.Height / 2 - bounds.Height / 2);
|
moel@289
|
215 |
}
|
moel@289
|
216 |
};
|
moel@289
|
217 |
|
moel@244
|
218 |
MouseDoubleClick += delegate(object obj, MouseEventArgs args) {
|
moel@244
|
219 |
SendHideShowCommand();
|
moel@244
|
220 |
};
|
moel@176
|
221 |
}
|
moel@176
|
222 |
|
moel@181
|
223 |
public override void Dispose() {
|
moel@181
|
224 |
|
moel@181
|
225 |
largeFont.Dispose();
|
moel@181
|
226 |
largeFont = null;
|
moel@181
|
227 |
|
moel@181
|
228 |
smallFont.Dispose();
|
moel@181
|
229 |
smallFont = null;
|
moel@181
|
230 |
|
moel@181
|
231 |
darkWhite.Dispose();
|
moel@181
|
232 |
darkWhite = null;
|
moel@181
|
233 |
|
moel@183
|
234 |
stringFormat.Dispose();
|
moel@183
|
235 |
stringFormat = null;
|
moel@183
|
236 |
|
moel@181
|
237 |
trimStringFormat.Dispose();
|
moel@181
|
238 |
trimStringFormat = null;
|
moel@181
|
239 |
|
moel@181
|
240 |
alignRightStringFormat.Dispose();
|
moel@181
|
241 |
alignRightStringFormat = null;
|
moel@181
|
242 |
|
moel@181
|
243 |
base.Dispose();
|
moel@181
|
244 |
}
|
moel@181
|
245 |
|
moel@176
|
246 |
private void HardwareRemoved(IHardware hardware) {
|
moel@176
|
247 |
hardware.SensorAdded -= new SensorEventHandler(SensorAdded);
|
moel@176
|
248 |
hardware.SensorRemoved -= new SensorEventHandler(SensorRemoved);
|
moel@176
|
249 |
foreach (ISensor sensor in hardware.Sensors)
|
moel@176
|
250 |
SensorRemoved(sensor);
|
moel@176
|
251 |
foreach (IHardware subHardware in hardware.SubHardware)
|
moel@176
|
252 |
HardwareRemoved(subHardware);
|
moel@176
|
253 |
}
|
moel@176
|
254 |
|
moel@176
|
255 |
private void HardwareAdded(IHardware hardware) {
|
moel@176
|
256 |
foreach (ISensor sensor in hardware.Sensors)
|
moel@176
|
257 |
SensorAdded(sensor);
|
moel@176
|
258 |
hardware.SensorAdded += new SensorEventHandler(SensorAdded);
|
moel@176
|
259 |
hardware.SensorRemoved += new SensorEventHandler(SensorRemoved);
|
moel@176
|
260 |
foreach (IHardware subHardware in hardware.SubHardware)
|
moel@176
|
261 |
HardwareAdded(subHardware);
|
moel@176
|
262 |
}
|
moel@176
|
263 |
|
moel@176
|
264 |
private void SensorAdded(ISensor sensor) {
|
moel@176
|
265 |
if (settings.GetValue(new Identifier(sensor.Identifier,
|
moel@176
|
266 |
"gadget").ToString(), false))
|
moel@176
|
267 |
Add(sensor);
|
moel@176
|
268 |
}
|
moel@176
|
269 |
|
moel@176
|
270 |
private void SensorRemoved(ISensor sensor) {
|
moel@176
|
271 |
if (Contains(sensor))
|
moel@176
|
272 |
Remove(sensor, false);
|
moel@176
|
273 |
}
|
moel@176
|
274 |
|
moel@176
|
275 |
public bool Contains(ISensor sensor) {
|
moel@176
|
276 |
foreach (IList<ISensor> list in sensors.Values)
|
moel@176
|
277 |
if (list.Contains(sensor))
|
moel@176
|
278 |
return true;
|
moel@176
|
279 |
return false;
|
moel@176
|
280 |
}
|
moel@176
|
281 |
|
moel@176
|
282 |
public void Add(ISensor sensor) {
|
moel@176
|
283 |
if (Contains(sensor)) {
|
moel@176
|
284 |
return;
|
moel@176
|
285 |
} else {
|
moel@176
|
286 |
// get the right hardware
|
moel@176
|
287 |
IHardware hardware = sensor.Hardware;
|
moel@176
|
288 |
while (hardware.Parent != null)
|
moel@176
|
289 |
hardware = hardware.Parent;
|
moel@176
|
290 |
|
moel@176
|
291 |
// get the sensor list associated with the hardware
|
moel@176
|
292 |
IList<ISensor> list;
|
moel@176
|
293 |
if (!sensors.TryGetValue(hardware, out list)) {
|
moel@176
|
294 |
list = new List<ISensor>();
|
moel@176
|
295 |
sensors.Add(hardware, list);
|
moel@176
|
296 |
}
|
moel@176
|
297 |
|
moel@176
|
298 |
// insert the sensor at the right position
|
moel@176
|
299 |
int i = 0;
|
moel@176
|
300 |
while (i < list.Count && (list[i].SensorType < sensor.SensorType ||
|
moel@176
|
301 |
(list[i].SensorType == sensor.SensorType &&
|
moel@176
|
302 |
list[i].Index < sensor.Index))) i++;
|
moel@176
|
303 |
list.Insert(i, sensor);
|
moel@176
|
304 |
|
moel@176
|
305 |
settings.SetValue(
|
moel@176
|
306 |
new Identifier(sensor.Identifier, "gadget").ToString(), true);
|
moel@176
|
307 |
|
moel@176
|
308 |
Resize();
|
moel@176
|
309 |
}
|
moel@176
|
310 |
}
|
moel@176
|
311 |
|
moel@176
|
312 |
public void Remove(ISensor sensor) {
|
moel@176
|
313 |
Remove(sensor, true);
|
moel@176
|
314 |
}
|
moel@176
|
315 |
|
moel@176
|
316 |
private void Remove(ISensor sensor, bool deleteConfig) {
|
moel@176
|
317 |
if (deleteConfig)
|
moel@176
|
318 |
settings.Remove(new Identifier(sensor.Identifier, "gadget").ToString());
|
moel@176
|
319 |
|
moel@176
|
320 |
foreach (KeyValuePair<IHardware, IList<ISensor>> keyValue in sensors)
|
moel@176
|
321 |
if (keyValue.Value.Contains(sensor)) {
|
moel@176
|
322 |
keyValue.Value.Remove(sensor);
|
moel@176
|
323 |
if (keyValue.Value.Count == 0) {
|
moel@176
|
324 |
sensors.Remove(keyValue.Key);
|
moel@176
|
325 |
break;
|
moel@176
|
326 |
}
|
moel@176
|
327 |
}
|
moel@176
|
328 |
Resize();
|
moel@183
|
329 |
}
|
moel@183
|
330 |
|
moel@244
|
331 |
public event EventHandler HideShowCommand;
|
moel@244
|
332 |
|
moel@244
|
333 |
public void SendHideShowCommand() {
|
moel@244
|
334 |
if (HideShowCommand != null)
|
moel@244
|
335 |
HideShowCommand(this, null);
|
moel@244
|
336 |
}
|
moel@244
|
337 |
|
moel@183
|
338 |
private Font CreateFont(float size, FontStyle style) {
|
moel@215
|
339 |
try {
|
moel@215
|
340 |
return new Font(SystemFonts.MessageBoxFont.FontFamily, size, style);
|
moel@215
|
341 |
} catch (ArgumentException) {
|
moel@215
|
342 |
// if the style is not supported, fall back to the original one
|
moel@215
|
343 |
return new Font(SystemFonts.MessageBoxFont.FontFamily, size,
|
moel@215
|
344 |
SystemFonts.MessageBoxFont.Style);
|
moel@215
|
345 |
}
|
moel@183
|
346 |
}
|
moel@183
|
347 |
|
moel@183
|
348 |
private void SetFontSize(float size) {
|
moel@183
|
349 |
fontSize = size;
|
moel@183
|
350 |
largeFont = CreateFont(fontSize, FontStyle.Bold);
|
moel@183
|
351 |
smallFont = CreateFont(fontSize, FontStyle.Regular);
|
moel@252
|
352 |
|
moel@252
|
353 |
double scaledFontSize = fontSize * scale;
|
moel@252
|
354 |
iconSize = (int)Math.Round(1.5 * scaledFontSize);
|
moel@252
|
355 |
hardwareLineHeight = (int)Math.Round(1.66 * scaledFontSize);
|
moel@252
|
356 |
sensorLineHeight = (int)Math.Round(1.33 * scaledFontSize);
|
moel@252
|
357 |
leftMargin = leftBorder + (int)Math.Round(0.3 * scaledFontSize);
|
moel@252
|
358 |
rightMargin = rightBorder + (int)Math.Round(0.3 * scaledFontSize);
|
moel@183
|
359 |
topMargin = topBorder;
|
moel@252
|
360 |
bottomMargin = bottomBorder + (int)Math.Round(0.3 * scaledFontSize);
|
moel@252
|
361 |
progressWidth = (int)Math.Round(5.3 * scaledFontSize);
|
moel@252
|
362 |
|
moel@252
|
363 |
Resize((int)Math.Round(17.3 * scaledFontSize));
|
moel@176
|
364 |
}
|
moel@176
|
365 |
|
moel@176
|
366 |
private void Resize() {
|
moel@183
|
367 |
Resize(this.Size.Width);
|
moel@183
|
368 |
}
|
moel@183
|
369 |
|
moel@183
|
370 |
private void Resize(int width) {
|
moel@183
|
371 |
int y = topMargin;
|
moel@176
|
372 |
foreach (KeyValuePair<IHardware, IList<ISensor>> pair in sensors) {
|
moel@181
|
373 |
if (hardwareNames.Value) {
|
moel@183
|
374 |
if (y > topMargin)
|
moel@183
|
375 |
y += hardwareLineHeight - sensorLineHeight;
|
moel@181
|
376 |
y += hardwareLineHeight;
|
moel@181
|
377 |
}
|
moel@176
|
378 |
y += pair.Value.Count * sensorLineHeight;
|
moel@263
|
379 |
}
|
moel@263
|
380 |
if (sensors.Count == 0)
|
moel@263
|
381 |
y += 4 * sensorLineHeight + hardwareLineHeight;
|
moel@183
|
382 |
y += bottomMargin;
|
moel@183
|
383 |
this.Size = new Size(width, y);
|
moel@176
|
384 |
}
|
moel@176
|
385 |
|
moel@176
|
386 |
private void DrawBackground(Graphics g) {
|
moel@176
|
387 |
int w = Size.Width;
|
moel@176
|
388 |
int h = Size.Height;
|
moel@176
|
389 |
int t = topBorder;
|
moel@176
|
390 |
int b = bottomBorder;
|
moel@176
|
391 |
int l = leftBorder;
|
moel@176
|
392 |
int r = rightBorder;
|
moel@176
|
393 |
GraphicsUnit u = GraphicsUnit.Pixel;
|
moel@176
|
394 |
|
moel@176
|
395 |
g.DrawImage(back, new Rectangle(0, 0, l, t),
|
moel@176
|
396 |
new Rectangle(0, 0, l, t), u);
|
moel@176
|
397 |
g.DrawImage(back, new Rectangle(l, 0, w - l - r, t),
|
moel@176
|
398 |
new Rectangle(l, 0, back.Width - l - r, t), u);
|
moel@176
|
399 |
g.DrawImage(back, new Rectangle(w - r, 0, r, t),
|
moel@176
|
400 |
new Rectangle(back.Width - r, 0, r, t), u);
|
moel@176
|
401 |
|
moel@176
|
402 |
g.DrawImage(back, new Rectangle(0, t, l, h - t - b),
|
moel@176
|
403 |
new Rectangle(0, t, l, back.Height - t - b), u);
|
moel@176
|
404 |
g.DrawImage(back, new Rectangle(l, t, w - l - r, h - t - b),
|
moel@176
|
405 |
new Rectangle(l, t, back.Width - l - r, back.Height - t - b), u);
|
moel@176
|
406 |
g.DrawImage(back, new Rectangle(w - r, t, r, h - t - b),
|
moel@176
|
407 |
new Rectangle(back.Width - r, t, r, back.Height - t - b), u);
|
moel@176
|
408 |
|
moel@176
|
409 |
g.DrawImage(back, new Rectangle(0, h - b, l, b),
|
moel@176
|
410 |
new Rectangle(0, back.Height - b, l, b), u);
|
moel@176
|
411 |
g.DrawImage(back, new Rectangle(l, h - b, w - l - r, b),
|
moel@176
|
412 |
new Rectangle(l, back.Height - b, back.Width - l - r, b), u);
|
moel@176
|
413 |
g.DrawImage(back, new Rectangle(w - r, h - b, r, b),
|
moel@176
|
414 |
new Rectangle(back.Width - r, back.Height - b, r, b), u);
|
moel@176
|
415 |
}
|
moel@176
|
416 |
|
moel@243
|
417 |
private void DrawProgress(Graphics g, float x, float y,
|
moel@243
|
418 |
float width, float height, float progress)
|
moel@176
|
419 |
{
|
moel@176
|
420 |
g.DrawImage(barBack,
|
moel@176
|
421 |
new RectangleF(x + width * progress, y, width * (1 - progress), height),
|
moel@176
|
422 |
new RectangleF(barBack.Width * progress, 0,
|
moel@176
|
423 |
(1 - progress) * barBack.Width, barBack.Height),
|
moel@176
|
424 |
GraphicsUnit.Pixel);
|
moel@176
|
425 |
g.DrawImage(barblue,
|
moel@176
|
426 |
new RectangleF(x, y, width * progress, height),
|
moel@176
|
427 |
new RectangleF(0, 0, progress * barblue.Width, barblue.Height),
|
moel@176
|
428 |
GraphicsUnit.Pixel);
|
moel@176
|
429 |
}
|
moel@176
|
430 |
|
moel@176
|
431 |
protected override void OnPaint(PaintEventArgs e) {
|
moel@176
|
432 |
Graphics g = e.Graphics;
|
moel@176
|
433 |
int w = Size.Width;
|
moel@176
|
434 |
|
moel@176
|
435 |
g.Clear(Color.Transparent);
|
moel@183
|
436 |
|
moel@176
|
437 |
DrawBackground(g);
|
moel@176
|
438 |
|
moel@176
|
439 |
int x;
|
moel@183
|
440 |
int y = topMargin;
|
moel@186
|
441 |
|
moel@186
|
442 |
if (sensors.Count == 0) {
|
moel@186
|
443 |
x = leftBorder + 1;
|
moel@263
|
444 |
g.DrawString("Right-click on a sensor in the main window and select " +
|
moel@263
|
445 |
"\"Show in Gadget\" to show the sensor here.",
|
moel@263
|
446 |
smallFont, Brushes.White,
|
moel@186
|
447 |
new Rectangle(x, y - 1, w - rightBorder - x, 0));
|
moel@186
|
448 |
}
|
moel@186
|
449 |
|
moel@176
|
450 |
foreach (KeyValuePair<IHardware, IList<ISensor>> pair in sensors) {
|
moel@181
|
451 |
if (hardwareNames.Value) {
|
moel@183
|
452 |
if (y > topMargin)
|
moel@183
|
453 |
y += hardwareLineHeight - sensorLineHeight;
|
moel@181
|
454 |
x = leftBorder + 1;
|
moel@181
|
455 |
g.DrawImage(HardwareTypeImage.Instance.GetImage(pair.Key.HardwareType),
|
moel@181
|
456 |
new Rectangle(x, y + 1, iconSize, iconSize));
|
moel@181
|
457 |
x += iconSize + 1;
|
moel@181
|
458 |
g.DrawString(pair.Key.Name, largeFont, Brushes.White,
|
moel@183
|
459 |
new Rectangle(x, y - 1, w - rightBorder - x, 0),
|
moel@183
|
460 |
stringFormat);
|
moel@181
|
461 |
y += hardwareLineHeight;
|
moel@181
|
462 |
}
|
moel@176
|
463 |
|
moel@176
|
464 |
foreach (ISensor sensor in pair.Value) {
|
moel@183
|
465 |
int remainingWidth;
|
moel@176
|
466 |
|
moel@187
|
467 |
|
moel@187
|
468 |
if ((sensor.SensorType != SensorType.Load &&
|
moel@217
|
469 |
sensor.SensorType != SensorType.Control &&
|
moel@217
|
470 |
sensor.SensorType != SensorType.Level) || !sensor.Value.HasValue)
|
moel@176
|
471 |
{
|
moel@187
|
472 |
string formatted;
|
moel@187
|
473 |
|
moel@187
|
474 |
if (sensor.Value.HasValue) {
|
moel@187
|
475 |
string format = "";
|
moel@187
|
476 |
switch (sensor.SensorType) {
|
moel@187
|
477 |
case SensorType.Voltage:
|
moel@300
|
478 |
format = "{0:F3} V";
|
moel@187
|
479 |
break;
|
moel@187
|
480 |
case SensorType.Clock:
|
moel@187
|
481 |
format = "{0:F0} MHz";
|
moel@187
|
482 |
break;
|
moel@187
|
483 |
case SensorType.Temperature:
|
moel@187
|
484 |
format = "{0:F1} °C";
|
moel@187
|
485 |
break;
|
moel@187
|
486 |
case SensorType.Fan:
|
moel@187
|
487 |
format = "{0:F0} RPM";
|
moel@187
|
488 |
break;
|
moel@187
|
489 |
case SensorType.Flow:
|
moel@187
|
490 |
format = "{0:F0} L/h";
|
moel@187
|
491 |
break;
|
moel@187
|
492 |
}
|
moel@187
|
493 |
|
moel@187
|
494 |
if (sensor.SensorType == SensorType.Temperature &&
|
moel@187
|
495 |
unitManager.TemperatureUnit == TemperatureUnit.Fahrenheit) {
|
moel@187
|
496 |
formatted = string.Format("{0:F1} °F",
|
moel@187
|
497 |
sensor.Value * 1.8 + 32);
|
moel@187
|
498 |
} else {
|
moel@187
|
499 |
formatted = string.Format(format, sensor.Value);
|
moel@187
|
500 |
}
|
moel@187
|
501 |
} else {
|
moel@187
|
502 |
formatted = "-";
|
moel@176
|
503 |
}
|
moel@176
|
504 |
|
moel@187
|
505 |
g.DrawString(formatted, smallFont, darkWhite,
|
moel@187
|
506 |
new RectangleF(-1, y - 1, w - rightMargin + 3, 0),
|
moel@181
|
507 |
alignRightStringFormat);
|
moel@181
|
508 |
|
moel@187
|
509 |
remainingWidth = w - (int)Math.Floor(g.MeasureString(formatted,
|
moel@187
|
510 |
smallFont, w, StringFormat.GenericTypographic).Width) -
|
moel@181
|
511 |
rightMargin;
|
moel@187
|
512 |
} else {
|
moel@187
|
513 |
DrawProgress(g, w - progressWidth - rightMargin,
|
moel@243
|
514 |
y + 0.35f * sensorLineHeight, progressWidth,
|
moel@243
|
515 |
0.6f * sensorLineHeight, 0.01f * sensor.Value.Value);
|
moel@183
|
516 |
|
moel@183
|
517 |
remainingWidth = w - progressWidth - rightMargin;
|
moel@176
|
518 |
}
|
moel@187
|
519 |
|
moel@183
|
520 |
remainingWidth -= leftMargin + 2;
|
moel@183
|
521 |
if (remainingWidth > 0) {
|
moel@183
|
522 |
g.DrawString(sensor.Name, smallFont, darkWhite,
|
moel@183
|
523 |
new RectangleF(leftMargin - 1, y - 1, remainingWidth, 0),
|
moel@183
|
524 |
trimStringFormat);
|
moel@183
|
525 |
}
|
moel@181
|
526 |
|
moel@176
|
527 |
y += sensorLineHeight;
|
moel@176
|
528 |
}
|
moel@176
|
529 |
}
|
moel@176
|
530 |
}
|
moel@176
|
531 |
|
moel@176
|
532 |
private class HardwareComparer : IComparer<IHardware> {
|
moel@176
|
533 |
public int Compare(IHardware x, IHardware y) {
|
moel@176
|
534 |
if (x == null && y == null)
|
moel@176
|
535 |
return 0;
|
moel@176
|
536 |
if (x == null)
|
moel@176
|
537 |
return -1;
|
moel@176
|
538 |
if (y == null)
|
moel@176
|
539 |
return 1;
|
moel@176
|
540 |
|
moel@176
|
541 |
if (x.HardwareType != y.HardwareType)
|
moel@176
|
542 |
return x.HardwareType.CompareTo(y.HardwareType);
|
moel@176
|
543 |
|
moel@184
|
544 |
return x.Identifier.CompareTo(y.Identifier);
|
moel@176
|
545 |
}
|
moel@176
|
546 |
}
|
moel@176
|
547 |
}
|
moel@176
|
548 |
}
|
moel@176
|
549 |
|