feat(ui): make CanvasBboxModule child of CanvasToolModule

This commit is contained in:
psychedelicious
2024-10-22 16:15:48 +10:00
parent dae4591de6
commit 371a1b1af3
6 changed files with 38 additions and 27 deletions

View File

@@ -10,8 +10,8 @@ export const CanvasToolbarFitBboxToLayersButton = memo(() => {
const canvasManager = useCanvasManager();
const isBusy = useCanvasIsBusy();
const onClick = useCallback(() => {
canvasManager.bbox.fitToLayers();
}, [canvasManager.bbox]);
canvasManager.tool.tools.bbox.fitToLayers();
}, [canvasManager.tool.tools.bbox]);
return (
<IconButton

View File

@@ -6,6 +6,7 @@ import {
} from 'common/util/roundDownToMultiple';
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
import { CanvasModuleBase } from 'features/controlLayers/konva/CanvasModuleBase';
import type { CanvasToolModule } from 'features/controlLayers/konva/CanvasTool/CanvasToolModule';
import { getKonvaNodeDebugAttrs, getPrefixedId } from 'features/controlLayers/konva/util';
import { selectBboxOverlay } from 'features/controlLayers/store/canvasSettingsSlice';
import { selectBbox } from 'features/controlLayers/store/selectors';
@@ -35,7 +36,7 @@ export class CanvasBboxModule extends CanvasModuleBase {
readonly type = 'bbox';
readonly id: string;
readonly path: string[];
readonly parent: CanvasManager;
readonly parent: CanvasToolModule;
readonly manager: CanvasManager;
readonly log: Logger;
@@ -61,18 +62,18 @@ export class CanvasBboxModule extends CanvasModuleBase {
*/
$aspectRatioBuffer = atom(1);
constructor(manager: CanvasManager) {
constructor(parent: CanvasToolModule) {
super();
this.id = getPrefixedId(this.type);
this.parent = manager;
this.manager = manager;
this.parent = parent;
this.manager = parent.manager;
this.path = this.manager.buildPath(this);
this.log = this.manager.buildLogger(this);
this.log.debug('Creating bbox module');
this.konva = {
group: new Konva.Group({ name: `${this.type}:group`, listening: true }),
group: new Konva.Group({ name: `${this.type}:group`, listening: false }),
// We will use a Konva.Transformer for the generation bbox. Transformers need some shape to transform, so we will
// create a transparent rect for this purpose.
proxyRect: new Konva.Rect({
@@ -127,6 +128,7 @@ export class CanvasBboxModule extends CanvasModuleBase {
perfectDrawEnabled: false,
}),
transformer: new Konva.Transformer({
listening: false,
name: `${this.type}:transformer`,
borderDash: [5, 5],
borderStroke: 'rgba(212,216,234,1)',
@@ -135,7 +137,6 @@ export class CanvasBboxModule extends CanvasModuleBase {
rotateEnabled: false,
keepRatio: false,
ignoreStroke: true,
listening: false,
flipEnabled: false,
anchorFill: 'rgba(212,216,234,1)',
anchorStroke: 'rgb(42,42,42)',
@@ -161,7 +162,7 @@ export class CanvasBboxModule extends CanvasModuleBase {
this.konva.group.add(this.konva.transformer);
// We will listen to the tool state to determine if the bbox should be visible or not.
this.subscriptions.add(this.manager.tool.$tool.listen(this.render));
this.subscriptions.add(this.parent.$tool.listen(this.render));
// Also listen to redux state to update the bbox's position and dimensions.
this.subscriptions.add(this.manager.stateApi.createStoreSubscription(selectBbox, this.render));
@@ -198,7 +199,7 @@ export class CanvasBboxModule extends CanvasModuleBase {
// We need to reach up to the preview layer to enable/disable listening so that the bbox can be interacted with.
// If the mangaer is busy, we disable listening so the bbox cannot be interacted with.
this.manager.konva.previewLayer.listening(tool === 'bbox' && !this.manager.$isBusy.get());
this.konva.group.listening(tool === 'bbox' && !this.manager.$isBusy.get());
this.konva.proxyRect.setAttrs({
x,

View File

@@ -2,7 +2,6 @@ import { logger } from 'app/logging/logger';
import type { AppStore } from 'app/store/store';
import type { SerializableObject } from 'common/types';
import { SyncableMap } from 'common/util/SyncableMap/SyncableMap';
import { CanvasBboxModule } from 'features/controlLayers/konva/CanvasBboxModule';
import { CanvasCacheModule } from 'features/controlLayers/konva/CanvasCacheModule';
import { CanvasCompositorModule } from 'features/controlLayers/konva/CanvasCompositorModule';
import { CanvasEntityAdapterControlLayer } from 'features/controlLayers/konva/CanvasEntity/CanvasEntityAdapterControlLayer';
@@ -62,7 +61,6 @@ export class CanvasManager extends CanvasModuleBase {
entityRenderer: CanvasEntityRendererModule;
compositor: CanvasCompositorModule;
tool: CanvasToolModule;
bbox: CanvasBboxModule;
stagingArea: CanvasStagingAreaModule;
progressImage: CanvasProgressImageModule;
@@ -124,18 +122,16 @@ export class CanvasManager extends CanvasModuleBase {
this.stage.addLayer(this.background.konva.layer);
this.konva = {
previewLayer: new Konva.Layer({ listening: false, imageSmoothingEnabled: false }),
previewLayer: new Konva.Layer({ listening: true, imageSmoothingEnabled: false }),
};
this.stage.addLayer(this.konva.previewLayer);
this.tool = new CanvasToolModule(this);
this.progressImage = new CanvasProgressImageModule(this);
this.bbox = new CanvasBboxModule(this);
// Must add in this order for correct z-index
this.konva.previewLayer.add(this.stagingArea.konva.group);
this.konva.previewLayer.add(this.progressImage.konva.group);
this.konva.previewLayer.add(this.bbox.konva.group);
this.konva.previewLayer.add(this.tool.konva.group);
}
@@ -233,7 +229,6 @@ export class CanvasManager extends CanvasModuleBase {
getAllModules = (): CanvasModuleBase[] => {
return [
this.bbox,
this.stagingArea,
this.tool,
this.progressImage,
@@ -281,7 +276,6 @@ export class CanvasManager extends CanvasModuleBase {
inpaintMasks: Array.from(this.adapters.inpaintMasks.values()).map((adapter) => adapter.repr()),
regionMasks: Array.from(this.adapters.regionMasks.values()).map((adapter) => adapter.repr()),
stateApi: this.stateApi.repr(),
bbox: this.bbox.repr(),
stagingArea: this.stagingArea.repr(),
tool: this.tool.repr(),
progressImage: this.progressImage.repr(),

View File

@@ -120,6 +120,7 @@ export class CanvasToolColorPicker extends CanvasModuleBase {
this.konva = {
group: new Konva.Group({ name: `${this.type}:color_picker_group`, listening: false }),
ringCandidateColor: new Konva.Ring({
listening: false,
name: `${this.type}:color_picker_candidate_color_ring`,
innerRadius: 0,
outerRadius: 0,
@@ -127,6 +128,7 @@ export class CanvasToolColorPicker extends CanvasModuleBase {
perfectDrawEnabled: false,
}),
ringCurrentColor: new Konva.Arc({
listening: false,
name: `${this.type}:color_picker_current_color_arc`,
innerRadius: 0,
outerRadius: 0,
@@ -135,6 +137,7 @@ export class CanvasToolColorPicker extends CanvasModuleBase {
perfectDrawEnabled: false,
}),
ringInnerBorder: new Konva.Ring({
listening: false,
name: `${this.type}:color_picker_inner_border_ring`,
innerRadius: 0,
outerRadius: 0,
@@ -143,6 +146,7 @@ export class CanvasToolColorPicker extends CanvasModuleBase {
perfectDrawEnabled: false,
}),
ringOuterBorder: new Konva.Ring({
listening: false,
name: `${this.type}:color_picker_outer_border_ring`,
innerRadius: 0,
outerRadius: 0,
@@ -151,41 +155,49 @@ export class CanvasToolColorPicker extends CanvasModuleBase {
perfectDrawEnabled: false,
}),
crosshairNorthInner: new Konva.Line({
listening: false,
name: `${this.type}:color_picker_crosshair_north1_line`,
stroke: this.config.CROSSHAIR_LINE_COLOR,
perfectDrawEnabled: false,
}),
crosshairNorthOuter: new Konva.Line({
listening: false,
name: `${this.type}:color_picker_crosshair_north2_line`,
stroke: this.config.CROSSHAIR_BORDER_COLOR,
perfectDrawEnabled: false,
}),
crosshairEastInner: new Konva.Line({
listening: false,
name: `${this.type}:color_picker_crosshair_east1_line`,
stroke: this.config.CROSSHAIR_LINE_COLOR,
perfectDrawEnabled: false,
}),
crosshairEastOuter: new Konva.Line({
listening: false,
name: `${this.type}:color_picker_crosshair_east2_line`,
stroke: this.config.CROSSHAIR_BORDER_COLOR,
perfectDrawEnabled: false,
}),
crosshairSouthInner: new Konva.Line({
listening: false,
name: `${this.type}:color_picker_crosshair_south1_line`,
stroke: this.config.CROSSHAIR_LINE_COLOR,
perfectDrawEnabled: false,
}),
crosshairSouthOuter: new Konva.Line({
listening: false,
name: `${this.type}:color_picker_crosshair_south2_line`,
stroke: this.config.CROSSHAIR_BORDER_COLOR,
perfectDrawEnabled: false,
}),
crosshairWestInner: new Konva.Line({
listening: false,
name: `${this.type}:color_picker_crosshair_west1_line`,
stroke: this.config.CROSSHAIR_LINE_COLOR,
perfectDrawEnabled: false,
}),
crosshairWestOuter: new Konva.Line({
listening: false,
name: `${this.type}:color_picker_crosshair_west2_line`,
stroke: this.config.CROSSHAIR_BORDER_COLOR,
perfectDrawEnabled: false,

View File

@@ -78,6 +78,7 @@ export class CanvasToolEraser extends CanvasModuleBase {
perfectDrawEnabled: false,
}),
outerBorder: new Konva.Ring({
listening: false,
name: `${this.type}:eraser_outer_border_ring`,
innerRadius: 0,
outerRadius: 0,

View File

@@ -1,3 +1,4 @@
import { CanvasBboxModule } from 'features/controlLayers/konva/CanvasBboxModule';
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
import { CanvasModuleBase } from 'features/controlLayers/konva/CanvasModuleBase';
import { CanvasToolBrush } from 'features/controlLayers/konva/CanvasTool/CanvasToolBrush';
@@ -58,6 +59,7 @@ export class CanvasToolModule extends CanvasModuleBase {
eraser: CanvasToolEraser;
rect: CanvasToolRect;
colorPicker: CanvasToolColorPicker;
bbox: CanvasBboxModule;
};
/**
@@ -111,16 +113,18 @@ export class CanvasToolModule extends CanvasModuleBase {
eraser: new CanvasToolEraser(this),
rect: new CanvasToolRect(this),
colorPicker: new CanvasToolColorPicker(this),
bbox: new CanvasBboxModule(this),
};
this.konva = {
stage: this.manager.stage.konva.stage,
group: new Konva.Group({ name: `${this.type}:group`, listening: false }),
group: new Konva.Group({ name: `${this.type}:group`, listening: true }),
};
this.konva.group.add(this.tools.brush.konva.group);
this.konva.group.add(this.tools.eraser.konva.group);
this.konva.group.add(this.tools.colorPicker.konva.group);
this.konva.group.add(this.tools.bbox.konva.group);
this.subscriptions.add(this.manager.stage.$stageAttrs.listen(this.render));
this.subscriptions.add(this.manager.$isBusy.listen(this.render));
@@ -145,12 +149,6 @@ export class CanvasToolModule extends CanvasModuleBase {
this.syncCursorStyle();
};
setToolVisibility = (tool: Tool, isDrawable: boolean) => {
this.tools.brush.setVisibility(isDrawable && tool === 'brush');
this.tools.eraser.setVisibility(isDrawable && tool === 'eraser');
this.tools.colorPicker.setVisibility(tool === 'colorPicker');
};
syncCursorStyle = () => {
const stage = this.manager.stage;
const tool = this.$tool.get();
@@ -191,6 +189,7 @@ export class CanvasToolModule extends CanvasModuleBase {
this.tools.brush.render();
this.tools.eraser.render();
this.tools.colorPicker.render();
this.tools.bbox.render();
};
syncCursorPositions = () => {
@@ -588,9 +587,13 @@ export class CanvasToolModule extends CanvasModuleBase {
$toolBuffer: this.$toolBuffer.get(),
$isMouseDown: this.$isMouseDown.get(),
$cursorPos: this.$cursorPos.get(),
brushToolPreview: this.tools.brush.repr(),
eraserToolPreview: this.tools.eraser.repr(),
colorPickerToolPreview: this.tools.colorPicker.repr(),
tools: {
brush: this.tools.brush.repr(),
eraser: this.tools.eraser.repr(),
colorPicker: this.tools.colorPicker.repr(),
rect: this.tools.rect.repr(),
bbox: this.tools.bbox.repr(),
},
};
};