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