GUI/SensorFrontView.cs
author StephaneLenclud
Mon, 04 Feb 2013 00:47:01 +0100
branchMiniDisplay
changeset 435 9ffcd8ed8537
child 438 f590956d3234
permissions -rw-r--r--
Now calling display init. Not getting the expected error code though.
StephaneLenclud@433
     1
/*
StephaneLenclud@433
     2
 
StephaneLenclud@433
     3
  This Source Code Form is subject to the terms of the Mozilla Public
StephaneLenclud@433
     4
  License, v. 2.0. If a copy of the MPL was not distributed with this
StephaneLenclud@433
     5
  file, You can obtain one at http://mozilla.org/MPL/2.0/.
StephaneLenclud@433
     6
 
StephaneLenclud@433
     7
  Copyright (C) 2009-2012 Michael Möller <mmoeller@openhardwaremonitor.org>
StephaneLenclud@433
     8
	
StephaneLenclud@433
     9
*/
StephaneLenclud@433
    10
StephaneLenclud@433
    11
using System;
StephaneLenclud@433
    12
using System.Drawing;
StephaneLenclud@433
    13
using System.Drawing.Drawing2D;
StephaneLenclud@433
    14
using System.Drawing.Imaging;
StephaneLenclud@433
    15
using System.Drawing.Text;
StephaneLenclud@433
    16
using System.Runtime.InteropServices;
StephaneLenclud@433
    17
using System.Windows.Forms;
StephaneLenclud@433
    18
using OpenHardwareMonitor.Hardware;
StephaneLenclud@433
    19
using OpenHardwareMonitor.Utilities;
StephaneLenclud@433
    20
StephaneLenclud@433
    21
namespace OpenHardwareMonitor.GUI
StephaneLenclud@433
    22
{
StephaneLenclud@433
    23
    public class SensorFrontView : IDisposable
StephaneLenclud@433
    24
    {
StephaneLenclud@433
    25
StephaneLenclud@433
    26
        private UnitManager unitManager;
StephaneLenclud@433
    27
StephaneLenclud@433
    28
        private ISensor sensor;
StephaneLenclud@433
    29
        private Bitmap bitmap;
StephaneLenclud@433
    30
        private Graphics graphics;
StephaneLenclud@433
    31
        private Color color;
StephaneLenclud@433
    32
        private Color darkColor;
StephaneLenclud@433
    33
        private Brush brush;
StephaneLenclud@433
    34
        private Brush darkBrush;
StephaneLenclud@433
    35
        private Pen pen;
StephaneLenclud@433
    36
        private Font font;
StephaneLenclud@433
    37
        private Font smallFont;
StephaneLenclud@433
    38
StephaneLenclud@433
    39
        public SensorFrontView(SoundGraphDisplay soundGraphDisplay, ISensor sensor,
StephaneLenclud@433
    40
          bool balloonTip, PersistentSettings settings, UnitManager unitManager)
StephaneLenclud@433
    41
        {
StephaneLenclud@433
    42
            this.unitManager = unitManager;
StephaneLenclud@433
    43
            this.sensor = sensor;
StephaneLenclud@433
    44
       
StephaneLenclud@433
    45
            // get the default dpi to create an icon with the correct size
StephaneLenclud@433
    46
            float dpiX, dpiY;
StephaneLenclud@433
    47
            using (Bitmap b = new Bitmap(1, 1, PixelFormat.Format32bppArgb))
StephaneLenclud@433
    48
            {
StephaneLenclud@433
    49
                dpiX = b.HorizontalResolution;
StephaneLenclud@433
    50
                dpiY = b.VerticalResolution;
StephaneLenclud@433
    51
            }
StephaneLenclud@433
    52
StephaneLenclud@433
    53
            // adjust the size of the icon to current dpi (default is 16x16 at 96 dpi) 
StephaneLenclud@433
    54
            int width = (int)Math.Round(16 * dpiX / 96);
StephaneLenclud@433
    55
            int height = (int)Math.Round(16 * dpiY / 96);
StephaneLenclud@433
    56
StephaneLenclud@433
    57
            // make sure it does never get smaller than 16x16
StephaneLenclud@433
    58
            width = width < 16 ? 16 : width;
StephaneLenclud@433
    59
            height = height < 16 ? 16 : height;
StephaneLenclud@433
    60
StephaneLenclud@433
    61
            // adjust the font size to the icon size
StephaneLenclud@433
    62
            FontFamily family = SystemFonts.MessageBoxFont.FontFamily;
StephaneLenclud@433
    63
            float baseSize;
StephaneLenclud@433
    64
            switch (family.Name)
StephaneLenclud@433
    65
            {
StephaneLenclud@433
    66
                case "Segoe UI": baseSize = 12; break;
StephaneLenclud@433
    67
                case "Tahoma": baseSize = 11; break;
StephaneLenclud@433
    68
                default: baseSize = 12; break;
StephaneLenclud@433
    69
            }
StephaneLenclud@433
    70
StephaneLenclud@433
    71
            this.font = new Font(family,
StephaneLenclud@433
    72
              baseSize * width / 16.0f, GraphicsUnit.Pixel);
StephaneLenclud@433
    73
            this.smallFont = new Font(family,
StephaneLenclud@433
    74
              0.75f * baseSize * width / 16.0f, GraphicsUnit.Pixel);
StephaneLenclud@433
    75
StephaneLenclud@433
    76
            this.bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
StephaneLenclud@433
    77
            this.graphics = Graphics.FromImage(this.bitmap);
StephaneLenclud@433
    78
StephaneLenclud@433
    79
            if (Environment.OSVersion.Version.Major > 5)
StephaneLenclud@433
    80
            {
StephaneLenclud@433
    81
                this.graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
StephaneLenclud@433
    82
                this.graphics.SmoothingMode = SmoothingMode.HighQuality;
StephaneLenclud@433
    83
            }
StephaneLenclud@433
    84
        }
StephaneLenclud@433
    85
StephaneLenclud@433
    86
        public ISensor Sensor
StephaneLenclud@433
    87
        {
StephaneLenclud@433
    88
            get { return sensor; }
StephaneLenclud@433
    89
        }
StephaneLenclud@433
    90
StephaneLenclud@433
    91
        public Color Color
StephaneLenclud@433
    92
        {
StephaneLenclud@433
    93
            get { return color; }
StephaneLenclud@433
    94
            set
StephaneLenclud@433
    95
            {
StephaneLenclud@433
    96
                this.color = value;
StephaneLenclud@433
    97
                this.darkColor = Color.FromArgb(255,
StephaneLenclud@433
    98
                  this.color.R / 3,
StephaneLenclud@433
    99
                  this.color.G / 3,
StephaneLenclud@433
   100
                  this.color.B / 3);
StephaneLenclud@433
   101
                Brush brush = this.brush;
StephaneLenclud@433
   102
                this.brush = new SolidBrush(this.color);
StephaneLenclud@433
   103
                if (brush != null)
StephaneLenclud@433
   104
                    brush.Dispose();
StephaneLenclud@433
   105
                Brush darkBrush = this.darkBrush;
StephaneLenclud@433
   106
                this.darkBrush = new SolidBrush(this.darkColor);
StephaneLenclud@433
   107
                if (darkBrush != null)
StephaneLenclud@433
   108
                    darkBrush.Dispose();
StephaneLenclud@433
   109
            }
StephaneLenclud@433
   110
        }
StephaneLenclud@433
   111
StephaneLenclud@433
   112
        public void Dispose()
StephaneLenclud@433
   113
        {
StephaneLenclud@433
   114
StephaneLenclud@433
   115
            if (brush != null)
StephaneLenclud@433
   116
                brush.Dispose();
StephaneLenclud@433
   117
            if (darkBrush != null)
StephaneLenclud@433
   118
                darkBrush.Dispose();
StephaneLenclud@433
   119
            pen.Dispose();
StephaneLenclud@433
   120
            graphics.Dispose();
StephaneLenclud@433
   121
            bitmap.Dispose();
StephaneLenclud@433
   122
            font.Dispose();
StephaneLenclud@433
   123
            smallFont.Dispose();
StephaneLenclud@433
   124
        }
StephaneLenclud@433
   125
StephaneLenclud@433
   126
        private string GetString()
StephaneLenclud@433
   127
        {
StephaneLenclud@433
   128
            if (!sensor.Value.HasValue)
StephaneLenclud@433
   129
                return "-";
StephaneLenclud@433
   130
StephaneLenclud@433
   131
            switch (sensor.SensorType)
StephaneLenclud@433
   132
            {
StephaneLenclud@433
   133
                case SensorType.Voltage:
StephaneLenclud@433
   134
                    return string.Format("{0:F1}", sensor.Value);
StephaneLenclud@433
   135
                case SensorType.Clock:
StephaneLenclud@433
   136
                    return string.Format("{0:F1}", 1e-3f * sensor.Value);
StephaneLenclud@433
   137
                case SensorType.Load:
StephaneLenclud@433
   138
                    return string.Format("{0:F0}", sensor.Value);
StephaneLenclud@433
   139
                case SensorType.Temperature:
StephaneLenclud@433
   140
                    if (unitManager.TemperatureUnit == TemperatureUnit.Fahrenheit)
StephaneLenclud@433
   141
                        return string.Format("{0:F0}",
StephaneLenclud@433
   142
                          UnitManager.CelsiusToFahrenheit(sensor.Value));
StephaneLenclud@433
   143
                    else
StephaneLenclud@433
   144
                        return string.Format("{0:F0}", sensor.Value);
StephaneLenclud@433
   145
                case SensorType.Fan:
StephaneLenclud@433
   146
                    return string.Format("{0:F1}", 1e-3f * sensor.Value);
StephaneLenclud@433
   147
                case SensorType.Flow:
StephaneLenclud@433
   148
                    return string.Format("{0:F1}", 1e-3f * sensor.Value);
StephaneLenclud@433
   149
                case SensorType.Control:
StephaneLenclud@433
   150
                    return string.Format("{0:F0}", sensor.Value);
StephaneLenclud@433
   151
                case SensorType.Level:
StephaneLenclud@433
   152
                    return string.Format("{0:F0}", sensor.Value);
StephaneLenclud@433
   153
                case SensorType.Power:
StephaneLenclud@433
   154
                    return string.Format("{0:F0}", sensor.Value);
StephaneLenclud@433
   155
                case SensorType.Data:
StephaneLenclud@433
   156
                    return string.Format("{0:F0}", sensor.Value);
StephaneLenclud@433
   157
                case SensorType.Factor:
StephaneLenclud@433
   158
                    return string.Format("{0:F1}", sensor.Value);
StephaneLenclud@433
   159
            }
StephaneLenclud@433
   160
            return "-";
StephaneLenclud@433
   161
        }
StephaneLenclud@433
   162
StephaneLenclud@433
   163
        private Icon CreateTransparentIcon()
StephaneLenclud@433
   164
        {
StephaneLenclud@433
   165
            string text = GetString();
StephaneLenclud@433
   166
            int count = 0;
StephaneLenclud@433
   167
            for (int i = 0; i < text.Length; i++)
StephaneLenclud@433
   168
                if ((text[i] >= '0' && text[i] <= '9') || text[i] == '-')
StephaneLenclud@433
   169
                    count++;
StephaneLenclud@433
   170
            bool small = count > 2;
StephaneLenclud@433
   171
StephaneLenclud@433
   172
            graphics.Clear(Color.Black);
StephaneLenclud@433
   173
            TextRenderer.DrawText(graphics, text, small ? smallFont : font,
StephaneLenclud@433
   174
              new Point(-2, small ? 1 : 0), Color.White, Color.Black);
StephaneLenclud@433
   175
StephaneLenclud@433
   176
            BitmapData data = bitmap.LockBits(
StephaneLenclud@433
   177
              new Rectangle(0, 0, bitmap.Width, bitmap.Height),
StephaneLenclud@433
   178
              ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
StephaneLenclud@433
   179
StephaneLenclud@433
   180
            IntPtr Scan0 = data.Scan0;
StephaneLenclud@433
   181
StephaneLenclud@433
   182
            int numBytes = bitmap.Width * bitmap.Height * 4;
StephaneLenclud@433
   183
            byte[] bytes = new byte[numBytes];
StephaneLenclud@433
   184
            Marshal.Copy(Scan0, bytes, 0, numBytes);
StephaneLenclud@433
   185
            bitmap.UnlockBits(data);
StephaneLenclud@433
   186
StephaneLenclud@433
   187
            byte red, green, blue;
StephaneLenclud@433
   188
            for (int i = 0; i < bytes.Length; i += 4)
StephaneLenclud@433
   189
            {
StephaneLenclud@433
   190
                blue = bytes[i];
StephaneLenclud@433
   191
                green = bytes[i + 1];
StephaneLenclud@433
   192
                red = bytes[i + 2];
StephaneLenclud@433
   193
StephaneLenclud@433
   194
                bytes[i] = color.B;
StephaneLenclud@433
   195
                bytes[i + 1] = color.G;
StephaneLenclud@433
   196
                bytes[i + 2] = color.R;
StephaneLenclud@433
   197
                bytes[i + 3] = (byte)(0.3 * red + 0.59 * green + 0.11 * blue);
StephaneLenclud@433
   198
            }
StephaneLenclud@433
   199
StephaneLenclud@433
   200
            return IconFactory.Create(bytes, bitmap.Width, bitmap.Height,
StephaneLenclud@433
   201
              PixelFormat.Format32bppArgb);
StephaneLenclud@433
   202
        }
StephaneLenclud@433
   203
StephaneLenclud@433
   204
        private Icon CreatePercentageIcon()
StephaneLenclud@433
   205
        {
StephaneLenclud@433
   206
            try
StephaneLenclud@433
   207
            {
StephaneLenclud@433
   208
                graphics.Clear(Color.Transparent);
StephaneLenclud@433
   209
            }
StephaneLenclud@433
   210
            catch (ArgumentException)
StephaneLenclud@433
   211
            {
StephaneLenclud@433
   212
                graphics.Clear(Color.Black);
StephaneLenclud@433
   213
            }
StephaneLenclud@433
   214
            graphics.FillRectangle(darkBrush, 0.5f, -0.5f, bitmap.Width - 2, bitmap.Height);
StephaneLenclud@433
   215
            float value = sensor.Value.GetValueOrDefault();
StephaneLenclud@433
   216
            float y = 0.16f * (100 - value);
StephaneLenclud@433
   217
            graphics.FillRectangle(brush, 0.5f, -0.5f + y, bitmap.Width - 2, bitmap.Height - y);
StephaneLenclud@433
   218
            graphics.DrawRectangle(pen, 1, 0, bitmap.Width - 3, bitmap.Height - 1);
StephaneLenclud@433
   219
StephaneLenclud@433
   220
            BitmapData data = bitmap.LockBits(
StephaneLenclud@433
   221
              new Rectangle(0, 0, bitmap.Width, bitmap.Height),
StephaneLenclud@433
   222
              ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
StephaneLenclud@433
   223
            byte[] bytes = new byte[bitmap.Width * bitmap.Height * 4];
StephaneLenclud@433
   224
            Marshal.Copy(data.Scan0, bytes, 0, bytes.Length);
StephaneLenclud@433
   225
            bitmap.UnlockBits(data);
StephaneLenclud@433
   226
StephaneLenclud@433
   227
            return IconFactory.Create(bytes, bitmap.Width, bitmap.Height,
StephaneLenclud@433
   228
              PixelFormat.Format32bppArgb);
StephaneLenclud@433
   229
        }
StephaneLenclud@433
   230
StephaneLenclud@433
   231
        public void Update()
StephaneLenclud@433
   232
        {
StephaneLenclud@433
   233
 
StephaneLenclud@433
   234
StephaneLenclud@433
   235
            switch (sensor.SensorType)
StephaneLenclud@433
   236
            {
StephaneLenclud@433
   237
                case SensorType.Load:
StephaneLenclud@433
   238
                case SensorType.Control:
StephaneLenclud@433
   239
                case SensorType.Level:
StephaneLenclud@433
   240
                    //notifyIcon.Icon = CreatePercentageIcon();
StephaneLenclud@433
   241
                    break;
StephaneLenclud@433
   242
                default:
StephaneLenclud@433
   243
                    //notifyIcon.Icon = CreateTransparentIcon();
StephaneLenclud@433
   244
                    break;
StephaneLenclud@433
   245
            }
StephaneLenclud@433
   246
StephaneLenclud@433
   247
StephaneLenclud@433
   248
            string format = "";
StephaneLenclud@433
   249
            switch (sensor.SensorType)
StephaneLenclud@433
   250
            {
StephaneLenclud@433
   251
                case SensorType.Voltage: format = "\n{0}: {1:F2} V"; break;
StephaneLenclud@433
   252
                case SensorType.Clock: format = "\n{0}: {1:F0} MHz"; break;
StephaneLenclud@433
   253
                case SensorType.Load: format = "\n{0}: {1:F1} %"; break;
StephaneLenclud@433
   254
                case SensorType.Temperature: format = "\n{0}: {1:F1} °C"; break;
StephaneLenclud@433
   255
                case SensorType.Fan: format = "\n{0}: {1:F0} RPM"; break;
StephaneLenclud@433
   256
                case SensorType.Flow: format = "\n{0}: {1:F0} L/h"; break;
StephaneLenclud@433
   257
                case SensorType.Control: format = "\n{0}: {1:F1} %"; break;
StephaneLenclud@433
   258
                case SensorType.Level: format = "\n{0}: {1:F1} %"; break;
StephaneLenclud@433
   259
                case SensorType.Power: format = "\n{0}: {1:F0} W"; break;
StephaneLenclud@433
   260
                case SensorType.Data: format = "\n{0}: {1:F0} GB"; break;
StephaneLenclud@433
   261
                case SensorType.Factor: format = "\n{0}: {1:F3} GB"; break;
StephaneLenclud@433
   262
            }
StephaneLenclud@433
   263
            string formattedValue = string.Format(format, sensor.Name, sensor.Value);
StephaneLenclud@433
   264
StephaneLenclud@433
   265
            if (sensor.SensorType == SensorType.Temperature &&
StephaneLenclud@433
   266
              unitManager.TemperatureUnit == TemperatureUnit.Fahrenheit)
StephaneLenclud@433
   267
            {
StephaneLenclud@433
   268
                format = "\n{0}: {1:F1} °F";
StephaneLenclud@433
   269
                formattedValue = string.Format(format, sensor.Name,
StephaneLenclud@433
   270
                  UnitManager.CelsiusToFahrenheit(sensor.Value));
StephaneLenclud@433
   271
            }
StephaneLenclud@433
   272
StephaneLenclud@433
   273
            string hardwareName = sensor.Hardware.Name;
StephaneLenclud@433
   274
            hardwareName = hardwareName.Substring(0,
StephaneLenclud@433
   275
              Math.Min(63 - formattedValue.Length, hardwareName.Length));
StephaneLenclud@433
   276
            string text = hardwareName + formattedValue;
StephaneLenclud@433
   277
            if (text.Length > 63)
StephaneLenclud@433
   278
                text = null;
StephaneLenclud@433
   279
StephaneLenclud@433
   280
StephaneLenclud@433
   281
        }
StephaneLenclud@433
   282
    }
StephaneLenclud@433
   283
}