diff options
Diffstat (limited to 'src/GraphicObjects/Label.cs')
| -rw-r--r-- | src/GraphicObjects/Label.cs | 846 |
1 files changed, 0 insertions, 846 deletions
diff --git a/src/GraphicObjects/Label.cs b/src/GraphicObjects/Label.cs deleted file mode 100644 index 0e0d9fe1..00000000 --- a/src/GraphicObjects/Label.cs +++ /dev/null @@ -1,846 +0,0 @@ -// -// Label.cs -// -// Author: -// Jean-Philippe Bruyère <jp.bruyere@hotmail.com> -// -// Copyright (c) 2013-2017 Jean-Philippe Bruyère -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Diagnostics; -using Cairo; -using System.Text.RegularExpressions; -using System.Xml.Serialization; -using System.ComponentModel; - -namespace Crow -{ - public class Label : GraphicObject - { - #region CTOR - protected Label () : base(){} - - public Label(Interface iface) : base(iface) - { - - } -// public Label(string _text) -// : base() -// { -// Text = _text; -// } - #endregion - - public event EventHandler<TextChangeEventArgs> TextChanged; - - public virtual void OnTextChanged(Object sender, TextChangeEventArgs e) - { - textMeasureIsUpToDate = false; - NotifyValueChanged ("Text", Text); - TextChanged.Raise (this, e); - } - //TODO:change protected to private - - #region private and protected fields - string _text = "label"; - Alignment _textAlignment; - bool horizontalStretch; - bool verticalStretch; - bool _selectable; - bool _multiline; - Color selBackground; - Color selForeground; - Point mouseLocalPos = -1;//mouse coord in widget space, filled only when clicked - int _currentCol; //0 based cursor position in string - int _currentLine; - Point _selBegin = -1; //selection start (row,column) - Point _selRelease = -1; //selection end (row,column) - double textCursorPos; //cursor position in cairo units in widget client coord. - double SelStartCursorPos = -1; - double SelEndCursorPos = -1; - bool SelectionInProgress = false; - - protected Rectangle rText; - protected float widthRatio = 1f; - protected float heightRatio = 1f; - protected FontExtents fe; - protected TextExtents te; - #endregion - - [XmlAttributeAttribute][DefaultValue("SteelBlue")] - public virtual Color SelectionBackground { - get { return selBackground; } - set { - if (value == selBackground) - return; - selBackground = value; - NotifyValueChanged ("SelectionBackground", selBackground); - RegisterForRedraw (); - } - } - [XmlAttributeAttribute][DefaultValue("White")] - public virtual Color SelectionForeground { - get { return selForeground; } - set { - if (value == selForeground) - return; - selForeground = value; - NotifyValueChanged ("SelectionForeground", selForeground); - RegisterForRedraw (); - } - } - [XmlAttributeAttribute][DefaultValue(Alignment.Left)] - public Alignment TextAlignment - { - get { return _textAlignment; } - set { - if (value == _textAlignment) - return; - _textAlignment = value; - RegisterForRedraw (); - NotifyValueChanged ("TextAlignment", _textAlignment); - } - } - [XmlAttributeAttribute][DefaultValue(false)] - public virtual bool HorizontalStretch { - get { return horizontalStretch; } - set { - if (horizontalStretch == value) - return; - horizontalStretch = value; - RegisterForRedraw (); - NotifyValueChanged ("HorizontalStretch", horizontalStretch); - } - } - [XmlAttributeAttribute][DefaultValue(false)] - public virtual bool VerticalStretch { - get { return verticalStretch; } - set { - if (verticalStretch == value) - return; - verticalStretch = value; - RegisterForRedraw (); - NotifyValueChanged ("VerticalStretch", verticalStretch); - } - } - [XmlAttributeAttribute][DefaultValue("label")] - public string Text - { - get { - return lines == null ? - _text : lines.Aggregate((i, j) => i + Interface.LineBreak + j); - } - set - { - if (string.Equals (value, _text, StringComparison.Ordinal)) - return; - - _text = value; - - if (string.IsNullOrEmpty(_text)) - _text = ""; - - lines = getLines; - - OnTextChanged (this, new TextChangeEventArgs (Text)); - RegisterForGraphicUpdate (); - } - } - [XmlAttributeAttribute][DefaultValue(false)] - public bool Selectable - { - get { return _selectable; } - set - { - if (value == _selectable) - return; - _selectable = value; - NotifyValueChanged ("Selectable", _selectable); - SelBegin = -1; - SelRelease = -1; - RegisterForRedraw (); - } - } - [XmlAttributeAttribute][DefaultValue(false)] - public bool Multiline - { - get { return _multiline; } - set - { - if (value == _multiline) - return; - _multiline = value; - NotifyValueChanged ("Multiline", _multiline); - RegisterForGraphicUpdate(); - } - } - [XmlAttributeAttribute][DefaultValue(0)] - public int CurrentColumn{ - get { return _currentCol; } - set { - if (value == _currentCol) - return; - if (value < 0) - _currentCol = 0; - else if (value > lines [_currentLine].Length) - _currentCol = lines [_currentLine].Length; - else - _currentCol = value; - NotifyValueChanged ("CurrentColumn", _currentCol); - } - } - [XmlAttributeAttribute][DefaultValue(0)] - public int CurrentLine{ - get { return _currentLine; } - set { - if (value == _currentLine) - return; - if (value >= lines.Count) - _currentLine = lines.Count-1; - else if (value < 0) - _currentLine = 0; - else - _currentLine = value; - //force recheck of currentCol for bounding - int cc = _currentCol; - _currentCol = 0; - CurrentColumn = cc; - NotifyValueChanged ("CurrentLine", _currentLine); - } - } - [XmlIgnore]public Point CurrentPosition { - get { return new Point(_currentCol, CurrentLine); } - } - //TODO:using HasFocus for drawing selection cause SelBegin and Release binding not to work - /// <summary> - /// Selection begin position in char units - /// </summary> - [XmlAttributeAttribute][DefaultValue("-1")] - public Point SelBegin { - get { - return _selBegin; - } - set { - if (value == _selBegin) - return; - _selBegin = value; - NotifyValueChanged ("SelBegin", _selBegin); - NotifyValueChanged ("SelectedText", SelectedText); - } - } - [XmlAttributeAttribute][DefaultValue("-1")] - public Point SelRelease { - get { - return _selRelease; - } - set { - if (value == _selRelease) - return; - _selRelease = value; - NotifyValueChanged ("SelRelease", _selRelease); - NotifyValueChanged ("SelectedText", SelectedText); - } - } - /// <summary> - /// return char at CurrentLine, CurrentColumn - /// </summary> - [XmlIgnore]protected Char CurrentChar - { - get { - return lines [CurrentLine] [CurrentColumn]; - } - } - /// <summary> - /// ordered selection start and end positions in char units - /// </summary> - [XmlIgnore]protected Point selectionStart - { - get { - return SelRelease < 0 || SelBegin.Y < SelRelease.Y ? SelBegin : - SelBegin.Y > SelRelease.Y ? SelRelease : - SelBegin.X < SelRelease.X ? SelBegin : SelRelease; - } - } - [XmlIgnore]public Point selectionEnd - { - get { - return SelRelease < 0 || SelBegin.Y > SelRelease.Y ? SelBegin : - SelBegin.Y < SelRelease.Y ? SelRelease : - SelBegin.X > SelRelease.X ? SelBegin : SelRelease; - } - } - [XmlIgnore]public string SelectedText - { - get { - - if (SelRelease < 0 || SelBegin < 0) - return ""; - if (selectionStart.Y == selectionEnd.Y) - return lines [selectionStart.Y].Substring (selectionStart.X, selectionEnd.X - selectionStart.X); - string tmp = ""; - tmp = lines [selectionStart.Y].Substring (selectionStart.X); - for (int l = selectionStart.Y + 1; l < selectionEnd.Y; l++) { - tmp += Interface.LineBreak + lines [l]; - } - tmp += Interface.LineBreak + lines [selectionEnd.Y].Substring (0, selectionEnd.X); - return tmp; - } - } - [XmlIgnore]public bool selectionIsEmpty - { get { return SelRelease < 0; } } - - List<string> lines; - List<string> getLines { - get { - return _multiline ? - Regex.Split (_text, "\r\n|\r|\n|\\\\n").ToList() : - new List<string>(new string[] { _text }); - } - } - /// <summary> - /// Moves cursor one char to the left. - /// </summary> - /// <returns><c>true</c> if move succeed</returns> - public bool MoveLeft(){ - int tmp = _currentCol - 1; - if (tmp < 0) { - if (_currentLine == 0) - return false; - CurrentLine--; - CurrentColumn = int.MaxValue; - } else - CurrentColumn = tmp; - return true; - } - /// <summary> - /// Moves cursor one char to the right. - /// </summary> - /// <returns><c>true</c> if move succeed</returns> - public bool MoveRight(){ - int tmp = _currentCol + 1; - if (tmp > lines [_currentLine].Length){ - if (CurrentLine == lines.Count - 1) - return false; - CurrentLine++; - CurrentColumn = 0; - } else - CurrentColumn = tmp; - return true; - } - public void GotoWordStart(){ - CurrentColumn--; - //skip white spaces - while (!char.IsLetterOrDigit (this.CurrentChar) && CurrentColumn > 0) - CurrentColumn--; - while (char.IsLetterOrDigit (lines [CurrentLine] [CurrentColumn]) && CurrentColumn > 0) - CurrentColumn--; - if (!char.IsLetterOrDigit (this.CurrentChar)) - CurrentColumn++; - } - public void GotoWordEnd(){ - //skip white spaces - if (CurrentColumn >= lines [CurrentLine].Length - 1) - return; - while (!char.IsLetterOrDigit (this.CurrentChar) && CurrentColumn < lines [CurrentLine].Length-1) - CurrentColumn++; - while (char.IsLetterOrDigit (this.CurrentChar) && CurrentColumn < lines [CurrentLine].Length-1) - CurrentColumn++; - if (char.IsLetterOrDigit (this.CurrentChar)) - CurrentColumn++; - } - public void DeleteChar() - { - if (selectionIsEmpty) { - if (CurrentColumn == 0) { - if (CurrentLine == 0 && lines.Count == 1) - return; - CurrentLine--; - CurrentColumn = lines [CurrentLine].Length; - lines [CurrentLine] += lines [CurrentLine + 1]; - lines.RemoveAt (CurrentLine + 1); - - OnTextChanged (this, new TextChangeEventArgs (Text)); - return; - } - CurrentColumn--; - lines [CurrentLine] = lines [CurrentLine].Remove (CurrentColumn, 1); - } else { - int linesToRemove = selectionEnd.Y - selectionStart.Y + 1; - int l = selectionStart.Y; - - if (linesToRemove > 0) { - lines [l] = lines [l].Remove (selectionStart.X, lines [l].Length - selectionStart.X) + - lines [selectionEnd.Y].Substring (selectionEnd.X, lines [selectionEnd.Y].Length - selectionEnd.X); - l++; - for (int c = 0; c < linesToRemove-1; c++) - lines.RemoveAt (l); - CurrentLine = selectionStart.Y; - CurrentColumn = selectionStart.X; - } else - lines [l] = lines [l].Remove (selectionStart.X, selectionEnd.X - selectionStart.X); - CurrentColumn = selectionStart.X; - SelBegin = -1; - SelRelease = -1; - } - OnTextChanged (this, new TextChangeEventArgs (Text)); - } - /// <summary> - /// Insert new string at caret position, should be sure no line break is inside. - /// </summary> - /// <param name="str">String.</param> - protected void Insert(string str) - { - if (!selectionIsEmpty) - this.DeleteChar (); - if (_multiline) { - string[] strLines = Regex.Split (str, "\r\n|\r|\n|" + @"\\n").ToArray(); - lines [CurrentLine] = lines [CurrentLine].Insert (CurrentColumn, strLines[0]); - CurrentColumn += strLines[0].Length; - for (int i = 1; i < strLines.Length; i++) { - InsertLineBreak (); - lines [CurrentLine] = lines [CurrentLine].Insert (CurrentColumn, strLines[i]); - CurrentColumn += strLines[i].Length; - } - } else { - lines [CurrentLine] = lines [CurrentLine].Insert (CurrentColumn, str); - CurrentColumn += str.Length; - } - OnTextChanged (this, new TextChangeEventArgs (Text)); - } - /// <summary> - /// Insert a line break. - /// </summary> - protected void InsertLineBreak() - { - lines.Insert(CurrentLine + 1, lines[CurrentLine].Substring(CurrentColumn)); - lines [CurrentLine] = lines [CurrentLine].Substring (0, CurrentColumn); - CurrentLine++; - CurrentColumn = 0; - OnTextChanged (this, new TextChangeEventArgs (Text)); - } - bool textMeasureIsUpToDate = false; - Size cachedTextSize = default(Size); - - #region GraphicObject overrides - protected override int measureRawSize(LayoutingType lt) - { - if (lines == null) - lines = getLines; - if (!textMeasureIsUpToDate) { - using (ImageSurface img = new ImageSurface (Format.Argb32, 10, 10)) { - using (Context gr = new Context (img)) { - //Cairo.FontFace cf = gr.GetContextFontFace (); - - gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); - gr.SetFontSize (Font.Size); - gr.FontOptions = Interface.FontRenderingOptions; - gr.Antialias = Interface.Antialias; - - fe = gr.FontExtents; - te = new TextExtents (); - - cachedTextSize.Height = (int)Math.Ceiling ((fe.Ascent+fe.Descent) * Math.Max (1, lines.Count)) + Margin * 2; - - try { - foreach (string s in lines) { - string l = s.Replace ("\t", new String (' ', Interface.TabSize)); - - TextExtents tmp = gr.TextExtents (l); - - if (tmp.XAdvance > te.XAdvance) - te = tmp; - } - cachedTextSize.Width = (int)Math.Ceiling (te.XAdvance) + Margin * 2; - textMeasureIsUpToDate = true; - } catch { - return -1; - } - } - } - - } - return lt == LayoutingType.Height ? cachedTextSize.Height : cachedTextSize.Width; - } - protected override void onDraw (Context gr) - { - base.onDraw (gr); - - gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); - gr.SetFontSize (Font.Size); - gr.FontOptions = Interface.FontRenderingOptions; - gr.Antialias = Interface.Antialias; - - rText = new Rectangle(new Size( - measureRawSize(LayoutingType.Width), measureRawSize(LayoutingType.Height))); - rText.Width -= 2 * Margin; - rText.Height -= 2 * Margin; - - widthRatio = 1f; - heightRatio = 1f; - - Rectangle cb = ClientRectangle; - - rText.X = cb.X; - rText.Y = cb.Y; - - if (horizontalStretch) { - widthRatio = (float)cb.Width / (float)rText.Width; - if (!verticalStretch) - heightRatio = widthRatio; - } - - if (verticalStretch) { - heightRatio = (float)cb.Height / (float)rText.Height; - if (!horizontalStretch) - widthRatio = heightRatio; - } - - rText.Width = (int)(widthRatio * (float)rText.Width); - rText.Height = (int)(heightRatio * (float)rText.Height); - - switch (TextAlignment) - { - case Alignment.TopLeft: //ok - rText.X = cb.X; - rText.Y = cb.Y; - break; - case Alignment.Top: //ok - rText.Y = cb.Y; - rText.X = cb.X + cb.Width / 2 - rText.Width / 2; - break; - case Alignment.TopRight: //ok - rText.Y = cb.Y; - rText.X = cb.Right - rText.Width; - break; - case Alignment.Left://ok - rText.X = cb.X; - rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2; - break; - case Alignment.Right://ok - rText.X = cb.X + cb.Width - rText.Width; - rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2; - break; - case Alignment.Bottom://ok - rText.X = cb.Width / 2 - rText.Width / 2; - rText.Y = cb.Height - rText.Height; - break; - case Alignment.BottomLeft://ok - rText.X = cb.X; - rText.Y = cb.Bottom - rText.Height; - break; - case Alignment.BottomRight://ok - rText.Y = cb.Bottom - rText.Height; - rText.X = cb.Right - rText.Width; - break; - case Alignment.Center://ok - rText.X = cb.X + cb.Width / 2 - rText.Width / 2; - //rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2; - rText.Y = cb.Y + (int)Math.Floor((double)cb.Height / 2.0 - (double)rText.Height / 2.0); - break; - } - - //gr.FontMatrix = new Matrix(widthRatio * (float)Font.Size, 0, 0, heightRatio * (float)Font.Size, 0, 0); - fe = gr.FontExtents; - - #region draw text cursor - if (HasFocus && Selectable) - { - if (mouseLocalPos >= 0) - { - computeTextCursor(gr); - - if (SelectionInProgress) - { - if (SelBegin < 0){ - SelBegin = new Point(CurrentColumn, CurrentLine); - SelStartCursorPos = textCursorPos; - SelRelease = -1; - }else{ - SelRelease = new Point(CurrentColumn, CurrentLine); - if (SelRelease == SelBegin) - SelRelease = -1; - else - SelEndCursorPos = textCursorPos; - } - }else - computeTextCursorPosition(gr); - }else - computeTextCursorPosition(gr); - - Foreground.SetAsSource (gr); - gr.LineWidth = 1.0; - gr.MoveTo (0.5 + textCursorPos + rText.X, rText.Y + CurrentLine * (fe.Ascent+fe.Descent)); - gr.LineTo (0.5 + textCursorPos + rText.X, rText.Y + (CurrentLine + 1) * (fe.Ascent+fe.Descent)); - gr.Stroke(); - } - #endregion - - //****** debug selection ************* -// if (SelRelease >= 0) { -// new SolidColor(Color.DarkGreen).SetAsSource(gr); -// Rectangle R = new Rectangle ( -// rText.X + (int)SelEndCursorPos - 3, -// rText.Y + (int)(SelRelease.Y * (fe.Ascent+fe.Descent)), -// 6, -// (int)(fe.Ascent+fe.Descent)); -// gr.Rectangle (R); -// gr.Fill (); -// } -// if (SelBegin >= 0) { -// new SolidColor(Color.DarkRed).SetAsSource(gr); -// Rectangle R = new Rectangle ( -// rText.X + (int)SelStartCursorPos - 3, -// rText.Y + (int)(SelBegin.Y * (fe.Ascent+fe.Descent)), -// 6, -// (int)(fe.Ascent+fe.Descent)); -// gr.Rectangle (R); -// gr.Fill (); -// } - //******************* - - for (int i = 0; i < lines.Count; i++) { - string l = lines [i].Replace ("\t", new String (' ', Interface.TabSize)); - int lineLength = (int)gr.TextExtents (l).XAdvance; - Rectangle lineRect = new Rectangle ( - rText.X, - rText.Y + i * (int)(fe.Ascent+fe.Descent), - lineLength, - (int)(fe.Ascent+fe.Descent)); - -// if (TextAlignment == Alignment.Center || -// TextAlignment == Alignment.Top || -// TextAlignment == Alignment.Bottom) -// lineRect.X += (rText.Width - lineLength) / 2; -// else if (TextAlignment == Alignment.Right || -// TextAlignment == Alignment.TopRight || -// TextAlignment == Alignment.BottomRight) -// lineRect.X += (rText.Width - lineLength); - if (string.IsNullOrWhiteSpace (l)) - continue; - - Foreground.SetAsSource (gr); - gr.MoveTo (lineRect.X,(double)rText.Y + fe.Ascent + (fe.Ascent+fe.Descent) * i) ; - gr.ShowText (l); - gr.Fill (); - - if (Selectable) { - if (SelRelease >= 0 && i >= selectionStart.Y && i <= selectionEnd.Y) { - gr.SetSourceColor (selBackground); - - Rectangle selRect = lineRect; - - int cpStart = (int)SelStartCursorPos, - cpEnd = (int)SelEndCursorPos; - - if (SelBegin.Y > SelRelease.Y) { - cpStart = cpEnd; - cpEnd = (int)SelStartCursorPos; - } - - if (i == selectionStart.Y) { - selRect.Width -= cpStart; - selRect.Left += cpStart; - } - if (i == selectionEnd.Y) - selRect.Width -= (lineLength - cpEnd); - - gr.Rectangle (selRect); - gr.FillPreserve (); - gr.Save (); - gr.Clip (); - gr.SetSourceColor (SelectionForeground); - gr.MoveTo (lineRect.X, rText.Y + fe.Ascent + (fe.Ascent+fe.Descent) * i); - gr.ShowText (l); - gr.Fill (); - gr.Restore (); - } - } - } - } - #endregion - - #region Mouse handling - void updatemouseLocalPos(Point mpos){ - mouseLocalPos = mpos - ScreenCoordinates(Slot).TopLeft - ClientRectangle.TopLeft; - if (mouseLocalPos.X < 0) - mouseLocalPos.X = 0; - if (mouseLocalPos.Y < 0) - mouseLocalPos.Y = 0; - } - public override void onMouseEnter (object sender, MouseMoveEventArgs e) - { - base.onMouseEnter (sender, e); - if (Selectable) - IFace.MouseCursor = XCursor.Text; - } - public override void onMouseLeave (object sender, MouseMoveEventArgs e) - { - base.onMouseLeave (sender, e); - IFace.MouseCursor = XCursor.Default; - } - protected override void onFocused (object sender, EventArgs e) - { - base.onFocused (sender, e); - - if (!_selectable) - return; - SelBegin = new Point(0,0); - SelRelease = new Point (lines.LastOrDefault ().Length, lines.Count-1); - RegisterForRedraw (); - } - protected override void onUnfocused (object sender, EventArgs e) - { - base.onUnfocused (sender, e); - - SelBegin = -1; - SelRelease = -1; - RegisterForRedraw (); - } - public override void onMouseMove (object sender, MouseMoveEventArgs e) - { - base.onMouseMove (sender, e); - - if (!(SelectionInProgress && HasFocus && _selectable)) - return; - - updatemouseLocalPos (e.Position); - - RegisterForRedraw(); - } - public override void onMouseDown (object sender, MouseButtonEventArgs e) - { - if (this.HasFocus && _selectable){ - updatemouseLocalPos (e.Position); - SelBegin = -1; - SelRelease = -1; - SelectionInProgress = true; - RegisterForRedraw();//TODO:should put it in properties - } - - //done at the end to set 'hasFocus' value after testing it - base.onMouseDown (sender, e); - } - public override void onMouseUp (object sender, MouseButtonEventArgs e) - { - base.onMouseUp (sender, e); - if (!(this.HasFocus || _selectable)) - return; - if (!SelectionInProgress) - return; - - updatemouseLocalPos (e.Position); - SelectionInProgress = false; - RegisterForRedraw (); - } - public override void onMouseDoubleClick (object sender, MouseButtonEventArgs e) - { - base.onMouseDoubleClick (sender, e); - if (!(this.HasFocus || _selectable)) - return; - - GotoWordStart (); - SelBegin = CurrentPosition; - GotoWordEnd (); - SelRelease = CurrentPosition; - SelectionInProgress = false; - RegisterForRedraw (); - } - #endregion - - /// <summary> - /// Update Current Column, line and TextCursorPos - /// from mouseLocalPos - /// </summary> - void computeTextCursor(Context gr) - { - TextExtents te; - - double cPos = 0f; - - CurrentLine = (int)(mouseLocalPos.Y / (fe.Ascent+fe.Descent)); - - //fix cu - if (CurrentLine >= lines.Count) - CurrentLine = lines.Count - 1; - - switch (TextAlignment) { - case Alignment.Center: - case Alignment.Top: - case Alignment.Bottom: - cPos+= ClientRectangle.Width - gr.TextExtents(lines [CurrentLine]).Width/2.0; - break; - case Alignment.Right: - case Alignment.TopRight: - case Alignment.BottomRight: - cPos += ClientRectangle.Width - gr.TextExtents(lines [CurrentLine]).Width; - break; - } - - for (int i = 0; i < lines[CurrentLine].Length; i++) - { - string c = lines [CurrentLine].Substring (i, 1); - if (c == "\t") - c = new string (' ', Interface.TabSize); - - te = gr.TextExtents(c); - - double halfWidth = te.XAdvance / 2; - - if (mouseLocalPos.X <= cPos + halfWidth) - { - CurrentColumn = i; - textCursorPos = cPos; - mouseLocalPos = -1; - return; - } - - cPos += te.XAdvance; - } - CurrentColumn = lines[CurrentLine].Length; - textCursorPos = cPos; - - //reset mouseLocalPos - mouseLocalPos = -1; - } - /// <summary> Computes offsets in cairo units </summary> - void computeTextCursorPosition(Context gr) - { - if (SelBegin >= 0) - SelStartCursorPos = GetXFromTextPointer (gr, SelBegin); - if (SelRelease >= 0) - SelEndCursorPos = GetXFromTextPointer (gr, SelRelease); - textCursorPos = GetXFromTextPointer (gr, new Point(CurrentColumn, CurrentLine)); - } - /// <summary> Compute x offset in cairo unit from text position </summary> - double GetXFromTextPointer(Context gr, Point pos) - { - try { - string l = lines [pos.Y].Substring (0, pos.X). - Replace ("\t", new String (' ', Interface.TabSize)); - return gr.TextExtents (l).XAdvance; - } catch{ - return -1; - } - } - } -} |