Adding SoundGraphDisplay and SensorFrontView classes. MiniDisplay
authorStephaneLenclud
Sun, 03 Feb 2013 18:01:50 +0100
branchMiniDisplay
changeset 433090259cfd699
parent 432 7b859a06eecb
child 434 480652d72031
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.
GUI/MainForm.cs
GUI/SensorFrontView.cs
GUI/SoundGraphDisplay.cs
OpenHardwareMonitor.csproj
     1.1 --- a/GUI/MainForm.cs	Tue Dec 30 22:49:32 2014 +0000
     1.2 +++ b/GUI/MainForm.cs	Sun Feb 03 18:01:50 2013 +0100
     1.3 @@ -35,7 +35,8 @@
     1.4      private IDictionary<ISensor, Color> sensorPlotColors = 
     1.5        new Dictionary<ISensor, Color>();
     1.6      private Color[] plotColorPalette;
     1.7 -    private SystemTray systemTray;    
     1.8 +    private SystemTray systemTray;
     1.9 +    private SoundGraphDisplay soundGraphDisplay;
    1.10      private StartupManager startupManager = new StartupManager();
    1.11      private UpdateVisitor updateVisitor = new UpdateVisitor();
    1.12      private SensorGadget gadget;
    1.13 @@ -129,6 +130,8 @@
    1.14        systemTray = new SystemTray(computer, settings, unitManager);
    1.15        systemTray.HideShowCommand += hideShowClick;
    1.16        systemTray.ExitCommand += exitClick;
    1.17 +  
    1.18 +      soundGraphDisplay = new SoundGraphDisplay(computer, settings, unitManager); 
    1.19  
    1.20        int p = (int)Environment.OSVersion.Platform;
    1.21        if ((p == 4) || (p == 128)) { // Unix
    1.22 @@ -603,6 +606,7 @@
    1.23        if (runWebServer.Value)
    1.24            server.Quit();
    1.25        systemTray.Dispose();
    1.26 +      soundGraphDisplay.Dispose();
    1.27      }
    1.28  
    1.29      private void aboutMenuItem_Click(object sender, EventArgs e) {
    1.30 @@ -662,6 +666,18 @@
    1.31              };
    1.32              treeContextMenu.MenuItems.Add(item);
    1.33            }
    1.34 +          {
    1.35 +              MenuItem item = new MenuItem("Show in iMON FrontView");
    1.36 +              item.Checked = systemTray.Contains(node.Sensor);
    1.37 +              item.Click += delegate(object obj, EventArgs args)
    1.38 +              {
    1.39 +                  if (item.Checked)
    1.40 +                      soundGraphDisplay.Remove(node.Sensor);
    1.41 +                  else
    1.42 +                      soundGraphDisplay.Add(node.Sensor, true);
    1.43 +              };
    1.44 +              treeContextMenu.MenuItems.Add(item);
    1.45 +          }
    1.46            if (gadget != null) {
    1.47              MenuItem item = new MenuItem("Show in Gadget");
    1.48              item.Checked = gadget.Contains(node.Sensor);
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/GUI/SensorFrontView.cs	Sun Feb 03 18:01:50 2013 +0100
     2.3 @@ -0,0 +1,283 @@
     2.4 +/*
     2.5 + 
     2.6 +  This Source Code Form is subject to the terms of the Mozilla Public
     2.7 +  License, v. 2.0. If a copy of the MPL was not distributed with this
     2.8 +  file, You can obtain one at http://mozilla.org/MPL/2.0/.
     2.9 + 
    2.10 +  Copyright (C) 2009-2012 Michael Möller <mmoeller@openhardwaremonitor.org>
    2.11 +	
    2.12 +*/
    2.13 +
    2.14 +using System;
    2.15 +using System.Drawing;
    2.16 +using System.Drawing.Drawing2D;
    2.17 +using System.Drawing.Imaging;
    2.18 +using System.Drawing.Text;
    2.19 +using System.Runtime.InteropServices;
    2.20 +using System.Windows.Forms;
    2.21 +using OpenHardwareMonitor.Hardware;
    2.22 +using OpenHardwareMonitor.Utilities;
    2.23 +
    2.24 +namespace OpenHardwareMonitor.GUI
    2.25 +{
    2.26 +    public class SensorFrontView : IDisposable
    2.27 +    {
    2.28 +
    2.29 +        private UnitManager unitManager;
    2.30 +
    2.31 +        private ISensor sensor;
    2.32 +        private Bitmap bitmap;
    2.33 +        private Graphics graphics;
    2.34 +        private Color color;
    2.35 +        private Color darkColor;
    2.36 +        private Brush brush;
    2.37 +        private Brush darkBrush;
    2.38 +        private Pen pen;
    2.39 +        private Font font;
    2.40 +        private Font smallFont;
    2.41 +
    2.42 +        public SensorFrontView(SoundGraphDisplay soundGraphDisplay, ISensor sensor,
    2.43 +          bool balloonTip, PersistentSettings settings, UnitManager unitManager)
    2.44 +        {
    2.45 +            this.unitManager = unitManager;
    2.46 +            this.sensor = sensor;
    2.47 +       
    2.48 +            // get the default dpi to create an icon with the correct size
    2.49 +            float dpiX, dpiY;
    2.50 +            using (Bitmap b = new Bitmap(1, 1, PixelFormat.Format32bppArgb))
    2.51 +            {
    2.52 +                dpiX = b.HorizontalResolution;
    2.53 +                dpiY = b.VerticalResolution;
    2.54 +            }
    2.55 +
    2.56 +            // adjust the size of the icon to current dpi (default is 16x16 at 96 dpi) 
    2.57 +            int width = (int)Math.Round(16 * dpiX / 96);
    2.58 +            int height = (int)Math.Round(16 * dpiY / 96);
    2.59 +
    2.60 +            // make sure it does never get smaller than 16x16
    2.61 +            width = width < 16 ? 16 : width;
    2.62 +            height = height < 16 ? 16 : height;
    2.63 +
    2.64 +            // adjust the font size to the icon size
    2.65 +            FontFamily family = SystemFonts.MessageBoxFont.FontFamily;
    2.66 +            float baseSize;
    2.67 +            switch (family.Name)
    2.68 +            {
    2.69 +                case "Segoe UI": baseSize = 12; break;
    2.70 +                case "Tahoma": baseSize = 11; break;
    2.71 +                default: baseSize = 12; break;
    2.72 +            }
    2.73 +
    2.74 +            this.font = new Font(family,
    2.75 +              baseSize * width / 16.0f, GraphicsUnit.Pixel);
    2.76 +            this.smallFont = new Font(family,
    2.77 +              0.75f * baseSize * width / 16.0f, GraphicsUnit.Pixel);
    2.78 +
    2.79 +            this.bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
    2.80 +            this.graphics = Graphics.FromImage(this.bitmap);
    2.81 +
    2.82 +            if (Environment.OSVersion.Version.Major > 5)
    2.83 +            {
    2.84 +                this.graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
    2.85 +                this.graphics.SmoothingMode = SmoothingMode.HighQuality;
    2.86 +            }
    2.87 +        }
    2.88 +
    2.89 +        public ISensor Sensor
    2.90 +        {
    2.91 +            get { return sensor; }
    2.92 +        }
    2.93 +
    2.94 +        public Color Color
    2.95 +        {
    2.96 +            get { return color; }
    2.97 +            set
    2.98 +            {
    2.99 +                this.color = value;
   2.100 +                this.darkColor = Color.FromArgb(255,
   2.101 +                  this.color.R / 3,
   2.102 +                  this.color.G / 3,
   2.103 +                  this.color.B / 3);
   2.104 +                Brush brush = this.brush;
   2.105 +                this.brush = new SolidBrush(this.color);
   2.106 +                if (brush != null)
   2.107 +                    brush.Dispose();
   2.108 +                Brush darkBrush = this.darkBrush;
   2.109 +                this.darkBrush = new SolidBrush(this.darkColor);
   2.110 +                if (darkBrush != null)
   2.111 +                    darkBrush.Dispose();
   2.112 +            }
   2.113 +        }
   2.114 +
   2.115 +        public void Dispose()
   2.116 +        {
   2.117 +
   2.118 +            if (brush != null)
   2.119 +                brush.Dispose();
   2.120 +            if (darkBrush != null)
   2.121 +                darkBrush.Dispose();
   2.122 +            pen.Dispose();
   2.123 +            graphics.Dispose();
   2.124 +            bitmap.Dispose();
   2.125 +            font.Dispose();
   2.126 +            smallFont.Dispose();
   2.127 +        }
   2.128 +
   2.129 +        private string GetString()
   2.130 +        {
   2.131 +            if (!sensor.Value.HasValue)
   2.132 +                return "-";
   2.133 +
   2.134 +            switch (sensor.SensorType)
   2.135 +            {
   2.136 +                case SensorType.Voltage:
   2.137 +                    return string.Format("{0:F1}", sensor.Value);
   2.138 +                case SensorType.Clock:
   2.139 +                    return string.Format("{0:F1}", 1e-3f * sensor.Value);
   2.140 +                case SensorType.Load:
   2.141 +                    return string.Format("{0:F0}", sensor.Value);
   2.142 +                case SensorType.Temperature:
   2.143 +                    if (unitManager.TemperatureUnit == TemperatureUnit.Fahrenheit)
   2.144 +                        return string.Format("{0:F0}",
   2.145 +                          UnitManager.CelsiusToFahrenheit(sensor.Value));
   2.146 +                    else
   2.147 +                        return string.Format("{0:F0}", sensor.Value);
   2.148 +                case SensorType.Fan:
   2.149 +                    return string.Format("{0:F1}", 1e-3f * sensor.Value);
   2.150 +                case SensorType.Flow:
   2.151 +                    return string.Format("{0:F1}", 1e-3f * sensor.Value);
   2.152 +                case SensorType.Control:
   2.153 +                    return string.Format("{0:F0}", sensor.Value);
   2.154 +                case SensorType.Level:
   2.155 +                    return string.Format("{0:F0}", sensor.Value);
   2.156 +                case SensorType.Power:
   2.157 +                    return string.Format("{0:F0}", sensor.Value);
   2.158 +                case SensorType.Data:
   2.159 +                    return string.Format("{0:F0}", sensor.Value);
   2.160 +                case SensorType.Factor:
   2.161 +                    return string.Format("{0:F1}", sensor.Value);
   2.162 +            }
   2.163 +            return "-";
   2.164 +        }
   2.165 +
   2.166 +        private Icon CreateTransparentIcon()
   2.167 +        {
   2.168 +            string text = GetString();
   2.169 +            int count = 0;
   2.170 +            for (int i = 0; i < text.Length; i++)
   2.171 +                if ((text[i] >= '0' && text[i] <= '9') || text[i] == '-')
   2.172 +                    count++;
   2.173 +            bool small = count > 2;
   2.174 +
   2.175 +            graphics.Clear(Color.Black);
   2.176 +            TextRenderer.DrawText(graphics, text, small ? smallFont : font,
   2.177 +              new Point(-2, small ? 1 : 0), Color.White, Color.Black);
   2.178 +
   2.179 +            BitmapData data = bitmap.LockBits(
   2.180 +              new Rectangle(0, 0, bitmap.Width, bitmap.Height),
   2.181 +              ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
   2.182 +
   2.183 +            IntPtr Scan0 = data.Scan0;
   2.184 +
   2.185 +            int numBytes = bitmap.Width * bitmap.Height * 4;
   2.186 +            byte[] bytes = new byte[numBytes];
   2.187 +            Marshal.Copy(Scan0, bytes, 0, numBytes);
   2.188 +            bitmap.UnlockBits(data);
   2.189 +
   2.190 +            byte red, green, blue;
   2.191 +            for (int i = 0; i < bytes.Length; i += 4)
   2.192 +            {
   2.193 +                blue = bytes[i];
   2.194 +                green = bytes[i + 1];
   2.195 +                red = bytes[i + 2];
   2.196 +
   2.197 +                bytes[i] = color.B;
   2.198 +                bytes[i + 1] = color.G;
   2.199 +                bytes[i + 2] = color.R;
   2.200 +                bytes[i + 3] = (byte)(0.3 * red + 0.59 * green + 0.11 * blue);
   2.201 +            }
   2.202 +
   2.203 +            return IconFactory.Create(bytes, bitmap.Width, bitmap.Height,
   2.204 +              PixelFormat.Format32bppArgb);
   2.205 +        }
   2.206 +
   2.207 +        private Icon CreatePercentageIcon()
   2.208 +        {
   2.209 +            try
   2.210 +            {
   2.211 +                graphics.Clear(Color.Transparent);
   2.212 +            }
   2.213 +            catch (ArgumentException)
   2.214 +            {
   2.215 +                graphics.Clear(Color.Black);
   2.216 +            }
   2.217 +            graphics.FillRectangle(darkBrush, 0.5f, -0.5f, bitmap.Width - 2, bitmap.Height);
   2.218 +            float value = sensor.Value.GetValueOrDefault();
   2.219 +            float y = 0.16f * (100 - value);
   2.220 +            graphics.FillRectangle(brush, 0.5f, -0.5f + y, bitmap.Width - 2, bitmap.Height - y);
   2.221 +            graphics.DrawRectangle(pen, 1, 0, bitmap.Width - 3, bitmap.Height - 1);
   2.222 +
   2.223 +            BitmapData data = bitmap.LockBits(
   2.224 +              new Rectangle(0, 0, bitmap.Width, bitmap.Height),
   2.225 +              ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
   2.226 +            byte[] bytes = new byte[bitmap.Width * bitmap.Height * 4];
   2.227 +            Marshal.Copy(data.Scan0, bytes, 0, bytes.Length);
   2.228 +            bitmap.UnlockBits(data);
   2.229 +
   2.230 +            return IconFactory.Create(bytes, bitmap.Width, bitmap.Height,
   2.231 +              PixelFormat.Format32bppArgb);
   2.232 +        }
   2.233 +
   2.234 +        public void Update()
   2.235 +        {
   2.236 + 
   2.237 +
   2.238 +            switch (sensor.SensorType)
   2.239 +            {
   2.240 +                case SensorType.Load:
   2.241 +                case SensorType.Control:
   2.242 +                case SensorType.Level:
   2.243 +                    //notifyIcon.Icon = CreatePercentageIcon();
   2.244 +                    break;
   2.245 +                default:
   2.246 +                    //notifyIcon.Icon = CreateTransparentIcon();
   2.247 +                    break;
   2.248 +            }
   2.249 +
   2.250 +
   2.251 +            string format = "";
   2.252 +            switch (sensor.SensorType)
   2.253 +            {
   2.254 +                case SensorType.Voltage: format = "\n{0}: {1:F2} V"; break;
   2.255 +                case SensorType.Clock: format = "\n{0}: {1:F0} MHz"; break;
   2.256 +                case SensorType.Load: format = "\n{0}: {1:F1} %"; break;
   2.257 +                case SensorType.Temperature: format = "\n{0}: {1:F1} °C"; break;
   2.258 +                case SensorType.Fan: format = "\n{0}: {1:F0} RPM"; break;
   2.259 +                case SensorType.Flow: format = "\n{0}: {1:F0} L/h"; break;
   2.260 +                case SensorType.Control: format = "\n{0}: {1:F1} %"; break;
   2.261 +                case SensorType.Level: format = "\n{0}: {1:F1} %"; break;
   2.262 +                case SensorType.Power: format = "\n{0}: {1:F0} W"; break;
   2.263 +                case SensorType.Data: format = "\n{0}: {1:F0} GB"; break;
   2.264 +                case SensorType.Factor: format = "\n{0}: {1:F3} GB"; break;
   2.265 +            }
   2.266 +            string formattedValue = string.Format(format, sensor.Name, sensor.Value);
   2.267 +
   2.268 +            if (sensor.SensorType == SensorType.Temperature &&
   2.269 +              unitManager.TemperatureUnit == TemperatureUnit.Fahrenheit)
   2.270 +            {
   2.271 +                format = "\n{0}: {1:F1} °F";
   2.272 +                formattedValue = string.Format(format, sensor.Name,
   2.273 +                  UnitManager.CelsiusToFahrenheit(sensor.Value));
   2.274 +            }
   2.275 +
   2.276 +            string hardwareName = sensor.Hardware.Name;
   2.277 +            hardwareName = hardwareName.Substring(0,
   2.278 +              Math.Min(63 - formattedValue.Length, hardwareName.Length));
   2.279 +            string text = hardwareName + formattedValue;
   2.280 +            if (text.Length > 63)
   2.281 +                text = null;
   2.282 +
   2.283 +
   2.284 +        }
   2.285 +    }
   2.286 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/GUI/SoundGraphDisplay.cs	Sun Feb 03 18:01:50 2013 +0100
     3.3 @@ -0,0 +1,221 @@
     3.4 +/*
     3.5 + 
     3.6 +  This Source Code Form is subject to the terms of the Mozilla Public
     3.7 +  License, v. 2.0. If a copy of the MPL was not distributed with this
     3.8 +  file, You can obtain one at http://mozilla.org/MPL/2.0/.
     3.9 + 
    3.10 +  Copyright (C) 2009-2012 Michael Möller <mmoeller@openhardwaremonitor.org>
    3.11 +	
    3.12 +*/
    3.13 +
    3.14 +using System;
    3.15 +using System.Collections.Generic;
    3.16 +using System.Drawing;
    3.17 +using System.Text;
    3.18 +using System.Windows.Forms;
    3.19 +using OpenHardwareMonitor.Hardware;
    3.20 +using OpenHardwareMonitor.Utilities;
    3.21 +using System.Runtime.InteropServices;
    3.22 +
    3.23 +
    3.24 +
    3.25 +static class NativeMethods
    3.26 +{
    3.27 +    [System.Flags]
    3.28 +    public enum LoadLibraryFlags : uint
    3.29 +    {
    3.30 +        DONT_RESOLVE_DLL_REFERENCES = 0x00000001,
    3.31 +        LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010,
    3.32 +        LOAD_LIBRARY_AS_DATAFILE = 0x00000002,
    3.33 +        LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x00000040,
    3.34 +        LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020,
    3.35 +        LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008
    3.36 +    }
    3.37 +
    3.38 +
    3.39 +    [DllImport("kernel32.dll", SetLastError = true)]
    3.40 +    public static extern IntPtr LoadLibrary(string dllToLoad);
    3.41 +
    3.42 +    [DllImport("kernel32.dll")]
    3.43 +    public static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, LoadLibraryFlags dwFlags);
    3.44 +
    3.45 +    [DllImport("kernel32.dll", SetLastError = true)]
    3.46 +    public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
    3.47 +
    3.48 +    [DllImport("kernel32.dll", SetLastError = true)]
    3.49 +    public static extern bool FreeLibrary(IntPtr hModule);
    3.50 +}
    3.51 +
    3.52 +
    3.53 +namespace OpenHardwareMonitor.GUI
    3.54 +{
    3.55 +    public class SoundGraphDisplay : IDisposable
    3.56 +    {
    3.57 +        private IComputer computer;
    3.58 +        private PersistentSettings settings;
    3.59 +        private UnitManager unitManager;
    3.60 +        private List<SensorFrontView> list = new List<SensorFrontView>();
    3.61 +        //private bool mainIconEnabled = false;
    3.62 +        //private NotifyIconAdv mainIcon;
    3.63 +        IntPtr iSoundGraphDll;
    3.64 +
    3.65 +        public SoundGraphDisplay(IComputer computer, PersistentSettings settings,
    3.66 +          UnitManager unitManager)
    3.67 +        {
    3.68 +            this.computer = computer;
    3.69 +            this.settings = settings;
    3.70 +            this.unitManager = unitManager;
    3.71 +            computer.HardwareAdded += new HardwareEventHandler(HardwareAdded);
    3.72 +            computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved);
    3.73 +
    3.74 +            //Try loading SoundGraph iMON Disaply DLL
    3.75 +            iSoundGraphDll = NativeMethods.LoadLibraryEx(@"iMONDisplay.dll", IntPtr.Zero, NativeMethods.LoadLibraryFlags.LOAD_WITH_ALTERED_SEARCH_PATH);
    3.76 +            int err=Marshal.GetLastWin32Error(); //If you 193  it means you need build for x86
    3.77 +            if (err == 193)
    3.78 +            {
    3.79 +                Console.Write(@"iMON: Cannot load x86 DLL from x64 process.");
    3.80 +            }
    3.81 +            else if (err != 0)
    3.82 +            {
    3.83 +                Console.Write(@"iMON: Error: %i - Failed to load iMONDisplay.dll", err);
    3.84 +            }
    3.85 +            else
    3.86 +            {
    3.87 +                Console.Write(@"iMON: DLL loaded.");
    3.88 +            }
    3.89 +
    3.90 +
    3.91 +        }
    3.92 +
    3.93 +        private void HardwareRemoved(IHardware hardware)
    3.94 +        {
    3.95 +            hardware.SensorAdded -= new SensorEventHandler(SensorAdded);
    3.96 +            hardware.SensorRemoved -= new SensorEventHandler(SensorRemoved);
    3.97 +            foreach (ISensor sensor in hardware.Sensors)
    3.98 +                SensorRemoved(sensor);
    3.99 +            foreach (IHardware subHardware in hardware.SubHardware)
   3.100 +                HardwareRemoved(subHardware);
   3.101 +        }
   3.102 +
   3.103 +        private void HardwareAdded(IHardware hardware)
   3.104 +        {
   3.105 +            foreach (ISensor sensor in hardware.Sensors)
   3.106 +                SensorAdded(sensor);
   3.107 +            hardware.SensorAdded += new SensorEventHandler(SensorAdded);
   3.108 +            hardware.SensorRemoved += new SensorEventHandler(SensorRemoved);
   3.109 +            foreach (IHardware subHardware in hardware.SubHardware)
   3.110 +                HardwareAdded(subHardware);
   3.111 +        }
   3.112 +
   3.113 +        private void SensorAdded(ISensor sensor)
   3.114 +        {
   3.115 +            if (settings.GetValue(new Identifier(sensor.Identifier,
   3.116 +              "tray").ToString(), false))
   3.117 +                Add(sensor, false);
   3.118 +        }
   3.119 +
   3.120 +        private void SensorRemoved(ISensor sensor)
   3.121 +        {
   3.122 +            if (Contains(sensor))
   3.123 +                Remove(sensor, false);
   3.124 +        }
   3.125 +
   3.126 +        public void Dispose()
   3.127 +        {
   3.128 +            foreach (SensorFrontView icon in list)
   3.129 +                icon.Dispose();
   3.130 +
   3.131 +            //Unload our DLL
   3.132 +            if (iSoundGraphDll != IntPtr.Zero)
   3.133 +            {
   3.134 +                bool result = NativeMethods.FreeLibrary(iSoundGraphDll);
   3.135 +            }
   3.136 +
   3.137 +        }
   3.138 +
   3.139 +        public void Redraw()
   3.140 +        {
   3.141 +            foreach (SensorFrontView icon in list)
   3.142 +                icon.Update();
   3.143 +        }
   3.144 +
   3.145 +        public bool Contains(ISensor sensor)
   3.146 +        {
   3.147 +            foreach (SensorFrontView icon in list)
   3.148 +                if (icon.Sensor == sensor)
   3.149 +                    return true;
   3.150 +            return false;
   3.151 +        }
   3.152 +
   3.153 +        public void Add(ISensor sensor, bool balloonTip)
   3.154 +        {
   3.155 +            if (Contains(sensor))
   3.156 +            {
   3.157 +                return;
   3.158 +            }
   3.159 +            else
   3.160 +            {
   3.161 +                //SL:
   3.162 +                //list.Add(new SensorFrontView(this, sensor, balloonTip, settings, unitManager));
   3.163 +                //UpdateMainIconVisibilty();
   3.164 +                //settings.SetValue(new Identifier(sensor.Identifier, "tray").ToString(), true);
   3.165 +            }
   3.166 +        }
   3.167 +
   3.168 +        public void Remove(ISensor sensor)
   3.169 +        {
   3.170 +            Remove(sensor, true);
   3.171 +        }
   3.172 +
   3.173 +        private void Remove(ISensor sensor, bool deleteConfig)
   3.174 +        {
   3.175 +            if (deleteConfig)
   3.176 +            {
   3.177 +                settings.Remove(
   3.178 +                  new Identifier(sensor.Identifier, "tray").ToString());
   3.179 +                settings.Remove(
   3.180 +                  new Identifier(sensor.Identifier, "traycolor").ToString());
   3.181 +            }
   3.182 +            SensorFrontView instance = null;
   3.183 +            foreach (SensorFrontView icon in list)
   3.184 +                if (icon.Sensor == sensor)
   3.185 +                    instance = icon;
   3.186 +            if (instance != null)
   3.187 +            {
   3.188 +                list.Remove(instance);
   3.189 +                UpdateMainIconVisibilty();
   3.190 +                instance.Dispose();
   3.191 +            }
   3.192 +        }
   3.193 +
   3.194 +
   3.195 +
   3.196 +        private void UpdateMainIconVisibilty()
   3.197 +        {
   3.198 +            /*
   3.199 +            if (mainIconEnabled)
   3.200 +            {
   3.201 +                mainIcon.Visible = list.Count == 0;
   3.202 +            }
   3.203 +            else
   3.204 +            {
   3.205 +                mainIcon.Visible = false;
   3.206 +            }
   3.207 +             */
   3.208 +        }
   3.209 +
   3.210 +        /*
   3.211 +        public bool IsMainIconEnabled
   3.212 +        {
   3.213 +            get { return mainIconEnabled; }
   3.214 +            set
   3.215 +            {
   3.216 +                if (mainIconEnabled != value)
   3.217 +                {
   3.218 +                    mainIconEnabled = value;
   3.219 +                    UpdateMainIconVisibilty();
   3.220 +                }
   3.221 +            }
   3.222 +        }*/
   3.223 +    }
   3.224 +}
     4.1 --- a/OpenHardwareMonitor.csproj	Tue Dec 30 22:49:32 2014 +0000
     4.2 +++ b/OpenHardwareMonitor.csproj	Sun Feb 03 18:01:50 2013 +0100
     4.3 @@ -108,9 +108,11 @@
     4.4      <Compile Include="GUI\ParameterForm.Designer.cs">
     4.5        <DependentUpon>ParameterForm.cs</DependentUpon>
     4.6      </Compile>
     4.7 +    <Compile Include="GUI\SensorFrontView.cs" />
     4.8      <Compile Include="GUI\SensorGadget.cs" />
     4.9      <Compile Include="GUI\SensorNotifyIcon.cs" />
    4.10      <Compile Include="GUI\ShowDesktop.cs" />
    4.11 +    <Compile Include="GUI\SoundGraphDisplay.cs" />
    4.12      <Compile Include="GUI\SplitContainerAdv.cs">
    4.13        <SubType>Component</SubType>
    4.14      </Compile>