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
5a3127949b
commit
757bd62ebe
@ -7,6 +7,7 @@ import { CanvasEntitySettingsWrapper } from 'features/controlLayers/components/c
|
||||
import { CanvasEntityEditableTitle } from 'features/controlLayers/components/common/CanvasEntityTitleEdit';
|
||||
import { ControlLayerControlAdapter } from 'features/controlLayers/components/ControlLayer/ControlLayerControlAdapter';
|
||||
import { EntityIdentifierContext } from 'features/controlLayers/contexts/EntityIdentifierContext';
|
||||
import { EntityLayerAdapterProviderGate } from 'features/controlLayers/hooks/useEntityLayerAdapter';
|
||||
import type { CanvasEntityIdentifier } from 'features/controlLayers/store/types';
|
||||
import { memo, useMemo } from 'react';
|
||||
|
||||
@ -19,17 +20,19 @@ export const ControlLayer = memo(({ id }: Props) => {
|
||||
|
||||
return (
|
||||
<EntityIdentifierContext.Provider value={entityIdentifier}>
|
||||
<CanvasEntityContainer>
|
||||
<CanvasEntityHeader>
|
||||
<CanvasEntityEnabledToggle />
|
||||
<CanvasEntityEditableTitle />
|
||||
<Spacer />
|
||||
<CanvasEntityDeleteButton />
|
||||
</CanvasEntityHeader>
|
||||
<CanvasEntitySettingsWrapper>
|
||||
<ControlLayerControlAdapter />
|
||||
</CanvasEntitySettingsWrapper>
|
||||
</CanvasEntityContainer>
|
||||
<EntityLayerAdapterProviderGate>
|
||||
<CanvasEntityContainer>
|
||||
<CanvasEntityHeader>
|
||||
<CanvasEntityEnabledToggle />
|
||||
<CanvasEntityEditableTitle />
|
||||
<Spacer />
|
||||
<CanvasEntityDeleteButton />
|
||||
</CanvasEntityHeader>
|
||||
<CanvasEntitySettingsWrapper>
|
||||
<ControlLayerControlAdapter />
|
||||
</CanvasEntitySettingsWrapper>
|
||||
</CanvasEntityContainer>
|
||||
</EntityLayerAdapterProviderGate>
|
||||
</EntityIdentifierContext.Provider>
|
||||
);
|
||||
});
|
||||
|
@ -4,6 +4,7 @@ import { CanvasEntityEnabledToggle } from 'features/controlLayers/components/com
|
||||
import { CanvasEntityHeader } from 'features/controlLayers/components/common/CanvasEntityHeader';
|
||||
import { CanvasEntityEditableTitle } from 'features/controlLayers/components/common/CanvasEntityTitleEdit';
|
||||
import { EntityIdentifierContext } from 'features/controlLayers/contexts/EntityIdentifierContext';
|
||||
import { EntityMaskAdapterProviderGate } from 'features/controlLayers/hooks/useEntityMaskAdapter';
|
||||
import type { CanvasEntityIdentifier } from 'features/controlLayers/store/types';
|
||||
import { memo, useMemo } from 'react';
|
||||
|
||||
@ -18,14 +19,16 @@ export const InpaintMask = memo(({ id }: Props) => {
|
||||
|
||||
return (
|
||||
<EntityIdentifierContext.Provider value={entityIdentifier}>
|
||||
<CanvasEntityContainer>
|
||||
<CanvasEntityHeader>
|
||||
<CanvasEntityEnabledToggle />
|
||||
<CanvasEntityEditableTitle />
|
||||
<Spacer />
|
||||
<InpaintMaskMaskFillColorPicker />
|
||||
</CanvasEntityHeader>
|
||||
</CanvasEntityContainer>
|
||||
<EntityMaskAdapterProviderGate>
|
||||
<CanvasEntityContainer>
|
||||
<CanvasEntityHeader>
|
||||
<CanvasEntityEnabledToggle />
|
||||
<CanvasEntityEditableTitle />
|
||||
<Spacer />
|
||||
<InpaintMaskMaskFillColorPicker />
|
||||
</CanvasEntityHeader>
|
||||
</CanvasEntityContainer>
|
||||
</EntityMaskAdapterProviderGate>
|
||||
</EntityIdentifierContext.Provider>
|
||||
);
|
||||
});
|
||||
|
@ -5,6 +5,7 @@ import { CanvasEntityEnabledToggle } from 'features/controlLayers/components/com
|
||||
import { CanvasEntityHeader } from 'features/controlLayers/components/common/CanvasEntityHeader';
|
||||
import { CanvasEntityEditableTitle } from 'features/controlLayers/components/common/CanvasEntityTitleEdit';
|
||||
import { EntityIdentifierContext } from 'features/controlLayers/contexts/EntityIdentifierContext';
|
||||
import { EntityLayerAdapterProviderGate } from 'features/controlLayers/hooks/useEntityLayerAdapter';
|
||||
import type { CanvasEntityIdentifier } from 'features/controlLayers/store/types';
|
||||
import { memo, useMemo } from 'react';
|
||||
|
||||
@ -17,14 +18,16 @@ export const RasterLayer = memo(({ id }: Props) => {
|
||||
|
||||
return (
|
||||
<EntityIdentifierContext.Provider value={entityIdentifier}>
|
||||
<CanvasEntityContainer>
|
||||
<CanvasEntityHeader>
|
||||
<CanvasEntityEnabledToggle />
|
||||
<CanvasEntityEditableTitle />
|
||||
<Spacer />
|
||||
<CanvasEntityDeleteButton />
|
||||
</CanvasEntityHeader>
|
||||
</CanvasEntityContainer>
|
||||
<EntityLayerAdapterProviderGate>
|
||||
<CanvasEntityContainer>
|
||||
<CanvasEntityHeader>
|
||||
<CanvasEntityEnabledToggle />
|
||||
<CanvasEntityEditableTitle />
|
||||
<Spacer />
|
||||
<CanvasEntityDeleteButton />
|
||||
</CanvasEntityHeader>
|
||||
</CanvasEntityContainer>
|
||||
</EntityLayerAdapterProviderGate>
|
||||
</EntityIdentifierContext.Provider>
|
||||
);
|
||||
});
|
||||
|
@ -7,6 +7,7 @@ import { CanvasEntityEditableTitle } from 'features/controlLayers/components/com
|
||||
import { RegionalGuidanceBadges } from 'features/controlLayers/components/RegionalGuidance/RegionalGuidanceBadges';
|
||||
import { RegionalGuidanceSettings } from 'features/controlLayers/components/RegionalGuidance/RegionalGuidanceSettings';
|
||||
import { EntityIdentifierContext } from 'features/controlLayers/contexts/EntityIdentifierContext';
|
||||
import { EntityMaskAdapterProviderGate } from 'features/controlLayers/hooks/useEntityMaskAdapter';
|
||||
import type { CanvasEntityIdentifier } from 'features/controlLayers/store/types';
|
||||
import { memo, useMemo } from 'react';
|
||||
|
||||
@ -22,18 +23,20 @@ export const RegionalGuidance = memo(({ id }: Props) => {
|
||||
|
||||
return (
|
||||
<EntityIdentifierContext.Provider value={entityIdentifier}>
|
||||
<CanvasEntityContainer>
|
||||
<CanvasEntityHeader>
|
||||
<CanvasEntityEnabledToggle />
|
||||
<CanvasEntityEditableTitle />
|
||||
<Spacer />
|
||||
<RegionalGuidanceBadges />
|
||||
<RegionalGuidanceMaskFillColorPicker />
|
||||
<RegionalGuidanceSettingsPopover />
|
||||
<CanvasEntityDeleteButton />
|
||||
</CanvasEntityHeader>
|
||||
<RegionalGuidanceSettings />
|
||||
</CanvasEntityContainer>
|
||||
<EntityMaskAdapterProviderGate>
|
||||
<CanvasEntityContainer>
|
||||
<CanvasEntityHeader>
|
||||
<CanvasEntityEnabledToggle />
|
||||
<CanvasEntityEditableTitle />
|
||||
<Spacer />
|
||||
<RegionalGuidanceBadges />
|
||||
<RegionalGuidanceMaskFillColorPicker />
|
||||
<RegionalGuidanceSettingsPopover />
|
||||
<CanvasEntityDeleteButton />
|
||||
</CanvasEntityHeader>
|
||||
<RegionalGuidanceSettings />
|
||||
</CanvasEntityContainer>
|
||||
</EntityMaskAdapterProviderGate>
|
||||
</EntityIdentifierContext.Provider>
|
||||
);
|
||||
});
|
||||
|
@ -6,12 +6,6 @@ import { assert } from 'tsafe';
|
||||
|
||||
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) => {
|
||||
const canvasManager = useStore($canvasManager);
|
||||
|
||||
@ -23,3 +17,9 @@ export const CanvasManagerProviderGate = memo(({ children }: PropsWithChildren)
|
||||
});
|
||||
|
||||
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 { $canvasManager } from 'features/controlLayers/konva/CanvasManager';
|
||||
import { useCanvasManager } from 'features/controlLayers/contexts/CanvasManagerProviderGate';
|
||||
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 { useMemo } from 'react';
|
||||
import { assert } from 'tsafe';
|
||||
|
||||
export const useEntityAdapter = (entityIdentifier: CanvasEntityIdentifier) => {
|
||||
const canvasManager = useStore($canvasManager);
|
||||
console.log(canvasManager);
|
||||
export const useEntityAdapter = (entityIdentifier: CanvasEntityIdentifier): CanvasLayerAdapter | CanvasMaskAdapter => {
|
||||
const canvasManager = useCanvasManager();
|
||||
|
||||
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…
Reference in New Issue
Block a user