123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569 |
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Text.RegularExpressions;
- using UnityEngine;
- using FairyGUI.Utils;
- namespace FairyGUI
- {
-
-
-
- public class InputTextField : RichTextField
- {
-
-
-
- public int maxLength { get; set; }
-
-
-
-
- public bool keyboardInput { get; set; }
-
-
-
- public int keyboardType { get; set; }
-
-
-
- public bool hideInput { get; set; }
-
-
-
- public bool disableIME { get; set; }
-
-
-
- public bool mouseWheelEnabled { get; set; }
-
-
-
- public static Action<InputTextField, string> onCopy;
-
-
-
- public static Action<InputTextField> onPaste;
-
-
-
- public static PopupMenu contextMenu;
- string _text;
- string _restrict;
- Regex _restrictPattern;
- bool _displayAsPassword;
- string _promptText;
- string _decodedPromptText;
- int _border;
- int _corner;
- Color _borderColor;
- Color _backgroundColor;
- bool _editable;
- bool _editing;
- int _caretPosition;
- int _selectionStart;
- int _composing;
- char _highSurrogateChar;
- string _textBeforeEdit;
- EventListener _onChanged;
- EventListener _onSubmit;
- Shape _caret;
- SelectionShape _selectionShape;
- float _nextBlink;
- const int GUTTER_X = 2;
- const int GUTTER_Y = 2;
- public InputTextField()
- {
- gameObject.name = "InputTextField";
- _text = string.Empty;
- maxLength = 0;
- _editable = true;
- _composing = 0;
- keyboardInput = Stage.keyboardInput;
- _borderColor = Color.black;
- _backgroundColor = Color.clear;
- mouseWheelEnabled = true;
- this.tabStop = true;
- cursor = "text-ibeam";
-
- this.hitArea = new RectHitTest();
- this.touchChildren = false;
- onFocusIn.Add(__focusIn);
- onFocusOut.AddCapture(__focusOut);
- onKeyDown.Add(__keydown);
- onTouchBegin.AddCapture(__touchBegin);
- onTouchMove.AddCapture(__touchMove);
- onMouseWheel.Add(__mouseWheel);
- onClick.Add(__click);
- onRightClick.Add(__rightClick);
- }
-
-
-
- public EventListener onChanged
- {
- get { return _onChanged ?? (_onChanged = new EventListener(this, "onChanged")); }
- }
-
-
-
- public EventListener onSubmit
- {
- get { return _onSubmit ?? (_onSubmit = new EventListener(this, "onSubmit")); }
- }
-
-
-
- public override string text
- {
- get
- {
- return _text;
- }
- set
- {
- _text = value;
- ClearSelection();
- UpdateText();
- }
- }
-
-
-
- public override TextFormat textFormat
- {
- get
- {
- return base.textFormat;
- }
- set
- {
- base.textFormat = value;
- if (_editing)
- {
- _caret.height = textField.textFormat.size;
- _caret.DrawRect(0, Color.clear, textField.textFormat.color);
- }
- }
- }
-
-
-
- public string restrict
- {
- get { return _restrict; }
- set
- {
- _restrict = value;
- if (string.IsNullOrEmpty(_restrict))
- _restrictPattern = null;
- else
- _restrictPattern = new Regex(value);
- }
- }
-
-
-
- public int caretPosition
- {
- get
- {
- textField.Redraw();
- return _caretPosition;
- }
- set
- {
- SetSelection(value, 0);
- }
- }
- public int selectionBeginIndex
- {
- get { return _selectionStart < _caretPosition ? _selectionStart : _caretPosition; }
- }
- public int selectionEndIndex
- {
- get { return _selectionStart < _caretPosition ? _caretPosition : _selectionStart; }
- }
-
-
-
- public string promptText
- {
- get
- {
- return _promptText;
- }
- set
- {
- _promptText = value;
- if (!string.IsNullOrEmpty(_promptText))
- _decodedPromptText = UBBParser.inst.Parse(XMLUtils.EncodeString(_promptText));
- else
- _decodedPromptText = null;
- UpdateText();
- }
- }
-
-
-
- public bool displayAsPassword
- {
- get { return _displayAsPassword; }
- set
- {
- if (_displayAsPassword != value)
- {
- _displayAsPassword = value;
- UpdateText();
- }
- }
- }
-
-
-
- public bool editable
- {
- get { return _editable; }
- set
- {
- _editable = value;
- if (_caret != null)
- _caret.visible = _editable;
- }
- }
-
-
-
- public int border
- {
- get { return _border; }
- set
- {
- _border = value;
- UpdateShape();
- }
- }
-
-
-
- public int corner
- {
- get { return _corner; }
- set
- {
- _corner = value;
- UpdateShape();
- }
- }
-
-
-
- public Color borderColor
- {
- get { return _borderColor; }
- set
- {
- _borderColor = value;
- UpdateShape();
- }
- }
-
-
-
- public Color backgroundColor
- {
- get { return _backgroundColor; }
- set
- {
- _backgroundColor = value;
- UpdateShape();
- }
- }
- void UpdateShape()
- {
- if (_border > 0 || _backgroundColor.a > 0)
- {
- CreateGraphics();
- graphics.enabled = true;
- RoundedRectMesh mesh = graphics.GetMeshFactory<RoundedRectMesh>();
- mesh.lineWidth = _border;
- mesh.lineColor = _borderColor;
- mesh.fillColor = _backgroundColor;
- mesh.topLeftRadius = mesh.topRightRadius = mesh.bottomLeftRadius = mesh.bottomRightRadius = corner;
- graphics.SetMeshDirty();
- }
- else
- {
- if (graphics != null)
- graphics.enabled = false;
- }
- }
-
-
-
-
-
- public void SetSelection(int start, int length)
- {
- if (!_editing)
- Stage.inst.focus = this;
- _selectionStart = start;
- _caretPosition = length < 0 ? int.MaxValue : (start + length);
- if (!textField.Redraw())
- {
- int cnt = textField.charPositions.Count;
- if (_caretPosition >= cnt)
- _caretPosition = cnt - 1;
- if (_selectionStart >= cnt)
- _selectionStart = cnt - 1;
- UpdateCaret();
- }
- }
-
-
-
-
- public void ReplaceSelection(string value)
- {
- if (keyboardInput && Stage.keyboardInput && !Stage.inst.keyboard.supportsCaret)
- {
- this.text = _text + value;
- OnChanged();
- return;
- }
- if (!_editing)
- Stage.inst.focus = this;
- textField.Redraw();
- int t0, t1;
- if (_selectionStart != _caretPosition)
- {
- if (_selectionStart < _caretPosition)
- {
- t0 = _selectionStart;
- t1 = _caretPosition;
- _caretPosition = _selectionStart;
- }
- else
- {
- t0 = _caretPosition;
- t1 = _selectionStart;
- _selectionStart = _caretPosition;
- }
- }
- else
- {
- if (string.IsNullOrEmpty(value))
- return;
- t0 = t1 = _caretPosition;
- }
- StringBuilder buffer = new StringBuilder();
- GetPartialText(0, t0, buffer);
- if (!string.IsNullOrEmpty(value))
- {
- value = ValidateInput(value);
- buffer.Append(value);
- _caretPosition += GetTextlength(value);
- }
- GetPartialText(t1 + _composing, -1, buffer);
- string newText = buffer.ToString();
- if (maxLength > 0)
- {
- string newText2 = TruncateText(newText, maxLength);
- if (newText2.Length != newText.Length)
- _caretPosition += (newText2.Length - newText.Length);
- newText = newText2;
- }
- this.text = newText;
- OnChanged();
- }
-
-
-
-
- public void ReplaceText(string value)
- {
- if (value == _text)
- return;
- if (value == null)
- value = string.Empty;
- value = ValidateInput(value);
- if (maxLength > 0)
- value = TruncateText(value, maxLength);
- _caretPosition = value.Length;
- this.text = value;
- OnChanged();
- }
- void GetPartialText(int startIndex, int endIndex, StringBuilder buffer)
- {
- int elementCount = textField.htmlElements.Count;
- int lastIndex = startIndex;
- string tt;
- if (_displayAsPassword)
- tt = _text;
- else
- tt = textField.parsedText;
- if (endIndex < 0)
- endIndex = tt.Length;
- for (int i = 0; i < elementCount; i++)
- {
- HtmlElement element = textField.htmlElements[i];
- if (element.htmlObject != null && element.text != null)
- {
- if (element.charIndex >= startIndex && element.charIndex < endIndex)
- {
- buffer.Append(tt.Substring(lastIndex, element.charIndex - lastIndex));
- buffer.Append(element.text);
- lastIndex = element.charIndex + 1;
- }
- }
- }
- if (lastIndex < tt.Length)
- buffer.Append(tt.Substring(lastIndex, endIndex - lastIndex));
- }
- int GetTextlength(string value)
- {
- int textLen = value.Length;
- int ret = textLen;
- for (int i = 0; i < textLen; i++)
- {
- if (char.IsHighSurrogate(value[i]))
- ret--;
- }
- return ret;
- }
- string TruncateText(string value, int length)
- {
- int textLen = value.Length;
- int len = 0;
- int i = 0;
- while (i < textLen)
- {
- if (len == length)
- return value.Substring(0, i);
- if (char.IsHighSurrogate(value[i]))
- i++;
- i++;
- len++;
- }
- return value;
- }
- string ValidateInput(string source)
- {
- if (_restrict != null)
- {
- StringBuilder sb = new StringBuilder();
- Match mc = _restrictPattern.Match(source);
- int lastPos = 0;
- string s;
- while (mc != Match.Empty)
- {
- if (mc.Index != lastPos)
- {
-
- for (int i = lastPos; i < mc.Index; i++)
- {
- if (source[i] == '\n' || source[i] == '\t')
- sb.Append(source[i]);
- }
- }
- s = mc.ToString();
- lastPos = mc.Index + s.Length;
- sb.Append(s);
- mc = mc.NextMatch();
- }
- for (int i = lastPos; i < source.Length; i++)
- {
- if (source[i] == '\n' || source[i] == '\t')
- sb.Append(source[i]);
- }
- return sb.ToString();
- }
- else
- return source;
- }
- void UpdateText()
- {
- if (!_editing && _text.Length == 0 && !string.IsNullOrEmpty(_decodedPromptText))
- {
- textField.htmlText = _decodedPromptText;
- return;
- }
- if (_displayAsPassword)
- textField.text = EncodePasswordText(_text);
- else
- textField.text = _text;
- _composing = Input.compositionString.Length;
- if (_composing > 0)
- {
- StringBuilder buffer = new StringBuilder();
- GetPartialText(0, _caretPosition, buffer);
- buffer.Append(Input.compositionString);
- GetPartialText(_caretPosition, -1, buffer);
- textField.text = buffer.ToString();
- }
- }
- string EncodePasswordText(string value)
- {
- int textLen = value.Length;
- StringBuilder tmp = new StringBuilder(textLen);
- int i = 0;
- while (i < textLen)
- {
- char c = value[i];
- if (c == '\n')
- tmp.Append(c);
- else
- {
- if (char.IsHighSurrogate(c))
- i++;
- tmp.Append("*");
- }
- i++;
- }
- return tmp.ToString();
- }
- void ClearSelection()
- {
- if (_selectionStart != _caretPosition)
- {
- if (_selectionShape != null)
- _selectionShape.Clear();
- _selectionStart = _caretPosition;
- }
- }
- public string GetSelection()
- {
- if (_selectionStart == _caretPosition)
- return string.Empty;
- StringBuilder buffer = new StringBuilder();
- if (_selectionStart < _caretPosition)
- GetPartialText(_selectionStart, _caretPosition, buffer);
- else
- GetPartialText(_caretPosition, _selectionStart, buffer);
- return buffer.ToString();
- }
- void Scroll(int hScroll, int vScroll)
- {
- vScroll = Mathf.Clamp(vScroll, 0, textField.lines.Count - 1);
- TextField.LineInfo line = textField.lines[vScroll];
- hScroll = Mathf.Clamp(hScroll, 0, line.charCount - 1);
- TextField.CharPosition cp = GetCharPosition(line.charIndex + hScroll);
- Vector2 pt = GetCharLocation(cp);
- MoveContent(new Vector2(GUTTER_X - pt.x, GUTTER_Y - pt.y), false);
- }
- void AdjustCaret(TextField.CharPosition cp, bool moveSelectionHeader = false)
- {
- _caretPosition = cp.charIndex;
- if (moveSelectionHeader)
- _selectionStart = _caretPosition;
- UpdateCaret();
- }
- void UpdateCaret(bool forceUpdate = false)
- {
- TextField.CharPosition cp;
- if (_editing)
- cp = GetCharPosition(_caretPosition + Input.compositionString.Length);
- else
- cp = GetCharPosition(_caretPosition);
- Vector2 pos = GetCharLocation(cp);
- TextField.LineInfo line = textField.lines[cp.lineIndex];
- Vector2 offset = pos + textField.xy;
- if (offset.x < textField.textFormat.size)
- offset.x += Mathf.Min(50, _contentRect.width * 0.5f);
- else if (offset.x > _contentRect.width - GUTTER_X - textField.textFormat.size)
- offset.x -= Mathf.Min(50, _contentRect.width * 0.5f);
- if (offset.x < GUTTER_X)
- offset.x = GUTTER_X;
- else if (offset.x > _contentRect.width - GUTTER_X)
- offset.x = Mathf.Max(GUTTER_X, _contentRect.width - GUTTER_X);
- if (offset.y < GUTTER_Y)
- offset.y = GUTTER_Y;
- else if (offset.y + line.height >= _contentRect.height - GUTTER_Y)
- offset.y = Mathf.Max(GUTTER_Y, _contentRect.height - line.height - GUTTER_Y);
- MoveContent(offset - pos, forceUpdate);
- if (_editing)
- {
- _caret.position = textField.xy + pos;
- _caret.height = line.height > 0 ? line.height : textField.textFormat.size;
- if (_editable)
- {
- Vector2 cursorPos = _caret.LocalToWorld(new Vector2(0, _caret.height));
- cursorPos = StageCamera.main.WorldToScreenPoint(cursorPos);
- #if !UNITY_2019_OR_NEWER
- if (Stage.devicePixelRatio == 1)
- {
- #endif
- cursorPos.y = Screen.height - cursorPos.y;
- cursorPos = cursorPos / Stage.devicePixelRatio;
- Input.compositionCursorPos = cursorPos + new Vector2(0, 20);
- #if !UNITY_2019_OR_NEWER
- }
- else
- Input.compositionCursorPos = cursorPos - new Vector2(0, 20);
- #endif
- }
- _nextBlink = Time.time + 0.5f;
- _caret.graphics.enabled = true;
- UpdateSelection(cp);
- }
- }
- void MoveContent(Vector2 pos, bool forceUpdate)
- {
- float ox = textField.x;
- float oy = textField.y;
- float nx = pos.x;
- float ny = pos.y;
- float rectWidth = _contentRect.width - 1;
- if (rectWidth - nx > textField.textWidth)
- nx = rectWidth - textField.textWidth;
- if (_contentRect.height - ny > textField.textHeight)
- ny = _contentRect.height - textField.textHeight;
- if (nx > 0)
- nx = 0;
- if (ny > 0)
- ny = 0;
- nx = (int)nx;
- ny = (int)ny;
- if (nx != ox || ny != oy || forceUpdate)
- {
- if (_caret != null)
- {
- _caret.SetXY(nx + _caret.x - ox, ny + _caret.y - oy);
- _selectionShape.SetXY(nx, ny);
- }
- textField.SetXY(nx, ny);
- List<HtmlElement> elements = textField.htmlElements;
- int count = elements.Count;
- for (int i = 0; i < count; i++)
- {
- HtmlElement element = elements[i];
- if (element.htmlObject != null)
- element.htmlObject.SetPosition(element.position.x + nx, element.position.y + ny);
- }
- }
- }
- void UpdateSelection(TextField.CharPosition cp)
- {
- if (_selectionStart == _caretPosition)
- {
- _selectionShape.Clear();
- return;
- }
- TextField.CharPosition start;
- if (_editing && Input.compositionString.Length > 0)
- {
- if (_selectionStart < _caretPosition)
- {
- cp = GetCharPosition(_caretPosition);
- start = GetCharPosition(_selectionStart);
- }
- else
- start = GetCharPosition(_selectionStart + Input.compositionString.Length);
- }
- else
- start = GetCharPosition(_selectionStart);
- if (start.charIndex > cp.charIndex)
- {
- TextField.CharPosition tmp = start;
- start = cp;
- cp = tmp;
- }
- Vector2 v1 = GetCharLocation(start);
- Vector2 v2 = GetCharLocation(cp);
- _selectionShape.rects.Clear();
- textField.GetLinesShape(start.lineIndex, v1.x, cp.lineIndex, v2.x, false, _selectionShape.rects);
- _selectionShape.Refresh();
- }
- TextField.CharPosition GetCharPosition(int caretIndex)
- {
- if (caretIndex < 0)
- caretIndex = 0;
- else if (caretIndex >= textField.charPositions.Count)
- caretIndex = textField.charPositions.Count - 1;
- return textField.charPositions[caretIndex];
- }
-
-
-
-
-
- TextField.CharPosition GetCharPosition(Vector2 location)
- {
- if (textField.charPositions.Count <= 1)
- return textField.charPositions[0];
- location.x -= textField.x;
- location.y -= textField.y;
- List<TextField.LineInfo> lines = textField.lines;
- int len = lines.Count;
- TextField.LineInfo line;
- int i;
- for (i = 0; i < len; i++)
- {
- line = lines[i];
- if (line.y + line.height > location.y)
- break;
- }
- if (i == len)
- i = len - 1;
- int lineIndex = i;
- len = textField.charPositions.Count;
- TextField.CharPosition v;
- int firstInLine = -1;
- for (i = 0; i < len; i++)
- {
- v = textField.charPositions[i];
- if (v.lineIndex == lineIndex)
- {
- if (firstInLine == -1)
- firstInLine = i;
- if (v.offsetX + v.width * 0.5f > location.x)
- return v;
- }
- else if (firstInLine != -1)
- return v;
- }
- return textField.charPositions[i - 1];
- }
-
-
-
-
-
- Vector2 GetCharLocation(TextField.CharPosition cp)
- {
- TextField.LineInfo line = textField.lines[cp.lineIndex];
- Vector2 pos;
- if (line.charCount == 0 || textField.charPositions.Count == 0)
- {
- if (textField.align == AlignType.Center)
- pos.x = (int)(_contentRect.width / 2);
- else
- pos.x = GUTTER_X;
- }
- else
- {
- TextField.CharPosition v = textField.charPositions[Math.Min(cp.charIndex, textField.charPositions.Count - 1)];
- pos.x = v.offsetX;
- }
- pos.y = line.y;
- return pos;
- }
- override internal void RefreshObjects()
- {
- base.RefreshObjects();
- if (_editing)
- {
- SetChildIndex(_selectionShape, 0);
- SetChildIndex(_caret, this.numChildren - 1);
- }
- int cnt = textField.charPositions.Count;
- if (_caretPosition >= cnt)
- _caretPosition = cnt - 1;
- if (_selectionStart >= cnt)
- _selectionStart = cnt - 1;
- UpdateCaret(true);
- }
- protected void OnChanged()
- {
- DispatchEvent("onChanged", null);
- TextInputHistory.inst.MarkChanged(this);
- }
- protected override void OnSizeChanged()
- {
- base.OnSizeChanged();
- Rect rect = _contentRect;
- rect.x += GUTTER_X;
- rect.y += GUTTER_Y;
- rect.width -= GUTTER_X * 2;
- rect.height -= GUTTER_Y * 2;
- this.clipRect = rect;
- ((RectHitTest)this.hitArea).rect = _contentRect;
- }
- public override void Update(UpdateContext context)
- {
- base.Update(context);
- if (_editing)
- {
- if (_nextBlink < Time.time)
- {
- _nextBlink = Time.time + 0.5f;
- _caret.graphics.enabled = !_caret.graphics.enabled;
- }
- }
- }
- public override void Dispose()
- {
- if ((_flags & Flags.Disposed) != 0)
- return;
- _editing = false;
- if (_caret != null)
- {
- _caret.Dispose();
- _selectionShape.Dispose();
- }
- base.Dispose();
- }
- void DoCopy(string value)
- {
- if (onCopy != null)
- {
- onCopy(this, value);
- return;
- }
- #if UNITY_WEBPLAYER || UNITY_WEBGL || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_EDITOR
- TextEditor textEditor = new TextEditor();
- #if UNITY_5_3_OR_NEWER
- textEditor.text = value;
- #else
- textEditor.content = new GUIContent(value);
- #endif
- textEditor.OnFocus();
- textEditor.Copy();
- #endif
- }
- void DoPaste()
- {
- if (onPaste != null)
- {
- onPaste(this);
- return;
- }
- #if UNITY_WEBPLAYER || UNITY_WEBGL || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_EDITOR
- TextEditor textEditor = new TextEditor();
- #if UNITY_5_3_OR_NEWER
- textEditor.text = string.Empty;
- #else
- textEditor.content = new GUIContent(string.Empty);
- #endif
- textEditor.multiline = !textField.singleLine;
- textEditor.Paste();
- #if UNITY_5_3_OR_NEWER
- string value = textEditor.text;
- #else
- string value = textEditor.content.text;
- #endif
- if (!string.IsNullOrEmpty(value))
- ReplaceSelection(value);
- #endif
- }
- void CreateCaret()
- {
- _caret = new Shape();
- _caret.gameObject.name = "Caret";
- _caret.touchable = false;
- _caret._flags |= Flags.SkipBatching;
- _caret.xy = textField.xy;
- _selectionShape = new SelectionShape();
- _selectionShape.gameObject.name = "Selection";
- _selectionShape.color = UIConfig.inputHighlightColor;
- _selectionShape._flags |= Flags.SkipBatching;
- _selectionShape.touchable = false;
- _selectionShape.xy = textField.xy;
- }
- void __touchBegin(EventContext context)
- {
- if (!_editing || textField.charPositions.Count <= 1
- || keyboardInput && Stage.keyboardInput && !Stage.inst.keyboard.supportsCaret
- || context.inputEvent.button != 0)
- return;
- ClearSelection();
- Vector3 v = Stage.inst.touchPosition;
- v = this.GlobalToLocal(v);
- TextField.CharPosition cp = GetCharPosition(v);
- AdjustCaret(cp, true);
- context.CaptureTouch();
- }
- void __touchMove(EventContext context)
- {
- if (!_editing)
- return;
- Vector3 v = Stage.inst.touchPosition;
- v = this.GlobalToLocal(v);
- if (float.IsNaN(v.x))
- return;
- TextField.CharPosition cp = GetCharPosition(v);
- if (cp.charIndex != _caretPosition)
- AdjustCaret(cp);
- }
- void __mouseWheel(EventContext context)
- {
- if (_editing && mouseWheelEnabled)
- {
- context.StopPropagation();
- TextField.CharPosition cp = GetCharPosition(new Vector2(GUTTER_X, GUTTER_Y));
- int vScroll = cp.lineIndex;
- int hScroll = cp.charIndex - textField.lines[cp.lineIndex].charIndex;
- if (context.inputEvent.mouseWheelDelta < 0)
- vScroll--;
- else
- vScroll++;
- Scroll(hScroll, vScroll);
- }
- }
- void __focusIn(EventContext context)
- {
- if (!Application.isPlaying)
- return;
- _editing = true;
- _textBeforeEdit = _text;
- if (_caret == null)
- CreateCaret();
- if (!string.IsNullOrEmpty(_promptText))
- UpdateText();
- float caretSize;
-
- if (UIConfig.inputCaretSize == 1 && UIContentScaler.scaleFactor < 1)
- caretSize = UIConfig.inputCaretSize / UIContentScaler.scaleFactor;
- else
- caretSize = UIConfig.inputCaretSize;
- _caret.SetSize(caretSize, textField.textFormat.size);
- _caret.DrawRect(0, Color.clear, textField.textFormat.color);
- _caret.visible = _editable;
- AddChild(_caret);
- _selectionShape.Clear();
- AddChildAt(_selectionShape, 0);
- if (!textField.Redraw())
- {
- TextField.CharPosition cp = GetCharPosition(_caretPosition);
- AdjustCaret(cp);
- }
- if (Stage.keyboardInput)
- {
- if (keyboardInput)
- {
- if (_editable)
- Stage.inst.OpenKeyboard(_text, false, _displayAsPassword ? false : !textField.singleLine,
- _displayAsPassword, false, null, keyboardType, hideInput);
- SetSelection(0, -1);
- }
- }
- else
- {
- if (!disableIME && !_displayAsPassword)
- Input.imeCompositionMode = IMECompositionMode.On;
- else
- Input.imeCompositionMode = IMECompositionMode.Off;
- _composing = 0;
- if ((string)context.data == "key")
- SetSelection(0, -1);
- TextInputHistory.inst.StartRecord(this);
- }
- }
- void __focusOut(EventContext contxt)
- {
- if (!_editing)
- return;
- _editing = false;
- if (Stage.keyboardInput)
- {
- if (keyboardInput)
- Stage.inst.CloseKeyboard();
- }
- else
- {
- Input.imeCompositionMode = IMECompositionMode.Auto;
- TextInputHistory.inst.StopRecord(this);
- }
- if (!string.IsNullOrEmpty(_promptText))
- UpdateText();
- _caret.RemoveFromParent();
- _selectionShape.RemoveFromParent();
- if (contextMenu != null && contextMenu.contentPane.onStage)
- contextMenu.Hide();
- }
- void __keydown(EventContext context)
- {
- if (!_editing)
- return;
- if (HandleKey(context.inputEvent))
- context.StopPropagation();
- }
- bool HandleKey(InputEvent evt)
- {
- bool keyCodeHandled = true;
- switch (evt.keyCode)
- {
- case KeyCode.Backspace:
- {
- if (evt.command)
- {
-
- if (_selectionStart == _caretPosition && _caretPosition < textField.charPositions.Count - 1)
- _selectionStart = _caretPosition + 1;
- }
- else
- {
- if (_selectionStart == _caretPosition && _caretPosition > 0)
- _selectionStart = _caretPosition - 1;
- }
- if (_editable)
- ReplaceSelection(null);
- break;
- }
- case KeyCode.Delete:
- {
- if (_selectionStart == _caretPosition && _caretPosition < textField.charPositions.Count - 1)
- _selectionStart = _caretPosition + 1;
- if (_editable)
- ReplaceSelection(null);
- break;
- }
- case KeyCode.LeftArrow:
- {
- if (!evt.shift)
- ClearSelection();
- if (_caretPosition > 0)
- {
- if (evt.command)
- {
- TextField.CharPosition cp = GetCharPosition(_caretPosition);
- TextField.LineInfo line = textField.lines[cp.lineIndex];
- cp = GetCharPosition(new Vector2(int.MinValue, line.y + textField.y));
- AdjustCaret(cp, !evt.shift);
- }
- else
- {
- TextField.CharPosition cp = GetCharPosition(_caretPosition - 1);
- AdjustCaret(cp, !evt.shift);
- }
- }
- break;
- }
- case KeyCode.RightArrow:
- {
- if (!evt.shift)
- ClearSelection();
- if (_caretPosition < textField.charPositions.Count - 1)
- {
- if (evt.command)
- {
- TextField.CharPosition cp = GetCharPosition(_caretPosition);
- TextField.LineInfo line = textField.lines[cp.lineIndex];
- cp = GetCharPosition(new Vector2(int.MaxValue, line.y + textField.y));
- AdjustCaret(cp, !evt.shift);
- }
- else
- {
- TextField.CharPosition cp = GetCharPosition(_caretPosition + 1);
- AdjustCaret(cp, !evt.shift);
- }
- }
- break;
- }
- case KeyCode.UpArrow:
- {
- if (!evt.shift)
- ClearSelection();
- TextField.CharPosition cp = GetCharPosition(_caretPosition);
- if (cp.lineIndex > 0)
- {
- TextField.LineInfo line = textField.lines[cp.lineIndex - 1];
- cp = GetCharPosition(new Vector2(_caret.x, line.y + textField.y));
- AdjustCaret(cp, !evt.shift);
- }
- break;
- }
- case KeyCode.DownArrow:
- {
- if (!evt.shift)
- ClearSelection();
- TextField.CharPosition cp = GetCharPosition(_caretPosition);
- if (cp.lineIndex == textField.lines.Count - 1)
- cp.charIndex = textField.charPositions.Count - 1;
- else
- {
- TextField.LineInfo line = textField.lines[cp.lineIndex + 1];
- cp = GetCharPosition(new Vector2(_caret.x, line.y + textField.y));
- }
- AdjustCaret(cp, !evt.shift);
- break;
- }
- case KeyCode.PageUp:
- {
- ClearSelection();
- break;
- }
- case KeyCode.PageDown:
- {
- ClearSelection();
- break;
- }
- case KeyCode.Home:
- {
- if (!evt.shift)
- ClearSelection();
- TextField.CharPosition cp = GetCharPosition(_caretPosition);
- TextField.LineInfo line = textField.lines[cp.lineIndex];
- cp = GetCharPosition(new Vector2(int.MinValue, line.y + textField.y));
- AdjustCaret(cp, !evt.shift);
- break;
- }
- case KeyCode.End:
- {
- if (!evt.shift)
- ClearSelection();
- TextField.CharPosition cp = GetCharPosition(_caretPosition);
- TextField.LineInfo line = textField.lines[cp.lineIndex];
- cp = GetCharPosition(new Vector2(int.MaxValue, line.y + textField.y));
- AdjustCaret(cp, !evt.shift);
- break;
- }
-
- case KeyCode.A:
- {
- if (evt.ctrlOrCmd)
- {
- _selectionStart = 0;
- AdjustCaret(GetCharPosition(int.MaxValue));
- }
- break;
- }
-
- case KeyCode.C:
- {
- if (evt.ctrlOrCmd && !_displayAsPassword)
- {
- string s = GetSelection();
- if (!string.IsNullOrEmpty(s))
- DoCopy(s);
- }
- break;
- }
-
- case KeyCode.V:
- {
- if (evt.ctrlOrCmd && _editable)
- DoPaste();
- break;
- }
-
- case KeyCode.X:
- {
- if (evt.ctrlOrCmd && !_displayAsPassword)
- {
- string s = GetSelection();
- if (!string.IsNullOrEmpty(s))
- {
- DoCopy(s);
- if (_editable)
- ReplaceSelection(null);
- }
- }
- break;
- }
- case KeyCode.Z:
- {
- if (evt.ctrlOrCmd && _editable)
- {
- if (evt.shift)
- TextInputHistory.inst.Redo(this);
- else
- TextInputHistory.inst.Undo(this);
- }
- break;
- }
- case KeyCode.Y:
- {
- if (evt.ctrlOrCmd && _editable)
- TextInputHistory.inst.Redo(this);
- break;
- }
- case KeyCode.Return:
- case KeyCode.KeypadEnter:
- {
- if (textField.singleLine)
- {
- Stage.inst.focus = parent;
- DispatchEvent("onSubmit", null);
- DispatchEvent("onKeyDown", null);
- }
- break;
- }
- case KeyCode.Tab:
- {
- if (textField.singleLine)
- {
- Stage.inst.DoKeyNavigate(evt.shift);
- keyCodeHandled = false;
- }
- break;
- }
- case KeyCode.Escape:
- {
- this.text = _textBeforeEdit;
- Stage.inst.focus = parent;
- break;
- }
- default:
- keyCodeHandled = (int)evt.keyCode <= 272 && !evt.ctrlOrCmd;
- break;
- }
- char c = evt.character;
- if (c != 0)
- {
- if (evt.ctrlOrCmd)
- return true;
- if (c == '\r' || c == 3)
- c = '\n';
- if (c == 25)
- c = '\t';
- if (c == 27 || textField.singleLine && (c == '\n' || c == '\t'))
- return true;
- if (char.IsHighSurrogate(c))
- {
- _highSurrogateChar = c;
- return true;
- }
- if (_editable)
- {
- if (char.IsLowSurrogate(c))
- ReplaceSelection(char.ConvertFromUtf32(((int)c & 0x03FF) + ((((int)_highSurrogateChar & 0x03FF) + 0x40) << 10)));
- else
- ReplaceSelection(c.ToString());
- }
- return true;
- }
- else
- {
- if (Input.compositionString.Length > 0 && _editable)
- {
- int composing = _composing;
- _composing = Input.compositionString.Length;
- StringBuilder buffer = new StringBuilder();
- GetPartialText(0, _caretPosition, buffer);
- buffer.Append(Input.compositionString);
- GetPartialText(_caretPosition + composing, -1, buffer);
- textField.text = buffer.ToString();
- }
- return keyCodeHandled;
- }
- }
- internal void CheckComposition()
- {
- if (_composing != 0 && Input.compositionString.Length == 0)
- UpdateText();
- }
- void __click(EventContext context)
- {
- if (_editing && context.inputEvent.isDoubleClick)
- {
- context.StopPropagation();
- _selectionStart = 0;
- AdjustCaret(GetCharPosition(int.MaxValue));
- }
- }
- void __rightClick(EventContext context)
- {
- if (contextMenu != null)
- {
- context.StopPropagation();
- contextMenu.Show();
- }
- }
- }
- class TextInputHistory
- {
- static TextInputHistory _inst;
- public static TextInputHistory inst
- {
- get
- {
- if (_inst == null)
- _inst = new TextInputHistory();
- return _inst;
- }
- }
- List<string> _undoBuffer;
- List<string> _redoBuffer;
- string _currentText;
- InputTextField _textField;
- bool _lock;
- int _changedFrame;
- public const int maxHistoryLength = 5;
- public TextInputHistory()
- {
- _undoBuffer = new List<string>();
- _redoBuffer = new List<string>();
- }
- public void StartRecord(InputTextField textField)
- {
- _undoBuffer.Clear();
- _redoBuffer.Clear();
- _textField = textField;
- _lock = false;
- _currentText = textField.text;
- _changedFrame = 0;
- }
- public void MarkChanged(InputTextField textField)
- {
- if (_textField != textField)
- return;
- if (_lock)
- return;
- string newText = _textField.text;
- if (_currentText == newText)
- return;
- if (_changedFrame != Time.frameCount)
- {
- _changedFrame = Time.frameCount;
- _undoBuffer.Add(_currentText);
- if (_undoBuffer.Count > maxHistoryLength)
- _undoBuffer.RemoveAt(0);
- }
- else
- {
- int cnt = _undoBuffer.Count;
- if (cnt > 0 && newText == _undoBuffer[cnt - 1])
- _undoBuffer.RemoveAt(cnt - 1);
- }
- _currentText = newText;
- }
- public void StopRecord(InputTextField textField)
- {
- if (_textField != textField)
- return;
- _undoBuffer.Clear();
- _redoBuffer.Clear();
- _textField = null;
- _currentText = null;
- }
- public void Undo(InputTextField textField)
- {
- if (_textField != textField)
- return;
- if (_undoBuffer.Count == 0)
- return;
- string text = _undoBuffer[_undoBuffer.Count - 1];
- _undoBuffer.RemoveAt(_undoBuffer.Count - 1);
- _redoBuffer.Add(_currentText);
- _lock = true;
- int caretPos = _textField.caretPosition;
- _textField.text = text;
- int dlen = text.Length - _currentText.Length;
- if (dlen < 0)
- _textField.caretPosition = caretPos + dlen;
- _currentText = text;
- _lock = false;
- }
- public void Redo(InputTextField textField)
- {
- if (_textField != textField)
- return;
- if (_redoBuffer.Count == 0)
- return;
- string text = _redoBuffer[_redoBuffer.Count - 1];
- _redoBuffer.RemoveAt(_redoBuffer.Count - 1);
- _undoBuffer.Add(_currentText);
- _lock = true;
- int caretPos = _textField.caretPosition;
- _textField.text = text;
- int dlen = text.Length - _currentText.Length;
- if (dlen > 0)
- _textField.caretPosition = caretPos + dlen;
- _currentText = text;
- _lock = false;
- }
- }
- }
|