diff --git a/packages/editor/src/editor/EditorApp.tsx b/packages/editor/src/editor/EditorApp.tsx index fb5fcf5..e3bf740 100644 --- a/packages/editor/src/editor/EditorApp.tsx +++ b/packages/editor/src/editor/EditorApp.tsx @@ -502,14 +502,60 @@ export function EditorApp() { 尺寸 - - + { + if (!selected) return; + if (typeof v !== 'number') return; + dispatch({ type: 'updateWidgetRect', id: selected.id, rect: { w: v } }); + }} + style={{ width: 120 }} + /> + { + if (!selected) return; + if (typeof v !== 'number') return; + dispatch({ type: 'updateWidgetRect', id: selected.id, rect: { h: v } }); + }} + style={{ width: 120 }} + /> 位置 - - + { + if (!selected) return; + if (typeof v !== 'number') return; + dispatch({ type: 'updateWidgetRect', id: selected.id, rect: { x: v } }); + }} + style={{ width: 120 }} + /> + { + if (!selected) return; + if (typeof v !== 'number') return; + dispatch({ type: 'updateWidgetRect', id: selected.id, rect: { y: v } }); + }} + style={{ width: 120 }} + /> diff --git a/packages/editor/src/editor/store.ts b/packages/editor/src/editor/store.ts index 380d05c..e808a8c 100644 --- a/packages/editor/src/editor/store.ts +++ b/packages/editor/src/editor/store.ts @@ -67,6 +67,7 @@ export type EditorAction = | { type: 'bringForwardSelected' } | { type: 'sendBackwardSelected' } | { type: 'sendToBackSelected' } + | { type: 'updateWidgetRect'; id: string; rect: Partial } | UpdateWidgetPropsAction; interface DragSession { @@ -336,6 +337,41 @@ export function editorReducer(state: EditorRuntimeState, action: EditorAction): }; } + case 'updateWidgetRect': { + const target = state.doc.screen.nodes.find((n) => n.id === action.id); + if (!target) return state; + if (target.locked) return state; + + const next: Rect = { + x: typeof action.rect.x === 'number' ? action.rect.x : target.rect.x, + y: typeof action.rect.y === 'number' ? action.rect.y : target.rect.y, + w: typeof action.rect.w === 'number' ? action.rect.w : target.rect.w, + h: typeof action.rect.h === 'number' ? action.rect.h : target.rect.h, + }; + + const bounds = { w: state.doc.screen.width, h: state.doc.screen.height }; + const rect = clampRectToBounds( + { + x: Math.round(next.x), + y: Math.round(next.y), + w: Math.round(next.w), + h: Math.round(next.h), + }, + bounds, + 50, + ); + + return { + ...historyPush(state), + doc: { + screen: { + ...state.doc.screen, + nodes: state.doc.screen.nodes.map((n) => (n.id === action.id ? { ...n, rect } : n)), + }, + }, + }; + } + case 'updateWidgetProps': { return updateWidgetProps(state, action); }