diff --git a/packages/chili-core/src/selectionFilter.ts b/packages/chili-core/src/selectionFilter.ts index ac9890b8..e14e7dcd 100644 --- a/packages/chili-core/src/selectionFilter.ts +++ b/packages/chili-core/src/selectionFilter.ts @@ -1,6 +1,6 @@ // Copyright 2022-2023 the Chili authors. All rights reserved. AGPL-3.0 license. -import { INode } from "./model"; +import { INode, ShapeNode } from "./model"; import { IShape } from "./shape"; export interface IShapeFilter { @@ -10,3 +10,9 @@ export interface IShapeFilter { export interface INodeFilter { allow(node: INode): boolean; } + +export class ShapeNodeFilter implements INodeFilter { + allow(node: INode): boolean { + return node instanceof ShapeNode; + } +} diff --git a/packages/chili-vis/src/nodeSelectionEventHandler.ts b/packages/chili-vis/src/nodeSelectionEventHandler.ts index 7e2b96e1..ae836e74 100644 --- a/packages/chili-vis/src/nodeSelectionEventHandler.ts +++ b/packages/chili-vis/src/nodeSelectionEventHandler.ts @@ -2,7 +2,6 @@ import { AsyncController, - GeometryNode, IDocument, INodeFilter, IView, diff --git a/packages/chili/src/commands/boolean.ts b/packages/chili/src/commands/boolean.ts index 07e00f66..6dca0fcd 100644 --- a/packages/chili/src/commands/boolean.ts +++ b/packages/chili/src/commands/boolean.ts @@ -2,7 +2,7 @@ import { GeometryNode, IShape, Result, ShapeNode, command } from "chili-core"; import { BooleanNode } from "../bodys/boolean"; -import { IStep, SelectNodeStep } from "../step"; +import { IStep, SelectShapeNodeStep } from "../step"; import { CreateCommand } from "./createCommand"; export abstract class BooleanOperate extends CreateCommand { @@ -30,8 +30,8 @@ export abstract class BooleanOperate extends CreateCommand { protected override getSteps(): IStep[] { return [ - new SelectNodeStep("prompt.select.shape", false), - new SelectNodeStep("prompt.select.shape", false, { + new SelectShapeNodeStep("prompt.select.shape", false), + new SelectShapeNodeStep("prompt.select.shape", false, { allow: (shape) => { return !this.stepDatas[0].nodes ?.map((x) => (x as ShapeNode).shape.value) diff --git a/packages/chili/src/commands/create/converter.ts b/packages/chili/src/commands/create/converter.ts index 14e9bbe1..13651083 100644 --- a/packages/chili/src/commands/create/converter.ts +++ b/packages/chili/src/commands/create/converter.ts @@ -17,7 +17,7 @@ import { } from "chili-core"; import { FaceNode } from "../../bodys/face"; import { WireNode } from "../../bodys/wire"; -import { SelectNodeStep } from "../../step"; +import { SelectShapeNodeStep } from "../../step"; abstract class ConvertCommand extends CancelableCommand { async executeAsync(): Promise { @@ -49,7 +49,7 @@ abstract class ConvertCommand extends CancelableCommand { let models = this._getSelectedModels(document, filter); document.selection.clearSelection(); if (models.length > 0) return models; - let step = new SelectNodeStep("prompt.select.models", true, filter); + let step = new SelectShapeNodeStep("prompt.select.models", true, filter); this.controller = new AsyncController(); let data = await step.execute(document, this.controller); document.selection.clearSelection(); diff --git a/packages/chili/src/selection.ts b/packages/chili/src/selection.ts index b26a17d1..0dfe2a42 100644 --- a/packages/chili/src/selection.ts +++ b/packages/chili/src/selection.ts @@ -43,12 +43,9 @@ export class Selection implements ISelection, IDisposable { } async pickNode(prompt: I18nKeys, controller: AsyncController, multiMode: boolean) { - try { - let handler = new NodeSelectionHandler(this.document, multiMode, controller, this.nodeFilter); - await this.pickAsync(handler, prompt, controller, multiMode); - return handler.nodes(); - } finally { - } + let handler = new NodeSelectionHandler(this.document, multiMode, controller, this.nodeFilter); + await this.pickAsync(handler, prompt, controller, multiMode); + return handler.nodes(); } async pickAsync( diff --git a/packages/chili/src/step/selectStep.ts b/packages/chili/src/step/selectStep.ts index c6c2f85d..0877ce69 100644 --- a/packages/chili/src/step/selectStep.ts +++ b/packages/chili/src/step/selectStep.ts @@ -1,6 +1,14 @@ // Copyright 2022-2023 the Chili authors. All rights reserved. AGPL-3.0 license. -import { AsyncController, I18nKeys, IDocument, IShapeFilter, ShapeType } from "chili-core"; +import { + AsyncController, + I18nKeys, + IDocument, + INodeFilter, + IShapeFilter, + ShapeNodeFilter, + ShapeType, +} from "chili-core"; import { SnapedData } from "../snap"; import { IStep } from "./step"; @@ -13,15 +21,15 @@ export abstract class SelectStep implements IStep { ) {} async execute(document: IDocument, controller: AsyncController): Promise { - let oldShapeType = document.selection.shapeType; - let oldFilter = document.selection.shapeFilter; + const { shapeType, shapeFilter, nodeFilter } = document.selection; try { document.selection.shapeType = this.snapeType; document.selection.shapeFilter = this.filter; return await this.select(document, controller); } finally { - document.selection.shapeType = oldShapeType; - document.selection.shapeFilter = oldFilter; + document.selection.shapeType = shapeType; + document.selection.shapeFilter = shapeFilter; + document.selection.nodeFilter = nodeFilter; } } @@ -42,7 +50,7 @@ export class SelectShapeStep extends SelectStep { } } -export class SelectNodeStep extends SelectStep { +export class SelectShapeNodeStep extends SelectStep { constructor(prompt: I18nKeys, multiple: boolean, filter?: IShapeFilter) { super(ShapeType.Shape, prompt, multiple, filter); } @@ -51,12 +59,37 @@ export class SelectNodeStep extends SelectStep { document: IDocument, controller: AsyncController, ): Promise { + document.selection.nodeFilter = new ShapeNodeFilter(); let nodes = await document.selection.pickNode(this.prompt, controller, this.multiple); if (nodes.length === 0) return undefined; return { view: document.application.activeView!, shapes: [], - nodes: nodes, + nodes, }; } } + +export class SelectNodeStep implements IStep { + constructor( + readonly prompt: I18nKeys, + readonly multiple: boolean = false, + readonly filter?: INodeFilter, + ) {} + + async execute(document: IDocument, controller: AsyncController): Promise { + const oldFilter = document.selection.nodeFilter; + try { + document.selection.nodeFilter = this.filter; + let nodes = await document.selection.pickNode(this.prompt, controller, this.multiple); + if (nodes.length === 0) return undefined; + return { + view: document.application.activeView!, + shapes: [], + nodes, + }; + } finally { + document.selection.nodeFilter = oldFilter; + } + } +}