diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index 9820478..22715e2 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -5,6 +5,8 @@ "windows": ["main"], "permissions": [ "core:default", - "shell:allow-open" + "shell:allow-open", + "core:window:allow-set-fullscreen", + "core:window:allow-is-fullscreen" ] } diff --git a/src-tauri/gen/schemas/capabilities.json b/src-tauri/gen/schemas/capabilities.json index c1550d9..700904f 100644 --- a/src-tauri/gen/schemas/capabilities.json +++ b/src-tauri/gen/schemas/capabilities.json @@ -1 +1 @@ -{"default":{"identifier":"default","description":"Capability for the main application window","local":true,"windows":["main"],"permissions":["core:default","shell:allow-open"]}} \ No newline at end of file +{"default":{"identifier":"default","description":"Capability for the main application window","local":true,"windows":["main"],"permissions":["core:default","shell:allow-open","core:window:allow-set-fullscreen","core:window:allow-is-fullscreen"]}} \ No newline at end of file diff --git a/src/components/white-balance/white-balance.tsx b/src/components/white-balance/white-balance.tsx index 7e5d29c..7bc597f 100644 --- a/src/components/white-balance/white-balance.tsx +++ b/src/components/white-balance/white-balance.tsx @@ -1,5 +1,5 @@ import { listen } from '@tauri-apps/api/event'; -import { Component, createEffect, onCleanup } from 'solid-js'; +import { Component, createEffect, onCleanup, createSignal } from 'solid-js'; import { ColorCalibration, LedStripConfigContainer } from '../../models/led-strip-config'; import { ledStripStore, setLedStripStore } from '../../stores/led-strip.store'; import { ColorSlider } from './color-slider'; @@ -7,6 +7,8 @@ import { TestColorsBg } from './test-colors-bg'; import { invoke } from '@tauri-apps/api/core'; import { VsClose } from 'solid-icons/vs'; import { BiRegularReset } from 'solid-icons/bi'; +import { BsFullscreen, BsFullscreenExit } from 'solid-icons/bs'; +import { getCurrentWindow } from '@tauri-apps/api/window'; import transparentBg from '../../assets/transparent-grid-background.svg?url'; const Value: Component<{ value: number }> = (props) => { @@ -18,6 +20,82 @@ const Value: Component<{ value: number }> = (props) => { }; export const WhiteBalance = () => { + const [isFullscreen, setIsFullscreen] = createSignal(false); + const [panelPosition, setPanelPosition] = createSignal({ x: 0, y: 0 }); + const [isDragging, setIsDragging] = createSignal(false); + const [dragOffset, setDragOffset] = createSignal({ x: 0, y: 0 }); + + // 自动进入全屏模式 + createEffect(() => { + const autoEnterFullscreen = async () => { + try { + const window = getCurrentWindow(); + const currentFullscreen = await window.isFullscreen(); + if (!currentFullscreen) { + await window.setFullscreen(true); + setIsFullscreen(true); + } else { + setIsFullscreen(true); + } + } catch (error) { + console.error('Failed to auto enter fullscreen:', error); + } + }; + + autoEnterFullscreen(); + }); + + // 初始化面板位置到屏幕中央 + createEffect(() => { + if (isFullscreen()) { + const centerX = window.innerWidth / 2 - 160; // 160是面板宽度的一半 + const centerY = window.innerHeight / 2 - 200; // 200是面板高度的一半 + setPanelPosition({ x: centerX, y: centerY }); + } + }); + + // 拖拽处理函数 + const handleMouseDown = (e: MouseEvent) => { + setIsDragging(true); + const rect = (e.currentTarget as HTMLElement).getBoundingClientRect(); + setDragOffset({ + x: e.clientX - rect.left, + y: e.clientY - rect.top + }); + e.preventDefault(); + }; + + const handleMouseMove = (e: MouseEvent) => { + if (isDragging()) { + const newX = e.clientX - dragOffset().x; + const newY = e.clientY - dragOffset().y; + + // 限制面板在屏幕范围内 + const maxX = window.innerWidth - 320; // 320是面板宽度 + const maxY = window.innerHeight - 400; // 400是面板高度 + + setPanelPosition({ + x: Math.max(0, Math.min(newX, maxX)), + y: Math.max(0, Math.min(newY, maxY)) + }); + } + }; + + const handleMouseUp = () => { + setIsDragging(false); + }; + + // 添加全局鼠标事件监听 + createEffect(() => { + if (isDragging()) { + document.addEventListener('mousemove', handleMouseMove); + document.addEventListener('mouseup', handleMouseUp); + } else { + document.removeEventListener('mousemove', handleMouseMove); + document.removeEventListener('mouseup', handleMouseUp); + } + }); + // listen to config_changed event createEffect(() => { const unlisten = listen('config_changed', (event) => { @@ -31,20 +109,48 @@ export const WhiteBalance = () => { }); }); - onCleanup(() => { - unlisten.then((unlisten) => unlisten()); + onCleanup(async () => { + (await unlisten)(); }); }); - const updateColorCalibration = (field: keyof ColorCalibration, value: number) => { - const calibration = { ...ledStripStore.colorCalibration, [field]: value }; - invoke('set_color_calibration', { - calibration, - }).catch((error) => console.log(error)); + const updateColorCalibration = ( + key: keyof ColorCalibration, + value: number, + ) => { + const calibration = { ...ledStripStore.colorCalibration }; + calibration[key] = value; + setLedStripStore('colorCalibration', calibration); + invoke('set_color_calibration', { calibration }).catch((error) => + console.log(error), + ); + }; + + const toggleFullscreen = async () => { + try { + const window = getCurrentWindow(); + const currentFullscreen = await window.isFullscreen(); + await window.setFullscreen(!currentFullscreen); + setIsFullscreen(!currentFullscreen); + + // 退出全屏时重置面板位置 + if (currentFullscreen) { + setPanelPosition({ x: 0, y: 0 }); + } + } catch (error) { + console.error('Failed to toggle fullscreen:', error); + } }; const exit = () => { - window.history.back(); + // 退出时确保退出全屏模式 + if (isFullscreen()) { + toggleFullscreen().then(() => { + window.history.back(); + }); + } else { + window.history.back(); + } }; const reset = () => { @@ -54,118 +160,273 @@ export const WhiteBalance = () => { }; return ( -
-
-

白平衡调节

-
- - -
-
+ <> + {/* 普通模式 */} + {!isFullscreen() && ( +
+
+

白平衡调节

+
+ + + +
+
-
- {/* 颜色测试区域 */} -
-
-
- 颜色测试 -
点击测试
+
+ {/* 颜色测试区域 */} +
+
+
+ 颜色测试 +
点击测试
+
+
+ +
+
+ 💡 提示:点击颜色块进行单色测试,再次点击返回多色模式 +
+
-
- -
-
- 💡 提示:点击颜色块进行单色测试,再次点击返回多色模式 + + {/* 白平衡控制面板 */} +
+
+
+ RGB调节 +
实时调节
+
+ +
+
+ + + updateColorCalibration( + 'r', + (ev.target as HTMLInputElement).valueAsNumber ?? 1, + ) + } + /> +
+ +
+ + + updateColorCalibration( + 'g', + (ev.target as HTMLInputElement).valueAsNumber ?? 1, + ) + } + /> +
+ +
+ + + updateColorCalibration( + 'b', + (ev.target as HTMLInputElement).valueAsNumber ?? 1, + ) + } + /> +
+ +
+ + +
+
+ + {/* 使用说明 - 可展开 */} +
+ +
+ 💡 白平衡调节使用说明 +
+
+
+

🎯 推荐使用方法:

+
    +
  1. 点击上方"全屏"按钮进入全屏模式
  2. +
  3. 全屏模式下屏幕边缘会显示彩色条带
  4. +
  5. 将RGB控制面板拖拽到合适位置
  6. +
  7. 对比LED灯条颜色与屏幕边缘颜色
  8. +
+
+ +
+

🔧 调节技巧:

+
    +
  • 红色偏强:降低R值,LED会减少红色成分
  • +
  • 绿色偏强:降低G值,LED会减少绿色成分
  • +
  • 蓝色偏强:降低B值,LED会减少蓝色成分
  • +
  • 白色发黄:适当提高B值,降低R/G值
  • +
  • 白色发蓝:适当降低B值,提高R/G值
  • +
+
+ +
+

📋 对比方法:

+
    +
  • 重点观察白色区域,确保LED白光与屏幕白色一致
  • +
  • 检查彩色区域,确保LED颜色饱和度合适
  • +
  • 在不同环境光下测试,确保效果稳定
  • +
  • 调节完成后可点击"重置"按钮恢复默认值
  • +
+
+
+
+
+ )} - {/* 白平衡控制面板 */} -
-
-
- RGB调节 -
实时调节
-
+ {/* 全屏模式 */} + {isFullscreen() && ( +
+ {/* 全屏颜色测试区域 - 紧贴边缘 */} +
+ +
-
-
- - - updateColorCalibration( - 'r', - (ev.target as HTMLInputElement).valueAsNumber ?? 1, - ) - } - /> + {/* 可拖拽的RGB控制面板 */} +
+
+
+
+ ⋮⋮ + RGB调节 +
可拖拽
+
+
-
- - - updateColorCalibration( - 'g', - (ev.target as HTMLInputElement).valueAsNumber ?? 1, - ) - } - /> +
+
+ + + updateColorCalibration( + 'r', + (ev.target as HTMLInputElement).valueAsNumber ?? 1, + ) + } + /> +
+ +
+ + + updateColorCalibration( + 'g', + (ev.target as HTMLInputElement).valueAsNumber ?? 1, + ) + } + /> +
+ +
+ + + updateColorCalibration( + 'b', + (ev.target as HTMLInputElement).valueAsNumber ?? 1, + ) + } + /> +
+ +
+ + +
-
- - - updateColorCalibration( - 'b', - (ev.target as HTMLInputElement).valueAsNumber ?? 1, - ) - } - /> +
+ 💡 对比屏幕边缘颜色与LED灯条,调节RGB滑块使颜色一致
-
- - +
+ +
- -
- 💡 提示:调节RGB滑块来校正LED灯条的白平衡,使白色更加纯净 -
-
-
+ )} + ); -}; +}; \ No newline at end of file