private void InitEvent(Window owner) { Nexus.GUI.Widgets.UIEditBox editBox = owner as Nexus.GUI.Widgets.UIEditBox; editBox.TextChange += this.OnOwnerTextChanged; editBox.Sized += this.OnOwnerSizeChanged; editBox.Moved += this.OnOwnerSizeChanged; editBox.TextSelectionChanged += this.OnOwnerTextSelectionChanged; editBox.CaratMoved += this.OnOwnerCaretPositionChanged; }
public virtual int GetTextIndexFromPosition(Vector2 vec) { Nexus.GUI.Widgets.UIEditBox editBox = (Nexus.GUI.Widgets.UIEditBox)owner; int postion = 0; if (font != null && editBox != null) { //if (this.targetRect.IsPointInRect(vec) && editBox.Text.Length > 0) //为了选择时能让超出显示范围的文本滚动,需要解除IsPointInRect检测 if (editBox.Text.Length > 0) { Vector2 v = vec - editBox.AbsolutePosition; int x = m_TextBuffer.CPtoX(m_StartVisible, false); return(m_TextBuffer.XtoCP(x + (int)v.x)); } } return(postion); }
/// <summary> /// TODO(zewu): 优化 /// </summary> public override void Draw() { Nexus.GUI.Widgets.UIEditBox editBox = owner as Nexus.GUI.Widgets.UIEditBox; if (font == null || editBox == null || m_TextBuffer == null) { return; } StringBuilder editText = new StringBuilder(); if (editBox.TextMasked) { editText.Append(editBox.MaskCodePoint, editBox.Text.Length); } else { editText = editBox.Text; } if (m_TextBuffer.Text.Length > 0) { //Rect drawRC = this.targetRect; DrawTextFormat textFormt = DrawTextFormat.Left | DrawTextFormat.NoClip | DrawTextFormat.Top | DrawTextFormat.SingleLine; // 渲染文本 if (editBox.SelectionLength > 0) { if (m_First.Length > 0) { font.DrawString(m_First, m_BeforeSelectionRect, textFormt, normalTextColor, shadowColor); } GUISystem.Instance.Renderer.DrawRectangle(m_SelectionRect, selectBrushColor); if (m_Mid.Length > 0) { font.DrawString(m_Mid, m_SelectionRect, textFormt, selectTextColor, shadowColor); } if (m_Last.Length > 0) { font.DrawString(m_Last, m_AfterSelectionRect, textFormt, normalTextColor, shadowColor); } } else { font.DrawString(m_First, m_BeforeSelectionRect, textFormt, normalTextColor, shadowColor); } } // 渲染光标 if (editBox.HasInputFocus && !editBox.ReadOnly) { int caret_pos = -1; if (editBox.CaratPosition >= 0) { caret_pos = m_TextBuffer.CPtoX(editBox.CaratPosition, false) - m_TextBuffer.CPtoX(m_StartVisible, false); } Rect caretRC = new Rect(); caretRC.left = this.targetRect.left + caret_pos; caretRC.right = caretRC.left + cursorSize; caretRC.top = targetRect.top; caretRC.Height = fontDesc.Height; GUISystem.Instance.Renderer.DrawRectangle(caretRC, cursorColor); } }
//重新计算可见字符的范围 private void UpdateVisibleRange() { Nexus.GUI.Widgets.UIEditBox editBox = owner as Nexus.GUI.Widgets.UIEditBox; m_TextBuffer.Text = editBox.Text.ToString(); if (m_TextBuffer.Text.Length == 0) { m_StartVisible = 0; m_VisibleCount = 0; m_Last = ""; m_AfterSelectionRect.left = m_AfterSelectionRect.right = m_TextBuffer.CPtoX(0, false); return; } //计算新的可见字符范围 int nx1, nx, nx2; int cp = editBox.CaratPosition; nx1 = m_TextBuffer.CPtoX(m_StartVisible, false); nx = m_TextBuffer.CPtoX(cp, false); if (cp == m_TextBuffer.Text.Length) { nx2 = nx; } else { nx2 = m_TextBuffer.CPtoX(cp, true); } if (nx < nx1) { m_StartVisible = cp; } else if (nx2 > nx1 + (int)targetRect.Width) { int nXNewLeft = nx2 - (int)targetRect.Width; int NewStart = m_TextBuffer.XtoCP(nXNewLeft); int NewX = m_TextBuffer.CPtoX(NewStart, false); if (NewX < nXNewLeft) { ++NewStart; } m_StartVisible = NewStart; } int end_x = m_TextBuffer.CPtoX(m_StartVisible, false) + (int)targetRect.Width; m_VisibleCount = m_TextBuffer.XtoCP(end_x) - m_StartVisible; //计算新的渲染矩形 if (editBox.SelectionLength > 0) { int offset = m_TextBuffer.CPtoX(m_StartVisible, false); Segment sa, sb, sc, sd, se; sa = new Segment(0, editBox.SelectionStartIndex); sb = new Segment(editBox.SelectionStartIndex, editBox.SelectionLength); sc = new Segment(editBox.SelectionEndIndex, m_TextBuffer.Text.Length - editBox.SelectionEndIndex); sd = new Segment(m_StartVisible, m_VisibleCount); se = sd.Intersection(sa); m_First = m_TextBuffer.Text.Substring(se.X, se.Length); m_BeforeSelectionRect.left = targetRect.left + m_TextBuffer.CPtoX(se.X, false) - offset; m_BeforeSelectionRect.right = targetRect.left + m_TextBuffer.CPtoX(se.Right, false) - offset; se = sd.Intersection(sb); m_Mid = m_TextBuffer.Text.Substring(se.X, se.Length); m_SelectionRect.left = targetRect.left + m_TextBuffer.CPtoX(se.X, false) - offset; m_SelectionRect.right = targetRect.left + m_TextBuffer.CPtoX(se.Right, false) - offset; se = sd.Intersection(sc); m_Last = m_TextBuffer.Text.Substring(se.X, se.Length); m_AfterSelectionRect.left = targetRect.left + m_TextBuffer.CPtoX(se.X, false) - offset; m_AfterSelectionRect.right = targetRect.left + m_TextBuffer.CPtoX(se.Right, false) - offset; } else { m_First = m_TextBuffer.Text.Substring(m_StartVisible, m_VisibleCount); m_BeforeSelectionRect.left = this.targetRect.left; m_BeforeSelectionRect.right = this.targetRect.right; } m_BeforeSelectionRect.top = this.targetRect.top; m_BeforeSelectionRect.bottom = this.targetRect.top + fontDesc.Height; m_SelectionRect.top = this.targetRect.top; m_SelectionRect.bottom = this.targetRect.top + fontDesc.Height; m_AfterSelectionRect.top = this.targetRect.top; m_AfterSelectionRect.bottom = this.targetRect.top + fontDesc.Height; }
protected void OnOwnerTextSelectionChanged(object sender, WindowEventArgs e) { Nexus.GUI.Widgets.UIEditBox editBox = owner as Nexus.GUI.Widgets.UIEditBox; UpdateVisibleRange(); }
protected void OnOwnerCaretPositionChanged(object sender, WindowEventArgs e) { Nexus.GUI.Widgets.UIEditBox editBox = owner as Nexus.GUI.Widgets.UIEditBox; //重新计算可见的文本范围,基准是插入提示符必须始终在可见范围内 UpdateVisibleRange(); }
protected void OnOwnerSizeChanged(object sender, GUIEventArgs e) { Nexus.GUI.Widgets.UIEditBox editBox = owner as Nexus.GUI.Widgets.UIEditBox; UpdateVisibleRange(); }