Click here to Skip to main content
15,883,901 members
Articles / Programming Languages / C#

NextUI Thermometer Panel

Rate me:
Please Sign up or sign in to vote.
3.56/5 (15 votes)
23 Oct 20073 min read 32.3K   2.8K   33  
a thermometer like display
// *****************************************************************************
// 
//  (c) NextWave Software  2007
//  All rights reserved. The software and associated documentation 
//  supplied hereunder are the proprietary information of NextWave Software 
//	Limited, Kuala Lumpur , Malaysia and are supplied subject to 
//	licence terms.
// 
//  Version 0.9 	www.nextwavesoft.com
// *****************************************************************************

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using NextUI.Common;
using NextUI.Helper;
using NextUI.Collection;
using System.Windows.Forms;

namespace NextUI.Bar
{
    public class KnobPanel
    {
        public enum Marking { NONE, LINE, CONT, BOTH };
        public enum MarkingImage { FONT, IMAGE, NONE };
        private int _x, _y, _width, _height;
        private Control _parent;
        private Rectangle _clientRect ;
        private bool _mouseDown = false;
        private float _currentAngle = 360f;
        private PointF _center = new PointF(0, 0);
        private float _distance = 360f;
        private Marking _markingType = Marking.CONT;
        private MarkingImage _markingImage = MarkingImage.IMAGE;
        private Font _f = new Font(FontFamily.GenericMonospace, 8);
        private bool _step = true;
        private Collection.MeterLabelCollection _collection = null;
        private Image _knobHandleImage = null;
        private Color _fontColor = Color.Black;
        private int _value = -1;
        public Color FontColor
        {
            get { return _fontColor; }
            set { _fontColor = value; }
        }

        public int PointerValue
        {
            get { return _value; }
        }

        public bool IsMouseDown
        {
            get { return _mouseDown; }
        }

        public KnobPanel.MarkingImage MarkingImageType
        {
            get { return _markingImage; }
            set
            {
                if (_markingImage != value)
                {
                    _markingImage = value;
                }
            }
        }

        public KnobPanel.Marking MarkingType
        {
            get { return _markingType; }
            set
            {
                if (_markingType != value)
                {
                    _markingType = value;
                }
            }
        }

        public Image KnobHandleimage
        {
            get { return _knobHandleImage; }
            set { _knobHandleImage = value; }
        }

        public Font MainFont
        {
            get { return _f; }
            set { _f = value; }
        }

        public bool Step
        {
            get { return _step; }
            set { _step = value; }
        }

        public MeterLabelCollection Collection
        {
            get { return _collection; }
        }

            
        public int Left
        {
            get { return _x; }
            set
            {
                if (_x != value)
                {
                    _x = value;
                    InternalConstruct(_x, _y, _width, _height);
                }
            }
        }

        public int Top
        {
            get { return _y; }
            set
            {
                if (_y != value)
                {
                    _y = value;
                    InternalConstruct(_x, _y, _width, _height);
                }
            }
        }

        public int Width
        {
            get { return _width; }
            set
            {
                if (_width != value)
                {
                    _width = value;
                    InternalConstruct(_x, _y, _width, _height);
                }
            }
        }

        public int Height
        {
            get { return _height; }
            set
            {
                if (_height != value)
                {
                    _height = value;
                    InternalConstruct(_x, _y, _width, _height);
                }
            }
        }

        public KnobPanel(Control parent)
        {
            _parent = parent;
            InternalConstruct(0, 0, 20, 20);
        }

        public KnobPanel(Rectangle location, Control parent)
        {
            _parent = parent;
            InternalConstruct(location.X, location.Y, location.Width, location.Height);
        }

        private void InternalConstruct(int x, int y, int width, int height)
        {
            _x = x;
            _y = y;
            _width = width;
            _height = height;
            _clientRect = new Rectangle(_x,_y,_width,_height);
            if (_collection == null)
            {
                _collection = new MeterLabelCollection();
                _collection.Delete += new OnRemove(_collection_Delete);
                _collection.Insert += new OnInsert(_collection_Insert);
                _collection.Set += new OnSet(_collection_Set);
            }
        }

        void _collection_Set(object sender, int index)
        {
        }

        void _collection_Insert(object sender, int index)
        {
            _distance = 360f / _collection.Count;
            if (_step)
            {
                NearestAngle();
            }

           
        }

        void _collection_Delete(object sender, int index)
        {
            if (_step)
            {
                if (_collection.Count > 0)
                {
                    _distance = 360f / _collection.Count;
                    NearestAngle();
                }
                else
                {
                    _distance = 360f;
                    _currentAngle = _distance;
                }
            }
            
        }

        public void MouseDown(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (Helper.AlgorithmHelper.IsPointInRect(_clientRect, e.Location))
                {
                    _mouseDown = true;
                    if (_collection.Count > 1)
                    {
                        if (_step)
                        {
                            NearestAngle();
                        }
                        else
                        {
                            _currentAngle = AlgorithmHelper.PointToCenterAngle(_center, e.Location);
                            _currentAngle = AlgorithmHelper.NormalizeDegree(270, _currentAngle);
                        }
                    }
                }                       
            }
        }

        public void MouseUp(MouseEventArgs e)
        {
            _mouseDown = false;
            if (_step)
            {
                // we pick the closest target.
                NearestAngle();
           
            }
        }

        public void MouseMove(MouseEventArgs e)
        {
            if (_mouseDown)
            {
                if (_collection.Count > 1)
                {
                        _currentAngle = Helper.AlgorithmHelper.PointToCenterAngle(_center, e.Location);
                        _currentAngle = AlgorithmHelper.NormalizeDegree(270, _currentAngle);
                       // Console.WriteLine("VAL ===== " + PointerToValue(_currentAngle));
                        _value = PointerToValue(_currentAngle);
                }
            }

        }

        public void Draw(Graphics e)
        {
            Rectangle r1 = RectangleHelper.Shrink(_clientRect,10);
            r1.Height = r1.Width;
            _center = new PointF((float)(r1.Left + r1.Width / 2),(float)( r1.Top + r1.Height / 2));
            GraphicsPath s1 = new GraphicsPath();
            s1.AddEllipse(r1);
          /*  PathGradientBrush pb = new PathGradientBrush(s1);
            pb.CenterColor = Color.White;
            pb.SurroundColors = new Color[] { Color.Gray };
            pb.CenterPoint = new PointF(-2f, -2f);
            e.FillEllipse(pb,r1);*/
            e.DrawEllipse(new Pen(Color.Black), r1);
            Rectangle r2 = RectangleHelper.Shrink(r1, 10);
            //the knob handle
            LinearGradientBrush b = new LinearGradientBrush(r2, Color.Silver, Color.White, 180f);
            e.FillEllipse(b, r2);
            e.DrawEllipse(new Pen(Color.DarkSlateBlue), r2);
            GraphicsPath p = new GraphicsPath();
            p.AddEllipse(r2);
            
            //The pointer

            GraphicsPath ptr = new GraphicsPath();
            ptr.AddEllipse(new Rectangle(r2.Left + r2.Width / 2 - 5, r2.Top , 10, 10));
            PathGradientBrush pbptr = new PathGradientBrush(ptr);
            pbptr.CenterColor = Color.LightGray;
         //   pbptr.CenterPoint = new PointF(0, -0.5f);
            pbptr.SurroundColors = new Color[] { Color.Black };

            DrawMarking(e, r1, r2);

            GraphicsState state = e.Save();
            Matrix m = new Matrix();
            m.RotateAt(_currentAngle, _center);
            e.Transform = m;
            e.FillPath(pbptr, ptr);
            e.SetClip(p);
            if (_knobHandleImage != null)
            {
                e.DrawImage(_knobHandleImage, r2);
            }
            e.ResetClip();
            p.Dispose();
            e.Restore(state);
            ptr.Dispose();
            pbptr.Dispose();
            //end
                
        }


        private void DrawMarking(Graphics e, Rectangle outBound , Rectangle inBound)
        {
           // e.SmoothingMode = SmoothingMode.HighQuality;
            GraphicsState state = e.Save();
            e.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
            e.SmoothingMode = SmoothingMode.HighQuality;
            Matrix mat = new Matrix();
            Point sp = new Point(inBound.Left + inBound.Width / 2, outBound.Top );
            Point ep = new Point(inBound.Left + inBound.Width / 2, inBound.Top);
            if (_collection.Count > 0)
            {
                float angle = 0;
                for (int i = 0; i < _collection.Count; i++)
                {
                    mat.RotateAt(_distance, _center);
                 //   Console.WriteLine("rotate " + i + " : " + _distance + " collection value=" + _collection[i].Value);
                    angle += _distance;
                    e.Transform = mat;
                    if  ( _markingType == Marking.CONT || _markingType== Marking.BOTH)
                    {
                        GraphicsPath p = new GraphicsPath();
                        p.AddLine(sp, ep);
                        p.AddArc(inBound, 270, _distance);
                        p.Reverse();
                        GraphicsPath p2 = new GraphicsPath();
                        p2.AddArc(outBound, 270, _distance);
                        p2.AddLine(
                            AlgorithmHelper.LocationToCenter(_center, outBound.Width / 2, AlgorithmHelper.NormalizeDegreeFromX(270 + _distance)),
                            AlgorithmHelper.LocationToCenter(_center, inBound.Width / 2, AlgorithmHelper.NormalizeDegreeFromX(270 + _distance)));
                        p2.AddPath(p, true);
                        e.FillPath(new SolidBrush(_collection[i].MainColor), p2);

                    }
                    if  (_markingType == Marking.LINE || _markingType == Marking.BOTH)
                    {
                        e.DrawLine(new Pen(_fontColor, 2), sp, ep);
                    }
                     Size z = new Size(0,0);
                    if ( _markingImage == MarkingImage.FONT)
                    {
                        String text = _collection[i].Desc;
                        z = TextRenderer.MeasureText(text, _f);
                        Point fp = new Point(inBound.Left + inBound.Width / 2 - z.Width / 2, outBound.Top - z.Height);
                        e.DrawString(text, _f, new SolidBrush(_fontColor), fp);
                        //TextEffectHelper.HaloEffect(_f, new SolidBrush(_fontColor), e, fp, text);

                    }
                    if ( _markingImage == MarkingImage.IMAGE)
                    {
                        if (_collection[i].Image != null)
                        {
                            e.DrawImage(_collection[i].Image, new Rectangle(inBound.Left + inBound.Width / 2 - 6, outBound.Top - z.Height - 14, 12, 12),
                                        new Rectangle(0, 0, _collection[i].Image.Width, _collection[i].Image.Height), GraphicsUnit.Pixel);

                        }
                    }

                }
            }
            e.Restore(state);
        }

        private void NearestAngle()
        {
            //we use division to calculate the nearest angle
            //Console.Write("Nearest angle = " + _currentAngle);
            _currentAngle = ((int)(_currentAngle / _distance)) * _distance;
           // Console.WriteLine(" to = " + _currentAngle);

        }

        private int PointerToValue(float angle)
        {
            /*
             * rotate 0 : 120 collection value=0
             * rotate 1 : 120 collection value=1
             * rotate 2 : 120 collection value=2
             */
            int index = (int)( angle / _distance) - 1;
            if (index < 0)
            {
                index = _collection.Count - 1;
            }
            return (int)(_collection[index].Value);
        }



    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior) www.nextwavesoft.com
United States United States
Senior Software Developer at nextwavesoft

Comments and Discussions