UGUI源码解析(十三)InputField

InputField

InputField可以提供文本输入功能,是与用户交互的一个重要手段。我们可以在编辑器里,为OnValueChanged和OnEndEdit两个事件添加监听,这样就可以获得用户输入的文本。

public class InputField : Selectable,IUpdateSelectedHandler,IBeginDragHandler,
IDragHandler,IEndDragHandler,IPointerClickHandler,ISubmitHandler,
ICanvasElement,ILayoutElement

 

OnEnable方法

  • 设置了输入文字绘制开始的位置,结束的位置。
  • m_TextComponent调用了RegisterDirtyVerticesCallback两次,添加MarkGeometryAsDirty和UpdateLabel回调,
  • 调用了RegisterDirtyMaterialCallback,添加UpdateCaretMaterial回调,
  • 最后调用UpdateLabel。

MarkGeometryAsDirty

在CanvasUpdateRegistry里把自己注册到图形重建序列。

UpdateLabel方法

  • 为字符串添加光标,如果是密码类型的输入,用*号代替输入,如果是空的,显示占位符。
  • 如果字符串不为空,先通过GetGenerationSettings方法,获取文本生成设置,
  • 调用cachedInputTextGenerator.PopulateWithErrors方法,生成Mesh的顶点数据和文本字符串数据,
  • 然后调用SetDrawRangeToContainCaretPosition设置包含光标的字符串绘制区域,根据TextGenerator和caretPos(光标位置)来计算m_DrawStart和m_DrawEnd,并根据这两个值取字符串的子字符串,设置光标可见(使用协程闪烁)。
  • 把经过加工的processed赋值给m_TextComponent.text,并调用MarkGeometryAsDirty把自己注册到图形重建序列。

UpdateCaretMaterial方法

  • 调用m_TextComponent.GetModifiedMaterial(Graphic.defaultGraphicMaterial), Texture2D.whiteTexture);创建一个默认的材质
  • 调用m_CachedInputRenderer.SetMaterial把创建的材质赋值给光标,更新光标的材质

OnDisable方法

  • 停止了光标闪烁,调用DeactivateInputField停用InputField
  • 解除了m_TextComponent的三个回调,并把自己从布局重建序列和图形重建序列中移除,
  • 清空m_CachedInputRenderer
  • DestroyImmediate(m_Mesh),并设置m_Mesh为null,也就是清空绘制光标和选中区域的Mesh。

DeactivateInputField方法,停用InputField,以停止处理事件

  • 设置m_Keyboard.active为false,
  • 设置光标位置为0,
  • 如果IsInteractable为true,调用SendOnSubmit,发送onEndEdit事件, onEndEdit.Invoke(m_Text),
  • 最后调用MarkGeometryAsDirty等待重建。

ActivateInputField方法,激活InputField,以开始处理事件

  • 设置m_Keyboard.active为true,
  • 为m_Text赋值给m_Keyboard.text,
  • 设置m_ShouldActivateNextUpdate为true。

 

重写OnPointerDown方法,设置本对象为当前选择对象,如果已经被选中,则设置光标的位置,然后调用UpdateLabel。

重写OnSelect方法,重写OnPointerClick,同样调用ActivateInputField,激活InputField方法

重写OnDeSelect方法,调用DeactivateInputField,停用InputField。

Selectable的DoStateTransition也被重写,会让点击过后的输入区域一直处于高亮状态,直到输入区域被反激活。

OnUpdateSelected方法

继承自IUpdateSelectedHandler接口,输入模块切换到StandaloneInputModule时会被调用。在键盘按下时,执行KeyPressed方法,处理一系列键盘输入的操作,比如退格键,复制粘贴(Ctrl+ c、Ctrl+v)。

OnBeginDrag方法,设置m_UpdateDrag为true。

OnDrag方法

根据鼠标的位置设置选中区域,如果鼠标在边界范围之外,调用协程MouseDragOutsideRect,只是单行时,如果鼠标位置比rect的最小值还小,把选择光标移动到左边,否则往右移动。多行时,会有上下的选中区域移动,然后UpdateLabel更新。当拖拽结束或回到InputField范围内,停止协程。

OnEndDrag方法,设置m_UpdateDrag为false。

OnPointerClick方法,调用ActivateInputField,激活InputField。

OnSubmit方法,如果isFocused为false,设置m_ShouldActivateNextUpdate为true,在LateUpdate里激活输入区域。

Rebuild方法

CanvasUpdateRegistry重建图像是会回调Rebuild方法。方法里调用了UpdateGeometry方法。

UpdateGeometry方法

  • 为InputField添加一个InputField Input Caret对象,在添加的对象上,添加了RectTransform和CanvasRenderer,用于显示光标和选中区域。
  • 添加LayoutElement组件,并设置ignoreLayout为true,调用AssignPositioningIfNeeded设置光标的位置等信息,
  • 调用OnFillVBO方法为CanvasRenderer生成Mesh, m_CachedInputRenderer.SetMesh(mesh)。

OnFillVBO方法

如果没有选择区域,调用GenerateCaret生成光标的Mesh,否则,调用GenerateHightlight生成选中区域的Mesh。然后调用VertexHelper.FillMesh,填充Mesh。

GenerateCaret方法

根据光标位置,计算出四个顶点,调用vbo.AddUIVertexQuad添加四个顶点到VertexHelper。

GenerateHightlight方法

根据选中区域的起始点和结束点,计算出四个顶点,调用vbo.AddVert添加顶点到VertexHelper。

LateUpdate方法

  • 如果m_ShouldActivateNextUpdate为true,调用ActivateInputFieldInternal,激活InputField,
  • 调用AssignPositioningIfNeeded设置光标的位置等信息,
  • 如果m_Keyboard == null或m_Keyboard.done(结束输入),调用OnDeselect,方法里调用DeactivateInputField,停用InputField。
  • 如果m_Keyboard的输入与之前的不同,遍历输入字符, 根据CharacterValidation类型(Integer,Decimal(小数),Alphanumeric(字母数字),Name,EmailAddress)判断输入字符的合法性。
  • 如果characterLimit > 0并且输入字符长度大于characterLimit,截取限制长度的字符串。
  • 调用SendOnValueChangedAndUpdateLabel,发送OnValueChanged事件,并更新。
  • 如果键盘结束输入,调用OnDeselect,方法里调用DeactivateInputField,停用InputField。

ActivateInputFieldInternal方法

  • 设置本对象为选择对象SetSelectedGameObject
  • 如果支持触屏键盘,开启触屏键盘TouchScreenKeyboard.Open,调用MoveTextEnd选中全部
  • 设置光标可见SetCaretVisible
  • 调用UpdateLabel更新
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值