GUI/SensorNotifyIcon.cs
author moel.mich
Sat, 15 May 2010 12:50:28 +0000
changeset 117 14329d236f05
parent 116 c92e98bc2073
child 118 407f98562c3b
permissions -rw-r--r--
Fixed some font issues.
     1 /*
     2   
     3   Version: MPL 1.1/GPL 2.0/LGPL 2.1
     4 
     5   The contents of this file are subject to the Mozilla Public License Version
     6   1.1 (the "License"); you may not use this file except in compliance with
     7   the License. You may obtain a copy of the License at
     8  
     9   http://www.mozilla.org/MPL/
    10 
    11   Software distributed under the License is distributed on an "AS IS" basis,
    12   WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    13   for the specific language governing rights and limitations under the License.
    14 
    15   The Original Code is the Open Hardware Monitor code.
    16 
    17   The Initial Developer of the Original Code is 
    18   Michael Möller <m.moeller@gmx.ch>.
    19   Portions created by the Initial Developer are Copyright (C) 2009-2010
    20   the Initial Developer. All Rights Reserved.
    21 
    22   Contributor(s):
    23 
    24   Alternatively, the contents of this file may be used under the terms of
    25   either the GNU General Public License Version 2 or later (the "GPL"), or
    26   the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    27   in which case the provisions of the GPL or the LGPL are applicable instead
    28   of those above. If you wish to allow use of your version of this file only
    29   under the terms of either the GPL or the LGPL, and not to allow others to
    30   use your version of this file under the terms of the MPL, indicate your
    31   decision by deleting the provisions above and replace them with the notice
    32   and other provisions required by the GPL or the LGPL. If you do not delete
    33   the provisions above, a recipient may use your version of this file under
    34   the terms of any one of the MPL, the GPL or the LGPL.
    35  
    36 */
    37 
    38 using System;
    39 using System.Collections.Generic;
    40 using System.Drawing;
    41 using System.Drawing.Drawing2D;
    42 using System.Drawing.Imaging;
    43 using System.Drawing.Text;
    44 using System.Text;
    45 using System.Windows.Forms;
    46 using System.Runtime.InteropServices;
    47 using OpenHardwareMonitor.Hardware;
    48 using OpenHardwareMonitor.Utilities;
    49 
    50 namespace OpenHardwareMonitor.GUI {
    51   public class SensorNotifyIcon : IDisposable {
    52 
    53     private ISensor sensor;
    54     private NotifyIcon notifyIcon;
    55     private Bitmap bitmap;
    56     private Graphics graphics;
    57     private Color color;
    58     private Color darkColor;
    59     private Brush brush;
    60     private Brush darkBrush;
    61     private Pen pen;
    62     private Font font;
    63 
    64     public SensorNotifyIcon(SensorSystemTray sensorSystemTray, ISensor sensor,
    65       bool balloonTip) 
    66     {
    67       this.sensor = sensor;
    68       this.notifyIcon = new NotifyIcon();
    69 
    70       Color defaultColor = Color.Black;
    71       if (sensor.SensorType == SensorType.Load) {
    72         defaultColor = Color.FromArgb(0xff, 0x70, 0x8c, 0xf1);
    73       }
    74       Color = Config.Get(new Identifier(sensor.Identifier, 
    75         "traycolor").ToString(), defaultColor);      
    76       
    77       this.pen = new Pen(Color.FromArgb(96, Color.Black));
    78       this.font = SystemFonts.MessageBoxFont;
    79 
    80       ContextMenuStrip contextMenuStrip = new ContextMenuStrip();
    81       ToolStripMenuItem removeItem = new ToolStripMenuItem("Remove");
    82       removeItem.Click += delegate(object obj, EventArgs args) {
    83         sensorSystemTray.Remove(this.sensor);
    84       };
    85       contextMenuStrip.Items.Add(removeItem);
    86       ToolStripMenuItem colorItem = new ToolStripMenuItem("Change Color...");
    87       colorItem.Click += delegate(object obj, EventArgs args) {
    88         ColorDialog dialog = new ColorDialog();
    89         dialog.Color = Color;
    90         if (dialog.ShowDialog() == DialogResult.OK) {
    91           Color = dialog.Color;
    92           Config.Set(new Identifier(sensor.Identifier,
    93             "traycolor").ToString(), Color);
    94         }
    95       };
    96       contextMenuStrip.Items.Add(colorItem);
    97       this.notifyIcon.ContextMenuStrip = contextMenuStrip;
    98 
    99       this.bitmap = new Bitmap(16, 16, PixelFormat.Format32bppArgb);
   100       this.graphics = Graphics.FromImage(this.bitmap);
   101 
   102       if (Environment.OSVersion.Version.Major > 5) {
   103         this.graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
   104         this.graphics.SmoothingMode = SmoothingMode.HighQuality;
   105       }
   106     }
   107 
   108     public ISensor Sensor {
   109       get { return sensor; }
   110     }
   111 
   112     public Color Color {
   113       get { return color; }
   114       set { 
   115         this.color = value;
   116         this.darkColor = Color.FromArgb(255,
   117           this.color.R / 3,
   118           this.color.G / 3,
   119           this.color.B / 3);
   120         Brush brush = this.brush;
   121         this.brush = new SolidBrush(this.color);
   122         if (brush != null)
   123           brush.Dispose();
   124         Brush darkBrush = this.darkBrush;
   125         this.darkBrush = new SolidBrush(this.darkColor);
   126         if (darkBrush != null)
   127           darkBrush.Dispose();
   128       }
   129     }
   130 
   131     public void Dispose() {      
   132       Icon icon = notifyIcon.Icon;
   133       notifyIcon.Icon = null;
   134       if (icon != null)
   135         icon.Dispose();      
   136       notifyIcon.Dispose();
   137 
   138       if (brush != null)
   139         brush.Dispose();
   140       if (darkBrush != null)
   141         darkBrush.Dispose();
   142       pen.Dispose();
   143       graphics.Dispose();      
   144       bitmap.Dispose();      
   145     }
   146 
   147     private string GetString() {
   148       switch (sensor.SensorType) {
   149         case SensorType.Voltage:
   150           return string.Format("{0:F11}", sensor.Value);
   151         case SensorType.Clock:
   152           return string.Format("{0:F11}", 1e-3f * sensor.Value);
   153         case SensorType.Load: 
   154           return string.Format("{0:F0}", sensor.Value < 99 ? sensor.Value : 99);
   155         case SensorType.Temperature: 
   156           return string.Format("{0:F0}", sensor.Value);
   157         case SensorType.Fan: 
   158           return string.Format("{0:F11}", 1e-3f * sensor.Value);
   159         case SensorType.Flow:
   160           return string.Format("{0:F11}", 1e-3f * sensor.Value);
   161       }
   162       return "-";
   163     }
   164 
   165     private Icon CreateTransparentIcon() {
   166 
   167       graphics.Clear(Color.Black);
   168       TextRenderer.DrawText(graphics, GetString(), font,
   169         new Point(-2, 0), Color.White, Color.Black);        
   170 
   171       BitmapData data = bitmap.LockBits(
   172         new Rectangle(0, 0, bitmap.Width, bitmap.Height),
   173         ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
   174 
   175       int stride = data.Stride;
   176       IntPtr Scan0 = data.Scan0;
   177 
   178       int numBytes = bitmap.Width * bitmap.Height * 4;
   179       byte[] bytes = new byte[numBytes];
   180       Marshal.Copy(Scan0, bytes, 0, numBytes);
   181       bitmap.UnlockBits(data);
   182 
   183       byte red, green, blue;
   184       for (int i = 0; i < bytes.Length; i += 4) {
   185         blue = bytes[i];
   186         green = bytes[i + 1];
   187         red = bytes[i + 2];
   188 
   189         bytes[i] = color.B;
   190         bytes[i + 1] = color.G;
   191         bytes[i + 2] = color.R;
   192         bytes[i + 3] = (byte)(0.3 * red + 0.59 * green + 0.11 * blue);
   193       }
   194 
   195       return IconFactory.Create(bytes, 16, 16, PixelFormat.Format32bppArgb);
   196     }
   197 
   198     private Icon CreateLoadIcon() {      
   199       try {
   200         graphics.Clear(Color.Transparent);
   201       } catch (ArgumentException) {
   202         graphics.Clear(Color.Black);
   203       }
   204       graphics.FillRectangle(darkBrush, 0.5f, -0.5f, 14, 16);
   205       float y = 0.16f * (100 - sensor.Value.Value);
   206       graphics.FillRectangle(brush, 0.5f, -0.5f + y, 14, 16 - y);
   207       graphics.DrawRectangle(pen, 1, 0, 13, 15);
   208 
   209       BitmapData data = bitmap.LockBits(
   210         new Rectangle(0, 0, bitmap.Width, bitmap.Height),
   211         ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
   212       byte[] bytes = new byte[bitmap.Width * bitmap.Height * 4];
   213       Marshal.Copy(data.Scan0, bytes, 0, bytes.Length);
   214       bitmap.UnlockBits(data);
   215 
   216       return IconFactory.Create(bytes, 16, 16, PixelFormat.Format32bppArgb);
   217     }
   218 
   219     public void Update() {
   220       Icon icon = notifyIcon.Icon;
   221 
   222       if (sensor.SensorType == SensorType.Load) {
   223         notifyIcon.Icon = CreateLoadIcon();
   224       } else {
   225         notifyIcon.Icon = CreateTransparentIcon();
   226       }
   227       if (icon != null) 
   228         icon.Dispose();
   229 
   230       string format = "";
   231       switch (sensor.SensorType) {
   232         case SensorType.Voltage: format = "\n{0}: {1:F2} V"; break;
   233         case SensorType.Clock: format = "\n{0}: {1:F0} MHz"; break;
   234         case SensorType.Load: format = "\n{0}: {1:F1} %"; break;
   235         case SensorType.Temperature: format = "\n{0}: {1:F1} °C"; break;
   236         case SensorType.Fan: format = "\n{0}: {1:F0} RPM"; break;
   237         case SensorType.Flow: format = "\n{0}: {1:F0} L/h"; break;
   238       }
   239       string formattedValue = string.Format(format, sensor.Name, sensor.Value);
   240       string hardwareName = sensor.Hardware.Name;
   241       hardwareName = hardwareName.Substring(0, 
   242         Math.Min(63 - formattedValue.Length, hardwareName.Length));
   243       string text = hardwareName + formattedValue;
   244       if (text.Length > 63)
   245         text = null;
   246 
   247       notifyIcon.Text = text;
   248       notifyIcon.Visible = true;         
   249     }
   250   }
   251 }