aboutsummaryrefslogtreecommitdiffstatsci
path: root/src/GraphicObjects
diff options
context:
space:
mode:
authorjpbruyere <jp.bruyere@hotmail.com>2015-04-15 12:02:25 +0200
committerjpbruyere <jp.bruyere@hotmail.com>2015-04-15 12:02:25 +0200
commit137749098ac20b4ea84ced1151dbd6d7f56766ed (patch)
treee88f4d9e62959f74b80e51fca7b7564f82f73d89 /src/GraphicObjects
parentb9ef3d364896edc96f189dc899d33b90d79c6d38 (diff)
Multiline TextBox
Diffstat (limited to 'src/GraphicObjects')
-rwxr-xr-xsrc/GraphicObjects/GraphicObject.cs3
-rw-r--r--src/GraphicObjects/Group.cs16
-rwxr-xr-xsrc/GraphicObjects/Label.cs387
-rw-r--r--src/GraphicObjects/Scroller.cs4
-rw-r--r--src/GraphicObjects/TextBox.cs337
5 files changed, 434 insertions, 313 deletions
diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs
index 86cb3009..aa108e22 100755
--- a/src/GraphicObjects/GraphicObject.cs
+++ b/src/GraphicObjects/GraphicObject.cs
@@ -54,6 +54,9 @@ namespace go
bool yIsValid = false;
#endregion
+ public static int TabSize = 4;
+ public static string LineBreak = "\r\n";
+ public static bool ReplaceTabsWithSpace = false;
public static bool DesignerMode = false;
#region public fields
diff --git a/src/GraphicObjects/Group.cs b/src/GraphicObjects/Group.cs
index 4e8e5492..d2c48904 100644
--- a/src/GraphicObjects/Group.cs
+++ b/src/GraphicObjects/Group.cs
@@ -140,13 +140,13 @@ namespace go
foreach (GraphicObject c in Children) {
if (raw.Width < 0) {
- if (c.XIsValid & c.WIsValid)
+ if (c.WIsValid)
tmp.Width = Math.Max (tmp.Width, c.Slot.Right);
else
return raw;
}
if (raw.Height < 0) {
- if (c.YIsValid & c.HIsValid)
+ if (c.HIsValid)
tmp.Height = Math.Max (tmp.Height, c.Slot.Bottom);
else
return raw;
@@ -172,12 +172,12 @@ namespace go
if (c.LayoutIsValid)
continue;
- if (Width < 0 && c.Width != 0) {
+ if (Width < 0 && c.WIsValid) {
if (!atLeastOneChildHasWNotDependingOnParent && !(this is GenericStack))
c.XIsValid = true;
atLeastOneChildHasWNotDependingOnParent = true;
}
- if (Height < 0 && c.Height != 0) {
+ if (Height < 0 && c.HIsValid) {
if (!atLeastOneChildHasHNotDependingOnParent && !(this is GenericStack))
c.YIsValid = true;
atLeastOneChildHasHNotDependingOnParent = true;
@@ -186,10 +186,10 @@ namespace go
c.UpdateLayout ();
}
- if (Width < 0 && !atLeastOneChildHasWNotDependingOnParent)
- Debug.WriteLine ("ERROR: no child has fixed width and parent width is set to content!");
- if (Height < 0 && !atLeastOneChildHasHNotDependingOnParent)
- Debug.WriteLine ("ERROR: no child has fixed height and parent height is set to content!");
+// if (Width < 0 && !atLeastOneChildHasWNotDependingOnParent)
+// Debug.WriteLine ("ERROR: no child has fixed width and parent width is set to content!");
+// if (Height < 0 && !atLeastOneChildHasHNotDependingOnParent)
+// Debug.WriteLine ("ERROR: no child has fixed height and parent height is set to content!");
base.UpdateLayout ();
}
diff --git a/src/GraphicObjects/Label.cs b/src/GraphicObjects/Label.cs
index 37e2b8c7..aa93a7e9 100755
--- a/src/GraphicObjects/Label.cs
+++ b/src/GraphicObjects/Label.cs
@@ -7,6 +7,7 @@ using Cairo;
using System.Text.RegularExpressions;
using System.Xml.Serialization;
using System.ComponentModel;
+using OpenTK.Input;
namespace go
{
@@ -32,6 +33,15 @@ namespace go
Alignment _textAlignment = Alignment.LeftCenter;
Font _font;
bool _multiline = false;
+ Color selColor;
+ Color selFontColor;
+ Point mouseLocalPos; //mouse coord in widget space, filled only when clicked
+ int _currentCol; //0 based cursor position in string
+ int _currentLine;
+ 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;
@@ -40,7 +50,22 @@ namespace go
protected TextExtents te;
#endregion
- //public string FontFace = "MagicMedieval";
+ [XmlAttributeAttribute()][DefaultValue("SkyBlue")]
+ public virtual Color SelectionBackground {
+ get { return selColor; }
+ set {
+ selColor = value;
+ registerForGraphicUpdate ();
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue("Black")]
+ public virtual Color SelectionForeground {
+ get { return selFontColor; }
+ set {
+ selFontColor = value;
+ registerForGraphicUpdate ();
+ }
+ }
[XmlAttributeAttribute()][DefaultValue(Alignment.LeftCenter)]
public Alignment TextAlignment
@@ -51,17 +76,24 @@ namespace go
[XmlAttributeAttribute()][DefaultValue("label")]
public string Text
{
- get { return _text; }
+ get {
+ return lines == null ?
+ _text : lines.Aggregate((i, j) => i + GraphicObject.LineBreak + j);
+ }
set
{
if (_text == value)
return;
-
-
+
registerForGraphicUpdate();
InvalidateLayout();
_text = value;
+
+ if (string.IsNullOrEmpty(_text))
+ _text = "";
+
+ lines = getLines;
}
}
[XmlAttributeAttribute()][DefaultValue("droid,10")]
@@ -79,15 +111,108 @@ namespace go
registerForGraphicUpdate();
}
}
-
- string[] getLines {
- get {
+ [XmlIgnore]public int currentCol{
+ get { return _currentCol; }
+ set {
+ if (value < 0)
+ _currentCol = 0;
+ else if (value > lines [_currentLine].Count ())
+ _currentCol = lines [_currentLine].Count ();
+ else
+ _currentCol = value;
+ }
+ }
+ [XmlIgnore]public int currentLine{
+ get { return _currentLine; }
+ set {
+ if (value > lines.Count)
+ _currentLine = lines.Count;
+ else if (value < 0)
+ _currentLine = 0;
+ else
+ _currentLine = value;
+ }
+ }
+ [XmlIgnore]protected Point selBegin;
+ [XmlIgnore]protected Point selRelease;
+ [XmlIgnore]protected Point selectionStart //ordered selection start and end positions
+ {
+ 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 {
+ return null;
+ //selectionEnd < 0 ? null :
+ //Text.Substring(selectionStart, selectionEnd - selectionStart);
+ }
+ }
+ [XmlIgnore]public bool selectionIsEmpty
+ { get { return selRelease < 0; } }
+
+ List<string> lines;
+ List<string> getLines {
+ get {
return _multiline ?
- Regex.Split (_text, "\r\n|\r|\n") :
- new string[] { _text };
+ Regex.Split (_text, "\r\n|\r|\n").ToList() :
+ new List<string>(new string[] { _text });
}
}
+ public void DeleteChar()
+ {
+ if (selectionIsEmpty) {
+ if (currentCol == 0) {
+ if (currentLine == 0)
+ return;
+ currentLine--;
+ currentCol = lines [currentLine].Count ();
+ lines [currentLine] += lines [currentLine + 1];
+ lines.RemoveAt (currentLine + 1);
+ return;
+ }
+ currentCol--;
+ lines [currentLine] = lines [currentLine].Remove (currentCol, 1);
+ } else {
+ Debug.WriteLine (selectionEnd.ToString());
+ int linesToRemove = selectionEnd.Y - selectionStart.Y;
+ 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);
+ } else
+ lines [l] = lines [l].Remove (selectionStart.X, selectionEnd.X - selectionStart.X);
+ currentCol = selectionStart.X;
+ selBegin = -1;
+ selRelease = -1;
+ }
+ }
+ /// <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)
+ {
+ lines [currentLine] = lines [currentLine].Insert (currentCol, str);
+ currentCol += str.Length;
+ }
+
#region GraphicObject overrides
[XmlAttributeAttribute()][DefaultValue(-1)]
public override int Width {
@@ -107,13 +232,10 @@ namespace go
protected override Size measureRawSize()
{
- Size s;
-
+ Size size;
- if (string.IsNullOrEmpty(_text))
- _text = "";
-
- string[] lines = getLines;
+ if (lines == null)
+ lines = getLines;
using (ImageSurface img = new ImageSurface (Format.Argb32, 10, 10)) {
using (Context gr = new Context (img)) {
@@ -124,25 +246,26 @@ namespace go
te = new TextExtents();
- foreach (string str in lines) {
+ foreach (string s in lines) {
+ string l = s.Replace("\t", new String (' ', GraphicObject.TabSize));
+
#if _WIN32 || _WIN64
- TextExtents tmp = gr.TextExtents(str.ToUtf8());
+ TextExtents tmp = gr.TextExtents(str.ToUtf8());
#elif __linux__
- TextExtents tmp = gr.TextExtents (str);
+ TextExtents tmp = gr.TextExtents (l);
#endif
if (tmp.XAdvance > te.XAdvance)
te = tmp;
}
fe = gr.FontExtents;
- s = new Size ((int)Math.Ceiling (te.XAdvance) + Margin * 2, (int)Math.Ceiling (fe.Height) * lines.Length + Margin*2);
+ size = new Size ((int)Math.Ceiling (te.XAdvance) + Margin * 2, (int)(fe.Height * lines.Count) + Margin*2);
}
}
- return s;// +borderWidth;
+ return size;// +borderWidth;
}
protected override void onDraw (Context gr)
{
base.onDraw (gr);
- string[] lines = getLines;
gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
gr.SetFontSize (Font.Size);
@@ -151,7 +274,7 @@ namespace go
//gr.FontOptions.Antialias = Antialias.Subpixel;
//gr.FontOptions.HintMetrics = HintMetrics.On;
- rText = new Rectangle(new Point(0, 0),new Size((int)te.Width,(int)fe.Height * lines.Length));
+ rText = ClientRectangle;
widthRatio = 1f;
heightRatio = 1f;
@@ -256,20 +379,228 @@ namespace go
}
}
- gr.Color = Foreground;
+ #region draw text cursor
+ if (mouseLocalPos > 0)
+ {
+ computeTextCursor(gr);
+
+ if (SelectionInProgress)
+ {
+ selRelease = new Point(currentCol, currentLine);
+ SelEndCursorPos = textCursorPos;
+ }
+ else if (selBegin < 0)
+ {
+ selBegin = new Point(currentCol, currentLine);
+ SelStartCursorPos = textCursorPos;
+ selRelease = -1;
+ }
+ else
+ computeTextCursorPosition(gr);
+ }
+ else
+ computeTextCursorPosition(gr);
+
+ if (HasFocus)
+ {
+ //TODO:
+ gr.Color = Color.White;
+ gr.LineWidth = 1.5;
+ gr.MoveTo(new PointD(textCursorPos + rText.X, rText.Y + currentLine * fe.Height));
+ gr.LineTo(new PointD(textCursorPos + rText.X, rText.Y + (currentLine + 1) * fe.Height));
+ gr.Stroke();
+ }
+ #endregion
+
+// gr.Color = Color.Green;
+// Rectangle R = new Rectangle(
+// rText.X + (int)SelEndCursorPos-10,
+// rText.Y + (int)(selRelease.Y * fe.Height),
+// 20,
+// (int)fe.Height);
+// gr.Rectangle(R);
+// gr.Fill();
+// gr.Color = Color.UnmellowYellow;
+// R = new Rectangle(
+// rText.X + (int)SelStartCursorPos-10,
+// rText.Y + (int)(selBegin.Y * fe.Height),
+// 20,
+// (int)fe.Height);
+// gr.Rectangle(R);
+// gr.Fill();
gr.FontMatrix = new Matrix(widthRatio * Font.Size, 0, 0, heightRatio * Font.Size, 0, 0);
- for (int i = 0; i < lines.Length; i++) {
- gr.MoveTo(rText.X, rText.Y + fe.Ascent + fe.Height * i);
+ for (int i = 0; i < lines.Count; i++) {
+ string l = lines [i].Replace ("\t", new String (' ', GraphicObject.TabSize));
+ if (selRelease >= 0 && i >= selectionStart.Y && i <= selectionEnd.Y) {
+ gr.Color = selColor;
+ int lineLength = (int)gr.TextExtents (l).XAdvance;
+ Rectangle selRect = new Rectangle (
+ rText.X,
+ rText.Y + (int)(i * fe.Height),
+ lineLength,
+ (int)fe.Height);
+
+ 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.Fill ();
+ }
+
+ if (string.IsNullOrWhiteSpace (l))
+ continue;
+
+ gr.Color = Foreground;
+ gr.MoveTo (rText.X, rText.Y + fe.Ascent + fe.Height * i);
+
#if _WIN32 || _WIN64
- gr.ShowText(lines[i].ToUtf8());
+ gr.ShowText(l.ToUtf8());
#elif __linux__
- gr.ShowText(lines[i]);
+ gr.ShowText (l);
#endif
+ gr.Fill ();
+
}
- gr.Fill();
}
#endregion
+
+ #region Mouse handling
+ public override void onMouseEnter (object sender, MouseMoveEventArgs e)
+ {
+ // SelectionInProgress = true;
+ // mouseLocalPos = e.Position - ScreenCoordBounds.TopLeft - rText.TopLeft;
+ // registerForGraphicUpdate();
+
+ base.onMouseEnter (sender, e);
+ }
+ public override void onMouseLeave (object sender, MouseMoveEventArgs e)
+ {
+ base.onMouseLeave (sender, e);
+ }
+ public override void onMouseMove (object sender, MouseMoveEventArgs e)
+ {
+ base.onMouseMove (sender, e);
+
+ if ((sender as OpenTKGameWindow).activeWidget != this)
+ return;
+
+ SelectionInProgress = true;
+ mouseLocalPos = e.Position - ScreenCoordinates(ClientRectangle).TopLeft;
+ registerForGraphicUpdate();
+
+ }
+ public override void onMouseButtonDown (object sender, MouseButtonEventArgs e)
+ {
+ if (this.HasFocus){
+ mouseLocalPos = e.Position - ScreenCoordinates(ClientRectangle).TopLeft;
+ selBegin = -1;
+ selRelease = -1;
+ }else{
+// selBeginPos = 0;
+// selReleasePos = new Point(lines[lines.Count].Length-1, lines.Count-1);
+ }
+
+ //done at the end to set 'hasFocus' value after testing it
+ base.onMouseButtonDown (sender, e);
+
+ registerForGraphicUpdate();
+ }
+ public override void onMouseButtonUp (object sender, MouseButtonEventArgs e)
+ {
+ base.onMouseButtonUp (sender, e);
+ SelectionInProgress = false;
+ }
+ #endregion
+
+
+ void computeTextCursor(Context gr)
+ {
+ //FontExtents fe = gr.FontExtents;
+ TextExtents te;
+
+ double cPos = 0f;
+
+ currentLine = (int)(mouseLocalPos.Y / fe.Height);
+
+ for (int i = 0; i < lines[currentLine].Length; i++)
+ {
+ string c = lines [currentLine].Substring (i, 1);
+ if (c == "\t")
+ c = new string (' ', GraphicObject.TabSize);
+
+ #if _WIN32 || _WIN64
+ byte[] c = System.Text.UTF8Encoding.UTF8.GetBytes(Text.Substring(i, 1));
+ te = gr.TextExtents(c);
+ #elif __linux__
+ te = gr.TextExtents(c);
+ #endif
+ double halfWidth = te.XAdvance / 2;
+
+ if (mouseLocalPos.X <= cPos + halfWidth)
+ {
+ currentCol = i;
+ textCursorPos = cPos;
+ mouseLocalPos = -1;
+ return;
+ }
+
+ cPos += te.XAdvance;
+ }
+ currentCol = lines[currentLine].Length;
+ textCursorPos = cPos;
+
+ //reset mouseLocalPos
+ mouseLocalPos = -1;
+ }
+ void computeTextCursorPosition(Context gr)
+ {
+ TextExtents te;
+
+ double cPos = 0f;
+
+ int limit = currentCol;
+
+ if (selectionEnd > 0)
+ limit = Math.Max(currentCol, selectionEnd.X);
+
+ for (int i = 0; i <= limit; i++)
+ {
+ if (i == currentCol)
+ textCursorPos = cPos;
+ if (i == selectionStart.X)
+ SelStartCursorPos = cPos;
+ if (i == selectionEnd.X)
+ SelEndCursorPos = cPos;
+
+ if (i < lines[currentLine].Length)
+ {
+ string c = lines [currentLine].Substring (i, 1);
+ if (c == "\t")
+ c = new string (' ', GraphicObject.TabSize);
+ #if _WIN32 || _WIN64
+ byte[] c = System.Text.UTF8Encoding.UTF8.GetBytes(Text.Substring(i, 1));
+ te = gr.TextExtents(c);
+ #elif __linux__
+ te = gr.TextExtents(c);
+ #endif
+ cPos += te.XAdvance;
+ }
+ }
+
+ }
}
}
diff --git a/src/GraphicObjects/Scroller.cs b/src/GraphicObjects/Scroller.cs
index 3d952fd0..45a8a8b3 100644
--- a/src/GraphicObjects/Scroller.cs
+++ b/src/GraphicObjects/Scroller.cs
@@ -52,8 +52,7 @@ namespace go
#region Mouse handling
public override bool MouseIsIn (Point m)
- {
- //Debug.WriteLine ("scroller mouse is in");
+ {
return Visible ? base.ScreenCoordinates(Slot).ContainsOrIsEqual (m) : false;
}
public override void onMouseMove (object sender, MouseMoveEventArgs e)
@@ -72,7 +71,6 @@ namespace go
if (VerticalScrolling )
{
- Debug.WriteLine ("scroll");
//add redraw call with old bounds to errase old position
registerForRedraw();
diff --git a/src/GraphicObjects/TextBox.cs b/src/GraphicObjects/TextBox.cs
index 70d841aa..be7cdab9 100644
--- a/src/GraphicObjects/TextBox.cs
+++ b/src/GraphicObjects/TextBox.cs
@@ -8,6 +8,7 @@ using System.Diagnostics;
using System.Xml.Serialization;
using System.Globalization;
using System.ComponentModel;
+using System.Runtime.InteropServices;
namespace go
{
@@ -36,33 +37,6 @@ namespace go
set { _capitalOn = value; }
}
- #region private fields
- Color selColor;
- Color selFontColor;
- Point mouseLocalPos; //mouse coord in widget space, filled only when clicked
- int _currentPos; //0 based cursor position in string
- double textCursorPos; //cursor position in cairo units in widget client coord.
- double SelStartCursorPos = -1;
- double SelEndCursorPos = -1;
- bool SelectionInProgress = false;
- #endregion
-
- [XmlAttributeAttribute()][DefaultValue("SkyBlue")]
- public virtual Color SelectionBackground {
- get { return selColor; }
- set {
- selColor = value;
- registerForGraphicUpdate ();
- }
- }
- [XmlAttributeAttribute()][DefaultValue("Black")]
- public virtual Color SelectionForeground {
- get { return selFontColor; }
- set {
- selFontColor = value;
- registerForGraphicUpdate ();
- }
- }
#region GraphicObject overrides
[XmlIgnore]public override bool HasFocus //trigger update when lost focus to errase text beam
@@ -84,12 +58,12 @@ namespace go
set { base.Focusable = value; }
}
[XmlAttributeAttribute()][DefaultValue("White")]
- public virtual Color Background {
+ public override Color Background {
get { return base.Background; }
set { base.Background = value; }
}
[XmlAttributeAttribute()][DefaultValue("Black")]
- public virtual Color Foreground {
+ public override Color Foreground {
get { return base.Foreground; }
set { base.Foreground = value; }
}
@@ -99,66 +73,20 @@ namespace go
base.onDraw (gr);
// gr.FontOptions.Antialias = Antialias.Subpixel;
// gr.FontOptions.HintMetrics = HintMetrics.On;
- gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
- gr.SetFontSize (Font.Size);
+// gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
+// gr.SetFontSize (Font.Size);
FontExtents fe = gr.FontExtents;
- #region draw text cursor
- if (mouseLocalPos > 0)
- {
- computeTextCursor(gr);
-
- if (SelectionInProgress)
- {
- selReleasePos = currentPos;
- SelEndCursorPos = textCursorPos;
- }
- else if (selBeginPos < 0)
- {
- selBeginPos = currentPos;
- SelStartCursorPos = textCursorPos;
- selReleasePos = -1;
- }
- else
- computeTextCursorPosition(gr);
-
- }
- else
- computeTextCursorPosition(gr);
-
- if (HasFocus)
- {
- //TODO:
- gr.Color = Foreground;
- gr.LineWidth = 2;
- gr.MoveTo(new PointD(textCursorPos + rText.X, rText.Y ));
- gr.LineTo(new PointD(textCursorPos + rText.X, rText.Y + fe.Height));
- gr.Stroke();
- }
-
- #endregion
-
- if (selReleasePos >= 0)
- {
- gr.Color = selColor;
- Rectangle selRect =
- new Rectangle((int)SelStartCursorPos + rText.X, (int)(rText.Y), (int)(SelEndCursorPos - SelStartCursorPos), (int)fe.Height);
- gr.Rectangle(selRect);
- gr.Fill();
- gr.Color = selFontColor;
- }
- else
- gr.Color = Foreground;
- gr.MoveTo(rText.X, rText.Y + fe.Ascent);
- #if _WIN32 || _WIN64
- gr.ShowText(txt);
- #elif __linux__
- gr.ShowText(Text);
- #endif
- gr.Fill();
+// gr.MoveTo(rText.X, rText.Y + fe.Ascent);
+// #if _WIN32 || _WIN64
+// gr.ShowText(txt);
+// #elif __linux__
+// gr.ShowText(Text);
+// #endif
+// gr.Fill();
}
#endregion
@@ -169,26 +97,6 @@ namespace go
{
TextChanged (this, e);
}
-
-
- [XmlIgnore]public int currentPos{
- get { return _currentPos; }
- set { _currentPos = value; }
- }
- [XmlIgnore]public int selBeginPos;
- [XmlIgnore]public int selReleasePos;
- [XmlIgnore]public int selectionStart //ordered selection start and end positions
- {
- get { return selReleasePos < 0 ? selBeginPos : Math.Min(selBeginPos, selReleasePos); }
- }
- [XmlIgnore]public int selectionEnd
- { get { return selReleasePos < 0 ? selReleasePos : Math.Max(selBeginPos, selReleasePos); } }
- [XmlIgnore]public string selectedText
- { get { return selectionEnd < 0 ? null : Text.Substring(selectionStart, selectionEnd - selectionStart); } }
- [XmlIgnore]public bool selectionIsEmpty
- { get { return string.IsNullOrEmpty(selectedText); } }
-
-
#region Keyboard handling
public override void onKeyDown (object sender, KeyboardKeyEventArgs e)
@@ -202,32 +110,19 @@ namespace go
case Key.Back:
if (!selectionIsEmpty)
{
- Text = Text.Remove(selectionStart, selectionEnd - selectionStart);
- selReleasePos = -1;
- currentPos = selBeginPos;
- }
- else if (currentPos > 0)
- {
- currentPos--;
- Text = Text.Remove(currentPos, 1);
+// Text = Text.Remove(selectionStart, selectionEnd - selectionStart);
+// selReleasePos = -1;
+// currentCol = selBeginPos;
}
+ else
+ this.DeleteChar();
break;
case Key.Clear:
break;
case Key.Delete:
- if (!selectionIsEmpty)
- {
- Text = Text.Remove(selectionStart, selectionEnd - selectionStart);
- selReleasePos = -1;
- currentPos = selBeginPos;
- }
- else if (currentPos < Text.Length)
- Text = Text.Remove(currentPos, 1);
- break;
- case Key.Down:
- break;
- case Key.End:
- currentPos = Text.Length;
+ if (selectionIsEmpty)
+ currentCol++;
+ this.DeleteChar ();
break;
case Key.Enter:
case Key.KeypadEnter:
@@ -235,17 +130,33 @@ namespace go
break;
case Key.Escape:
Text = "";
- currentPos = 0;
- selReleasePos = -1;
+ currentCol = 0;
+ selRelease = -1;
break;
case Key.Home:
- currentPos = 0;
+ //TODO
+ if (e.Control)
+ currentLine = 0;
+ currentCol = 0;
+ break;
+ case Key.End:
+ if (e.Control)
+ currentLine = int.MaxValue;
+ currentCol = int.MaxValue;
break;
case Key.Insert:
break;
- case Key.Left:
- if (currentPos > 0)
- currentPos--;
+ case Key.Left:
+ currentCol--;
+ break;
+ case Key.Right:
+ currentCol++;
+ break;
+ case Key.Up:
+ currentLine--;
+ break;
+ case Key.Down:
+ currentLine++;
break;
case Key.Menu:
break;
@@ -257,49 +168,43 @@ namespace go
break;
case Key.RWin:
break;
- case Key.Right:
- if (currentPos < Text.Length)
- currentPos++;
- break;
case Key.Tab:
- Text = Text.Insert(currentPos, "\t");
- currentPos++;
- break;
- case Key.Up:
+ this.Insert("\t");
break;
case Key.KeypadDecimal:
- Text = Text.Insert(currentPos, new string(new char[]
- { Convert.ToChar(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator) }));
- currentPos++;
+ this.Insert (".");
break;
case Key.Space:
- Text = Text.Insert(currentPos, " ");
- currentPos++;
+ this.Insert(" ");
break;
case Key.KeypadDivide:
case Key.Slash:
- Text = Text.Insert(currentPos, "/");
- currentPos++;
+ this.Insert("/");
break;
case Key.KeypadMultiply:
- Text = Text.Insert(currentPos, "*");
- currentPos++;
+ this.Insert("*");
break;
case Key.KeypadMinus:
case Key.Minus:
- Text = Text.Insert(currentPos, "-");
- currentPos++;
+ this.Insert("-");
break;
case Key.KeypadPlus:
case Key.Plus:
- Text = Text.Insert(currentPos, "+");
- currentPos++;
+ this.Insert("+");
+ break;
+ case Key.ShiftLeft:
+ case Key.ShiftRight:
+ case Key.AltLeft:
+ case Key.AltRight:
+ break;
+ case Key.Semicolon:
+ this.Insert(";");
break;
default:
if (!selectionIsEmpty)
{
- Text = Text.Remove(selectionStart, selectionEnd - selectionStart);
- currentPos = selBeginPos;
+// Text = Text.Remove(selectionStart, selectionEnd - selectionStart);
+// currentCol = selBeginPos;
}
string k = "?";
@@ -307,136 +212,20 @@ namespace go
k = ((int)key - 67).ToString();
else if ((char)key >= 109 && (char)key <= 118)
k = ((int)key - 109).ToString();
- else if (capitalOn)
+ else if (e.Shift)
k = key.ToString();
else
k = key.ToString().ToLower();
- Text = Text.Insert(currentPos, k);
- currentPos++;
+ this.Insert (k);
- selReleasePos = -1;
- selBeginPos = currentPos;
+ selRelease = -1;
+ selBegin.X = currentCol;
break;
}
registerForGraphicUpdate();
}
#endregion
-
- #region Mouse handling
- public override void onMouseEnter (object sender, MouseMoveEventArgs e)
- {
-// SelectionInProgress = true;
-// mouseLocalPos = e.Position - ScreenCoordBounds.TopLeft - rText.TopLeft;
-// registerForGraphicUpdate();
-
- base.onMouseEnter (sender, e);
- }
- public override void onMouseLeave (object sender, MouseMoveEventArgs e)
- {
- base.onMouseLeave (sender, e);
- }
- public override void onMouseMove (object sender, MouseMoveEventArgs e)
- {
- base.onMouseMove (sender, e);
-
- if ((sender as OpenTKGameWindow).activeWidget != this)
- return;
-
- SelectionInProgress = true;
- mouseLocalPos = e.Position - ScreenCoordinates(rText).TopLeft;
- registerForGraphicUpdate();
-
- }
- public override void onMouseButtonDown (object sender, MouseButtonEventArgs e)
- {
- if (this.HasFocus){
- mouseLocalPos = e.Position - ScreenCoordinates(rText).TopLeft - rText.TopLeft;
- selBeginPos = -1;
- selReleasePos = -1;
- }else{
- selBeginPos = 0;
- selReleasePos = Text.Length;
- }
-
- //done at the end to set 'hasFocus' value after testing it
- base.onMouseButtonDown (sender, e);
-
- registerForGraphicUpdate();
- }
- public override void onMouseButtonUp (object sender, MouseButtonEventArgs e)
- {
- base.onMouseButtonUp (sender, e);
- SelectionInProgress = false;
- }
- #endregion
-
- void computeTextCursor(Context gr)
- {
- FontExtents fe = gr.FontExtents;
- TextExtents te;
-
- double cPos = 0f;
- for (int i = 0; i < _text.Length; i++)
- {
-#if _WIN32 || _WIN64
- byte[] c = System.Text.UTF8Encoding.UTF8.GetBytes(Text.Substring(i, 1));
- te = gr.TextExtents(c);
-#elif __linux__
- te = gr.TextExtents(Text.Substring(i, 1));
-#endif
- double halfWidth = te.XAdvance / 2;
-
- if (mouseLocalPos.X <= cPos + halfWidth)
- {
- currentPos = i;
- textCursorPos = cPos;
- mouseLocalPos = -1;
- return;
- }
-
- cPos += te.XAdvance;
- }
- currentPos = _text.Length;
- textCursorPos = cPos;
-
- //reset mouseLocalPos
- mouseLocalPos = -1;
- }
- void computeTextCursorPosition(Context gr)
- {
- FontExtents fe = gr.FontExtents;
- TextExtents te;
-
- double cPos = 0f;
-
- int limit = currentPos;
-
- if (selectionEnd > 0)
- limit = Math.Max(currentPos, selectionEnd);
-
- for (int i = 0; i <= limit; i++)
- {
- if (i == currentPos)
- textCursorPos = cPos;
- if (i == selectionStart)
- SelStartCursorPos = cPos;
- if (i == selectionEnd)
- SelEndCursorPos = cPos;
-
- if (i < Text.Length)
- {
-#if _WIN32 || _WIN64
- byte[] c = System.Text.UTF8Encoding.UTF8.GetBytes(Text.Substring(i, 1));
- te = gr.TextExtents(c);
-#elif __linux__
- te = gr.TextExtents(Text.Substring(i,1));
-#endif
- cPos += te.XAdvance;
- }
- }
-
- }
}
}