2015-12-04 10:23:49 +01:00
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
// //
|
|
|
|
|
// Neoforce Controls //
|
|
|
|
|
// //
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
// //
|
|
|
|
|
// File: TextBox.cs //
|
|
|
|
|
// //
|
|
|
|
|
// Version: 0.7 //
|
|
|
|
|
// //
|
|
|
|
|
// Date: 11/09/2010 //
|
|
|
|
|
// //
|
|
|
|
|
// Author: Tom Shane //
|
|
|
|
|
// //
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
// //
|
|
|
|
|
// Copyright (c) by Tom Shane //
|
|
|
|
|
// //
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
#region //// Using /////////////
|
|
|
|
|
|
|
|
|
|
using Microsoft.Xna.Framework;
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
|
|
|
using Microsoft.Xna.Framework.Input;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Collections;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using Microsoft.Xna.Framework.GamerServices;
|
2015-12-05 19:57:37 +01:00
|
|
|
|
|
2015-12-04 10:23:49 +01:00
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
namespace TomShane.Neoforce.Controls
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
#region //// Enums /////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
public enum TextBoxMode
|
|
|
|
|
{
|
|
|
|
|
Normal,
|
|
|
|
|
Password,
|
|
|
|
|
Multiline
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region //// Classes ///////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
public class TextBox : ClipControl
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
#region //// Structs ///////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
private struct Selection
|
|
|
|
|
{
|
|
|
|
|
private int start;
|
|
|
|
|
private int end;
|
|
|
|
|
|
|
|
|
|
public int Start
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
if (start > end && start != -1 && end != -1) return end;
|
|
|
|
|
else return start;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
start = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int End
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
if (end < start && start != -1 && end != -1) return start;
|
|
|
|
|
else return end;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
end = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool IsEmpty
|
|
|
|
|
{
|
|
|
|
|
get { return Start == -1 && End == -1; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int Length
|
|
|
|
|
{
|
|
|
|
|
get { return IsEmpty ? 0 : (End - Start); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Selection(int start, int end)
|
|
|
|
|
{
|
|
|
|
|
this.start = start;
|
|
|
|
|
this.end = end;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Clear()
|
|
|
|
|
{
|
|
|
|
|
Start = -1;
|
|
|
|
|
End = -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region //// Consts ////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
private const string skTextBox = "TextBox";
|
|
|
|
|
private const string lrTextBox = "Control";
|
|
|
|
|
private const string lrCursor = "Cursor";
|
|
|
|
|
|
|
|
|
|
private const string crDefault = "Default";
|
|
|
|
|
private const string crText = "Text";
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region //// Fields ////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
private bool showCursor = false;
|
|
|
|
|
private double flashTime = 0;
|
|
|
|
|
private int posx = 0;
|
|
|
|
|
private int posy = 0;
|
|
|
|
|
private char passwordChar = '<27>';
|
|
|
|
|
private TextBoxMode mode = TextBoxMode.Normal;
|
|
|
|
|
private string shownText = "";
|
|
|
|
|
private bool readOnly = false;
|
|
|
|
|
private bool drawBorders = true;
|
|
|
|
|
private Selection selection = new Selection(-1, -1);
|
|
|
|
|
private bool caretVisible = true;
|
|
|
|
|
private ScrollBar horz = null;
|
|
|
|
|
private ScrollBar vert = null;
|
|
|
|
|
private List<string> lines = new List<string>();
|
|
|
|
|
private int linesDrawn = 0;
|
|
|
|
|
private int charsDrawn = 0;
|
|
|
|
|
private SpriteFont font = null;
|
|
|
|
|
private bool wordWrap = false;
|
|
|
|
|
private ScrollBars scrollBars = ScrollBars.Both;
|
|
|
|
|
private string Separator = "\n";
|
|
|
|
|
private string text = "";
|
|
|
|
|
private string buffer = "";
|
|
|
|
|
private bool autoSelection = true;
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region //// Properties ////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
private int PosX
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return posx;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
posx = value;
|
|
|
|
|
|
|
|
|
|
if (posx < 0) posx = 0;
|
|
|
|
|
if (posx > Lines[PosY].Length) posx = Lines[PosY].Length;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
private int PosY
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return posy;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
posy = value;
|
|
|
|
|
|
|
|
|
|
if (posy < 0) posy = 0;
|
|
|
|
|
if (posy > Lines.Count - 1) posy = Lines.Count - 1;
|
|
|
|
|
|
|
|
|
|
PosX = PosX;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
private int Pos
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return GetPos(PosX, PosY);
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
PosY = GetPosY(value);
|
|
|
|
|
PosX = GetPosX(value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
//>>>>
|
|
|
|
|
|
|
|
|
|
public virtual bool WordWrap
|
|
|
|
|
{
|
|
|
|
|
get { return wordWrap; }
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
wordWrap = value;
|
|
|
|
|
if (ClientArea != null) ClientArea.Invalidate();
|
|
|
|
|
SetupBars();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
public virtual ScrollBars ScrollBars
|
|
|
|
|
{
|
|
|
|
|
get { return scrollBars; }
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
scrollBars = value;
|
|
|
|
|
SetupBars();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
public virtual char PasswordChar
|
|
|
|
|
{
|
|
|
|
|
get { return passwordChar; }
|
|
|
|
|
set { passwordChar = value; if (ClientArea != null) ClientArea.Invalidate(); }
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
public virtual bool CaretVisible
|
|
|
|
|
{
|
|
|
|
|
get { return caretVisible; }
|
|
|
|
|
set { caretVisible = value; }
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
public virtual TextBoxMode Mode
|
|
|
|
|
{
|
|
|
|
|
get { return mode; }
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (value != TextBoxMode.Multiline)
|
|
|
|
|
{
|
|
|
|
|
Text = Text.Replace(Separator, "");
|
|
|
|
|
}
|
|
|
|
|
mode = value;
|
|
|
|
|
selection.Clear();
|
|
|
|
|
|
|
|
|
|
if (ClientArea != null) ClientArea.Invalidate();
|
|
|
|
|
SetupBars();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
public virtual bool ReadOnly
|
|
|
|
|
{
|
|
|
|
|
get { return readOnly; }
|
|
|
|
|
set { readOnly = value; }
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
public virtual bool DrawBorders
|
|
|
|
|
{
|
|
|
|
|
get { return drawBorders; }
|
|
|
|
|
set { drawBorders = value; if (ClientArea != null) ClientArea.Invalidate(); }
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
public virtual int CursorPosition
|
|
|
|
|
{
|
|
|
|
|
get { return Pos; }
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
Pos = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
public virtual string SelectedText
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
if (selection.IsEmpty)
|
|
|
|
|
{
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return Text.Substring(selection.Start, selection.Length);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
public virtual int SelectionStart
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
if (selection.IsEmpty)
|
|
|
|
|
{
|
|
|
|
|
return Pos;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return selection.Start;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
Pos = value;
|
|
|
|
|
if (Pos < 0) Pos = 0;
|
|
|
|
|
if (Pos > Text.Length) Pos = Text.Length;
|
|
|
|
|
selection.Start = Pos;
|
|
|
|
|
if (selection.End == -1) selection.End = Pos;
|
|
|
|
|
ClientArea.Invalidate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
public virtual bool AutoSelection
|
|
|
|
|
{
|
|
|
|
|
get { return autoSelection; }
|
|
|
|
|
set { autoSelection = value; }
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
public virtual int SelectionLength
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return selection.Length;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (value == 0)
|
|
|
|
|
{
|
|
|
|
|
selection.End = selection.Start;
|
|
|
|
|
}
|
|
|
|
|
else if (selection.IsEmpty)
|
|
|
|
|
{
|
|
|
|
|
selection.Start = 0;
|
|
|
|
|
selection.End = value;
|
|
|
|
|
}
|
|
|
|
|
else if (!selection.IsEmpty)
|
|
|
|
|
{
|
|
|
|
|
selection.End = selection.Start + value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!selection.IsEmpty)
|
|
|
|
|
{
|
|
|
|
|
if (selection.Start < 0) selection.Start = 0;
|
|
|
|
|
if (selection.Start > Text.Length) selection.Start = Text.Length;
|
|
|
|
|
if (selection.End < 0) selection.End = 0;
|
|
|
|
|
if (selection.End > Text.Length) selection.End = Text.Length;
|
|
|
|
|
}
|
|
|
|
|
ClientArea.Invalidate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
private List<string> Lines
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return lines;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
lines = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
public override string Text
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return text;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (wordWrap)
|
|
|
|
|
value = WrapWords(value, ClientWidth);
|
|
|
|
|
|
|
|
|
|
if (mode != TextBoxMode.Multiline && value != null)
|
|
|
|
|
{
|
|
|
|
|
value = value.Replace(Separator, "");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
text = value;
|
|
|
|
|
|
|
|
|
|
if (!Suspended) OnTextChanged(new EventArgs());
|
|
|
|
|
|
|
|
|
|
lines = SplitLines(text);
|
|
|
|
|
if (ClientArea != null) ClientArea.Invalidate();
|
|
|
|
|
|
|
|
|
|
SetupBars();
|
|
|
|
|
ProcessScrolling();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region //// Construstors //////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
public TextBox(Manager manager)
|
|
|
|
|
: base(manager)
|
|
|
|
|
{
|
|
|
|
|
CheckLayer(Skin, lrCursor);
|
|
|
|
|
|
|
|
|
|
SetDefaultSize(128, 20);
|
|
|
|
|
Lines.Add("");
|
|
|
|
|
|
|
|
|
|
ClientArea.Draw += new DrawEventHandler(ClientArea_Draw);
|
|
|
|
|
|
|
|
|
|
vert = new ScrollBar(manager, Orientation.Vertical);
|
|
|
|
|
horz = new ScrollBar(manager, Orientation.Horizontal);
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region //// Methods ///////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
public override void Init()
|
|
|
|
|
{
|
|
|
|
|
base.Init();
|
|
|
|
|
|
|
|
|
|
vert.Init();
|
|
|
|
|
vert.Range = 1;
|
|
|
|
|
vert.PageSize = 1;
|
|
|
|
|
vert.Value = 0;
|
|
|
|
|
vert.Anchor = Anchors.Top | Anchors.Right | Anchors.Bottom;
|
|
|
|
|
vert.ValueChanged += new EventHandler(sb_ValueChanged);
|
|
|
|
|
|
|
|
|
|
horz.Init();
|
|
|
|
|
horz.Range = ClientArea.Width;
|
|
|
|
|
horz.PageSize = ClientArea.Width;
|
|
|
|
|
horz.Value = 0;
|
|
|
|
|
horz.Anchor = Anchors.Right | Anchors.Left | Anchors.Bottom;
|
|
|
|
|
horz.ValueChanged += new EventHandler(sb_ValueChanged);
|
|
|
|
|
|
|
|
|
|
horz.Visible = false;
|
|
|
|
|
vert.Visible = false;
|
|
|
|
|
|
|
|
|
|
Add(vert, false);
|
|
|
|
|
Add(horz, false);
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
protected internal override void InitSkin()
|
|
|
|
|
{
|
|
|
|
|
base.InitSkin();
|
|
|
|
|
Skin = new SkinControl(Manager.Skin.Controls[skTextBox]);
|
|
|
|
|
|
|
|
|
|
#if (!XBOX && !XBOX_FAKE)
|
|
|
|
|
Cursor = Manager.Skin.Cursors[crText].Resource;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
font = (Skin.Layers[lrTextBox].Text != null) ? Skin.Layers[lrTextBox].Text.Font.Resource : null;
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
protected override void DrawControl(Renderer renderer, Rectangle rect, GameTime gameTime)
|
|
|
|
|
{
|
|
|
|
|
if (drawBorders)
|
|
|
|
|
{
|
|
|
|
|
base.DrawControl(renderer, rect, gameTime);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
private int GetFitChars(string text, int width)
|
|
|
|
|
{
|
|
|
|
|
int ret = text.Length;
|
|
|
|
|
int size = 0;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < text.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
size = (int)font.MeasureString(text.Substring(0, i)).X;
|
|
|
|
|
if (size > width)
|
|
|
|
|
{
|
|
|
|
|
ret = i;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
private void DeterminePages()
|
|
|
|
|
{
|
|
|
|
|
if (ClientArea != null)
|
|
|
|
|
{
|
|
|
|
|
int sizey = (int)font.LineSpacing;
|
|
|
|
|
linesDrawn = (int)(ClientArea.Height / sizey);
|
|
|
|
|
if (linesDrawn > Lines.Count) linesDrawn = Lines.Count;
|
|
|
|
|
|
|
|
|
|
charsDrawn = ClientArea.Width - 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
private string GetMaxLine()
|
|
|
|
|
{
|
|
|
|
|
int max = 0;
|
|
|
|
|
int x = 0;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < Lines.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
if (Lines[i].Length > max)
|
|
|
|
|
{
|
|
|
|
|
max = Lines[i].Length;
|
|
|
|
|
x = i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return Lines.Count > 0 ? Lines[x] : "";
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
void ClientArea_Draw(object sender, DrawEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
SkinLayer layer = Skin.Layers[lrTextBox];
|
|
|
|
|
Color col = Skin.Layers[lrTextBox].Text.Colors.Enabled;
|
|
|
|
|
SkinLayer cursor = Skin.Layers[lrCursor];
|
|
|
|
|
Alignment al = mode == TextBoxMode.Multiline ? Alignment.TopLeft : Alignment.MiddleLeft;
|
|
|
|
|
Renderer renderer = e.Renderer;
|
|
|
|
|
Rectangle r = e.Rectangle;
|
|
|
|
|
bool drawsel = !selection.IsEmpty;
|
|
|
|
|
string tmpText = "";
|
|
|
|
|
|
|
|
|
|
font = (Skin.Layers[lrTextBox].Text != null) ? Skin.Layers[lrTextBox].Text.Font.Resource : null;
|
|
|
|
|
|
|
|
|
|
if (Text != null && font != null)
|
|
|
|
|
{
|
|
|
|
|
DeterminePages();
|
|
|
|
|
|
|
|
|
|
if (mode == TextBoxMode.Multiline)
|
|
|
|
|
{
|
|
|
|
|
shownText = Text;
|
|
|
|
|
tmpText = Lines[PosY];
|
|
|
|
|
}
|
|
|
|
|
else if (mode == TextBoxMode.Password)
|
|
|
|
|
{
|
|
|
|
|
shownText = "";
|
|
|
|
|
for (int i = 0; i < Text.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
shownText = shownText + passwordChar;
|
|
|
|
|
}
|
|
|
|
|
tmpText = shownText;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
shownText = Text;
|
|
|
|
|
tmpText = Lines[PosY];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (TextColor != UndefinedColor && ControlState != ControlState.Disabled)
|
|
|
|
|
{
|
|
|
|
|
col = TextColor;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mode != TextBoxMode.Multiline)
|
|
|
|
|
{
|
|
|
|
|
linesDrawn = 0;
|
|
|
|
|
vert.Value = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (drawsel)
|
|
|
|
|
{
|
|
|
|
|
DrawSelection(e.Renderer, r);
|
|
|
|
|
/*
|
|
|
|
|
renderer.End();
|
|
|
|
|
renderer.SpriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.None);
|
|
|
|
|
renderer.SpriteBatch.GraphicsDevice.RenderState.SeparateAlphaBlendEnabled = true;
|
|
|
|
|
renderer.SpriteBatch.GraphicsDevice.RenderState.SourceBlend = Blend.DestinationColor;
|
|
|
|
|
renderer.SpriteBatch.GraphicsDevice.RenderState.DestinationBlend = Blend.SourceColor;
|
|
|
|
|
renderer.SpriteBatch.GraphicsDevice.RenderState.BlendFunction = BlendFunction.Subtract;
|
|
|
|
|
//renderer.SpriteBatch.GraphicsDevice.RenderState.AlphaFunction = CompareFunction.Equal;
|
|
|
|
|
//renderer.SpriteBatch.GraphicsDevice.RenderState.AlphaSourceBlend = Blend.One;
|
|
|
|
|
//renderer.SpriteBatch.GraphicsDevice.RenderState.AlphaDestinationBlend = Blend.DestinationAlpha;
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int sizey = (int)font.LineSpacing;
|
|
|
|
|
|
|
|
|
|
if (showCursor && caretVisible)
|
|
|
|
|
{
|
|
|
|
|
Vector2 size = Vector2.Zero;
|
|
|
|
|
if (PosX > 0 && PosX <= tmpText.Length)
|
|
|
|
|
{
|
|
|
|
|
size = font.MeasureString(tmpText.Substring(0, PosX));
|
|
|
|
|
}
|
|
|
|
|
if (size.Y == 0)
|
|
|
|
|
{
|
|
|
|
|
size = font.MeasureString(" ");
|
|
|
|
|
size.X = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int m = r.Height - font.LineSpacing;
|
|
|
|
|
|
|
|
|
|
Rectangle rc = new Rectangle(r.Left - horz.Value + (int)size.X, r.Top + m / 2, cursor.Width, font.LineSpacing);
|
|
|
|
|
|
|
|
|
|
if (mode == TextBoxMode.Multiline)
|
|
|
|
|
{
|
|
|
|
|
rc = new Rectangle(r.Left + (int)size.X - horz.Value, r.Top + (int)((PosY - vert.Value) * font.LineSpacing), cursor.Width, font.LineSpacing);
|
|
|
|
|
}
|
|
|
|
|
cursor.Alignment = al;
|
|
|
|
|
renderer.DrawLayer(cursor, rc, col, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < linesDrawn + 1; i++)
|
|
|
|
|
{
|
|
|
|
|
int ii = i + vert.Value;
|
|
|
|
|
if (ii >= Lines.Count || ii < 0) break;
|
|
|
|
|
|
|
|
|
|
if (Lines[ii] != "")
|
|
|
|
|
{
|
|
|
|
|
if (mode == TextBoxMode.Multiline)
|
|
|
|
|
{
|
|
|
|
|
renderer.DrawString(font, Lines[ii], r.Left - horz.Value, r.Top + (i * sizey), col);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Rectangle rx = new Rectangle(r.Left - horz.Value, r.Top, r.Width, r.Height);
|
|
|
|
|
renderer.DrawString(font, shownText, rx, col, al, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* if (drawsel)
|
|
|
|
|
{
|
|
|
|
|
renderer.End();
|
|
|
|
|
renderer.Begin(BlendingMode.Premultiplied);
|
|
|
|
|
}*/
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
private int GetStringWidth(string text, int count)
|
|
|
|
|
{
|
|
|
|
|
if (count > text.Length) count = text.Length;
|
|
|
|
|
return (int)font.MeasureString(text.Substring(0, count)).X;
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
private void ProcessScrolling()
|
|
|
|
|
{
|
|
|
|
|
if (vert != null && horz != null)
|
|
|
|
|
{
|
|
|
|
|
vert.PageSize = linesDrawn;
|
|
|
|
|
horz.PageSize = charsDrawn;
|
|
|
|
|
|
|
|
|
|
if (horz.PageSize > horz.Range) horz.PageSize = horz.Range;
|
|
|
|
|
|
|
|
|
|
if (PosY >= vert.Value + vert.PageSize)
|
|
|
|
|
{
|
|
|
|
|
vert.Value = (PosY + 1) - vert.PageSize;
|
|
|
|
|
}
|
|
|
|
|
else if (PosY < vert.Value)
|
|
|
|
|
{
|
|
|
|
|
vert.Value = PosY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (GetStringWidth(Lines[PosY], PosX) >= horz.Value + horz.PageSize)
|
|
|
|
|
{
|
|
|
|
|
horz.Value = (GetStringWidth(Lines[PosY], PosX) + 1) - horz.PageSize;
|
|
|
|
|
}
|
|
|
|
|
else if (GetStringWidth(Lines[PosY], PosX) < horz.Value)
|
|
|
|
|
{
|
|
|
|
|
horz.Value = GetStringWidth(Lines[PosY], PosX) - horz.PageSize;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
private void DrawSelection(Renderer renderer, Rectangle rect)
|
|
|
|
|
{
|
|
|
|
|
if (!selection.IsEmpty)
|
|
|
|
|
{
|
|
|
|
|
int s = selection.Start;
|
|
|
|
|
int e = selection.End;
|
|
|
|
|
|
|
|
|
|
int sl = GetPosY(s);
|
|
|
|
|
int el = GetPosY(e);
|
|
|
|
|
int sc = GetPosX(s);
|
|
|
|
|
int ec = GetPosX(e);
|
|
|
|
|
|
|
|
|
|
int hgt = font.LineSpacing;
|
|
|
|
|
|
|
|
|
|
int start = sl;
|
|
|
|
|
int end = el;
|
|
|
|
|
|
|
|
|
|
if (start < vert.Value) start = vert.Value;
|
|
|
|
|
if (end > vert.Value + linesDrawn) end = vert.Value + linesDrawn;
|
|
|
|
|
|
|
|
|
|
for (int i = start; i <= end; i++)
|
|
|
|
|
{
|
|
|
|
|
Rectangle r = Rectangle.Empty;
|
|
|
|
|
|
|
|
|
|
if (mode == TextBoxMode.Normal)
|
|
|
|
|
{
|
|
|
|
|
int m = ClientArea.Height - font.LineSpacing;
|
|
|
|
|
r = new Rectangle(rect.Left - horz.Value + (int)font.MeasureString(Lines[i].Substring(0, sc)).X, rect.Top + m / 2,
|
|
|
|
|
(int)font.MeasureString(Lines[i].Substring(0, ec + 0)).X - (int)font.MeasureString(Lines[i].Substring(0, sc)).X, hgt);
|
|
|
|
|
}
|
|
|
|
|
else if (sl == el)
|
|
|
|
|
{
|
|
|
|
|
r = new Rectangle(rect.Left - horz.Value + (int)font.MeasureString(Lines[i].Substring(0, sc)).X, rect.Top + (i - vert.Value) * hgt,
|
|
|
|
|
(int)font.MeasureString(Lines[i].Substring(0, ec + 0)).X - (int)font.MeasureString(Lines[i].Substring(0, sc)).X, hgt);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (i == sl) r = new Rectangle(rect.Left - horz.Value + (int)font.MeasureString(Lines[i].Substring(0, sc)).X, rect.Top + (i - vert.Value) * hgt, (int)font.MeasureString(Lines[i]).X - (int)font.MeasureString(Lines[i].Substring(0, sc)).X, hgt);
|
|
|
|
|
else if (i == el) r = new Rectangle(rect.Left - horz.Value, rect.Top + (i - vert.Value) * hgt, (int)font.MeasureString(Lines[i].Substring(0, ec + 0)).X, hgt);
|
|
|
|
|
else r = new Rectangle(rect.Left - horz.Value, rect.Top + (i - vert.Value) * hgt, (int)font.MeasureString(Lines[i]).X, hgt);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
renderer.Draw(Manager.Skin.Images["Control"].Resource, r, Color.FromNonPremultiplied(160, 160, 160, 128));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
protected internal override void Update(GameTime gameTime)
|
|
|
|
|
{
|
|
|
|
|
base.Update(gameTime);
|
|
|
|
|
|
|
|
|
|
bool sc = showCursor;
|
|
|
|
|
|
|
|
|
|
showCursor = Focused;
|
|
|
|
|
|
|
|
|
|
if (Focused)
|
|
|
|
|
{
|
|
|
|
|
flashTime += gameTime.ElapsedGameTime.TotalSeconds;
|
|
|
|
|
showCursor = flashTime < 0.5;
|
|
|
|
|
if (flashTime > 1) flashTime = 0;
|
|
|
|
|
}
|
|
|
|
|
if (sc != showCursor) ClientArea.Invalidate();
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
private int FindPrevWord(string text)
|
|
|
|
|
{
|
|
|
|
|
bool letter = false;
|
|
|
|
|
|
|
|
|
|
int p = Pos - 1;
|
|
|
|
|
if (p < 0) p = 0;
|
|
|
|
|
if (p >= text.Length) p = text.Length - 1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = p; i >= 0; i--)
|
|
|
|
|
{
|
|
|
|
|
if (char.IsLetterOrDigit(text[i]))
|
|
|
|
|
{
|
|
|
|
|
letter = true;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (letter && !char.IsLetterOrDigit(text[i]))
|
|
|
|
|
{
|
|
|
|
|
return i + 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
private int FindNextWord(string text)
|
|
|
|
|
{
|
|
|
|
|
bool space = false;
|
|
|
|
|
|
|
|
|
|
for (int i = Pos; i < text.Length - 1; i++)
|
|
|
|
|
{
|
|
|
|
|
if (!char.IsLetterOrDigit(text[i]))
|
|
|
|
|
{
|
|
|
|
|
space = true;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (space && char.IsLetterOrDigit(text[i]))
|
|
|
|
|
{
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return text.Length;
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
private int GetPosY(int pos)
|
|
|
|
|
{
|
|
|
|
|
if (pos >= Text.Length) return Lines.Count - 1;
|
|
|
|
|
|
|
|
|
|
int p = pos;
|
|
|
|
|
for (int i = 0; i < Lines.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
p -= Lines[i].Length + Separator.Length;
|
|
|
|
|
if (p < 0)
|
|
|
|
|
{
|
|
|
|
|
p = p + Lines[i].Length + Separator.Length;
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
private int GetPosX(int pos)
|
|
|
|
|
{
|
|
|
|
|
if (pos >= Text.Length) return Lines[Lines.Count - 1].Length;
|
|
|
|
|
|
|
|
|
|
int p = pos;
|
|
|
|
|
for (int i = 0; i < Lines.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
p -= Lines[i].Length + Separator.Length;
|
|
|
|
|
if (p < 0)
|
|
|
|
|
{
|
|
|
|
|
p = p + Lines[i].Length + Separator.Length;
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
private int GetPos(int x, int y)
|
|
|
|
|
{
|
|
|
|
|
int p = 0;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < y; i++)
|
|
|
|
|
{
|
|
|
|
|
p += Lines[i].Length + Separator.Length;
|
|
|
|
|
}
|
|
|
|
|
p += x;
|
|
|
|
|
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
private int CharAtPos(Point pos)
|
|
|
|
|
{
|
|
|
|
|
int x = pos.X;
|
|
|
|
|
int y = pos.Y;
|
|
|
|
|
int px = 0;
|
|
|
|
|
int py = 0;
|
|
|
|
|
|
|
|
|
|
if (mode == TextBoxMode.Multiline)
|
|
|
|
|
{
|
|
|
|
|
py = vert.Value + (int)((y - ClientTop) / font.LineSpacing);
|
|
|
|
|
if (py < 0) py = 0;
|
|
|
|
|
if (py >= Lines.Count) py = Lines.Count - 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
py = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string str = mode == TextBoxMode.Multiline ? Lines[py] : shownText;
|
|
|
|
|
|
|
|
|
|
if (str != null && str != "")
|
|
|
|
|
{
|
|
|
|
|
for (int i = 1; i <= Lines[py].Length; i++)
|
|
|
|
|
{
|
|
|
|
|
Vector2 v = font.MeasureString(str.Substring(0, i)) - (font.MeasureString(str[i - 1].ToString()) / 3);
|
|
|
|
|
if (x <= (ClientLeft + (int)v.X) - horz.Value)
|
|
|
|
|
{
|
|
|
|
|
px = i - 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (x > ClientLeft + ((int)font.MeasureString(str).X) - horz.Value - (font.MeasureString(str[str.Length - 1].ToString()).X / 3)) px = str.Length;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return GetPos(px, py);
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
protected override void OnMouseDown(MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
base.OnMouseDown(e);
|
|
|
|
|
|
|
|
|
|
flashTime = 0;
|
|
|
|
|
|
|
|
|
|
Pos = CharAtPos(e.Position);
|
|
|
|
|
selection.Clear();
|
|
|
|
|
|
|
|
|
|
if (e.Button == MouseButton.Left && caretVisible && mode != TextBoxMode.Password)
|
|
|
|
|
{
|
|
|
|
|
selection.Start = Pos;
|
|
|
|
|
selection.End = Pos;
|
|
|
|
|
}
|
|
|
|
|
ClientArea.Invalidate();
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
protected override void OnMouseMove(MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
base.OnMouseMove(e);
|
|
|
|
|
|
|
|
|
|
if (e.Button == MouseButton.Left && !selection.IsEmpty && mode != TextBoxMode.Password && selection.Length < Text.Length)
|
|
|
|
|
{
|
|
|
|
|
int pos = CharAtPos(e.Position);
|
|
|
|
|
selection.End = CharAtPos(e.Position);
|
|
|
|
|
Pos = pos;
|
|
|
|
|
|
|
|
|
|
ClientArea.Invalidate();
|
|
|
|
|
|
|
|
|
|
ProcessScrolling();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
protected override void OnMouseUp(MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
base.OnMouseUp(e);
|
|
|
|
|
|
|
|
|
|
if (e.Button == MouseButton.Left && !selection.IsEmpty && mode != TextBoxMode.Password)
|
|
|
|
|
{
|
|
|
|
|
if (selection.Length == 0) selection.Clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
protected override void OnMouseScroll(MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (Mode != TextBoxMode.Multiline)
|
|
|
|
|
{
|
|
|
|
|
base.OnMouseScroll(e);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (e.ScrollDirection == MouseScrollDirection.Down)
|
|
|
|
|
vert.ScrollDown();
|
|
|
|
|
else
|
|
|
|
|
vert.ScrollUp();
|
|
|
|
|
|
|
|
|
|
base.OnMouseScroll(e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
protected override void OnKeyPress(KeyEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
flashTime = 0;
|
|
|
|
|
|
|
|
|
|
if (Manager.UseGuide && Guide.IsVisible) return;
|
|
|
|
|
|
|
|
|
|
if (!e.Handled)
|
|
|
|
|
{
|
|
|
|
|
if (e.Key == Keys.A && e.Control && mode != TextBoxMode.Password)
|
|
|
|
|
{
|
|
|
|
|
SelectAll();
|
|
|
|
|
}
|
|
|
|
|
if (e.Key == Keys.Up)
|
|
|
|
|
{
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
|
|
|
|
|
if (e.Shift && selection.IsEmpty && mode != TextBoxMode.Password)
|
|
|
|
|
{
|
|
|
|
|
selection.Start = Pos;
|
|
|
|
|
}
|
|
|
|
|
if (!e.Control)
|
|
|
|
|
{
|
|
|
|
|
PosY -= 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (e.Key == Keys.Down)
|
|
|
|
|
{
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
if (e.Shift && selection.IsEmpty && mode != TextBoxMode.Password)
|
|
|
|
|
{
|
|
|
|
|
selection.Start = Pos;
|
|
|
|
|
}
|
|
|
|
|
if (!e.Control)
|
|
|
|
|
{
|
|
|
|
|
PosY += 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (e.Key == Keys.Back && !readOnly)
|
|
|
|
|
{
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
if (!selection.IsEmpty)
|
|
|
|
|
{
|
|
|
|
|
Text = Text.Remove(selection.Start, selection.Length);
|
|
|
|
|
Pos = selection.Start;
|
|
|
|
|
}
|
|
|
|
|
else if (Text.Length > 0 && Pos > 0)
|
|
|
|
|
{
|
|
|
|
|
Pos -= 1;
|
|
|
|
|
Text = Text.Remove(Pos, 1);
|
|
|
|
|
}
|
|
|
|
|
selection.Clear();
|
|
|
|
|
}
|
|
|
|
|
else if (e.Key == Keys.Delete && !readOnly)
|
|
|
|
|
{
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
if (!selection.IsEmpty)
|
|
|
|
|
{
|
|
|
|
|
Text = Text.Remove(selection.Start, selection.Length);
|
|
|
|
|
Pos = selection.Start;
|
|
|
|
|
}
|
|
|
|
|
else if (Pos < Text.Length)
|
|
|
|
|
{
|
|
|
|
|
Text = Text.Remove(Pos, 1);
|
|
|
|
|
}
|
|
|
|
|
selection.Clear();
|
|
|
|
|
}
|
|
|
|
|
else if (e.Key == Keys.Left)
|
|
|
|
|
{
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
if (e.Shift && selection.IsEmpty && mode != TextBoxMode.Password)
|
|
|
|
|
{
|
|
|
|
|
selection.Start = Pos;
|
|
|
|
|
}
|
|
|
|
|
if (!e.Control)
|
|
|
|
|
{
|
|
|
|
|
Pos -= 1;
|
|
|
|
|
}
|
|
|
|
|
if (e.Control)
|
|
|
|
|
{
|
|
|
|
|
Pos = FindPrevWord(shownText);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (e.Key == Keys.Right)
|
|
|
|
|
{
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
if (e.Shift && selection.IsEmpty && mode != TextBoxMode.Password)
|
|
|
|
|
{
|
|
|
|
|
selection.Start = Pos;
|
|
|
|
|
}
|
|
|
|
|
if (!e.Control)
|
|
|
|
|
{
|
|
|
|
|
Pos += 1;
|
|
|
|
|
}
|
|
|
|
|
if (e.Control)
|
|
|
|
|
{
|
|
|
|
|
Pos = FindNextWord(shownText);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (e.Key == Keys.Home)
|
|
|
|
|
{
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
if (e.Shift && selection.IsEmpty && mode != TextBoxMode.Password)
|
|
|
|
|
{
|
|
|
|
|
selection.Start = Pos;
|
|
|
|
|
}
|
|
|
|
|
if (!e.Control)
|
|
|
|
|
{
|
|
|
|
|
PosX = 0;
|
|
|
|
|
}
|
|
|
|
|
if (e.Control)
|
|
|
|
|
{
|
|
|
|
|
Pos = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (e.Key == Keys.End)
|
|
|
|
|
{
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
if (e.Shift && selection.IsEmpty && mode != TextBoxMode.Password)
|
|
|
|
|
{
|
|
|
|
|
selection.Start = Pos;
|
|
|
|
|
}
|
|
|
|
|
if (!e.Control)
|
|
|
|
|
{
|
|
|
|
|
PosX = Lines[PosY].Length;
|
|
|
|
|
}
|
|
|
|
|
if (e.Control)
|
|
|
|
|
{
|
|
|
|
|
Pos = Text.Length;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (e.Key == Keys.PageUp)
|
|
|
|
|
{
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
if (e.Shift && selection.IsEmpty && mode != TextBoxMode.Password)
|
|
|
|
|
{
|
|
|
|
|
selection.Start = Pos;
|
|
|
|
|
}
|
|
|
|
|
if (!e.Control)
|
|
|
|
|
{
|
|
|
|
|
PosY -= linesDrawn;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (e.Key == Keys.PageDown)
|
|
|
|
|
{
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
if (e.Shift && selection.IsEmpty && mode != TextBoxMode.Password)
|
|
|
|
|
{
|
|
|
|
|
selection.Start = Pos;
|
|
|
|
|
}
|
|
|
|
|
if (!e.Control)
|
|
|
|
|
{
|
|
|
|
|
PosY += linesDrawn;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (e.Key == Keys.Enter && mode == TextBoxMode.Multiline && !readOnly)
|
|
|
|
|
{
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
Text = Text.Insert(Pos, Separator);
|
|
|
|
|
PosX = 0;
|
|
|
|
|
PosY += 1;
|
|
|
|
|
}
|
|
|
|
|
else if (e.Key == Keys.Tab)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
else if (!readOnly && !e.Control)
|
|
|
|
|
{
|
|
|
|
|
string c = Manager.KeyboardLayout.GetKey(e);
|
|
|
|
|
if (selection.IsEmpty)
|
|
|
|
|
{
|
|
|
|
|
Text = Text.Insert(Pos, c);
|
|
|
|
|
if (c != "") PosX += 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (Text.Length > 0)
|
|
|
|
|
{
|
|
|
|
|
Text = Text.Remove(selection.Start, selection.Length);
|
|
|
|
|
Text = Text.Insert(selection.Start, c);
|
|
|
|
|
Pos = selection.Start + 1;
|
|
|
|
|
}
|
|
|
|
|
selection.Clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (e.Shift && !selection.IsEmpty)
|
|
|
|
|
{
|
|
|
|
|
selection.End = Pos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* TODO: Fix
|
|
|
|
|
* MONOTODO: Fix
|
|
|
|
|
if (e.Control && e.Key == Keys.C && mode != TextBoxMode.Password)
|
|
|
|
|
{
|
|
|
|
|
#if (!XBOX && !XBOX_FAKE)
|
|
|
|
|
System.Windows.Forms.Clipboard.Clear();
|
|
|
|
|
if (mode != TextBoxMode.Password && !selection.IsEmpty)
|
|
|
|
|
{
|
|
|
|
|
System.Windows.Forms.Clipboard.SetText((Text.Substring(selection.Start, selection.Length)).Replace("\n", Environment.NewLine));
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
else if (e.Control && e.Key == Keys.V && !readOnly && mode != TextBoxMode.Password)
|
|
|
|
|
{
|
|
|
|
|
#if (!XBOX && !XBOX_FAKE)
|
|
|
|
|
string t = System.Windows.Forms.Clipboard.GetText().Replace(Environment.NewLine, "\n");
|
|
|
|
|
if (selection.IsEmpty)
|
|
|
|
|
{
|
|
|
|
|
Text = Text.Insert(Pos, t);
|
|
|
|
|
Pos = Pos + t.Length;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Text = Text.Remove(selection.Start, selection.Length);
|
|
|
|
|
Text = Text.Insert(selection.Start, t);
|
|
|
|
|
PosX = selection.Start + t.Length;
|
|
|
|
|
selection.Clear();
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
if ((!e.Shift && !e.Control) || Text.Length <= 0)
|
|
|
|
|
{
|
|
|
|
|
selection.Clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (e.Control && e.Key == Keys.Down)
|
|
|
|
|
{
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
HandleGuide(PlayerIndex.One);
|
|
|
|
|
}
|
|
|
|
|
flashTime = 0;
|
|
|
|
|
if (ClientArea != null) ClientArea.Invalidate();
|
|
|
|
|
|
|
|
|
|
DeterminePages();
|
|
|
|
|
ProcessScrolling();
|
|
|
|
|
}
|
|
|
|
|
base.OnKeyPress(e);
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
protected override void OnGamePadDown(GamePadEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (Manager.UseGuide && Guide.IsVisible) return;
|
|
|
|
|
|
|
|
|
|
if (!e.Handled)
|
|
|
|
|
{
|
|
|
|
|
if (e.Button == GamePadActions.Click)
|
|
|
|
|
{
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
HandleGuide(e.PlayerIndex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
base.OnGamePadDown(e);
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
private void HandleGuide(PlayerIndex pi)
|
|
|
|
|
{
|
|
|
|
|
if (Manager.UseGuide && !Guide.IsVisible)
|
|
|
|
|
{
|
|
|
|
|
Guide.BeginShowKeyboardInput(pi, "Enter Text", "", Text, GetText, pi.ToString());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
private void GetText(IAsyncResult result)
|
|
|
|
|
{
|
|
|
|
|
string res = Guide.EndShowKeyboardInput(result);
|
|
|
|
|
Text = res != null ? res : "";
|
|
|
|
|
Pos = text.Length;
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
private void SetupBars()
|
|
|
|
|
{
|
|
|
|
|
DeterminePages();
|
|
|
|
|
|
|
|
|
|
if (vert != null) vert.Range = Lines.Count;
|
|
|
|
|
if (horz != null)
|
|
|
|
|
{
|
|
|
|
|
horz.Range = (int)font.MeasureString(GetMaxLine()).X;
|
|
|
|
|
if (horz.Range == 0) horz.Range = ClientArea.Width;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (vert != null)
|
|
|
|
|
{
|
|
|
|
|
vert.Left = Width - 16 - 2;
|
|
|
|
|
vert.Top = 2;
|
|
|
|
|
vert.Height = Height - 4 - 16;
|
|
|
|
|
|
|
|
|
|
if (Height < 50 || (scrollBars != ScrollBars.Both && scrollBars != ScrollBars.Vertical)) vert.Visible = false;
|
|
|
|
|
else if ((scrollBars == ScrollBars.Vertical || scrollBars == ScrollBars.Both) && mode == TextBoxMode.Multiline) vert.Visible = true;
|
|
|
|
|
}
|
|
|
|
|
if (horz != null)
|
|
|
|
|
{
|
|
|
|
|
horz.Left = 2;
|
|
|
|
|
horz.Top = Height - 16 - 2;
|
|
|
|
|
horz.Width = Width - 4 - 16;
|
|
|
|
|
|
|
|
|
|
if (Width < 50 || wordWrap || (scrollBars != ScrollBars.Both && scrollBars != ScrollBars.Horizontal)) horz.Visible = false;
|
|
|
|
|
else if ((scrollBars == ScrollBars.Horizontal || scrollBars == ScrollBars.Both) && mode == TextBoxMode.Multiline && !wordWrap) horz.Visible = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AdjustMargins();
|
|
|
|
|
|
|
|
|
|
if (vert != null) vert.PageSize = linesDrawn;
|
|
|
|
|
if (horz != null) horz.PageSize = charsDrawn;
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
protected override void AdjustMargins()
|
|
|
|
|
{
|
|
|
|
|
if (horz != null && !horz.Visible)
|
|
|
|
|
{
|
|
|
|
|
vert.Height = Height - 4;
|
|
|
|
|
ClientMargins = new Margins(ClientMargins.Left, ClientMargins.Top, ClientMargins.Right, Skin.ClientMargins.Bottom);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ClientMargins = new Margins(ClientMargins.Left, ClientMargins.Top, ClientMargins.Right, 18 + Skin.ClientMargins.Bottom);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (vert != null && !vert.Visible)
|
|
|
|
|
{
|
|
|
|
|
horz.Width = Width - 4;
|
|
|
|
|
ClientMargins = new Margins(ClientMargins.Left, ClientMargins.Top, Skin.ClientMargins.Right, ClientMargins.Bottom);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ClientMargins = new Margins(ClientMargins.Left, ClientMargins.Top, 18 + Skin.ClientMargins.Right, ClientMargins.Bottom);
|
|
|
|
|
}
|
|
|
|
|
base.AdjustMargins();
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
protected override void OnResize(ResizeEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
base.OnResize(e);
|
|
|
|
|
selection.Clear();
|
|
|
|
|
SetupBars();
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
private string WrapWords(string text, int size)
|
|
|
|
|
{
|
|
|
|
|
string ret = "";
|
|
|
|
|
string line = "";
|
|
|
|
|
|
|
|
|
|
string[] words = text.Replace("\v", "").Split(" ".ToCharArray());
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < words.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
if (font.MeasureString(line + words[i]).X > size)
|
|
|
|
|
{
|
|
|
|
|
ret += line + "\n";
|
|
|
|
|
line = words[i] + " ";
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
line += words[i] + " ";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret += line;
|
|
|
|
|
|
|
|
|
|
return ret.Remove(ret.Length - 1, 1);
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
public virtual void SelectAll()
|
|
|
|
|
{
|
|
|
|
|
if (text.Length > 0)
|
|
|
|
|
{
|
|
|
|
|
selection.Start = 0;
|
|
|
|
|
selection.End = Text.Length;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
private List<string> SplitLines(string text)
|
|
|
|
|
{
|
|
|
|
|
if (buffer != text)
|
|
|
|
|
{
|
|
|
|
|
buffer = text;
|
|
|
|
|
List<string> list = new List<string>();
|
|
|
|
|
string[] s = text.Split(new char[] { Separator[0] });
|
|
|
|
|
list.Clear();
|
|
|
|
|
|
|
|
|
|
//Before adding the lines back in, we will want to first, measure the lines, and split words if needed...
|
|
|
|
|
|
|
|
|
|
list.AddRange(s);
|
|
|
|
|
|
|
|
|
|
if (posy < 0) posy = 0;
|
|
|
|
|
if (posy > list.Count - 1) posy = list.Count - 1;
|
|
|
|
|
|
|
|
|
|
if (posx < 0) posx = 0;
|
|
|
|
|
if (posx > list[PosY].Length) posx = list[PosY].Length;
|
|
|
|
|
|
|
|
|
|
return list;
|
|
|
|
|
}
|
|
|
|
|
else return lines;
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
void sb_ValueChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
ClientArea.Invalidate();
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
protected override void OnFocusLost(EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
selection.Clear();
|
|
|
|
|
ClientArea.Invalidate();
|
|
|
|
|
base.OnFocusLost(e);
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
protected override void OnFocusGained(EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (!readOnly && autoSelection)
|
|
|
|
|
{
|
|
|
|
|
SelectAll();
|
|
|
|
|
ClientArea.Invalidate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
base.OnFocusGained(e);
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
}
|