📄 htmllabel.cs
字号:
namespace Imps.Client.Pc.BizControls
{
using Imps.Client.Core;
using Imps.Client.Resource;
using Imps.Utils.TagParser;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Text;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;
using System.Windows.Forms;
public class HtmlLabel : Label
{
private bool _allowAnimate;
private bool _autoDetectUrls;
private bool _autoResizeHeight;
private Dictionary<List<RectangleF>, string> _dicLinkRectangleF = new Dictionary<List<RectangleF>, string>();
private bool _drawFinish;
private Timer _emotionTimer;
private int _lineHight;
private Color _linkColor = Color.Blue;
private PointF _nextPoint;
private bool _parseEmotion;
private bool _showBackgroundImage;
private int _spaceDistance;
private Imps.Utils.TagParser.TagParser parser;
private Regex regUrl;
public event EventHandler<LabelLinkClickEventArgs> LabelLinkClick;
public HtmlLabel()
{
base.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.SupportsTransparentBackColor | ControlStyles.UserPaint, true);
base.SetStyle(ControlStyles.Selectable | ControlStyles.FixedHeight, false);
base.SetStyle(ControlStyles.ResizeRedraw, true);
base.Disposed += new EventHandler(this.HtmlLabel_Disposed);
base.AutoSize = false;
}
private void DrawImage(Graphics gp, Image image)
{
int num = this._lineHight;
int width = Convert.ToInt32((float) (image.Width * (((float) (num + this.SpaceDistance)) / ((float) image.Height))));
if (((width + this._nextPoint.X) + 1f) > this.LineWidth)
{
this._nextPoint = new PointF((float) this.ClientRectangle.Left, (this._nextPoint.Y + this._lineHight) + this.SpaceDistance);
}
this._nextPoint.X += 1f;
Rectangle rect = new Rectangle(Convert.ToInt32(this._nextPoint.X), Convert.ToInt32(this._nextPoint.Y), width, num + this.SpaceDistance);
gp.DrawImage(image, rect);
this._nextPoint.X += width;
}
private void DrawNode(Graphics gp, TagNode node, ref Font font, ref Color color)
{
FontStyle style = font.Style;
bool flag = ParserFontStyle(node, ref style);
if (node is FontElement)
{
font = new Font((node as FontElement).Face, (node as FontElement).Size, style);
color = (node as FontElement).Color;
}
else if (flag)
{
if (font.Style != style)
{
font = new Font(font.FontFamily, font.Size, style);
}
}
else
{
FontElement element = node.GetAncestor("font") as FontElement;
if (element != null)
{
font = new Font(element.Face, element.Size, this.Font.Style);
color = element.Color;
}
else
{
font = this.Font;
color = this.ForeColor;
}
}
if (node is HyperlinkElement)
{
List<RectangleF> rects = new List<RectangleF>();
Font linkFont = GetLinkFont(font);
this.DrawString(gp, (node as HyperlinkElement).Text, linkFont, this._linkColor, rects);
this._dicLinkRectangleF.Add(rects, (node as HyperlinkElement).Href);
}
else if (node.HasChild)
{
for (TagNode firstChild = node.FirstChild; firstChild != null; firstChild = firstChild.Next)
{
this.DrawNode(gp, firstChild, ref font, ref color);
}
}
else if (!this._drawFinish)
{
if (!this.ParseEmotion)
{
this.DrawString(gp, node.Text, font, color);
}
else
{
List<object>.Enumerator enumerator = EmoticonParser.ParseString(null, node.Text).GetEnumerator();
try
{
while (enumerator.MoveNext())
{
object obj2 = enumerator.get_Current();
if (obj2 is Emoticon)
{
Emoticon emoticon = (Emoticon) obj2;
this.DrawImage(gp, emoticon.AmigoImage.NextFrame(100));
if ((this.AllowAnimate && emoticon.AmigoImage.CanPlay) && (this._emotionTimer == null))
{
this._emotionTimer = new Timer();
this._emotionTimer.Interval = 100;
this._emotionTimer.Tick += new EventHandler(this.emotionTimer_Tick);
this._emotionTimer.Start();
}
}
else if (obj2 is string)
{
this.DrawString(gp, (string) obj2, font, color);
}
}
}
finally
{
enumerator.Dispose();
}
}
}
}
private void DrawString(Graphics gp, string content, Font font, Color color)
{
if (!this.AutoDetectUrls)
{
this.DrawString(gp, content, font, color, null);
}
else
{
MatchCollection matchs = this.regUrl.Matches(content);
if (matchs.Count == 0)
{
this.DrawString(gp, content, font, color, null);
}
else
{
int startIndex = 0;
for (int i = 0; i < matchs.Count; i++)
{
Match match = matchs[i];
if (match.Index != startIndex)
{
this.DrawString(gp, content.Substring(startIndex, match.Index - startIndex), font, color, null);
}
List<RectangleF> rects = new List<RectangleF>();
Font linkFont = GetLinkFont(font);
this.DrawString(gp, match.Value, linkFont, this._linkColor, rects);
this._dicLinkRectangleF.Add(rects, match.Value);
startIndex = match.Index + match.Length;
if ((i == (matchs.Count - 1)) && (startIndex != content.Length))
{
this.DrawString(gp, content.Substring(startIndex, content.Length - startIndex), font, color, null);
}
}
}
}
}
private void DrawString(Graphics gp, string content, Font font, Color color, List<RectangleF> rects)
{
if (!this._drawFinish)
{
int length = content.IndexOf("\r\n");
if (length > -1)
{
string text = content.Substring(0, length);
string text2 = content.Substring(length + 2);
if (!string.IsNullOrEmpty(text))
{
this.DrawString(gp, text, font, color, rects);
}
this._nextPoint = new PointF((float) this.ClientRectangle.Left, (this._nextPoint.Y + this._lineHight) + this.SpaceDistance);
if (((this._nextPoint.Y + this._lineHight) + this.SpaceDistance) > this.ClientRectangle.Height)
{
this._drawFinish = true;
}
if (!string.IsNullOrEmpty(text2))
{
this.DrawString(gp, text2, font, color, rects);
}
}
else
{
StringFormat format = (StringFormat) StringFormat.GenericDefault.Clone();
format.HotkeyPrefix = base.UseMnemonic ? HotkeyPrefix.Show : HotkeyPrefix.None;
TextFormatFlags flags = base.UseMnemonic ? ((TextFormatFlags) 0x10000000) : ((TextFormatFlags) 0x800);
Size size = TextRenderer.MeasureText((IDeviceContext) gp, content, font, Size.Empty, flags);
if (((size.Width + this._nextPoint.X) + 1f) < this.LineWidth)
{
if (rects != null)
{
rects.Add(new RectangleF(this._nextPoint, (SizeF) size));
}
using (Brush brush = new SolidBrush(color))
{
Rectangle rectangle = new Rectangle(Point.Ceiling(this._nextPoint), size);
TextRenderer.DrawText((IDeviceContext) gp, content, font, rectangle, color, flags);
}
this._nextPoint.X += size.Width;
}
else
{
RectangleF rec = new RectangleF(this._nextPoint.X, this._nextPoint.Y, this.LineWidth - this._nextPoint.X, (float) this._lineHight);
string s = this.RectangleContainString(gp, rec, content, font);
if (rects != null)
{
rects.Add(rec);
}
if (((this._nextPoint.Y + (this._lineHight * 2)) + this.SpaceDistance) > this.ClientRectangle.Height)
{
if (!this.AutoResizeHeight || (((base.Height + this._lineHight) + this.SpaceDistance) >= this.get_MaximumSize().Height))
{
if (base.get_AutoEllipsis())
{
format.Trimming = StringTrimming.EllipsisCharacter;
}
using (Brush brush2 = new SolidBrush(color))
{
gp.DrawString(content, font, brush2, rec, format);
}
this._drawFinish = true;
return;
}
base.Height += this._lineHight + this.SpaceDistance;
}
using (Brush brush3 = new SolidBrush(color))
{
gp.DrawString(s, font, brush3, this._nextPoint, format);
}
this._nextPoint = new PointF((float) this.ClientRectangle.Left, (this._nextPoint.Y + this._lineHight) + this.SpaceDistance);
this.DrawString(gp, content.Substring(s.Length, content.Length - s.Length), font, color, rects);
}
}
}
}
private void emotionTimer_Tick(object sender, EventArgs e)
{
base.Invalidate();
}
private static Font GetLinkFont(Font font)
{
return new Font(font, font.Style | FontStyle.Underline);
}
private void HtmlLabel_Disposed(object sender, EventArgs e)
{
if (this._emotionTimer != null)
{
this._emotionTimer.Dispose();
}
}
protected override void OnMouseClick(MouseEventArgs e)
{
base.OnMouseClick(e);
if (((this.LabelLinkClick != null) && (e.Button == MouseButtons.Left)) && (this.Cursor == Cursors.Hand))
{
lock (this._dicLinkRectangleF)
{
Dictionary<List<RectangleF>, string>.KeyCollection.Enumerator enumerator = this._dicLinkRectangleF.get_Keys().GetEnumerator();
try
{
while (enumerator.MoveNext())
{
List<RectangleF> list = enumerator.get_Current();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -