فهرست منبع

fix: 修改控件问题

liaojiaxing 2 هفته پیش
والد
کامیت
2263fc0ae7

+ 61 - 11
src/renderer/src/lvgl-widgets/bar/Bar.vue

@@ -1,15 +1,14 @@
 <template>
   <div :style="styleMap?.mainStyle" class="w-full h-full box-border relative">
     <ImageBg :src="styleMap?.mainStyle?.imageSrc" :image-style="styleMap?.mainStyle?.imageStyle" />
-    <div class="absolute overflow-hidden" :style="indicatorStyle">
-      <ImageBg
-        :src="styleMap?.indicatorStyle?.imageSrc"
-        :image-style="styleMap?.indicatorStyle?.imageStyle"
-        :style="{
-          width: width + 'px',
-          height: height + 'px'
-        }"
-      />
+    <div class="absolute" :style="trackStyle">
+      <div class="absolute overflow-hidden" :style="indicatorStyle">
+        <ImageBg
+          :src="styleMap?.indicatorStyle?.imageSrc"
+          :image-style="styleMap?.indicatorStyle?.imageStyle"
+          :style="indicatorImageStyle"
+        />
+      </div>
     </div>
   </div>
 </template>
@@ -56,14 +55,65 @@ const getOffset = (value: string | number | undefined, total = 0) => {
   return Number(value) || 0
 }
 
+const parseCssNumber = (value: unknown) => {
+  const number = Number.parseFloat(String(value ?? 0))
+  return Number.isFinite(number) ? number : 0
+}
+
+const parsePadding = (padding: CSSProperties['padding']) => {
+  const values = String(padding ?? '0')
+    .trim()
+    .split(/\s+/)
+    .map(parseCssNumber)
+
+  const top = values[0] ?? 0
+  const right = values[1] ?? top
+  const bottom = values[2] ?? top
+  const left = values[3] ?? right
+
+  return { top, right, bottom, left }
+}
+
+const mainPadding = computed(() => parsePadding(styleMap.value?.mainStyle?.padding))
+
+const trackStyle = computed<CSSProperties>(() => {
+  const { top, right, bottom, left } = mainPadding.value
+
+  return {
+    top: `${top}px`,
+    right: `${right}px`,
+    bottom: `${bottom}px`,
+    left: `${left}px`
+  }
+})
+
+const indicatorOffset = computed(() => {
+  const width = Number(props.width || 0)
+  const height = Number(props.height || 0)
+  const { top, right, bottom, left } = mainPadding.value
+  const trackWidth = Math.max(width - left - right, 0)
+  const trackHeight = Math.max(height - top - bottom, 0)
+
+  return {
+    left: left + getOffset(otherStyle.value.left, trackWidth),
+    top: top + getOffset(otherStyle.value.top, trackHeight)
+  }
+})
+
+const indicatorImageStyle = computed<CSSProperties>(() => ({
+  width: `${props.width || 0}px`,
+  height: `${props.height || 0}px`,
+  left: `${-indicatorOffset.value.left}px`,
+  top: `${-indicatorOffset.value.top}px`
+}))
+
 const indicatorGradientStyle = computed<CSSProperties>(() => {
   const indicatorBackground = styleMap.value?.indicatorStyle?.background
   if (!isGradientBackground(indicatorBackground)) return {}
 
   const width = Number(props.width || 0)
   const height = Number(props.height || 0)
-  const left = getOffset(otherStyle.value.left, width)
-  const top = getOffset(otherStyle.value.top, height)
+  const { left, top } = indicatorOffset.value
 
   return {
     backgroundSize: `${width}px ${height}px`,

+ 14 - 13
src/renderer/src/lvgl-widgets/bar/index.ts

@@ -48,10 +48,10 @@ export default {
       max: 100,
       animationTime: 1000,
       value: 50,
-      animation: true,
+      animation: false,
       mode: 'range',
       startValue: 20,
-      startanimation: true
+      startanimation: false
       // direction: 'left'
     },
     styles: [
@@ -209,17 +209,6 @@ export default {
           }
         ]
       },
-      {
-        label: '动画时间',
-        field: 'props.animationTime',
-        valueType: 'number',
-        labelWidth: '100px',
-        componentProps: {
-          min: 0,
-          max: 100000
-        },
-        slots: { suffix: 'ms' }
-      },
       {
         label: '',
         valueType: 'group',
@@ -346,6 +335,7 @@ export default {
                   field: 'border',
                   valueType: 'border'
                 },
+
                 {
                   label: '轮廓',
                   field: 'outline',
@@ -361,6 +351,17 @@ export default {
                   field: 'shadow',
                   valueType: 'shadow'
                 },
+                {
+                  label: '动画时间',
+                  field: 'props.animationTime',
+                  valueType: 'number',
+                  labelWidth: '100px',
+                  componentProps: {
+                    min: 0,
+                    max: 100000
+                  },
+                  slots: { suffix: 'ms' }
+                },
                 {
                   label: '变换',
                   field: 'transform',

+ 1 - 1
src/renderer/src/lvgl-widgets/bezier/Config.vue

@@ -27,7 +27,7 @@
 
     <template v-else>
       <div class="segment-actions">
-        <el-button type="text" size="small" class="px-0!" @click="openBezierEditor">
+        <el-button text size="small" class="px-0!" @click="openBezierEditor">
           <LuPencilLine size="14" />
           编辑
         </el-button>

+ 6 - 6
src/renderer/src/lvgl-widgets/image-button/ImageButton.vue

@@ -46,32 +46,32 @@ const props = defineProps<{
   text?: string
   styles: any
   state?: string
-  ReleasedImage: {
+  ReleasedImage?: {
     left: string
     center: string
     right: string
   }
-  DisableImage: {
+  DisableImage?: {
     left: string
     center: string
     right: string
   }
-  PessedImage: {
+  PessedImage?: {
     left: string
     center: string
     right: string
   }
-  CheckedReleasedImage: {
+  CheckedReleasedImage?: {
     left: string
     center: string
     right: string
   }
-  CheckedPressedImage: {
+  CheckedPressedImage?: {
     left: string
     center: string
     right: string
   }
-  CheckedDisableImage: {
+  CheckedDisableImage?: {
     left: string
     center: string
     right: string

+ 99 - 50
src/renderer/src/lvgl-widgets/slider/Slider.vue

@@ -1,43 +1,40 @@
 <template>
   <div :style="styleMap?.mainStyle" class="w-full h-full box-border relative">
     <ImageBg :src="styleMap?.mainStyle?.imageSrc" :image-style="styleMap?.mainStyle?.imageStyle" />
-    <div class="absolute" :style="indicatorStyle">
-      <div class="absolute w-full h-full overflow-hidden">
-        <ImageBg
-          :src="styleMap?.indicatorStyle?.imageSrc"
-          :image-style="styleMap?.indicatorStyle?.imageStyle"
-          :style="{
-            width: width + 'px',
-            height: height + 'px'
-          }"
-        />
-      </div>
-      <!-- 左边值 -->
-      <div
-        v-if="mode === 'range'"
-        :style="{
-          ...styleMap?.knobStyle,
-          ...otherStyle.startKnobStyle
-        }"
-        class="absolute aspect-square"
-      >
-        <ImageBg
-          :src="styleMap?.knobStyle?.imageSrc"
-          :image-style="styleMap?.knobStyle?.imageStyle"
-        />
-      </div>
-      <!-- 右边值 -->
-      <div
-        :style="{
-          ...styleMap?.knobStyle,
-          ...otherStyle.endKnobStyle
-        }"
-        class="absolute aspect-square"
-      >
-        <ImageBg
-          :src="styleMap?.knobStyle?.imageSrc"
-          :image-style="styleMap?.knobStyle?.imageStyle"
-        />
+    <div class="absolute" :style="trackStyle">
+      <div class="absolute" :style="indicatorStyle">
+        <div class="absolute w-full h-full overflow-hidden">
+          <ImageBg
+            :src="styleMap?.indicatorStyle?.imageSrc"
+            :image-style="styleMap?.indicatorStyle?.imageStyle"
+            :style="indicatorImageStyle"
+          />
+        </div>
+        <!-- 左边值 -->
+        <div
+          v-if="mode === 'range'"
+          :style="otherStyle.startKnobStyle"
+          class="absolute aspect-square flex items-center justify-center"
+        >
+          <div :style="styleMap?.knobStyle" class="shrink-0">
+            <ImageBg
+              :src="styleMap?.knobStyle?.imageSrc"
+              :image-style="styleMap?.knobStyle?.imageStyle"
+            />
+          </div>
+        </div>
+        <!-- 右边值 -->
+        <div
+          :style="otherStyle.endKnobStyle"
+          class="absolute aspect-square flex items-center justify-center"
+        >
+          <div :style="styleMap?.knobStyle" class="shrink-0">
+            <ImageBg
+              :src="styleMap?.knobStyle?.imageSrc"
+              :image-style="styleMap?.knobStyle?.imageStyle"
+            />
+          </div>
+        </div>
       </div>
     </div>
   </div>
@@ -67,7 +64,6 @@ const styleMap = useWidgetStyle({
   widget: 'lv_slider',
   props
 })
-
 const isGradientBackground = (background: unknown) => {
   return typeof background === 'string' && /(?:linear|radial|conic)-gradient\(/.test(background)
 }
@@ -84,14 +80,65 @@ const getOffset = (value: string | number | undefined, total = 0) => {
   return Number(value) || 0
 }
 
+const parseCssNumber = (value: unknown) => {
+  const number = Number.parseFloat(String(value ?? 0))
+  return Number.isFinite(number) ? number : 0
+}
+
+const parsePadding = (padding: CSSProperties['padding']) => {
+  const values = String(padding ?? '0')
+    .trim()
+    .split(/\s+/)
+    .map(parseCssNumber)
+
+  const top = values[0] ?? 0
+  const right = values[1] ?? top
+  const bottom = values[2] ?? top
+  const left = values[3] ?? right
+
+  return { top, right, bottom, left }
+}
+
+const mainPadding = computed(() => parsePadding(styleMap.value?.mainStyle?.padding))
+
+const trackStyle = computed<CSSProperties>(() => {
+  const { top, right, bottom, left } = mainPadding.value
+
+  return {
+    top: `${top}px`,
+    right: `${right}px`,
+    bottom: `${bottom}px`,
+    left: `${left}px`
+  }
+})
+
+const indicatorOffset = computed(() => {
+  const width = Number(props.width || 0)
+  const height = Number(props.height || 0)
+  const { top, right, bottom, left } = mainPadding.value
+  const trackWidth = Math.max(width - left - right, 0)
+  const trackHeight = Math.max(height - top - bottom, 0)
+
+  return {
+    left: left + getOffset(otherStyle.value.barStyle.left, trackWidth),
+    top: top + getOffset(otherStyle.value.barStyle.top, trackHeight)
+  }
+})
+
+const indicatorImageStyle = computed<CSSProperties>(() => ({
+  width: `${props.width || 0}px`,
+  height: `${props.height || 0}px`,
+  left: `${-indicatorOffset.value.left}px`,
+  top: `${-indicatorOffset.value.top}px`
+}))
+
 const indicatorGradientStyle = computed<CSSProperties>(() => {
   const indicatorBackground = styleMap.value?.indicatorStyle?.background
   if (!isGradientBackground(indicatorBackground)) return {}
 
   const width = Number(props.width || 0)
   const height = Number(props.height || 0)
-  const left = getOffset(otherStyle.value.barStyle.left, width)
-  const top = getOffset(otherStyle.value.barStyle.top, height)
+  const { left, top } = indicatorOffset.value
 
   return {
     backgroundSize: `${width}px ${height}px`,
@@ -215,37 +262,39 @@ const otherStyle = computed(() => {
     direction,
     endKnobStyle: isHorizontal
       ? {
-          top: '-4px',
+          top: -mainPadding.value.top + 'px',
           bottom: 'auto',
           right: endHorizontalAnchor === 'right' ? '0' : 'auto',
           left: endHorizontalAnchor === 'left' ? '0' : 'auto',
-          height: 'calc(100% + 8px)',
+          height: height + 'px',
+          width: height + 'px',
           transform: getHorizontalKnobTransform(endHorizontalAnchor)
         }
       : {
-          left: '50%',
+          left: -mainPadding.value.left + 'px',
           right: 'auto',
           top: endVerticalAnchor === 'top' ? '0' : 'auto',
           bottom: endVerticalAnchor === 'bottom' ? '0' : 'auto',
-          width: 'calc(100% + 8px)',
-          transform: `translateX(-50%) ${getVerticalKnobTransform(endVerticalAnchor)}`
+          width: width + 'px',
+          height: width + 'px'
         },
     startKnobStyle: isHorizontal
       ? {
-          top: '-4px',
+          top: -mainPadding.value.top + 'px',
           bottom: 'auto',
           right: startHorizontalAnchor === 'right' ? '0' : 'auto',
           left: startHorizontalAnchor === 'left' ? '0' : 'auto',
-          height: 'calc(100% + 8px)',
+          height: height + 'px',
+          width: height + 'px',
           transform: getHorizontalKnobTransform(startHorizontalAnchor)
         }
       : {
-          left: '50%',
+          left: -mainPadding.value.left + 'px',
           right: 'auto',
           top: startVerticalAnchor === 'top' ? '0' : 'auto',
           bottom: startVerticalAnchor === 'bottom' ? '0' : 'auto',
-          width: 'calc(100% + 8px)',
-          transform: `translateX(-50%) ${getVerticalKnobTransform(startVerticalAnchor)}`
+          width: width + 'px',
+          height: width + 'px'
         }
   }
 })

+ 68 - 35
src/renderer/src/lvgl-widgets/slider/index.ts

@@ -52,10 +52,10 @@ export default {
       max: 100,
       animationTime: 1000,
       value: 50,
-      animation: true,
+      animation: false,
       mode: 'range',
       startValue: 20,
-      startanimation: true,
+      startanimation: false,
       direction: 'left'
     },
     styles: [
@@ -213,17 +213,6 @@ export default {
           }
         ]
       },
-      {
-        label: '动画时间',
-        field: 'props.animationTime',
-        valueType: 'number',
-        labelWidth: '100px',
-        componentProps: {
-          min: 0,
-          max: 100000
-        },
-        slots: { suffix: 'ms' }
-      },
       {
         label: '',
         valueType: 'group',
@@ -365,34 +354,78 @@ export default {
                   field: 'shadow',
                   valueType: 'shadow'
                 },
+                {
+                  label: '动画时间',
+                  field: 'props.animationTime',
+                  valueType: 'number',
+                  labelWidth: '100px',
+                  componentProps: {
+                    min: 0,
+                    max: 100000
+                  },
+                  slots: { suffix: 'ms' }
+                },
                 {
                   label: '变换',
                   field: 'transform',
                   valueType: 'transform'
                 }
               ]
-            : [
-                {
-                  label: '背景',
-                  field: 'background',
-                  valueType: 'background'
-                },
-                {
-                  label: '边框',
-                  field: 'border',
-                  valueType: 'border'
-                },
-                {
-                  label: '轮廓',
-                  field: 'outline',
-                  valueType: 'outline'
-                },
-                {
-                  label: '阴影',
-                  field: 'shadow',
-                  valueType: 'shadow'
-                }
-              ]
+            : part?.name === 'knob'
+              ? [
+                  {
+                    label: '背景',
+                    field: 'background',
+                    valueType: 'background'
+                  },
+                  {
+                    label: '边框',
+                    field: 'border',
+                    valueType: 'border'
+                  },
+                  {
+                    label: '轮廓',
+                    field: 'outline',
+                    valueType: 'outline'
+                  },
+                  {
+                    label: '内边距',
+                    field: 'padding',
+                    valueType: 'padding'
+                  },
+                  {
+                    label: '阴影',
+                    field: 'shadow',
+                    valueType: 'shadow'
+                  },
+                  {
+                    label: '变换',
+                    field: 'transform',
+                    valueType: 'transform'
+                  }
+                ]
+              : [
+                  {
+                    label: '背景',
+                    field: 'background',
+                    valueType: 'background'
+                  },
+                  {
+                    label: '边框',
+                    field: 'border',
+                    valueType: 'border'
+                  },
+                  {
+                    label: '轮廓',
+                    field: 'outline',
+                    valueType: 'outline'
+                  },
+                  {
+                    label: '阴影',
+                    field: 'shadow',
+                    valueType: 'shadow'
+                  }
+                ]
         }
       }
     ]

+ 16 - 0
src/renderer/src/lvgl-widgets/slider/style.json

@@ -104,12 +104,28 @@
           "width": 0,
           "pad": 0
         },
+        "padding": {
+          "left": 5,
+          "right": 5,
+          "top": 5,
+          "bottom": 5
+        },
         "shadow": {
           "color": "#2092f5ff",
           "offsetX": 0,
           "offsetY": 0,
           "spread": 0,
           "width": 0
+        },
+        "transform": {
+          "width": 0,
+          "height": 0,
+          "translateX": 0,
+          "translateY": 0,
+          "originX": 0,
+          "originY": 0,
+          "rotate": 0,
+          "scale": 256
         }
       },
       "state": []

+ 1 - 0
src/renderer/src/lvgl-widgets/tabview/Config.vue

@@ -105,6 +105,7 @@ const handleAddRow = () => {
   children.value?.push({
     name: 'Tab',
     type: 'tab',
+    text: '',
     children: []
   })
 }

+ 1 - 1
src/renderer/src/views/designer/config/AnimationConfig.vue

@@ -3,7 +3,7 @@
     <el-form label-position="top">
       <ViewTitle title="设置动画">
         <template #right>
-          <el-button type="text" @click="addAnimation"
+          <el-button text @click="addAnimation"
             ><el-icon class="cursor-pointer" @click.stop="addAnimation"> <Plus /> </el-icon
           ></el-button>
         </template>

+ 2 - 2
src/renderer/src/views/designer/config/VariableConfig.vue

@@ -2,7 +2,7 @@
   <el-scrollbar height="calc(100vh - 130px)" class="config">
     <ViewTitle :title="t('pageVariables')">
       <template #right>
-        <el-button type="text" @click="addPageVariables"
+        <el-button text @click="addPageVariables"
           ><el-icon class="cursor-pointer"> <Plus /> </el-icon
         ></el-button>
       </template>
@@ -52,7 +52,7 @@
 
     <ViewTitle :title="t('globalVariables')">
       <template #right>
-        <el-button type="text" @click="addVariableGroup"
+        <el-button text @click="addVariableGroup"
           ><el-icon class="cursor-pointer"> <Plus /> </el-icon
         ></el-button>
       </template>

+ 1 - 1
src/renderer/src/views/designer/config/property/components/BezierConfig.vue

@@ -168,7 +168,7 @@
       </el-form-item>
       <template v-else>
         <div class="segment-actions">
-          <el-button type="text" size="small" class="px-0!" @click="openBezierEditor">
+          <el-button text size="small" class="px-0!" @click="openBezierEditor">
             <LuPencilLine size="14" />
             编辑
           </el-button>

+ 1 - 1
src/renderer/src/views/designer/sidebar/Method.vue

@@ -2,7 +2,7 @@
   <div style="height: calc(100vh - 150px)" class="w-full flex flex-col">
     <ViewTitle title="函数代码">
       <template #right>
-        <el-button type="text" @click="handleAdd"><LuPlus size="14px" /></el-button>
+        <el-button text @click="handleAdd"><LuPlus size="14px" /></el-button>
       </template>
     </ViewTitle>
     <div class="flex-1 min-h-0">

+ 4 - 4
src/renderer/src/views/designer/sidebar/Resource.vue

@@ -15,7 +15,7 @@
             </span>
           </el-tooltip>
           <el-tooltip content="添加">
-            <el-button type="text" class="mr-12px" @click.capture.stop="handleAddImage">
+            <el-button text class="mr-12px" @click.capture.stop="handleAddImage">
               <LuPlus size="14px" />
             </el-button>
           </el-tooltip>
@@ -46,7 +46,7 @@
     <SplitterCollapseItem title="字体">
       <template #header-right>
         <el-tooltip content="添加">
-          <el-button type="text" class="mr-12px" @click.capture.stop="handleAddFont">
+          <el-button text class="mr-12px" @click.capture.stop="handleAddFont">
             <LuPlus size="14px" />
           </el-button>
         </el-tooltip>
@@ -75,7 +75,7 @@
     <SplitterCollapseItem title="贝塞尔动画">
       <template #header-right>
         <el-tooltip content="添加">
-          <el-button type="text" class="mr-12px" @click.capture.stop="handleAddBezier">
+          <el-button text class="mr-12px" @click.capture.stop="handleAddBezier">
             <LuPlus size="14px" />
           </el-button>
         </el-tooltip>
@@ -106,7 +106,7 @@
     <SplitterCollapseItem title="其他资源">
       <template #header-right>
         <el-tooltip content="添加">
-          <el-button type="text" class="mr-12px" @click.capture.stop="handleAddOther">
+          <el-button text class="mr-12px" @click.capture.stop="handleAddOther">
             <LuPlus size="14px" />
           </el-button>
         </el-tooltip>

+ 1 - 1
src/renderer/src/views/designer/sidebar/components/EditFontModal.vue

@@ -57,7 +57,7 @@
             :options="projectStore.project.bins"
             :props="{ label: 'name', value: 'id' }"
           />
-          <el-button type="text" :disabled="!formData.bin" @click="editBin">
+          <el-button text :disabled="!formData.bin" @click="editBin">
             <LuPencilLine size="18" />
           </el-button>
         </div>

+ 1 - 1
src/renderer/src/views/designer/sidebar/components/EditImageModal.vue

@@ -100,7 +100,7 @@
                 :options="projectStore.project.bins"
                 :props="{ label: 'name', value: 'id' }"
               />
-              <el-button type="text" :disabled="!formData.bin" @click="editBin">
+              <el-button text :disabled="!formData.bin" @click="editBin">
                 <LuPencilLine size="18" />
               </el-button>
             </div> </el-form-item

+ 3 - 3
src/renderer/src/views/designer/sidebar/components/LanguageModal.vue

@@ -18,19 +18,19 @@
         <el-select v-model="currentLanguage" :options="languagesMenu" />
       </div>
       <div class="flex items-center gap-8px">
-        <el-button type="text" @click="handleCollapseAll">
+        <el-button text @click="handleCollapseAll">
           <el-icon class="cursor-pointer">
             <ArrowRight />
           </el-icon>
           <span>一键折叠</span>
         </el-button>
-        <el-button type="text" @click="handleExpandAll">
+        <el-button text @click="handleExpandAll">
           <el-icon class="cursor-pointer">
             <ArrowDown />
           </el-icon>
           <span>一键展开</span>
         </el-button>
-        <el-button type="text" @click="handleAdd">
+        <el-button text @click="handleAdd">
           <el-icon class="cursor-pointer">
             <Plus />
           </el-icon>

+ 2 - 1
src/renderer/src/views/designer/workspace/stage/Moveable.vue

@@ -401,8 +401,9 @@ const onRotateEnd = (e) => {
     return
   }
   if (e.lastEvent && id && projectStore.activeWidgetMap[id]) {
+    const rotation = Math.round(e.lastEvent.rotate) * 10
     // 设置位置
-    projectStore.activeWidgetMap[id].props.rotation = Math.round(e.lastEvent.rotate)
+    projectStore.activeWidgetMap[id].props.rotation = rotation % 3600
   }
   onTransformEnd()
 }

+ 3 - 3
src/renderer/src/views/designer/workspace/stage/Node.vue

@@ -134,7 +134,8 @@ const getStyle = computed((): CSSProperties => {
 
   let rotate = ''
   if (resolvedProps?.rotation) {
-    rotate = `rotate(${resolvedProps.rotation}deg)`
+    // 角度值按照10倍换算
+    rotate = `rotate(${resolvedProps.rotation / 10}deg)`
     if (resolvedProps?.pivot) {
       other.transformOrigin = `${resolvedProps.pivot.x}px ${resolvedProps.pivot.y}px`
     }
@@ -249,8 +250,7 @@ const childStyle = computed((): CSSProperties => {
 
 const hasLockedWidgetTree = (widget?: BaseWidget | Page): boolean => {
   return (
-    !!widget &&
-    (!!widget.locked || !!widget.children?.some((child) => hasLockedWidgetTree(child)))
+    !!widget && (!!widget.locked || !!widget.children?.some((child) => hasLockedWidgetTree(child)))
   )
 }