GUI/SensorFrontView.cs
author StephaneLenclud
Sun, 03 Feb 2013 19:06:01 +0100
branchMiniDisplay
changeset 434 480652d72031
child 438 f590956d3234
permissions -rw-r--r--
Now fetching some of our Sound Graph DLL function pointers.
     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 }