# 硬件插件设置菜单
# 功能
通过配置设置菜单,可以完成非程序运行类的功能,如查看固件信息、升级固件、配网、搜索外设、展示传感器数值等,对积木块编程和使用硬件有一定的辅助作用。
# 组成
硬件插件设置菜单至少需要包含以下部分:
- 图标
- 菜单名
- 菜单点击事件处理函数
如果还需要根据当前的连接方式、运行模式,来启用或禁用菜单(比如串口连接时,可以使用“串口监视器”,但蓝牙连接时,不能使用串口功能,菜单灰显),还需要配置:
- 菜单支持的运行模式列表
- 菜单支持的连接方式列表
# 定义方式
在插件入口文件中,找到 register 配置,使用 SettingMenuRegister
来配置插件菜单。
import type { UCodeExternalHardwareDefinition } from "@ubtech/ucode-extension-common-sdk/types";
const register: UCodeExternalHardwareDefinition.ExtensionRegister = {
// ... 省略其他字段 ...
// 配置插件菜单
SettingMenuRegister: {
ID_FIRMWARE_VERSION /* 菜单ID */: {
type: "callback", // 无UI的逻辑菜单类型
name: "查看固件版本", // 菜单名
icon: firmwareInfoIcon, // 菜单图标
availableDeviceTypes: [UDPDeviceType], // 菜单支持的连接方式
availableWorkingModes: ["online"], // 菜单支持的运行模式
callback: (util: { targetId: string }) => {
// 菜单点击事件处理函数
console.log("查看固件信息");
},
},
},
};
self.UCode.extensions.register(register);
# 参数说明
SettingMenuRegister
类型声明如下:
- 菜单基本数据:
type CommonSettingMenuItem<T = any> = {
/**
* 菜单名
*/
name: string;
/**
* 菜单图标
*/
icon: string;
/**
* 支持的设备连接类型,不支持将被禁用。比如一个菜单只能在串口下使用,在蓝牙连接方式下,会被禁用
*/
availableDeviceTypes?: DeviceType[];
/**
* 支持的工作模式,不支持将被禁用。比如一个菜单只能在在线模式下使用,在烧录模式下,会被禁用
*/
availableWorkingModes?: UCode.WorkingModeType[];
/**
* UI显示的额外参数
*/
additionalData?: T;
};
- 不带 UI 的设置菜单类型:
type CallbackSettingMenuItem = CommonSettingMenuItem & {
type: "callback";
callback: (util: ExtensionSettingUtil) => void;
};
支持自定义 UI 的菜单类型:
interface ReactComponent { (props: ReactComponentPropType): JSX.Element; } type ReactComponentRegisterData = { title?: string | UBT.IntlMessage; size?: UCodeCustomUI.ModalSizeType; radius?: string | number; // 弹窗的圆角 }; type ReactSettingMenuItem = CommonSettingMenuItem<ReactComponentRegisterData> & { type: "component"; component: ReactComponent; // react组件 };
例:
- 定义弹窗:
// components/example.tsx import React from "react"; import { UCodeExternalHardwareDefinition } from "@ubtech/ucode-extension-common-sdk/types"; export const DemoComponent: UCodeExternalHardwareDefinition.ReactComponent = (props) => { console.log(props.getDevice()); return ( <h1> 我是一个 React Hook 组件 MenuId: {props.menuId}, 设备类型: {props.getDevice()?.deviceType?.name} </h1> ); };
- 注册菜单:
// index.ts import { DemoComponent } from './components/example'; self.UCode.extensions.register({ // 省略... SettingMenuRegister: { myMenu: { name: '我的组件(自定义弹窗,无图标)', icon: '', // demo暂未配置图标 type: 'component', // 声明为有UI的菜单 component: DemoComponent, // 注册组件 additionalData: { title: '我的组件', }, },
- 菜单展示:
- UI 展示:
# 菜单名
设置 name
参数。
# 菜单图标
设置 icon
参数。
需要在 webpack 中使用 url-loader
,将图标打包进代码中。或者用完整的网络图标地址,比如:https://xxxx.xxxx.xxx/xxx/menu.svg
// webpack > module > rules
{
test: /\.(svg|png|jpg|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 10240,
},
},
],
},
为了与 uCode 的 UI 风格保持一致,我们建议自定义图标符合以下描述:
项 | 值 | 备注 |
---|---|---|
颜色 | #6A7078 或接近值 | 线框颜色 |
尺寸 | 推荐 22 x 22, 单位:px | |
图标格式 | 推荐 SVG。png、jpg、gif 可用 | |
风格描述 | - 线型 - 图标无异议 |
# 支持的连接方式
设置 availableDeviceTypes
参数。
availableDeviceTypes、DeviceRegister、当前连接方式,共同决定了该菜单是否可用。
在
DeviceRegister
中,设置了DeviceType
。当设备已连接,且连接方式是DeviceRegister
设置的一种。如果菜单设置支持的连接方式列表中,包含当前连接方式,那么菜单可用。
availableDeviceTypes 类型声明如下:
availableDeviceTypes?: DeviceType[];
type DeviceType = DeviceType: AutoConnectDeviceType | DiscoverDeviceType | InputIdDeviceType
连接方式可以是内置提供的,也可以是自定义的。如果是自定义类型,类型需要是
AutoConnectDeviceType | DiscoverDeviceType | InputIdDeviceType
中的一种。具体可以查阅 API 文档--DeviceType
内置的
DeviceType
内置的 DeviceType 有:
- 串口
- 蓝牙 webble
- 蓝牙 ucodeble
- mDNS
- udp
- tcp
通过下面方式,可以获取内置的
DeviceType
:import { CommonProtocols } from "@ubtech/ucode-extension-common-sdk"; const { SerialPortDeviceType } = CommonProtocols.SerialPort; const { WebBleDeviceType, UCodeBleDeviceType } = CommonProtocols.BLE; const { mDNSDeviceType } = CommonProtocols.MDNS; const { UDPDeviceType } = CommonProtocols.UDP; const { AutoTCPDeviceType } = CommonProtocols.TCP; // 使用时,根据需要,配置列表。 // register > SettingMenuRegister > menu > item availableDeviceTypes: [SerialPortDeviceType, WebBleDeviceType, UDPDeviceType, AutoTCPDeviceType /* 其他... */];
自定义的
DeviceType
假设自定义的 如下:
import type { DiscoverDeviceType } from "@ubtech/ucode-extension-common-sdk/types"; export function getTCPUDPDeviceType(): DiscoverDeviceType { return { connectType: "discover", // 连接类型,先搜索后连接。 id: "udp-tcp", // 通过id判断菜单是否支持当前连接方式 name: "Wi-Fi", // 在连接方式选择界面中显示的连接方式的文案。(当有多个连接方式时,会出现连接方式选择界面。) scanTime: 20, // 20秒搜索超时 needUcodelink: !isRunInMobile(), // 是否需要uCodeLink才能连接设备 }; } // 使用时,根据需要,配置列表。 // register > SettingMenuRegister > menu > item availableDeviceTypes: [SerialPortDeviceType, getTCPUDPDeviceType() /* 其他... */];
设置了多个连接方式:
# 支持的运行模式
设置 availableWorkingModes
参数。
availableWorkingModes 和 uCode 当前所处的运行模式共同决定了该菜单是否可用。
声明如下:
availableWorkingModes?: UCode.WorkingModeType[]; // UCode.WorkingModeType有两个值:'online', 'upload'
如果支持在线模式,填'online';如果支持烧录模式,填'upload';如果都支持,那就都填上。
availableWorkingModes: ["online", "upload"];