gpui-kit 无样式单行输入控件 Input 完整指南:状态模型、掩码校验与数字步进
发布时间:2026/9/14 15:35:50 作者:尧图编辑部 阅读量:1,286

gpui-kit 无样式单行输入控件 Input 完整指南状态模型、掩码校验与数字步进【免费下载链接】gpui-kitRust GUI components for building fantastic cross-platform desktop application by using GPUI.项目地址: https://gitcode.com/GitHub_Trending/gp/gpui-kitInput是gpui-base提供的单行文本输入控件它接管了编辑行为、焦点、选区、键盘输入、IME 输入法、掩码、校验与事件等全部交互逻辑而把外观呈现完全交给应用层。本文基于 website/base/primitives/input.md 展开结合 crates/base/src/input 下的真实源码系统讲解其状态生命周期、builder 配置 API、掩码/校验/数字步进原理、事件订阅方式与无样式呈现方案读完即可在 GPUI 应用中落地一个可运行的Input。一、Input 在 gpui-base 中的定位gpui-base把文本输入拆成了三个层级递进的控件Input负责普通单行文本Textarea负责多行普通文本Editor面向源码编辑。三者共享同一个底层引擎InputBaseStateM见 crates/base/src/input/base/state.rs通过类型参数M: InputModeKind区分能力InputState InputBaseStateInputMode其中InputMode的MULTI_LINE false见 crates/base/src/input/base/kind.rs即单行输入TextareaMode的MULTI_LINE true对应多行文本Editor模式额外叠加语言高亮、LSP、折叠等代码编辑能力。这种一个引擎、三种模式的设计意味着Input天然继承了完整的文本编辑内核——Rope 文本存储、显示映射DisplayMap、光标闪烁、撤销管理器UndoManager、选区与剪贴板操作而InputMode只负责把能力裁剪到单行输入所需的范围。从源码结构看Input的状态对象同时拥有focus_handle、text、selections、ime_marked_range等字段这正是它能同时处理焦点、键盘与中文等 IME 输入的基础。二、导入与基础用法按文档约定从gpui-kit统一入口导入use gpui_kit::base::input::{Input, InputEvent, InputState};Input的使用遵循 GPUI 的持久状态 每帧渲染范式状态InputState只创建一次保存为Entity渲染时通过Input::new(input)引用它避免每帧重建状态导致的焦点丢失与性能损耗let input cx.new(|cx| { InputState::new(window, cx) .placeholder(Account name) .default_value(Ada) }); // 渲染阶段 Input::new(input)其中default_value在状态构造时把文本直接写入内部的Rope见 crates/base/src/input/base/state.rs并标记_pending_update真正的文本布局会在下一次渲染的prepare阶段完成。读写值读取当前文本使用value()它会将内部的Rope物化为一个拥有所有权的SharedString程序化更新使用set_value需要同时传入window与cxlet value input.read(cx).value(); input.update(cx, |state, cx| { state.set_value(Grace, window, cx); });set_value的实现值得注意crates/base/src/input/base/state.rs它先把撤销管理器置为忽略模式、暂停事件发射再整体替换文本随后重置选区、滚动回起点并清空撤销历史。这模拟了 HTMLinput的行为——单行输入下光标置于文本末尾、视图滚回开头长值显示开头而非尾部同时程序化的整体赋值不进入用户的撤销栈。三、核心状态配置 API 一览InputState的配置方法分为构造期 builder 方法返回Self与运行期 setter 方法需要window/cx下表归纳自 crates/base/src/input/base/state.rs类别构造期方法运行期方法说明占位文本placeholderset_placeholder空值时的提示文字默认值default_valueset_value初始文本set_value会清空撤销历史密码掩码maskedset_masked/toggle_masked掩码状态下值不进入剪贴板格式掩码mask_patternset_mask_pattern如(999)999-9999自动生成占位符正则校验patternset_pattern传入regex::Regex输入必须整体匹配函数校验validateset_validator返回bool的闭包数字步进step/step_byset_step步长默认1.0数字范围min/maxset_min/set_max步进与失焦时夹取焦点—focus主动聚焦并启动光标闪烁右键菜单context_menuset_context_menu_enabled默认开启掩码与校验文档给出了密码输入的标准写法.masked(true)隐藏真实文本.validate提供业务校验闭包这里校验密码长度不少于 8 个字符let password cx.new(|cx| { InputState::new(window, cx) .placeholder(Password) .masked(true) .validate(|value, _| value.chars().count() 8) });validate的闭包签名是Fn(str, mut App) - boolcrates/base/src/input/base/state.rs在每次输入变化时被调用返回值决定本次编辑是否被接受pattern则接受一个预编译的regex::Regex要求输入整体匹配正则内部以is_match判断。二者可以叠加使用pattern管格式validate管业务语义。对于格式化输入文档强调组合使用mask_pattern、pattern、min、max、step或step_by。其中mask_pattern的占位符语法定义在 crates/base/src/input/base/mask_pattern.rs9—— 数字[0-9]A—— 字母[a-zA-Z]#—— 字母或数字[a-zA-Z0-9]*—— 任意字符其他字符 —— 作为字面分隔符自动插入例如(999)999-9999可格式化美国电话号码99999-9999可格式化邮政编码分隔符如括号、连字符会随输入自动补齐且mask_pattern设置后会自动把占位文本替换为形如(___) ___-____的掩码占位符见MaskPattern::placeholder。掩码模式还支持MaskPattern::Number变体可配置千分位分隔符与小数位数。读取带掩码输入的真实值使用unmask_value()crates/base/src/input/base/state.rs它会剥离掩码中的字面分隔符只返回用户真正键入的内容——这是提交表单时的正确取值方式。数字输入与步进min、max、step、step_by组合起来可以构造一个纯文本的数字输入配合组件层的 NumberInput 使用。语义如下step每次增减的步长默认1.0当step/min/max任一被设置时控件会内部更新值按step步进、夹取到min/max区间并发出InputEvent::Change而不是只抛出步进事件crates/base/src/input/base/state.rsstep_by传入一个Fn(f64, StepAction, mut App) - f64的自定义步长函数步长可随当前值变化例如在阈值 1.0 附近下行用 0.1、上行用 0.5min/max值会在步进时被夹取也会在失焦时再次夹取仅当夹取后的值能通过pattern/validate校验。四、事件订阅InputState通过EventEmitterInputEvent发射四类事件定义见 crates/base/src/input/base/state.rs事件触发时机InputEvent::Change文本内容发生变化InputEvent::PressEnter按下回车携带secondary与shift修饰键信息InputEvent::Focus获得焦点InputEvent::Blur失去焦点PressEnter对应输入上下文CONTEXT Input中绑定的enter、shift-enter、secondary-enter三个按键动作crates/base/src/input/base/state.rs因此可以在订阅中区分主回车、Shift回车与第二回车键例如用于提交表单 / 插入换行 / 确认但不关闭三种语义。订阅示例文档原例在Change事件中同步业务状态并触发重绘cx.subscribe(input, |this, state, event: InputEvent, cx| { if matches!(event, InputEvent::Change) { this.value state.read(cx).value(); cx.notify(); } });除事件外Input上下文还内置了大量按键绑定见init函数crates/base/src/input/base/state.rs方向键移动光标、Shift方向键扩展选区、Home/End行首行尾、Ctrl/CmdC/X/V剪贴板、Ctrl/CmdZ/CtrlY/CmdShiftZ撤销重做、Ctrl/CmdA全选macOS 与 Windows/Linux 采用各自惯用的修饰键方案且 Linux 下刻意避开了可能被桌面环境占用的CtrlAlt方向键组合。五、呈现层无样式哲学与 InputBasegpui-base的核心设计原则是不安装任何产品级样式。InputState只提供编辑语义呈现完全交给应用层通过set_editor_style向状态注入InputEditorStyle文本样式、配色等状态渲染时使用把控件组合进自己的 frame 中通常以InputBase作为外框。InputBasecrates/base/src/input/base/mod.rs是有意保持语义化的基础框架它只负责输入语义、交互转发与普通子元素支持focused/disabled状态、role覆盖默认Role::TextInput利于无障碍、accessibility_label并提供styles(|styles| ...)以声明式定义聚焦/禁用时的语义样式聚焦时边框变色、禁用时降透明度等。结合 crates/base/examples/showcase/components/input.rs 的示例一个典型的呈现组合是InputBase::new(example-input) .w_full() .h_7() .px_2() .flex() .items_center() .border_1() .border_color(example_rgb(0xd4d4d4)) .styles(|styles| { styles.focused(|style| style.border_color(example_rgb(0x171717))) }) .on_mouse_down(MouseButton::Left, move |_, window, cx| { state.update(cx, |state, cx| state.focus(window, cx)); }) .child(Input::new(input)),示例中InputBase承担边框、尺寸、悬停/聚焦视觉与鼠标聚焦转发Input::new(input)只负责内部文本的渲染与交互。如果你不想自行拼装外观文档明确推荐使用现成主题的gpui-component版 Input——它提供了完整的主题、尺寸、边框、前缀/后缀插槽如搜索图标、货币符号与清除按钮详见 website/component/input.md。两者的取舍是gpui-base的Input给你 100% 的视觉控制权适合定制化产品或设计系统gpui-component的Input开箱即用适合快速搭建。六、可运行示例仓库自带 showcase 示例可直接运行查看Input的实际效果cargo run -p gpui-base-examples -- input示例的实现位于 crates/base/examples/showcase/components/input.rs与之配套的文本控件还包括 Textarea 与 Editor 的示例组件。若需了解Input的底层行为源码集中在 crates/base/src/input/base 目录state.rs ——InputBaseState引擎文本、选区、IME、掩码、校验、步进、键绑定与全部配置 APIkind.rs —— 模式标记InputMode单行/TextareaMode多行等mask_pattern.rs —— 掩码 token 解析、占位符生成与unmask逻辑mod.rs ——InputBase语义框架与右键菜单能力InputContextMenuCapabilities掩码输入会禁止复制到剪贴板。小结Input是gpui-base文本输入体系中的单行基石一个状态对象承载焦点、选区、IME、掩码、校验、步进与事件应用层通过InputBase与InputEditorStyle自由决定外观。本文覆盖了从导入、状态创建、值读写到掩码/正则/函数三层校验、数字步进、事件订阅与呈现层组合的完整链路。若需要多行文本或源码编辑能力可进一步阅读同目录下的 Textarea 与 Editor 文档需要开箱即用的主题化输入则转向gpui-component的 Input 组件文档。【免费下载链接】gpui-kitRust GUI components for building fantastic cross-platform desktop application by using GPUI.项目地址: https://gitcode.com/GitHub_Trending/gp/gpui-kit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考