431 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			431 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using System;
 | 
						|
using System.Text;
 | 
						|
using System.Windows.Forms;
 | 
						|
using System.ComponentModel;
 | 
						|
using System.Drawing;
 | 
						|
using System.Drawing.Drawing2D;
 | 
						|
using System.Drawing.Imaging;
 | 
						|
 | 
						|
namespace DevComponents.DotNetBar.Controls
 | 
						|
{
 | 
						|
    /// <summary>
 | 
						|
    /// Represents an single line of text label control with text-markup support and built-in reflection.
 | 
						|
    /// </summary>
 | 
						|
    [ToolboxItem(true), Designer("DevComponents.DotNetBar.Design.ReflectionLabelDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral,  PublicKeyToken=90f470f34c89ccaf"), ToolboxBitmap(typeof(LabelX), "Controls.ReflectionLabel.ico")]
 | 
						|
    public class ReflectionLabel : ControlWithBackgroundStyle
 | 
						|
    {
 | 
						|
        #region Private Variables
 | 
						|
        private TextMarkup.BodyElement _TextMarkup = null;
 | 
						|
        private Bitmap _ReflectionBitmap = null;
 | 
						|
        private float _ReflectionFactor = .52f;
 | 
						|
        private Size _TextSize = Size.Empty;
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Events
 | 
						|
        /// <summary>
 | 
						|
        /// Occurs when text markup link is clicked. Markup links can be created using "a" tag, for example:
 | 
						|
        /// <a name="MyLink">Markup link</a>
 | 
						|
        /// </summary>
 | 
						|
        public event MarkupLinkClickEventHandler MarkupLinkClick;
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Constructor
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Internal Implementation
 | 
						|
        protected override void Dispose(bool disposing)
 | 
						|
        {
 | 
						|
            DisposeReflectionImage();
 | 
						|
            base.Dispose(disposing);
 | 
						|
        }
 | 
						|
 | 
						|
        protected override void PaintContent(PaintEventArgs e)
 | 
						|
        {
 | 
						|
            Graphics g = e.Graphics;
 | 
						|
            SmoothingMode sm = g.SmoothingMode;
 | 
						|
            if (AntiAlias)
 | 
						|
            {
 | 
						|
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
 | 
						|
                g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint;
 | 
						|
            }
 | 
						|
 | 
						|
            Rectangle r = GetContentRectangle();
 | 
						|
            Point reflectionLocation = r.Location;
 | 
						|
            bool disposeStyle = false;
 | 
						|
            ElementStyle style = this.GetBackgroundStyle(out disposeStyle);
 | 
						|
 | 
						|
            if (_TextMarkup != null)
 | 
						|
            {
 | 
						|
                TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, this.Font, (style.TextColor.IsEmpty?this.ForeColor:style.TextColor), 
 | 
						|
                    (this.RightToLeft == RightToLeft.Yes), Rectangle.Empty, true);
 | 
						|
                if (!this.Enabled)
 | 
						|
                {
 | 
						|
                    d.IgnoreFormattingColors = true;
 | 
						|
                    d.CurrentForeColor = SystemColors.ControlDark;
 | 
						|
                }
 | 
						|
                _TextMarkup.Render(d);
 | 
						|
                reflectionLocation.Y = _TextMarkup.Bounds.Bottom;
 | 
						|
                reflectionLocation.X = 0;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                int totalHeight = (int)(_TextSize.Height * (1 + _ReflectionFactor));
 | 
						|
                int y = r.Y, x = r.X;
 | 
						|
                if (style.TextLineAlignment == eStyleTextAlignment.Center)
 | 
						|
                {
 | 
						|
                    y += (r.Height - totalHeight) / 2;
 | 
						|
                }
 | 
						|
                else if (style.TextLineAlignment == eStyleTextAlignment.Far)
 | 
						|
                {
 | 
						|
                    y += (r.Height - totalHeight);
 | 
						|
                }
 | 
						|
                TextDrawing.DrawString(g, this.Text, this.Font, (style.TextColor.IsEmpty ? this.ForeColor : style.TextColor), new Rectangle(x, y, r.Width, r.Height), GetTextFormat(style));
 | 
						|
                reflectionLocation.Y = y + _TextSize.Height;
 | 
						|
            }
 | 
						|
 | 
						|
            Rectangle rClip = new Rectangle(0, reflectionLocation.Y, this.Width, this.Height - reflectionLocation.Y);
 | 
						|
            g.SetClip(rClip, CombineMode.Replace);
 | 
						|
 | 
						|
            int fontBaseOffset = (int)Math.Floor(Font.Size * Font.FontFamily.GetCellDescent(Font.Style) / Font.FontFamily.GetEmHeight(Font.Style));
 | 
						|
            reflectionLocation.Y -= fontBaseOffset;
 | 
						|
 | 
						|
            if (_ReflectionBitmap != null && _ReflectionEnabled)
 | 
						|
            {
 | 
						|
                g.DrawImage(_ReflectionBitmap, reflectionLocation);
 | 
						|
            }
 | 
						|
            g.ResetClip();
 | 
						|
            if (disposeStyle) style.Dispose();
 | 
						|
            if (AntiAlias)
 | 
						|
                g.SmoothingMode = sm;
 | 
						|
        }
 | 
						|
 | 
						|
        protected override void OnTextChanged(EventArgs e)
 | 
						|
        {
 | 
						|
            UpdateDisplay();
 | 
						|
            base.OnTextChanged(e);
 | 
						|
        }
 | 
						|
 | 
						|
        protected override void OnFontChanged(EventArgs e)
 | 
						|
        {
 | 
						|
            UpdateDisplay();
 | 
						|
            base.OnFontChanged(e);
 | 
						|
        }
 | 
						|
 | 
						|
        protected override void OnForeColorChanged(EventArgs e)
 | 
						|
        {
 | 
						|
            UpdateDisplay();
 | 
						|
            base.OnForeColorChanged(e);
 | 
						|
        }
 | 
						|
 | 
						|
        protected override void OnVisualPropertyChanged()
 | 
						|
        {
 | 
						|
            UpdateDisplay();
 | 
						|
            base.OnVisualPropertyChanged();
 | 
						|
        }
 | 
						|
 | 
						|
        protected override void OnResize(EventArgs e)
 | 
						|
        {
 | 
						|
            UpdateDisplay();
 | 
						|
            base.OnResize(e);
 | 
						|
        }
 | 
						|
 | 
						|
        private void UpdateDisplay()
 | 
						|
        {
 | 
						|
            string text = this.Text;
 | 
						|
 | 
						|
            if (_TextMarkup != null)
 | 
						|
            {
 | 
						|
                _TextMarkup.MouseLeave(this);
 | 
						|
                _TextMarkup.HyperLinkClick -= new EventHandler(TextMarkupLinkClicked);
 | 
						|
                _TextMarkup = null;
 | 
						|
            }
 | 
						|
 | 
						|
            if (TextMarkup.MarkupParser.IsMarkup(ref text))
 | 
						|
                _TextMarkup = TextMarkup.MarkupParser.Parse(text);
 | 
						|
 | 
						|
            if (_TextMarkup != null)
 | 
						|
            {
 | 
						|
                _TextMarkup.HyperLinkClick += new EventHandler(TextMarkupLinkClicked);
 | 
						|
            }
 | 
						|
 | 
						|
            CreateReflection();
 | 
						|
            this.Invalidate();
 | 
						|
        }
 | 
						|
 | 
						|
        private void CreateReflection()
 | 
						|
        {
 | 
						|
            DisposeReflectionImage();
 | 
						|
            if (Text.Length == 0 || this.Width <= 0 || this.Height <= 0 || this.Font == null) return;
 | 
						|
 | 
						|
            // Create image based on the control content
 | 
						|
            Bitmap bmp = null;
 | 
						|
            if (_TextMarkup == null)
 | 
						|
            {
 | 
						|
                using(Graphics g = this.CreateGraphics())
 | 
						|
                {
 | 
						|
                    if (AntiAlias)
 | 
						|
                    {
 | 
						|
                        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
 | 
						|
                        g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint;
 | 
						|
                    }
 | 
						|
                    Size s = TextDrawing.MeasureString(g, this.Text, this.Font);
 | 
						|
                    bmp = new Bitmap(this.Width, s.Height, PixelFormat.Format32bppArgb);
 | 
						|
                    _TextSize = s;
 | 
						|
                }
 | 
						|
                bmp.MakeTransparent();
 | 
						|
 | 
						|
                Color transparentColor = Color.Empty;
 | 
						|
                using (Graphics g = Graphics.FromImage(bmp))
 | 
						|
                {
 | 
						|
                    bool disposeStyle = false;
 | 
						|
                    ElementStyle style = this.GetBackgroundStyle(out disposeStyle);
 | 
						|
                    
 | 
						|
                    if (AntiAlias)
 | 
						|
                    {
 | 
						|
                        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
 | 
						|
                        g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint;
 | 
						|
                        transparentColor = style.BackColor.IsEmpty ? this.BackColor : style.BackColor;
 | 
						|
                        if (transparentColor.IsEmpty || transparentColor == Color.Transparent) transparentColor = Color.WhiteSmoke;
 | 
						|
                        DisplayHelp.FillRectangle(g, new Rectangle(0, 0, bmp.Width, bmp.Height), transparentColor);
 | 
						|
                    }
 | 
						|
 | 
						|
                    TextDrawing.DrawString(g, this.Text, this.Font, (style.TextColor.IsEmpty ? this.ForeColor : style.TextColor),
 | 
						|
                        new Rectangle(0, 0, bmp.Width, bmp.Height), GetTextFormat(style));
 | 
						|
 | 
						|
                    if (disposeStyle) style.Dispose();
 | 
						|
                }
 | 
						|
                if (!transparentColor.IsEmpty)
 | 
						|
                    bmp.MakeTransparent(transparentColor);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                ResizeMarkup();
 | 
						|
                if (_TextMarkup.Bounds.Height > 0)
 | 
						|
                {
 | 
						|
                    bmp = new Bitmap(this.Width, _TextMarkup.Bounds.Height, PixelFormat.Format32bppArgb);
 | 
						|
                    Color transparentColor = Color.Empty;
 | 
						|
                    using (Graphics g = Graphics.FromImage(bmp))
 | 
						|
                    {
 | 
						|
                        bool disposeStyle = false;
 | 
						|
                        ElementStyle style = this.GetBackgroundStyle(out disposeStyle);
 | 
						|
 | 
						|
                        if (AntiAlias)
 | 
						|
                        {
 | 
						|
                            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
 | 
						|
                            g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint;
 | 
						|
                            transparentColor = style.BackColor.IsEmpty ? this.BackColor : style.BackColor;
 | 
						|
                            if (transparentColor.IsEmpty || transparentColor == Color.Transparent) transparentColor = Color.WhiteSmoke;
 | 
						|
                            DisplayHelp.FillRectangle(g, new Rectangle(0, 0, bmp.Width, bmp.Height), transparentColor);
 | 
						|
                        }
 | 
						|
                        if (_TextMarkup.Bounds.Top > 0)
 | 
						|
                            g.TranslateTransform(0, -(_TextMarkup.Bounds.Top - GetContentRectangle().Y));
 | 
						|
                        TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, this.Font, (style.TextColor.IsEmpty ? this.ForeColor : style.TextColor),
 | 
						|
                        (this.RightToLeft == RightToLeft.Yes), Rectangle.Empty, true);
 | 
						|
                        if (!this.Enabled)
 | 
						|
                        {
 | 
						|
                            d.IgnoreFormattingColors = true;
 | 
						|
                            d.CurrentForeColor = SystemColors.ControlDark;
 | 
						|
                        }
 | 
						|
                        _TextMarkup.Render(d);
 | 
						|
 | 
						|
                        if (disposeStyle) style.Dispose();
 | 
						|
                    }
 | 
						|
                    if (!transparentColor.IsEmpty)
 | 
						|
                        bmp.MakeTransparent(transparentColor);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            if (bmp != null)
 | 
						|
            {
 | 
						|
                _ReflectionBitmap = ImageHelper.CreateReflectionImage(bmp);
 | 
						|
                bmp.Dispose();
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        private eTextFormat GetTextFormat(ElementStyle style)
 | 
						|
        {
 | 
						|
            if (style.TextAlignment == eStyleTextAlignment.Center)
 | 
						|
                return eTextFormat.HorizontalCenter;
 | 
						|
            else if (style.TextAlignment == eStyleTextAlignment.Far)
 | 
						|
                return eTextFormat.Right;
 | 
						|
            return eTextFormat.Default;
 | 
						|
        }
 | 
						|
 | 
						|
        private void DisposeReflectionImage()
 | 
						|
        {
 | 
						|
            if (_ReflectionBitmap != null)
 | 
						|
            {
 | 
						|
                _ReflectionBitmap.Dispose();
 | 
						|
                _ReflectionBitmap = null;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        private void TextMarkupLinkClicked(object sender, EventArgs e)
 | 
						|
        {
 | 
						|
            TextMarkup.HyperLink link = sender as TextMarkup.HyperLink;
 | 
						|
            if (link != null)
 | 
						|
            {
 | 
						|
                OnMarkupLinkClick(new MarkupLinkClickEventArgs(link.Name, link.HRef));
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        protected virtual void OnMarkupLinkClick(MarkupLinkClickEventArgs e)
 | 
						|
        {
 | 
						|
            if (this.MarkupLinkClick != null)
 | 
						|
                MarkupLinkClick(this, e);
 | 
						|
        }
 | 
						|
 | 
						|
        protected virtual void ResizeMarkup()
 | 
						|
        {
 | 
						|
            if (_TextMarkup != null)
 | 
						|
            {
 | 
						|
                Rectangle r = this.GetContentRectangle();
 | 
						|
                if (r.Width <= 0 || r.Height <= 0)
 | 
						|
                    return;
 | 
						|
 | 
						|
                Graphics g = this.CreateGraphics();
 | 
						|
                try
 | 
						|
                {
 | 
						|
                    if (AntiAlias)
 | 
						|
                    {
 | 
						|
                        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
 | 
						|
                        g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint;
 | 
						|
                    }
 | 
						|
                    TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, this.Font, SystemColors.Control, (this.RightToLeft == RightToLeft.Yes));
 | 
						|
                    Size measureSize = new Size(10000, r.Height);
 | 
						|
                    _TextMarkup.Measure(measureSize, d);
 | 
						|
                    bool disposeStyle = false;
 | 
						|
                    ElementStyle style = this.GetBackgroundStyle(out disposeStyle);
 | 
						|
 | 
						|
                    int totalHeight = (int)(_TextMarkup.Bounds.Height * (1 + _ReflectionFactor));
 | 
						|
                    if (totalHeight < r.Height)
 | 
						|
                    {
 | 
						|
                        if (style.TextLineAlignment == eStyleTextAlignment.Center)
 | 
						|
                        {
 | 
						|
                            r.Y += (r.Height - totalHeight) / 2;
 | 
						|
                            r.Height = _TextMarkup.Bounds.Height;
 | 
						|
                        }
 | 
						|
                        else if (style.TextLineAlignment == eStyleTextAlignment.Far)
 | 
						|
                        {
 | 
						|
                            r.Y = (r.Bottom - totalHeight);
 | 
						|
                            r.Height = _TextMarkup.Bounds.Height;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
 | 
						|
                    if (_TextMarkup.Bounds.Width < r.Width)
 | 
						|
                    {
 | 
						|
                        if (style.TextAlignment == eStyleTextAlignment.Center)
 | 
						|
                        {
 | 
						|
                            r.X += (r.Width - _TextMarkup.Bounds.Width) / 2;
 | 
						|
                            r.Width = _TextMarkup.Bounds.Width;
 | 
						|
                        }
 | 
						|
                        else if (style.TextAlignment == eStyleTextAlignment.Far && this.RightToLeft == RightToLeft.No ||
 | 
						|
                            style.TextAlignment == eStyleTextAlignment.Near && this.RightToLeft == RightToLeft.Yes)
 | 
						|
                        {
 | 
						|
                            r.X = (r.Right - _TextMarkup.Bounds.Width);
 | 
						|
                            r.Width = _TextMarkup.Bounds.Width;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
 | 
						|
                    _TextMarkup.Arrange(r, d);
 | 
						|
 | 
						|
                    if (disposeStyle) style.Dispose();
 | 
						|
                }
 | 
						|
                finally
 | 
						|
                {
 | 
						|
                    g.Dispose();
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        protected override void OnEnabledChanged(EventArgs e)
 | 
						|
        {
 | 
						|
            CreateReflection();
 | 
						|
            this.Invalidate();
 | 
						|
            base.OnEnabledChanged(e);
 | 
						|
        }
 | 
						|
 | 
						|
        protected override Size DefaultSize
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                return new Size(175, 70);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        private bool _ReflectionEnabled = true;
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets whether reflection effect is enabled. Default value is true.
 | 
						|
        /// </summary>
 | 
						|
        [DefaultValue(true), Description("Indicates whether reflection effect is enabled.")]
 | 
						|
        public bool ReflectionEnabled
 | 
						|
        {
 | 
						|
            get { return _ReflectionEnabled; }
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (_ReflectionEnabled != value)
 | 
						|
                {
 | 
						|
                    _ReflectionEnabled = value;
 | 
						|
                    this.Invalidate();
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Property hiding
 | 
						|
        [Browsable(false)]
 | 
						|
        public override Image BackgroundImage
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                return base.BackgroundImage;
 | 
						|
            }
 | 
						|
            set
 | 
						|
            {
 | 
						|
                base.BackgroundImage = value;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
#if FRAMEWORK20
 | 
						|
		[Browsable(false)]
 | 
						|
        public override ImageLayout BackgroundImageLayout
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                return base.BackgroundImageLayout;
 | 
						|
            }
 | 
						|
            set
 | 
						|
            {
 | 
						|
                base.BackgroundImageLayout = value;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        [Browsable(false)]
 | 
						|
        public new System.Windows.Forms.Padding Padding
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                return base.Padding;
 | 
						|
            }
 | 
						|
            set
 | 
						|
            {
 | 
						|
                base.Padding = value;
 | 
						|
            }
 | 
						|
        }
 | 
						|
#endif
 | 
						|
        [Browsable(true), DefaultValue(""), Editor("DevComponents.DotNetBar.Design.TextMarkupUIEditor, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral,  PublicKeyToken=90f470f34c89ccaf", typeof(System.Drawing.Design.UITypeEditor)), EditorBrowsable(EditorBrowsableState.Always), Category("Appearance"), Description("Gets or sets the text displayed on label.")]
 | 
						|
        public override string Text
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                return base.Text;
 | 
						|
            }
 | 
						|
            set
 | 
						|
            {
 | 
						|
                base.Text = value;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        #endregion
 | 
						|
    }
 | 
						|
}
 |