Sfoglia il codice sorgente

fix: 修改屏幕重置等问题

jiaxing.liao 2 mesi fa
parent
commit
2b87c94480

+ 18 - 1
src/renderer/src/lvgl-widgets/hooks/useWidgetStyle.ts

@@ -47,13 +47,30 @@ export const getStyle = (key, value) => {
       style.fontSize = `${value?.size}px`
       style.fontFamily = value?.family
       style.textAlign = value?.align
-      style.fontWeight = value?.weight === 'bold' ? 'bold' : 'normal'
+
       style.fontStyle = value?.italic ? 'italic' : 'normal'
       style.textDecoration = value?.strike
         ? 'line-through'
         : value?.underline
           ? 'underline'
           : 'none'
+      // 字形
+      switch (value?.weight) {
+        case 'normal':
+          style.fontWeight = 'normal'
+          break
+        case 'bold':
+          style.fontWeight = 'bold'
+          break
+        case 'italic':
+          style.fontWeight = 'normal'
+          style.fontStyle = 'italic'
+          break
+        case 'bold italic':
+          style.fontWeight = 'bold'
+          style.fontStyle = 'italic'
+          break
+      }
       break
     }
     // 边框样式

+ 2 - 2
src/renderer/src/lvgl-widgets/textarea/style.json

@@ -19,7 +19,7 @@
               "color": "#000000ff",
               "family": "xx",
               "size": 16,
-              "weight": 500,
+              "weight": "normal",
               "align": "center"
             },
             "spacer": {
@@ -60,7 +60,7 @@
               "color": "#000000ff",
               "family": "xx",
               "size": 16,
-              "weight": 500,
+              "weight": "normal",
               "align": "center"
             },
             "spacer": {

+ 5 - 0
src/renderer/src/store/modules/project.ts

@@ -61,6 +61,8 @@ export const useProjectStore = defineStore('project', () => {
   const projectPath = ref<string>()
   // 图片压缩格式
   const imageCompressFormat = ref<string[]>([])
+  // 当前最大化屏幕
+  const currentMaxScreen = ref<string | null>(null)
 
   // 激活页面ID
   const activePageId = ref<string>()
@@ -116,6 +118,7 @@ export const useProjectStore = defineStore('project', () => {
     }
     // 2、构建屏幕信息
     activePageId.value = ''
+    currentMaxScreen.value = null
     openPages.value = []
     meta.screens.forEach((screen, index) => {
       const newScreen = createScreen(screen)
@@ -193,6 +196,7 @@ export const useProjectStore = defineStore('project', () => {
   const loadProject = (newProject: IProject, path: string, style: any) => {
     project.value = newProject
     globalStyle.value = style
+    currentMaxScreen.value = null
     // 修改项目路径
     if (project.value.meta.path !== path) {
       project.value.meta.path = path
@@ -301,6 +305,7 @@ export const useProjectStore = defineStore('project', () => {
     setSelectWidgets,
     activeWidgetMap,
     globalStyle,
+    currentMaxScreen,
 
     // 历史记录
     history,

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

@@ -1,5 +1,5 @@
 <template>
-  <el-scrollbar :height="'calc(100vh - 198px)'" class="config">
+  <el-scrollbar height="calc(100vh - 130px)" class="config">
     <el-form label-position="top">
       <ViewTitle title="设置动画">
         <template #right>

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

@@ -1,5 +1,5 @@
 <template>
-  <el-scrollbar :height="'calc(100vh - 198px)'" class="config">
+  <el-scrollbar height="calc(100vh - 130px)" class="config">
     <ViewTitle title="设置语言">
       <template #right>
         <el-button type="text" @click="handleAdd"

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

@@ -1,5 +1,5 @@
 <template>
-  <el-scrollbar :height="'calc(100vh - 185px)'">
+  <el-scrollbar height="calc(100vh - 130px)">
     <el-form label-position="top" class="h-full">
       <SplitterCollapse>
         <SplitterCollapseItem title="组件属性" class="flex-none">

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

@@ -1,5 +1,5 @@
 <template>
-  <el-scrollbar :height="'calc(100vh - 198px)'" class="config">
+  <el-scrollbar height="calc(100vh - 130px)" class="config">
     <ViewTitle title="设置变量">
       <template #right>
         <el-button type="text" @click="addVariableGroup"

+ 7 - 7
src/renderer/src/views/designer/config/property/components/StyleFont.vue

@@ -9,30 +9,30 @@
       <span class="text-text-active">{{ modelValue?.color }}</span>
     </el-form-item>
     <el-form-item label="字体" label-position="left" label-width="60px">
-      <el-select-v2 v-model="family" placeholder="请选择" :options="fontOptions" />
+      <el-select-v2 v-model="family" :options="fontOptions" />
     </el-form-item>
     <el-form-item label="字体大小" label-position="left" label-width="60px">
       <el-input-number
         v-model="size"
         controls-position="right"
-        placeholder="请输入"
         style="width: 100%"
         :min="1"
         :max="1000"
       />
     </el-form-item>
-    <el-form-item label="字" label-position="left" label-width="60px">
+    <el-form-item label="字" label-position="left" label-width="60px">
       <el-select-v2
         v-model="weight"
-        placeholder="请选择"
         :options="[
-          { label: '正常', value: 'normal' },
-          { label: '加粗', value: 'bold' }
+          { label: '常规', value: 'normal' },
+          { label: '斜体', value: 'italic' },
+          { label: '粗体', value: 'bold' },
+          { label: '粗斜体', value: 'bold italic' }
         ]"
       />
     </el-form-item>
     <el-form-item v-if="!hideAlign" label="对齐方式" label-position="left" label-width="60px">
-      <el-select-v2 v-model="align" placeholder="请选择" :options="alignOptions" />
+      <el-select-v2 v-model="align" :options="alignOptions" />
     </el-form-item>
   </div>
 </template>

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

@@ -1,5 +1,5 @@
 <template>
-  <el-scrollbar ref="scrollbarRef" height="calc(100vh - 198px)">
+  <el-scrollbar ref="scrollbarRef" height="calc(100vh - 130px)">
     <!-- 基础属性 -->
     <el-form
       ref="formRef"

+ 2 - 2
src/renderer/src/views/designer/index.vue

@@ -19,7 +19,7 @@
           </SplitterPanel>
         </SplitterGroup>
       </div>
-      <Info></Info>
+      <!-- <Info></Info> -->
     </div>
   </div>
   <ProjectModal ref="projectModel" />
@@ -31,7 +31,7 @@ import Tools from './tools/index.vue'
 import Sidebar from './sidebar/index.vue'
 import Workspace from './workspace/index.vue'
 import Config from './config/index.vue'
-import Info from './info/index.vue'
+// import Info from './info/index.vue'
 import ProjectModal from './modals/projectModal/index.vue'
 import { ref, provide } from 'vue'
 

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

@@ -4,6 +4,7 @@
     :class="{
       'selected-tree-node': projectStore.activePageId === data.id
     }"
+    @dblclick="handleSetMaxScreen"
   >
     <template v-if="!edit">
       <div class="flex-1 flex items-center gap-8px">
@@ -75,7 +76,7 @@ import { createPage } from '@/model'
 import { Page } from '@/types/page'
 import { useActionStore } from '@/store/modules/action'
 
-defineProps<{
+const props = defineProps<{
   node: RenderContentContext['node']
   data: any
 }>()
@@ -107,6 +108,17 @@ const addPage = (screen: Screen) => {
 const deletePage = (page: Page) => {
   actionStore.onDeletePage(page.id)
 }
+
+// 双击最大化当前屏幕
+const handleSetMaxScreen = () => {
+  const { data, node } = props
+  if (data.type === 'screen') {
+    projectStore.currentMaxScreen = data.id
+  } else {
+    projectStore.currentMaxScreen = node?.parent?.data.id
+    projectStore.activePageId = data.id
+  }
+}
 </script>
 
 <style scoped></style>

+ 3 - 2
src/renderer/src/views/designer/tools/Operate.vue

@@ -23,7 +23,8 @@ import {
   LuArrowUpToLine,
   LuArrowDownToLine,
   LuAlignHorizontalSpaceAround,
-  LuAlignVerticalSpaceAround
+  LuAlignVerticalSpaceAround,
+  LuArrowDown
 } from 'vue-icons-plus/lu'
 import MenuItem from './components/MenuItem.vue'
 import { useProjectStore } from '@/store/modules/project'
@@ -153,7 +154,7 @@ const projectMenu = computed((): MenuItemType[] => {
     {
       key: 'down',
       label: '下移一层',
-      img: LuLayoutGrid,
+      img: LuArrowDown,
       disabled: disabledLevel,
       onClick: () => actionStore.onLevel('down')
     },

+ 3 - 0
src/renderer/src/views/designer/tools/index.vue

@@ -39,4 +39,7 @@ const activeMenu = ref('project')
     height: 32px;
   }
 }
+:deep(.el-tabs__content) {
+  padding: 3px 15px;
+}
 </style>

+ 62 - 5
src/renderer/src/views/designer/workspace/index.vue

@@ -10,10 +10,11 @@
         >
           <el-tab-pane label="界面设计" name="design" :closable="false">
             <SplitterGroup :direction="appStore.screenLayout">
-              <SplitterPanel>
+              <SplitterPanel ref="screen1Ref" collapsible>
                 <Stage
-                  key="1"
+                  ref="stage1Ref"
                   v-if="projectStore.project?.screens[0]"
+                  :key="projectStore.project.screens[0].id"
                   :screen="projectStore.project?.screens[0]"
                   :page="projectStore.openPages[0]"
                 />
@@ -23,10 +24,15 @@
                 :class="appStore.screenLayout === 'vertical' ? 'h-2px' : 'w-2px'"
                 v-if="projectStore.project?.meta.screenType === 'dual'"
               />
-              <SplitterPanel v-if="projectStore.project?.meta.screenType === 'dual'">
+              <SplitterPanel
+                ref="screen2Ref"
+                v-if="projectStore.project?.meta.screenType === 'dual'"
+                collapsible
+              >
                 <Stage
-                  key="2"
+                  ref="stage2Ref"
                   :screen="projectStore.project?.screens[1]"
+                  :key="projectStore.project.screens[1].id"
                   :page="projectStore.openPages[1]"
                 />
               </SplitterPanel>
@@ -58,7 +64,7 @@
 <script setup lang="ts">
 import type { TabPaneName } from 'element-plus'
 
-import { ref, onMounted, shallowRef } from 'vue'
+import { ref, onMounted, shallowRef, watch } from 'vue'
 import { SplitterGroup, SplitterPanel, SplitterResizeHandle } from 'reka-ui'
 import { useProjectStore } from '@/store/modules/project'
 import { useAppStore } from '@/store/modules/app'
@@ -75,6 +81,12 @@ type TabItem = {
 
 const projectStore = useProjectStore()
 const appStore = useAppStore()
+// panel ref
+const screen1Ref = ref<InstanceType<typeof SplitterPanel>>()
+const screen2Ref = ref<InstanceType<typeof SplitterPanel>>()
+// stage
+const stage1Ref = ref<InstanceType<typeof Stage>>()
+const stage2Ref = ref<InstanceType<typeof Stage>>()
 
 const content = ref('')
 const activeTab = ref<TabPaneName>('design')
@@ -107,6 +119,51 @@ const handleTabRemove = (tabName: TabPaneName) => {
     activeTab.value = tabPaneList.value.at(-1)?.name || 'design'
   }
 }
+
+/**
+ * 监听当前最大化屏幕
+ */
+watch(
+  () => projectStore.currentMaxScreen,
+  (id) => {
+    if (projectStore.project?.meta.screenType === 'dual' && id) {
+      if (id === projectStore.project?.screens[0].id) {
+        // 屏幕1最大化
+        screen2Ref.value?.resize(0)
+        setTimeout(() => {
+          stage1Ref.value?.handleCenter()
+        }, 0)
+      } else {
+        // 屏幕2最大化
+        screen1Ref.value?.resize(0)
+        setTimeout(() => {
+          stage2Ref.value?.handleCenter()
+        }, 0)
+      }
+    }
+  }
+)
+
+/**
+ * 屏幕布局切换
+ * 修改屏幕大小
+ * 重置页面位置大小
+ */
+watch(
+  () => appStore.screenLayout,
+  () => {
+    if (projectStore.project?.meta.screenType === 'dual') {
+      screen1Ref.value?.expand()
+      screen2Ref.value?.expand()
+      screen1Ref.value?.resize(50)
+      screen2Ref.value?.resize(50)
+      setTimeout(() => {
+        stage1Ref.value?.handleCenter()
+        stage2Ref.value?.handleCenter()
+      }, 0)
+    }
+  }
+)
 </script>
 
 <style scoped>

+ 8 - 15
src/renderer/src/views/designer/workspace/stage/DesignerCanvas.vue

@@ -1,7 +1,9 @@
 <template>
   <div class="stage-wrapper" ref="stageWrapperRef" :style="getWrapperStyle">
     <div class="stage" ref="stageRef" :style="getStyles.stageStyle">
-      <div ref="tipRef" class="tip-txt" :style="getStyles.tipStyle">{{ page?.name }}</div>
+      <div ref="tipRef" class="tip-txt" :style="getStyles.tipStyle">
+        {{ screen?.name }}:{{ page?.name }}
+      </div>
       <!-- 格子背景 -->
       <div class="absolute transparent-bg" :style="getStyles.transpartBg"></div>
       <!-- 画布区域 -->
@@ -36,9 +38,10 @@
 import type { Ref } from 'vue'
 import type { StageState } from './type'
 import type { Page } from '@/types/page'
+import type { Screen } from '@/types/screen'
 
-import { ref, onMounted, onBeforeUnmount, computed, nextTick } from 'vue'
-import { useScroll, useElementSize, useResizeObserver } from '@vueuse/core'
+import { ref, onMounted, computed, nextTick } from 'vue'
+import { useScroll, useElementSize } from '@vueuse/core'
 import { useProjectStore } from '@/store/modules/project'
 
 import Nodes from './Node.vue'
@@ -47,6 +50,7 @@ import Moveable from './Moveable.vue'
 const props = defineProps<{
   state: StageState
   page?: Page
+  screen?: Screen
 }>()
 const emit = defineEmits<{
   changeState: [Partial<StageState>]
@@ -147,11 +151,6 @@ useScroll(stageWrapperRef, {
   }
 })
 
-useResizeObserver(stageWrapperRef, () => {
-  initScale()
-  initStagePosition()
-})
-
 /* 设置缩放倍数 */
 const initScale = async () => {
   if (!clientWidth.value || !clientHeight.value) return
@@ -205,13 +204,7 @@ onMounted(() => {
   setTimeout(() => {
     initScale()
     initStagePosition()
-  }, 100)
-  window.addEventListener('resize', initScale)
-  window.addEventListener('resize', initStagePosition)
-})
-onBeforeUnmount(() => {
-  window.removeEventListener('resize', initScale)
-  window.removeEventListener('resize', initStagePosition)
+  }, 10)
 })
 </script>
 

+ 71 - 39
src/renderer/src/views/designer/workspace/stage/index.vue

@@ -8,12 +8,18 @@
     @mouseup="handleMouseUp"
   >
     <div class="workspace flex flex-col">
-      <div class="h-32px bg-bg-secondary stage-title border-b-1px border-b-solid border-border">
+      <!-- <div class="h-32px bg-bg-secondary stage-title border-b-1px border-b-solid border-border">
         <div class="px-12px leading-32px text-text-primary font-bold">{{ $t('screen') }}</div>
-      </div>
+      </div> -->
       <div class="workspace-top">
         <!-- 画布 -->
-        <DesignerCanvas :state="state" :page="page" ref="canvasRef" @changeState="handleSetState" />
+        <DesignerCanvas
+          :state="state"
+          :page="page"
+          :screen="screen"
+          ref="canvasRef"
+          @changeState="handleSetState"
+        />
         <!-- 标尺 -->
         <Ruler :state="state" :page="page" v-show="state.showRuler" />
       </div>
@@ -26,41 +32,53 @@
           <span>{{ state.width }} * {{ state.height }}</span>
         </div>
         <div class="bottom-right flex items-center gap-8px">
-          <div
-            v-if="projectStore.project?.meta.screenType === 'dual'"
-            class="w-20px h-20px flex items-center justify-center cursor-pointer"
-            @click="appStore.toggleLayout"
-          >
-            <LuRows2 :size="16" v-if="appStore.screenLayout === 'vertical'" />
-            <LuColumns2 :size="16" v-else />
-          </div>
-          <div
-            class="w-20px h-20px flex items-center justify-center cursor-pointer"
-            @click="handleCenter"
-          >
-            <LuFocus :size="16" />
-          </div>
-          <div
-            class="w-20px h-20px flex items-center justify-center cursor-pointer border-1px border-solid border-transparent"
-            :class="state.showRuler ? 'border-blue! border-1px border-solid bg-bg-primary' : ''"
-            @click="state.showRuler = !state.showRuler"
-          >
-            <LuRuler :size="16" />
-          </div>
-          <div
-            class="w-20px h-20px flex items-center justify-center cursor-pointer border-1px border-solid border-transparent"
-            :class="state.showBorder ? 'border-blue! border-1px border-solid bg-bg-primary' : ''"
-            @click="state.showBorder = !state.showBorder"
-          >
-            <LuBoxSelect :size="16" />
-          </div>
-          <div
-            class="w-20px h-20px flex items-center justify-center cursor-pointer border-1px border-solid border-transparent"
-            :class="state.showBgGrid ? 'border-blue! border-1px border-solid bg-bg-primary' : ''"
-            @click="state.showBgGrid = !state.showBgGrid"
-          >
-            <LuGrid3X3 :size="16" />
-          </div>
+          <el-tooltip content="屏幕布局">
+            <div
+              v-if="projectStore.project?.meta.screenType === 'dual'"
+              class="w-20px h-20px flex items-center justify-center cursor-pointer"
+              @click="appStore.toggleLayout"
+            >
+              <LuRows2 :size="16" v-if="appStore.screenLayout === 'vertical'" />
+              <LuColumns2 :size="16" v-else />
+            </div>
+          </el-tooltip>
+
+          <el-tooltip content="中心位置">
+            <div
+              class="w-20px h-20px flex items-center justify-center cursor-pointer"
+              @click="handleCenter"
+            >
+              <LuFocus :size="16" />
+            </div>
+          </el-tooltip>
+          <el-tooltip content="标尺">
+            <div
+              class="w-20px h-20px flex items-center justify-center cursor-pointer border-1px border-solid border-transparent"
+              :class="state.showRuler ? 'border-blue! border-1px border-solid bg-bg-primary' : ''"
+              @click="state.showRuler = !state.showRuler"
+            >
+              <LuRuler :size="16" />
+            </div>
+          </el-tooltip>
+          <el-tooltip content="控件边框">
+            <div
+              class="w-20px h-20px flex items-center justify-center cursor-pointer border-1px border-solid border-transparent"
+              :class="state.showBorder ? 'border-blue! border-1px border-solid bg-bg-primary' : ''"
+              @click="state.showBorder = !state.showBorder"
+            >
+              <LuBoxSelect :size="16" />
+            </div>
+          </el-tooltip>
+          <el-tooltip content="网格">
+            <div
+              class="w-20px h-20px flex items-center justify-center cursor-pointer border-1px border-solid border-transparent"
+              :class="state.showBgGrid ? 'border-blue! border-1px border-solid bg-bg-primary' : ''"
+              @click="state.showBgGrid = !state.showBgGrid"
+            >
+              <LuGrid3X3 :size="16" />
+            </div>
+          </el-tooltip>
+
           <el-slider
             v-model="state.scale"
             :min="0.1"
@@ -70,7 +88,11 @@
             size="small"
             style="width: 140px"
           ></el-slider>
-          <span class="inline w-30px">{{ (state.scale * 100).toFixed(0) }}%</span>
+          <el-tooltip content="重置缩放">
+            <span class="inline w-30px cursor-pointer" @click="setOriginSize"
+              >{{ (state.scale * 100).toFixed(0) }}%</span
+            >
+          </el-tooltip>
         </div>
       </div>
     </div>
@@ -149,6 +171,12 @@ const handleCenter = () => {
   canvasRef.value?.initStagePosition()
 }
 
+// 原始尺寸
+const setOriginSize = () => {
+  state.scale = 1
+  canvasRef.value?.initStagePosition()
+}
+
 const handleClick = () => {
   // 点击画布空白处
   projectStore.activePageId = props.page?.id
@@ -258,6 +286,10 @@ const handleSelectComponent = (startX: number, startY: number, endX: number, end
 provide('page', props.page)
 provide('state', state)
 provide('pageEl', boxRef)
+
+defineExpose({
+  handleCenter
+})
 </script>
 
 <style lang="less" scoped>