mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): add contexts/hooks to access entity adapters directly
This commit is contained in:
parent
489e875a6e
commit
c9690a4b21
@ -7,6 +7,7 @@ import { CanvasEntitySettingsWrapper } from 'features/controlLayers/components/c
|
|||||||
import { CanvasEntityEditableTitle } from 'features/controlLayers/components/common/CanvasEntityTitleEdit';
|
import { CanvasEntityEditableTitle } from 'features/controlLayers/components/common/CanvasEntityTitleEdit';
|
||||||
import { ControlLayerControlAdapter } from 'features/controlLayers/components/ControlLayer/ControlLayerControlAdapter';
|
import { ControlLayerControlAdapter } from 'features/controlLayers/components/ControlLayer/ControlLayerControlAdapter';
|
||||||
import { EntityIdentifierContext } from 'features/controlLayers/contexts/EntityIdentifierContext';
|
import { EntityIdentifierContext } from 'features/controlLayers/contexts/EntityIdentifierContext';
|
||||||
|
import { EntityLayerAdapterProviderGate } from 'features/controlLayers/hooks/useEntityLayerAdapter';
|
||||||
import type { CanvasEntityIdentifier } from 'features/controlLayers/store/types';
|
import type { CanvasEntityIdentifier } from 'features/controlLayers/store/types';
|
||||||
import { memo, useMemo } from 'react';
|
import { memo, useMemo } from 'react';
|
||||||
|
|
||||||
@ -19,6 +20,7 @@ export const ControlLayer = memo(({ id }: Props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<EntityIdentifierContext.Provider value={entityIdentifier}>
|
<EntityIdentifierContext.Provider value={entityIdentifier}>
|
||||||
|
<EntityLayerAdapterProviderGate>
|
||||||
<CanvasEntityContainer>
|
<CanvasEntityContainer>
|
||||||
<CanvasEntityHeader>
|
<CanvasEntityHeader>
|
||||||
<CanvasEntityEnabledToggle />
|
<CanvasEntityEnabledToggle />
|
||||||
@ -30,6 +32,7 @@ export const ControlLayer = memo(({ id }: Props) => {
|
|||||||
<ControlLayerControlAdapter />
|
<ControlLayerControlAdapter />
|
||||||
</CanvasEntitySettingsWrapper>
|
</CanvasEntitySettingsWrapper>
|
||||||
</CanvasEntityContainer>
|
</CanvasEntityContainer>
|
||||||
|
</EntityLayerAdapterProviderGate>
|
||||||
</EntityIdentifierContext.Provider>
|
</EntityIdentifierContext.Provider>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -4,6 +4,7 @@ import { CanvasEntityEnabledToggle } from 'features/controlLayers/components/com
|
|||||||
import { CanvasEntityHeader } from 'features/controlLayers/components/common/CanvasEntityHeader';
|
import { CanvasEntityHeader } from 'features/controlLayers/components/common/CanvasEntityHeader';
|
||||||
import { CanvasEntityEditableTitle } from 'features/controlLayers/components/common/CanvasEntityTitleEdit';
|
import { CanvasEntityEditableTitle } from 'features/controlLayers/components/common/CanvasEntityTitleEdit';
|
||||||
import { EntityIdentifierContext } from 'features/controlLayers/contexts/EntityIdentifierContext';
|
import { EntityIdentifierContext } from 'features/controlLayers/contexts/EntityIdentifierContext';
|
||||||
|
import { EntityMaskAdapterProviderGate } from 'features/controlLayers/hooks/useEntityMaskAdapter';
|
||||||
import type { CanvasEntityIdentifier } from 'features/controlLayers/store/types';
|
import type { CanvasEntityIdentifier } from 'features/controlLayers/store/types';
|
||||||
import { memo, useMemo } from 'react';
|
import { memo, useMemo } from 'react';
|
||||||
|
|
||||||
@ -18,6 +19,7 @@ export const InpaintMask = memo(({ id }: Props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<EntityIdentifierContext.Provider value={entityIdentifier}>
|
<EntityIdentifierContext.Provider value={entityIdentifier}>
|
||||||
|
<EntityMaskAdapterProviderGate>
|
||||||
<CanvasEntityContainer>
|
<CanvasEntityContainer>
|
||||||
<CanvasEntityHeader>
|
<CanvasEntityHeader>
|
||||||
<CanvasEntityEnabledToggle />
|
<CanvasEntityEnabledToggle />
|
||||||
@ -26,6 +28,7 @@ export const InpaintMask = memo(({ id }: Props) => {
|
|||||||
<InpaintMaskMaskFillColorPicker />
|
<InpaintMaskMaskFillColorPicker />
|
||||||
</CanvasEntityHeader>
|
</CanvasEntityHeader>
|
||||||
</CanvasEntityContainer>
|
</CanvasEntityContainer>
|
||||||
|
</EntityMaskAdapterProviderGate>
|
||||||
</EntityIdentifierContext.Provider>
|
</EntityIdentifierContext.Provider>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -5,6 +5,7 @@ import { CanvasEntityEnabledToggle } from 'features/controlLayers/components/com
|
|||||||
import { CanvasEntityHeader } from 'features/controlLayers/components/common/CanvasEntityHeader';
|
import { CanvasEntityHeader } from 'features/controlLayers/components/common/CanvasEntityHeader';
|
||||||
import { CanvasEntityEditableTitle } from 'features/controlLayers/components/common/CanvasEntityTitleEdit';
|
import { CanvasEntityEditableTitle } from 'features/controlLayers/components/common/CanvasEntityTitleEdit';
|
||||||
import { EntityIdentifierContext } from 'features/controlLayers/contexts/EntityIdentifierContext';
|
import { EntityIdentifierContext } from 'features/controlLayers/contexts/EntityIdentifierContext';
|
||||||
|
import { EntityLayerAdapterProviderGate } from 'features/controlLayers/hooks/useEntityLayerAdapter';
|
||||||
import type { CanvasEntityIdentifier } from 'features/controlLayers/store/types';
|
import type { CanvasEntityIdentifier } from 'features/controlLayers/store/types';
|
||||||
import { memo, useMemo } from 'react';
|
import { memo, useMemo } from 'react';
|
||||||
|
|
||||||
@ -17,6 +18,7 @@ export const RasterLayer = memo(({ id }: Props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<EntityIdentifierContext.Provider value={entityIdentifier}>
|
<EntityIdentifierContext.Provider value={entityIdentifier}>
|
||||||
|
<EntityLayerAdapterProviderGate>
|
||||||
<CanvasEntityContainer>
|
<CanvasEntityContainer>
|
||||||
<CanvasEntityHeader>
|
<CanvasEntityHeader>
|
||||||
<CanvasEntityEnabledToggle />
|
<CanvasEntityEnabledToggle />
|
||||||
@ -25,6 +27,7 @@ export const RasterLayer = memo(({ id }: Props) => {
|
|||||||
<CanvasEntityDeleteButton />
|
<CanvasEntityDeleteButton />
|
||||||
</CanvasEntityHeader>
|
</CanvasEntityHeader>
|
||||||
</CanvasEntityContainer>
|
</CanvasEntityContainer>
|
||||||
|
</EntityLayerAdapterProviderGate>
|
||||||
</EntityIdentifierContext.Provider>
|
</EntityIdentifierContext.Provider>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -7,6 +7,7 @@ import { CanvasEntityEditableTitle } from 'features/controlLayers/components/com
|
|||||||
import { RegionalGuidanceBadges } from 'features/controlLayers/components/RegionalGuidance/RegionalGuidanceBadges';
|
import { RegionalGuidanceBadges } from 'features/controlLayers/components/RegionalGuidance/RegionalGuidanceBadges';
|
||||||
import { RegionalGuidanceSettings } from 'features/controlLayers/components/RegionalGuidance/RegionalGuidanceSettings';
|
import { RegionalGuidanceSettings } from 'features/controlLayers/components/RegionalGuidance/RegionalGuidanceSettings';
|
||||||
import { EntityIdentifierContext } from 'features/controlLayers/contexts/EntityIdentifierContext';
|
import { EntityIdentifierContext } from 'features/controlLayers/contexts/EntityIdentifierContext';
|
||||||
|
import { EntityMaskAdapterProviderGate } from 'features/controlLayers/hooks/useEntityMaskAdapter';
|
||||||
import type { CanvasEntityIdentifier } from 'features/controlLayers/store/types';
|
import type { CanvasEntityIdentifier } from 'features/controlLayers/store/types';
|
||||||
import { memo, useMemo } from 'react';
|
import { memo, useMemo } from 'react';
|
||||||
|
|
||||||
@ -22,6 +23,7 @@ export const RegionalGuidance = memo(({ id }: Props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<EntityIdentifierContext.Provider value={entityIdentifier}>
|
<EntityIdentifierContext.Provider value={entityIdentifier}>
|
||||||
|
<EntityMaskAdapterProviderGate>
|
||||||
<CanvasEntityContainer>
|
<CanvasEntityContainer>
|
||||||
<CanvasEntityHeader>
|
<CanvasEntityHeader>
|
||||||
<CanvasEntityEnabledToggle />
|
<CanvasEntityEnabledToggle />
|
||||||
@ -34,6 +36,7 @@ export const RegionalGuidance = memo(({ id }: Props) => {
|
|||||||
</CanvasEntityHeader>
|
</CanvasEntityHeader>
|
||||||
<RegionalGuidanceSettings />
|
<RegionalGuidanceSettings />
|
||||||
</CanvasEntityContainer>
|
</CanvasEntityContainer>
|
||||||
|
</EntityMaskAdapterProviderGate>
|
||||||
</EntityIdentifierContext.Provider>
|
</EntityIdentifierContext.Provider>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -6,12 +6,6 @@ import { assert } from 'tsafe';
|
|||||||
|
|
||||||
const CanvasManagerContext = createContext<CanvasManager | null>(null);
|
const CanvasManagerContext = createContext<CanvasManager | null>(null);
|
||||||
|
|
||||||
export const useCanvasManager = (): CanvasManager => {
|
|
||||||
const canvasManager = useContext(CanvasManagerContext);
|
|
||||||
assert(canvasManager, 'useCanvasManagerContext must be used within a CanvasManagerContext');
|
|
||||||
return canvasManager;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const CanvasManagerProviderGate = memo(({ children }: PropsWithChildren) => {
|
export const CanvasManagerProviderGate = memo(({ children }: PropsWithChildren) => {
|
||||||
const canvasManager = useStore($canvasManager);
|
const canvasManager = useStore($canvasManager);
|
||||||
|
|
||||||
@ -23,3 +17,9 @@ export const CanvasManagerProviderGate = memo(({ children }: PropsWithChildren)
|
|||||||
});
|
});
|
||||||
|
|
||||||
CanvasManagerProviderGate.displayName = 'CanvasManagerProviderGate';
|
CanvasManagerProviderGate.displayName = 'CanvasManagerProviderGate';
|
||||||
|
|
||||||
|
export const useCanvasManager = (): CanvasManager => {
|
||||||
|
const canvasManager = useContext(CanvasManagerContext);
|
||||||
|
assert(canvasManager, 'useCanvasManagerContext must be used within a CanvasManagerProviderGate');
|
||||||
|
return canvasManager;
|
||||||
|
};
|
||||||
|
@ -1,8 +1,18 @@
|
|||||||
import { useStore } from '@nanostores/react';
|
import { useCanvasManager } from 'features/controlLayers/contexts/CanvasManagerProviderGate';
|
||||||
import { $canvasManager } from 'features/controlLayers/konva/CanvasManager';
|
import type { CanvasLayerAdapter } from 'features/controlLayers/konva/CanvasLayerAdapter';
|
||||||
|
import type { CanvasMaskAdapter } from 'features/controlLayers/konva/CanvasMaskAdapter';
|
||||||
import type { CanvasEntityIdentifier } from 'features/controlLayers/store/types';
|
import type { CanvasEntityIdentifier } from 'features/controlLayers/store/types';
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
import { assert } from 'tsafe';
|
||||||
|
|
||||||
export const useEntityAdapter = (entityIdentifier: CanvasEntityIdentifier) => {
|
export const useEntityAdapter = (entityIdentifier: CanvasEntityIdentifier): CanvasLayerAdapter | CanvasMaskAdapter => {
|
||||||
const canvasManager = useStore($canvasManager);
|
const canvasManager = useCanvasManager();
|
||||||
console.log(canvasManager);
|
|
||||||
|
const adapter = useMemo(() => {
|
||||||
|
const entity = canvasManager.stateApi.getEntity(entityIdentifier);
|
||||||
|
assert(entity, 'Entity adapter not found');
|
||||||
|
return entity.adapter;
|
||||||
|
}, [canvasManager, entityIdentifier]);
|
||||||
|
|
||||||
|
return adapter;
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
import { useCanvasManager } from 'features/controlLayers/contexts/CanvasManagerProviderGate';
|
||||||
|
import { useEntityIdentifierContext } from 'features/controlLayers/contexts/EntityIdentifierContext';
|
||||||
|
import type { CanvasLayerAdapter } from 'features/controlLayers/konva/CanvasLayerAdapter';
|
||||||
|
import type { PropsWithChildren } from 'react';
|
||||||
|
import { createContext, memo, useContext, useMemo } from 'react';
|
||||||
|
import { assert } from 'tsafe';
|
||||||
|
|
||||||
|
const EntityLayerAdapterContext = createContext<CanvasLayerAdapter | null>(null);
|
||||||
|
|
||||||
|
export const EntityLayerAdapterProviderGate = memo(({ children }: PropsWithChildren) => {
|
||||||
|
const entityIdentifier = useEntityIdentifierContext();
|
||||||
|
const canvasManager = useCanvasManager();
|
||||||
|
const adapter = useMemo(() => {
|
||||||
|
if (entityIdentifier.type === 'raster_layer') {
|
||||||
|
return canvasManager.rasterLayerAdapters.get(entityIdentifier.id) ?? null;
|
||||||
|
} else if (entityIdentifier.type === 'control_layer') {
|
||||||
|
return canvasManager.controlLayerAdapters.get(entityIdentifier.id) ?? null;
|
||||||
|
}
|
||||||
|
assert(false, 'EntityLayerAdapterProviderGate must be used with a valid EntityIdentifierContext');
|
||||||
|
}, [canvasManager, entityIdentifier]);
|
||||||
|
|
||||||
|
if (!canvasManager) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <EntityLayerAdapterContext.Provider value={adapter}>{children}</EntityLayerAdapterContext.Provider>;
|
||||||
|
});
|
||||||
|
|
||||||
|
EntityLayerAdapterProviderGate.displayName = 'EntityLayerAdapterProviderGate';
|
||||||
|
|
||||||
|
export const useEntityLayerAdapter = (): CanvasLayerAdapter => {
|
||||||
|
const adapter = useContext(EntityLayerAdapterContext);
|
||||||
|
|
||||||
|
assert(adapter, 'useEntityLayerAdapter must be used within a EntityLayerAdapterProviderGate');
|
||||||
|
|
||||||
|
return adapter;
|
||||||
|
};
|
@ -0,0 +1,37 @@
|
|||||||
|
import { useCanvasManager } from 'features/controlLayers/contexts/CanvasManagerProviderGate';
|
||||||
|
import { useEntityIdentifierContext } from 'features/controlLayers/contexts/EntityIdentifierContext';
|
||||||
|
import type { CanvasMaskAdapter } from 'features/controlLayers/konva/CanvasMaskAdapter';
|
||||||
|
import type { PropsWithChildren } from 'react';
|
||||||
|
import { createContext, memo, useContext, useMemo } from 'react';
|
||||||
|
import { assert } from 'tsafe';
|
||||||
|
|
||||||
|
const EntityMaskAdapterContext = createContext<CanvasMaskAdapter | null>(null);
|
||||||
|
|
||||||
|
export const EntityMaskAdapterProviderGate = memo(({ children }: PropsWithChildren) => {
|
||||||
|
const entityIdentifier = useEntityIdentifierContext();
|
||||||
|
const canvasManager = useCanvasManager();
|
||||||
|
const adapter = useMemo(() => {
|
||||||
|
if (entityIdentifier.type === 'inpaint_mask') {
|
||||||
|
return canvasManager.inpaintMaskAdapters.get(entityIdentifier.id) ?? null;
|
||||||
|
} else if (entityIdentifier.type === 'regional_guidance') {
|
||||||
|
return canvasManager.regionalGuidanceAdapters.get(entityIdentifier.id) ?? null;
|
||||||
|
}
|
||||||
|
assert(false, 'EntityMaskAdapterProviderGate must be used with a valid EntityIdentifierContext');
|
||||||
|
}, [canvasManager, entityIdentifier]);
|
||||||
|
|
||||||
|
if (!canvasManager) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <EntityMaskAdapterContext.Provider value={adapter}>{children}</EntityMaskAdapterContext.Provider>;
|
||||||
|
});
|
||||||
|
|
||||||
|
EntityMaskAdapterProviderGate.displayName = 'EntityMaskAdapterProviderGate';
|
||||||
|
|
||||||
|
export const useEntityMaskAdapter = (): CanvasMaskAdapter => {
|
||||||
|
const adapter = useContext(EntityMaskAdapterContext);
|
||||||
|
|
||||||
|
assert(adapter, 'useEntityMaskAdapter must be used within a EntityLayerAdapterProviderGate');
|
||||||
|
|
||||||
|
return adapter;
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user