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@340
|
19 |
Portions created by the Initial Developer are Copyright (C) 2010-2012
|
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@316
|
41 |
using System.Drawing.Imaging;
|
moel@176
|
42 |
using System.Windows.Forms;
|
moel@342
|
43 |
using System.IO;
|
moel@176
|
44 |
using OpenHardwareMonitor.Hardware;
|
moel@176
|
45 |
|
moel@176
|
46 |
namespace OpenHardwareMonitor.GUI {
|
moel@176
|
47 |
public class SensorGadget : Gadget {
|
moel@176
|
48 |
|
moel@176
|
49 |
private UnitManager unitManager;
|
moel@176
|
50 |
|
moel@176
|
51 |
private Image back = Utilities.EmbeddedResources.GetImage("gadget.png");
|
moel@342
|
52 |
private Image image = null;
|
moel@342
|
53 |
private Image fore = null;
|
moel@176
|
54 |
private Image barBack = Utilities.EmbeddedResources.GetImage("barback.png");
|
moel@342
|
55 |
private Image barFore = Utilities.EmbeddedResources.GetImage("barblue.png");
|
moel@183
|
56 |
private const int topBorder = 6;
|
moel@183
|
57 |
private const int bottomBorder = 7;
|
moel@176
|
58 |
private const int leftBorder = 6;
|
moel@183
|
59 |
private const int rightBorder = 7;
|
moel@316
|
60 |
private Image background = new Bitmap(1, 1);
|
moel@183
|
61 |
|
moel@252
|
62 |
private readonly float scale;
|
moel@183
|
63 |
private float fontSize;
|
moel@183
|
64 |
private int iconSize;
|
moel@183
|
65 |
private int hardwareLineHeight;
|
moel@183
|
66 |
private int sensorLineHeight;
|
moel@183
|
67 |
private int rightMargin;
|
moel@183
|
68 |
private int leftMargin;
|
moel@183
|
69 |
private int topMargin;
|
moel@183
|
70 |
private int bottomMargin;
|
moel@183
|
71 |
private int progressWidth;
|
moel@176
|
72 |
|
moel@176
|
73 |
private IDictionary<IHardware, IList<ISensor>> sensors =
|
moel@176
|
74 |
new SortedDictionary<IHardware, IList<ISensor>>(new HardwareComparer());
|
moel@176
|
75 |
|
moel@176
|
76 |
private PersistentSettings settings;
|
moel@181
|
77 |
private UserOption hardwareNames;
|
moel@176
|
78 |
private UserOption alwaysOnTop;
|
moel@183
|
79 |
private UserOption lockPositionAndSize;
|
moel@176
|
80 |
|
moel@176
|
81 |
private Font largeFont;
|
moel@176
|
82 |
private Font smallFont;
|
moel@181
|
83 |
private Brush darkWhite;
|
moel@183
|
84 |
private StringFormat stringFormat;
|
moel@181
|
85 |
private StringFormat trimStringFormat;
|
moel@181
|
86 |
private StringFormat alignRightStringFormat;
|
moel@176
|
87 |
|
moel@176
|
88 |
public SensorGadget(IComputer computer, PersistentSettings settings,
|
moel@176
|
89 |
UnitManager unitManager)
|
moel@176
|
90 |
{
|
moel@176
|
91 |
this.unitManager = unitManager;
|
moel@176
|
92 |
this.settings = settings;
|
moel@176
|
93 |
computer.HardwareAdded += new HardwareEventHandler(HardwareAdded);
|
moel@183
|
94 |
computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved);
|
moel@176
|
95 |
|
moel@181
|
96 |
this.darkWhite = new SolidBrush(Color.FromArgb(0xF0, 0xF0, 0xF0));
|
moel@181
|
97 |
|
moel@183
|
98 |
this.stringFormat = new StringFormat();
|
moel@183
|
99 |
this.stringFormat.FormatFlags = StringFormatFlags.NoWrap;
|
moel@183
|
100 |
|
moel@181
|
101 |
this.trimStringFormat = new StringFormat();
|
moel@181
|
102 |
this.trimStringFormat.Trimming = StringTrimming.EllipsisCharacter;
|
moel@183
|
103 |
this.trimStringFormat.FormatFlags = StringFormatFlags.NoWrap;
|
moel@181
|
104 |
|
moel@181
|
105 |
this.alignRightStringFormat = new StringFormat();
|
moel@181
|
106 |
this.alignRightStringFormat.Alignment = StringAlignment.Far;
|
moel@183
|
107 |
this.alignRightStringFormat.FormatFlags = StringFormatFlags.NoWrap;
|
moel@176
|
108 |
|
moel@342
|
109 |
if (File.Exists("gadget_background.png")) {
|
moel@342
|
110 |
try {
|
moel@342
|
111 |
Image newBack = new Bitmap("gadget_background.png");
|
moel@342
|
112 |
back.Dispose();
|
moel@342
|
113 |
back = newBack;
|
moel@342
|
114 |
} catch { }
|
moel@342
|
115 |
}
|
moel@342
|
116 |
|
moel@342
|
117 |
if (File.Exists("gadget_image.png")) {
|
moel@342
|
118 |
try {
|
moel@342
|
119 |
image = new Bitmap("gadget_image.png");
|
moel@342
|
120 |
} catch {}
|
moel@342
|
121 |
}
|
moel@342
|
122 |
|
moel@342
|
123 |
if (File.Exists("gadget_foreground.png")) {
|
moel@342
|
124 |
try {
|
moel@342
|
125 |
fore = new Bitmap("gadget_foreground.png");
|
moel@342
|
126 |
} catch { }
|
moel@342
|
127 |
}
|
moel@342
|
128 |
|
moel@342
|
129 |
if (File.Exists("gadget_bar_background.png")) {
|
moel@342
|
130 |
try {
|
moel@342
|
131 |
Image newBarBack = new Bitmap("gadget_bar_background.png");
|
moel@342
|
132 |
barBack.Dispose();
|
moel@342
|
133 |
barBack = newBarBack;
|
moel@342
|
134 |
} catch { }
|
moel@342
|
135 |
}
|
moel@342
|
136 |
|
moel@342
|
137 |
if (File.Exists("gadget_bar_foreground.png")) {
|
moel@342
|
138 |
try {
|
moel@342
|
139 |
Image newBarColor = new Bitmap("gadget_bar_foreground.png");
|
moel@342
|
140 |
barFore.Dispose();
|
moel@342
|
141 |
barFore = newBarColor;
|
moel@342
|
142 |
} catch { }
|
moel@342
|
143 |
}
|
moel@342
|
144 |
|
moel@176
|
145 |
this.Location = new Point(
|
moel@176
|
146 |
settings.GetValue("sensorGadget.Location.X", 100),
|
moel@176
|
147 |
settings.GetValue("sensorGadget.Location.Y", 100));
|
moel@176
|
148 |
LocationChanged += delegate(object sender, EventArgs e) {
|
moel@176
|
149 |
settings.SetValue("sensorGadget.Location.X", Location.X);
|
moel@176
|
150 |
settings.SetValue("sensorGadget.Location.Y", Location.Y);
|
moel@176
|
151 |
};
|
moel@183
|
152 |
|
moel@252
|
153 |
// get the custom to default dpi ratio
|
moel@252
|
154 |
using (Bitmap b = new Bitmap(1, 1)) {
|
moel@252
|
155 |
scale = b.HorizontalResolution / 96.0f;
|
moel@252
|
156 |
}
|
moel@252
|
157 |
|
moel@183
|
158 |
SetFontSize(settings.GetValue("sensorGadget.FontSize", 7.5f));
|
moel@183
|
159 |
Resize(settings.GetValue("sensorGadget.Width", Size.Width));
|
moel@176
|
160 |
|
moel@176
|
161 |
ContextMenu contextMenu = new ContextMenu();
|
moel@181
|
162 |
MenuItem hardwareNamesItem = new MenuItem("Hardware Names");
|
moel@181
|
163 |
contextMenu.MenuItems.Add(hardwareNamesItem);
|
moel@183
|
164 |
MenuItem fontSizeMenu = new MenuItem("Font Size");
|
moel@183
|
165 |
for (int i = 0; i < 4; i++) {
|
moel@183
|
166 |
float size;
|
moel@183
|
167 |
string name;
|
moel@183
|
168 |
switch (i) {
|
moel@183
|
169 |
case 0: size = 6.5f; name = "Small"; break;
|
moel@183
|
170 |
case 1: size = 7.5f; name = "Medium"; break;
|
moel@183
|
171 |
case 2: size = 9f; name = "Large"; break;
|
moel@183
|
172 |
case 3: size = 11f; name = "Very Large"; break;
|
moel@183
|
173 |
default: throw new NotImplementedException();
|
moel@183
|
174 |
}
|
moel@183
|
175 |
MenuItem item = new MenuItem(name);
|
moel@183
|
176 |
item.Checked = fontSize == size;
|
moel@183
|
177 |
item.Click += delegate(object sender, EventArgs e) {
|
moel@183
|
178 |
SetFontSize(size);
|
moel@183
|
179 |
settings.SetValue("sensorGadget.FontSize", size);
|
moel@183
|
180 |
foreach (MenuItem mi in fontSizeMenu.MenuItems)
|
moel@183
|
181 |
mi.Checked = mi == item;
|
moel@183
|
182 |
};
|
moel@183
|
183 |
fontSizeMenu.MenuItems.Add(item);
|
moel@183
|
184 |
}
|
moel@183
|
185 |
contextMenu.MenuItems.Add(fontSizeMenu);
|
moel@181
|
186 |
contextMenu.MenuItems.Add(new MenuItem("-"));
|
moel@183
|
187 |
MenuItem lockItem = new MenuItem("Lock Position and Size");
|
moel@176
|
188 |
contextMenu.MenuItems.Add(lockItem);
|
moel@176
|
189 |
contextMenu.MenuItems.Add(new MenuItem("-"));
|
moel@176
|
190 |
MenuItem alwaysOnTopItem = new MenuItem("Always on Top");
|
moel@176
|
191 |
contextMenu.MenuItems.Add(alwaysOnTopItem);
|
moel@176
|
192 |
MenuItem opacityMenu = new MenuItem("Opacity");
|
moel@176
|
193 |
contextMenu.MenuItems.Add(opacityMenu);
|
moel@176
|
194 |
Opacity = (byte)settings.GetValue("sensorGadget.Opacity", 255);
|
moel@176
|
195 |
for (int i = 0; i < 5; i++) {
|
moel@176
|
196 |
MenuItem item = new MenuItem((20 * (i + 1)).ToString() + " %");
|
moel@176
|
197 |
byte o = (byte)(51 * (i + 1));
|
moel@176
|
198 |
item.Checked = Opacity == o;
|
moel@176
|
199 |
item.Click += delegate(object sender, EventArgs e) {
|
moel@178
|
200 |
Opacity = o;
|
moel@176
|
201 |
settings.SetValue("sensorGadget.Opacity", Opacity);
|
moel@176
|
202 |
foreach (MenuItem mi in opacityMenu.MenuItems)
|
moel@178
|
203 |
mi.Checked = mi == item;
|
moel@176
|
204 |
};
|
moel@176
|
205 |
opacityMenu.MenuItems.Add(item);
|
moel@176
|
206 |
}
|
moel@176
|
207 |
this.ContextMenu = contextMenu;
|
moel@176
|
208 |
|
moel@181
|
209 |
hardwareNames = new UserOption("sensorGadget.Hardwarenames", true,
|
moel@181
|
210 |
hardwareNamesItem, settings);
|
moel@181
|
211 |
hardwareNames.Changed += delegate(object sender, EventArgs e) {
|
moel@181
|
212 |
Resize();
|
moel@181
|
213 |
};
|
moel@181
|
214 |
|
moel@176
|
215 |
alwaysOnTop = new UserOption("sensorGadget.AlwaysOnTop", false,
|
moel@176
|
216 |
alwaysOnTopItem, settings);
|
moel@176
|
217 |
alwaysOnTop.Changed += delegate(object sender, EventArgs e) {
|
moel@176
|
218 |
this.AlwaysOnTop = alwaysOnTop.Value;
|
moel@176
|
219 |
};
|
moel@183
|
220 |
lockPositionAndSize = new UserOption("sensorGadget.LockPositionAndSize",
|
moel@183
|
221 |
false, lockItem, settings);
|
moel@183
|
222 |
lockPositionAndSize.Changed += delegate(object sender, EventArgs e) {
|
moel@183
|
223 |
this.LockPositionAndSize = lockPositionAndSize.Value;
|
moel@176
|
224 |
};
|
moel@176
|
225 |
|
moel@183
|
226 |
HitTest += delegate(object sender, HitTestEventArgs e) {
|
moel@183
|
227 |
if (lockPositionAndSize.Value)
|
moel@183
|
228 |
return;
|
moel@183
|
229 |
|
moel@183
|
230 |
if (e.Location.X < leftBorder) {
|
moel@183
|
231 |
e.HitResult = HitResult.Left;
|
moel@183
|
232 |
return;
|
moel@183
|
233 |
}
|
moel@183
|
234 |
if (e.Location.X > Size.Width - 1 - rightBorder) {
|
moel@183
|
235 |
e.HitResult = HitResult.Right;
|
moel@183
|
236 |
return;
|
moel@183
|
237 |
}
|
moel@183
|
238 |
};
|
moel@183
|
239 |
|
moel@183
|
240 |
SizeChanged += delegate(object sender, EventArgs e) {
|
moel@183
|
241 |
settings.SetValue("sensorGadget.Width", Size.Width);
|
moel@183
|
242 |
Redraw();
|
moel@183
|
243 |
};
|
moel@244
|
244 |
|
moel@289
|
245 |
VisibleChanged += delegate(object sender, EventArgs e) {
|
moel@289
|
246 |
Rectangle bounds = new Rectangle(Location, Size);
|
moel@289
|
247 |
Screen screen = Screen.FromRectangle(bounds);
|
moel@289
|
248 |
Rectangle intersection =
|
moel@289
|
249 |
Rectangle.Intersect(screen.WorkingArea, bounds);
|
moel@289
|
250 |
if (intersection.Width < Math.Min(16, bounds.Width) ||
|
moel@289
|
251 |
intersection.Height < Math.Min(16, bounds.Height))
|
moel@289
|
252 |
{
|
moel@289
|
253 |
Location = new Point(
|
moel@289
|
254 |
screen.WorkingArea.Width / 2 - bounds.Width / 2,
|
moel@289
|
255 |
screen.WorkingArea.Height / 2 - bounds.Height / 2);
|
moel@289
|
256 |
}
|
moel@289
|
257 |
};
|
moel@289
|
258 |
|
moel@244
|
259 |
MouseDoubleClick += delegate(object obj, MouseEventArgs args) {
|
moel@244
|
260 |
SendHideShowCommand();
|
moel@244
|
261 |
};
|
moel@176
|
262 |
}
|
moel@176
|
263 |
|
moel@181
|
264 |
public override void Dispose() {
|
moel@181
|
265 |
|
moel@181
|
266 |
largeFont.Dispose();
|
moel@181
|
267 |
largeFont = null;
|
moel@181
|
268 |
|
moel@181
|
269 |
smallFont.Dispose();
|
moel@181
|
270 |
smallFont = null;
|
moel@181
|
271 |
|
moel@181
|
272 |
darkWhite.Dispose();
|
moel@181
|
273 |
darkWhite = null;
|
moel@181
|
274 |
|
moel@183
|
275 |
stringFormat.Dispose();
|
moel@183
|
276 |
stringFormat = null;
|
moel@183
|
277 |
|
moel@181
|
278 |
trimStringFormat.Dispose();
|
moel@181
|
279 |
trimStringFormat = null;
|
moel@181
|
280 |
|
moel@181
|
281 |
alignRightStringFormat.Dispose();
|
moel@316
|
282 |
alignRightStringFormat = null;
|
moel@316
|
283 |
|
moel@316
|
284 |
back.Dispose();
|
moel@316
|
285 |
back = null;
|
moel@316
|
286 |
|
moel@342
|
287 |
barFore.Dispose();
|
moel@342
|
288 |
barFore = null;
|
moel@316
|
289 |
|
moel@316
|
290 |
barBack.Dispose();
|
moel@316
|
291 |
barBack = null;
|
moel@316
|
292 |
|
moel@316
|
293 |
background.Dispose();
|
moel@316
|
294 |
background = null;
|
moel@181
|
295 |
|
moel@342
|
296 |
if (image != null) {
|
moel@342
|
297 |
image.Dispose();
|
moel@342
|
298 |
image = null;
|
moel@342
|
299 |
}
|
moel@342
|
300 |
|
moel@342
|
301 |
if (fore != null) {
|
moel@342
|
302 |
fore.Dispose();
|
moel@342
|
303 |
fore = null;
|
moel@342
|
304 |
}
|
moel@342
|
305 |
|
moel@181
|
306 |
base.Dispose();
|
moel@181
|
307 |
}
|
moel@181
|
308 |
|
moel@176
|
309 |
private void HardwareRemoved(IHardware hardware) {
|
moel@176
|
310 |
hardware.SensorAdded -= new SensorEventHandler(SensorAdded);
|
moel@176
|
311 |
hardware.SensorRemoved -= new SensorEventHandler(SensorRemoved);
|
moel@176
|
312 |
foreach (ISensor sensor in hardware.Sensors)
|
moel@176
|
313 |
SensorRemoved(sensor);
|
moel@176
|
314 |
foreach (IHardware subHardware in hardware.SubHardware)
|
moel@176
|
315 |
HardwareRemoved(subHardware);
|
moel@176
|
316 |
}
|
moel@176
|
317 |
|
moel@176
|
318 |
private void HardwareAdded(IHardware hardware) {
|
moel@176
|
319 |
foreach (ISensor sensor in hardware.Sensors)
|
moel@176
|
320 |
SensorAdded(sensor);
|
moel@176
|
321 |
hardware.SensorAdded += new SensorEventHandler(SensorAdded);
|
moel@176
|
322 |
hardware.SensorRemoved += new SensorEventHandler(SensorRemoved);
|
moel@176
|
323 |
foreach (IHardware subHardware in hardware.SubHardware)
|
moel@176
|
324 |
HardwareAdded(subHardware);
|
moel@176
|
325 |
}
|
moel@176
|
326 |
|
moel@176
|
327 |
private void SensorAdded(ISensor sensor) {
|
moel@176
|
328 |
if (settings.GetValue(new Identifier(sensor.Identifier,
|
moel@176
|
329 |
"gadget").ToString(), false))
|
moel@176
|
330 |
Add(sensor);
|
moel@176
|
331 |
}
|
moel@176
|
332 |
|
moel@176
|
333 |
private void SensorRemoved(ISensor sensor) {
|
moel@176
|
334 |
if (Contains(sensor))
|
moel@176
|
335 |
Remove(sensor, false);
|
moel@176
|
336 |
}
|
moel@176
|
337 |
|
moel@176
|
338 |
public bool Contains(ISensor sensor) {
|
moel@176
|
339 |
foreach (IList<ISensor> list in sensors.Values)
|
moel@176
|
340 |
if (list.Contains(sensor))
|
moel@176
|
341 |
return true;
|
moel@176
|
342 |
return false;
|
moel@176
|
343 |
}
|
moel@176
|
344 |
|
moel@176
|
345 |
public void Add(ISensor sensor) {
|
moel@176
|
346 |
if (Contains(sensor)) {
|
moel@176
|
347 |
return;
|
moel@176
|
348 |
} else {
|
moel@176
|
349 |
// get the right hardware
|
moel@176
|
350 |
IHardware hardware = sensor.Hardware;
|
moel@176
|
351 |
while (hardware.Parent != null)
|
moel@176
|
352 |
hardware = hardware.Parent;
|
moel@176
|
353 |
|
moel@176
|
354 |
// get the sensor list associated with the hardware
|
moel@176
|
355 |
IList<ISensor> list;
|
moel@176
|
356 |
if (!sensors.TryGetValue(hardware, out list)) {
|
moel@176
|
357 |
list = new List<ISensor>();
|
moel@176
|
358 |
sensors.Add(hardware, list);
|
moel@176
|
359 |
}
|
moel@176
|
360 |
|
moel@176
|
361 |
// insert the sensor at the right position
|
moel@176
|
362 |
int i = 0;
|
moel@176
|
363 |
while (i < list.Count && (list[i].SensorType < sensor.SensorType ||
|
moel@176
|
364 |
(list[i].SensorType == sensor.SensorType &&
|
moel@176
|
365 |
list[i].Index < sensor.Index))) i++;
|
moel@176
|
366 |
list.Insert(i, sensor);
|
moel@176
|
367 |
|
moel@176
|
368 |
settings.SetValue(
|
moel@176
|
369 |
new Identifier(sensor.Identifier, "gadget").ToString(), true);
|
moel@176
|
370 |
|
moel@176
|
371 |
Resize();
|
moel@176
|
372 |
}
|
moel@176
|
373 |
}
|
moel@176
|
374 |
|
moel@176
|
375 |
public void Remove(ISensor sensor) {
|
moel@176
|
376 |
Remove(sensor, true);
|
moel@176
|
377 |
}
|
moel@176
|
378 |
|
moel@176
|
379 |
private void Remove(ISensor sensor, bool deleteConfig) {
|
moel@176
|
380 |
if (deleteConfig)
|
moel@176
|
381 |
settings.Remove(new Identifier(sensor.Identifier, "gadget").ToString());
|
moel@176
|
382 |
|
moel@176
|
383 |
foreach (KeyValuePair<IHardware, IList<ISensor>> keyValue in sensors)
|
moel@176
|
384 |
if (keyValue.Value.Contains(sensor)) {
|
moel@176
|
385 |
keyValue.Value.Remove(sensor);
|
moel@176
|
386 |
if (keyValue.Value.Count == 0) {
|
moel@176
|
387 |
sensors.Remove(keyValue.Key);
|
moel@176
|
388 |
break;
|
moel@176
|
389 |
}
|
moel@176
|
390 |
}
|
moel@176
|
391 |
Resize();
|
moel@183
|
392 |
}
|
moel@183
|
393 |
|
moel@244
|
394 |
public event EventHandler HideShowCommand;
|
moel@244
|
395 |
|
moel@244
|
396 |
public void SendHideShowCommand() {
|
moel@244
|
397 |
if (HideShowCommand != null)
|
moel@244
|
398 |
HideShowCommand(this, null);
|
moel@244
|
399 |
}
|
moel@244
|
400 |
|
moel@183
|
401 |
private Font CreateFont(float size, FontStyle style) {
|
moel@215
|
402 |
try {
|
moel@215
|
403 |
return new Font(SystemFonts.MessageBoxFont.FontFamily, size, style);
|
moel@215
|
404 |
} catch (ArgumentException) {
|
moel@215
|
405 |
// if the style is not supported, fall back to the original one
|
moel@215
|
406 |
return new Font(SystemFonts.MessageBoxFont.FontFamily, size,
|
moel@215
|
407 |
SystemFonts.MessageBoxFont.Style);
|
moel@215
|
408 |
}
|
moel@183
|
409 |
}
|
moel@183
|
410 |
|
moel@183
|
411 |
private void SetFontSize(float size) {
|
moel@183
|
412 |
fontSize = size;
|
moel@183
|
413 |
largeFont = CreateFont(fontSize, FontStyle.Bold);
|
moel@183
|
414 |
smallFont = CreateFont(fontSize, FontStyle.Regular);
|
moel@252
|
415 |
|
moel@252
|
416 |
double scaledFontSize = fontSize * scale;
|
moel@252
|
417 |
iconSize = (int)Math.Round(1.5 * scaledFontSize);
|
moel@252
|
418 |
hardwareLineHeight = (int)Math.Round(1.66 * scaledFontSize);
|
moel@252
|
419 |
sensorLineHeight = (int)Math.Round(1.33 * scaledFontSize);
|
moel@252
|
420 |
leftMargin = leftBorder + (int)Math.Round(0.3 * scaledFontSize);
|
moel@252
|
421 |
rightMargin = rightBorder + (int)Math.Round(0.3 * scaledFontSize);
|
moel@183
|
422 |
topMargin = topBorder;
|
moel@252
|
423 |
bottomMargin = bottomBorder + (int)Math.Round(0.3 * scaledFontSize);
|
moel@252
|
424 |
progressWidth = (int)Math.Round(5.3 * scaledFontSize);
|
moel@252
|
425 |
|
moel@252
|
426 |
Resize((int)Math.Round(17.3 * scaledFontSize));
|
moel@176
|
427 |
}
|
moel@176
|
428 |
|
moel@176
|
429 |
private void Resize() {
|
moel@183
|
430 |
Resize(this.Size.Width);
|
moel@183
|
431 |
}
|
moel@183
|
432 |
|
moel@183
|
433 |
private void Resize(int width) {
|
moel@183
|
434 |
int y = topMargin;
|
moel@176
|
435 |
foreach (KeyValuePair<IHardware, IList<ISensor>> pair in sensors) {
|
moel@181
|
436 |
if (hardwareNames.Value) {
|
moel@183
|
437 |
if (y > topMargin)
|
moel@183
|
438 |
y += hardwareLineHeight - sensorLineHeight;
|
moel@181
|
439 |
y += hardwareLineHeight;
|
moel@181
|
440 |
}
|
moel@176
|
441 |
y += pair.Value.Count * sensorLineHeight;
|
moel@263
|
442 |
}
|
moel@263
|
443 |
if (sensors.Count == 0)
|
moel@263
|
444 |
y += 4 * sensorLineHeight + hardwareLineHeight;
|
moel@183
|
445 |
y += bottomMargin;
|
moel@183
|
446 |
this.Size = new Size(width, y);
|
moel@176
|
447 |
}
|
moel@176
|
448 |
|
moel@342
|
449 |
private void DrawImageWidthBorder(Graphics g, int width, int height,
|
moel@342
|
450 |
Image back, int t, int b, int l, int r)
|
moel@342
|
451 |
{
|
moel@342
|
452 |
GraphicsUnit u = GraphicsUnit.Pixel;
|
moel@342
|
453 |
|
moel@342
|
454 |
g.DrawImage(back, new Rectangle(0, 0, l, t),
|
moel@342
|
455 |
new Rectangle(0, 0, l, t), u);
|
moel@342
|
456 |
g.DrawImage(back, new Rectangle(l, 0, width - l - r, t),
|
moel@342
|
457 |
new Rectangle(l, 0, back.Width - l - r, t), u);
|
moel@342
|
458 |
g.DrawImage(back, new Rectangle(width - r, 0, r, t),
|
moel@342
|
459 |
new Rectangle(back.Width - r, 0, r, t), u);
|
moel@342
|
460 |
|
moel@342
|
461 |
g.DrawImage(back, new Rectangle(0, t, l, height - t - b),
|
moel@342
|
462 |
new Rectangle(0, t, l, back.Height - t - b), u);
|
moel@342
|
463 |
g.DrawImage(back, new Rectangle(l, t, width - l - r, height - t - b),
|
moel@342
|
464 |
new Rectangle(l, t, back.Width - l - r, back.Height - t - b), u);
|
moel@342
|
465 |
g.DrawImage(back, new Rectangle(width - r, t, r, height - t - b),
|
moel@342
|
466 |
new Rectangle(back.Width - r, t, r, back.Height - t - b), u);
|
moel@342
|
467 |
|
moel@342
|
468 |
g.DrawImage(back, new Rectangle(0, height - b, l, b),
|
moel@342
|
469 |
new Rectangle(0, back.Height - b, l, b), u);
|
moel@342
|
470 |
g.DrawImage(back, new Rectangle(l, height - b, width - l - r, b),
|
moel@342
|
471 |
new Rectangle(l, back.Height - b, back.Width - l - r, b), u);
|
moel@342
|
472 |
g.DrawImage(back, new Rectangle(width - r, height - b, r, b),
|
moel@342
|
473 |
new Rectangle(back.Width - r, back.Height - b, r, b), u);
|
moel@342
|
474 |
}
|
moel@342
|
475 |
|
moel@176
|
476 |
private void DrawBackground(Graphics g) {
|
moel@176
|
477 |
int w = Size.Width;
|
moel@316
|
478 |
int h = Size.Height;
|
moel@176
|
479 |
|
moel@316
|
480 |
if (w != background.Width || h != background.Height) {
|
moel@176
|
481 |
|
moel@316
|
482 |
background.Dispose();
|
moel@316
|
483 |
background = new Bitmap(w, h, PixelFormat.Format32bppPArgb);
|
moel@316
|
484 |
using (Graphics graphics = Graphics.FromImage(background)) {
|
moel@176
|
485 |
|
moel@342
|
486 |
DrawImageWidthBorder(graphics, w, h, back, topBorder, bottomBorder,
|
moel@342
|
487 |
leftBorder, rightBorder);
|
moel@342
|
488 |
|
moel@342
|
489 |
if (fore != null)
|
moel@342
|
490 |
DrawImageWidthBorder(graphics, w, h, fore, topBorder, bottomBorder,
|
moel@342
|
491 |
leftBorder, rightBorder);
|
moel@316
|
492 |
|
moel@342
|
493 |
if (image != null) {
|
moel@342
|
494 |
int width = w - leftBorder - rightBorder;
|
moel@342
|
495 |
int height = h - topBorder - bottomBorder;
|
moel@342
|
496 |
float xRatio = width / (float)image.Width;
|
moel@342
|
497 |
float yRatio = height / (float)image.Height;
|
moel@342
|
498 |
float destWidth, destHeight;
|
moel@342
|
499 |
float xOffset, yOffset;
|
moel@342
|
500 |
if (xRatio < yRatio) {
|
moel@342
|
501 |
destWidth = width;
|
moel@342
|
502 |
destHeight = image.Height * xRatio;
|
moel@342
|
503 |
xOffset = 0;
|
moel@342
|
504 |
yOffset = 0.5f * (height - destHeight);
|
moel@342
|
505 |
} else {
|
moel@342
|
506 |
destWidth = image.Width * yRatio;
|
moel@342
|
507 |
destHeight = height;
|
moel@342
|
508 |
xOffset = 0.5f * (width - destWidth);
|
moel@342
|
509 |
yOffset = 0;
|
moel@342
|
510 |
}
|
moel@316
|
511 |
|
moel@342
|
512 |
graphics.DrawImage(image,
|
moel@342
|
513 |
new RectangleF(leftBorder + xOffset, topBorder + yOffset,
|
moel@342
|
514 |
destWidth, destHeight));
|
moel@342
|
515 |
}
|
moel@316
|
516 |
}
|
moel@316
|
517 |
}
|
moel@316
|
518 |
|
moel@316
|
519 |
g.DrawImageUnscaled(background, 0, 0);
|
moel@176
|
520 |
}
|
moel@176
|
521 |
|
moel@243
|
522 |
private void DrawProgress(Graphics g, float x, float y,
|
moel@243
|
523 |
float width, float height, float progress)
|
moel@176
|
524 |
{
|
moel@176
|
525 |
g.DrawImage(barBack,
|
moel@176
|
526 |
new RectangleF(x + width * progress, y, width * (1 - progress), height),
|
moel@176
|
527 |
new RectangleF(barBack.Width * progress, 0,
|
moel@176
|
528 |
(1 - progress) * barBack.Width, barBack.Height),
|
moel@176
|
529 |
GraphicsUnit.Pixel);
|
moel@342
|
530 |
g.DrawImage(barFore,
|
moel@176
|
531 |
new RectangleF(x, y, width * progress, height),
|
moel@342
|
532 |
new RectangleF(0, 0, progress * barFore.Width, barFore.Height),
|
moel@176
|
533 |
GraphicsUnit.Pixel);
|
moel@176
|
534 |
}
|
moel@176
|
535 |
|
moel@176
|
536 |
protected override void OnPaint(PaintEventArgs e) {
|
moel@176
|
537 |
Graphics g = e.Graphics;
|
moel@176
|
538 |
int w = Size.Width;
|
moel@176
|
539 |
|
moel@176
|
540 |
g.Clear(Color.Transparent);
|
moel@183
|
541 |
|
moel@176
|
542 |
DrawBackground(g);
|
moel@176
|
543 |
|
moel@176
|
544 |
int x;
|
moel@183
|
545 |
int y = topMargin;
|
moel@186
|
546 |
|
moel@186
|
547 |
if (sensors.Count == 0) {
|
moel@186
|
548 |
x = leftBorder + 1;
|
moel@263
|
549 |
g.DrawString("Right-click on a sensor in the main window and select " +
|
moel@263
|
550 |
"\"Show in Gadget\" to show the sensor here.",
|
moel@263
|
551 |
smallFont, Brushes.White,
|
moel@186
|
552 |
new Rectangle(x, y - 1, w - rightBorder - x, 0));
|
moel@186
|
553 |
}
|
moel@186
|
554 |
|
moel@176
|
555 |
foreach (KeyValuePair<IHardware, IList<ISensor>> pair in sensors) {
|
moel@181
|
556 |
if (hardwareNames.Value) {
|
moel@183
|
557 |
if (y > topMargin)
|
moel@183
|
558 |
y += hardwareLineHeight - sensorLineHeight;
|
moel@181
|
559 |
x = leftBorder + 1;
|
moel@181
|
560 |
g.DrawImage(HardwareTypeImage.Instance.GetImage(pair.Key.HardwareType),
|
moel@181
|
561 |
new Rectangle(x, y + 1, iconSize, iconSize));
|
moel@181
|
562 |
x += iconSize + 1;
|
moel@181
|
563 |
g.DrawString(pair.Key.Name, largeFont, Brushes.White,
|
moel@183
|
564 |
new Rectangle(x, y - 1, w - rightBorder - x, 0),
|
moel@183
|
565 |
stringFormat);
|
moel@181
|
566 |
y += hardwareLineHeight;
|
moel@181
|
567 |
}
|
moel@176
|
568 |
|
moel@176
|
569 |
foreach (ISensor sensor in pair.Value) {
|
moel@183
|
570 |
int remainingWidth;
|
moel@176
|
571 |
|
moel@187
|
572 |
|
moel@187
|
573 |
if ((sensor.SensorType != SensorType.Load &&
|
moel@217
|
574 |
sensor.SensorType != SensorType.Control &&
|
moel@217
|
575 |
sensor.SensorType != SensorType.Level) || !sensor.Value.HasValue)
|
moel@176
|
576 |
{
|
moel@187
|
577 |
string formatted;
|
moel@187
|
578 |
|
moel@187
|
579 |
if (sensor.Value.HasValue) {
|
moel@187
|
580 |
string format = "";
|
moel@187
|
581 |
switch (sensor.SensorType) {
|
moel@187
|
582 |
case SensorType.Voltage:
|
moel@300
|
583 |
format = "{0:F3} V";
|
moel@187
|
584 |
break;
|
moel@187
|
585 |
case SensorType.Clock:
|
moel@187
|
586 |
format = "{0:F0} MHz";
|
moel@187
|
587 |
break;
|
moel@187
|
588 |
case SensorType.Temperature:
|
moel@187
|
589 |
format = "{0:F1} °C";
|
moel@187
|
590 |
break;
|
moel@187
|
591 |
case SensorType.Fan:
|
moel@187
|
592 |
format = "{0:F0} RPM";
|
moel@187
|
593 |
break;
|
moel@187
|
594 |
case SensorType.Flow:
|
moel@187
|
595 |
format = "{0:F0} L/h";
|
moel@187
|
596 |
break;
|
moel@318
|
597 |
case SensorType.Power:
|
moel@318
|
598 |
format = "{0:F1} W";
|
moel@318
|
599 |
break;
|
moel@324
|
600 |
case SensorType.Data:
|
moel@324
|
601 |
format = "{0:F1} GB";
|
moel@324
|
602 |
break;
|
moel@340
|
603 |
case SensorType.Factor:
|
moel@340
|
604 |
format = "{0:F3}";
|
moel@340
|
605 |
break;
|
moel@187
|
606 |
}
|
moel@187
|
607 |
|
moel@187
|
608 |
if (sensor.SensorType == SensorType.Temperature &&
|
moel@187
|
609 |
unitManager.TemperatureUnit == TemperatureUnit.Fahrenheit) {
|
moel@187
|
610 |
formatted = string.Format("{0:F1} °F",
|
moel@187
|
611 |
sensor.Value * 1.8 + 32);
|
moel@187
|
612 |
} else {
|
moel@187
|
613 |
formatted = string.Format(format, sensor.Value);
|
moel@187
|
614 |
}
|
moel@187
|
615 |
} else {
|
moel@187
|
616 |
formatted = "-";
|
moel@176
|
617 |
}
|
moel@176
|
618 |
|
moel@187
|
619 |
g.DrawString(formatted, smallFont, darkWhite,
|
moel@187
|
620 |
new RectangleF(-1, y - 1, w - rightMargin + 3, 0),
|
moel@181
|
621 |
alignRightStringFormat);
|
moel@181
|
622 |
|
moel@187
|
623 |
remainingWidth = w - (int)Math.Floor(g.MeasureString(formatted,
|
moel@187
|
624 |
smallFont, w, StringFormat.GenericTypographic).Width) -
|
moel@181
|
625 |
rightMargin;
|
moel@187
|
626 |
} else {
|
moel@187
|
627 |
DrawProgress(g, w - progressWidth - rightMargin,
|
moel@243
|
628 |
y + 0.35f * sensorLineHeight, progressWidth,
|
moel@243
|
629 |
0.6f * sensorLineHeight, 0.01f * sensor.Value.Value);
|
moel@183
|
630 |
|
moel@183
|
631 |
remainingWidth = w - progressWidth - rightMargin;
|
moel@176
|
632 |
}
|
moel@187
|
633 |
|
moel@183
|
634 |
remainingWidth -= leftMargin + 2;
|
moel@183
|
635 |
if (remainingWidth > 0) {
|
moel@183
|
636 |
g.DrawString(sensor.Name, smallFont, darkWhite,
|
moel@183
|
637 |
new RectangleF(leftMargin - 1, y - 1, remainingWidth, 0),
|
moel@183
|
638 |
trimStringFormat);
|
moel@183
|
639 |
}
|
moel@181
|
640 |
|
moel@176
|
641 |
y += sensorLineHeight;
|
moel@176
|
642 |
}
|
moel@176
|
643 |
}
|
moel@176
|
644 |
}
|
moel@176
|
645 |
|
moel@176
|
646 |
private class HardwareComparer : IComparer<IHardware> {
|
moel@176
|
647 |
public int Compare(IHardware x, IHardware y) {
|
moel@176
|
648 |
if (x == null && y == null)
|
moel@176
|
649 |
return 0;
|
moel@176
|
650 |
if (x == null)
|
moel@176
|
651 |
return -1;
|
moel@176
|
652 |
if (y == null)
|
moel@176
|
653 |
return 1;
|
moel@176
|
654 |
|
moel@176
|
655 |
if (x.HardwareType != y.HardwareType)
|
moel@176
|
656 |
return x.HardwareType.CompareTo(y.HardwareType);
|
moel@176
|
657 |
|
moel@184
|
658 |
return x.Identifier.CompareTo(y.Identifier);
|
moel@176
|
659 |
}
|
moel@176
|
660 |
}
|
moel@176
|
661 |
}
|
moel@176
|
662 |
}
|
moel@176
|
663 |
|