Feature/render pipeline (#232)

* refactor(engine): 重构2D渲染管线坐标系统

* feat(engine): 完善2D渲染管线和编辑器视口功能

* feat(editor): 实现Viewport变换工具系统

* feat(editor): 优化Inspector渲染性能并修复Gizmo变换工具显示

* feat(editor): 实现Run on Device移动预览功能

* feat(editor): 添加组件属性控制和依赖关系系统

* feat(editor): 实现动画预览功能和优化SpriteAnimator编辑器

* feat(editor): 修复SpriteAnimator动画预览功能并迁移CI到pnpm

* feat(editor): 修复SpriteAnimator动画预览并迁移到pnpm

* feat(editor): 修复SpriteAnimator动画预览并迁移到pnpm

* feat(editor): 修复SpriteAnimator动画预览并迁移到pnpm

* feat(editor): 修复SpriteAnimator动画预览并迁移到pnpm

* feat(ci): 迁移项目到pnpm并修复CI构建问题

* chore: 迁移CI工作流到pnpm并添加WASM构建支持

* chore: 迁移CI工作流到pnpm并添加WASM构建支持

* chore: 迁移CI工作流到pnpm并添加WASM构建支持

* chore: 迁移CI工作流到pnpm并添加WASM构建支持

* chore: 迁移CI工作流到pnpm并添加WASM构建支持

* chore: 迁移CI工作流到pnpm并添加WASM构建支持

* chore: 移除 network 相关包

* chore: 移除 network 相关包
This commit is contained in:
YHH
2025-11-23 14:49:37 +08:00
committed by GitHub
parent b15cbab313
commit a3f7cc38b1
247 changed files with 33561 additions and 52047 deletions

View File

@@ -1,10 +1,10 @@
import React, { useState, useRef, useCallback } from 'react';
import { FileText, Search, X, FolderOpen, ArrowRight, Package } from 'lucide-react';
import { open } from '@tauri-apps/plugin-dialog';
import { AssetPickerDialog } from '../../../components/dialogs/AssetPickerDialog';
import './AssetField.css';
interface AssetFieldProps {
label: string;
label?: string;
value: string | null;
onChange: (value: string | null) => void;
fileExtension?: string; // 例如: '.btree'
@@ -24,6 +24,7 @@ export function AssetField({
}: AssetFieldProps) {
const [isDragging, setIsDragging] = useState(false);
const [isHovered, setIsHovered] = useState(false);
const [showPicker, setShowPicker] = useState(false);
const inputRef = useRef<HTMLDivElement>(null);
const handleDragEnter = useCallback((e: React.DragEvent) => {
@@ -54,7 +55,7 @@ export function AssetField({
// 处理从文件系统拖入的文件
const files = Array.from(e.dataTransfer.files);
const file = files.find(f =>
const file = files.find((f) =>
!fileExtension || f.name.endsWith(fileExtension)
);
@@ -78,25 +79,15 @@ export function AssetField({
}
}, [onChange, fileExtension, readonly]);
const handleBrowse = useCallback(async () => {
const handleBrowse = useCallback(() => {
if (readonly) return;
setShowPicker(true);
}, [readonly]);
try {
const selected = await open({
multiple: false,
filters: fileExtension ? [{
name: `${fileExtension} Files`,
extensions: [fileExtension.replace('.', '')]
}] : []
});
if (selected) {
onChange(selected as string);
}
} catch (error) {
console.error('Failed to open file dialog:', error);
}
}, [onChange, fileExtension, readonly]);
const handlePickerSelect = useCallback((path: string) => {
onChange(path);
setShowPicker(false);
}, [onChange]);
const handleClear = useCallback(() => {
if (!readonly) {
@@ -111,7 +102,7 @@ export function AssetField({
return (
<div className="asset-field">
<label className="asset-field__label">{label}</label>
{label && <label className="asset-field__label">{label}</label>}
<div
className={`asset-field__container ${isDragging ? 'dragging' : ''} ${isHovered ? 'hovered' : ''}`}
onMouseEnter={() => setIsHovered(true)}
@@ -160,17 +151,21 @@ export function AssetField({
</button>
)}
{/* 导航按钮 */}
{value && onNavigate && (
{/* 导航/定位按钮 */}
{onNavigate && (
<button
className="asset-field__button"
onClick={(e) => {
e.stopPropagation();
onNavigate(value);
if (value) {
onNavigate(value);
} else {
handleBrowse();
}
}}
title="在资产浏览器中显示"
title={value ? '在资产浏览器中显示' : '选择资产'}
>
<ArrowRight size={12} />
{value ? <ArrowRight size={12} /> : <FolderOpen size={12} />}
</button>
)}
@@ -189,6 +184,14 @@ export function AssetField({
)}
</div>
</div>
<AssetPickerDialog
isOpen={showPicker}
onClose={() => setShowPicker(false)}
onSelect={handlePickerSelect}
title="Select Asset"
fileExtensions={fileExtension ? [fileExtension] : []}
/>
</div>
);
}
}