ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Momentum Firmware JS 开发指南:使用 gui/text_box 视图展示可滚动只读文本

Momentum Firmware JS 开发指南:使用 gui/text_box 视图展示可滚动只读文本 Momentum Firmware JS 开发指南使用 gui/text_box 视图展示可滚动只读文本【免费下载链接】Momentum-Firmware Feature-rich, stable and customizable Flipper Firmware项目地址: https://gitcode.com/GitHub_Trending/mo/Momentum-Firmware导读本文面向在 Momentum Firmware 上使用 JavaScript 编写 Flipper 应用的开发者系统讲解gui/text_box视图模块的完整用法。该模块用于在设备屏幕上显示一段可滚动的只读多行文本是展示长文本、说明信息、数据日志等内容的常用界面组件。读完本文你将掌握 text_box 的模块引入顺序、三个核心属性text/font/focus的取值与作用并能结合官方gui.js示例与底层 C 实现写出可滚动展示长文本的完整 JS 应用。模块定位与引入方式gui/text_box是 GUI 模块gui下的一个子模块与byte_input、dialog、submenu、widget等同属一类视图适配层。在 js_gui.md 的视图清单中text_box被标记为已有 JS 适配器的视图✅。与其他 GUI 视图一样它存在严格的依赖关系gui/text_box依赖gui模块而gui模块又依赖event_loop模块因此必须按下述顺序依次导入顺序颠倒会导致依赖缺失let eventLoop require(event_loop); let gui require(gui); let textBoxView require(gui/text_box);在 JS SDK 的类型声明packages/fz-sdk/gui/text_box.d.ts中该模块导出的是一个TextBoxFactory其中Props恰好由text、font、focus三个属性构成Child类型为never说明 text_box 是一个不接收子元素的简单视图。视图属性详解text_box 共有三个属性均可在创建视图时通过makeWith(props)传入或在创建后用view.set(name, value)动态修改属性类型说明textstring文本框中要显示的文本内容fontstring文本渲染字体取值为text或hexfocusstring文本框的初始焦点位置取值为start或endtext待显示文本text属性设置文本框中显示的字符串。底层实现会把字符串拷贝保存再交给 C 层视图渲染。从 JS 适配层源码text_box.c可以看到其处理逻辑static bool text_assign(struct mjs* mjs, TextBox* text_box, JsViewPropValue value, FuriString* context) { UNUSED(mjs); furi_string_set(context, value.string); text_box_set_text(text_box, furi_string_get_cstr(context)); return true; }JS 传入的字符串会先存入一个FuriString上下文再通过text_box_set_text交给底层TextBox对象对应 C API text_box.h。值得注意的是底层TextBox结构体text_box.c只保存const char* text指针而 JS 适配层用FuriString上下文持有字符串所有权保证视图渲染期间文本数据始终有效——这正是ctx_make/ctx_destroy在视图创建与销毁时分配、释放FuriString的原因。文本支持\n换行符当内容超出屏幕时视图会自动启用上下滚动方向键D-Pad上下即可翻阅。font文本字体font决定文本的渲染字体仅接受text或hex两个取值对应底层 text_box.h 中的两个枚举typedef enum { TextBoxFontText, TextBoxFontHex, } TextBoxFont;JS 适配层text_box.c通过大小写不敏感的字符串比较完成映射static bool font_assign(struct mjs* mjs, TextBox* text_box, JsViewPropValue value, void* context) { UNUSED(context); TextBoxFont font; if(strcasecmp(value.string, hex) 0) { font TextBoxFontHex; } else if(strcasecmp(value.string, text) 0) { font TextBoxFontText; } else { mjs_prepend_errorf(mjs, MJS_BAD_ARGS_ERROR, must be one of: \text\, \hex\); return false; } text_box_set_font(text_box, font); return true; }text常规文本字体适合展示普通说明文字、日志内容hex等宽风格字体适合展示十六进制转储、固定格式数据等。传入其他任何值都会触发MJS_BAD_ARGS_ERROR错误错误信息为must be one of: text, hex因此务必只使用这两个取值。focus初始焦点focus决定视图首次显示时文本定位在开头还是结尾对应底层 text_box.h 的枚举typedef enum { TextBoxFocusStart, TextBoxFocusEnd, } TextBoxFocus;JS 适配层text_box.c同样只接受两个取值其余值会报错startTextBoxFocusStart从文本开头显示适合阅读型长文endTextBoxFocusEnd定位到文本末尾适合日志/追加型内容——打开即可看到最新写入的数据。创建与使用完整示例text_box 视图的创建方式与其他视图一致均来自ViewFactory的make()/makeWith(props)两个方法随后通过view.set(name, value)修改属性通用ViewAPI 的实现见 js_gui.c 与 js_gui.c。最小可用示例let eventLoop require(event_loop); let gui require(gui); let textBoxView require(gui/text_box); // 用 makeWith 直接传入初始属性 let infoView textBoxView.makeWith({ text: Momentum Firmware\nJS text box demo\n\nThis is a scrollable read-only text field., font: text, focus: start, }); // 也可以先用 make() 创建空视图再逐个 set 属性 let logView textBoxView.make(); logView.set(text, line 1\nline 2\n...); logView.set(font, hex); logView.set(focus, end); // 通过 view dispatcher 切换到该视图并启动事件循环 gui.viewDispatcher.switchTo(infoView); eventLoop.run();官方示例gui.js 中的 Text box demo官方综合示例脚本 gui.js 中演示了 text_box 的典型用法。脚本先引入模块let textBoxView require(gui/text_box);随后用makeWith创建一个展示超长文本的视图gui.jslongText: textBoxView.makeWith({ text: This is a very long string that demonstrates the TextBox view. Use the D-Pad to scroll backwards and forwards.\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse rhoncus est malesuada quam egestas ultrices. Maecenas non eros a nulla eleifend vulputate et ut risus. Quisque in mauris mattis, venenatis risus eget, aliquam diam. Fusce pretium feugiat mauris, ut faucibus ex volutpat in. Phasellus volutpat ex sed gravida consectetur. Aliquam sed lectus feugiat, tristique lectus et, bibendum lacus. Ut sit amet augue eu sapien elementum aliquam quis vitae tortor. Vestibulum quis commodo odio. In elementum fermentum massa, eu pellentesque nibh cursus at. Integer eleifend lacus nec purus elementum sodales. Nulla elementum neque urna, non vulputate massa semper sed. Fusce ut nisi vitae dui blandit congue pretium vitae turpis., }),注意这里的文本刻意使用了不含换行的超长字符串——底层 TextBox 会依据屏幕宽度自动折行行数超过一屏后即可上下滚动。脚本通过eventLoop.subscribe订阅子菜单选择事件在选择 “Text box” 菜单项时执行gui.viewDispatcher.switchTo(views.longText)切换到该视图同时订阅gui.viewDispatcher.navigation事件按返回键回到 demo 选择菜单完整交互代码见 gui.js。源码级原理从 JS 属性到 C 视图的调用链text_box 的 JS 适配层是一个标准化的JsViewDescriptortext_box.c描述了一个视图所需的全部钩子与属性表static const JsViewDescriptor view_descriptor { .alloc (JsViewAlloc)text_box_alloc, .free (JsViewFree)text_box_free, .get_view (JsViewGetView)text_box_get_view, .custom_make (JsViewCustomMake)ctx_make, .custom_destroy (JsViewCustomDestroy)ctx_destroy, .prop_cnt 3, .props { (JsViewPropDescriptor){ .name text, .type JsViewPropTypeString, .assign (JsViewPropAssign)text_assign}, (JsViewPropDescriptor){ .name font, .type JsViewPropTypeString, .assign (JsViewPropAssign)font_assign}, (JsViewPropDescriptor){ .name focus, .type JsViewPropTypeString, .assign (JsViewPropAssign)focus_assign}, }}; JS_GUI_VIEW_DEF(text_box, view_descriptor);由此可以梳理出完整的调用链require(gui/text_box)返回一个ViewFactory对象js_gui_make_view_factory见 js_gui.c其make/makeWith方法指向统一的工厂函数makeWith({...})调用 js_gui.c 中的js_gui_vf_make_with先通过js_gui_make_view分配底层视图text_box_alloc、向view_dispatcher注册并获得视图 ID再遍历props对象逐个调用属性分配逻辑属性分配js_gui_view_assignjs_gui.c按属性名在props表中查找描述符校验 JS 值类型如text/font/focus都要求是string最后调用对应的assign回调assign回调内部再调用 C 层 APItext_box_set_text/text_box_set_font/text_box_set_focus最终由 text_box.c 完成渲染与输入处理。底层的滚动与渲染实现从底层实现 text_box.c 可以看出 TextBox 视图的设计细节文本区域尺寸为TEXT_BOX_TEXT_WIDTH 120、TEXT_BOX_TEXT_HEIGHT 56像素每屏最多显示 10 行TEXT_BOX_MAX_LINES_PER_SCREEN按方向键上/下滚动长按会触发加速按住超过阈值后滚动速度从中速每 tick 3 行提升到快速每 tick 5 行并有饱和上限TEXT_BOX_LINES_SCROLL_SPEED_SATURATION 9相关常量定义见 text_box.c模型状态scroll_pos/scroll_num/line_offset等跟踪当前滚动位置与总行数text_box_process_down/text_box_process_uptext_box.c负责边界钳制与逐行/逐屏滚动。这些常量说明 text_box 面向的是 Flipper 128×64 的屏幕单屏信息密度约 10 行文本长内容必须依赖滚动浏览。典型使用场景与注意事项适用场景展示长说明、使用条款、帮助文本等只读内容显示运行日志、数据转储配合hex字体展示动态生成的多行结果如文件内容预览、命令输出。注意事项导入顺序不可颠倒必须event_loop→gui→gui/text_boxfont与focus取值受限非法值会直接抛出MJS_BAD_ARGS_ERRORJS 应用应当只传文档规定的枚举值text_box 不支持子元素View.addChild/setChildren等方法对 text_box 不可用类型声明中Child never需要组合多种元素时请改用gui/widgetwidget 视图内部同样支持添加text_box类型元素见 widget.c更新文本后焦点行为focus: end适合日志追加场景新文本写入后视图会定位到末尾而focus: start则始终从开头展示。延伸阅读GUI 模块总览View / ViewFactory / ViewDispatcher 概念与全部子模块清单JS 模块入口与线程模型 与 JS 事件循环理解event_loop.run()与事件订阅机制底层 TextBox 视图 APIC 层TextBox的分配、设置与释放接口JS 适配层实现text_box 三个属性的 JS→C 绑定代码综合示例脚本包含 text_box 与其他十余种视图的完整可运行 demo【免费下载链接】Momentum-Firmware Feature-rich, stable and customizable Flipper Firmware项目地址: https://gitcode.com/GitHub_Trending/mo/Momentum-Firmware创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表