diff --git a/src/lib/elements/collections/FillCollection.ts b/src/lib/elements/collections/FillCollection.ts index b8a43183a2abefc074cf8f028349df915e383d8a..df591b46de672727184edbe9408e2915a63fb1a7 100644 --- a/src/lib/elements/collections/FillCollection.ts +++ b/src/lib/elements/collections/FillCollection.ts @@ -18,6 +18,8 @@ import {InteractiveGenerator} from "../../generators/InteractiveGenerator"; import {LegendCollection} from "./LegendCollection"; import {LegendColumnCollection} from "./LegendColumnCollection"; import {NumberElement} from "../interactions/number/NumberElement"; +import {MoveInteraction} from "../../interactions/MoveInteraction"; +import * as Keyboard from "pixi.js-keyboard"; /** * Fill collection @@ -38,7 +40,8 @@ export class FillCollection extends BaseElementContainer<Models.FillCollection> /** * Interactions */ - protected _selectInteraction: SelectInteraction; + private _selectInteraction: SelectInteraction; + private _moveInteraction: MoveInteraction; /** * Elements @@ -149,6 +152,9 @@ export class FillCollection extends BaseElementContainer<Models.FillCollection> this.on("onSelectStart", this._onSelectStart, this); this.on("onInteractive", this._onInteractive, this); // TODO + this.moveInteraction = new MoveInteraction(this); + this.on("onMove", this._onMove, this); + // Elements const buttonSize = this.canvasWidth / this._buttonSizeAspect; @@ -408,6 +414,11 @@ export class FillCollection extends BaseElementContainer<Models.FillCollection> delete this.selectInteraction; } + if (this.moveInteraction) { + this.off("onMove", this._onMove, this); + delete this.moveInteraction; + } + this._colorPicker.off("color", this._onColor, this); // TODO this._lineColorPicker.off("color", this._onLineColor, this); this._strokeWidthElement.off("number", this._onStrokeWidth, this); @@ -659,9 +670,24 @@ export class FillCollection extends BaseElementContainer<Models.FillCollection> // Events this.interactive = true; this.on("pointerover", this.selectInteraction.onHover, this.selectInteraction); - this.on("pointerdown", this._onPointerDown, this); - this.on("pointerup", this._onPointerUp, this); + this.on("pointerover", this.moveInteraction.onMoveHover, this.moveInteraction); + this.on("pointerdown", this.moveInteraction.startMove, this.moveInteraction); + this.on("pointermove", this.moveInteraction.onMove, this.moveInteraction); + this.on("pointerup", this.moveInteraction.endMove, this.moveInteraction); + this.on("startMove", this._startMove, this); + this.on("endMove", this._endMove, this); this.on("onRelease", this._onRelease, this); + + Keyboard.events.on("down_ArrowUp", "onLegendCollectionMoveUp", this.moveInteraction.moveUp.bind(this.moveInteraction)); + Keyboard.events.on("down_ArrowRight", "onLegendCollectionMoveRight", this.moveInteraction.moveRight.bind(this.moveInteraction)); + Keyboard.events.on("down_ArrowDown", "onLegendCollectionMoveDown", this.moveInteraction.moveDown.bind(this.moveInteraction)); + Keyboard.events.on("down_ArrowLeft", "onLegendCollectionMoveLeft", this.moveInteraction.moveLeft.bind(this.moveInteraction)); + Keyboard.events.on("released_ArrowUp", "onLegendCollectionMoveUpEnd", this.moveInteraction.moveRelease.bind(this.moveInteraction)); + Keyboard.events.on("released_ArrowRight", "onLegendCollectionMoveRightEnd", this.moveInteraction.moveRelease.bind(this.moveInteraction)); + Keyboard.events.on("released_ArrowDown", "onLegendCollectionMoveDownEnd", this.moveInteraction.moveRelease.bind(this.moveInteraction)); + Keyboard.events.on("released_ArrowLeft", "onLegendCollectionMoveLeftEnd", this.moveInteraction.moveRelease.bind(this.moveInteraction)); + + this.emit("pointerover", new PIXI.interaction.InteractionEvent()); } protected _removeModeSelect(): void { @@ -670,9 +696,22 @@ export class FillCollection extends BaseElementContainer<Models.FillCollection> // Events this.interactive = false; this.off("pointerover", this.selectInteraction.onHover, this.selectInteraction); - this.off("pointerdown", this._onPointerDown, this); - this.off("pointerup", this._onPointerUp, this); + this.off("pointerover", this.moveInteraction.onMoveHover, this.moveInteraction); + this.off("pointerdown", this.moveInteraction.startMove, this.moveInteraction); + this.off("pointermove", this.moveInteraction.onMove, this.moveInteraction); + this.off("pointerup", this.moveInteraction.onMove, this.moveInteraction); + this.off("startMove", this._startMove, this); + this.off("endMove", this._endMove, this); this.off("onRelease", this._onRelease, this); + + Keyboard.events.remove("down_ArrowUp", "onLegendCollectionMoveUp"); + Keyboard.events.remove("down_ArrowRight", "onLegendCollectionMoveRight"); + Keyboard.events.remove("down_ArrowDown", "onLegendCollectionMoveDown"); + Keyboard.events.remove("down_ArrowLeft", "onLegendCollectionMoveLeft"); + Keyboard.events.remove("released_ArrowUp", "onLegendCollectionMoveUpEnd"); + Keyboard.events.remove("released_ArrowRight", "onLegendCollectionMoveRightEnd"); + Keyboard.events.remove("released_ArrowDown", "onLegendCollectionMoveDownEnd"); + Keyboard.events.remove("released_ArrowLeft", "onLegendCollectionMoveLeftEnd"); } protected _modeBlocked(parent: ImageObject, element: ImageObject): void { @@ -833,6 +872,35 @@ export class FillCollection extends BaseElementContainer<Models.FillCollection> //</editor-fold> //</editor-fold> + //<editor-fold desc="Move"> + protected _startMove(): void { + this.removeChild(this._configurationElement); + + // Events + this.off("pointerover", this.selectInteraction.onHover, this.selectInteraction); + } + + protected _onMove(event: PIXI.interaction.InteractionEvent, dX: number, dY: number): void { + this.lines.forEach((line: Line) => { + if (line.graphicLine.direction === LineDirection.START_END) { + // @ts-ignore + line.graphicLine.start.emit("onMove", event, dX, dY); + } else { + // @ts-ignore + line.graphicLine.end.emit("onMove", event, dX, dY); + } + }); + } + + protected _endMove(event: PIXI.interaction.InteractionEvent): void { + this.addChild(this._configurationElement); + + // Events + this.on("pointerover", this.selectInteraction.onHover, this.selectInteraction); + this.emit("pointerover", event); + } + //</editor-fold> + //<editor-fold desc="Select"> protected _onPointerDown(event: PIXI.interaction.InteractionEvent): void { event.stopPropagation(); @@ -1033,6 +1101,14 @@ export class FillCollection extends BaseElementContainer<Models.FillCollection> this._selectInteraction = value; } + public get moveInteraction(): MoveInteraction { + return this._moveInteraction; + } + + public set moveInteraction(value: MoveInteraction) { + this._moveInteraction = value; + } + public get isInteractive(): boolean { return this.model.isInteractive; } diff --git a/src/lib/elements/collections/LegendCollection.ts b/src/lib/elements/collections/LegendCollection.ts index 92758151e8f676d5620bf40f103cc15b35d9c1f5..724135f4b159f381e3f7f84926404b669bc0b396 100644 --- a/src/lib/elements/collections/LegendCollection.ts +++ b/src/lib/elements/collections/LegendCollection.ts @@ -302,12 +302,6 @@ export class LegendCollection extends BaseElementContainer<Models.LegendCollecti this.modeInteraction.off("remove-draw", this._removeModeDraw, this); this.modeInteraction.off("drawing", this._modeDrawing, this); this.modeInteraction.off("remove-drawing", this._removeModeDrawing, this); - /* TODO remove ??? - this.modeInteraction.off("selftest_choosing", this._modeSelftestChoosing, this); - this.modeInteraction.off("remove-selftest_choosing", this._removeSelftestModeChoosing, this); - this.modeInteraction.off("fill_choosing", this._modeFillChoosing, this); - this.modeInteraction.off("remove-fill_choosing", this._removeFillModeChoosing, this); - */ this.modeInteraction.off("delete", this._modeDelete, this); delete this.modeInteraction; } @@ -318,6 +312,22 @@ export class LegendCollection extends BaseElementContainer<Models.LegendCollecti delete this.selectInteraction; } + if (this.moveInteraction) { + this.off("onMove", this._onMove, this); + delete this.moveInteraction; + } + + if (this.scaleInteraction) { + this.off("onScale", this._onScale, this); + delete this.scaleInteraction; + } + + if (this.rotateInteraction) { + this.off("onRotate", this._onRotate, this); + this.off("lineRotate", this._lineRotate, this); + delete this.rotateInteraction; + } + this._staticButton.off("button", this._onStaticButton, this); this._removeButton.off("button", this._onRemoveButton, this); } @@ -793,6 +803,9 @@ export class LegendCollection extends BaseElementContainer<Models.LegendCollecti //<editor-fold desc="Move"> protected _startMove(): void { + this.rotateContainer.removeChild(this._configurationElement); + + // Events this.off("pointerover", this.selectInteraction.onHover, this.selectInteraction); } @@ -809,6 +822,9 @@ export class LegendCollection extends BaseElementContainer<Models.LegendCollecti } protected _endMove(event: PIXI.interaction.InteractionEvent): void { + this.rotateContainer.addChild(this._configurationElement); + + // Events this.on("pointerover", this.selectInteraction.onHover, this.selectInteraction); this.emit("pointerover", event); } diff --git a/src/lib/elements/interactions/select/SelectElement.ts b/src/lib/elements/interactions/select/SelectElement.ts index 1719ebaf28aea3d44c9f06e01a206e14f4675445..79d3726eb120178525fb1c1c6ff4bdcd47681c6a 100644 --- a/src/lib/elements/interactions/select/SelectElement.ts +++ b/src/lib/elements/interactions/select/SelectElement.ts @@ -1,5 +1,6 @@ import * as PIXI from "pixi.js-legacy"; import {BaseContainer, ImageObject} from "../../../bases/BaseModul"; +import {MoveInteraction} from "../../../interactions/MoveInteraction"; /** * Select element @@ -9,10 +10,16 @@ export class SelectElement extends BaseContainer { * Members */ private _groupImageObjects: string[]; + private _groupImageObjectRefs: ImageObject[]; protected _rectangle: PIXI.Rectangle; protected _lineColor: number; protected _fillColor: number; + /** + * Interactions + */ + private _moveInteraction: MoveInteraction; + /** * Elements */ @@ -42,9 +49,24 @@ export class SelectElement extends BaseContainer { // Setup this.zIndex = 50; this._groupImageObjects = groupImageObjects; + this._groupImageObjectRefs = []; this._lineColor = this._lineColorNormal; this._fillColor = this._fillColorNormal; + // Events + this.interactive = true; + + this.moveInteraction = new MoveInteraction(this); + this.on("pointerover", this.moveInteraction.onMoveHover, this.moveInteraction); + this.on("pointerdown", this.moveInteraction.startMove, this.moveInteraction); + this.on("pointermove", this.moveInteraction.onMove, this.moveInteraction); + this.on("pointerup", this.moveInteraction.endMove, this.moveInteraction); + this.on("pointerupoutside", this.moveInteraction.endMove, this.moveInteraction); + + this.on("startMoveStart", this._onPointerDown, this); + this.on("onMove", this._onMove, this); + this.on("rightup", this._onRightUp, this); + // Elements this._topLineElement = new PIXI.Graphics(); this.addChild(this._topLineElement); @@ -91,6 +113,23 @@ export class SelectElement extends BaseContainer { this.hitArea = this._rectangle; } + + public cleanUp(): void { + this.off("pointerover", this.moveInteraction.onMoveHover, this.moveInteraction); + this.off("pointerdown", this.moveInteraction.startMove, this.moveInteraction); + this.off("pointermove", this.moveInteraction.onMove, this.moveInteraction); + this.off("pointerup", this.moveInteraction.endMove, this.moveInteraction); + this.off("pointerupoutside", this.moveInteraction.endMove, this.moveInteraction); + + this.off("startMoveStart", this._onPointerDown, this); + this.off("onMove", this._onMove, this); + this.off("rightup", this._onRightUp, this); + } + + public destroy(options?: { children?: boolean; texture?: boolean; baseTexture?: boolean }): void { + this.cleanUp(); + super.destroy(options); + } //</editor-fold> //<editor-fold desc="Private functions"> @@ -153,6 +192,17 @@ export class SelectElement extends BaseContainer { this.getImage().allItemReleased(event); } + + protected _onMove(event: PIXI.interaction.InteractionEvent, dX: number, dY: number): void { + this._groupImageObjectRefs.forEach((element: ImageObject) => { + element.emit("onMove", event, dX, dY); + }); + } + + protected _onItemMove(): void { + this._calculateRectangle(); + this.draw(); + } //</editor-fold> //<editor-fold desc="BaseContainer"> @@ -165,8 +215,6 @@ export class SelectElement extends BaseContainer { // Events this.interactive = true; - this.on("pointerdown", this._onPointerDown, this); - this.on("rightup", this._onRightUp, this); } public hideItem(): void { @@ -174,21 +222,42 @@ export class SelectElement extends BaseContainer { // Events this.interactive = false; - this.off("pointerdown", this._onPointerDown, this); - this.off("rightup", this._onRightUp, this); } //</editor-fold> //<editor-fold desc="Getter and Setter"> + public get moveInteraction(): MoveInteraction { + return this._moveInteraction; + } + + public set moveInteraction(value: MoveInteraction) { + this._moveInteraction = value; + } + public get groupImageObjects(): string[] { return this._groupImageObjects; } public set groupImageObjects(value: string[]) { + // Remove old references + this._groupImageObjectRefs.forEach((element: ImageObject) => { + element.off("onMove", this._onItemMove, this); + }); + this._groupImageObjectRefs = []; + + // Setup new values this._groupImageObjects = value; + if (this._groupImageObjects.length > 0) { - this._calculateRectangle(); - this.draw(); + // Add events + this.groupImageObjects.forEach((id: string) => { + const element = this.getImage().getChildByName(id) as ImageObject; + element.on("onMove", this._onItemMove, this); + this._groupImageObjectRefs.push(element); + }); + + // Show selection + this._onItemMove(); } } //</editor-fold> diff --git a/src/lib/elements/positionings/PositionPoint.ts b/src/lib/elements/positionings/PositionPoint.ts index d6619b176130f8fe40e3081fe9c9ebc6d46ed494..e2b1a7e6f5761bcc34f8bfaa22909332bd329cda 100644 --- a/src/lib/elements/positionings/PositionPoint.ts +++ b/src/lib/elements/positionings/PositionPoint.ts @@ -632,9 +632,12 @@ export class PositionPoint extends BaseElementContainer<Models.PositionPoint> { //<editor-fold desc="Move"> protected _startMove(): void { - this.off("pointerover", this.selectInteraction.onHover, this.selectInteraction); this._circle.radius += MOVE_HITTEST_EXTENSION; this._positionPointElement.hitArea = this._circle; + this.removeChild(this._configurationElement); + + // Events + this.off("pointerover", this.selectInteraction.onHover, this.selectInteraction); } protected _onMove(event: PIXI.interaction.InteractionEvent, dX: number, dY: number) { @@ -645,10 +648,13 @@ export class PositionPoint extends BaseElementContainer<Models.PositionPoint> { } protected _endMove(event: PIXI.interaction.InteractionEvent): void { - this.on("pointerover", this.selectInteraction.onHover, this.selectInteraction); - this.emit("pointerover", event); this._circle.radius -= MOVE_HITTEST_EXTENSION; this._positionPointElement.hitArea = this._circle; + this.addChild(this._configurationElement); + + // Events + this.on("pointerover", this.selectInteraction.onHover, this.selectInteraction); + this.emit("pointerover", event); } //</editor-fold> diff --git a/src/lib/elements/primitives/ArrowPrimitive.ts b/src/lib/elements/primitives/ArrowPrimitive.ts index 816612ad02565207fe5b5d726e0f43dfe6100295..a810088a4d368790745eb0c72ef473e78e8f79ff 100644 --- a/src/lib/elements/primitives/ArrowPrimitive.ts +++ b/src/lib/elements/primitives/ArrowPrimitive.ts @@ -753,6 +753,9 @@ export class ArrowPrimitive extends BaseElementContainer<Models.ArrowPrimitive> //<editor-fold desc="Move"> protected _startMove(): void { + this._rotateContainer.removeChild(this._configurationElement); + + // Events this.off("pointerover", this.selectInteraction.onHover, this.selectInteraction); /* TODO check if needed this._rectangle.pad(MOVE_HITTEST_EXTENSION, MOVE_HITTEST_EXTENSION); @@ -785,6 +788,9 @@ export class ArrowPrimitive extends BaseElementContainer<Models.ArrowPrimitive> } protected _endMove(event: PIXI.interaction.InteractionEvent): void { + this._rotateContainer.addChild(this._configurationElement); + + // Events this.on("pointerover", this.selectInteraction.onHover, this.selectInteraction); this.emit("pointerover", event); /* TODO check if needed diff --git a/src/lib/elements/primitives/EllipsePrimitive.ts b/src/lib/elements/primitives/EllipsePrimitive.ts index dbc2d8d539493d53466d686133051589a833f3f9..05a908896b5f4d1cebf21cf1ec0a6e5a27d49e12 100644 --- a/src/lib/elements/primitives/EllipsePrimitive.ts +++ b/src/lib/elements/primitives/EllipsePrimitive.ts @@ -727,6 +727,9 @@ export class EllipsePrimitive extends BaseElementContainer<Models.EllipsePrimiti //<editor-fold desc="Move"> protected _startMove(): void { + this._rotateContainer.removeChild(this._configurationElement); + + // Events this.off("pointerover", this.selectInteraction.onHover, this.selectInteraction); /* TODO check if needed this._rectangle.pad(MOVE_HITTEST_EXTENSION, MOVE_HITTEST_EXTENSION); @@ -746,6 +749,9 @@ export class EllipsePrimitive extends BaseElementContainer<Models.EllipsePrimiti } protected _endMove(event: PIXI.interaction.InteractionEvent): void { + this._rotateContainer.addChild(this._configurationElement); + + // Events this.on("pointerover", this.selectInteraction.onHover, this.selectInteraction); this.emit("pointerover", event); /* TODO check if needed diff --git a/src/lib/elements/primitives/RectanglePrimitive.ts b/src/lib/elements/primitives/RectanglePrimitive.ts index ef4bbe6db9b444a548cb9fe5e36b59769a728d8f..dde27b60157ad3a81a7bc9a34b649043a3ef0cd3 100644 --- a/src/lib/elements/primitives/RectanglePrimitive.ts +++ b/src/lib/elements/primitives/RectanglePrimitive.ts @@ -727,6 +727,9 @@ export class RectanglePrimitive extends BaseElementContainer<Models.RectanglePri //<editor-fold desc="Move"> protected _startMove(): void { + this._rotateContainer.removeChild(this._configurationElement); + + // Events this.off("pointerover", this.selectInteraction.onHover, this.selectInteraction); /* TODO check if needed this._rectangle.pad(MOVE_HITTEST_EXTENSION, MOVE_HITTEST_EXTENSION); @@ -746,6 +749,9 @@ export class RectanglePrimitive extends BaseElementContainer<Models.RectanglePri } protected _endMove(event: PIXI.interaction.InteractionEvent): void { + this._rotateContainer.addChild(this._configurationElement); + + // Events this.on("pointerover", this.selectInteraction.onHover, this.selectInteraction); this.emit("pointerover", event); /* TODO check if needed diff --git a/src/lib/elements/primitives/TextPrimitive.ts b/src/lib/elements/primitives/TextPrimitive.ts index 1d36c0dce4adee08f010220a22f5ff55b1db2fde..9d2cc7c3a3ffe3ac7847295dd1a5273eb8027956 100644 --- a/src/lib/elements/primitives/TextPrimitive.ts +++ b/src/lib/elements/primitives/TextPrimitive.ts @@ -868,6 +868,9 @@ export class TextPrimitive extends BaseElementContainer<Models.TextPrimitive> { //<editor-fold desc="Move"> protected _startMove(): void { + this._rotateContainer.removeChild(this._configurationElement); + + // Events this.off("pointerover", this.selectInteraction.onHover, this.selectInteraction); /* TODO check if needed this._rectangle.pad(MOVE_HITTEST_EXTENSION, MOVE_HITTEST_EXTENSION); @@ -887,6 +890,9 @@ export class TextPrimitive extends BaseElementContainer<Models.TextPrimitive> { } protected _endMove(event: PIXI.interaction.InteractionEvent): void { + this._rotateContainer.addChild(this._configurationElement); + + // Events this.on("pointerover", this.selectInteraction.onHover, this.selectInteraction); this.emit("pointerover", event); /* TODO check if needed