Browse Source

feat: 添加矩阵按钮

jiaxing.liao 2 weeks ago
parent
commit
fa5978d20e

+ 2 - 1
src/renderer/src/locales/en_US.json

@@ -86,5 +86,6 @@
   "page": "page",
   "createTime": "Create Time",
   "imgButton": "Image Button",
-  "label": "Label"
+  "label": "Label",
+  "buttonMatrix": "Matrix Button"
 }

+ 2 - 1
src/renderer/src/locales/zh_CN.json

@@ -86,5 +86,6 @@
   "page": "页面",
   "createTime": "创建时间",
   "imgButton": "图片按钮",
-  "label": "标签"
+  "label": "标签",
+  "buttonMatrix": "矩阵按钮"
 }

+ 62 - 0
src/renderer/src/lvgl-widgets/button-matrix/ButtonMatrix.vue

@@ -0,0 +1,62 @@
+<template>
+  <div v-bind="getProps">{{ props.text }}</div>
+</template>
+
+<script setup lang="ts">
+import { computed } from 'vue'
+import defaultStyle from './style.json'
+
+const props = defineProps<{
+  width: number
+  height: number
+  text?: string
+  styles: any
+  state?: string
+}>()
+
+const getProps = computed(() => {
+  const styles = props.styles
+  let stateStyles = styles.find((item) => item.state === props.state)
+
+  // 从默认样式获取样式
+  if (!stateStyles && props.state) {
+    stateStyles = defaultStyle.part[0].state.find((item) => item.state === props.state)?.style
+  }
+
+  return {
+    class: 'button',
+    style: {
+      width: `${props.width}px`,
+      height: `${props.height}px`,
+
+      backgroundColor: stateStyles?.background.color,
+
+      fontSize: `${stateStyles?.text.size}px`,
+      color: stateStyles?.text?.color,
+      display: 'flex',
+      justifyContent: stateStyles?.text?.align || 'center',
+      alignItems: 'center',
+
+      borderRadius: `${stateStyles?.border.radius}px`,
+      borderColor: 'transparent',
+      borderWidth: `${stateStyles?.border.width}px`,
+      borderTopColor: ['all', 'top'].includes(stateStyles?.border?.side)
+        ? stateStyles?.border?.color
+        : 'transparent',
+      borderRightColor: ['all', 'right'].includes(stateStyles?.border?.side)
+        ? stateStyles?.border?.color
+        : 'transparent',
+      borderBottomColor: ['all', 'bottom'].includes(stateStyles?.border?.side)
+        ? stateStyles?.border?.color
+        : 'transparent',
+      borderLeftColor: ['all', 'left'].includes(stateStyles?.border?.side)
+        ? stateStyles?.border?.color
+        : 'transparent',
+      /* x 偏移量 | y 偏移量 | 阴影模糊半径 | 阴影扩散半径 | 阴影颜色 */
+      boxShodow: stateStyles?.boxShadow
+        ? `${stateStyles?.boxShadow?.offsetX}px ${stateStyles?.boxShadow?.offsetY}px ${stateStyles?.boxShadow?.width}px ${stateStyles?.boxShadow?.spread}px ${stateStyles?.boxShadow?.color}`
+        : 'none'
+    }
+  }
+})
+</script>

+ 242 - 0
src/renderer/src/lvgl-widgets/button-matrix/index.ts

@@ -0,0 +1,242 @@
+import LvButtonMatrix from './ButtonMatrix.vue'
+import icon from '../assets/icon/icon_3btn_group.svg'
+import type { IComponentModelConfig } from '../type'
+import i18n from '@/locales'
+import { flagOptions } from '@/constants'
+
+export default {
+  label: i18n.global.t('buttonMatrix'),
+  icon,
+  component: LvButtonMatrix,
+  key: 'lv_buttonmatrix',
+  group: i18n.global.t('basic'),
+  sort: 1,
+  parts: [
+    {
+      name: 'main',
+      stateList: ['default', 'focused', 'disabled']
+    },
+    {
+      name: 'items',
+      stateList: ['default', 'pressed']
+    }
+  ],
+  defaultSchema: {
+    props: {
+      name: 'btnmatrix',
+      x: 0,
+      y: 0,
+      width: 200,
+      height: 150,
+      addFlags: [],
+      removeFlags: [],
+      group: [
+        ['1', '2', '3'],
+        ['4', '5', '6'],
+        ['7', '8', '9']
+      ]
+    },
+    styles: [
+      {
+        part: {
+          name: 'main',
+          state: 'default'
+        },
+        background: {
+          color: '#ffffffff',
+          image: {
+            imgId: '',
+            color: ''
+          }
+        },
+        border: {
+          color: '#c8c8c8c8ff',
+          width: 1,
+          radius: 4,
+          side: ['all']
+        },
+        padding: {
+          top: 12,
+          right: 12,
+          bottom: 12,
+          left: 12
+        },
+        gap: {
+          row: 8,
+          column: 8
+        }
+      },
+      {
+        part: {
+          name: 'items',
+          state: 'default'
+        },
+        background: {
+          color: '#2092f5ff',
+          image: {
+            imgId: '',
+            color: '#00000000'
+          }
+        },
+        text: {
+          color: '#ffffffff',
+          family: 'xx',
+          size: 16,
+          align: 'center',
+          weight: 'normal'
+        },
+        border: {
+          color: '#c8c8c8ff',
+          width: 1,
+          radius: 4,
+          side: ['all']
+        },
+        shadow: {
+          color: '#2092f5ff',
+          x: 0,
+          y: 0,
+          spread: 0,
+          width: 0
+        }
+      }
+    ]
+  },
+  config: {
+    // 组件属性
+    props: [
+      {
+        label: '名称',
+        field: 'name',
+        valueType: 'text',
+        componentProps: {
+          placeholder: '请输入名称'
+        }
+      },
+      {
+        label: '位置/大小',
+        valueType: 'group',
+        children: [
+          {
+            label: 'X',
+            field: 'x',
+            valueType: 'number',
+            componentProps: {
+              span: 12
+            }
+          },
+          {
+            label: 'Y',
+            field: 'y',
+            valueType: 'number',
+            componentProps: {
+              span: 12
+            }
+          },
+          {
+            label: '宽度',
+            field: 'width',
+            valueType: 'number',
+            componentProps: {
+              span: 12
+            }
+          },
+          {
+            label: '高度',
+            field: 'height',
+            valueType: 'number',
+            componentProps: {
+              span: 12
+            }
+          }
+        ]
+      },
+      {
+        label: '添加标识',
+        field: 'addFlags',
+        valueType: 'checkbox',
+        componentProps: {
+          options: flagOptions
+        }
+      },
+      {
+        label: '删除标识',
+        field: 'removeFlags',
+        valueType: 'checkbox',
+        componentProps: {
+          options: flagOptions
+        }
+      },
+      {
+        label: '文本',
+        field: 'text',
+        valueType: 'text',
+        componentProps: {
+          useSymbol: true
+        }
+      },
+      {
+        label: '模式',
+        field: 'mode',
+        valueType: 'select',
+        componentProps: {
+          options: [
+            { label: 'Circular', value: 'circular' },
+            { label: 'Clip', value: 'clip' },
+            { label: 'Dot', value: 'dot' },
+            { label: 'Scroll', value: 'Scroll' },
+            { label: 'Wrap', value: 'wrap' }
+          ]
+        }
+      }
+    ],
+    // 组件样式
+    styles: [
+      {
+        label: '模块状态',
+        field: 'part',
+        valueType: 'part'
+      },
+      {
+        label: '背景',
+        field: 'background',
+        valueType: 'background'
+      },
+      {
+        label: '边框',
+        field: 'border',
+        valueType: 'border'
+      },
+      {
+        valueType: 'dependency',
+        name: ['part'],
+        dependency: ({ part }) => {
+          return part === 'items'
+            ? [
+                {
+                  label: '字体',
+                  field: 'text',
+                  valueType: 'text'
+                },
+                {
+                  label: '阴影',
+                  field: 'shadow',
+                  valueType: 'shadow'
+                }
+              ]
+            : [
+                {
+                  label: '内边距',
+                  field: 'shadow',
+                  valueType: 'shadow'
+                },
+                {
+                  label: '间距',
+                  field: 'gap',
+                  valueType: 'gap'
+                }
+              ]
+        }
+      }
+    ]
+  }
+} as IComponentModelConfig

+ 171 - 0
src/renderer/src/lvgl-widgets/button-matrix/style.json

@@ -0,0 +1,171 @@
+{
+  "widget": "button",
+  "styleName": "defualt",
+  "part": [
+    {
+      "partName": "main",
+      "state": [
+        {
+          "state": "default",
+          "style": {
+            "background": {
+              "color": "#2195f6ff",
+              "image": {
+                "imgId": "",
+                "color": ""
+              }
+            },
+            "text": {
+              "color": "#ffffffff",
+              "family": "xx",
+              "size": 16,
+              "weight": "normal",
+              "align": "center"
+            },
+            "border": {
+              "color": "#000000ff",
+              "width": 0,
+              "radius": 5,
+              "side": ["all"]
+            },
+            "shadow": {
+              "color": "#2092f5ff",
+              "x": 0,
+              "y": 0,
+              "spread": 0,
+              "width": 0
+            }
+          }
+        },
+        {
+          "state": "focused",
+          "style": {
+            "background": {
+              "color": "#2195f6ff",
+              "image": {
+                "imgId": "",
+                "color": ""
+              }
+            },
+            "text": {
+              "color": "#ffffffff",
+              "family": "xx",
+              "size": 16,
+              "weight": "normal",
+              "align": "center"
+            },
+            "border": {
+              "color": "#000000ff",
+              "width": 0,
+              "radius": 5,
+              "side": ["all"]
+            },
+            "shadow": {
+              "color": "#2092f5ff",
+              "x": 0,
+              "y": 0,
+              "spread": 0,
+              "width": 0
+            }
+          }
+        },
+        {
+          "state": "pressed",
+          "style": {
+            "background": {
+              "color": "#2195f6ff",
+              "image": {
+                "imgId": "",
+                "color": ""
+              }
+            },
+            "text": {
+              "color": "#ffffffff",
+              "family": "xx",
+              "size": 16,
+              "weight": "normal",
+              "align": "center"
+            },
+            "border": {
+              "color": "#000000ff",
+              "width": 0,
+              "radius": 5,
+              "side": ["all"]
+            },
+            "shadow": {
+              "color": "#2092f5ff",
+              "x": 0,
+              "y": 0,
+              "spread": 0,
+              "width": 0
+            }
+          }
+        },
+        {
+          "state": "checked",
+          "style": {
+            "background": {
+              "color": "#2195f6ff",
+              "image": {
+                "imgId": "",
+                "color": ""
+              }
+            },
+            "text": {
+              "color": "#000000ff",
+              "family": "xx",
+              "size": 16,
+              "weight": "normal",
+              "align": "center"
+            },
+            "border": {
+              "color": "#000000ff",
+              "width": 0,
+              "radius": 5,
+              "side": ["all"]
+            },
+            "shadow": {
+              "color": "#2092f5ff",
+              "x": 0,
+              "y": 0,
+              "spread": 0,
+              "width": 0
+            }
+          }
+        },
+        {
+          "state": "disabled",
+          "style": {
+            "background": {
+              "color": "#2195f6ff",
+              "image": {
+                "imgId": "",
+                "color": ""
+              }
+            },
+            "text": {
+              "color": "#000000ff",
+              "family": "xx",
+              "size": 16,
+              "weight": "normal",
+              "align": "center"
+            },
+            "border": {
+              "color": "#000000ff",
+              "width": 0,
+              "radius": 5,
+              "side": ["all"]
+            },
+            "shadow": {
+              "color": "#2092f5ff",
+              "x": 0,
+              "y": 0,
+              "spread": 0,
+              "width": 0
+            }
+          }
+        }
+      ]
+    }
+  ]
+}

+ 5 - 5
src/renderer/src/lvgl-widgets/button/style.json

@@ -19,7 +19,7 @@
               "color": "#ffffffff",
               "family": "xx",
               "size": 16,
-              "weight": 500,
+              "weight": "normal",
               "align": "center"
             },
             "border": {
@@ -51,7 +51,7 @@
               "color": "#ffffffff",
               "family": "xx",
               "size": 16,
-              "weight": 500,
+              "weight": "normal",
               "align": "center"
             },
             "border": {
@@ -83,7 +83,7 @@
               "color": "#ffffffff",
               "family": "xx",
               "size": 16,
-              "weight": 500,
+              "weight": "normal",
               "align": "center"
             },
             "border": {
@@ -115,7 +115,7 @@
               "color": "#000000ff",
               "family": "xx",
               "size": 16,
-              "weight": 500,
+              "weight": "normal",
               "align": "center"
             },
             "border": {
@@ -147,7 +147,7 @@
               "color": "#000000ff",
               "family": "xx",
               "size": 16,
-              "weight": 500,
+              "weight": "normal",
               "align": "center"
             },
             "border": {

+ 1 - 13
src/renderer/src/lvgl-widgets/image-button/index.ts

@@ -14,7 +14,7 @@ export default {
   parts: [
     {
       name: 'main',
-      stateList: ['default', 'focused', 'pressed', 'checked', 'disabled']
+      stateList: ['default', 'pressed', 'checked', 'disabled']
     }
   ],
   defaultSchema: {
@@ -36,13 +36,6 @@ export default {
           name: 'main',
           state: 'default'
         },
-        background: {
-          color: '#00000000',
-          image: {
-            imgId: '',
-            color: ''
-          }
-        },
         text: {
           color: '#ff00ffff',
           family: '',
@@ -168,11 +161,6 @@ export default {
         field: 'part',
         valueType: 'part'
       },
-      {
-        label: '背景',
-        field: 'background',
-        valueType: 'background'
-      },
       {
         label: '字体',
         field: 'text',

+ 87 - 0
src/renderer/src/lvgl-widgets/image-button/style.json

@@ -0,0 +1,87 @@
+{
+  "widget": "imagebutton",
+  "styleName": "defualt",
+  "part": [
+    {
+      "partName": "main",
+      "state": [
+        {
+          "state": "default",
+          "style": {
+            "text": {
+              "color": "#ff00ffff",
+              "family": "xx",
+              "size": 12,
+              "weight": "normal",
+              "align": "center"
+            },
+            "shadow": {
+              "color": "#2092f5ff",
+              "x": 0,
+              "y": 0,
+              "spread": 0,
+              "width": 0
+            }
+          }
+        },
+        {
+          "state": "pressed",
+          "style": {
+            "text": {
+              "color": "#ff00ffff",
+              "family": "xx",
+              "size": 12,
+              "weight": "normal",
+              "align": "center"
+            },
+            "shadow": {
+              "color": "#2092f5ff",
+              "x": 0,
+              "y": 0,
+              "spread": 0,
+              "width": 0
+            }
+          }
+        },
+        {
+          "state": "checked",
+          "style": {
+            "text": {
+              "color": "#ff00ffff",
+              "family": "xx",
+              "size": 12,
+              "weight": "normal",
+              "align": "center"
+            },
+            "shadow": {
+              "color": "#2092f5ff",
+              "x": 0,
+              "y": 0,
+              "spread": 0,
+              "width": 0
+            }
+          }
+        },
+        {
+          "state": "disabled",
+          "style": {
+            "text": {
+              "color": "#ff00ffff",
+              "family": "xx",
+              "size": 12,
+              "weight": "normal",
+              "align": "center"
+            },
+            "shadow": {
+              "color": "#2092f5ff",
+              "x": 0,
+              "y": 0,
+              "spread": 0,
+              "width": 0
+            }
+          }
+        }
+      ]
+    }
+  ]
+}

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

@@ -1,11 +1,12 @@
 import Button from './button'
 import ImageButton from './image-button'
+import MatrixButton from './button-matrix'
 import Container from './container'
 import Label from './label'
 import Page from './page'
 import { IComponentModelConfig } from './type'
 
-export const ComponentArray = [Button, ImageButton, Container, Page, Label]
+export const ComponentArray = [Button, ImageButton, MatrixButton, Container, Page, Label]
 
 const componentMap: { [key: string]: IComponentModelConfig } = ComponentArray.reduce((acc, cur) => {
   acc[cur.key] = cur