//#define DEBUG_TEXT_MEASURE using System; using System.Drawing; using Gwen.Control; namespace Gwen.ControlInternal { /// /// Displays text. Always sized to contents. /// public class Text : Base { private String m_String; private Font m_Font; /// /// Font used to display the text. /// /// /// The font is not being disposed by this class. /// public Font Font { get { return m_Font; } set { m_Font = value; SizeToContents(); } } /// /// Text to display. /// public String String { get { return m_String; } set { m_String = value; SizeToContents(); } } /// /// Text color. /// public Color TextColor { get; set; } /// /// Determines whether the control should be automatically resized to fit the text. /// //public bool AutoSizeToContents { get; set; } // [omeg] added /// /// Text length in characters. /// public int Length { get { return String.Length; } } /// /// Text color override - used by tooltips. /// public Color TextColorOverride { get; set; } /// /// Text override - used to display different string. /// public String TextOverride { get; set; } /// /// Initializes a new instance of the class. /// /// Parent control. public Text(Base parent) : base(parent) { m_Font = Skin.DefaultFont; m_String = string.Empty; TextColor = Skin.Colors.Label.Default; MouseInputEnabled = false; TextColorOverride = Color.FromArgb(0, 255, 255, 255); // A==0, override disabled } /// /// Renders the control using specified skin. /// /// Skin to use. protected override void Render(Skin.Base skin) { if (Length == 0 || Font == null) return; if (TextColorOverride.A == 0) skin.Renderer.DrawColor = TextColor; else skin.Renderer.DrawColor = TextColorOverride; skin.Renderer.RenderText(Font, Point.Empty, TextOverride ?? String); #if DEBUG_TEXT_MEASURE { Point lastPos = Point.Empty; for (int i = 0; i < m_String.Length + 1; i++) { String sub = (TextOverride ?? String).Substring(0, i); Point p = Skin.Renderer.MeasureText(Font, sub); Rectangle rect = new Rectangle(); rect.Location = lastPos; rect.Size = new Size(p.X - lastPos.X, p.Y); skin.Renderer.DrawColor = Color.FromArgb(64, 0, 0, 0); skin.Renderer.DrawLinedRect(rect); lastPos = new Point(rect.Right, 0); } } #endif } /// /// Lays out the control's interior according to alignment, padding, dock etc. /// /// Skin to use. protected override void Layout(Skin.Base skin) { SizeToContents(); base.Layout(skin); } /// /// Handler invoked when control's scale changes. /// protected override void OnScaleChanged() { Invalidate(); } /// /// Sizes the control to its contents. /// public void SizeToContents() { if (String == null) return; if (Font == null) { throw new InvalidOperationException("Text.SizeToContents() - No Font!!\n"); } Point p = new Point(1, Font.Size); if (Length > 0) { p = Skin.Renderer.MeasureText(Font, TextOverride ?? String); } if (p.X == Width && p.Y == Height) return; SetSize(p.X, p.Y); Invalidate(); InvalidateParent(); } /// /// Gets the coordinates of specified character in the text. /// /// Character index. /// Character position in local coordinates. public Point GetCharacterPosition(int index) { if (Length == 0 || index == 0) { return new Point(0, 0); } String sub = (TextOverride ?? String).Substring(0, index); Point p = Skin.Renderer.MeasureText(Font, sub); return p; } /// /// Searches for a character closest to given point. /// /// Point. /// Character index. public int GetClosestCharacter(Point p) { int distance = MaxCoord; int c = 0; for (int i = 0; i < String.Length + 1; i++) { Point cp = GetCharacterPosition(i); int dist = Math.Abs(cp.X - p.X); // TODO: handle multiline if (dist > distance) continue; distance = dist; c = i; } return c; } } }