Bladeren bron

feat: 新增led控件,调整屏幕参数等

jiaxing.liao 2 weken geleden
bovenliggende
commit
ec6e00f5ea

+ 210 - 210
src/renderer/src/config/multi_chip_config.json

@@ -30,131 +30,131 @@
           "width": 1920,
           "height": 1080,
           "PCLK": 150.0,
-          "VBP": 36,
-          "VFP": 4,
-          "HBP": 148,
           "HFP": 88,
-          "HSYNC": 44,
-          "VSYNC": 5,
-          "HsyncWidth": 44,
-          "VsyncWidth": 5
+          "HBP": 148,
+          "HSW": 44,
+          "HSPOL": 0,
+          "VFP": 4,
+          "VBP": 36,
+          "VSW": 5,
+          "VSPOL": 1
         },
         "1920x720": {
           "width": 1920,
           "height": 720,
           "PCLK": 92.0,
-          "VBP": 28,
-          "VFP": 5,
-          "HBP": 110,
           "HFP": 40,
-          "HSYNC": 18,
-          "VSYNC": 5,
-          "HsyncWidth": 18,
-          "VsyncWidth": 5
+          "HBP": 110,
+          "HSW": 18,
+          "HSPOL": 0,
+          "VFP": 5,
+          "VBP": 28,
+          "VSW": 5,
+          "VSPOL": 0
         },
         "1280x800": {
           "width": 1280,
           "height": 800,
           "PCLK": 75.0,
-          "VBP": 18,
-          "VFP": 3,
-          "HBP": 84,
           "HFP": 40,
-          "HSYNC": 32,
-          "VSYNC": 6,
-          "HsyncWidth": 32,
-          "VsyncWidth": 6
+          "HBP": 84,
+          "HSW": 32,
+          "HSPOL": 0,
+          "VFP": 3,
+          "VBP": 18,
+          "VSW": 6,
+          "VSPOL": 0
         },
         "1280x720": {
           "width": 1280,
           "height": 720,
           "PCLK": 76.0,
-          "VBP": 20,
-          "VFP": 5,
-          "HBP": 112,
           "HFP": 20,
-          "HSYNC": 40,
-          "VSYNC": 5,
-          "HsyncWidth": 40,
-          "VsyncWidth": 5
+          "HBP": 112,
+          "HSW": 40,
+          "HSPOL": 0,
+          "VFP": 5,
+          "VBP": 20,
+          "VSW": 5,
+          "VSPOL": 0
         },
         "1280x480": {
           "width": 1280,
           "height": 480,
           "PCLK": 42.0,
-          "VBP": 12,
-          "VFP": 8,
-          "HBP": 42,
           "HFP": 40,
-          "HSYNC": 10,
-          "VSYNC": 4,
-          "HsyncWidth": 10,
-          "VsyncWidth": 4
+          "HBP": 42,
+          "HSW": 10,
+          "HSPOL": 0,
+          "VFP": 8,
+          "VBP": 12,
+          "VSW": 4,
+          "VSPOL": 0
         },
         "1024x600": {
           "width": 1024,
           "height": 600,
           "PCLK": 55.0,
-          "VBP": 24,
-          "VFP": 2,
-          "HBP": 170,
           "HFP": 160,
-          "HSYNC": 20,
-          "VSYNC": 3,
-          "HsyncWidth": 20,
-          "VsyncWidth": 3
+          "HBP": 170,
+          "HSW": 20,
+          "HSPOL": 0,
+          "VFP": 2,
+          "VBP": 24,
+          "VSW": 3,
+          "VSPOL": 0
         },
         "800x600": {
           "width": 800,
           "height": 600,
           "PCLK": 42.0,
-          "VBP": 25,
-          "VFP": 1,
-          "HBP": 90,
           "HFP": 40,
-          "HSYNC": 130,
-          "VSYNC": 4,
-          "HsyncWidth": 130,
-          "VsyncWidth": 4
+          "HBP": 90,
+          "HSW": 130,
+          "HSPOL": 0,
+          "VFP": 1,
+          "VBP": 25,
+          "VSW": 4,
+          "VSPOL": 0
         },
         "800x480": {
           "width": 800,
           "height": 480,
           "PCLK": 40.0,
-          "VBP": 15,
-          "VFP": 5,
-          "HBP": 40,
           "HFP": 40,
-          "HSYNC": 5,
-          "VSYNC": 5,
-          "HsyncWidth": 5,
-          "VsyncWidth": 5
+          "HBP": 40,
+          "HSW": 5,
+          "HSPOL": 0,
+          "VFP": 5,
+          "VBP": 15,
+          "VSW": 5,
+          "VSPOL": 0
         },
         "480x272": {
           "width": 480,
           "height": 272,
           "PCLK": 10.0,
-          "VBP": 4,
-          "VFP": 2,
-          "HBP": 4,
           "HFP": 4,
-          "HSYNC": 10,
-          "VSYNC": 4,
-          "HsyncWidth": 10,
-          "VsyncWidth": 4
+          "HBP": 4,
+          "HSW": 10,
+          "HSPOL": 0,
+          "VFP": 2,
+          "VBP": 4,
+          "VSW": 4,
+          "VSPOL": 0
         },
         "320x240": {
           "width": 320,
           "height": 240,
           "PCLK": 6.5,
-          "VBP": 16,
-          "VFP": 4,
-          "HBP": 40,
           "HFP": 12,
-          "HSYNC": 30,
-          "VSYNC": 3,
-          "HsyncWidth": 30,
-          "VsyncWidth": 3
+          "HBP": 40,
+          "HSW": 30,
+          "HSPOL": 0,
+          "VFP": 4,
+          "VBP": 16,
+          "VSW": 3,
+          "VSPOL": 0
         }
       },
       "single_screen": {
@@ -256,131 +256,131 @@
           "width": 1920,
           "height": 1080,
           "PCLK": 150.0,
-          "VBP": 36,
-          "VFP": 4,
-          "HBP": 148,
           "HFP": 88,
-          "HSYNC": 44,
-          "VSYNC": 5,
-          "HsyncWidth": 44,
-          "VsyncWidth": 5
+          "HBP": 148,
+          "HSW": 44,
+          "HSPOL": 0,
+          "VFP": 4,
+          "VBP": 36,
+          "VSW": 5,
+          "VSPOL": 1
         },
         "1920x720": {
           "width": 1920,
           "height": 720,
           "PCLK": 92.0,
-          "VBP": 28,
-          "VFP": 5,
-          "HBP": 110,
           "HFP": 40,
-          "HSYNC": 18,
-          "VSYNC": 5,
-          "HsyncWidth": 18,
-          "VsyncWidth": 5
+          "HBP": 110,
+          "HSW": 18,
+          "HSPOL": 0,
+          "VFP": 5,
+          "VBP": 28,
+          "VSW": 5,
+          "VSPOL": 0
         },
         "1280x800": {
           "width": 1280,
           "height": 800,
           "PCLK": 75.0,
-          "VBP": 18,
-          "VFP": 3,
-          "HBP": 84,
           "HFP": 40,
-          "HSYNC": 32,
-          "VSYNC": 6,
-          "HsyncWidth": 32,
-          "VsyncWidth": 6
+          "HBP": 84,
+          "HSW": 32,
+          "HSPOL": 0,
+          "VFP": 3,
+          "VBP": 18,
+          "VSW": 6,
+          "VSPOL": 0
         },
         "1280x720": {
           "width": 1280,
           "height": 720,
           "PCLK": 76.0,
-          "VBP": 20,
-          "VFP": 5,
-          "HBP": 112,
           "HFP": 20,
-          "HSYNC": 40,
-          "VSYNC": 5,
-          "HsyncWidth": 40,
-          "VsyncWidth": 5
+          "HBP": 112,
+          "HSW": 40,
+          "HSPOL": 0,
+          "VFP": 5,
+          "VBP": 20,
+          "VSW": 5,
+          "VSPOL": 0
         },
         "1280x480": {
           "width": 1280,
           "height": 480,
           "PCLK": 42.0,
-          "VBP": 12,
-          "VFP": 8,
-          "HBP": 42,
           "HFP": 40,
-          "HSYNC": 10,
-          "VSYNC": 4,
-          "HsyncWidth": 10,
-          "VsyncWidth": 4
+          "HBP": 42,
+          "HSW": 10,
+          "HSPOL": 0,
+          "VFP": 8,
+          "VBP": 12,
+          "VSW": 4,
+          "VSPOL": 0
         },
         "1024x600": {
           "width": 1024,
           "height": 600,
           "PCLK": 55.0,
-          "VBP": 24,
-          "VFP": 2,
-          "HBP": 170,
           "HFP": 160,
-          "HSYNC": 20,
-          "VSYNC": 3,
-          "HsyncWidth": 20,
-          "VsyncWidth": 3
+          "HBP": 170,
+          "HSW": 20,
+          "HSPOL": 0,
+          "VFP": 2,
+          "VBP": 24,
+          "VSW": 3,
+          "VSPOL": 0
         },
         "800x600": {
           "width": 800,
           "height": 600,
           "PCLK": 42.0,
-          "VBP": 25,
-          "VFP": 1,
-          "HBP": 90,
           "HFP": 40,
-          "HSYNC": 130,
-          "VSYNC": 4,
-          "HsyncWidth": 130,
-          "VsyncWidth": 4
+          "HBP": 90,
+          "HSW": 130,
+          "HSPOL": 0,
+          "VFP": 1,
+          "VBP": 25,
+          "VSW": 4,
+          "VSPOL": 0
         },
         "800x480": {
           "width": 800,
           "height": 480,
           "PCLK": 40.0,
-          "VBP": 15,
-          "VFP": 5,
-          "HBP": 40,
           "HFP": 40,
-          "HSYNC": 5,
-          "VSYNC": 5,
-          "HsyncWidth": 5,
-          "VsyncWidth": 5
+          "HBP": 40,
+          "HSW": 5,
+          "HSPOL": 0,
+          "VFP": 5,
+          "VBP": 15,
+          "VSW": 5,
+          "VSPOL": 0
         },
         "480x272": {
           "width": 480,
           "height": 272,
           "PCLK": 10.0,
-          "VBP": 4,
-          "VFP": 2,
-          "HBP": 4,
           "HFP": 4,
-          "HSYNC": 10,
-          "VSYNC": 4,
-          "HsyncWidth": 10,
-          "VsyncWidth": 4
+          "HBP": 4,
+          "HSW": 10,
+          "HSPOL": 0,
+          "VFP": 2,
+          "VBP": 4,
+          "VSW": 4,
+          "VSPOL": 0
         },
         "320x240": {
           "width": 320,
           "height": 240,
           "PCLK": 6.5,
-          "VBP": 16,
-          "VFP": 4,
-          "HBP": 40,
           "HFP": 12,
-          "HSYNC": 30,
-          "VSYNC": 3,
-          "HsyncWidth": 30,
-          "VsyncWidth": 3
+          "HBP": 40,
+          "HSW": 30,
+          "HSPOL": 0,
+          "VFP": 4,
+          "VBP": 16,
+          "VSW": 3,
+          "VSPOL": 0
         }
       },
       "single_screen": {
@@ -481,131 +481,131 @@
           "width": 1920,
           "height": 1080,
           "PCLK": 150.0,
-          "VBP": 36,
-          "VFP": 4,
-          "HBP": 148,
           "HFP": 88,
-          "HSYNC": 44,
-          "VSYNC": 5,
-          "HsyncWidth": 44,
-          "VsyncWidth": 5
+          "HBP": 148,
+          "HSW": 44,
+          "HSPOL": 0,
+          "VFP": 4,
+          "VBP": 36,
+          "VSW": 5,
+          "VSPOL": 1
         },
         "1920x720": {
           "width": 1920,
           "height": 720,
           "PCLK": 92.0,
-          "VBP": 28,
-          "VFP": 5,
-          "HBP": 110,
           "HFP": 40,
-          "HSYNC": 18,
-          "VSYNC": 5,
-          "HsyncWidth": 18,
-          "VsyncWidth": 5
+          "HBP": 110,
+          "HSW": 18,
+          "HSPOL": 0,
+          "VFP": 5,
+          "VBP": 28,
+          "VSW": 5,
+          "VSPOL": 0
         },
         "1280x800": {
           "width": 1280,
           "height": 800,
           "PCLK": 75.0,
-          "VBP": 18,
-          "VFP": 3,
-          "HBP": 84,
           "HFP": 40,
-          "HSYNC": 32,
-          "VSYNC": 6,
-          "HsyncWidth": 32,
-          "VsyncWidth": 6
+          "HBP": 84,
+          "HSW": 32,
+          "HSPOL": 0,
+          "VFP": 3,
+          "VBP": 18,
+          "VSW": 6,
+          "VSPOL": 0
         },
         "1280x720": {
           "width": 1280,
           "height": 720,
           "PCLK": 76.0,
-          "VBP": 20,
-          "VFP": 5,
-          "HBP": 112,
           "HFP": 20,
-          "HSYNC": 40,
-          "VSYNC": 5,
-          "HsyncWidth": 40,
-          "VsyncWidth": 5
+          "HBP": 112,
+          "HSW": 40,
+          "HSPOL": 0,
+          "VFP": 5,
+          "VBP": 20,
+          "VSW": 5,
+          "VSPOL": 0
         },
         "1280x480": {
           "width": 1280,
           "height": 480,
           "PCLK": 42.0,
-          "VBP": 12,
-          "VFP": 8,
-          "HBP": 42,
           "HFP": 40,
-          "HSYNC": 10,
-          "VSYNC": 4,
-          "HsyncWidth": 10,
-          "VsyncWidth": 4
+          "HBP": 42,
+          "HSW": 10,
+          "HSPOL": 0,
+          "VFP": 8,
+          "VBP": 12,
+          "VSW": 4,
+          "VSPOL": 0
         },
         "1024x600": {
           "width": 1024,
           "height": 600,
           "PCLK": 55.0,
-          "VBP": 24,
-          "VFP": 2,
-          "HBP": 170,
           "HFP": 160,
-          "HSYNC": 20,
-          "VSYNC": 3,
-          "HsyncWidth": 20,
-          "VsyncWidth": 3
+          "HBP": 170,
+          "HSW": 20,
+          "HSPOL": 0,
+          "VFP": 2,
+          "VBP": 24,
+          "VSW": 3,
+          "VSPOL": 0
         },
         "800x600": {
           "width": 800,
           "height": 600,
           "PCLK": 42.0,
-          "VBP": 25,
-          "VFP": 1,
-          "HBP": 90,
           "HFP": 40,
-          "HSYNC": 130,
-          "VSYNC": 4,
-          "HsyncWidth": 130,
-          "VsyncWidth": 4
+          "HBP": 90,
+          "HSW": 130,
+          "HSPOL": 0,
+          "VFP": 1,
+          "VBP": 25,
+          "VSW": 4,
+          "VSPOL": 0
         },
         "800x480": {
           "width": 800,
           "height": 480,
           "PCLK": 40.0,
-          "VBP": 15,
-          "VFP": 5,
-          "HBP": 40,
           "HFP": 40,
-          "HSYNC": 5,
-          "VSYNC": 5,
-          "HsyncWidth": 5,
-          "VsyncWidth": 5
+          "HBP": 40,
+          "HSW": 5,
+          "HSPOL": 0,
+          "VFP": 5,
+          "VBP": 15,
+          "VSW": 5,
+          "VSPOL": 0
         },
         "480x272": {
           "width": 480,
           "height": 272,
           "PCLK": 10.0,
-          "VBP": 4,
-          "VFP": 2,
-          "HBP": 4,
           "HFP": 4,
-          "HSYNC": 10,
-          "VSYNC": 4,
-          "HsyncWidth": 10,
-          "VsyncWidth": 4
+          "HBP": 4,
+          "HSW": 10,
+          "HSPOL": 0,
+          "VFP": 2,
+          "VBP": 4,
+          "VSW": 4,
+          "VSPOL": 0
         },
         "320x240": {
           "width": 320,
           "height": 240,
           "PCLK": 6.5,
-          "VBP": 16,
-          "VFP": 4,
-          "HBP": 40,
           "HFP": 12,
-          "HSYNC": 30,
-          "VSYNC": 3,
-          "HsyncWidth": 30,
-          "VsyncWidth": 3
+          "HBP": 40,
+          "HSW": 30,
+          "HSPOL": 0,
+          "VFP": 4,
+          "VBP": 16,
+          "VSW": 3,
+          "VSPOL": 0
         }
       },
       "single_screen": {

+ 8 - 6
src/renderer/src/locales/en_US.json

@@ -115,18 +115,20 @@
   "versionRequired": "version number is required",
   "pclkRequired": "PCLK is required",
   "VBPRequired": "VBP is required",
-  "VFPRequired": "VFP is required",
+  "HSWRequired": "HSW is required",
   "HBPRequired": "HBP is required",
   "HFPRequired": "HFP is required",
-  "HSYNCRequired": "HSYNC is required",
-  "VSYNCRequired": "VSYNC is required",
-  "HsyncWidthRequired": "HsyncWidth is required",
-  "VsyncWidthRequired": "VsyncWidth is required",
+  "HSPOLRequired": "HSPOL is required",
+  "VFPRequired": "VFP is required",
+  "VSWRequired": "VSW is required",
+  "VSPOLRequired": "VSPOL is required",
   "event": "Event",
   "log": "Log",
   "screenDirection": "Direction",
   "createComponent": "Create Component",
   "name": "Name",
   "desc": "Description",
-  "icon": "Icon"
+  "icon": "Icon",
+  "led": "LED",
+  "chart": "Chart"
 }

+ 8 - 6
src/renderer/src/locales/zh_CN.json

@@ -115,18 +115,20 @@
   "versionRequired": "版本号不能为空",
   "pclkRequired": "PCLK不能为空",
   "VBPRequired": "VBP不能为空",
-  "VFPRequired": "VFP不能为空",
+  "HSWRequired": "HSW不能为空",
   "HBPRequired": "HBP不能为空",
   "HFPRequired": "HFP 不能为空",
-  "HSYNCRequired": "HSYNC不能为空",
-  "VSYNCRequired": "VSYNC不能为空",
-  "HsyncWidthRequired": "HsyncWidth不能为空",
-  "VsyncWidthRequired": "VsyncWidth不能为空",
+  "HSPOLRequired": "HSPOL不能为空",
+  "VFPRequired": "VFP不能为空",
+  "VSWRequired": "VSW不能为空",
+  "VSPOLRequired": "VSPOL不能为空",
   "event": "事件",
   "log": "日志",
   "screenDirection": "方向",
   "createComponent": "创建组件",
   "name": "名称",
   "desc": "描述",
-  "icon": "图标"
+  "icon": "图标",
+  "led": "LED",
+  "chart": "图表"
 }

+ 3 - 1
src/renderer/src/lvgl-widgets/index.ts

@@ -23,6 +23,7 @@ import Menu from './menu/index'
 import Line from './line/index'
 import Arc from './arc'
 import Scale from './scale/index'
+import Led from './led/index'
 
 import Page from './page'
 import { IComponentModelConfig } from './type'
@@ -54,7 +55,8 @@ export const ComponentArray = [
 
   Line,
   Arc,
-  Scale
+  Scale,
+  Led
 ]
 
 const componentMap: { [key: string]: IComponentModelConfig } = ComponentArray.reduce((acc, cur) => {

+ 31 - 0
src/renderer/src/lvgl-widgets/led/Led.vue

@@ -0,0 +1,31 @@
+<template>
+  <div :style="ledStyle" class="w-full h-full flex items-center justify-center"></div>
+</template>
+
+<script setup lang="ts">
+import { computed } from 'vue'
+
+const props = defineProps<{
+  width: number
+  height: number
+  image: string
+  styles: any
+  part?: string
+  state?: string
+  led_color: string
+  led_set_bright: number
+}>()
+
+const ledStyle = computed(() => {
+  // LVGL LED 亮度:0~255,LV_LED_BRIGHT_MIN 默认 80(约 31%)
+  // 亮度映射:0 → 31%,255 → 100%,用 filter: brightness() 模拟变暗效果
+  const bright = props.led_set_bright / 255
+  const effectiveBright = 0.31 + 0.69 * bright
+  const r = Math.min(props.width, props.height) / 2
+  return {
+    borderRadius: `${r}px`,
+    backgroundColor: props.led_color,
+    filter: `brightness(${effectiveBright}) blur(${bright}px)`
+  }
+})
+</script>

+ 135 - 0
src/renderer/src/lvgl-widgets/led/index.ts

@@ -0,0 +1,135 @@
+import Led from './Led.vue'
+import icon from '../assets/icon/icon_23Led.svg'
+import { flagOptions, stateOptions } from '@/constants'
+import type { IComponentModelConfig } from '../type'
+import i18n from '@/locales'
+
+export default {
+  label: i18n.global.t('led'),
+  icon,
+  component: Led,
+  key: 'lv_led',
+  group: i18n.global.t('display'),
+  sort: 1,
+  hasChildren: false,
+  parts: [],
+  defaultSchema: {
+    name: 'led',
+    props: {
+      x: 0,
+      y: 0,
+      width: 40,
+      height: 40,
+      flags: [],
+      states: [],
+      led_color: '#2196f3',
+      led_set_bright: 255
+    },
+    styles: []
+  },
+  config: {
+    // 组件属性
+    props: [
+      {
+        label: '名称',
+        field: 'name',
+        valueType: 'text',
+        componentProps: {
+          placeholder: '请输入名称',
+          type: 'text'
+        }
+      },
+      {
+        label: '位置/大小',
+        valueType: 'group',
+        children: [
+          {
+            label: '',
+            field: 'props.x',
+            valueType: 'number',
+            componentProps: {
+              span: 12,
+              min: -10000,
+              max: 10000
+            },
+            slots: { prefix: 'X' }
+          },
+          {
+            label: '',
+            field: 'props.y',
+            valueType: 'number',
+            componentProps: {
+              span: 12,
+              min: -10000,
+              max: 10000
+            },
+            slots: { prefix: 'Y' }
+          },
+          {
+            label: '',
+            field: 'props.width',
+            valueType: 'number',
+            componentProps: {
+              span: 12,
+              min: 1,
+              max: 10000
+            },
+            slots: { prefix: 'W' }
+          },
+          {
+            label: '',
+            field: 'props.height',
+            valueType: 'number',
+            componentProps: {
+              span: 12,
+              min: 1,
+              max: 10000
+            },
+            slots: { prefix: 'H' }
+          }
+        ]
+      },
+      {
+        label: '标识',
+        field: 'props.flags',
+        valueType: 'checkbox',
+        componentProps: {
+          options: flagOptions,
+          defaultCollapsed: true
+        }
+      },
+      {
+        label: '状态',
+        field: 'props.states',
+        valueType: 'checkbox',
+        componentProps: {
+          options: stateOptions,
+          defaultCollapsed: true
+        }
+      }
+    ],
+    coreProps: [
+      {
+        label: '颜色',
+        field: 'props.led_color',
+        valueType: 'color',
+        componentProps: {
+          format: 'hex',
+          disableAlpha: true
+        }
+      },
+      {
+        label: '亮度',
+        field: 'props.led_set_bright',
+        valueType: 'slider',
+        componentProps: {
+          min: 0,
+          max: 255,
+          step: 1
+        }
+      }
+    ],
+    // 组件样式
+    styles: []
+  }
+} as IComponentModelConfig

+ 5 - 0
src/renderer/src/lvgl-widgets/led/style.json

@@ -0,0 +1,5 @@
+{
+  "widget": "lv_led",
+  "styleName": "defualt",
+  "part": []
+}

+ 1 - 1
src/renderer/src/model/index.ts

@@ -177,7 +177,7 @@ export const createWidget = (
     copyFrom: '',
     hidden: false,
     locked: false,
-    part: parts?.[0].name,
+    part: parts?.[0]?.name,
     state: parts?.[0]?.stateList?.[0],
     props: klona(defaultSchema.props || {}),
     style: klona(defaultSchema.styles || []),

+ 7 - 7
src/renderer/src/types/appMeta.d.ts

@@ -40,14 +40,14 @@ export type ScreenConfig = {
   // 屏幕参数
   params: {
     PCLK?: number
-    VBP?: number
-    VFP?: number
-    HBP?: number
     HFP?: number
-    HSYNC?: number
-    VSYNC?: number
-    HsyncWidth?: number
-    VsyncWidth?: number
+    HBP?: number
+    HSW?: number
+    HSPOL?: number
+    VFP?: number
+    VBP?: number
+    VSW?: number
+    VSPOL?: number
   }
 }
 

+ 25 - 0
src/renderer/src/utils/color.ts

@@ -45,6 +45,31 @@ function splitArgs(str: string): string[] {
   return result
 }
 
+/**
+ * hex 转 rgba,支持 #RGB、#RRGGBB、#RRGGBBAA
+ * @param hex 十六进制颜色
+ * @param alpha 透明度 0-1
+ */
+export function hexToRgba(hex: string, alpha: number): string {
+  if (!hex || !hex.startsWith('#')) return hex
+  let r = 0,
+    g = 0,
+    b = 0
+  const h = hex.slice(1)
+  if (h.length === 3) {
+    r = parseInt(h[0] + h[0], 16)
+    g = parseInt(h[1] + h[1], 16)
+    b = parseInt(h[2] + h[2], 16)
+  } else if (h.length === 6 || h.length === 8) {
+    r = parseInt(h.slice(0, 2), 16)
+    g = parseInt(h.slice(2, 4), 16)
+    b = parseInt(h.slice(4, 6), 16)
+  } else {
+    return hex
+  }
+  return `rgba(${r}, ${g}, ${b}, ${alpha})`
+}
+
 /**
  * [工具] hex8 (#RRGGBBAA) 转 rgba
  */

+ 13 - 1
src/renderer/src/views/designer/config/property/CusFormItem.vue

@@ -87,6 +87,18 @@
         v-model="value"
         v-bind="schema?.componentProps"
       />
+      <!-- 颜色选择 -->
+      <div class="flex" v-if="schema.valueType === 'color'">
+        <ColorPicker
+          v-model:pureColor="value"
+          v-model:gradientColor="value"
+          use-type="pure"
+          picker-type="chrome"
+          format="hex8"
+          v-bind="schema?.componentProps"
+        />
+        <span class="text-text-active">{{ value }}</span>
+      </div>
     </el-form-item>
 
     <!-- 分组 -->
@@ -240,6 +252,7 @@ import CusCheckbox from './components/CusCheckbox.vue'
 import CusTextarea from './components/CusTextarea.vue'
 import ImageSelect from './components/ImageSelect.vue'
 import SymbolSelect from './components/SymbolSelect.vue'
+import { ColorPicker } from '@/components'
 
 import StyleBackground from './components/StyleBackground.vue'
 import StyleBorder from './components/StyleBorder.vue'
@@ -298,7 +311,6 @@ const isFormItem = computed(() => {
   const exclude: string[] = [
     'group',
     'checkbox',
-    'color',
     'part',
     'background',
     'font',

+ 1 - 0
src/renderer/src/views/designer/config/property/type.d.ts

@@ -14,6 +14,7 @@ export enum ValueType {
   checkbox = 'checkbox',
   switch = 'switch',
   dependency = 'dependency',
+  symbol = 'symbol',
   // 样式部分
   part = 'part',
   background = 'background',

+ 68 - 64
src/renderer/src/views/designer/modals/projectModal/index.vue

@@ -195,69 +195,80 @@
                       controls-position="right"
                       style="width: 100%"
                       v-model="item.params.PCLK"
+                    >
+                      <template #suffix>MHz</template>
+                    </input-number>
+                  </el-form-item>
+                </el-col>
+                <el-col :span="8">
+                  <el-form-item label="HFP" :prop="`screens.${index}.params.HFP`">
+                    <input-number
+                      controls-position="right"
+                      style="width: 100%"
+                      v-model="item.params.HFP"
                     />
                   </el-form-item>
                 </el-col>
                 <el-col :span="8">
-                  <el-form-item label="VBP" :prop="`screens.${index}.params.VBP`">
+                  <el-form-item label="HBP" :prop="`screens.${index}.params.HBP`">
                     <input-number
                       controls-position="right"
                       style="width: 100%"
-                      v-model="item.params.VBP"
+                      v-model="item.params.HBP"
                     />
                   </el-form-item>
                 </el-col>
                 <el-col :span="8">
-                  <el-form-item label="VFP" :prop="`screens.${index}.params.VFP`">
+                  <el-form-item label="HSW" :prop="`screens.${index}.params.HSW`">
                     <input-number
                       controls-position="right"
                       style="width: 100%"
-                      v-model="item.params.VFP"
+                      v-model="item.params.HSW"
                     />
                   </el-form-item>
                 </el-col>
                 <el-col :span="8">
-                  <el-form-item label="HFP" :prop="`screens.${index}.params.HFP`">
+                  <el-form-item label="HSPOL" :prop="`screens.${index}.params.HSPOL`">
                     <input-number
                       controls-position="right"
                       style="width: 100%"
-                      v-model="item.params.HFP"
+                      v-model="item.params.HSPOL"
                     />
                   </el-form-item>
                 </el-col>
                 <el-col :span="8">
-                  <el-form-item label="HSYNC" :prop="`screens.${index}.params.HSYNC`">
+                  <el-form-item label="VFP" :prop="`screens.${index}.params.VFP`">
                     <input-number
                       controls-position="right"
                       style="width: 100%"
-                      v-model="item.params.HSYNC"
+                      v-model="item.params.VFP"
                     />
                   </el-form-item>
                 </el-col>
                 <el-col :span="8">
-                  <el-form-item label="VSYNC" :prop="`screens.${index}.params.VSYNC`">
+                  <el-form-item label="VBP" :prop="`screens.${index}.params.VBP`">
                     <input-number
                       controls-position="right"
                       style="width: 100%"
-                      v-model="item.params.VSYNC"
+                      v-model="item.params.VBP"
                     />
                   </el-form-item>
                 </el-col>
                 <el-col :span="8">
-                  <el-form-item label="HsyncWidth" :prop="`screens.${index}.params.HsyncWidth`">
+                  <el-form-item label="VSW" :prop="`screens.${index}.params.VSW`">
                     <input-number
                       controls-position="right"
                       style="width: 100%"
-                      v-model="item.params.HsyncWidth"
+                      v-model="item.params.VSW"
                     />
                   </el-form-item>
                 </el-col>
                 <el-col :span="8">
-                  <el-form-item label="VsyncWidth" :prop="`screens.${index}.params.VsyncWidth`">
+                  <el-form-item label="VSPOL" :prop="`screens.${index}.params.VSPOL`">
                     <input-number
                       controls-position="right"
                       style="width: 100%"
-                      v-model="item.params.VsyncWidth"
+                      v-model="item.params.VSPOL"
                     />
                   </el-form-item>
                 </el-col>
@@ -555,14 +566,14 @@ const formData = reactive<
       colorFormat: 'BGR',
       params: {
         PCLK: undefined,
-        VBP: undefined,
-        VFP: undefined,
-        HBP: undefined,
         HFP: undefined,
-        HSYNC: undefined,
-        VSYNC: undefined,
-        HsyncWidth: undefined,
-        VsyncWidth: undefined
+        HBP: undefined,
+        HSW: undefined,
+        HSPOL: undefined,
+        VFP: undefined,
+        VBP: undefined,
+        VSW: undefined,
+        VSPOL: undefined
       }
     }
   ],
@@ -637,31 +648,24 @@ const rules = computed(() => {
     ],
     'chip.ram_size.capacity': [{ required: true, message: t('ramIsRequired'), trigger: 'blur' }],
     'screens.0.params.PCLK': [{ required: true, message: t('pclkRequired'), trigger: 'change' }],
-    'screens.0.params.VBP': [{ required: true, message: t('VBPRequired'), trigger: 'change' }],
-    'screens.0.params.VFP': [{ required: true, message: t('VFPRequired'), trigger: 'change' }],
-    'screens.0.params.HBP': [{ required: true, message: t('HBPRequired'), trigger: 'change' }],
     'screens.0.params.HFP': [{ required: true, message: t('HFPRequired'), trigger: 'change' }],
-    'screens.0.params.HSYNC': [{ required: true, message: t('HSYNCRequired'), trigger: 'change' }],
-    'screens.0.params.VSYNC': [{ required: true, message: t('VSYNCRequired'), trigger: 'change' }],
-    'screens.0.params.HsyncWidth': [
-      { required: true, message: t('HsyncWidthRequired'), trigger: 'change' }
-    ],
-    'screens.0.params.VsyncWidth': [
-      { required: true, message: t('VsyncWidthRequired'), trigger: 'change' }
-    ],
+    'screens.0.params.HBP': [{ required: true, message: t('HBPRequired'), trigger: 'change' }],
+    'screens.0.params.HSW': [{ required: true, message: t('HSWRequired'), trigger: 'change' }],
+    'screens.0.params.HSPOL': [{ required: true, message: t('HSPOLRequired'), trigger: 'change' }],
+    'screens.0.params.VFP': [{ required: true, message: t('VFPRequired'), trigger: 'change' }],
+    'screens.0.params.VBP': [{ required: true, message: t('VBPRequired'), trigger: 'change' }],
+    'screens.0.params.VSW': [{ required: true, message: t('VSWRequired'), trigger: 'change' }],
+    'screens.0.params.VSPOL': [{ required: true, message: t('VSPOLRequired'), trigger: 'change' }],
+
     'screens.1.params.PCLK': [{ required: true, message: t('pclkRequired'), trigger: 'change' }],
-    'screens.1.params.VBP': [{ required: true, message: t('VBPRequired'), trigger: 'change' }],
-    'screens.1.params.VFP': [{ required: true, message: t('VFPRequired'), trigger: 'change' }],
-    'screens.1.params.HBP': [{ required: true, message: t('HBPRequired'), trigger: 'change' }],
     'screens.1.params.HFP': [{ required: true, message: t('HFPRequired'), trigger: 'change' }],
-    'screens.1.params.HSYNC': [{ required: true, message: t('HSYNCRequired'), trigger: 'change' }],
-    'screens.1.params.VSYNC': [{ required: true, message: t('VSYNCRequired'), trigger: 'change' }],
-    'screens.1.params.HsyncWidth': [
-      { required: true, message: t('HsyncWidthRequired'), trigger: 'change' }
-    ],
-    'screens.1.params.VsyncWidth': [
-      { required: true, message: t('VsyncWidthRequired'), trigger: 'change' }
-    ]
+    'screens.1.params.HBP': [{ required: true, message: t('HBPRequired'), trigger: 'change' }],
+    'screens.1.params.HSW': [{ required: true, message: t('HSWRequired'), trigger: 'change' }],
+    'screens.1.params.HSPOL': [{ required: true, message: t('HSPOLRequired'), trigger: 'change' }],
+    'screens.1.params.VFP': [{ required: true, message: t('VFPRequired'), trigger: 'change' }],
+    'screens.1.params.VBP': [{ required: true, message: t('VBPRequired'), trigger: 'change' }],
+    'screens.1.params.VSW': [{ required: true, message: t('VSWRequired'), trigger: 'change' }],
+    'screens.1.params.VSPOL': [{ required: true, message: t('VSPOLRequired'), trigger: 'change' }]
   }
 })
 
@@ -812,14 +816,14 @@ const handleChangeScreenTypeByChip = (type: any) => {
       // 屏幕参数
       params: {
         PCLK: resolution?.PCLK,
-        VBP: resolution?.VBP,
-        VFP: resolution?.VFP,
-        HBP: resolution?.HBP,
         HFP: resolution?.HFP,
-        HSYNC: resolution?.HSYNC,
-        VSYNC: resolution?.VSYNC,
-        HsyncWidth: resolution?.HsyncWidth,
-        VsyncWidth: resolution?.VsyncWidth
+        HBP: resolution?.HBP,
+        HSW: resolution?.HSW,
+        HSPOL: resolution?.HSPOL,
+        VFP: resolution?.VFP,
+        VBP: resolution?.VBP,
+        VSW: resolution?.VSW,
+        VSPOL: resolution?.VSPOL
       }
     })
   })
@@ -893,14 +897,14 @@ const handleChangeScreenTypeByBoard = (board: any) => {
       screenDirection: screen?.screen_direction?.default,
       params: {
         PCLK: undefined,
-        VBP: undefined,
-        VFP: undefined,
-        HBP: undefined,
         HFP: undefined,
-        HSYNC: undefined,
-        VSYNC: undefined,
-        HsyncWidth: undefined,
-        VsyncWidth: undefined
+        HBP: undefined,
+        HSW: undefined,
+        HSPOL: undefined,
+        VFP: undefined,
+        VBP: undefined,
+        VSW: undefined,
+        VSPOL: undefined
       }
     })
   })
@@ -945,14 +949,14 @@ const handleChangeScreenTypeByAnalog = (type: any) => {
       screenDirection: screen?.screen_direction?.default,
       params: {
         PCLK: undefined,
-        VBP: undefined,
-        VFP: undefined,
-        HBP: undefined,
         HFP: undefined,
-        HSYNC: undefined,
-        VSYNC: undefined,
-        HsyncWidth: undefined,
-        VsyncWidth: undefined
+        HBP: undefined,
+        HSW: undefined,
+        HSPOL: undefined,
+        VFP: undefined,
+        VBP: undefined,
+        VSW: undefined,
+        VSPOL: undefined
       }
     })
   })