From 8dd6fbfc5cf69d794cf669ecca2a3ec3a6368ab1 Mon Sep 17 00:00:00 2001 From: Lisann Engel Date: Sun, 9 Nov 2025 15:25:13 +0100 Subject: [PATCH 01/11] moved all the methods implemented in all subclasses up in the canvasobjects class --- .../static/js/editor/objects/canvasObject.mjs | 83 +++++++++++++++---- .../static/js/editor/objects/heliostat.mjs | 53 ++++-------- .../static/js/editor/objects/lightSource.mjs | 54 ++++-------- .../static/js/editor/objects/receiver.mjs | 53 ++++-------- 4 files changed, 111 insertions(+), 132 deletions(-) diff --git a/canvas_editor/static/js/editor/objects/canvasObject.mjs b/canvas_editor/static/js/editor/objects/canvasObject.mjs index 533e477b..f8a44fdc 100644 --- a/canvas_editor/static/js/editor/objects/canvasObject.mjs +++ b/canvas_editor/static/js/editor/objects/canvasObject.mjs @@ -3,20 +3,29 @@ import { Object3D, Vector3 } from "three"; import * as THREE from "three"; import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js"; import { methodMustBeImplementedError } from "message_dict"; +import { Command } from "command"; /** * Represents a Object in CANVAS */ export class CanvasObject extends Object3D { objectName; + #undoRedoHandler; + #rotatableAxis; + #isMovable; + #isSelectable; /** * Creates a new selectable object * @param {string} name the name of the object */ - constructor(name) { + constructor(name, undoRedoHandler, rotatableAxis = [], isMovable, isSelectable) { super(); this.objectName = name; + this.#undoRedoHandler = undoRedoHandler; + this.#rotatableAxis = rotatableAxis; + this.#isMovable = isMovable; + this.#isSelectable = isSelectable; } /** @@ -30,11 +39,29 @@ export class CanvasObject extends Object3D { } /** - * Updates and saves the new name through a command - * @param {string} name the new name you want to save and update + * Update and save the name of the object + * @param {string} name the new name + * @returns {void} */ // eslint-disable-next-line no-unused-vars -- required for interface compatibility updateAndSaveObjectName(name) { + const UpdatePropertyCommand = this.updatePropertyCommand; + if (!UpdatePropertyCommand) { + throw new Error("updateNameCommand not implemented"); + } + + this.#undoRedoHandler.executeCommand( + new UpdatePropertyCommand(this, "objectName", name), + ); + } + + /** + * Returns the command class used to update the name of the object + * @abstract + * @throws {Error} Throws an error if the method is not implemented in subclasses. + * @returns {new (...args: any[]) => Command} + */ + get updatePropertyCommand() { throw new Error(methodMustBeImplementedError); } @@ -75,46 +102,72 @@ export class CanvasObject extends Object3D { } /** - * Duplicates the object + * Duplicate the object + * @returns {void} */ duplicate() { + const DuplicateCommand = this.duplicateCommand; + if (!DuplicateCommand) { + throw new Error("duplicateCommand not implemented"); + } + + this.#undoRedoHandler.executeCommand(new DuplicateCommand(this)); + } + + /** + * Returns the command class used to duplicate the object + * @abstract + * @throws {Error} - Throws an error if the method is not implemented in subclasses. + * @returns {new (...args: any[]) => Command} + */ + get duplicateCommand() { throw new Error(methodMustBeImplementedError); } + /** * Deletes the object */ delete() { - throw new Error(methodMustBeImplementedError); + const DeleteCommand = this.deleteCommand; + if (!DeleteCommand) { + throw new Error("deleteCommand not implemented"); + } + + this.#undoRedoHandler.executeCommand(new DeleteCommand(this)); } /** - * Returns the axis on which the object is rotatable + * Returns the command class used to delete the object * @abstract * @throws {Error} - Throws an error if the method is not implemented in subclasses. - * @returns {string[]} array containing all rotatable axis. + * @returns {new (...args: any[]) => Command} */ - get rotatableAxis() { + get deleteCommand() { throw new Error(methodMustBeImplementedError); } /** - * Returns whether the object is movable or not - * @abstract - * @throws {Error} - Throws an error if the method is not implemented in subclasses. + * Returns the rotatable axis of the object + * @returns {string[]} containing all rotatable axis + */ + get rotatableAxis() { + return this.#rotatableAxis; + } + + /** + * Returns whether an object is movable or not * @returns {boolean} whether the object is movable */ get isMovable() { - throw new Error(methodMustBeImplementedError); + return this.#isMovable; } /** * Returns whether an object is selectable or not - * @abstract - * @throws {Error} - Throws an error if the method is not implemented in subclasses. * @returns {boolean} whether the object is selectable */ get isSelectable() { - throw new Error(methodMustBeImplementedError); + return this.#isSelectable; } /** diff --git a/canvas_editor/static/js/editor/objects/heliostat.mjs b/canvas_editor/static/js/editor/objects/heliostat.mjs index d37a8197..c0867fd7 100644 --- a/canvas_editor/static/js/editor/objects/heliostat.mjs +++ b/canvas_editor/static/js/editor/objects/heliostat.mjs @@ -11,6 +11,7 @@ import { Vector3 } from "three"; import { UndoRedoHandler } from "undoRedoHandler"; import { UpdateHeliostatCommand } from "updateCommands"; import * as THREE from "three"; +import { Command } from "command"; /** * Class that represents the Heliostat object @@ -24,11 +25,9 @@ export class Heliostat extends CanvasObject { #headerComponent; #positionComponent; #undoRedoHandler = UndoRedoHandler.getInstance(); - #isMovable = true; /** * @type { string[] } */ - #rotatableAxis = null; #lastPosition; /** @@ -38,7 +37,7 @@ export class Heliostat extends CanvasObject { * @param {number} [apiID] The id for api usage */ constructor(heliostatName, position, apiID = null) { - super(heliostatName); + super(heliostatName, UndoRedoHandler.getInstance(), null, true, true); loadGltf("/static/models/heliostat.glb", this, true); this.position.copy(position); this.#lastPosition = new Vector3(position.x, position.y, position.z); @@ -119,27 +118,27 @@ export class Heliostat extends CanvasObject { } /** - * Update and save the name of the object - * @param {string} name the new name for the object + * Returns the command class used to update the name of the object + * @returns {new (...args: any[]) => Command} the command class used to update the name */ - updateAndSaveObjectName(name) { - this.#undoRedoHandler.executeCommand( - new UpdateHeliostatCommand(this, "objectName", name), - ); + get updatePropertyCommand() { + return UpdateHeliostatCommand; } /** - * Duplicate the object + * Returns the command class used to duplicate the object + * @returns {new (...args: any[]) => Command} the command class used to duplicate the object */ - duplicate() { - this.#undoRedoHandler.executeCommand(new DuplicateHeliostatCommand(this)); + get duplicateCommand() { + return DuplicateHeliostatCommand; } /** - * Delete the object + * Returns the command class used to delete the object + * @returns {new (...args: any[]) => Command} the command class used to delete the object */ - delete() { - this.#undoRedoHandler.executeCommand(new DeleteHeliostatCommand(this)); + get deleteCommand() { + return DeleteHeliostatCommand; } /** @@ -160,30 +159,6 @@ export class Heliostat extends CanvasObject { return [this.#headerComponent, this.#positionComponent]; } - /** - * Get an array containing all rotatable axis - * @returns {string[]} containing all rotatable axis - */ - get rotatableAxis() { - return this.#rotatableAxis; - } - - /** - * Get whether the object is selectable - * @returns {boolean} whether the object is selectable - */ - get isSelectable() { - return true; - } - - /** - * Get whether the object is movable - * @returns {boolean} whether the object is movable - */ - get isMovable() { - return this.#isMovable; - } - /** * Get the current position of the object * @returns {THREE.Vector3} the position of the object diff --git a/canvas_editor/static/js/editor/objects/lightSource.mjs b/canvas_editor/static/js/editor/objects/lightSource.mjs index e6c6dcc4..a11a151b 100644 --- a/canvas_editor/static/js/editor/objects/lightSource.mjs +++ b/canvas_editor/static/js/editor/objects/lightSource.mjs @@ -1,4 +1,5 @@ import { CanvasObject } from "canvasObject"; +import { Command } from "command"; import { DeleteLightSourceCommand } from "deleteCommands"; import { DuplicateLightSourceCommand } from "duplicateCommands"; import { @@ -44,8 +45,6 @@ export class LightSource extends CanvasObject { #distributionCovarianceComponent; #undoRedoHandler = UndoRedoHandler.getInstance(); - #isMovable = false; - #rotatableAxis = null; /** * Create the light source object @@ -66,7 +65,7 @@ export class LightSource extends CanvasObject { distributionCovariance, apiID = null, ) { - super(lightSourceName); + super(lightSourceName, UndoRedoHandler.getInstance(), null, false, false); this.apiID = apiID; this.numberOfRays = numberOfRays; this.lightSourceType = lightSourceType; @@ -147,50 +146,27 @@ export class LightSource extends CanvasObject { } /** - * Update and save the name of the object - * @param {string} name the new name + * Returns the command class used to update the name of the object + * @returns {new (...args: any[]) => Command} the command class used to update the name */ - updateAndSaveObjectName(name) { - this.#undoRedoHandler.executeCommand( - new UpdateLightsourceCommand(this, "objectName", name), - ); + get updatePropertyCommand() { + return UpdateLightsourceCommand; } /** - * Duplicate the object - */ - duplicate() { - this.#undoRedoHandler.executeCommand(new DuplicateLightSourceCommand(this)); - } - /** - * Delete the object + * Returns the command class used to duplicate the object + * @returns {new (...args: any[]) => Command} the command class used to duplicate the object */ - delete() { - this.#undoRedoHandler.executeCommand(new DeleteLightSourceCommand(this)); + get duplicateCommand() { + return DuplicateLightSourceCommand; } - - /** - * Returns whether the light source is rotatable or not - * @returns {string[]} false, as the light source is not rotatable - */ - get rotatableAxis() { - return this.#rotatableAxis; - } - - /** - * Returns whether the light source is movable or not - * @returns {boolean} false, as the light source is movable - */ - get isMovable() { - return this.#isMovable; - } - + /** - * Get whether the object is selectable - * @returns {boolean} if the object is selectable + * Returns the command class used to delete the object + * @returns {new (...args: any[]) => Command} the command class used to delete the object */ - get isSelectable() { - return false; + get deleteCommand() { + return DeleteLightSourceCommand; } /** diff --git a/canvas_editor/static/js/editor/objects/receiver.mjs b/canvas_editor/static/js/editor/objects/receiver.mjs index 66fcc832..5acbae26 100644 --- a/canvas_editor/static/js/editor/objects/receiver.mjs +++ b/canvas_editor/static/js/editor/objects/receiver.mjs @@ -13,6 +13,7 @@ import { UndoRedoHandler } from "undoRedoHandler"; import { UpdateReceiverCommand } from "updateCommands"; import * as THREE from "three"; import { towerBasePath, towerTopPath } from "path_dict"; +import { Command } from "command"; /** * Class that represents the receiver object @@ -66,8 +67,6 @@ export class Receiver extends CanvasObject { #curvatureComponent; #planeComponent; #resolutionComponent; - #isMovable = true; - #rotatableAxis = null; #lastPosition; /** @@ -97,7 +96,7 @@ export class Receiver extends CanvasObject { curvatureU, apiID = null, ) { - super(receiverName); + super(receiverName, UndoRedoHandler.getInstance(), null, true, true); // place the 3D object this.#base = new ReceiverBase(); this.add(this.#base); @@ -363,51 +362,27 @@ export class Receiver extends CanvasObject { } /** - * Update and save the name of the object - * @param {string} name the new name + * Returns the command class used to update the name of the object + * @returns {new (...args: any[]) => Command} the command class used to update the name */ - updateAndSaveObjectName(name) { - this.#undoRedoHandler.executeCommand( - new UpdateReceiverCommand(this, "objectName", name), - ); - } - - /** - * Deletes the receiver - */ - delete() { - this.#undoRedoHandler.executeCommand(new DeleteReceiverCommand(this)); - } - - /** - * Duplicates the receiver - */ - duplicate() { - this.#undoRedoHandler.executeCommand(new DuplicateReceiverCommand(this)); - } - - /** - * Get all rotatable axis - * @returns {string[]} containing all rotatable axis - */ - get rotatableAxis() { - return this.#rotatableAxis; + get updatePropertyCommand() { + return UpdateReceiverCommand; } /** - * Get whether the object is movable or not - * @returns {boolean} whether the object is movable + * Returns the command class used to delete the object + * @returns {new (...args: any[]) => Command} the command class used to delete the object */ - get isMovable() { - return this.#isMovable; + get deleteCommand() { + return DeleteReceiverCommand; } /** - * Get whether the object is selectable - * @returns {boolean} whether the object is selectable + * Returns the command class used to duplicate the object + * @returns {new (...args: any[]) => Command} the command class used to duplicate the object */ - get isSelectable() { - return true; + get duplicateCommand() { + return DuplicateReceiverCommand; } /** From edf8004b1fb7ef7217e73a8ff0e95b2edf2d122c Mon Sep 17 00:00:00 2001 From: Lisann Engel Date: Tue, 11 Nov 2025 08:41:57 +0100 Subject: [PATCH 02/11] base of movableCanvasObject Class --- canvas_editor/editor/templates/editor/editor.html | 3 ++- canvas_editor/jsconfig.json | 3 ++- .../static/js/editor/objects/movableCanvasObjects.mjs | 8 ++++++++ 3 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs diff --git a/canvas_editor/editor/templates/editor/editor.html b/canvas_editor/editor/templates/editor/editor.html index 564ec033..0946faca 100644 --- a/canvas_editor/editor/templates/editor/editor.html +++ b/canvas_editor/editor/templates/editor/editor.html @@ -46,7 +46,8 @@ "promptCommands": "{% static 'js/editor/promptCommands.mjs' %}", "modeSelector": "{% static 'js/editor/modeSelector.mjs' %}", "message_dict": "{% static 'js/message_dict.js' %}", - "path_dict": "{% static 'js/path_dict.js' %}" + "path_dict": "{% static 'js/path_dict.js' %}", + "movableCanvasObjects": "{% static 'js/editor/objects/movableCanvasObjects.mjs' %}" } } diff --git a/canvas_editor/jsconfig.json b/canvas_editor/jsconfig.json index 55be9334..20f0cefa 100644 --- a/canvas_editor/jsconfig.json +++ b/canvas_editor/jsconfig.json @@ -38,7 +38,8 @@ "modeSelector": ["static/js/editor/modeSelector.mjs"], "projectOverviewHandler": ["static/js/editor/projectOverviewHandler.mjs"], "message_dict": ["static/js/message_dict.js"], - "path_dict": ["static/js/path_dict.js"] + "path_dict": ["static/js/path_dict.js"], + "movableCanvasObjects": ["static/js/editor/objects/movableCanvasObjects.mjs"] } } } diff --git a/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs b/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs new file mode 100644 index 00000000..899eb198 --- /dev/null +++ b/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs @@ -0,0 +1,8 @@ +import { CanvasObject } from "canvasObject"; +import { UndoRedoHandler } from "undoRedoHandler"; + +export class movableCanvasObject extends CanvasObject { + constructor(movableObjectName, undoRedoHandler) { + super(movableObjectName, undoRedoHandler, null, true, true); + } +} \ No newline at end of file From be26c1883e8db56db8717992c3e1047a984381b6 Mon Sep 17 00:00:00 2001 From: Lisann Engel Date: Tue, 11 Nov 2025 08:59:37 +0100 Subject: [PATCH 03/11] movableCanvasObjects extends Receiver and Heliostat-base set up done --- canvas_editor/static/js/editor/objects/heliostat.mjs | 7 ++++--- .../static/js/editor/objects/movableCanvasObjects.mjs | 1 - canvas_editor/static/js/editor/objects/receiver.mjs | 7 ++++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/canvas_editor/static/js/editor/objects/heliostat.mjs b/canvas_editor/static/js/editor/objects/heliostat.mjs index c0867fd7..ff85f764 100644 --- a/canvas_editor/static/js/editor/objects/heliostat.mjs +++ b/canvas_editor/static/js/editor/objects/heliostat.mjs @@ -1,4 +1,4 @@ -import { CanvasObject, loadGltf } from "canvasObject"; +import { loadGltf } from "canvasObject"; import { DeleteHeliostatCommand } from "deleteCommands"; import { DuplicateHeliostatCommand } from "duplicateCommands"; import { @@ -12,11 +12,12 @@ import { UndoRedoHandler } from "undoRedoHandler"; import { UpdateHeliostatCommand } from "updateCommands"; import * as THREE from "three"; import { Command } from "command"; +import { movableCanvasObject } from "movableCanvasObjects"; /** * Class that represents the Heliostat object */ -export class Heliostat extends CanvasObject { +export class Heliostat extends movableCanvasObject { /** * The api id used for this heliostat. * @type {number} @@ -37,7 +38,7 @@ export class Heliostat extends CanvasObject { * @param {number} [apiID] The id for api usage */ constructor(heliostatName, position, apiID = null) { - super(heliostatName, UndoRedoHandler.getInstance(), null, true, true); + super(heliostatName, UndoRedoHandler.getInstance()); loadGltf("/static/models/heliostat.glb", this, true); this.position.copy(position); this.#lastPosition = new Vector3(position.x, position.y, position.z); diff --git a/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs b/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs index 899eb198..b8f306ff 100644 --- a/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs +++ b/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs @@ -1,5 +1,4 @@ import { CanvasObject } from "canvasObject"; -import { UndoRedoHandler } from "undoRedoHandler"; export class movableCanvasObject extends CanvasObject { constructor(movableObjectName, undoRedoHandler) { diff --git a/canvas_editor/static/js/editor/objects/receiver.mjs b/canvas_editor/static/js/editor/objects/receiver.mjs index 5acbae26..2f045c5d 100644 --- a/canvas_editor/static/js/editor/objects/receiver.mjs +++ b/canvas_editor/static/js/editor/objects/receiver.mjs @@ -1,4 +1,4 @@ -import { CanvasObject, loadGltf } from "canvasObject"; +import { loadGltf } from "canvasObject"; import { DeleteReceiverCommand } from "deleteCommands"; import { DuplicateReceiverCommand } from "duplicateCommands"; import { @@ -14,11 +14,12 @@ import { UpdateReceiverCommand } from "updateCommands"; import * as THREE from "three"; import { towerBasePath, towerTopPath } from "path_dict"; import { Command } from "command"; +import { movableCanvasObject } from "movableCanvasObjects"; /** * Class that represents the receiver object */ -export class Receiver extends CanvasObject { +export class Receiver extends movableCanvasObject { /** * The apiID used for this receiver */ @@ -96,7 +97,7 @@ export class Receiver extends CanvasObject { curvatureU, apiID = null, ) { - super(receiverName, UndoRedoHandler.getInstance(), null, true, true); + super(receiverName, UndoRedoHandler.getInstance()); // place the 3D object this.#base = new ReceiverBase(); this.add(this.#base); From 16e82517decc4fdfec5ee55993997ed2f2a7896e Mon Sep 17 00:00:00 2001 From: Lisann Engel Date: Tue, 11 Nov 2025 09:53:04 +0100 Subject: [PATCH 04/11] moved methods up into movableCanvasObjects --- .../static/js/editor/objects/heliostat.mjs | 93 +----------- .../editor/objects/movableCanvasObjects.mjs | 109 +++++++++++++- .../static/js/editor/objects/receiver.mjs | 134 ++++-------------- 3 files changed, 137 insertions(+), 199 deletions(-) diff --git a/canvas_editor/static/js/editor/objects/heliostat.mjs b/canvas_editor/static/js/editor/objects/heliostat.mjs index ff85f764..8795b639 100644 --- a/canvas_editor/static/js/editor/objects/heliostat.mjs +++ b/canvas_editor/static/js/editor/objects/heliostat.mjs @@ -3,8 +3,6 @@ import { DeleteHeliostatCommand } from "deleteCommands"; import { DuplicateHeliostatCommand } from "duplicateCommands"; import { HeaderInspectorComponent, - SingleFieldInspectorComponent, - MultiFieldInspectorComponent, InspectorComponent, } from "inspectorComponents"; import { Vector3 } from "three"; @@ -24,12 +22,9 @@ export class Heliostat extends movableCanvasObject { */ apiID; #headerComponent; - #positionComponent; - #undoRedoHandler = UndoRedoHandler.getInstance(); /** * @type { string[] } */ - #lastPosition; /** * Creates a Heliostat object @@ -38,10 +33,9 @@ export class Heliostat extends movableCanvasObject { * @param {number} [apiID] The id for api usage */ constructor(heliostatName, position, apiID = null) { - super(heliostatName, UndoRedoHandler.getInstance()); + super(heliostatName, UndoRedoHandler.getInstance(), position); loadGltf("/static/models/heliostat.glb", this, true); this.position.copy(position); - this.#lastPosition = new Vector3(position.x, position.y, position.z); this.apiID = apiID; // create components for inspector @@ -51,71 +45,8 @@ export class Heliostat extends movableCanvasObject { ? this.objectName : "Heliostat", (name) => this.updateAndSaveObjectName(name), - this, + this ); - - const nCoordinate = new SingleFieldInspectorComponent( - "N", - "number", - () => this.position.x, - (newValue) => { - this.#undoRedoHandler.executeCommand( - new UpdateHeliostatCommand( - this, - "position", - new Vector3(newValue, this.position.y, this.position.z), - ), - ); - }, - -Infinity, - ); - - const uCoordinate = new SingleFieldInspectorComponent( - "U", - "number", - () => this.position.y, - (newValue) => { - this.#undoRedoHandler.executeCommand( - new UpdateHeliostatCommand( - this, - "position", - new Vector3(this.position.x, newValue, this.position.z), - ), - ); - }, - 0, - ); - - const eCoordinate = new SingleFieldInspectorComponent( - "E", - "number", - () => this.position.z, - (newValue) => { - this.#undoRedoHandler.executeCommand( - new UpdateHeliostatCommand( - this, - "position", - new Vector3(this.position.x, this.position.y, newValue), - ), - ); - }, - -Infinity, - ); - - this.#positionComponent = new MultiFieldInspectorComponent("Position", [ - nCoordinate, - uCoordinate, - eCoordinate, - ]); - } - - /** - * Updates the position of the heliostat - * @param {THREE.Vector3} position the new position - */ - updatePosition(position) { - this.position.copy(position); - this.#lastPosition = new Vector3(position.x, position.y, position.z); } /** @@ -142,29 +73,11 @@ export class Heliostat extends movableCanvasObject { return DeleteHeliostatCommand; } - /** - * Updates the position of the heliostat - * @param {Vector3} position - the new position of the heliostat - */ - updateAndSaveObjectPosition(position) { - this.#undoRedoHandler.executeCommand( - new UpdateHeliostatCommand(this, "position", position), - ); - } - /** * Get an array of all inspectorComponents for this object * @returns {InspectorComponent[]} array of inspectorComponents */ get inspectorComponents() { - return [this.#headerComponent, this.#positionComponent]; - } - - /** - * Get the current position of the object - * @returns {THREE.Vector3} the position of the object - */ - get lastPosition() { - return this.#lastPosition; + return [this.#headerComponent, super.positionComponent]; } } diff --git a/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs b/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs index b8f306ff..158bf06b 100644 --- a/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs +++ b/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs @@ -1,7 +1,108 @@ import { CanvasObject } from "canvasObject"; +import { + MultiFieldInspectorComponent, + SingleFieldInspectorComponent, +} from "inspectorComponents"; +import { Vector3 } from "three"; export class movableCanvasObject extends CanvasObject { - constructor(movableObjectName, undoRedoHandler) { - super(movableObjectName, undoRedoHandler, null, true, true); - } -} \ No newline at end of file + #undoRedoHandler; + #positionComponent; + #lastPosition; + + /** + * Creates a new movable object + * @param {string} movableObjectName the name of the movable object + * @param {import("undoRedoHandler").UndoRedoHandler} undoRedoHandler the undo redo handler + */ + constructor(movableObjectName, undoRedoHandler, position) { + super(movableObjectName, undoRedoHandler, null, true, true); + this.#undoRedoHandler = undoRedoHandler; + + this.#lastPosition = new Vector3(position.x, position.y, position.z); + + const nCoordinate = new SingleFieldInspectorComponent( + "N", + "number", + () => this.position.x, + (newValue) => { + this.#undoRedoHandler.executeCommand( + new this.updatePropertyCommand( + this, + "position", + new Vector3(newValue, this.position.y, this.position.z) + ) + ); + }, + -Infinity + ); + + const uCoordinate = new SingleFieldInspectorComponent( + "U", + "number", + () => this.position.y, + (newValue) => { + this.#undoRedoHandler.executeCommand( + new this.updatePropertyCommand( + this, + "position", + new Vector3(this.position.x, newValue, this.position.z) + ) + ); + }, + 0 + ); + + const eCoordinate = new SingleFieldInspectorComponent( + "E", + "number", + () => this.position.z, + (newValue) => { + this.#undoRedoHandler.executeCommand( + new this.updatePropertyCommand( + this, + "position", + new Vector3(this.position.x, this.position.y, newValue) + ) + ); + }, + -Infinity + ); + + this.#positionComponent = new MultiFieldInspectorComponent("Position", [ + nCoordinate, + uCoordinate, + eCoordinate, + ]); + } + + get positionComponent() { + return this.#positionComponent; + } + + /** + * Updates the position of the heliostat + * @param {THREE.Vector3} position the new position + */ + updatePosition(position) { + this.position.copy(position); + this.#lastPosition = new Vector3(position.x, position.y, position.z); + } + + /** + * Updates the position of the heliostat + * @param {Vector3} position - the new position of the heliostat + */ + updateAndSaveObjectPosition(position) { + this.#undoRedoHandler.executeCommand( + new this.updatePropertyCommand(this, "position", position) + ); + } + /** + * Get the current position of the object + * @returns {THREE.Vector3} the position of the object + */ + get lastPosition() { + return this.#lastPosition; + } +} diff --git a/canvas_editor/static/js/editor/objects/receiver.mjs b/canvas_editor/static/js/editor/objects/receiver.mjs index 2f045c5d..1f7e2aa9 100644 --- a/canvas_editor/static/js/editor/objects/receiver.mjs +++ b/canvas_editor/static/js/editor/objects/receiver.mjs @@ -62,13 +62,11 @@ export class Receiver extends movableCanvasObject { #base; #headerComponent; - #positionComponent; #normalVectorComponent; #towerTypeComponent; #curvatureComponent; #planeComponent; #resolutionComponent; - #lastPosition; /** * Creates a Receiver object @@ -95,9 +93,9 @@ export class Receiver extends movableCanvasObject { resolutionU, curvatureE, curvatureU, - apiID = null, + apiID = null ) { - super(receiverName, UndoRedoHandler.getInstance()); + super(receiverName, UndoRedoHandler.getInstance(), position); // place the 3D object this.#base = new ReceiverBase(); this.add(this.#base); @@ -116,7 +114,6 @@ export class Receiver extends movableCanvasObject { this.resolutionU = resolutionU; this.curvatureE = curvatureE; this.curvatureU = curvatureU; - this.#lastPosition = new Vector3(position.x, position.y, position.z); // create components for the inspector this.#headerComponent = new HeaderInspectorComponent( @@ -125,63 +122,9 @@ export class Receiver extends movableCanvasObject { ? this.objectName : "Receiver", (name) => this.updateAndSaveObjectName(name), - this, + this ); - const nCoordinate = new SingleFieldInspectorComponent( - "N", - "number", - () => this.lastPosition.x, - (newValue) => { - this.#undoRedoHandler.executeCommand( - new UpdateReceiverCommand( - this, - "position", - new Vector3(newValue, this.position.y, this.position.z), - ), - ); - }, - -Infinity, - ); - - const uCoordinate = new SingleFieldInspectorComponent( - "U", - "number", - () => this.lastPosition.y, - (newValue) => { - this.#undoRedoHandler.executeCommand( - new UpdateReceiverCommand( - this, - "position", - new Vector3(this.position.x, newValue, this.position.z), - ), - ); - }, - 0, - ); - - const eCoordinate = new SingleFieldInspectorComponent( - "E", - "number", - () => this.lastPosition.z, - (newValue) => { - this.#undoRedoHandler.executeCommand( - new UpdateReceiverCommand( - this, - "position", - new Vector3(this.position.x, this.position.y, newValue), - ), - ); - }, - -Infinity, - ); - - this.#positionComponent = new MultiFieldInspectorComponent("Position", [ - nCoordinate, - uCoordinate, - eCoordinate, - ]); - const nNormalVector = new SingleFieldInspectorComponent( "N", "number", @@ -191,11 +134,11 @@ export class Receiver extends movableCanvasObject { new UpdateReceiverCommand( this, "normalVector", - new Vector3(newValue, this.normalVector.y, this.normalVector.z), - ), + new Vector3(newValue, this.normalVector.y, this.normalVector.z) + ) ); }, - -Infinity, + -Infinity ); const uNormalVector = new SingleFieldInspectorComponent( @@ -207,11 +150,11 @@ export class Receiver extends movableCanvasObject { new UpdateReceiverCommand( this, "normalVector", - new Vector3(this.normalVector.x, newValue, this.normalVector.z), - ), + new Vector3(this.normalVector.x, newValue, this.normalVector.z) + ) ); }, - -Infinity, + -Infinity ); const eNormalVector = new SingleFieldInspectorComponent( @@ -223,16 +166,16 @@ export class Receiver extends movableCanvasObject { new UpdateReceiverCommand( this, "normalVector", - new Vector3(this.normalVector.x, this.normalVector.y, newValue), - ), + new Vector3(this.normalVector.x, this.normalVector.y, newValue) + ) ); }, - -Infinity, + -Infinity ); this.#normalVectorComponent = new MultiFieldInspectorComponent( "Normal Vector", - [nNormalVector, uNormalVector, eNormalVector], + [nNormalVector, uNormalVector, eNormalVector] ); this.#towerTypeComponent = new SelectFieldInspectorComponent( @@ -241,9 +184,9 @@ export class Receiver extends movableCanvasObject { () => this.towerType, (newValue) => { this.#undoRedoHandler.executeCommand( - new UpdateReceiverCommand(this, "towerType", newValue), + new UpdateReceiverCommand(this, "towerType", newValue) ); - }, + } ); const eCurvature = new SingleFieldInspectorComponent( @@ -252,10 +195,10 @@ export class Receiver extends movableCanvasObject { () => this.curvatureE, (newValue) => { this.#undoRedoHandler.executeCommand( - new UpdateReceiverCommand(this, "curvatureE", newValue), + new UpdateReceiverCommand(this, "curvatureE", newValue) ); }, - -Infinity, + -Infinity ); const uCurvature = new SingleFieldInspectorComponent( @@ -264,10 +207,10 @@ export class Receiver extends movableCanvasObject { () => this.curvatureU, (newValue) => { this.#undoRedoHandler.executeCommand( - new UpdateReceiverCommand(this, "curvatureU", newValue), + new UpdateReceiverCommand(this, "curvatureU", newValue) ); }, - -Infinity, + -Infinity ); this.#curvatureComponent = new MultiFieldInspectorComponent("Curvature", [ @@ -281,10 +224,10 @@ export class Receiver extends movableCanvasObject { () => this.planeE, (newValue) => { this.#undoRedoHandler.executeCommand( - new UpdateReceiverCommand(this, "planeE", newValue), + new UpdateReceiverCommand(this, "planeE", newValue) ); }, - -Infinity, + -Infinity ); const uPlane = new SingleFieldInspectorComponent( @@ -293,10 +236,10 @@ export class Receiver extends movableCanvasObject { () => this.planeU, (newValue) => { this.#undoRedoHandler.executeCommand( - new UpdateReceiverCommand(this, "planeU", newValue), + new UpdateReceiverCommand(this, "planeU", newValue) ); }, - -Infinity, + -Infinity ); this.#planeComponent = new MultiFieldInspectorComponent("Plane", [ @@ -310,10 +253,10 @@ export class Receiver extends movableCanvasObject { () => this.resolutionE, (newValue) => { this.#undoRedoHandler.executeCommand( - new UpdateReceiverCommand(this, "resolutionE", newValue), + new UpdateReceiverCommand(this, "resolutionE", newValue) ); }, - -Infinity, + -Infinity ); const uResolution = new SingleFieldInspectorComponent( @@ -322,10 +265,10 @@ export class Receiver extends movableCanvasObject { () => this.resolutionU, (newValue) => { this.#undoRedoHandler.executeCommand( - new UpdateReceiverCommand(this, "resolutionU", newValue), + new UpdateReceiverCommand(this, "resolutionU", newValue) ); }, - -Infinity, + -Infinity ); this.#resolutionComponent = new MultiFieldInspectorComponent("Resolution", [ @@ -342,23 +285,12 @@ export class Receiver extends movableCanvasObject { this.#base.position.y = y; } - /** - * Updates the position of the receiver - * @param {Vector3} position - the new position of the receiver - */ - updateAndSaveObjectPosition(position) { - this.#undoRedoHandler.executeCommand( - new UpdateReceiverCommand(this, "position", position), - ); - } - /** * Updates the receiver’s position by adjusting both the base and the top, ensuring that the base remains on the ground. * @param {THREE.Vector3} position the new position of the receiver */ updatePosition(position) { - this.position.copy(position); - this.#lastPosition = new Vector3(position.x, position.y, position.z); + super.updatePosition(position); this.#base.position.y = -position.y; } @@ -386,14 +318,6 @@ export class Receiver extends movableCanvasObject { return DuplicateReceiverCommand; } - /** - * Get the current position of the object - * @returns {THREE.Vector3} the current position - */ - get lastPosition() { - return this.#lastPosition; - } - /** * Get the inspectorComponents used for this object * @returns {InspectorComponent[]} array of the inspectorComponents used @@ -401,7 +325,7 @@ export class Receiver extends movableCanvasObject { get inspectorComponents() { return [ this.#headerComponent, - this.#positionComponent, + super.positionComponent, this.#normalVectorComponent, this.#towerTypeComponent, this.#curvatureComponent, From 886f4e3266fbfd38d8b44b35d8afe7c7f378524e Mon Sep 17 00:00:00 2001 From: Lisann Engel Date: Tue, 11 Nov 2025 11:07:17 +0100 Subject: [PATCH 05/11] removed unused varaibles, comments, switched some things in the constructor --- .../static/js/editor/objects/canvasObject.mjs | 68 ++++++++++++++----- .../static/js/editor/objects/heliostat.mjs | 21 +----- .../static/js/editor/objects/lightSource.mjs | 49 ++++++------- .../editor/objects/movableCanvasObjects.mjs | 27 ++++---- .../static/js/editor/objects/receiver.mjs | 17 +---- 5 files changed, 90 insertions(+), 92 deletions(-) diff --git a/canvas_editor/static/js/editor/objects/canvasObject.mjs b/canvas_editor/static/js/editor/objects/canvasObject.mjs index f8a44fdc..5b4e0975 100644 --- a/canvas_editor/static/js/editor/objects/canvasObject.mjs +++ b/canvas_editor/static/js/editor/objects/canvasObject.mjs @@ -1,4 +1,7 @@ -import { InspectorComponent } from "inspectorComponents"; +import { + HeaderInspectorComponent, + InspectorComponent, +} from "inspectorComponents"; import { Object3D, Vector3 } from "three"; import * as THREE from "three"; import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js"; @@ -14,28 +17,49 @@ export class CanvasObject extends Object3D { #rotatableAxis; #isMovable; #isSelectable; + #headerComponent; /** * Creates a new selectable object * @param {string} name the name of the object - */ - constructor(name, undoRedoHandler, rotatableAxis = [], isMovable, isSelectable) { + * @param {import("undoRedoHandler").UndoRedoHandler} undoRedoHandler the undo redo handler + * @param {string} defaultLabel the default label when no name is given + * @param {boolean} isMovable whether the object is movable + * @param {boolean} isSelectable whether the object is selectable + * @param {string[]} rotatableAxis containing all rotatable axis + */ + constructor( + name, + undoRedoHandler, + defaultLabel, + isMovable, + isSelectable, + rotatableAxis = [] + ) { super(); this.objectName = name; this.#undoRedoHandler = undoRedoHandler; this.#rotatableAxis = rotatableAxis; this.#isMovable = isMovable; this.#isSelectable = isSelectable; + + this.#headerComponent = new HeaderInspectorComponent( + () => + this.objectName !== "" && this.objectName + ? this.objectName + : defaultLabel, + (newValue) => this.updateAndSaveObjectName(newValue), + this + ); } /** - * Get a list of inspector components used for this object - * @abstract - * @throws {Error} Throws an error if the method is not implemented in subclasses. - * @returns {InspectorComponent[]} must be implemented in all subclasses + * Get the inspectorComponents used for this object + * The child classes should extend this method to add their own components + * @returns {InspectorComponent[]} array of the inspectorComponents used */ get inspectorComponents() { - throw new Error(methodMustBeImplementedError); + return [this.#headerComponent]; } /** @@ -51,7 +75,7 @@ export class CanvasObject extends Object3D { } this.#undoRedoHandler.executeCommand( - new UpdatePropertyCommand(this, "objectName", name), + new UpdatePropertyCommand(this, "objectName", name) ); } @@ -106,12 +130,12 @@ export class CanvasObject extends Object3D { * @returns {void} */ duplicate() { - const DuplicateCommand = this.duplicateCommand; - if (!DuplicateCommand) { - throw new Error("duplicateCommand not implemented"); - } + const DuplicateCommand = this.duplicateCommand; + if (!DuplicateCommand) { + throw new Error("duplicateCommand not implemented"); + } - this.#undoRedoHandler.executeCommand(new DuplicateCommand(this)); + this.#undoRedoHandler.executeCommand(new DuplicateCommand(this)); } /** @@ -129,11 +153,11 @@ export class CanvasObject extends Object3D { */ delete() { const DeleteCommand = this.deleteCommand; - if (!DeleteCommand) { - throw new Error("deleteCommand not implemented"); - } + if (!DeleteCommand) { + throw new Error("deleteCommand not implemented"); + } - this.#undoRedoHandler.executeCommand(new DeleteCommand(this)); + this.#undoRedoHandler.executeCommand(new DeleteCommand(this)); } /** @@ -189,6 +213,14 @@ export class CanvasObject extends Object3D { get lastRotation() { throw new Error(methodMustBeImplementedError); } + + /** + * Returns the undoRedoHandler used for this object + * @returns {import("undoRedoHandler").UndoRedoHandler} the undoRedoHandler + */ + get undoRedoHandler() { + return this.#undoRedoHandler; + } } /** diff --git a/canvas_editor/static/js/editor/objects/heliostat.mjs b/canvas_editor/static/js/editor/objects/heliostat.mjs index 8795b639..bdf10650 100644 --- a/canvas_editor/static/js/editor/objects/heliostat.mjs +++ b/canvas_editor/static/js/editor/objects/heliostat.mjs @@ -1,11 +1,7 @@ import { loadGltf } from "canvasObject"; import { DeleteHeliostatCommand } from "deleteCommands"; import { DuplicateHeliostatCommand } from "duplicateCommands"; -import { - HeaderInspectorComponent, - InspectorComponent, -} from "inspectorComponents"; -import { Vector3 } from "three"; +import { InspectorComponent } from "inspectorComponents"; import { UndoRedoHandler } from "undoRedoHandler"; import { UpdateHeliostatCommand } from "updateCommands"; import * as THREE from "three"; @@ -21,7 +17,6 @@ export class Heliostat extends movableCanvasObject { * @type {number} */ apiID; - #headerComponent; /** * @type { string[] } */ @@ -33,20 +28,10 @@ export class Heliostat extends movableCanvasObject { * @param {number} [apiID] The id for api usage */ constructor(heliostatName, position, apiID = null) { - super(heliostatName, UndoRedoHandler.getInstance(), position); + super(heliostatName, UndoRedoHandler.getInstance(), position, "Heliostat"); loadGltf("/static/models/heliostat.glb", this, true); this.position.copy(position); this.apiID = apiID; - - // create components for inspector - this.#headerComponent = new HeaderInspectorComponent( - () => - this.objectName !== "" && this.objectName - ? this.objectName - : "Heliostat", - (name) => this.updateAndSaveObjectName(name), - this - ); } /** @@ -78,6 +63,6 @@ export class Heliostat extends movableCanvasObject { * @returns {InspectorComponent[]} array of inspectorComponents */ get inspectorComponents() { - return [this.#headerComponent, super.positionComponent]; + return [...super.inspectorComponents]; } } diff --git a/canvas_editor/static/js/editor/objects/lightSource.mjs b/canvas_editor/static/js/editor/objects/lightSource.mjs index a11a151b..6e2811ef 100644 --- a/canvas_editor/static/js/editor/objects/lightSource.mjs +++ b/canvas_editor/static/js/editor/objects/lightSource.mjs @@ -3,7 +3,6 @@ import { Command } from "command"; import { DeleteLightSourceCommand } from "deleteCommands"; import { DuplicateLightSourceCommand } from "duplicateCommands"; import { - HeaderInspectorComponent, SingleFieldInspectorComponent, SelectFieldInspectorComponent, InspectorComponent, @@ -37,7 +36,6 @@ export class LightSource extends CanvasObject { */ distributionCovariance; - #header; #numberOfRaysComponent; #lightsourceTypeComponent; #distributionTypeComponent; @@ -63,9 +61,15 @@ export class LightSource extends CanvasObject { distributionType, distributionMean, distributionCovariance, - apiID = null, + apiID = null ) { - super(lightSourceName, UndoRedoHandler.getInstance(), null, false, false); + super( + lightSourceName, + UndoRedoHandler.getInstance(), + "Light Source", + false, + false + ); this.apiID = apiID; this.numberOfRays = numberOfRays; this.lightSourceType = lightSourceType; @@ -73,25 +77,16 @@ export class LightSource extends CanvasObject { this.distributionMean = distributionMean; this.distributionCovariance = distributionCovariance; - this.#header = new HeaderInspectorComponent( - () => - this.objectName !== "" && this.objectName - ? this.objectName - : "Light source", - (newValue) => this.updateAndSaveObjectName(newValue), - this, - ); - this.#numberOfRaysComponent = new SingleFieldInspectorComponent( "Number of rays", "number", () => this.numberOfRays, (newValue) => { this.#undoRedoHandler.executeCommand( - new UpdateLightsourceCommand(this, "numberOfRays", newValue), + new UpdateLightsourceCommand(this, "numberOfRays", newValue) ); }, - -Infinity, + -Infinity ); this.#lightsourceTypeComponent = new SelectFieldInspectorComponent( @@ -100,9 +95,9 @@ export class LightSource extends CanvasObject { () => this.lightSourceType, (newValue) => { this.#undoRedoHandler.executeCommand( - new UpdateLightsourceCommand(this, "lightSourceType", newValue), + new UpdateLightsourceCommand(this, "lightSourceType", newValue) ); - }, + } ); this.#distributionTypeComponent = new SelectFieldInspectorComponent( @@ -111,9 +106,9 @@ export class LightSource extends CanvasObject { () => this.distributionType, (newValue) => { this.#undoRedoHandler.executeCommand( - new UpdateLightsourceCommand(this, "distributionType", newValue), + new UpdateLightsourceCommand(this, "distributionType", newValue) ); - }, + } ); this.#distributionMeanComponent = new SingleFieldInspectorComponent( @@ -122,10 +117,10 @@ export class LightSource extends CanvasObject { () => this.distributionMean, (newValue) => { this.#undoRedoHandler.executeCommand( - new UpdateLightsourceCommand(this, "distributionMean", newValue), + new UpdateLightsourceCommand(this, "distributionMean", newValue) ); }, - -Infinity, + -Infinity ); this.#distributionCovarianceComponent = new SingleFieldInspectorComponent( @@ -134,14 +129,10 @@ export class LightSource extends CanvasObject { () => this.distributionCovariance, (newValue) => { this.#undoRedoHandler.executeCommand( - new UpdateLightsourceCommand( - this, - "distributionCovariance", - newValue, - ), + new UpdateLightsourceCommand(this, "distributionCovariance", newValue) ); }, - -Infinity, + -Infinity ); } @@ -160,7 +151,7 @@ export class LightSource extends CanvasObject { get duplicateCommand() { return DuplicateLightSourceCommand; } - + /** * Returns the command class used to delete the object * @returns {new (...args: any[]) => Command} the command class used to delete the object @@ -175,7 +166,7 @@ export class LightSource extends CanvasObject { */ get inspectorComponents() { return [ - this.#header, + ...super.inspectorComponents, this.#numberOfRaysComponent, this.#lightsourceTypeComponent, this.#distributionTypeComponent, diff --git a/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs b/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs index 158bf06b..20e0ca81 100644 --- a/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs +++ b/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs @@ -1,12 +1,12 @@ import { CanvasObject } from "canvasObject"; import { + InspectorComponent, MultiFieldInspectorComponent, SingleFieldInspectorComponent, } from "inspectorComponents"; import { Vector3 } from "three"; export class movableCanvasObject extends CanvasObject { - #undoRedoHandler; #positionComponent; #lastPosition; @@ -15,9 +15,8 @@ export class movableCanvasObject extends CanvasObject { * @param {string} movableObjectName the name of the movable object * @param {import("undoRedoHandler").UndoRedoHandler} undoRedoHandler the undo redo handler */ - constructor(movableObjectName, undoRedoHandler, position) { - super(movableObjectName, undoRedoHandler, null, true, true); - this.#undoRedoHandler = undoRedoHandler; + constructor(movableObjectName, undoRedoHandler, position, defaultLabel) { + super(movableObjectName, undoRedoHandler, defaultLabel, true, true); this.#lastPosition = new Vector3(position.x, position.y, position.z); @@ -26,7 +25,7 @@ export class movableCanvasObject extends CanvasObject { "number", () => this.position.x, (newValue) => { - this.#undoRedoHandler.executeCommand( + this.undoRedoHandler.executeCommand( new this.updatePropertyCommand( this, "position", @@ -42,7 +41,7 @@ export class movableCanvasObject extends CanvasObject { "number", () => this.position.y, (newValue) => { - this.#undoRedoHandler.executeCommand( + this.undoRedoHandler.executeCommand( new this.updatePropertyCommand( this, "position", @@ -58,7 +57,7 @@ export class movableCanvasObject extends CanvasObject { "number", () => this.position.z, (newValue) => { - this.#undoRedoHandler.executeCommand( + this.undoRedoHandler.executeCommand( new this.updatePropertyCommand( this, "position", @@ -76,10 +75,6 @@ export class movableCanvasObject extends CanvasObject { ]); } - get positionComponent() { - return this.#positionComponent; - } - /** * Updates the position of the heliostat * @param {THREE.Vector3} position the new position @@ -94,7 +89,7 @@ export class movableCanvasObject extends CanvasObject { * @param {Vector3} position - the new position of the heliostat */ updateAndSaveObjectPosition(position) { - this.#undoRedoHandler.executeCommand( + this.undoRedoHandler.executeCommand( new this.updatePropertyCommand(this, "position", position) ); } @@ -105,4 +100,12 @@ export class movableCanvasObject extends CanvasObject { get lastPosition() { return this.#lastPosition; } + + /** + * Get an array of all inspectorComponents used for this object + * @returns {InspectorComponent[]} array of all inspectorComponents + */ + get inspectorComponents() { + return [...super.inspectorComponents, this.#positionComponent]; + } } diff --git a/canvas_editor/static/js/editor/objects/receiver.mjs b/canvas_editor/static/js/editor/objects/receiver.mjs index 1f7e2aa9..aeaa26b2 100644 --- a/canvas_editor/static/js/editor/objects/receiver.mjs +++ b/canvas_editor/static/js/editor/objects/receiver.mjs @@ -2,7 +2,6 @@ import { loadGltf } from "canvasObject"; import { DeleteReceiverCommand } from "deleteCommands"; import { DuplicateReceiverCommand } from "duplicateCommands"; import { - HeaderInspectorComponent, SingleFieldInspectorComponent, MultiFieldInspectorComponent, SelectFieldInspectorComponent, @@ -61,7 +60,6 @@ export class Receiver extends movableCanvasObject { #top; #base; - #headerComponent; #normalVectorComponent; #towerTypeComponent; #curvatureComponent; @@ -95,7 +93,7 @@ export class Receiver extends movableCanvasObject { curvatureU, apiID = null ) { - super(receiverName, UndoRedoHandler.getInstance(), position); + super(receiverName, UndoRedoHandler.getInstance(), position, "Receiver"); // place the 3D object this.#base = new ReceiverBase(); this.add(this.#base); @@ -115,16 +113,6 @@ export class Receiver extends movableCanvasObject { this.curvatureE = curvatureE; this.curvatureU = curvatureU; - // create components for the inspector - this.#headerComponent = new HeaderInspectorComponent( - () => - this.objectName !== "" && this.objectName - ? this.objectName - : "Receiver", - (name) => this.updateAndSaveObjectName(name), - this - ); - const nNormalVector = new SingleFieldInspectorComponent( "N", "number", @@ -324,8 +312,7 @@ export class Receiver extends movableCanvasObject { */ get inspectorComponents() { return [ - this.#headerComponent, - super.positionComponent, + ...super.inspectorComponents, this.#normalVectorComponent, this.#towerTypeComponent, this.#curvatureComponent, From 8beb87f7c773e09b5cc543e78b3915c5655f3e7a Mon Sep 17 00:00:00 2001 From: Lisann Engel Date: Tue, 11 Nov 2025 14:52:16 +0100 Subject: [PATCH 06/11] comments --- .../static/js/editor/objects/canvasObject.mjs | 71 ++++++++++--------- .../static/js/editor/objects/heliostat.mjs | 3 + .../static/js/editor/objects/lightSource.mjs | 1 + .../editor/objects/movableCanvasObjects.mjs | 7 ++ canvas_editor/static/js/message_dict.js | 5 ++ 5 files changed, 54 insertions(+), 33 deletions(-) diff --git a/canvas_editor/static/js/editor/objects/canvasObject.mjs b/canvas_editor/static/js/editor/objects/canvasObject.mjs index 5b4e0975..8e40daec 100644 --- a/canvas_editor/static/js/editor/objects/canvasObject.mjs +++ b/canvas_editor/static/js/editor/objects/canvasObject.mjs @@ -5,7 +5,12 @@ import { import { Object3D, Vector3 } from "three"; import * as THREE from "three"; import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js"; -import { methodMustBeImplementedError } from "message_dict"; +import { + methodMustBeImplementedError, + deleteCommandNotImplementedError, + duplicateCommandNotImplementedError, + updateNameCommandNotImplementedError, +} from "message_dict"; import { Command } from "command"; /** @@ -53,15 +58,6 @@ export class CanvasObject extends Object3D { ); } - /** - * Get the inspectorComponents used for this object - * The child classes should extend this method to add their own components - * @returns {InspectorComponent[]} array of the inspectorComponents used - */ - get inspectorComponents() { - return [this.#headerComponent]; - } - /** * Update and save the name of the object * @param {string} name the new name @@ -71,7 +67,7 @@ export class CanvasObject extends Object3D { updateAndSaveObjectName(name) { const UpdatePropertyCommand = this.updatePropertyCommand; if (!UpdatePropertyCommand) { - throw new Error("updateNameCommand not implemented"); + throw new Error(updateNameCommandNotImplementedError); } this.#undoRedoHandler.executeCommand( @@ -79,16 +75,6 @@ export class CanvasObject extends Object3D { ); } - /** - * Returns the command class used to update the name of the object - * @abstract - * @throws {Error} Throws an error if the method is not implemented in subclasses. - * @returns {new (...args: any[]) => Command} - */ - get updatePropertyCommand() { - throw new Error(methodMustBeImplementedError); - } - /** * Updates and saves the new position through a command * @param {Vector3} position - the new position you want to save and update @@ -132,34 +118,53 @@ export class CanvasObject extends Object3D { duplicate() { const DuplicateCommand = this.duplicateCommand; if (!DuplicateCommand) { - throw new Error("duplicateCommand not implemented"); + throw new Error(duplicateCommandNotImplementedError); } this.#undoRedoHandler.executeCommand(new DuplicateCommand(this)); } - /** - * Returns the command class used to duplicate the object - * @abstract - * @throws {Error} - Throws an error if the method is not implemented in subclasses. - * @returns {new (...args: any[]) => Command} - */ - get duplicateCommand() { - throw new Error(methodMustBeImplementedError); - } - /** * Deletes the object */ delete() { const DeleteCommand = this.deleteCommand; if (!DeleteCommand) { - throw new Error("deleteCommand not implemented"); + throw new Error(deleteCommandNotImplementedError); } this.#undoRedoHandler.executeCommand(new DeleteCommand(this)); } + /** + * Get the inspectorComponents used for this object + * The child classes should extend this method to add their own components + * @returns {InspectorComponent[]} array of the inspectorComponents used + */ + get inspectorComponents() { + return [this.#headerComponent]; + } + + /** + * Returns the command class used to update the name of the object + * @abstract + * @throws {Error} Throws an error if the method is not implemented in subclasses. + * @returns {new (...args: any[]) => Command} + */ + get updatePropertyCommand() { + throw new Error(methodMustBeImplementedError); + } + + /** + * Returns the command class used to duplicate the object + * @abstract + * @throws {Error} - Throws an error if the method is not implemented in subclasses. + * @returns {new (...args: any[]) => Command} + */ + get duplicateCommand() { + throw new Error(methodMustBeImplementedError); + } + /** * Returns the command class used to delete the object * @abstract diff --git a/canvas_editor/static/js/editor/objects/heliostat.mjs b/canvas_editor/static/js/editor/objects/heliostat.mjs index bdf10650..5d2398e8 100644 --- a/canvas_editor/static/js/editor/objects/heliostat.mjs +++ b/canvas_editor/static/js/editor/objects/heliostat.mjs @@ -60,6 +60,9 @@ export class Heliostat extends movableCanvasObject { /** * Get an array of all inspectorComponents for this object + * The inspectorComponents from the parent class are also included + * Header component is already included from CanvasObject class + * and position components from movableCanvasObject class * @returns {InspectorComponent[]} array of inspectorComponents */ get inspectorComponents() { diff --git a/canvas_editor/static/js/editor/objects/lightSource.mjs b/canvas_editor/static/js/editor/objects/lightSource.mjs index 6e2811ef..184e5b96 100644 --- a/canvas_editor/static/js/editor/objects/lightSource.mjs +++ b/canvas_editor/static/js/editor/objects/lightSource.mjs @@ -162,6 +162,7 @@ export class LightSource extends CanvasObject { /** * Get an array of all inspectorComponents used for this object + * The inspectorComponents from the parent class are also included * @returns {InspectorComponent[]} array of all inspectorComponents */ get inspectorComponents() { diff --git a/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs b/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs index 20e0ca81..1d9e9592 100644 --- a/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs +++ b/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs @@ -6,6 +6,11 @@ import { } from "inspectorComponents"; import { Vector3 } from "three"; +/** + * Class that represents movable canvas objects + * For now this includes Heliostats and Receivers + * @extends {CanvasObject} + */ export class movableCanvasObject extends CanvasObject { #positionComponent; #lastPosition; @@ -14,6 +19,8 @@ export class movableCanvasObject extends CanvasObject { * Creates a new movable object * @param {string} movableObjectName the name of the movable object * @param {import("undoRedoHandler").UndoRedoHandler} undoRedoHandler the undo redo handler + * @param {THREE.Vector3} position the position of the movable object + * @param {string} defaultLabel the default label when no name is given */ constructor(movableObjectName, undoRedoHandler, position, defaultLabel) { super(movableObjectName, undoRedoHandler, defaultLabel, true, true); diff --git a/canvas_editor/static/js/message_dict.js b/canvas_editor/static/js/message_dict.js index 86145759..c64b8d9c 100644 --- a/canvas_editor/static/js/message_dict.js +++ b/canvas_editor/static/js/message_dict.js @@ -12,3 +12,8 @@ export const invalidCompassStyleError = "Invalid compass style specified"; export const projectIdRequiredError = "When executing get instance for the first time the project id is needed"; export const errorUploadingFile = "Error uploading file:"; +export const updateNameCommandNotImplementedError = + "updateNameCommand not implemented"; +export const duplicateCommandNotImplementedError = + "duplicateCommand not implemented"; +export const deleteCommandNotImplementedError = "deleteCommand not implemented"; From b5a0bb2516731f6fd80ad786b8b0c08d94d9d140 Mon Sep 17 00:00:00 2001 From: Lisann Engel Date: Tue, 11 Nov 2025 16:20:14 +0100 Subject: [PATCH 07/11] Merge main into 73-reduce-code-duplication and add shared CanvasObject logic --- .../static/js/editor/objects/canvasObject.mjs | 25 +-- .../static/js/editor/objects/lightSource.mjs | 12 +- .../editor/objects/movableCanvasObjects.mjs | 40 ++--- .../static/js/editor/objects/receiver.mjs | 147 ++---------------- canvas_editor/static/js/message_dict.js | 6 +- 5 files changed, 38 insertions(+), 192 deletions(-) diff --git a/canvas_editor/static/js/editor/objects/canvasObject.mjs b/canvas_editor/static/js/editor/objects/canvasObject.mjs index 8e40daec..a0f1225e 100644 --- a/canvas_editor/static/js/editor/objects/canvasObject.mjs +++ b/canvas_editor/static/js/editor/objects/canvasObject.mjs @@ -1,7 +1,4 @@ -import { - HeaderInspectorComponent, - InspectorComponent, -} from "inspectorComponents"; +import { HeaderInspectorComponent, InspectorComponent } from "inspectorComponents"; import { Object3D, Vector3 } from "three"; import * as THREE from "three"; import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js"; @@ -33,14 +30,7 @@ export class CanvasObject extends Object3D { * @param {boolean} isSelectable whether the object is selectable * @param {string[]} rotatableAxis containing all rotatable axis */ - constructor( - name, - undoRedoHandler, - defaultLabel, - isMovable, - isSelectable, - rotatableAxis = [] - ) { + constructor(name, undoRedoHandler, defaultLabel, isMovable, isSelectable, rotatableAxis = []) { super(); this.objectName = name; this.#undoRedoHandler = undoRedoHandler; @@ -49,12 +39,9 @@ export class CanvasObject extends Object3D { this.#isSelectable = isSelectable; this.#headerComponent = new HeaderInspectorComponent( - () => - this.objectName !== "" && this.objectName - ? this.objectName - : defaultLabel, + () => (this.objectName !== "" && this.objectName ? this.objectName : defaultLabel), (newValue) => this.updateAndSaveObjectName(newValue), - this + this, ); } @@ -70,9 +57,7 @@ export class CanvasObject extends Object3D { throw new Error(updateNameCommandNotImplementedError); } - this.#undoRedoHandler.executeCommand( - new UpdatePropertyCommand(this, "objectName", name) - ); + this.#undoRedoHandler.executeCommand(new UpdatePropertyCommand(this, "objectName", name)); } /** diff --git a/canvas_editor/static/js/editor/objects/lightSource.mjs b/canvas_editor/static/js/editor/objects/lightSource.mjs index 64f86b5d..6558a90b 100644 --- a/canvas_editor/static/js/editor/objects/lightSource.mjs +++ b/canvas_editor/static/js/editor/objects/lightSource.mjs @@ -57,7 +57,7 @@ export class LightSource extends CanvasObject { distributionType, distributionMean, distributionCovariance, - apiID = null + apiID = null, ) { super(lightSourceName, UndoRedoHandler.getInstance(), "Light Source", false, false); this.apiID = apiID; @@ -74,7 +74,7 @@ export class LightSource extends CanvasObject { (newValue) => { this.#undoRedoHandler.executeCommand(new UpdateLightsourceCommand(this, "numberOfRays", newValue)); }, - -Infinity + -Infinity, ); this.#lightsourceTypeComponent = new SelectFieldInspectorComponent( @@ -83,7 +83,7 @@ export class LightSource extends CanvasObject { () => this.lightSourceType, (newValue) => { this.#undoRedoHandler.executeCommand(new UpdateLightsourceCommand(this, "lightSourceType", newValue)); - } + }, ); this.#distributionTypeComponent = new SelectFieldInspectorComponent( @@ -92,7 +92,7 @@ export class LightSource extends CanvasObject { () => this.distributionType, (newValue) => { this.#undoRedoHandler.executeCommand(new UpdateLightsourceCommand(this, "distributionType", newValue)); - } + }, ); this.#distributionMeanComponent = new SingleFieldInspectorComponent( @@ -102,7 +102,7 @@ export class LightSource extends CanvasObject { (newValue) => { this.#undoRedoHandler.executeCommand(new UpdateLightsourceCommand(this, "distributionMean", newValue)); }, - -Infinity + -Infinity, ); this.#distributionCovarianceComponent = new SingleFieldInspectorComponent( @@ -112,7 +112,7 @@ export class LightSource extends CanvasObject { (newValue) => { this.#undoRedoHandler.executeCommand(new UpdateLightsourceCommand(this, "distributionCovariance", newValue)); }, - -Infinity + -Infinity, ); } diff --git a/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs b/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs index 1d9e9592..120fddbb 100644 --- a/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs +++ b/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs @@ -1,9 +1,5 @@ import { CanvasObject } from "canvasObject"; -import { - InspectorComponent, - MultiFieldInspectorComponent, - SingleFieldInspectorComponent, -} from "inspectorComponents"; +import { InspectorComponent, MultiFieldInspectorComponent, SingleFieldInspectorComponent } from "inspectorComponents"; import { Vector3 } from "three"; /** @@ -33,14 +29,10 @@ export class movableCanvasObject extends CanvasObject { () => this.position.x, (newValue) => { this.undoRedoHandler.executeCommand( - new this.updatePropertyCommand( - this, - "position", - new Vector3(newValue, this.position.y, this.position.z) - ) + new this.updatePropertyCommand(this, "position", new Vector3(newValue, this.position.y, this.position.z)), ); }, - -Infinity + -Infinity, ); const uCoordinate = new SingleFieldInspectorComponent( @@ -49,14 +41,10 @@ export class movableCanvasObject extends CanvasObject { () => this.position.y, (newValue) => { this.undoRedoHandler.executeCommand( - new this.updatePropertyCommand( - this, - "position", - new Vector3(this.position.x, newValue, this.position.z) - ) + new this.updatePropertyCommand(this, "position", new Vector3(this.position.x, newValue, this.position.z)), ); }, - 0 + 0, ); const eCoordinate = new SingleFieldInspectorComponent( @@ -65,21 +53,13 @@ export class movableCanvasObject extends CanvasObject { () => this.position.z, (newValue) => { this.undoRedoHandler.executeCommand( - new this.updatePropertyCommand( - this, - "position", - new Vector3(this.position.x, this.position.y, newValue) - ) + new this.updatePropertyCommand(this, "position", new Vector3(this.position.x, this.position.y, newValue)), ); }, - -Infinity + -Infinity, ); - this.#positionComponent = new MultiFieldInspectorComponent("Position", [ - nCoordinate, - uCoordinate, - eCoordinate, - ]); + this.#positionComponent = new MultiFieldInspectorComponent("Position", [nCoordinate, uCoordinate, eCoordinate]); } /** @@ -96,9 +76,7 @@ export class movableCanvasObject extends CanvasObject { * @param {Vector3} position - the new position of the heliostat */ updateAndSaveObjectPosition(position) { - this.undoRedoHandler.executeCommand( - new this.updatePropertyCommand(this, "position", position) - ); + this.undoRedoHandler.executeCommand(new this.updatePropertyCommand(this, "position", position)); } /** * Get the current position of the object diff --git a/canvas_editor/static/js/editor/objects/receiver.mjs b/canvas_editor/static/js/editor/objects/receiver.mjs index fae18573..ed5f8343 100644 --- a/canvas_editor/static/js/editor/objects/receiver.mjs +++ b/canvas_editor/static/js/editor/objects/receiver.mjs @@ -91,7 +91,7 @@ export class Receiver extends movableCanvasObject { resolutionU, curvatureE, curvatureU, - apiID = null + apiID = null, ) { super(receiverName, UndoRedoHandler.getInstance(), position, "Receiver"); // place the 3D object @@ -112,55 +112,6 @@ export class Receiver extends movableCanvasObject { this.resolutionU = resolutionU; this.curvatureE = curvatureE; this.curvatureU = curvatureU; -<<<<<<< HEAD -======= - this.#lastPosition = new Vector3(position.x, position.y, position.z); - - // create components for the inspector - this.#headerComponent = new HeaderInspectorComponent( - () => (this.objectName !== "" && this.objectName ? this.objectName : "Receiver"), - (name) => this.updateAndSaveObjectName(name), - this, - ); - - const nCoordinate = new SingleFieldInspectorComponent( - "N", - "number", - () => this.lastPosition.x, - (newValue) => { - this.#undoRedoHandler.executeCommand( - new UpdateReceiverCommand(this, "position", new Vector3(newValue, this.position.y, this.position.z)), - ); - }, - -Infinity, - ); - - const uCoordinate = new SingleFieldInspectorComponent( - "U", - "number", - () => this.lastPosition.y, - (newValue) => { - this.#undoRedoHandler.executeCommand( - new UpdateReceiverCommand(this, "position", new Vector3(this.position.x, newValue, this.position.z)), - ); - }, - 0, - ); - - const eCoordinate = new SingleFieldInspectorComponent( - "E", - "number", - () => this.lastPosition.z, - (newValue) => { - this.#undoRedoHandler.executeCommand( - new UpdateReceiverCommand(this, "position", new Vector3(this.position.x, this.position.y, newValue)), - ); - }, - -Infinity, - ); - - this.#positionComponent = new MultiFieldInspectorComponent("Position", [nCoordinate, uCoordinate, eCoordinate]); ->>>>>>> origin/main const nNormalVector = new SingleFieldInspectorComponent( "N", @@ -171,11 +122,11 @@ export class Receiver extends movableCanvasObject { new UpdateReceiverCommand( this, "normalVector", - new Vector3(newValue, this.normalVector.y, this.normalVector.z) - ) + new Vector3(newValue, this.normalVector.y, this.normalVector.z), + ), ); }, - -Infinity + -Infinity, ); const uNormalVector = new SingleFieldInspectorComponent( @@ -187,11 +138,11 @@ export class Receiver extends movableCanvasObject { new UpdateReceiverCommand( this, "normalVector", - new Vector3(this.normalVector.x, newValue, this.normalVector.z) - ) + new Vector3(this.normalVector.x, newValue, this.normalVector.z), + ), ); }, - -Infinity + -Infinity, ); const eNormalVector = new SingleFieldInspectorComponent( @@ -203,40 +154,26 @@ export class Receiver extends movableCanvasObject { new UpdateReceiverCommand( this, "normalVector", - new Vector3(this.normalVector.x, this.normalVector.y, newValue) - ) + new Vector3(this.normalVector.x, this.normalVector.y, newValue), + ), ); }, - -Infinity + -Infinity, ); -<<<<<<< HEAD - this.#normalVectorComponent = new MultiFieldInspectorComponent( - "Normal Vector", - [nNormalVector, uNormalVector, eNormalVector] - ); -======= this.#normalVectorComponent = new MultiFieldInspectorComponent("Normal Vector", [ nNormalVector, uNormalVector, eNormalVector, ]); ->>>>>>> origin/main this.#towerTypeComponent = new SelectFieldInspectorComponent( "Type", [{ label: "planar", value: "planar" }], () => this.towerType, (newValue) => { -<<<<<<< HEAD - this.#undoRedoHandler.executeCommand( - new UpdateReceiverCommand(this, "towerType", newValue) - ); - } -======= this.#undoRedoHandler.executeCommand(new UpdateReceiverCommand(this, "towerType", newValue)); }, ->>>>>>> origin/main ); const eCurvature = new SingleFieldInspectorComponent( @@ -244,15 +181,9 @@ export class Receiver extends movableCanvasObject { "number", () => this.curvatureE, (newValue) => { -<<<<<<< HEAD - this.#undoRedoHandler.executeCommand( - new UpdateReceiverCommand(this, "curvatureE", newValue) - ); -======= this.#undoRedoHandler.executeCommand(new UpdateReceiverCommand(this, "curvatureE", newValue)); ->>>>>>> origin/main }, - -Infinity + -Infinity, ); const uCurvature = new SingleFieldInspectorComponent( @@ -260,15 +191,9 @@ export class Receiver extends movableCanvasObject { "number", () => this.curvatureU, (newValue) => { -<<<<<<< HEAD - this.#undoRedoHandler.executeCommand( - new UpdateReceiverCommand(this, "curvatureU", newValue) - ); -======= this.#undoRedoHandler.executeCommand(new UpdateReceiverCommand(this, "curvatureU", newValue)); ->>>>>>> origin/main }, - -Infinity + -Infinity, ); this.#curvatureComponent = new MultiFieldInspectorComponent("Curvature", [eCurvature, uCurvature]); @@ -278,15 +203,9 @@ export class Receiver extends movableCanvasObject { "number", () => this.planeE, (newValue) => { -<<<<<<< HEAD - this.#undoRedoHandler.executeCommand( - new UpdateReceiverCommand(this, "planeE", newValue) - ); -======= this.#undoRedoHandler.executeCommand(new UpdateReceiverCommand(this, "planeE", newValue)); ->>>>>>> origin/main }, - -Infinity + -Infinity, ); const uPlane = new SingleFieldInspectorComponent( @@ -294,15 +213,9 @@ export class Receiver extends movableCanvasObject { "number", () => this.planeU, (newValue) => { -<<<<<<< HEAD - this.#undoRedoHandler.executeCommand( - new UpdateReceiverCommand(this, "planeU", newValue) - ); -======= this.#undoRedoHandler.executeCommand(new UpdateReceiverCommand(this, "planeU", newValue)); ->>>>>>> origin/main }, - -Infinity + -Infinity, ); this.#planeComponent = new MultiFieldInspectorComponent("Plane", [ePlane, uPlane]); @@ -312,15 +225,9 @@ export class Receiver extends movableCanvasObject { "number", () => this.resolutionE, (newValue) => { -<<<<<<< HEAD - this.#undoRedoHandler.executeCommand( - new UpdateReceiverCommand(this, "resolutionE", newValue) - ); -======= this.#undoRedoHandler.executeCommand(new UpdateReceiverCommand(this, "resolutionE", newValue)); ->>>>>>> origin/main }, - -Infinity + -Infinity, ); const uResolution = new SingleFieldInspectorComponent( @@ -328,15 +235,9 @@ export class Receiver extends movableCanvasObject { "number", () => this.resolutionU, (newValue) => { -<<<<<<< HEAD - this.#undoRedoHandler.executeCommand( - new UpdateReceiverCommand(this, "resolutionU", newValue) - ); -======= this.#undoRedoHandler.executeCommand(new UpdateReceiverCommand(this, "resolutionU", newValue)); ->>>>>>> origin/main }, - -Infinity + -Infinity, ); this.#resolutionComponent = new MultiFieldInspectorComponent("Resolution", [eResolution, uResolution]); @@ -351,17 +252,6 @@ export class Receiver extends movableCanvasObject { } /** -<<<<<<< HEAD -======= - * Updates the position of the receiver - * @param {Vector3} position - the new position of the receiver - */ - updateAndSaveObjectPosition(position) { - this.#undoRedoHandler.executeCommand(new UpdateReceiverCommand(this, "position", position)); - } - - /** ->>>>>>> origin/main * Updates the receiver’s position by adjusting both the base and the top, ensuring that the base remains on the ground. * @param {THREE.Vector3} position the new position of the receiver */ @@ -374,13 +264,8 @@ export class Receiver extends movableCanvasObject { * Returns the command class used to update the name of the object * @returns {new (...args: any[]) => Command} the command class used to update the name */ -<<<<<<< HEAD get updatePropertyCommand() { return UpdateReceiverCommand; -======= - updateAndSaveObjectName(name) { - this.#undoRedoHandler.executeCommand(new UpdateReceiverCommand(this, "objectName", name)); ->>>>>>> origin/main } /** diff --git a/canvas_editor/static/js/message_dict.js b/canvas_editor/static/js/message_dict.js index ef238173..3888b458 100644 --- a/canvas_editor/static/js/message_dict.js +++ b/canvas_editor/static/js/message_dict.js @@ -10,8 +10,6 @@ export const methodMustBeImplementedError = "This method must be implemented in export const invalidCompassStyleError = "Invalid compass style specified"; export const projectIdRequiredError = "When executing get instance for the first time the project id is needed"; export const errorUploadingFile = "Error uploading file:"; -export const updateNameCommandNotImplementedError = - "updateNameCommand not implemented"; -export const duplicateCommandNotImplementedError = - "duplicateCommand not implemented"; +export const updateNameCommandNotImplementedError = "updateNameCommand not implemented"; +export const duplicateCommandNotImplementedError = "duplicateCommand not implemented"; export const deleteCommandNotImplementedError = "deleteCommand not implemented"; From f3724b0aec60a92e8375264745a002b53bfb5438 Mon Sep 17 00:00:00 2001 From: Lisann Engel Date: Mon, 17 Nov 2025 12:22:48 +0100 Subject: [PATCH 08/11] minor eslint fixes --- canvas_editor/static/js/editor/objects/canvasObject.mjs | 5 ----- .../static/js/editor/objects/movableCanvasObjects.mjs | 8 ++++---- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/canvas_editor/static/js/editor/objects/canvasObject.mjs b/canvas_editor/static/js/editor/objects/canvasObject.mjs index a0f1225e..746dc928 100644 --- a/canvas_editor/static/js/editor/objects/canvasObject.mjs +++ b/canvas_editor/static/js/editor/objects/canvasObject.mjs @@ -8,7 +8,6 @@ import { duplicateCommandNotImplementedError, updateNameCommandNotImplementedError, } from "message_dict"; -import { Command } from "command"; /** * Represents a Object in CANVAS @@ -50,7 +49,6 @@ export class CanvasObject extends Object3D { * @param {string} name the new name * @returns {void} */ - // eslint-disable-next-line no-unused-vars -- required for interface compatibility updateAndSaveObjectName(name) { const UpdatePropertyCommand = this.updatePropertyCommand; if (!UpdatePropertyCommand) { @@ -134,7 +132,6 @@ export class CanvasObject extends Object3D { * Returns the command class used to update the name of the object * @abstract * @throws {Error} Throws an error if the method is not implemented in subclasses. - * @returns {new (...args: any[]) => Command} */ get updatePropertyCommand() { throw new Error(methodMustBeImplementedError); @@ -144,7 +141,6 @@ export class CanvasObject extends Object3D { * Returns the command class used to duplicate the object * @abstract * @throws {Error} - Throws an error if the method is not implemented in subclasses. - * @returns {new (...args: any[]) => Command} */ get duplicateCommand() { throw new Error(methodMustBeImplementedError); @@ -154,7 +150,6 @@ export class CanvasObject extends Object3D { * Returns the command class used to delete the object * @abstract * @throws {Error} - Throws an error if the method is not implemented in subclasses. - * @returns {new (...args: any[]) => Command} */ get deleteCommand() { throw new Error(methodMustBeImplementedError); diff --git a/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs b/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs index 120fddbb..df44ba27 100644 --- a/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs +++ b/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs @@ -5,7 +5,7 @@ import { Vector3 } from "three"; /** * Class that represents movable canvas objects * For now this includes Heliostats and Receivers - * @extends {CanvasObject} + * @augments {CanvasObject} */ export class movableCanvasObject extends CanvasObject { #positionComponent; @@ -15,7 +15,7 @@ export class movableCanvasObject extends CanvasObject { * Creates a new movable object * @param {string} movableObjectName the name of the movable object * @param {import("undoRedoHandler").UndoRedoHandler} undoRedoHandler the undo redo handler - * @param {THREE.Vector3} position the position of the movable object + * @param {Vector3} position the position of the movable object * @param {string} defaultLabel the default label when no name is given */ constructor(movableObjectName, undoRedoHandler, position, defaultLabel) { @@ -64,7 +64,7 @@ export class movableCanvasObject extends CanvasObject { /** * Updates the position of the heliostat - * @param {THREE.Vector3} position the new position + * @param {Vector3} position the new position */ updatePosition(position) { this.position.copy(position); @@ -80,7 +80,7 @@ export class movableCanvasObject extends CanvasObject { } /** * Get the current position of the object - * @returns {THREE.Vector3} the position of the object + * @returns {Vector3} the position of the object */ get lastPosition() { return this.#lastPosition; From 15f50ad2359a3e5d21ab60dc2883cac8fb964a01 Mon Sep 17 00:00:00 2001 From: Lisann Engel Date: Tue, 18 Nov 2025 11:20:22 +0100 Subject: [PATCH 09/11] Replace inheritance with composition for movable objects --- .../static/js/editor/objects/canvasObject.mjs | 4 ++ .../static/js/editor/objects/heliostat.mjs | 47 ++++++++++++--- .../editor/objects/movableCanvasObjects.mjs | 60 ++++++++++++------- .../static/js/editor/objects/receiver.mjs | 37 +++++++++--- 4 files changed, 110 insertions(+), 38 deletions(-) diff --git a/canvas_editor/static/js/editor/objects/canvasObject.mjs b/canvas_editor/static/js/editor/objects/canvasObject.mjs index 746dc928..5c6d10d9 100644 --- a/canvas_editor/static/js/editor/objects/canvasObject.mjs +++ b/canvas_editor/static/js/editor/objects/canvasObject.mjs @@ -8,6 +8,7 @@ import { duplicateCommandNotImplementedError, updateNameCommandNotImplementedError, } from "message_dict"; +import { Command } from "command"; /** * Represents a Object in CANVAS @@ -132,6 +133,7 @@ export class CanvasObject extends Object3D { * Returns the command class used to update the name of the object * @abstract * @throws {Error} Throws an error if the method is not implemented in subclasses. + * @returns {new (...args: any[]) => Command} the command class used to update the name */ get updatePropertyCommand() { throw new Error(methodMustBeImplementedError); @@ -141,6 +143,7 @@ export class CanvasObject extends Object3D { * Returns the command class used to duplicate the object * @abstract * @throws {Error} - Throws an error if the method is not implemented in subclasses. + * @returns {new (...args: any[]) => Command} the command class used to duplicate the object */ get duplicateCommand() { throw new Error(methodMustBeImplementedError); @@ -150,6 +153,7 @@ export class CanvasObject extends Object3D { * Returns the command class used to delete the object * @abstract * @throws {Error} - Throws an error if the method is not implemented in subclasses. + * @returns {new (...args: any[]) => Command} the command class used to delete the object */ get deleteCommand() { throw new Error(methodMustBeImplementedError); diff --git a/canvas_editor/static/js/editor/objects/heliostat.mjs b/canvas_editor/static/js/editor/objects/heliostat.mjs index 5d2398e8..c4800831 100644 --- a/canvas_editor/static/js/editor/objects/heliostat.mjs +++ b/canvas_editor/static/js/editor/objects/heliostat.mjs @@ -1,4 +1,4 @@ -import { loadGltf } from "canvasObject"; +import { CanvasObject, loadGltf } from "canvasObject"; import { DeleteHeliostatCommand } from "deleteCommands"; import { DuplicateHeliostatCommand } from "duplicateCommands"; import { InspectorComponent } from "inspectorComponents"; @@ -11,15 +11,17 @@ import { movableCanvasObject } from "movableCanvasObjects"; /** * Class that represents the Heliostat object */ -export class Heliostat extends movableCanvasObject { +export class Heliostat extends CanvasObject { /** * The api id used for this heliostat. * @type {number} */ apiID; + /** - * @type { string[] } + * @type {movableCanvasObject} */ + #movement; /** * Creates a Heliostat object @@ -28,10 +30,16 @@ export class Heliostat extends movableCanvasObject { * @param {number} [apiID] The id for api usage */ constructor(heliostatName, position, apiID = null) { - super(heliostatName, UndoRedoHandler.getInstance(), position, "Heliostat"); + super(heliostatName, UndoRedoHandler.getInstance(), "Heliostat", true, true, null); loadGltf("/static/models/heliostat.glb", this, true); this.position.copy(position); this.apiID = apiID; + + /** + * @type {movableCanvasObject} + */ + this.#movement = new movableCanvasObject(this, position, UpdateHeliostatCommand); + this.updatePosition(position); } /** @@ -59,13 +67,34 @@ export class Heliostat extends movableCanvasObject { } /** - * Get an array of all inspectorComponents for this object - * The inspectorComponents from the parent class are also included - * Header component is already included from CanvasObject class - * and position components from movableCanvasObject class + * Call the movableCanvasObject to update the position + * @param {THREE.Vector3} position the new position of the heliostat + */ + updatePosition(position) { + this.#movement.updatePosition(position); + } + /** + * Call the movableCanvasObject to update and save the position + * @param {THREE.Vector3} position the new position of the heliostat + */ + updateAndSaveObjectPosition(position) { + this.#movement.updateAndSaveObjectPosition(position); + } + + /** + * Get the last Positon of the object from the movableCanvasObject + * @returns {THREE.Vector3} the last position of the object + */ + get lastPosition() { + return this.#movement.lastPosition; + } + /** + * Get the inspectorComponents used for this object + * The inspector components are included by the canvas objects + * The position inspector components are included by the movableCanvasObject * @returns {InspectorComponent[]} array of inspectorComponents */ get inspectorComponents() { - return [...super.inspectorComponents]; + return [...super.inspectorComponents, ...this.#movement.inspectorComponents]; } } diff --git a/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs b/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs index df44ba27..5cdbb9be 100644 --- a/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs +++ b/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs @@ -1,35 +1,43 @@ import { CanvasObject } from "canvasObject"; +import { Command } from "command"; import { InspectorComponent, MultiFieldInspectorComponent, SingleFieldInspectorComponent } from "inspectorComponents"; import { Vector3 } from "three"; /** * Class that represents movable canvas objects * For now this includes Heliostats and Receivers - * @augments {CanvasObject} */ -export class movableCanvasObject extends CanvasObject { +export class movableCanvasObject { + #target; #positionComponent; #lastPosition; - /** - * Creates a new movable object - * @param {string} movableObjectName the name of the movable object - * @param {import("undoRedoHandler").UndoRedoHandler} undoRedoHandler the undo redo handler - * @param {Vector3} position the position of the movable object - * @param {string} defaultLabel the default label when no name is given + * @type {new (...args: any[]) => Command} */ - constructor(movableObjectName, undoRedoHandler, position, defaultLabel) { - super(movableObjectName, undoRedoHandler, defaultLabel, true, true); + #updatePropertyCommand; + /** + * The constructor of the movable canvas object + * @param {CanvasObject} target the target object + * @param {Vector3} position the initial position + * @param {new (...args: any[]) => Command} updatePropertyCommand the command class used to update the position + */ + constructor(target, position, updatePropertyCommand) { + this.#target = target; this.#lastPosition = new Vector3(position.x, position.y, position.z); + this.#updatePropertyCommand = updatePropertyCommand; const nCoordinate = new SingleFieldInspectorComponent( "N", "number", - () => this.position.x, + () => this.#target.position.x, (newValue) => { - this.undoRedoHandler.executeCommand( - new this.updatePropertyCommand(this, "position", new Vector3(newValue, this.position.y, this.position.z)), + this.#target.undoRedoHandler.executeCommand( + new this.#updatePropertyCommand( + this.#target, + "position", + new Vector3(newValue, this.#target.position.y, this.#target.position.z), + ), ); }, -Infinity, @@ -38,10 +46,14 @@ export class movableCanvasObject extends CanvasObject { const uCoordinate = new SingleFieldInspectorComponent( "U", "number", - () => this.position.y, + () => this.#target.position.y, (newValue) => { - this.undoRedoHandler.executeCommand( - new this.updatePropertyCommand(this, "position", new Vector3(this.position.x, newValue, this.position.z)), + this.#target.undoRedoHandler.executeCommand( + new this.#updatePropertyCommand( + this.#target, + "position", + new Vector3(this.#target.position.x, newValue, this.#target.position.z), + ), ); }, 0, @@ -50,10 +62,14 @@ export class movableCanvasObject extends CanvasObject { const eCoordinate = new SingleFieldInspectorComponent( "E", "number", - () => this.position.z, + () => this.#target.position.z, (newValue) => { - this.undoRedoHandler.executeCommand( - new this.updatePropertyCommand(this, "position", new Vector3(this.position.x, this.position.y, newValue)), + this.#target.undoRedoHandler.executeCommand( + new this.#updatePropertyCommand( + this.#target, + "position", + new Vector3(this.#target.position.x, this.#target.position.y, newValue), + ), ); }, -Infinity, @@ -67,7 +83,7 @@ export class movableCanvasObject extends CanvasObject { * @param {Vector3} position the new position */ updatePosition(position) { - this.position.copy(position); + this.#target.position.copy(position); this.#lastPosition = new Vector3(position.x, position.y, position.z); } @@ -76,7 +92,7 @@ export class movableCanvasObject extends CanvasObject { * @param {Vector3} position - the new position of the heliostat */ updateAndSaveObjectPosition(position) { - this.undoRedoHandler.executeCommand(new this.updatePropertyCommand(this, "position", position)); + this.#target.undoRedoHandler.executeCommand(new this.#updatePropertyCommand(this.#target, "position", position)); } /** * Get the current position of the object @@ -91,6 +107,6 @@ export class movableCanvasObject extends CanvasObject { * @returns {InspectorComponent[]} array of all inspectorComponents */ get inspectorComponents() { - return [...super.inspectorComponents, this.#positionComponent]; + return [this.#positionComponent]; } } diff --git a/canvas_editor/static/js/editor/objects/receiver.mjs b/canvas_editor/static/js/editor/objects/receiver.mjs index ed5f8343..30dd2017 100644 --- a/canvas_editor/static/js/editor/objects/receiver.mjs +++ b/canvas_editor/static/js/editor/objects/receiver.mjs @@ -1,4 +1,4 @@ -import { loadGltf } from "canvasObject"; +import { CanvasObject, loadGltf } from "canvasObject"; import { DeleteReceiverCommand } from "deleteCommands"; import { DuplicateReceiverCommand } from "duplicateCommands"; import { @@ -14,11 +14,10 @@ import * as THREE from "three"; import { towerBasePath, towerTopPath } from "path_dict"; import { Command } from "command"; import { movableCanvasObject } from "movableCanvasObjects"; - /** * Class that represents the receiver object */ -export class Receiver extends movableCanvasObject { +export class Receiver extends CanvasObject { /** * The apiID used for this receiver */ @@ -57,6 +56,11 @@ export class Receiver extends movableCanvasObject { curvatureU; #undoRedoHandler = UndoRedoHandler.getInstance(); + /** + * @type {movableCanvasObject} + */ + #movement; + #top; #base; @@ -93,7 +97,7 @@ export class Receiver extends movableCanvasObject { curvatureU, apiID = null, ) { - super(receiverName, UndoRedoHandler.getInstance(), position, "Receiver"); + super(receiverName, UndoRedoHandler.getInstance(), "Receiver", true, true, null); // place the 3D object this.#base = new ReceiverBase(); this.add(this.#base); @@ -101,8 +105,6 @@ export class Receiver extends movableCanvasObject { this.#top = new ReceiverTop(); this.add(this.#top); - this.updatePosition(position); - this.apiID = apiID; this.towerType = towerType; this.normalVector = normalVector; @@ -113,6 +115,9 @@ export class Receiver extends movableCanvasObject { this.curvatureE = curvatureE; this.curvatureU = curvatureU; + this.#movement = new movableCanvasObject(this, position, UpdateReceiverCommand); + this.updatePosition(position); + const nNormalVector = new SingleFieldInspectorComponent( "N", "number", @@ -256,7 +261,7 @@ export class Receiver extends movableCanvasObject { * @param {THREE.Vector3} position the new position of the receiver */ updatePosition(position) { - super.updatePosition(position); + this.#movement.updatePosition(position); this.#base.position.y = -position.y; } @@ -284,13 +289,31 @@ export class Receiver extends movableCanvasObject { return DuplicateReceiverCommand; } + /** + * Call the movableCanvasObject to update and save the position + * @param {THREE.Vector3} position the new position of the heliostat + */ + updateAndSaveObjectPosition(position) { + this.#movement.updateAndSaveObjectPosition(position); + } + + /** + * Get the last Positon of the object from the movableCanvasObject + * @returns {THREE.Vector3} the last position of the object + */ + get lastPosition() { + return this.#movement.lastPosition; + } /** * Get the inspectorComponents used for this object + * Get the HeaderComponent from the super class canvasObject + * Get the InspectorComponents from the movableCanvasObject * @returns {InspectorComponent[]} array of the inspectorComponents used */ get inspectorComponents() { return [ ...super.inspectorComponents, + ...this.#movement.inspectorComponents, this.#normalVectorComponent, this.#towerTypeComponent, this.#curvatureComponent, From 89ba318e53840de6ebfdfb54cfdda1731df7c2b6 Mon Sep 17 00:00:00 2001 From: Lisann Engel Date: Wed, 19 Nov 2025 15:15:35 +0100 Subject: [PATCH 10/11] rename movableCanvasObject class to MovableCanvasObject class --- canvas_editor/static/js/editor/objects/heliostat.mjs | 8 ++++---- .../static/js/editor/objects/movableCanvasObjects.mjs | 2 +- canvas_editor/static/js/editor/objects/receiver.mjs | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/canvas_editor/static/js/editor/objects/heliostat.mjs b/canvas_editor/static/js/editor/objects/heliostat.mjs index c4800831..f335b027 100644 --- a/canvas_editor/static/js/editor/objects/heliostat.mjs +++ b/canvas_editor/static/js/editor/objects/heliostat.mjs @@ -6,7 +6,7 @@ import { UndoRedoHandler } from "undoRedoHandler"; import { UpdateHeliostatCommand } from "updateCommands"; import * as THREE from "three"; import { Command } from "command"; -import { movableCanvasObject } from "movableCanvasObjects"; +import { MovableCanvasObject } from "movableCanvasObjects"; /** * Class that represents the Heliostat object @@ -19,7 +19,7 @@ export class Heliostat extends CanvasObject { apiID; /** - * @type {movableCanvasObject} + * @type {MovableCanvasObject} */ #movement; @@ -36,9 +36,9 @@ export class Heliostat extends CanvasObject { this.apiID = apiID; /** - * @type {movableCanvasObject} + * @type {MovableCanvasObject} */ - this.#movement = new movableCanvasObject(this, position, UpdateHeliostatCommand); + this.#movement = new MovableCanvasObject(this, position, UpdateHeliostatCommand); this.updatePosition(position); } diff --git a/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs b/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs index 5cdbb9be..b371aa49 100644 --- a/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs +++ b/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs @@ -7,7 +7,7 @@ import { Vector3 } from "three"; * Class that represents movable canvas objects * For now this includes Heliostats and Receivers */ -export class movableCanvasObject { +export class MovableCanvasObject { #target; #positionComponent; #lastPosition; diff --git a/canvas_editor/static/js/editor/objects/receiver.mjs b/canvas_editor/static/js/editor/objects/receiver.mjs index 30dd2017..2db23bc1 100644 --- a/canvas_editor/static/js/editor/objects/receiver.mjs +++ b/canvas_editor/static/js/editor/objects/receiver.mjs @@ -13,7 +13,7 @@ import { UpdateReceiverCommand } from "updateCommands"; import * as THREE from "three"; import { towerBasePath, towerTopPath } from "path_dict"; import { Command } from "command"; -import { movableCanvasObject } from "movableCanvasObjects"; +import { MovableCanvasObject } from "movableCanvasObjects"; /** * Class that represents the receiver object */ @@ -57,7 +57,7 @@ export class Receiver extends CanvasObject { #undoRedoHandler = UndoRedoHandler.getInstance(); /** - * @type {movableCanvasObject} + * @type {MovableCanvasObject} */ #movement; @@ -115,7 +115,7 @@ export class Receiver extends CanvasObject { this.curvatureE = curvatureE; this.curvatureU = curvatureU; - this.#movement = new movableCanvasObject(this, position, UpdateReceiverCommand); + this.#movement = new MovableCanvasObject(this, position, UpdateReceiverCommand); this.updatePosition(position); const nNormalVector = new SingleFieldInspectorComponent( From 395543f256424ac4644edff9aed24c1ab3601197 Mon Sep 17 00:00:00 2001 From: Lisann Engel Date: Sun, 23 Nov 2025 16:05:15 +0100 Subject: [PATCH 11/11] pr review --- .../static/js/editor/objects/canvasObject.mjs | 6 +++--- canvas_editor/static/js/editor/objects/heliostat.mjs | 5 ++--- .../static/js/editor/objects/lightSource.mjs | 2 +- .../js/editor/objects/movableCanvasObjects.mjs | 12 +++++++++--- canvas_editor/static/js/editor/objects/receiver.mjs | 4 ++-- 5 files changed, 17 insertions(+), 12 deletions(-) diff --git a/canvas_editor/static/js/editor/objects/canvasObject.mjs b/canvas_editor/static/js/editor/objects/canvasObject.mjs index 5c6d10d9..3097daaa 100644 --- a/canvas_editor/static/js/editor/objects/canvasObject.mjs +++ b/canvas_editor/static/js/editor/objects/canvasObject.mjs @@ -9,6 +9,7 @@ import { updateNameCommandNotImplementedError, } from "message_dict"; import { Command } from "command"; +import { UndoRedoHandler } from "undoRedoHandler"; /** * Represents a Object in CANVAS @@ -24,16 +25,15 @@ export class CanvasObject extends Object3D { /** * Creates a new selectable object * @param {string} name the name of the object - * @param {import("undoRedoHandler").UndoRedoHandler} undoRedoHandler the undo redo handler * @param {string} defaultLabel the default label when no name is given * @param {boolean} isMovable whether the object is movable * @param {boolean} isSelectable whether the object is selectable * @param {string[]} rotatableAxis containing all rotatable axis */ - constructor(name, undoRedoHandler, defaultLabel, isMovable, isSelectable, rotatableAxis = []) { + constructor(name, defaultLabel, isMovable, isSelectable, rotatableAxis = []) { super(); this.objectName = name; - this.#undoRedoHandler = undoRedoHandler; + this.#undoRedoHandler = UndoRedoHandler.getInstance(); this.#rotatableAxis = rotatableAxis; this.#isMovable = isMovable; this.#isSelectable = isSelectable; diff --git a/canvas_editor/static/js/editor/objects/heliostat.mjs b/canvas_editor/static/js/editor/objects/heliostat.mjs index f335b027..d2b0a222 100644 --- a/canvas_editor/static/js/editor/objects/heliostat.mjs +++ b/canvas_editor/static/js/editor/objects/heliostat.mjs @@ -2,7 +2,6 @@ import { CanvasObject, loadGltf } from "canvasObject"; import { DeleteHeliostatCommand } from "deleteCommands"; import { DuplicateHeliostatCommand } from "duplicateCommands"; import { InspectorComponent } from "inspectorComponents"; -import { UndoRedoHandler } from "undoRedoHandler"; import { UpdateHeliostatCommand } from "updateCommands"; import * as THREE from "three"; import { Command } from "command"; @@ -30,7 +29,7 @@ export class Heliostat extends CanvasObject { * @param {number} [apiID] The id for api usage */ constructor(heliostatName, position, apiID = null) { - super(heliostatName, UndoRedoHandler.getInstance(), "Heliostat", true, true, null); + super(heliostatName, "Heliostat", true, true, null); loadGltf("/static/models/heliostat.glb", this, true); this.position.copy(position); this.apiID = apiID; @@ -82,7 +81,7 @@ export class Heliostat extends CanvasObject { } /** - * Get the last Positon of the object from the movableCanvasObject + * Get the last positon of the object from the movableCanvasObject * @returns {THREE.Vector3} the last position of the object */ get lastPosition() { diff --git a/canvas_editor/static/js/editor/objects/lightSource.mjs b/canvas_editor/static/js/editor/objects/lightSource.mjs index 6558a90b..ee1b4a5d 100644 --- a/canvas_editor/static/js/editor/objects/lightSource.mjs +++ b/canvas_editor/static/js/editor/objects/lightSource.mjs @@ -59,7 +59,7 @@ export class LightSource extends CanvasObject { distributionCovariance, apiID = null, ) { - super(lightSourceName, UndoRedoHandler.getInstance(), "Light Source", false, false); + super(lightSourceName, "Light Source", false, false); this.apiID = apiID; this.numberOfRays = numberOfRays; this.lightSourceType = lightSourceType; diff --git a/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs b/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs index b371aa49..c6f5aa56 100644 --- a/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs +++ b/canvas_editor/static/js/editor/objects/movableCanvasObjects.mjs @@ -79,7 +79,9 @@ export class MovableCanvasObject { } /** - * Updates the position of the heliostat + * Updates the position of the object + * + * Should only be used for internal updates (like inside commands) * @param {Vector3} position the new position */ updatePosition(position) { @@ -88,8 +90,12 @@ export class MovableCanvasObject { } /** - * Updates the position of the heliostat - * @param {Vector3} position - the new position of the heliostat + * Updates the position of the object + * and saves the change using the undoRedoHandler + * + * Use this method whenever the user intentionally changes a value and the change + * should be undoable, saved, and reflected in the UI. + * @param {Vector3} position - the new position of the object */ updateAndSaveObjectPosition(position) { this.#target.undoRedoHandler.executeCommand(new this.#updatePropertyCommand(this.#target, "position", position)); diff --git a/canvas_editor/static/js/editor/objects/receiver.mjs b/canvas_editor/static/js/editor/objects/receiver.mjs index 2db23bc1..a40050ea 100644 --- a/canvas_editor/static/js/editor/objects/receiver.mjs +++ b/canvas_editor/static/js/editor/objects/receiver.mjs @@ -97,7 +97,7 @@ export class Receiver extends CanvasObject { curvatureU, apiID = null, ) { - super(receiverName, UndoRedoHandler.getInstance(), "Receiver", true, true, null); + super(receiverName, "Receiver", true, true, null); // place the 3D object this.#base = new ReceiverBase(); this.add(this.#base); @@ -298,7 +298,7 @@ export class Receiver extends CanvasObject { } /** - * Get the last Positon of the object from the movableCanvasObject + * Get the last positon of the object from the movableCanvasObject * @returns {THREE.Vector3} the last position of the object */ get lastPosition() {