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
 | |
|     }
 | |
| }
 |