Add support for hovered viewport panel in transform operations

This commit is contained in:
2026-04-03 02:35:30 +02:00
parent e0b1c31323
commit 5c89a72dc8
2 changed files with 45 additions and 2 deletions

View File

@@ -922,6 +922,7 @@ export function App({ store, initialStatusMessage }: AppProps) {
const [statusMessage, setStatusMessage] = useState(initialStatusMessage ?? "Slice 3.5 advanced rendering ready.");
const [assetStatusMessage, setAssetStatusMessage] = useState<string | null>(null);
const [hoveredAssetId, setHoveredAssetId] = useState<string | null>(null);
const [hoveredViewportPanelId, setHoveredViewportPanelId] = useState<ViewportPanelId | null>(null);
const [addMenuPosition, setAddMenuPosition] = useState<HierarchicalMenuPosition | null>(null);
const [preferredNavigationMode, setPreferredNavigationMode] = useState<RuntimeNavigationMode>(
primaryPlayerStart === null ? "orbitVisitor" : "firstPerson"
@@ -1691,6 +1692,8 @@ export function App({ store, initialStatusMessage }: AppProps) {
return;
}
const transformSourcePanelId = hoveredViewportPanelId ?? activePanelId;
const transformTargetResult = resolveTransformTarget(editorState.document, editorState.selection);
const transformTarget = transformTargetResult.target;
@@ -1707,17 +1710,21 @@ export function App({ store, initialStatusMessage }: AppProps) {
blurActiveTextEntry();
closeAddMenu();
if (editorState.activeViewportPanelId !== transformSourcePanelId) {
store.setActiveViewportPanel(transformSourcePanelId);
}
store.setTransformSession(
createTransformSession({
source,
sourcePanelId: activePanelId,
sourcePanelId: transformSourcePanelId,
operation,
target: transformTarget
})
);
setStatusMessage(
`${getTransformOperationLabel(operation)} ${getTransformTargetLabel(transformTarget).toLowerCase()} in ${getViewportPanelLabel(
activePanelId
transformSourcePanelId
)}. Move the pointer, press X/Y/Z to constrain, click or press Enter to commit, Escape cancels.`
);
};
@@ -4860,6 +4867,7 @@ export function App({ store, initialStatusMessage }: AppProps) {
focusRequestId={focusRequest.panelId === panelId ? focusRequest.id : 0}
focusSelection={focusRequest.selection}
onActivatePanel={handleActivateViewportPanel}
onHoverPanel={setHoveredViewportPanelId}
onSetPanelViewMode={handleSetViewportPanelViewMode}
onSetPanelDisplayMode={handleSetViewportPanelDisplayMode}
onCommitCreation={handleCommitCreation}

View File

@@ -194,6 +194,16 @@ async function renderTransformFixtureApp() {
};
}
async function renderQuadTransformFixtureApp() {
const fixture = await renderTransformFixtureApp();
act(() => {
fixture.store.setViewportLayoutMode("quad");
});
return fixture;
}
function getLatestTransformSession(store: ReturnType<typeof createEditorStore>): ActiveTransformSession {
const transformSession = store.getState().viewportTransientState.transformSession;
@@ -418,4 +428,29 @@ describe("transform foundation integration", () => {
}
});
});
it("uses the hovered quad viewport as the active transform panel for keyboard entry", async () => {
const { store, brush } = await renderQuadTransformFixtureApp();
await act(async () => {
fireEvent.click(screen.getByRole("button", { name: /^Brush Transform Fixture$/ }));
});
fireEvent.pointerEnter(screen.getByTestId("viewport-panel-bottomRight"));
fireEvent.keyDown(window, {
key: "g",
code: "KeyG"
});
expect(store.getState().activeViewportPanelId).toBe("bottomRight");
expect(store.getState().viewportTransientState.transformSession).toMatchObject({
kind: "active",
operation: "translate",
sourcePanelId: "bottomRight",
target: {
kind: "brush",
brushId: brush.id
}
});
});
});