mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): rough out undo/redo on canvas UNDO ME?
This commit is contained in:
parent
217b2759c3
commit
35b483b83a
@ -58,7 +58,7 @@ export const addStagingListeners = (startAppListening: AppStartListening) => {
|
|||||||
const stagingAreaImage = state.canvasSession.stagedImages[index];
|
const stagingAreaImage = state.canvasSession.stagedImages[index];
|
||||||
|
|
||||||
assert(stagingAreaImage, 'No staged image found to accept');
|
assert(stagingAreaImage, 'No staged image found to accept');
|
||||||
const { x, y } = state.canvasV2.bbox.rect;
|
const { x, y } = state.canvasV2.present.bbox.rect;
|
||||||
|
|
||||||
const { imageDTO, offsetX, offsetY } = stagingAreaImage;
|
const { imageDTO, offsetX, offsetY } = stagingAreaImage;
|
||||||
const imageObject = imageDTOToImageObject(imageDTO);
|
const imageObject = imageDTOToImageObject(imageDTO);
|
||||||
|
@ -16,7 +16,7 @@ export const addDeleteBoardAndImagesFulfilledListener = (startAppListening: AppS
|
|||||||
const { nodes, canvasV2 } = getState();
|
const { nodes, canvasV2 } = getState();
|
||||||
|
|
||||||
deleted_images.forEach((image_name) => {
|
deleted_images.forEach((image_name) => {
|
||||||
const imageUsage = getImageUsage(nodes.present, canvasV2, image_name);
|
const imageUsage = getImageUsage(nodes.present, canvasV2.present, image_name);
|
||||||
|
|
||||||
if (imageUsage.isNodesImage && !wasNodeEditorReset) {
|
if (imageUsage.isNodesImage && !wasNodeEditorReset) {
|
||||||
dispatch(nodeEditorReset());
|
dispatch(nodeEditorReset());
|
||||||
|
@ -40,7 +40,7 @@ const deleteNodesImages = (state: RootState, dispatch: AppDispatch, imageDTO: Im
|
|||||||
};
|
};
|
||||||
|
|
||||||
// const deleteControlAdapterImages = (state: RootState, dispatch: AppDispatch, imageDTO: ImageDTO) => {
|
// const deleteControlAdapterImages = (state: RootState, dispatch: AppDispatch, imageDTO: ImageDTO) => {
|
||||||
// state.canvasV2.controlAdapters.entities.forEach(({ id, imageObject, processedImageObject }) => {
|
// state.canvasV2.present.controlAdapters.entities.forEach(({ id, imageObject, processedImageObject }) => {
|
||||||
// if (
|
// if (
|
||||||
// imageObject?.image.image_name === imageDTO.image_name ||
|
// imageObject?.image.image_name === imageDTO.image_name ||
|
||||||
// processedImageObject?.image.image_name === imageDTO.image_name
|
// processedImageObject?.image.image_name === imageDTO.image_name
|
||||||
@ -52,7 +52,7 @@ const deleteNodesImages = (state: RootState, dispatch: AppDispatch, imageDTO: Im
|
|||||||
// };
|
// };
|
||||||
|
|
||||||
const deleteIPAdapterImages = (state: RootState, dispatch: AppDispatch, imageDTO: ImageDTO) => {
|
const deleteIPAdapterImages = (state: RootState, dispatch: AppDispatch, imageDTO: ImageDTO) => {
|
||||||
state.canvasV2.ipAdapters.entities.forEach((entity) => {
|
state.canvasV2.present.ipAdapters.entities.forEach((entity) => {
|
||||||
if (entity.ipAdapter.image?.image_name === imageDTO.image_name) {
|
if (entity.ipAdapter.image?.image_name === imageDTO.image_name) {
|
||||||
dispatch(ipaImageChanged({ entityIdentifier: getEntityIdentifier(entity), imageDTO: null }));
|
dispatch(ipaImageChanged({ entityIdentifier: getEntityIdentifier(entity), imageDTO: null }));
|
||||||
}
|
}
|
||||||
@ -60,7 +60,7 @@ const deleteIPAdapterImages = (state: RootState, dispatch: AppDispatch, imageDTO
|
|||||||
};
|
};
|
||||||
|
|
||||||
const deleteLayerImages = (state: RootState, dispatch: AppDispatch, imageDTO: ImageDTO) => {
|
const deleteLayerImages = (state: RootState, dispatch: AppDispatch, imageDTO: ImageDTO) => {
|
||||||
state.canvasV2.rasterLayers.entities.forEach(({ id, objects }) => {
|
state.canvasV2.present.rasterLayers.entities.forEach(({ id, objects }) => {
|
||||||
let shouldDelete = false;
|
let shouldDelete = false;
|
||||||
for (const obj of objects) {
|
for (const obj of objects) {
|
||||||
if (obj.type === 'image' && obj.image.image_name === imageDTO.image_name) {
|
if (obj.type === 'image' && obj.image.image_name === imageDTO.image_name) {
|
||||||
|
@ -85,7 +85,7 @@ export const addImageDroppedListener = (startAppListening: AppStartListening) =>
|
|||||||
activeData.payload.imageDTO
|
activeData.payload.imageDTO
|
||||||
) {
|
) {
|
||||||
const imageObject = imageDTOToImageObject(activeData.payload.imageDTO);
|
const imageObject = imageDTOToImageObject(activeData.payload.imageDTO);
|
||||||
const { x, y } = getState().canvasV2.bbox.rect;
|
const { x, y } = getState().canvasV2.present.bbox.rect;
|
||||||
const overrides: Partial<CanvasRasterLayerState> = {
|
const overrides: Partial<CanvasRasterLayerState> = {
|
||||||
objects: [imageObject],
|
objects: [imageObject],
|
||||||
position: { x, y },
|
position: { x, y },
|
||||||
@ -103,7 +103,7 @@ export const addImageDroppedListener = (startAppListening: AppStartListening) =>
|
|||||||
activeData.payload.imageDTO
|
activeData.payload.imageDTO
|
||||||
) {
|
) {
|
||||||
const imageObject = imageDTOToImageObject(activeData.payload.imageDTO);
|
const imageObject = imageDTOToImageObject(activeData.payload.imageDTO);
|
||||||
const { x, y } = getState().canvasV2.bbox.rect;
|
const { x, y } = getState().canvasV2.present.bbox.rect;
|
||||||
const overrides: Partial<CanvasControlLayerState> = {
|
const overrides: Partial<CanvasControlLayerState> = {
|
||||||
objects: [imageObject],
|
objects: [imageObject],
|
||||||
position: { x, y },
|
position: { x, y },
|
||||||
|
@ -46,7 +46,7 @@ export const addModelSelectedListener = (startAppListening: AppStartListening) =
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handle incompatible controlnets
|
// handle incompatible controlnets
|
||||||
// state.canvasV2.controlAdapters.entities.forEach((ca) => {
|
// state.canvasV2.present.controlAdapters.entities.forEach((ca) => {
|
||||||
// if (ca.model?.base !== newBaseModel) {
|
// if (ca.model?.base !== newBaseModel) {
|
||||||
// modelsCleared += 1;
|
// modelsCleared += 1;
|
||||||
// if (ca.isEnabled) {
|
// if (ca.isEnabled) {
|
||||||
|
@ -83,11 +83,11 @@ const handleMainModels: ModelHandler = (models, state, dispatch, log) => {
|
|||||||
dispatch(modelChanged({ model: defaultModelInList, previousModel: currentModel }));
|
dispatch(modelChanged({ model: defaultModelInList, previousModel: currentModel }));
|
||||||
|
|
||||||
const optimalDimension = getOptimalDimension(defaultModelInList);
|
const optimalDimension = getOptimalDimension(defaultModelInList);
|
||||||
if (getIsSizeOptimal(state.canvasV2.bbox.rect.width, state.canvasV2.bbox.rect.height, optimalDimension)) {
|
if (getIsSizeOptimal(state.canvasV2.present.bbox.rect.width, state.canvasV2.present.bbox.rect.height, optimalDimension)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { width, height } = calculateNewSize(
|
const { width, height } = calculateNewSize(
|
||||||
state.canvasV2.bbox.aspectRatio.value,
|
state.canvasV2.present.bbox.aspectRatio.value,
|
||||||
optimalDimension * optimalDimension
|
optimalDimension * optimalDimension
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -172,7 +172,7 @@ const handleLoRAModels: ModelHandler = (models, state, dispatch, _log) => {
|
|||||||
|
|
||||||
const handleControlAdapterModels: ModelHandler = (models, state, dispatch, _log) => {
|
const handleControlAdapterModels: ModelHandler = (models, state, dispatch, _log) => {
|
||||||
const caModels = models.filter(isControlNetOrT2IAdapterModelConfig);
|
const caModels = models.filter(isControlNetOrT2IAdapterModelConfig);
|
||||||
state.canvasV2.controlLayers.entities.forEach((entity) => {
|
state.canvasV2.present.controlLayers.entities.forEach((entity) => {
|
||||||
const isModelAvailable = caModels.some((m) => m.key === entity.controlAdapter.model?.key);
|
const isModelAvailable = caModels.some((m) => m.key === entity.controlAdapter.model?.key);
|
||||||
if (isModelAvailable) {
|
if (isModelAvailable) {
|
||||||
return;
|
return;
|
||||||
@ -183,7 +183,7 @@ const handleControlAdapterModels: ModelHandler = (models, state, dispatch, _log)
|
|||||||
|
|
||||||
const handleIPAdapterModels: ModelHandler = (models, state, dispatch, _log) => {
|
const handleIPAdapterModels: ModelHandler = (models, state, dispatch, _log) => {
|
||||||
const ipaModels = models.filter(isIPAdapterModelConfig);
|
const ipaModels = models.filter(isIPAdapterModelConfig);
|
||||||
state.canvasV2.ipAdapters.entities.forEach((entity) => {
|
state.canvasV2.present.ipAdapters.entities.forEach((entity) => {
|
||||||
const isModelAvailable = ipaModels.some((m) => m.key === entity.ipAdapter.model?.key);
|
const isModelAvailable = ipaModels.some((m) => m.key === entity.ipAdapter.model?.key);
|
||||||
if (isModelAvailable) {
|
if (isModelAvailable) {
|
||||||
return;
|
return;
|
||||||
@ -191,7 +191,7 @@ const handleIPAdapterModels: ModelHandler = (models, state, dispatch, _log) => {
|
|||||||
dispatch(ipaModelChanged({ entityIdentifier: getEntityIdentifier(entity), modelConfig: null }));
|
dispatch(ipaModelChanged({ entityIdentifier: getEntityIdentifier(entity), modelConfig: null }));
|
||||||
});
|
});
|
||||||
|
|
||||||
state.canvasV2.regions.entities.forEach((entity) => {
|
state.canvasV2.present.regions.entities.forEach((entity) => {
|
||||||
entity.ipAdapters.forEach(({ id: ipAdapterId, model }) => {
|
entity.ipAdapters.forEach(({ id: ipAdapterId, model }) => {
|
||||||
const isModelAvailable = ipaModels.some((m) => m.key === model?.key);
|
const isModelAvailable = ipaModels.some((m) => m.key === model?.key);
|
||||||
if (isModelAvailable) {
|
if (isModelAvailable) {
|
||||||
|
@ -58,7 +58,7 @@ const allReducers = {
|
|||||||
[queueSlice.name]: queueSlice.reducer,
|
[queueSlice.name]: queueSlice.reducer,
|
||||||
[workflowSlice.name]: workflowSlice.reducer,
|
[workflowSlice.name]: workflowSlice.reducer,
|
||||||
[hrfSlice.name]: hrfSlice.reducer,
|
[hrfSlice.name]: hrfSlice.reducer,
|
||||||
[canvasV2Slice.name]: canvasV2Slice.reducer,
|
[canvasV2Slice.name]: undoable(canvasV2Slice.reducer),
|
||||||
[workflowSettingsSlice.name]: workflowSettingsSlice.reducer,
|
[workflowSettingsSlice.name]: workflowSettingsSlice.reducer,
|
||||||
[upscaleSlice.name]: upscaleSlice.reducer,
|
[upscaleSlice.name]: upscaleSlice.reducer,
|
||||||
[stylePresetSlice.name]: stylePresetSlice.reducer,
|
[stylePresetSlice.name]: stylePresetSlice.reducer,
|
||||||
|
@ -9,7 +9,7 @@ export const ControlLayerBadges = memo(() => {
|
|||||||
const entityIdentifier = useEntityIdentifierContext('control_layer');
|
const entityIdentifier = useEntityIdentifierContext('control_layer');
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const withTransparencyEffect = useAppSelector(
|
const withTransparencyEffect = useAppSelector(
|
||||||
(s) => selectEntityOrThrow(s.canvasV2, entityIdentifier).withTransparencyEffect
|
(s) => selectEntityOrThrow(s.canvasV2.present, entityIdentifier).withTransparencyEffect
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -11,7 +11,7 @@ const selectEntityIds = createMemoizedSelector(selectCanvasV2Slice, (canvasV2) =
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const ControlLayerEntityList = memo(() => {
|
export const ControlLayerEntityList = memo(() => {
|
||||||
const isSelected = useAppSelector((s) => Boolean(s.canvasV2.selectedEntityIdentifier?.type === 'control_layer'));
|
const isSelected = useAppSelector((s) => Boolean(s.canvasV2.present.selectedEntityIdentifier?.type === 'control_layer'));
|
||||||
const layerIds = useAppSelector(selectEntityIds);
|
const layerIds = useAppSelector(selectEntityIds);
|
||||||
|
|
||||||
if (layerIds.length === 0) {
|
if (layerIds.length === 0) {
|
||||||
|
@ -13,7 +13,7 @@ export const HeadsUpDisplay = memo(() => {
|
|||||||
const isMouseDown = useStore(canvasManager.stateApi.$isMouseDown);
|
const isMouseDown = useStore(canvasManager.stateApi.$isMouseDown);
|
||||||
const lastMouseDownPos = useStore(canvasManager.stateApi.$lastMouseDownPos);
|
const lastMouseDownPos = useStore(canvasManager.stateApi.$lastMouseDownPos);
|
||||||
const lastAddedPoint = useStore(canvasManager.stateApi.$lastAddedPoint);
|
const lastAddedPoint = useStore(canvasManager.stateApi.$lastAddedPoint);
|
||||||
const bbox = useAppSelector((s) => s.canvasV2.bbox);
|
const bbox = useAppSelector((s) => s.canvasV2.present.bbox);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex flexDir="column" bg="blackAlpha.400" borderBottomEndRadius="base" p={2} minW={64} gap={2}>
|
<Flex flexDir="column" bg="blackAlpha.400" borderBottomEndRadius="base" p={2} minW={64} gap={2}>
|
||||||
|
@ -12,7 +12,7 @@ const selectEntityIds = createMemoizedSelector(selectCanvasV2Slice, (canvasV2) =
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const IPAdapterList = memo(() => {
|
export const IPAdapterList = memo(() => {
|
||||||
const isSelected = useAppSelector((s) => Boolean(s.canvasV2.selectedEntityIdentifier?.type === 'ip_adapter'));
|
const isSelected = useAppSelector((s) => Boolean(s.canvasV2.present.selectedEntityIdentifier?.type === 'ip_adapter'));
|
||||||
const ipaIds = useAppSelector(selectEntityIds);
|
const ipaIds = useAppSelector(selectEntityIds);
|
||||||
|
|
||||||
if (ipaIds.length === 0) {
|
if (ipaIds.length === 0) {
|
||||||
|
@ -25,7 +25,7 @@ import { IPAdapterModel } from './IPAdapterModel';
|
|||||||
export const IPAdapterSettings = memo(() => {
|
export const IPAdapterSettings = memo(() => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const entityIdentifier = useEntityIdentifierContext('ip_adapter');
|
const entityIdentifier = useEntityIdentifierContext('ip_adapter');
|
||||||
const ipAdapter = useAppSelector((s) => selectEntityOrThrow(s.canvasV2, entityIdentifier).ipAdapter);
|
const ipAdapter = useAppSelector((s) => selectEntityOrThrow(s.canvasV2.present, entityIdentifier).ipAdapter);
|
||||||
|
|
||||||
const onChangeBeginEndStepPct = useCallback(
|
const onChangeBeginEndStepPct = useCallback(
|
||||||
(beginEndStepPct: [number, number]) => {
|
(beginEndStepPct: [number, number]) => {
|
||||||
|
@ -11,7 +11,7 @@ const selectEntityIds = createMemoizedSelector(selectCanvasV2Slice, (canvasV2) =
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const InpaintMaskList = memo(() => {
|
export const InpaintMaskList = memo(() => {
|
||||||
const isSelected = useAppSelector((s) => Boolean(s.canvasV2.selectedEntityIdentifier?.type === 'inpaint_mask'));
|
const isSelected = useAppSelector((s) => Boolean(s.canvasV2.present.selectedEntityIdentifier?.type === 'inpaint_mask'));
|
||||||
const entityIds = useAppSelector(selectEntityIds);
|
const entityIds = useAppSelector(selectEntityIds);
|
||||||
|
|
||||||
if (entityIds.length === 0) {
|
if (entityIds.length === 0) {
|
||||||
|
@ -14,7 +14,7 @@ export const InpaintMaskMaskFillColorPicker = memo(() => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const entityIdentifier = useEntityIdentifierContext('inpaint_mask');
|
const entityIdentifier = useEntityIdentifierContext('inpaint_mask');
|
||||||
const fill = useAppSelector((s) => selectEntityOrThrow(s.canvasV2, entityIdentifier).fill);
|
const fill = useAppSelector((s) => selectEntityOrThrow(s.canvasV2.present, entityIdentifier).fill);
|
||||||
|
|
||||||
const onChangeFillColor = useCallback(
|
const onChangeFillColor = useCallback(
|
||||||
(color: RgbColor) => {
|
(color: RgbColor) => {
|
||||||
|
@ -11,7 +11,7 @@ const selectEntityIds = createMemoizedSelector(selectCanvasV2Slice, (canvasV2) =
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const RasterLayerEntityList = memo(() => {
|
export const RasterLayerEntityList = memo(() => {
|
||||||
const isSelected = useAppSelector((s) => Boolean(s.canvasV2.selectedEntityIdentifier?.type === 'raster_layer'));
|
const isSelected = useAppSelector((s) => Boolean(s.canvasV2.present.selectedEntityIdentifier?.type === 'raster_layer'));
|
||||||
const layerIds = useAppSelector(selectEntityIds);
|
const layerIds = useAppSelector(selectEntityIds);
|
||||||
|
|
||||||
if (layerIds.length === 0) {
|
if (layerIds.length === 0) {
|
||||||
|
@ -8,7 +8,7 @@ import { useTranslation } from 'react-i18next';
|
|||||||
export const RegionalGuidanceBadges = memo(() => {
|
export const RegionalGuidanceBadges = memo(() => {
|
||||||
const entityIdentifier = useEntityIdentifierContext('regional_guidance');
|
const entityIdentifier = useEntityIdentifierContext('regional_guidance');
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const autoNegative = useAppSelector((s) => selectEntityOrThrow(s.canvasV2, entityIdentifier).autoNegative);
|
const autoNegative = useAppSelector((s) => selectEntityOrThrow(s.canvasV2.present, entityIdentifier).autoNegative);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -11,7 +11,7 @@ const selectEntityIds = createMemoizedSelector(selectCanvasV2Slice, (canvasV2) =
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const RegionalGuidanceEntityList = memo(() => {
|
export const RegionalGuidanceEntityList = memo(() => {
|
||||||
const isSelected = useAppSelector((s) => Boolean(s.canvasV2.selectedEntityIdentifier?.type === 'regional_guidance'));
|
const isSelected = useAppSelector((s) => Boolean(s.canvasV2.present.selectedEntityIdentifier?.type === 'regional_guidance'));
|
||||||
const rgIds = useAppSelector(selectEntityIds);
|
const rgIds = useAppSelector(selectEntityIds);
|
||||||
|
|
||||||
if (rgIds.length === 0) {
|
if (rgIds.length === 0) {
|
||||||
|
@ -35,7 +35,7 @@ export const RegionalGuidanceIPAdapterSettings = memo(({ ipAdapterId, ipAdapterN
|
|||||||
dispatch(rgIPAdapterDeleted({ entityIdentifier, ipAdapterId }));
|
dispatch(rgIPAdapterDeleted({ entityIdentifier, ipAdapterId }));
|
||||||
}, [dispatch, entityIdentifier, ipAdapterId]);
|
}, [dispatch, entityIdentifier, ipAdapterId]);
|
||||||
const ipAdapter = useAppSelector((s) => {
|
const ipAdapter = useAppSelector((s) => {
|
||||||
const ipa = selectRegionalGuidanceIPAdapter(s.canvasV2, entityIdentifier, ipAdapterId);
|
const ipa = selectRegionalGuidanceIPAdapter(s.canvasV2.present, entityIdentifier, ipAdapterId);
|
||||||
assert(ipa, `Regional GuidanceIP Adapter with id ${ipAdapterId} not found`);
|
assert(ipa, `Regional GuidanceIP Adapter with id ${ipAdapterId} not found`);
|
||||||
return ipa;
|
return ipa;
|
||||||
});
|
});
|
||||||
|
@ -14,7 +14,7 @@ export const RegionalGuidanceMaskFillColorPicker = memo(() => {
|
|||||||
const entityIdentifier = useEntityIdentifierContext('regional_guidance');
|
const entityIdentifier = useEntityIdentifierContext('regional_guidance');
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const fill = useAppSelector((s) => selectEntityOrThrow(s.canvasV2, entityIdentifier).fill);
|
const fill = useAppSelector((s) => selectEntityOrThrow(s.canvasV2.present, entityIdentifier).fill);
|
||||||
const onChangeFillColor = useCallback(
|
const onChangeFillColor = useCallback(
|
||||||
(color: RgbColor) => {
|
(color: RgbColor) => {
|
||||||
dispatch(rgFillColorChanged({ entityIdentifier, color }));
|
dispatch(rgFillColorChanged({ entityIdentifier, color }));
|
||||||
|
@ -11,7 +11,7 @@ export const RegionalGuidanceMenuItemsAutoNegative = memo(() => {
|
|||||||
const entityIdentifier = useEntityIdentifierContext('regional_guidance');
|
const entityIdentifier = useEntityIdentifierContext('regional_guidance');
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const autoNegative = useAppSelector((s) => selectEntityOrThrow(s.canvasV2, entityIdentifier).autoNegative);
|
const autoNegative = useAppSelector((s) => selectEntityOrThrow(s.canvasV2.present, entityIdentifier).autoNegative);
|
||||||
const onClick = useCallback(() => {
|
const onClick = useCallback(() => {
|
||||||
dispatch(rgAutoNegativeToggled({ entityIdentifier }));
|
dispatch(rgAutoNegativeToggled({ entityIdentifier }));
|
||||||
}, [dispatch, entityIdentifier]);
|
}, [dispatch, entityIdentifier]);
|
||||||
|
@ -13,7 +13,7 @@ import { useTranslation } from 'react-i18next';
|
|||||||
|
|
||||||
export const RegionalGuidanceNegativePrompt = memo(() => {
|
export const RegionalGuidanceNegativePrompt = memo(() => {
|
||||||
const entityIdentifier = useEntityIdentifierContext('regional_guidance');
|
const entityIdentifier = useEntityIdentifierContext('regional_guidance');
|
||||||
const prompt = useAppSelector((s) => selectEntityOrThrow(s.canvasV2, entityIdentifier).negativePrompt ?? '');
|
const prompt = useAppSelector((s) => selectEntityOrThrow(s.canvasV2.present, entityIdentifier).negativePrompt ?? '');
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
@ -13,7 +13,7 @@ import { useTranslation } from 'react-i18next';
|
|||||||
|
|
||||||
export const RegionalGuidancePositivePrompt = memo(() => {
|
export const RegionalGuidancePositivePrompt = memo(() => {
|
||||||
const entityIdentifier = useEntityIdentifierContext('regional_guidance');
|
const entityIdentifier = useEntityIdentifierContext('regional_guidance');
|
||||||
const prompt = useAppSelector((s) => selectEntityOrThrow(s.canvasV2, entityIdentifier).positivePrompt ?? '');
|
const prompt = useAppSelector((s) => selectEntityOrThrow(s.canvasV2.present, entityIdentifier).positivePrompt ?? '');
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
@ -13,12 +13,12 @@ import { RegionalGuidancePositivePrompt } from './RegionalGuidancePositivePrompt
|
|||||||
export const RegionalGuidanceSettings = memo(() => {
|
export const RegionalGuidanceSettings = memo(() => {
|
||||||
const entityIdentifier = useEntityIdentifierContext('regional_guidance');
|
const entityIdentifier = useEntityIdentifierContext('regional_guidance');
|
||||||
const hasPositivePrompt = useAppSelector(
|
const hasPositivePrompt = useAppSelector(
|
||||||
(s) => selectEntityOrThrow(s.canvasV2, entityIdentifier).positivePrompt !== null
|
(s) => selectEntityOrThrow(s.canvasV2.present, entityIdentifier).positivePrompt !== null
|
||||||
);
|
);
|
||||||
const hasNegativePrompt = useAppSelector(
|
const hasNegativePrompt = useAppSelector(
|
||||||
(s) => selectEntityOrThrow(s.canvasV2, entityIdentifier).negativePrompt !== null
|
(s) => selectEntityOrThrow(s.canvasV2.present, entityIdentifier).negativePrompt !== null
|
||||||
);
|
);
|
||||||
const hasIPAdapters = useAppSelector((s) => selectEntityOrThrow(s.canvasV2, entityIdentifier).ipAdapters.length > 0);
|
const hasIPAdapters = useAppSelector((s) => selectEntityOrThrow(s.canvasV2.present, entityIdentifier).ipAdapters.length > 0);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CanvasEntitySettingsWrapper>
|
<CanvasEntitySettingsWrapper>
|
||||||
|
@ -17,10 +17,10 @@ export const ToolBrushButton = memo(() => {
|
|||||||
const selectBrush = useSelectTool('brush');
|
const selectBrush = useSelectTool('brush');
|
||||||
const isSelected = useToolIsSelected('brush');
|
const isSelected = useToolIsSelected('brush');
|
||||||
const isDrawingToolAllowed = useAppSelector((s) => {
|
const isDrawingToolAllowed = useAppSelector((s) => {
|
||||||
if (!s.canvasV2.selectedEntityIdentifier?.type) {
|
if (!s.canvasV2.present.selectedEntityIdentifier?.type) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return isDrawableEntityType(s.canvasV2.selectedEntityIdentifier.type);
|
return isDrawableEntityType(s.canvasV2.present.selectedEntityIdentifier.type);
|
||||||
});
|
});
|
||||||
|
|
||||||
const isDisabled = useMemo(() => {
|
const isDisabled = useMemo(() => {
|
||||||
|
@ -17,10 +17,10 @@ export const ToolEraserButton = memo(() => {
|
|||||||
const selectEraser = useSelectTool('eraser');
|
const selectEraser = useSelectTool('eraser');
|
||||||
const isSelected = useToolIsSelected('eraser');
|
const isSelected = useToolIsSelected('eraser');
|
||||||
const isDrawingToolAllowed = useAppSelector((s) => {
|
const isDrawingToolAllowed = useAppSelector((s) => {
|
||||||
if (!s.canvasV2.selectedEntityIdentifier?.type) {
|
if (!s.canvasV2.present.selectedEntityIdentifier?.type) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return isDrawableEntityType(s.canvasV2.selectedEntityIdentifier.type);
|
return isDrawableEntityType(s.canvasV2.present.selectedEntityIdentifier.type);
|
||||||
});
|
});
|
||||||
const isDisabled = useMemo(() => {
|
const isDisabled = useMemo(() => {
|
||||||
return isTransforming || isFiltering || isStaging || !isDrawingToolAllowed;
|
return isTransforming || isFiltering || isStaging || !isDrawingToolAllowed;
|
||||||
|
@ -17,10 +17,10 @@ export const ToolMoveButton = memo(() => {
|
|||||||
const isSelected = useToolIsSelected('move');
|
const isSelected = useToolIsSelected('move');
|
||||||
const isStaging = useAppSelector((s) => s.canvasSession.isStaging);
|
const isStaging = useAppSelector((s) => s.canvasSession.isStaging);
|
||||||
const isDrawingToolAllowed = useAppSelector((s) => {
|
const isDrawingToolAllowed = useAppSelector((s) => {
|
||||||
if (!s.canvasV2.selectedEntityIdentifier?.type) {
|
if (!s.canvasV2.present.selectedEntityIdentifier?.type) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return isDrawableEntityType(s.canvasV2.selectedEntityIdentifier.type);
|
return isDrawableEntityType(s.canvasV2.present.selectedEntityIdentifier.type);
|
||||||
});
|
});
|
||||||
const isDisabled = useMemo(() => {
|
const isDisabled = useMemo(() => {
|
||||||
return isTransforming || isFiltering || isStaging || !isDrawingToolAllowed;
|
return isTransforming || isFiltering || isStaging || !isDrawingToolAllowed;
|
||||||
|
@ -17,10 +17,10 @@ export const ToolRectButton = memo(() => {
|
|||||||
const isTransforming = useIsTransforming();
|
const isTransforming = useIsTransforming();
|
||||||
const isStaging = useAppSelector((s) => s.canvasSession.isStaging);
|
const isStaging = useAppSelector((s) => s.canvasSession.isStaging);
|
||||||
const isDrawingToolAllowed = useAppSelector((s) => {
|
const isDrawingToolAllowed = useAppSelector((s) => {
|
||||||
if (!s.canvasV2.selectedEntityIdentifier?.type) {
|
if (!s.canvasV2.present.selectedEntityIdentifier?.type) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return isDrawableEntityType(s.canvasV2.selectedEntityIdentifier.type);
|
return isDrawableEntityType(s.canvasV2.present.selectedEntityIdentifier.type);
|
||||||
});
|
});
|
||||||
|
|
||||||
const isDisabled = useMemo(() => {
|
const isDisabled = useMemo(() => {
|
||||||
|
@ -5,22 +5,25 @@ import { memo, useCallback } from 'react';
|
|||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { PiArrowClockwiseBold, PiArrowCounterClockwiseBold } from 'react-icons/pi';
|
import { PiArrowClockwiseBold, PiArrowCounterClockwiseBold } from 'react-icons/pi';
|
||||||
|
import { useDispatch } from 'react-redux';
|
||||||
|
import { ActionCreators } from 'redux-undo';
|
||||||
|
|
||||||
export const UndoRedoButtonGroup = memo(() => {
|
export const UndoRedoButtonGroup = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const mayUndo = useAppSelector(() => false);
|
const mayUndo = useAppSelector(() => true);
|
||||||
const handleUndo = useCallback(() => {
|
const handleUndo = useCallback(() => {
|
||||||
// TODO(psyche): Implement undo
|
// TODO(psyche): Implement undo
|
||||||
// dispatch(undo());
|
dispatch(ActionCreators.undo());
|
||||||
}, []);
|
}, [dispatch]);
|
||||||
useHotkeys(['meta+z', 'ctrl+z'], handleUndo, { enabled: mayUndo, preventDefault: true }, [mayUndo, handleUndo]);
|
useHotkeys(['meta+z', 'ctrl+z'], handleUndo, { enabled: mayUndo, preventDefault: true }, [mayUndo, handleUndo]);
|
||||||
|
|
||||||
const mayRedo = useAppSelector(() => false);
|
const mayRedo = useAppSelector(() => true);
|
||||||
const handleRedo = useCallback(() => {
|
const handleRedo = useCallback(() => {
|
||||||
// TODO(psyche): Implement redo
|
// TODO(psyche): Implement redo
|
||||||
// dispatch(redo());
|
dispatch(ActionCreators.redo());
|
||||||
}, []);
|
}, [dispatch]);
|
||||||
useHotkeys(['meta+shift+z', 'ctrl+shift+z'], handleRedo, { enabled: mayRedo, preventDefault: true }, [
|
useHotkeys(['meta+shift+z', 'ctrl+shift+z'], handleRedo, { enabled: mayRedo, preventDefault: true }, [
|
||||||
mayRedo,
|
mayRedo,
|
||||||
handleRedo,
|
handleRedo,
|
||||||
|
@ -59,13 +59,13 @@ const snapCandidates = marks.slice(1, marks.length - 1);
|
|||||||
export const CanvasEntityOpacity = memo(() => {
|
export const CanvasEntityOpacity = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const selectedEntityIdentifier = useAppSelector((s) => s.canvasV2.selectedEntityIdentifier);
|
const selectedEntityIdentifier = useAppSelector((s) => s.canvasV2.present.selectedEntityIdentifier);
|
||||||
const opacity = useAppSelector((s) => {
|
const opacity = useAppSelector((s) => {
|
||||||
const selectedEntityIdentifier = s.canvasV2.selectedEntityIdentifier;
|
const selectedEntityIdentifier = s.canvasV2.present.selectedEntityIdentifier;
|
||||||
if (!selectedEntityIdentifier) {
|
if (!selectedEntityIdentifier) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const selectedEntity = selectEntity(s.canvasV2, selectedEntityIdentifier);
|
const selectedEntity = selectEntity(s.canvasV2.present, selectedEntityIdentifier);
|
||||||
if (!selectedEntity) {
|
if (!selectedEntity) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ import type { CanvasEntityIdentifier } from 'features/controlLayers/store/types'
|
|||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
export const useEntityIsSelected = (entityIdentifier: CanvasEntityIdentifier) => {
|
export const useEntityIsSelected = (entityIdentifier: CanvasEntityIdentifier) => {
|
||||||
const selectedEntityIdentifier = useAppSelector((s) => s.canvasV2.selectedEntityIdentifier);
|
const selectedEntityIdentifier = useAppSelector((s) => s.canvasV2.present.selectedEntityIdentifier);
|
||||||
const isSelected = useMemo(() => {
|
const isSelected = useMemo(() => {
|
||||||
return selectedEntityIdentifier?.id === entityIdentifier.id;
|
return selectedEntityIdentifier?.id === entityIdentifier.id;
|
||||||
}, [selectedEntityIdentifier, entityIdentifier.id]);
|
}, [selectedEntityIdentifier, entityIdentifier.id]);
|
||||||
|
@ -100,7 +100,7 @@ export class CanvasStateApiModule extends CanvasModuleBase {
|
|||||||
|
|
||||||
// Reminder - use arrow functions to avoid binding issues
|
// Reminder - use arrow functions to avoid binding issues
|
||||||
getCanvasState = () => {
|
getCanvasState = () => {
|
||||||
return this.store.getState().canvasV2;
|
return this.store.getState().canvasV2.present;
|
||||||
};
|
};
|
||||||
resetEntity = (arg: EntityIdentifierPayload) => {
|
resetEntity = (arg: EntityIdentifierPayload) => {
|
||||||
this.store.dispatch(entityReset(arg));
|
this.store.dispatch(entityReset(arg));
|
||||||
|
@ -16,7 +16,7 @@ import { assert } from 'tsafe';
|
|||||||
/**
|
/**
|
||||||
* Selects the canvasV2 slice from the root state
|
* Selects the canvasV2 slice from the root state
|
||||||
*/
|
*/
|
||||||
export const selectCanvasV2Slice = (state: RootState) => state.canvasV2;
|
export const selectCanvasV2Slice = (state: RootState) => state.canvasV2.present;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Selects the total canvas entity count:
|
* Selects the total canvas entity count:
|
||||||
|
@ -22,7 +22,7 @@ export const addInpaint = async (
|
|||||||
denoise.denoising_start = denoising_start;
|
denoise.denoising_start = denoising_start;
|
||||||
|
|
||||||
const { params, canvasV2, canvasSession } = state;
|
const { params, canvasV2, canvasSession } = state;
|
||||||
const { bbox } = canvasV2;
|
const { bbox } = canvasV2.present;
|
||||||
const { mode } = canvasSession;
|
const { mode } = canvasSession;
|
||||||
|
|
||||||
const initialImage = await manager.compositor.getCompositeRasterLayerImageDTO(bbox.rect);
|
const initialImage = await manager.compositor.getCompositeRasterLayerImageDTO(bbox.rect);
|
||||||
|
@ -23,7 +23,7 @@ export const addOutpaint = async (
|
|||||||
denoise.denoising_start = denoising_start;
|
denoise.denoising_start = denoising_start;
|
||||||
|
|
||||||
const { params, canvasV2, canvasSession } = state;
|
const { params, canvasV2, canvasSession } = state;
|
||||||
const { bbox } = canvasV2;
|
const { bbox } = canvasV2.present;
|
||||||
const { mode } = canvasSession;
|
const { mode } = canvasSession;
|
||||||
|
|
||||||
const initialImage = await manager.compositor.getCompositeRasterLayerImageDTO(bbox.rect);
|
const initialImage = await manager.compositor.getCompositeRasterLayerImageDTO(bbox.rect);
|
||||||
|
@ -32,7 +32,7 @@ export const buildSD1Graph = async (
|
|||||||
log.debug({ generationMode }, 'Building SD1/SD2 graph');
|
log.debug({ generationMode }, 'Building SD1/SD2 graph');
|
||||||
|
|
||||||
const { canvasV2, params, canvasSettings, canvasSession } = state;
|
const { canvasV2, params, canvasSettings, canvasSession } = state;
|
||||||
const { bbox } = canvasV2;
|
const { bbox } = canvasV2.present;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
model,
|
model,
|
||||||
@ -208,9 +208,9 @@ export const buildSD1Graph = async (
|
|||||||
});
|
});
|
||||||
const controlNetResult = await addControlNets(
|
const controlNetResult = await addControlNets(
|
||||||
manager,
|
manager,
|
||||||
state.canvasV2.controlLayers.entities,
|
state.canvasV2.present.controlLayers.entities,
|
||||||
g,
|
g,
|
||||||
state.canvasV2.bbox.rect,
|
state.canvasV2.present.bbox.rect,
|
||||||
controlNetCollector,
|
controlNetCollector,
|
||||||
modelConfig.base
|
modelConfig.base
|
||||||
);
|
);
|
||||||
@ -226,9 +226,9 @@ export const buildSD1Graph = async (
|
|||||||
});
|
});
|
||||||
const t2iAdapterResult = await addT2IAdapters(
|
const t2iAdapterResult = await addT2IAdapters(
|
||||||
manager,
|
manager,
|
||||||
state.canvasV2.controlLayers.entities,
|
state.canvasV2.present.controlLayers.entities,
|
||||||
g,
|
g,
|
||||||
state.canvasV2.bbox.rect,
|
state.canvasV2.present.bbox.rect,
|
||||||
t2iAdapterCollector,
|
t2iAdapterCollector,
|
||||||
modelConfig.base
|
modelConfig.base
|
||||||
);
|
);
|
||||||
@ -242,13 +242,13 @@ export const buildSD1Graph = async (
|
|||||||
type: 'collect',
|
type: 'collect',
|
||||||
id: getPrefixedId('ip_adapter_collector'),
|
id: getPrefixedId('ip_adapter_collector'),
|
||||||
});
|
});
|
||||||
const ipAdapterResult = addIPAdapters(state.canvasV2.ipAdapters.entities, g, ipAdapterCollector, modelConfig.base);
|
const ipAdapterResult = addIPAdapters(state.canvasV2.present.ipAdapters.entities, g, ipAdapterCollector, modelConfig.base);
|
||||||
|
|
||||||
const regionsResult = await addRegions(
|
const regionsResult = await addRegions(
|
||||||
manager,
|
manager,
|
||||||
state.canvasV2.regions.entities,
|
state.canvasV2.present.regions.entities,
|
||||||
g,
|
g,
|
||||||
state.canvasV2.bbox.rect,
|
state.canvasV2.present.bbox.rect,
|
||||||
modelConfig.base,
|
modelConfig.base,
|
||||||
denoise,
|
denoise,
|
||||||
posCond,
|
posCond,
|
||||||
|
@ -32,7 +32,7 @@ export const buildSDXLGraph = async (
|
|||||||
log.debug({ generationMode }, 'Building SDXL graph');
|
log.debug({ generationMode }, 'Building SDXL graph');
|
||||||
|
|
||||||
const { params, canvasV2, canvasSettings, canvasSession } = state;
|
const { params, canvasV2, canvasSettings, canvasSession } = state;
|
||||||
const { bbox } = canvasV2;
|
const { bbox } = canvasV2.present;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
model,
|
model,
|
||||||
@ -211,9 +211,9 @@ export const buildSDXLGraph = async (
|
|||||||
});
|
});
|
||||||
const controlNetResult = await addControlNets(
|
const controlNetResult = await addControlNets(
|
||||||
manager,
|
manager,
|
||||||
state.canvasV2.controlLayers.entities,
|
state.canvasV2.present.controlLayers.entities,
|
||||||
g,
|
g,
|
||||||
state.canvasV2.bbox.rect,
|
state.canvasV2.present.bbox.rect,
|
||||||
controlNetCollector,
|
controlNetCollector,
|
||||||
modelConfig.base
|
modelConfig.base
|
||||||
);
|
);
|
||||||
@ -229,9 +229,9 @@ export const buildSDXLGraph = async (
|
|||||||
});
|
});
|
||||||
const t2iAdapterResult = await addT2IAdapters(
|
const t2iAdapterResult = await addT2IAdapters(
|
||||||
manager,
|
manager,
|
||||||
state.canvasV2.controlLayers.entities,
|
state.canvasV2.present.controlLayers.entities,
|
||||||
g,
|
g,
|
||||||
state.canvasV2.bbox.rect,
|
state.canvasV2.present.bbox.rect,
|
||||||
t2iAdapterCollector,
|
t2iAdapterCollector,
|
||||||
modelConfig.base
|
modelConfig.base
|
||||||
);
|
);
|
||||||
@ -245,13 +245,13 @@ export const buildSDXLGraph = async (
|
|||||||
type: 'collect',
|
type: 'collect',
|
||||||
id: getPrefixedId('ip_adapter_collector'),
|
id: getPrefixedId('ip_adapter_collector'),
|
||||||
});
|
});
|
||||||
const ipAdapterResult = addIPAdapters(state.canvasV2.ipAdapters.entities, g, ipAdapterCollector, modelConfig.base);
|
const ipAdapterResult = addIPAdapters(state.canvasV2.present.ipAdapters.entities, g, ipAdapterCollector, modelConfig.base);
|
||||||
|
|
||||||
const regionsResult = await addRegions(
|
const regionsResult = await addRegions(
|
||||||
manager,
|
manager,
|
||||||
state.canvasV2.regions.entities,
|
state.canvasV2.present.regions.entities,
|
||||||
g,
|
g,
|
||||||
state.canvasV2.bbox.rect,
|
state.canvasV2.present.bbox.rect,
|
||||||
modelConfig.base,
|
modelConfig.base,
|
||||||
denoise,
|
denoise,
|
||||||
posCond,
|
posCond,
|
||||||
|
@ -10,7 +10,7 @@ import { useTranslation } from 'react-i18next';
|
|||||||
const ParamScaleBeforeProcessing = () => {
|
const ParamScaleBeforeProcessing = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const scaleMethod = useAppSelector((s) => s.canvasV2.bbox.scaleMethod);
|
const scaleMethod = useAppSelector((s) => s.canvasV2.present.bbox.scaleMethod);
|
||||||
|
|
||||||
const OPTIONS: ComboboxOption[] = useMemo(
|
const OPTIONS: ComboboxOption[] = useMemo(
|
||||||
() => [
|
() => [
|
||||||
|
@ -9,8 +9,8 @@ const ParamScaledHeight = () => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const optimalDimension = useAppSelector(selectOptimalDimension);
|
const optimalDimension = useAppSelector(selectOptimalDimension);
|
||||||
const isManual = useAppSelector((s) => s.canvasV2.bbox.scaleMethod === 'manual');
|
const isManual = useAppSelector((s) => s.canvasV2.present.bbox.scaleMethod === 'manual');
|
||||||
const height = useAppSelector((s) => s.canvasV2.bbox.scaledSize.height);
|
const height = useAppSelector((s) => s.canvasV2.present.bbox.scaledSize.height);
|
||||||
const sliderMin = useAppSelector((s) => s.config.sd.scaledBoundingBoxHeight.sliderMin);
|
const sliderMin = useAppSelector((s) => s.config.sd.scaledBoundingBoxHeight.sliderMin);
|
||||||
const sliderMax = useAppSelector((s) => s.config.sd.scaledBoundingBoxHeight.sliderMax);
|
const sliderMax = useAppSelector((s) => s.config.sd.scaledBoundingBoxHeight.sliderMax);
|
||||||
const numberInputMin = useAppSelector((s) => s.config.sd.scaledBoundingBoxHeight.numberInputMin);
|
const numberInputMin = useAppSelector((s) => s.config.sd.scaledBoundingBoxHeight.numberInputMin);
|
||||||
|
@ -9,8 +9,8 @@ const ParamScaledWidth = () => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const optimalDimension = useAppSelector(selectOptimalDimension);
|
const optimalDimension = useAppSelector(selectOptimalDimension);
|
||||||
const isManual = useAppSelector((s) => s.canvasV2.bbox.scaleMethod === 'manual');
|
const isManual = useAppSelector((s) => s.canvasV2.present.bbox.scaleMethod === 'manual');
|
||||||
const width = useAppSelector((s) => s.canvasV2.bbox.scaledSize.width);
|
const width = useAppSelector((s) => s.canvasV2.present.bbox.scaledSize.width);
|
||||||
const sliderMin = useAppSelector((s) => s.config.sd.scaledBoundingBoxWidth.sliderMin);
|
const sliderMin = useAppSelector((s) => s.config.sd.scaledBoundingBoxWidth.sliderMin);
|
||||||
const sliderMax = useAppSelector((s) => s.config.sd.scaledBoundingBoxWidth.sliderMax);
|
const sliderMax = useAppSelector((s) => s.config.sd.scaledBoundingBoxWidth.sliderMax);
|
||||||
const numberInputMin = useAppSelector((s) => s.config.sd.scaledBoundingBoxWidth.numberInputMin);
|
const numberInputMin = useAppSelector((s) => s.config.sd.scaledBoundingBoxWidth.numberInputMin);
|
||||||
|
@ -10,7 +10,7 @@ export const ParamHeight = memo(() => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const optimalDimension = useAppSelector(selectOptimalDimension);
|
const optimalDimension = useAppSelector(selectOptimalDimension);
|
||||||
const height = useAppSelector((s) => s.canvasV2.bbox.rect.height);
|
const height = useAppSelector((s) => s.canvasV2.present.bbox.rect.height);
|
||||||
const sliderMin = useAppSelector((s) => s.config.sd.height.sliderMin);
|
const sliderMin = useAppSelector((s) => s.config.sd.height.sliderMin);
|
||||||
const sliderMax = useAppSelector((s) => s.config.sd.height.sliderMax);
|
const sliderMax = useAppSelector((s) => s.config.sd.height.sliderMax);
|
||||||
const numberInputMin = useAppSelector((s) => s.config.sd.height.numberInputMin);
|
const numberInputMin = useAppSelector((s) => s.config.sd.height.numberInputMin);
|
||||||
|
@ -9,7 +9,7 @@ import { useTranslation } from 'react-i18next';
|
|||||||
export const ParamWidth = memo(() => {
|
export const ParamWidth = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const width = useAppSelector((s) => s.canvasV2.bbox.rect.width);
|
const width = useAppSelector((s) => s.canvasV2.present.bbox.rect.width);
|
||||||
const optimalDimension = useAppSelector(selectOptimalDimension);
|
const optimalDimension = useAppSelector(selectOptimalDimension);
|
||||||
const sliderMin = useAppSelector((s) => s.config.sd.width.sliderMin);
|
const sliderMin = useAppSelector((s) => s.config.sd.width.sliderMin);
|
||||||
const sliderMax = useAppSelector((s) => s.config.sd.width.sliderMax);
|
const sliderMax = useAppSelector((s) => s.config.sd.width.sliderMax);
|
||||||
|
@ -12,7 +12,7 @@ import { useTranslation } from 'react-i18next';
|
|||||||
export const AspectRatioSelect = memo(() => {
|
export const AspectRatioSelect = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const id = useAppSelector((s) => s.canvasV2.bbox.aspectRatio.id);
|
const id = useAppSelector((s) => s.canvasV2.present.bbox.aspectRatio.id);
|
||||||
|
|
||||||
const onChange = useCallback(
|
const onChange = useCallback(
|
||||||
(v: SingleValue<ComboboxOption>) => {
|
(v: SingleValue<ComboboxOption>) => {
|
||||||
|
@ -8,7 +8,7 @@ import { PiLockSimpleFill, PiLockSimpleOpenBold } from 'react-icons/pi';
|
|||||||
export const LockAspectRatioButton = memo(() => {
|
export const LockAspectRatioButton = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const isLocked = useAppSelector((s) => s.canvasV2.bbox.aspectRatio.isLocked);
|
const isLocked = useAppSelector((s) => s.canvasV2.present.bbox.aspectRatio.isLocked);
|
||||||
const onClick = useCallback(() => {
|
const onClick = useCallback(() => {
|
||||||
dispatch(bboxAspectRatioLockToggled());
|
dispatch(bboxAspectRatioLockToggled());
|
||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
@ -10,8 +10,8 @@ import { RiSparklingFill } from 'react-icons/ri';
|
|||||||
export const SetOptimalSizeButton = memo(() => {
|
export const SetOptimalSizeButton = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const width = useAppSelector((s) => s.canvasV2.bbox.rect.width);
|
const width = useAppSelector((s) => s.canvasV2.present.bbox.rect.width);
|
||||||
const height = useAppSelector((s) => s.canvasV2.bbox.rect.height);
|
const height = useAppSelector((s) => s.canvasV2.present.bbox.rect.height);
|
||||||
const optimalDimension = useAppSelector(selectOptimalDimension);
|
const optimalDimension = useAppSelector(selectOptimalDimension);
|
||||||
const isSizeTooSmall = useMemo(
|
const isSizeTooSmall = useMemo(
|
||||||
() => getIsSizeTooSmall(width, height, optimalDimension),
|
() => getIsSizeTooSmall(width, height, optimalDimension),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user