ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Momentum-Firmware 的 JS 十六进制字节输入视图(gui/byte_input)开发指南

Momentum-Firmware 的 JS 十六进制字节输入视图(gui/byte_input)开发指南 Momentum-Firmware 的 JS 十六进制字节输入视图gui/byte_input开发指南【免费下载链接】Momentum-Firmware Feature-rich, stable and customizable Flipper Firmware项目地址: https://gitcode.com/GitHub_Trending/mo/Momentum-Firmware导读gui/byte_input是 Momentum-Firmware JS 应用fz-sdk中用于在 Flipper Zero 屏幕上显示十六进制键盘的 GUI 子模块常用于输入密钥、序列号、原始二进制数据等字节型参数。本文将以仓库中的官方文档 js_gui__byte_input.md 为核心骨架结合其 C 层实现、TypeScript 类型定义与官方示例脚本系统讲解该视图的依赖关系、三个核心属性header、length、defaultData、input事件的使用方式以及它在底层如何与原生ByteInput模块和事件循环联动。读完本文你将能够独立编写一个基于字节输入视图的完整可运行 JS 应用。模块定位与依赖导入byte input 视图的职责非常单一显示一个十六进制键盘让用户逐字节编辑一块二进制缓冲区。官方文档将其描述为 Displays a hexadecimal keyboardjs_gui__byte_input.md。在 JS 侧使用它需要按固定顺序导入三个模块let eventLoop require(event_loop); let gui require(gui); let byteInputView require(gui/byte_input);官方文档明确指出该模块依赖gui模块而gui又依赖event_loop模块因此三者必须按上述顺序导入并建议先理解这两个基础模块再使用本视图。这一依赖关系在源码中同样可见C 层适配文件 byte_input.c 同时包含了js_gui.h与../js_event_loop/js_event_loop.h且通过JS_GUI_VIEW_DEF(byte_input, view_descriptor)宏注册为gui的一个子模块。此外GUI 总览文档 js_gui.md 的视图适配表中也确认了byte_input在原生 View 与 JS 适配器之间属于「已适配✅」状态。创建视图makeWith 与 set与gui模块下其他视图一致byte input 也通过ViewFactory创建实例官方推荐使用makeWith(props)在创建时一次性传入初始属性let bytekb byteInputView.makeWith({ header: Look ma, Im a header text!, length: 8, defaultData: Uint8Array([0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88]), });对于已经创建的视图也可以在运行时通过View.set(property, value)修改任意属性见 js_gui.md 的View.setAPI 说明。视图属性View props详解官方文档定义了三个属性下表为原文属性表Prop类型描述lengthnumber要修改的缓冲区长度字节headerstring显示在键盘上方的单行文本defaultDatastring默认显示的数据结合 byte_input.d.ts 类型定义Props的实际类型为header: string、length: number、defaultData: Uint8Array | ArrayBuffer类型定义中以ArrayBuffer为基准示例与 C 实现中则普遍使用Uint8Array。header键盘上方的标题文本header是一行显示在键盘区域上方的文本。C 层实现中它被存入FuriString并直接调用原生byte_input_set_header_text()下发给视图见 byte_input.c 的header_assign。运行效果可参考官方截图length缓冲区长度length决定可编辑缓冲区的字节数它直接对应原生byte_input_set_result_callback()的bytes_count参数。源码中有一个值得注意的校验逻辑在len_assign中若传入的length小于defaultData的长度会报错length must be larger than defaultData lengthMJS_BAD_ARGS_ERROR避免出现用户参数自相矛盾的情况见 byte_input.c。注意缓冲区存在一个默认值若完全不设置length与defaultData上下文初始化时的DEFAULT_BUF_SZ为 4 字节#define DEFAULT_BUF_SZ 4。defaultData默认显示的数据defaultData指定视图打开时缓冲区中预填的内容类型为ArrayBuffer/Uint8Array源码中还兼容DataView会先经mjs_dataview_get_buf取出底层缓冲区。C 层实现default_data_assign做了两件事若缓冲区小于默认数据长度自动扩容到与默认数据一致将默认数据memcpy进缓冲区并将超出默认数据长度的剩余字节memset为0x00确保上次遗留的数据被清空见 byte_input.c。视图事件View eventsinput官方文档定义了唯一的事件事件项类型描述inputArrayBuffer当用户点击 Save 按钮时触发在 JS 侧事件通过事件循环的Contract机制订阅。C 层在ctx_make中创建了一个信号量FuriSemaphore并注册为JsEventLoopObjectTypeSemaphore类型的 contract通过mjs_set(mjs, view_obj, input, ...)暴露给 JS当用户按下 Save 时原生回调input_callback释放信号量事件循环的input_transformer随即把内部缓冲区以ArrayBuffer的形式取出并交给订阅者见 byte_input.c。使用示例来自官方示例脚本 gui.jseventLoop.subscribe(views.bytekb.input, function (_sub, data, gui, views) { let data_view Uint8Array(data); let text 0x; for (let i 0; i data_view.length; i) { text data_view[i].toString(16); } views.helloDialog.set(text, You typed:\n text); views.helloDialog.set(center, Cool!); gui.viewDispatcher.switchTo(views.helloDialog); }, gui, views);由于事件携带的是ArrayBuffer推荐先包一层Uint8Array(data)再按字节遍历如上例将其格式化为0x112233...形式的十六进制字符串展示。完整可运行示例官方文档建议读者参考gui.js示例脚本这里提取其中与 byte input 相关的完整片段。首先创建视图并加入视图集合let bytekb byteInputView.makeWith({ header: Look ma, Im a header text!, length: 8, defaultData: Uint8Array([0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88]), });接着在子菜单选择器中切换到该视图并订阅input事件接收用户确认的数据eventLoop.subscribe(views.demos.chosen, function (_sub, index, gui, eventLoop, views) { // ...其他分支 } else if (index 3) { gui.viewDispatcher.switchTo(views.bytekb); } // ... }, gui, eventLoop, views); eventLoop.subscribe(views.bytekb.input, function (_sub, data, gui, views) { // 处理用户保存的字节数据 }, gui, views); // 最后启动事件循环 gui.viewDispatcher.switchTo(views.demos); eventLoop.run();其中gui.viewDispatcher.switchTo(views.bytekb)将显示权交给字节输入视图在用户按下屏幕右侧的save按钮后input事件携带编辑完成的缓冲区触发订阅回调。整个示例的运行入口与导航回调逻辑见 gui.js。底层原理与原生 ByteInput 模块的桥接byte input 视图并非纯 JS 实现而是对 C 层原生模块的薄封装。原生模块位于 byte_input.h / byte_input.c其公开 API 包括byte_input_alloc()/byte_input_free()创建与销毁字节输入视图byte_input_get_view()获取可供ViewDispatcher嵌入的View实例byte_input_set_result_callback()设置结果回调Save 时触发与字节变更回调并绑定缓冲区指针及长度byte_input_set_header_text()设置键盘上方的标题文本。JS 适配层的view_descriptor将三者一一映射.alloc对应byte_input_alloc、.free对应byte_input_free、.get_view对应byte_input_get_view三个属性header/length/defaultData则分别对应header_assign/len_assign/default_data_assign三个赋值函数见 byte_input.c 的view_descriptor定义。这意味着修改header属性 → 同步调用byte_input_set_header_text修改length/defaultData属性 → 重新分配/整理缓冲区后再次调用byte_input_set_result_callback刷新绑定用户保存 → 原生回调释放信号量 → 事件循环以ArrayBuffer派发input事件。使用注意事项导入顺序event_loop→gui→gui/byte_input缺一不可顺序不可颠倒length与defaultData的关系length必须不小于defaultData的字节长度否则触发MJS_BAD_ARGS_ERROR报错两者都未设置时缓冲区默认为 4 字节defaultData的兼容类型类型定义要求Uint8Array | ArrayBufferC 层同时兼容DataView事件数据类型input事件回调收到的参数是ArrayBuffer需要按需转换为Uint8Array再进行字节级处理默认数据清理defaultData之外的多余缓冲区字节会被清零因此未显式赋值的部分在保存时得到的是0x00而不是随机残留数据。延伸阅读模块总览js_gui.mdGUI 概念Canvas、Viewport、View、ViewDispatcher以及各视图适配状态表事件循环基础js_event_loop.mdJS 开发总览ReadMe.md官方示例脚本gui.jsC 层类型定义byte_input.d.ts原生模块实现byte_input.h【免费下载链接】Momentum-Firmware Feature-rich, stable and customizable Flipper Firmware项目地址: https://gitcode.com/GitHub_Trending/mo/Momentum-Firmware创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表