* Workaround for page changing on DDR5 systems with SPD Write Protection active has been implemented in new version of RAMSPDToolkit. Code for LHM has been adjusted accordingly. Added more sensors (timings). * Move abbreviation of timings to start of string. * Simplify names for timings. * Update version. * Remove extra padding.
769 lines
28 KiB
C#
769 lines
28 KiB
C#
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
|
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
// Copyright (C) LibreHardwareMonitor and Contributors.
|
|
// Partial Copyright (C) Michael Möller <mmoeller@openhardwaremonitor.org> and Contributors.
|
|
// All Rights Reserved.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.Drawing.Imaging;
|
|
using System.Windows.Forms;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using LibreHardwareMonitor.Hardware;
|
|
using LibreHardwareMonitor.Utilities;
|
|
|
|
namespace LibreHardwareMonitor.UI;
|
|
|
|
public class SensorGadget : Gadget
|
|
{
|
|
private const int TopBorder = 6;
|
|
private const int BottomBorder = 7;
|
|
private const int LeftBorder = 6;
|
|
private const int RightBorder = 7;
|
|
|
|
private readonly UnitManager _unitManager;
|
|
private Image _back = Utilities.EmbeddedResources.GetImage("gadget.png");
|
|
private Image _image;
|
|
private Image _fore;
|
|
private Image _barBack = Utilities.EmbeddedResources.GetImage("barback.png");
|
|
private Image _barFore = Utilities.EmbeddedResources.GetImage("barblue.png");
|
|
private Image _background = new Bitmap(1, 1);
|
|
private readonly float _scale;
|
|
private float _fontSize;
|
|
private int _iconSize;
|
|
private int _hardwareLineHeight;
|
|
private int _sensorLineHeight;
|
|
private int _rightMargin;
|
|
private int _leftMargin;
|
|
private int _topMargin;
|
|
private int _bottomMargin;
|
|
private int _progressWidth;
|
|
|
|
private readonly IDictionary<IHardware, IList<ISensor>> _sensors = new SortedDictionary<IHardware, IList<ISensor>>(new HardwareComparer());
|
|
private readonly PersistentSettings _settings;
|
|
private readonly UserOption _hardwareNames;
|
|
|
|
private Font _largeFont;
|
|
private Font _smallFont;
|
|
private Brush _textBrush;
|
|
private StringFormat _stringFormat;
|
|
private StringFormat _trimStringFormat;
|
|
private StringFormat _alignRightStringFormat;
|
|
|
|
public SensorGadget(IComputer computer, PersistentSettings settings, UnitManager unitManager)
|
|
{
|
|
_unitManager = unitManager;
|
|
_settings = settings;
|
|
computer.HardwareAdded += HardwareAdded;
|
|
computer.HardwareRemoved += HardwareRemoved;
|
|
|
|
_stringFormat = new StringFormat { FormatFlags = StringFormatFlags.NoWrap };
|
|
_trimStringFormat = new StringFormat { Trimming = StringTrimming.EllipsisCharacter, FormatFlags = StringFormatFlags.NoWrap };
|
|
_alignRightStringFormat = new StringFormat { Alignment = StringAlignment.Far, FormatFlags = StringFormatFlags.NoWrap };
|
|
|
|
if (File.Exists("gadget_background.png"))
|
|
{
|
|
try
|
|
{
|
|
Image newBack = new Bitmap("gadget_background.png");
|
|
_back.Dispose();
|
|
_back = newBack;
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
if (File.Exists("gadget_image.png"))
|
|
{
|
|
try
|
|
{
|
|
_image = new Bitmap("gadget_image.png");
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
if (File.Exists("gadget_foreground.png"))
|
|
{
|
|
try
|
|
{
|
|
_fore = new Bitmap("gadget_foreground.png");
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
if (File.Exists("gadget_bar_background.png"))
|
|
{
|
|
try
|
|
{
|
|
Image newBarBack = new Bitmap("gadget_bar_background.png");
|
|
_barBack.Dispose();
|
|
_barBack = newBarBack;
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
if (File.Exists("gadget_bar_foreground.png"))
|
|
{
|
|
try
|
|
{
|
|
Image newBarColor = new Bitmap("gadget_bar_foreground.png");
|
|
_barFore.Dispose();
|
|
_barFore = newBarColor;
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
Location = new Point(settings.GetValue("sensorGadget.Location.X", 100), settings.GetValue("sensorGadget.Location.Y", 100));
|
|
LocationChanged += delegate
|
|
{
|
|
settings.SetValue("sensorGadget.Location.X", Location.X);
|
|
settings.SetValue("sensorGadget.Location.Y", Location.Y);
|
|
};
|
|
|
|
// get the custom to default dpi ratio
|
|
using (Bitmap b = new Bitmap(1, 1))
|
|
{
|
|
_scale = b.HorizontalResolution / 96.0f;
|
|
}
|
|
|
|
SetFontSize(settings.GetValue("sensorGadget.FontSize", 7.5f));
|
|
Resize(settings.GetValue("sensorGadget.Width", Size.Width));
|
|
|
|
ContextMenuStrip contextMenuStrip = new ContextMenuStrip();
|
|
ToolStripMenuItem hardwareNamesItem = new ToolStripMenuItem("Hardware Names");
|
|
contextMenuStrip.Items.Add(hardwareNamesItem);
|
|
ToolStripMenuItem fontSizeMenu = new ToolStripMenuItem("Font Size");
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
float size;
|
|
string name;
|
|
switch (i)
|
|
{
|
|
case 0: size = 6.5f; name = "Small"; break;
|
|
case 1: size = 7.5f; name = "Medium"; break;
|
|
case 2: size = 9f; name = "Large"; break;
|
|
case 3: size = 11f; name = "Very Large"; break;
|
|
default: throw new NotImplementedException();
|
|
}
|
|
|
|
ToolStripItem item = new ToolStripMenuItem(name) { Checked = _fontSize == size };
|
|
item.Click += delegate
|
|
{
|
|
SetFontSize(size);
|
|
settings.SetValue("sensorGadget.FontSize", size);
|
|
foreach (ToolStripMenuItem mi in fontSizeMenu.DropDownItems)
|
|
mi.Checked = mi == item;
|
|
};
|
|
fontSizeMenu.DropDownItems.Add(item);
|
|
}
|
|
contextMenuStrip.Items.Add(fontSizeMenu);
|
|
|
|
Color fontColor = settings.GetValue("sensorGadget.FontColor", Color.White);
|
|
int fontColorArgb = fontColor.ToArgb();
|
|
|
|
SetFontColor(fontColor);
|
|
|
|
IEnumerable<Color> providedColors = Enum.GetValues(typeof(KnownColor))
|
|
.Cast<KnownColor>()
|
|
.Select(x => Color.FromKnownColor(x))
|
|
.Where(x => !x.IsSystemColor && x.Name.Length < 7);
|
|
|
|
ToolStripMenuItem fontColorMenu = new ToolStripMenuItem("Font Color");
|
|
foreach (Color color in providedColors)
|
|
{
|
|
ToolStripItem item = new ToolStripMenuItem(color.Name) { Checked = fontColorArgb == color.ToArgb() };
|
|
item.Click += delegate
|
|
{
|
|
SetFontColor(color);
|
|
settings.SetValue("sensorGadget.FontColor", color);
|
|
foreach (ToolStripMenuItem mi in fontColorMenu.DropDownItems)
|
|
mi.Checked = mi == item;
|
|
};
|
|
fontColorMenu.DropDownItems.Add(item);
|
|
}
|
|
contextMenuStrip.Items.Add(fontColorMenu);
|
|
contextMenuStrip.Items.Add(new ToolStripSeparator());
|
|
ToolStripMenuItem lockItem = new ToolStripMenuItem("Lock Position and Size");
|
|
contextMenuStrip.Items.Add(lockItem);
|
|
contextMenuStrip.Items.Add(new ToolStripSeparator());
|
|
ToolStripMenuItem alwaysOnTopItem = new ToolStripMenuItem("Always on Top");
|
|
contextMenuStrip.Items.Add(alwaysOnTopItem);
|
|
ToolStripMenuItem opacityMenu = new ToolStripMenuItem("Opacity");
|
|
contextMenuStrip.Items.Add(opacityMenu);
|
|
Opacity = (byte)settings.GetValue("sensorGadget.Opacity", 255);
|
|
|
|
for (int i = 0; i < 5; i++)
|
|
{
|
|
ToolStripMenuItem item = new ToolStripMenuItem((20 * (i + 1)).ToString() + " %");
|
|
byte o = (byte)(51 * (i + 1));
|
|
item.Checked = Opacity == o;
|
|
item.Click += delegate
|
|
{
|
|
Opacity = o;
|
|
settings.SetValue("sensorGadget.Opacity", Opacity);
|
|
foreach (ToolStripMenuItem mi in opacityMenu.DropDownItems)
|
|
mi.Checked = mi == item;
|
|
};
|
|
opacityMenu.DropDownItems.Add(item);
|
|
}
|
|
ContextMenuStrip = contextMenuStrip;
|
|
|
|
_hardwareNames = new UserOption("sensorGadget.Hardwarenames", true, hardwareNamesItem, settings);
|
|
_hardwareNames.Changed += delegate
|
|
{
|
|
Resize();
|
|
};
|
|
|
|
UserOption alwaysOnTop = new UserOption("sensorGadget.AlwaysOnTop", false, alwaysOnTopItem, settings);
|
|
alwaysOnTop.Changed += delegate
|
|
{
|
|
AlwaysOnTop = alwaysOnTop.Value;
|
|
};
|
|
UserOption lockPositionAndSize = new UserOption("sensorGadget.LockPositionAndSize", false, lockItem, settings);
|
|
lockPositionAndSize.Changed += delegate
|
|
{
|
|
LockPositionAndSize = lockPositionAndSize.Value;
|
|
};
|
|
|
|
HitTest += delegate (object sender, HitTestEventArgs e)
|
|
{
|
|
if (lockPositionAndSize.Value)
|
|
return;
|
|
|
|
if (e.Location.X < LeftBorder)
|
|
{
|
|
e.HitResult = HitResult.Left;
|
|
return;
|
|
}
|
|
if (e.Location.X > Size.Width - 1 - RightBorder)
|
|
{
|
|
e.HitResult = HitResult.Right;
|
|
}
|
|
};
|
|
|
|
SizeChanged += delegate
|
|
{
|
|
settings.SetValue("sensorGadget.Width", Size.Width);
|
|
Redraw();
|
|
};
|
|
|
|
VisibleChanged += delegate
|
|
{
|
|
Rectangle bounds = new Rectangle(Location, Size);
|
|
Screen screen = Screen.FromRectangle(bounds);
|
|
Rectangle intersection = Rectangle.Intersect(screen.WorkingArea, bounds);
|
|
if (intersection.Width < Math.Min(16, bounds.Width) || intersection.Height < Math.Min(16, bounds.Height))
|
|
{
|
|
Location = new Point(screen.WorkingArea.Width / 2 - bounds.Width / 2, screen.WorkingArea.Height / 2 - bounds.Height / 2);
|
|
}
|
|
};
|
|
|
|
MouseDoubleClick += delegate
|
|
{
|
|
SendHideShowCommand();
|
|
};
|
|
}
|
|
|
|
public override void Dispose()
|
|
{
|
|
|
|
_largeFont.Dispose();
|
|
_largeFont = null;
|
|
|
|
_smallFont.Dispose();
|
|
_smallFont = null;
|
|
|
|
_textBrush.Dispose();
|
|
_textBrush = null;
|
|
|
|
_stringFormat.Dispose();
|
|
_stringFormat = null;
|
|
|
|
_trimStringFormat.Dispose();
|
|
_trimStringFormat = null;
|
|
|
|
_alignRightStringFormat.Dispose();
|
|
_alignRightStringFormat = null;
|
|
|
|
_back.Dispose();
|
|
_back = null;
|
|
|
|
_barFore.Dispose();
|
|
_barFore = null;
|
|
|
|
_barBack.Dispose();
|
|
_barBack = null;
|
|
|
|
_background.Dispose();
|
|
_background = null;
|
|
|
|
if (_image != null)
|
|
{
|
|
_image.Dispose();
|
|
_image = null;
|
|
}
|
|
|
|
if (_fore != null)
|
|
{
|
|
_fore.Dispose();
|
|
_fore = null;
|
|
}
|
|
|
|
base.Dispose();
|
|
}
|
|
|
|
private void HardwareRemoved(IHardware hardware)
|
|
{
|
|
hardware.SensorAdded -= SensorAdded;
|
|
hardware.SensorRemoved -= SensorRemoved;
|
|
|
|
foreach (ISensor sensor in hardware.Sensors)
|
|
SensorRemoved(sensor);
|
|
|
|
foreach (IHardware subHardware in hardware.SubHardware)
|
|
HardwareRemoved(subHardware);
|
|
}
|
|
|
|
private void HardwareAdded(IHardware hardware)
|
|
{
|
|
foreach (ISensor sensor in hardware.Sensors)
|
|
SensorAdded(sensor);
|
|
|
|
hardware.SensorAdded += SensorAdded;
|
|
hardware.SensorRemoved += SensorRemoved;
|
|
|
|
foreach (IHardware subHardware in hardware.SubHardware)
|
|
HardwareAdded(subHardware);
|
|
}
|
|
|
|
private void SensorAdded(ISensor sensor)
|
|
{
|
|
if (_settings.GetValue(new Identifier(sensor.Identifier, "gadget").ToString(), false))
|
|
Add(sensor);
|
|
}
|
|
|
|
private void SensorRemoved(ISensor sensor)
|
|
{
|
|
if (Contains(sensor))
|
|
Remove(sensor, false);
|
|
}
|
|
|
|
public bool Contains(ISensor sensor)
|
|
{
|
|
return _sensors.Values.Any(list => list.Contains(sensor));
|
|
}
|
|
|
|
public void Add(ISensor sensor)
|
|
{
|
|
if (Contains(sensor))
|
|
return;
|
|
|
|
|
|
// get the right hardware
|
|
IHardware hardware = sensor.Hardware;
|
|
while (hardware.Parent != null)
|
|
hardware = hardware.Parent;
|
|
|
|
// get the sensor list associated with the hardware
|
|
if (!_sensors.TryGetValue(hardware, out IList<ISensor> list))
|
|
{
|
|
list = new List<ISensor>();
|
|
_sensors.Add(hardware, list);
|
|
}
|
|
|
|
// insert the sensor at the right position
|
|
int i = 0;
|
|
while (i < list.Count && (list[i].SensorType < sensor.SensorType || (list[i].SensorType == sensor.SensorType && list[i].Index < sensor.Index)))
|
|
i++;
|
|
|
|
list.Insert(i, sensor);
|
|
|
|
_settings.SetValue(new Identifier(sensor.Identifier, "gadget").ToString(), true);
|
|
Resize();
|
|
}
|
|
|
|
public void Remove(ISensor sensor)
|
|
{
|
|
Remove(sensor, true);
|
|
}
|
|
|
|
private void Remove(ISensor sensor, bool deleteConfig)
|
|
{
|
|
if (deleteConfig)
|
|
_settings.Remove(new Identifier(sensor.Identifier, "gadget").ToString());
|
|
|
|
foreach (KeyValuePair<IHardware, IList<ISensor>> keyValue in _sensors)
|
|
{
|
|
if (keyValue.Value.Contains(sensor))
|
|
{
|
|
keyValue.Value.Remove(sensor);
|
|
if (keyValue.Value.Count == 0)
|
|
{
|
|
_sensors.Remove(keyValue.Key);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
Resize();
|
|
}
|
|
|
|
public event EventHandler HideShowCommand;
|
|
|
|
public void SendHideShowCommand()
|
|
{
|
|
HideShowCommand?.Invoke(this, null);
|
|
}
|
|
|
|
private Font CreateFont(float size, FontStyle style)
|
|
{
|
|
try
|
|
{
|
|
return new Font(SystemFonts.MessageBoxFont.FontFamily, size, style);
|
|
}
|
|
catch (ArgumentException)
|
|
{
|
|
// if the style is not supported, fall back to the original one
|
|
return new Font(SystemFonts.MessageBoxFont.FontFamily, size,
|
|
SystemFonts.MessageBoxFont.Style);
|
|
}
|
|
}
|
|
|
|
private void SetFontSize(float size)
|
|
{
|
|
_fontSize = size;
|
|
_largeFont = CreateFont(_fontSize, FontStyle.Bold);
|
|
_smallFont = CreateFont(_fontSize, FontStyle.Regular);
|
|
|
|
double scaledFontSize = _fontSize * _scale;
|
|
_iconSize = (int)Math.Round(1.5 * scaledFontSize);
|
|
_hardwareLineHeight = (int)Math.Round(1.66 * scaledFontSize);
|
|
_sensorLineHeight = (int)Math.Round(1.33 * scaledFontSize);
|
|
_leftMargin = LeftBorder + (int)Math.Round(0.3 * scaledFontSize);
|
|
_rightMargin = RightBorder + (int)Math.Round(0.3 * scaledFontSize);
|
|
_topMargin = TopBorder;
|
|
_bottomMargin = BottomBorder + (int)Math.Round(0.3 * scaledFontSize);
|
|
_progressWidth = (int)Math.Round(5.3 * scaledFontSize);
|
|
|
|
Resize((int)Math.Round(17.3 * scaledFontSize));
|
|
}
|
|
|
|
private void SetFontColor(Color color)
|
|
{
|
|
_textBrush?.Dispose();
|
|
_textBrush = new SolidBrush(color);
|
|
}
|
|
|
|
private void Resize()
|
|
{
|
|
Resize(Size.Width);
|
|
}
|
|
|
|
private void Resize(int width)
|
|
{
|
|
int y = _topMargin;
|
|
|
|
foreach (KeyValuePair<IHardware, IList<ISensor>> pair in _sensors)
|
|
{
|
|
if (_hardwareNames.Value)
|
|
{
|
|
if (y > _topMargin)
|
|
y += _hardwareLineHeight - _sensorLineHeight;
|
|
y += _hardwareLineHeight;
|
|
}
|
|
y += pair.Value.Count * _sensorLineHeight;
|
|
}
|
|
|
|
if (_sensors.Count == 0)
|
|
y += 4 * _sensorLineHeight + _hardwareLineHeight;
|
|
|
|
y += _bottomMargin;
|
|
Size = new Size(width, y);
|
|
}
|
|
|
|
private void DrawImageWidthBorder(Graphics g, int width, int height, Image back, int t, int b, int l, int r)
|
|
{
|
|
GraphicsUnit u = GraphicsUnit.Pixel;
|
|
|
|
g.DrawImage(back, new Rectangle(0, 0, l, t), new Rectangle(0, 0, l, t), u);
|
|
g.DrawImage(back, new Rectangle(l, 0, width - l - r, t), new Rectangle(l, 0, back.Width - l - r, t), u);
|
|
g.DrawImage(back, new Rectangle(width - r, 0, r, t), new Rectangle(back.Width - r, 0, r, t), u);
|
|
|
|
g.DrawImage(back, new Rectangle(0, t, l, height - t - b), new Rectangle(0, t, l, back.Height - t - b), u);
|
|
g.DrawImage(back, new Rectangle(l, t, width - l - r, height - t - b), new Rectangle(l, t, back.Width - l - r, back.Height - t - b), u);
|
|
g.DrawImage(back, new Rectangle(width - r, t, r, height - t - b), new Rectangle(back.Width - r, t, r, back.Height - t - b), u);
|
|
|
|
g.DrawImage(back, new Rectangle(0, height - b, l, b), new Rectangle(0, back.Height - b, l, b), u);
|
|
g.DrawImage(back, new Rectangle(l, height - b, width - l - r, b), new Rectangle(l, back.Height - b, back.Width - l - r, b), u);
|
|
g.DrawImage(back, new Rectangle(width - r, height - b, r, b), new Rectangle(back.Width - r, back.Height - b, r, b), u);
|
|
}
|
|
|
|
private void DrawBackground(Graphics g)
|
|
{
|
|
int w = Size.Width;
|
|
int h = Size.Height;
|
|
|
|
if (w != _background.Width || h != _background.Height)
|
|
{
|
|
_background.Dispose();
|
|
_background = new Bitmap(w, h, PixelFormat.Format32bppPArgb);
|
|
|
|
using (Graphics graphics = Graphics.FromImage(_background))
|
|
{
|
|
DrawImageWidthBorder(graphics, w, h, _back, TopBorder, BottomBorder,LeftBorder, RightBorder);
|
|
|
|
if (_fore != null)
|
|
DrawImageWidthBorder(graphics, w, h, _fore, TopBorder, BottomBorder, LeftBorder, RightBorder);
|
|
|
|
if (_image != null)
|
|
{
|
|
int width = w - LeftBorder - RightBorder;
|
|
int height = h - TopBorder - BottomBorder;
|
|
float xRatio = width / (float)_image.Width;
|
|
float yRatio = height / (float)_image.Height;
|
|
float destWidth, destHeight;
|
|
float xOffset, yOffset;
|
|
|
|
if (xRatio < yRatio)
|
|
{
|
|
destWidth = width;
|
|
destHeight = _image.Height * xRatio;
|
|
xOffset = 0;
|
|
yOffset = 0.5f * (height - destHeight);
|
|
}
|
|
else
|
|
{
|
|
destWidth = _image.Width * yRatio;
|
|
destHeight = height;
|
|
xOffset = 0.5f * (width - destWidth);
|
|
yOffset = 0;
|
|
}
|
|
|
|
graphics.DrawImage(_image, new RectangleF(LeftBorder + xOffset, TopBorder + yOffset, destWidth, destHeight));
|
|
}
|
|
}
|
|
}
|
|
|
|
g.DrawImageUnscaled(_background, 0, 0);
|
|
}
|
|
|
|
private void DrawProgress(Graphics g, float x, float y, float width, float height, float progress)
|
|
{
|
|
g.DrawImage(_barBack,
|
|
new RectangleF(x + width * progress, y, width * (1 - progress), height),
|
|
new RectangleF(_barBack.Width * progress, 0, (1 - progress) * _barBack.Width, _barBack.Height),
|
|
GraphicsUnit.Pixel);
|
|
g.DrawImage(_barFore,
|
|
new RectangleF(x, y, width * progress, height),
|
|
new RectangleF(0, 0, progress * _barFore.Width, _barFore.Height), GraphicsUnit.Pixel);
|
|
}
|
|
|
|
protected override void OnPaint(PaintEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
Graphics g = e.Graphics;
|
|
int w = Size.Width;
|
|
|
|
g.Clear(Color.Transparent);
|
|
DrawBackground(g);
|
|
|
|
int x;
|
|
int y = _topMargin;
|
|
|
|
if (_sensors.Count == 0)
|
|
{
|
|
x = LeftBorder + 1;
|
|
g.DrawString("Right-click on a sensor in the main window and select " +
|
|
"\"Show in Gadget\" to show the sensor here.",
|
|
_smallFont, _textBrush,
|
|
new Rectangle(x, y - 1, w - RightBorder - x, 0));
|
|
}
|
|
|
|
foreach (KeyValuePair<IHardware, IList<ISensor>> pair in _sensors)
|
|
{
|
|
if (_hardwareNames.Value)
|
|
{
|
|
if (y > _topMargin)
|
|
y += _hardwareLineHeight - _sensorLineHeight;
|
|
|
|
x = LeftBorder + 1;
|
|
g.DrawImage(HardwareTypeImage.Instance.GetImage(pair.Key.HardwareType), new Rectangle(x, y + 1, _iconSize, _iconSize));
|
|
x += _iconSize + 1;
|
|
g.DrawString(pair.Key.Name, _largeFont, _textBrush, new Rectangle(x, y - 1, w - RightBorder - x, 0), _stringFormat);
|
|
y += _hardwareLineHeight;
|
|
}
|
|
|
|
foreach (ISensor sensor in pair.Value)
|
|
{
|
|
int remainingWidth;
|
|
|
|
if ((sensor.SensorType != SensorType.Load &&
|
|
sensor.SensorType != SensorType.Control &&
|
|
sensor.SensorType != SensorType.Level &&
|
|
sensor.SensorType != SensorType.Humidity) || !sensor.Value.HasValue)
|
|
{
|
|
string formatted;
|
|
|
|
if (sensor.Value.HasValue)
|
|
{
|
|
string format = "";
|
|
switch (sensor.SensorType)
|
|
{
|
|
case SensorType.Voltage:
|
|
format = "{0:F3} V";
|
|
break;
|
|
case SensorType.Current:
|
|
format = "{0:F3} A";
|
|
break;
|
|
case SensorType.Clock:
|
|
format = "{0:F0} MHz";
|
|
break;
|
|
case SensorType.Frequency:
|
|
format = "{0:F0} Hz";
|
|
break;
|
|
case SensorType.Temperature:
|
|
format = "{0:F1} °C";
|
|
break;
|
|
case SensorType.Fan:
|
|
format = "{0:F0} RPM";
|
|
break;
|
|
case SensorType.Flow:
|
|
format = "{0:F0} L/h";
|
|
break;
|
|
case SensorType.Power:
|
|
format = "{0:F1} W";
|
|
break;
|
|
case SensorType.Data:
|
|
format = "{0:F1} GB";
|
|
break;
|
|
case SensorType.SmallData:
|
|
format = "{0:F0} MB";
|
|
break;
|
|
case SensorType.Factor:
|
|
format = "{0:F3}";
|
|
break;
|
|
case SensorType.TimeSpan:
|
|
format = "{0:g}";
|
|
break;
|
|
case SensorType.Timing:
|
|
format = "{0:F3} ns";
|
|
break;
|
|
case SensorType.Energy:
|
|
format = "{0:F0} mWh";
|
|
break;
|
|
case SensorType.Noise:
|
|
format = "{0:F0} dBA";
|
|
break;
|
|
case SensorType.Conductivity:
|
|
format = "{0:F1} µS/cm";
|
|
break;
|
|
}
|
|
|
|
if (sensor.SensorType == SensorType.Temperature && _unitManager.TemperatureUnit == TemperatureUnit.Fahrenheit)
|
|
{
|
|
formatted = $"{UnitManager.CelsiusToFahrenheit(sensor.Value):F1} °F";
|
|
}
|
|
else if (sensor.SensorType == SensorType.Throughput)
|
|
{
|
|
string result;
|
|
switch (sensor.Name)
|
|
{
|
|
case "Connection Speed":
|
|
{
|
|
switch (sensor.Value)
|
|
{
|
|
case 100000000:
|
|
result = "100Mbps";
|
|
break;
|
|
case 1000000000:
|
|
result = "1Gbps";
|
|
break;
|
|
default:
|
|
{
|
|
if (sensor.Value < 1024)
|
|
result = $"{sensor.Value:F0} bps";
|
|
else if (sensor.Value < 1048576)
|
|
result = $"{sensor.Value / 1024:F1} Kbps";
|
|
else if (sensor.Value < 1073741824)
|
|
result = $"{sensor.Value / 1048576:F1} Mbps";
|
|
else
|
|
result = $"{sensor.Value / 1073741824:F1} Gbps";
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
if (sensor.Value < 1048576)
|
|
result = $"{sensor.Value / 1024:F1} KB/s";
|
|
else
|
|
result = $"{sensor.Value / 1048576:F1} MB/s";
|
|
}
|
|
break;
|
|
}
|
|
formatted = result;
|
|
}
|
|
else if (sensor.SensorType == SensorType.TimeSpan)
|
|
{
|
|
formatted = string.Format(format, TimeSpan.FromSeconds(sensor.Value.Value));
|
|
}
|
|
else
|
|
{
|
|
formatted = string.Format(format, sensor.Value);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
formatted = "-";
|
|
}
|
|
|
|
g.DrawString(formatted, _smallFont, _textBrush, new RectangleF(-1, y - 1, w - _rightMargin + 3, 0), _alignRightStringFormat);
|
|
|
|
remainingWidth = w - (int)Math.Floor(g.MeasureString(formatted, _smallFont, w, StringFormat.GenericTypographic).Width) - _rightMargin;
|
|
}
|
|
else
|
|
{
|
|
DrawProgress(g, w - _progressWidth - _rightMargin, y + 0.35f * _sensorLineHeight, _progressWidth, 0.6f * _sensorLineHeight, 0.01f * sensor.Value.Value);
|
|
remainingWidth = w - _progressWidth - _rightMargin;
|
|
}
|
|
|
|
remainingWidth -= _leftMargin + 2;
|
|
if (remainingWidth > 0)
|
|
{
|
|
g.DrawString(sensor.Name, _smallFont, _textBrush, new RectangleF(_leftMargin - 1, y - 1, remainingWidth, 0), _trimStringFormat);
|
|
}
|
|
y += _sensorLineHeight;
|
|
}
|
|
}
|
|
}
|
|
catch (ArgumentException)
|
|
{
|
|
// #1425.
|
|
}
|
|
}
|
|
|
|
private class HardwareComparer : IComparer<IHardware>
|
|
{
|
|
public int Compare(IHardware x, IHardware y)
|
|
{
|
|
switch (x)
|
|
{
|
|
case null when y == null:
|
|
return 0;
|
|
case null:
|
|
return -1;
|
|
}
|
|
|
|
if (y == null)
|
|
return 1;
|
|
|
|
if (x.HardwareType != y.HardwareType)
|
|
return x.HardwareType.CompareTo(y.HardwareType);
|
|
|
|
return x.Identifier.CompareTo(y.Identifier);
|
|
}
|
|
}
|
|
}
|