feat: 工具栏动态宽度 - 根据内容自动调整窗口宽度
This commit is contained in:
@@ -81,6 +81,11 @@ export function setupIpc(win: BrowserWindow): void {
|
||||
win.setPosition(x, y)
|
||||
})
|
||||
|
||||
ipcMain.handle('window:resizeMain', (_event, width: number) => {
|
||||
const [wx, wy] = win.getPosition()
|
||||
win.setBounds({ x: wx, y: wy, width: Math.max(200, Math.min(width, 1200)), height: 64 })
|
||||
})
|
||||
|
||||
ipcMain.handle('screenshot:start', () => {
|
||||
log.info('IPC: screenshot:start')
|
||||
startScreenshot(win)
|
||||
|
||||
@@ -3,7 +3,8 @@ import { contextBridge, ipcRenderer } from 'electron'
|
||||
contextBridge.exposeInMainWorld('electronAPI', {
|
||||
window: {
|
||||
dragMove: (deltaX: number, deltaY: number) => ipcRenderer.invoke('window:dragMove', { deltaX, deltaY }),
|
||||
dragEnd: (x: number, y: number) => ipcRenderer.invoke('window:dragEnd', { x, y })
|
||||
dragEnd: (x: number, y: number) => ipcRenderer.invoke('window:dragEnd', { x, y }),
|
||||
resizeMain: (width: number) => ipcRenderer.invoke('window:resizeMain', width)
|
||||
},
|
||||
|
||||
screenshot: {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="floating-toolbar" :class="{ 'is-hidden': !appStore.isToolbarVisible }">
|
||||
<div ref="toolbarRef" class="floating-toolbar" :class="{ 'is-hidden': !appStore.isToolbarVisible }">
|
||||
<div class="toolbar-buttons">
|
||||
<el-button class="toolbar-btn" @click="startScreenshot" :loading="appStore.isGrading">
|
||||
<span class="btn-icon">📷</span>
|
||||
@@ -11,19 +11,26 @@
|
||||
<span class="btn-label">评分标准</span>
|
||||
</el-button>
|
||||
|
||||
<el-dropdown trigger="click" @command="handleMenu">
|
||||
<el-button class="toolbar-btn">
|
||||
<template v-if="!showMenu">
|
||||
<el-button class="toolbar-btn" @click="showMenu = true">
|
||||
<span class="btn-icon">📎</span>
|
||||
<span class="btn-label">其它</span>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item command="image">📁 图片阅卷</el-dropdown-item>
|
||||
<el-dropdown-item command="templates">📚 模板</el-dropdown-item>
|
||||
<el-dropdown-item command="history">📜 历史</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-button class="toolbar-btn sub-btn" @click="showMenu = false; selectImage()">
|
||||
<span class="btn-icon">📁</span>
|
||||
<span class="btn-label">图片阅卷</span>
|
||||
</el-button>
|
||||
<el-button class="toolbar-btn sub-btn" @click="showMenu = false; openTemplates()">
|
||||
<span class="btn-icon">📚</span>
|
||||
<span class="btn-label">模板</span>
|
||||
</el-button>
|
||||
<el-button class="toolbar-btn sub-btn" @click="showMenu = false; openHistory()">
|
||||
<span class="btn-icon">📜</span>
|
||||
<span class="btn-label">历史</span>
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
<el-button class="toolbar-btn" @click="openSettings">
|
||||
<span class="btn-icon">⚙</span>
|
||||
@@ -34,7 +41,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, onUnmounted } from 'vue'
|
||||
import { ref, nextTick, watch, onMounted, onUnmounted } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { useAppStore } from '@/stores/app'
|
||||
import { useGradingStore } from '@/stores/grading'
|
||||
@@ -44,9 +51,23 @@ const appStore = useAppStore()
|
||||
const gradingStore = useGradingStore()
|
||||
const settingsStore = useSettingsStore()
|
||||
|
||||
const showMenu = ref(false)
|
||||
const toolbarRef = ref<HTMLElement | null>(null)
|
||||
|
||||
async function resizeWindow() {
|
||||
await nextTick()
|
||||
if (toolbarRef.value && window.electronAPI) {
|
||||
const w = toolbarRef.value.scrollWidth + 2
|
||||
window.electronAPI.window.resizeMain(w)
|
||||
}
|
||||
}
|
||||
|
||||
watch(showMenu, resizeWindow)
|
||||
|
||||
let cleanupScreenshotListener: (() => void) | null = null
|
||||
|
||||
onMounted(() => {
|
||||
resizeWindow()
|
||||
if (window.electronAPI) {
|
||||
cleanupScreenshotListener = window.electronAPI.screenshot.onCompleted((base64: string) => {
|
||||
if (!appStore.isGrading) {
|
||||
@@ -157,7 +178,11 @@ function openSettings() { window.electronAPI?.dialog.open('settings') }
|
||||
<style scoped>
|
||||
.floating-toolbar {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: fit-content;
|
||||
min-width: 200px;
|
||||
height: 64px;
|
||||
z-index: 99999;
|
||||
user-select: none;
|
||||
-webkit-app-region: drag;
|
||||
@@ -177,8 +202,8 @@ function openSettings() { window.electronAPI?.dialog.open('settings') }
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.toolbar-buttons :deep(.el-dropdown) {
|
||||
-webkit-app-region: no-drag;
|
||||
.sub-btn {
|
||||
padding: 4px 8px !important;
|
||||
}
|
||||
|
||||
.toolbar-btn {
|
||||
|
||||
@@ -46,6 +46,7 @@ export interface ElectronAPI {
|
||||
window: {
|
||||
dragMove: (deltaX: number, deltaY: number) => Promise<void>
|
||||
dragEnd: (x: number, y: number) => Promise<void>
|
||||
resizeMain: (width: number) => Promise<void>
|
||||
}
|
||||
screenshot: {
|
||||
start: () => Promise<void>
|
||||
|
||||
Reference in New Issue
Block a user