GUI/SensorFrontView.cs
author StephaneLenclud
Sun, 03 Feb 2013 18:01:50 +0100
branchMiniDisplay
changeset 433 090259cfd699
child 438 f590956d3234
permissions -rw-r--r--
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.
     1 /*
     2  
     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/.
     6  
     7   Copyright (C) 2009-2012 Michael Möller <mmoeller@openhardwaremonitor.org>
     8 	
     9 */
    10 
    11 using System;
    12 using System.Drawing;
    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;
    20 
    21 namespace OpenHardwareMonitor.GUI
    22 {
    23     public class SensorFrontView : IDisposable
    24     {
    25 
    26         private UnitManager unitManager;
    27 
    28         private ISensor sensor;
    29         private Bitmap bitmap;
    30         private Graphics graphics;
    31         private Color color;
    32         private Color darkColor;
    33         private Brush brush;
    34         private Brush darkBrush;
    35         private Pen pen;
    36         private Font font;
    37         private Font smallFont;
    38 
    39         public SensorFrontView(SoundGraphDisplay soundGraphDisplay, ISensor sensor,
    40           bool balloonTip, PersistentSettings settings, UnitManager unitManager)
    41         {
    42             this.unitManager = unitManager;
    43             this.sensor = sensor;
    44        
    45             // get the default dpi to create an icon with the correct size
    46             float dpiX, dpiY;
    47             using (Bitmap b = new Bitmap(1, 1, PixelFormat.Format32bppArgb))
    48             {
    49                 dpiX = b.HorizontalResolution;
    50                 dpiY = b.VerticalResolution;
    51             }
    52 
    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);
    56 
    57             // make sure it does never get smaller than 16x16
    58             width = width < 16 ? 16 : width;
    59             height = height < 16 ? 16 : height;
    60 
    61             // adjust the font size to the icon size
    62             FontFamily family = SystemFonts.MessageBoxFont.FontFamily;
    63             float baseSize;
    64             switch (family.Name)
    65             {
    66                 case "Segoe UI": baseSize = 12; break;
    67                 case "Tahoma": baseSize = 11; break;
    68                 default: baseSize = 12; break;
    69             }
    70 
    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);
    75 
    76             this.bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
    77             this.graphics = Graphics.FromImage(this.bitmap);
    78 
    79             if (Environment.OSVersion.Version.Major > 5)
    80             {
    81                 this.graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
    82                 this.graphics.SmoothingMode = SmoothingMode.HighQuality;
    83             }
    84         }
    85 
    86         public ISensor Sensor
    87         {
    88             get { return sensor; }
    89         }
    90 
    91         public Color Color
    92         {
    93             get { return color; }
    94             set
    95             {
    96                 this.color = value;
    97                 this.darkColor = Color.FromArgb(255,
    98                   this.color.R / 3,
    99                   this.color.G / 3,
   100                   this.color.B / 3);
   101                 Brush brush = this.brush;
   102                 this.brush = new SolidBrush(this.color);
   103                 if (brush != null)
   104                     brush.Dispose();
   105                 Brush darkBrush = this.darkBrush;
   106                 this.darkBrush = new SolidBrush(this.darkColor);
   107                 if (darkBrush != null)
   108                     darkBrush.Dispose();
   109             }
   110         }
   111 
   112         public void Dispose()
   113         {
   114 
   115             if (brush != null)
   116                 brush.Dispose();
   117             if (darkBrush != null)
   118                 darkBrush.Dispose();
   119             pen.Dispose();
   120             graphics.Dispose();
   121             bitmap.Dispose();
   122             font.Dispose();
   123             smallFont.Dispose();
   124         }
   125 
   126         private string GetString()
   127         {
   128             if (!sensor.Value.HasValue)
   129                 return "-";
   130 
   131             switch (sensor.SensorType)
   132             {
   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));
   143                     else
   144                         return string.Format("{0:F0}", sensor.Value);
   145                 case SensorType.Fan:
   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);
   159             }
   160             return "-";
   161         }
   162 
   163         private Icon CreateTransparentIcon()
   164         {
   165             string text = GetString();
   166             int count = 0;
   167             for (int i = 0; i < text.Length; i++)
   168                 if ((text[i] >= '0' && text[i] <= '9') || text[i] == '-')
   169                     count++;
   170             bool small = count > 2;
   171 
   172             graphics.Clear(Color.Black);
   173             TextRenderer.DrawText(graphics, text, small ? smallFont : font,
   174               new Point(-2, small ? 1 : 0), Color.White, Color.Black);
   175 
   176             BitmapData data = bitmap.LockBits(
   177               new Rectangle(0, 0, bitmap.Width, bitmap.Height),
   178               ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
   179 
   180             IntPtr Scan0 = data.Scan0;
   181 
   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);
   186 
   187             byte red, green, blue;
   188             for (int i = 0; i < bytes.Length; i += 4)
   189             {
   190                 blue = bytes[i];
   191                 green = bytes[i + 1];
   192                 red = bytes[i + 2];
   193 
   194                 bytes[i] = color.B;
   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);
   198             }
   199 
   200             return IconFactory.Create(bytes, bitmap.Width, bitmap.Height,
   201               PixelFormat.Format32bppArgb);
   202         }
   203 
   204         private Icon CreatePercentageIcon()
   205         {
   206             try
   207             {
   208                 graphics.Clear(Color.Transparent);
   209             }
   210             catch (ArgumentException)
   211             {
   212                 graphics.Clear(Color.Black);
   213             }
   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);
   219 
   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);
   226 
   227             return IconFactory.Create(bytes, bitmap.Width, bitmap.Height,
   228               PixelFormat.Format32bppArgb);
   229         }
   230 
   231         public void Update()
   232         {
   233  
   234 
   235             switch (sensor.SensorType)
   236             {
   237                 case SensorType.Load:
   238                 case SensorType.Control:
   239                 case SensorType.Level:
   240                     //notifyIcon.Icon = CreatePercentageIcon();
   241                     break;
   242                 default:
   243                     //notifyIcon.Icon = CreateTransparentIcon();
   244                     break;
   245             }
   246 
   247 
   248             string format = "";
   249             switch (sensor.SensorType)
   250             {
   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;
   262             }
   263             string formattedValue = string.Format(format, sensor.Name, sensor.Value);
   264 
   265             if (sensor.SensorType == SensorType.Temperature &&
   266               unitManager.TemperatureUnit == TemperatureUnit.Fahrenheit)
   267             {
   268                 format = "\n{0}: {1:F1} °F";
   269                 formattedValue = string.Format(format, sensor.Name,
   270                   UnitManager.CelsiusToFahrenheit(sensor.Value));
   271             }
   272 
   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)
   278                 text = null;
   279 
   280 
   281         }
   282     }
   283 }