diff --git a/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/CanvasLaunchpadPanel.tsx b/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/CanvasLaunchpadPanel.tsx
index 2af9fb2056..f773d6e8ba 100644
--- a/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/CanvasLaunchpadPanel.tsx
+++ b/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/CanvasLaunchpadPanel.tsx
@@ -1,5 +1,7 @@
import { Button, Flex, Grid, Heading, Text } from '@invoke-ai/ui-library';
-import { memo } from 'react';
+import { useAutoLayoutContext } from 'features/ui/layouts/auto-layout-context';
+import { WORKSPACE_PANEL_ID } from 'features/ui/layouts/shared';
+import { memo, useCallback } from 'react';
import { InitialStateMainModelPicker } from './InitialStateMainModelPicker';
import { LaunchpadAddStyleReference } from './LaunchpadAddStyleReference';
@@ -8,6 +10,10 @@ import { LaunchpadGenerateFromTextButton } from './LaunchpadGenerateFromTextButt
import { LaunchpadUseALayoutImageButton } from './LaunchpadUseALayoutImageButton';
export const CanvasLaunchpadPanel = memo(() => {
+ const ctx = useAutoLayoutContext();
+ const focusCanvas = useCallback(() => {
+ ctx.focusPanel(WORKSPACE_PANEL_ID);
+ }, [ctx]);
return (
@@ -24,10 +30,10 @@ export const CanvasLaunchpadPanel = memo(() => {
-
-
-
-
+
+
+
+
diff --git a/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/LaunchpadAddStyleReference.tsx b/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/LaunchpadAddStyleReference.tsx
index b4dfcff423..6ab253565b 100644
--- a/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/LaunchpadAddStyleReference.tsx
+++ b/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/LaunchpadAddStyleReference.tsx
@@ -13,7 +13,7 @@ import type { ImageDTO } from 'services/api/types';
const dndTargetData = addGlobalReferenceImageDndTarget.getData();
-export const LaunchpadAddStyleReference = memo(() => {
+export const LaunchpadAddStyleReference = memo((props: { extraAction?: () => void }) => {
const { dispatch, getState } = useAppStore();
const uploadOptions = useMemo(
@@ -23,10 +23,11 @@ export const LaunchpadAddStyleReference = memo(() => {
const config = getDefaultRefImageConfig(getState);
config.image = imageDTOToImageWithDims(imageDTO);
dispatch(refImageAdded({ overrides: { config } }));
+ props.extraAction?.();
},
allowMultiple: false,
}) as const,
- [dispatch, getState]
+ [dispatch, getState, props]
);
const uploadApi = useImageUploadButton(uploadOptions);
diff --git a/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/LaunchpadEditImageButton.tsx b/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/LaunchpadEditImageButton.tsx
index f509558427..afc5c6c403 100644
--- a/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/LaunchpadEditImageButton.tsx
+++ b/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/LaunchpadEditImageButton.tsx
@@ -13,14 +13,15 @@ const NEW_CANVAS_OPTIONS = { type: 'raster_layer', withInpaintMask: true } as co
const dndTargetData = newCanvasFromImageDndTarget.getData(NEW_CANVAS_OPTIONS);
-export const LaunchpadEditImageButton = memo(() => {
+export const LaunchpadEditImageButton = memo((props: { extraAction?: () => void }) => {
const { getState, dispatch } = useAppStore();
const onUpload = useCallback(
(imageDTO: ImageDTO) => {
newCanvasFromImage({ imageDTO, getState, dispatch, ...NEW_CANVAS_OPTIONS });
+ props.extraAction?.();
},
- [dispatch, getState]
+ [dispatch, getState, props]
);
const uploadApi = useImageUploadButton({ allowMultiple: false, onUpload });
diff --git a/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/LaunchpadGenerateFromTextButton.tsx b/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/LaunchpadGenerateFromTextButton.tsx
index bac9b2e750..055fb3a2ad 100644
--- a/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/LaunchpadGenerateFromTextButton.tsx
+++ b/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/LaunchpadGenerateFromTextButton.tsx
@@ -1,19 +1,29 @@
import { Flex, Heading, Icon, Text } from '@invoke-ai/ui-library';
import { LaunchpadButton } from 'features/controlLayers/components/SimpleSession/LaunchpadButton';
-import { memo } from 'react';
+import { useAutoLayoutContext } from 'features/ui/layouts/auto-layout-context';
+import { memo, useCallback } from 'react';
import { PiCursorTextBold, PiTextAaBold } from 'react-icons/pi';
-const focusOnPrompt = () => {
- const promptElement = document.getElementById('prompt');
+const focusOnPrompt = (el: HTMLElement) => {
+ const promptElement = el.querySelector('.positive-prompt-textarea');
if (promptElement instanceof HTMLTextAreaElement) {
promptElement.focus();
promptElement.select();
}
};
-export const LaunchpadGenerateFromTextButton = memo(() => {
+export const LaunchpadGenerateFromTextButton = memo((props: { extraAction?: () => void }) => {
+ const { rootRef } = useAutoLayoutContext();
+ const onClick = useCallback(() => {
+ const el = rootRef.current;
+ if (!el) {
+ return;
+ }
+ focusOnPrompt(el);
+ props.extraAction?.();
+ }, [props, rootRef]);
return (
-
+
Generate from Text
diff --git a/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/LaunchpadUseALayoutImageButton.tsx b/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/LaunchpadUseALayoutImageButton.tsx
index 204a684abb..f05290f095 100644
--- a/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/LaunchpadUseALayoutImageButton.tsx
+++ b/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/LaunchpadUseALayoutImageButton.tsx
@@ -14,14 +14,15 @@ const NEW_CANVAS_OPTIONS = { type: 'control_layer', withResize: true } as const;
const dndTargetData = newCanvasFromImageDndTarget.getData(NEW_CANVAS_OPTIONS);
-export const LaunchpadUseALayoutImageButton = memo(() => {
+export const LaunchpadUseALayoutImageButton = memo((props: { extraAction?: () => void }) => {
const { getState, dispatch } = useAppStore();
const onUpload = useCallback(
(imageDTO: ImageDTO) => {
newCanvasFromImage({ imageDTO, getState, dispatch, ...NEW_CANVAS_OPTIONS });
+ props.extraAction?.();
},
- [dispatch, getState]
+ [dispatch, getState, props]
);
const uploadApi = useImageUploadButton({ allowMultiple: false, onUpload });
diff --git a/invokeai/frontend/web/src/features/parameters/components/Core/ParamNegativePrompt.tsx b/invokeai/frontend/web/src/features/parameters/components/Core/ParamNegativePrompt.tsx
index f18d1238ea..1ba98fa774 100644
--- a/invokeai/frontend/web/src/features/parameters/components/Core/ParamNegativePrompt.tsx
+++ b/invokeai/frontend/web/src/features/parameters/components/Core/ParamNegativePrompt.tsx
@@ -57,7 +57,7 @@ export const ParamNegativePrompt = memo(() => {