Explorar el Código

fix: 修改部分样式及背景图问题

jiaxing.liao hace 1 mes
padre
commit
507c4eeb27

+ 36 - 4
src/renderer/src/lvgl-widgets/button-matrix/ButtonMatrix.vue

@@ -1,5 +1,13 @@
 <template>
-  <div :style="styleMap?.mainStyle" class="w-full h-full box-border flex flex-col overflow-hidden">
+  <div
+    :style="styleMap?.mainStyle"
+    class="w-full h-full box-border flex flex-col overflow-hidden relative"
+  >
+    <ImageBg
+      v-if="styleMap?.mainStyle?.imageSrc"
+      :src="styleMap?.mainStyle?.imageSrc"
+      :image-color-style="styleMap?.mainStyle?.imageStyle"
+    />
     <div
       v-for="(row, index) in group || []"
       :key="index"
@@ -7,7 +15,7 @@
       :style="{ columnGap: styleMap?.mainStyle?.columnGap }"
     >
       <div
-        class="h-full flex items-center justify-center overflow-hidden whitespace-pre!"
+        class="h-full flex items-center justify-center overflow-hidden whitespace-pre! relative"
         v-for="(item, index) in row || []"
         :key="`${index}-${index}`"
         :style="{
@@ -18,7 +26,12 @@
           )
         }"
       >
-        {{ item.text }}
+        <ImageBg
+          v-if="getBtnStyle(item)?.imageSrc"
+          :src="getBtnStyle(item)?.imageSrc"
+          :image-color-style="getBtnStyle(item)?.imageStyle"
+        />
+        <span class="z-2">{{ item.text }}</span>
       </div>
     </div>
   </div>
@@ -28,6 +41,9 @@
 import { useWidgetStyle, getStyle } from '../hooks/useWidgetStyle'
 import { ButtonItem } from './data'
 import { isEmpty, assign } from 'lodash-es'
+import { useProjectStore } from '@/store/modules/project'
+
+import ImageBg from '../ImageBg.vue'
 
 const props = defineProps<{
   width: number
@@ -43,14 +59,30 @@ const styleMap = useWidgetStyle({
   props
 })
 
+const projectStore = useProjectStore()
+
 /**
  * 获取自定义样式
  */
 const getBtnStyle = (btnItem: ButtonItem) => {
   const style = btnItem.style.find((item) => item.part.state === 'default') || {}
-  const styleMap = {}
+  const styleMap: Record<string, any> = {}
   Object.keys(style).forEach((key) => {
     assign(styleMap, getStyle(key, style?.[key]))
+
+    if (key === 'background' && style?.[key]?.image?.imgId) {
+      const basePath = projectStore?.projectPath
+      const imagePath = projectStore?.project?.resources.images.find(
+        (item) => item.id === style?.[key]?.image?.imgId
+      )?.path
+      if (basePath && imagePath) {
+        styleMap.imageSrc = `local:///${(basePath + imagePath).replaceAll('\\', '/')}`
+        styleMap.imageStyle = {
+          backgroundColor: style?.[key]?.image?.color,
+          opacity: (style?.[key]?.image?.alpha || 255) / 255
+        }
+      }
+    }
   })
 
   return isEmpty(styleMap) ? null : styleMap

+ 2 - 1
src/renderer/src/lvgl-widgets/button-matrix/index.tsx

@@ -160,7 +160,8 @@ export default {
           color: '#2092f5ff',
           image: {
             imgId: '',
-            color: '#00000000'
+            color: '#00000000',
+            alpha: 255
           }
         },
         text: {

+ 2 - 1
src/renderer/src/lvgl-widgets/button-matrix/style.json

@@ -52,7 +52,8 @@
           "color": "#2092f5ff",
           "image": {
             "imgId": "",
-            "color": "#00000000"
+            "color": "#00000000",
+            "alpha": 255
           }
         },
         "text": {

+ 7 - 1
src/renderer/src/lvgl-widgets/checkbox/Checkbox.vue

@@ -1,5 +1,10 @@
 <template>
-  <div :style="styleMap?.mainStyle" class="w-full h-full box-border flex items-center">
+  <div :style="styleMap?.mainStyle" class="w-full h-full box-border flex items-center relative">
+    <ImageBg
+      v-if="styleMap?.mainStyle?.imageSrc"
+      :src="styleMap?.mainStyle?.imageSrc"
+      :imageStyle="styleMap?.mainStyle?.imageStyle"
+    />
     <div
       :style="{ ...styleMap?.indicatorStyle, backgroundColor: 'transparent' }"
       class="h-16px w-16px shrink-0 overflow-hidden relative"
@@ -18,6 +23,7 @@
 <script setup lang="ts">
 import { useWidgetStyle } from '../hooks/useWidgetStyle'
 import { BsCheckSquareFill } from 'vue-icons-plus/bs'
+import ImageBg from '../ImageBg.vue'
 
 const props = defineProps<{
   width?: number

+ 8 - 1
src/renderer/src/lvgl-widgets/container/Container.vue

@@ -1,9 +1,16 @@
 <template>
-  <div :style="styleMap?.mainStyle" class="w-full h-full box-border"></div>
+  <div :style="styleMap?.mainStyle" class="w-full h-full box-border relative">
+    <ImageBg
+      v-if="styleMap?.mainStyle?.imageSrc"
+      :src="styleMap?.mainStyle?.imageSrc"
+      :imageStyle="styleMap?.mainStyle?.imageStyle"
+    />
+  </div>
 </template>
 
 <script setup lang="ts">
 import { useWidgetStyle } from '../hooks/useWidgetStyle'
+import ImageBg from '../ImageBg.vue'
 
 const props = defineProps<{
   width: number

+ 17 - 1
src/renderer/src/lvgl-widgets/dropdown/Dropdown.vue

@@ -1,5 +1,10 @@
 <template>
   <div :style="styleMap?.mainStyle" class="w-full h-full box-border relative">
+    <ImageBg
+      v-if="styleMap?.mainStyle?.imageSrc"
+      :src="styleMap?.mainStyle?.imageSrc"
+      :imageStyle="styleMap?.mainStyle?.imageStyle"
+    />
     <div class="relative w-full overflow-hidden" :class="direction === 'left' ? 'text-right' : ''">
       {{ options?.[0] }}
       <div
@@ -19,13 +24,23 @@
       style="padding: 0; width: 100%; height: auto"
       class="absolute bg-white max-h-[120px] overflow-y-auto dropdown-pop"
     >
+      <ImageBg
+        v-if="styleMap?.listStyle?.imageSrc"
+        :src="styleMap?.listStyle?.imageSrc"
+        :imageStyle="styleMap?.listStyle?.imageStyle"
+      />
       <div
         class="truncate h-24px leading-24px px-10px box-border"
         v-for="(item, index) in options"
         :key="item"
         :style="index === 0 ? styleMap?.listSelectedStyle : ''"
       >
-        {{ item }}
+        <ImageBg
+          v-if="styleMap?.listSelectedStyle?.imageSrc && index === 0"
+          :src="styleMap?.listSelectedStyle?.imageSrc"
+          :imageStyle="styleMap?.listSelectedStyle?.imageStyle"
+        />
+        <span class="z-1">{{ item }}</span>
       </div>
       <div class="absolute" :style="{ ...(styleMap?.scrollbarStyle || {}), ...scrollbarStyle }" />
     </div>
@@ -41,6 +56,7 @@ import {
   EpArrowRightBold
 } from 'vue-icons-plus/ep'
 import { useWidgetStyle } from '../hooks/useWidgetStyle'
+import ImageBg from '../ImageBg.vue'
 
 const props = defineProps<{
   width: number

+ 12 - 12
src/renderer/src/lvgl-widgets/switch/Switch.vue

@@ -1,17 +1,10 @@
 <template>
-  <div :style="getStyle" class="w-full h-full">
-    <img
+  <div :style="getStyle" class="w-full h-full relative">
+    <ImageBg
       v-if="getStyle?.imageSrc"
-      width="100%"
-      height="100%"
-      class="absolute z-0"
-      :src="getStyle.imageSrc"
+      :src="getStyle?.imageSrc"
+      :imageStyle="getStyle?.imageStyle"
     />
-    <div
-      v-if="getStyle?.imageSrc"
-      class="absolute w-full h-full z-1"
-      :style="getStyle?.imageStyle"
-    ></div>
     <div
       class="w-full h-full p-4px flex box-border"
       :style="{ 'justify-content': part !== 'indicator' ? 'start' : 'end' }"
@@ -20,7 +13,13 @@
         class="absolute inline-block flex-1 aspect-square box-border"
         :style="styleMap.knobStyle"
         style="height: calc(100% - 8px)"
-      ></span>
+      >
+        <ImageBg
+          v-if="styleMap?.knobStyle?.imageSrc"
+          :src="styleMap?.knobStyle?.imageSrc"
+          :imageStyle="styleMap?.knobStyle?.imageStyle"
+        />
+      </span>
     </div>
   </div>
 </template>
@@ -28,6 +27,7 @@
 <script setup lang="ts">
 import { computed } from 'vue'
 import { useWidgetStyle } from '../hooks/useWidgetStyle'
+import ImageBg from '../ImageBg.vue'
 
 const props = defineProps<{
   width: number

+ 8 - 1
src/renderer/src/lvgl-widgets/tabview/Tabview.vue

@@ -1,5 +1,10 @@
 <template>
-  <div :style="mainStyle" class="w-full h-full flex overflow-hidden">
+  <div :style="mainStyle" class="w-full h-full flex overflow-hidden relative">
+    <ImageBg
+      v-if="styleMap?.mainStyle?.imageSrc"
+      :src="styleMap?.mainStyle?.imageSrc"
+      :imageStyle="styleMap?.mainStyle?.imageStyle"
+    />
     <div class="flex box-border" :style="tabMainStyle">
       <div
         class="flex-1 shrink-0 grid place-items-center box-border overflow-hidden whitespace-pre!"
@@ -24,6 +29,8 @@ import { useWidgetStyle, getStyle } from '../hooks/useWidgetStyle'
 import { useProjectStore } from '@/store/modules/project'
 import defaultStyle from './style.json'
 
+import ImageBg from '../ImageBg.vue'
+
 const props = defineProps<{
   width: number
   height: number

+ 1 - 4
src/renderer/src/lvgl-widgets/tabview/index.tsx

@@ -302,10 +302,7 @@ export default {
                 {
                   label: '背景',
                   field: 'background',
-                  valueType: 'background',
-                  componentProps: {
-                    onlyColor: true
-                  }
+                  valueType: 'background'
                 },
                 {
                   label: '字体',

+ 6 - 0
src/renderer/src/lvgl-widgets/textarea/Textarea.vue

@@ -5,6 +5,11 @@
     class="w-full h-full flex overflow-hidden box-border relative"
     :class="nowrap ? 'whitespace-nowrap' : 'break-all'"
   >
+    <ImageBg
+      v-if="styleMap?.mainStyle?.imageSrc"
+      :src="styleMap?.mainStyle?.imageSrc"
+      :imageStyle="styleMap?.mainStyle?.imageStyle"
+    />
     <span
       ref="txtRef"
       class="w-full overflow-hidden whitespace-pre!"
@@ -31,6 +36,7 @@
 <script setup lang="ts">
 import { computed, ref, watch, nextTick } from 'vue'
 import { useWidgetStyle } from '../hooks/useWidgetStyle'
+import ImageBg from '../ImageBg.vue'
 
 const props = defineProps<{
   width: number

+ 6 - 1
src/renderer/src/lvgl-widgets/textarea/index.ts

@@ -46,7 +46,12 @@ export default {
           state: 'default'
         },
         background: {
-          color: '#ffffffff'
+          color: '#ffffffff',
+          image: {
+            imgId: '',
+            color: '#ffffff00',
+            alpha: 255
+          }
         },
         text: {
           color: '#000000ff',

+ 6 - 1
src/renderer/src/lvgl-widgets/textarea/style.json

@@ -6,7 +6,12 @@
       "partName": "main",
       "defaultStyle": {
         "background": {
-          "color": "#ffffffff"
+          "color": "#ffffffff",
+          "image": {
+            "imgId": "",
+            "color": "#ffffff00",
+            "alpha": 255
+          }
         },
         "text": {
           "color": "#000000ff",

+ 6 - 6
src/renderer/src/lvgl-widgets/tileview/Tileview.vue

@@ -1,5 +1,10 @@
 <template>
   <div :style="styleMap?.mainStyle" class="w-full h-full relative overflow-hidden">
+    <ImageBg
+      v-if="styleMap?.mainStyle?.imageSrc"
+      :src="styleMap?.mainStyle?.imageSrc"
+      :imageStyle="styleMap?.mainStyle?.imageStyle"
+    />
     <div
       class="h-scrollbar absolute bottom-6px h-4px"
       :style="{ ...(styleMap?.scrollbarStyle || {}), ...barStyle.hStyle }"
@@ -14,6 +19,7 @@
 <script setup lang="ts">
 import { computed } from 'vue'
 import { useWidgetStyle } from '../hooks/useWidgetStyle'
+import ImageBg from '../ImageBg.vue'
 
 const props = defineProps<{
   width: number
@@ -24,12 +30,6 @@ const props = defineProps<{
   scrollbar: string
   children?: any[]
   activeIndex: number
-  openRotate?: boolean
-  rotate?: {
-    x: number
-    y: number
-    angle: number
-  }
 }>()
 
 const styleMap = useWidgetStyle({

+ 4 - 3
src/renderer/src/views/designer/config/property/CusFormItem.vue

@@ -213,6 +213,7 @@
     :key="index"
     :schema="item"
     :form-data="formData"
+    @change-state-style="(field, type) => $emit('changeStateStyle', field, type)"
   />
 </template>
 
@@ -263,9 +264,9 @@ const value = computed({
     return schema.field ? get(formData, schema.field) : formData
   },
   set(val) {
-    const { schema } = props
-    if (schema.field && props.formData) {
-      set(props.formData, schema.field, val)
+    const { schema, formData } = props
+    if (schema.field && formData) {
+      set(formData, schema.field, val)
     }
     // 触发change事件
     if (schema?.componentProps?.onValueChange) {

+ 6 - 3
src/renderer/src/views/designer/config/property/index.vue

@@ -80,7 +80,10 @@
               v-for="(item, index) in formConfig.styles || []"
               :key="item.valueType + '_' + index"
               :schema="item"
-              :formData="styleFormData"
+              :formData="{
+                part,
+                ...styleFormData
+              }"
               :widgetData="projectStore.activeWidget!"
               @change-state-style="onChangeStateStyle"
             />
@@ -183,10 +186,10 @@ const getWidgetDefaultStyle = () => {
 
   const stateStyle = state?.find((item) => item.state === part.value.state)?.style || {}
 
-  return {
+  return klona({
     defaultStyle,
     stateStyle
-  }
+  })
 }
 
 /**