From caf3462911dfc1740555959fd41a3903bdbeb2da Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Wed, 5 Jul 2023 18:09:53 +0200 Subject: [PATCH] [Editor] Move the 'keep aspect ratio' stuff to the AnnotationEditor level It'll help to avoid code duplication between the different editors having this feature. --- src/display/editor/editor.js | 45 ++++++++++++++++++++++++++++++++++++ src/display/editor/ink.js | 42 ++++++++------------------------- 2 files changed, 54 insertions(+), 33 deletions(-) diff --git a/src/display/editor/editor.js b/src/display/editor/editor.js index 3751d8244..a974a88e4 100644 --- a/src/display/editor/editor.js +++ b/src/display/editor/editor.js @@ -21,6 +21,11 @@ import { bindEvents, ColorManager } from "./tools.js"; import { FeatureTest, shadow, unreachable } from "../../shared/util.js"; +// The dimensions of the resizer is 15x15: +// https://searchfox.org/mozilla-central/rev/1ce190047b9556c3c10ab4de70a0e61d893e2954/toolkit/content/minimal-xul.css#136-137 +// so each dimension must be greater than RESIZER_SIZE. +const RESIZER_SIZE = 16; + /** * @typedef {Object} AnnotationEditorParameters * @property {AnnotationEditorUIManager} uiManager - the global manager @@ -34,6 +39,8 @@ import { FeatureTest, shadow, unreachable } from "../../shared/util.js"; * Base class for editors. */ class AnnotationEditor { + #aspectRatio = 0; + #boundFocusin = this.focusin.bind(this); #boundFocusout = this.focusout.bind(this); @@ -614,6 +621,44 @@ class AnnotationEditor { this.parent.setActiveEditor(null); } } + + /** + * Set the minimum dimensions of the editor. + */ + setMinDims() { + const { style } = this.div; + if (this.#aspectRatio >= 1) { + style.minHeight = `${RESIZER_SIZE}px`; + style.minWidth = `${Math.round(this.#aspectRatio * RESIZER_SIZE)}px`; + } else { + style.minWidth = `${RESIZER_SIZE}px`; + style.minHeight = `${Math.round(RESIZER_SIZE / this.#aspectRatio)}px`; + } + } + + /** + * Set the aspect ratio to use when resizing. + * @param {number} width + * @param {number} height + */ + setAspectRatio(width, height) { + this.#aspectRatio = width / height; + } + + getHeight(width, height) { + if ( + this.#aspectRatio && + Math.abs(this.#aspectRatio - width / height) > 1e-2 + ) { + height = Math.ceil(width / this.#aspectRatio); + this.setDims(width, height); + } + return height; + } + + static get MIN_SIZE() { + return RESIZER_SIZE; + } } // This class is used to fake an editor which has been deleted. diff --git a/src/display/editor/ink.js b/src/display/editor/ink.js index 5ec0fdb1b..599e2b314 100644 --- a/src/display/editor/ink.js +++ b/src/display/editor/ink.js @@ -22,17 +22,10 @@ import { AnnotationEditor } from "./editor.js"; import { InkAnnotationElement } from "../annotation_layer.js"; import { opacityToHex } from "./tools.js"; -// The dimensions of the resizer is 15x15: -// https://searchfox.org/mozilla-central/rev/1ce190047b9556c3c10ab4de70a0e61d893e2954/toolkit/content/minimal-xul.css#136-137 -// so each dimension must be greater than RESIZER_SIZE. -const RESIZER_SIZE = 16; - /** * Basic draw editor in order to generate an Ink annotation. */ class InkEditor extends AnnotationEditor { - #aspectRatio = 0; - #baseHeight = 0; #baseWidth = 0; @@ -795,7 +788,7 @@ class InkEditor extends AnnotationEditor { this.#setCanvasDims(); this.setDims(this.width * parentWidth, this.height * parentHeight); this.#redraw(); - this.#setMinDims(); + this.setMinDims(); this.div.classList.add("disabled"); } else { this.div.classList.add("editing"); @@ -839,13 +832,7 @@ class InkEditor extends AnnotationEditor { this.canvas.style.visibility = "hidden"; - if ( - this.#aspectRatio && - Math.abs(this.#aspectRatio - width / height) > 1e-2 - ) { - height = Math.ceil(width / this.#aspectRatio); - this.setDims(width, height); - } + height = this.getHeight(width, height); const [parentWidth, parentHeight] = this.parentDimensions; this.width = width / parentWidth; @@ -1086,8 +1073,8 @@ class InkEditor extends AnnotationEditor { const bbox = this.#getBbox(); const padding = this.#getPadding(); - this.#baseWidth = Math.max(RESIZER_SIZE, bbox[2] - bbox[0]); - this.#baseHeight = Math.max(RESIZER_SIZE, bbox[3] - bbox[1]); + this.#baseWidth = Math.max(AnnotationEditor.MIN_SIZE, bbox[2] - bbox[0]); + this.#baseHeight = Math.max(AnnotationEditor.MIN_SIZE, bbox[3] - bbox[1]); const width = Math.ceil(padding + this.#baseWidth * this.scaleFactor); const height = Math.ceil(padding + this.#baseHeight * this.scaleFactor); @@ -1096,8 +1083,8 @@ class InkEditor extends AnnotationEditor { this.width = width / parentWidth; this.height = height / parentHeight; - this.#aspectRatio = width / height; - this.#setMinDims(); + this.setAspectRatio(width, height); + this.setMinDims(); const prevTranslationX = this.translationX; const prevTranslationY = this.translationY; @@ -1118,17 +1105,6 @@ class InkEditor extends AnnotationEditor { ); } - #setMinDims() { - const { style } = this.div; - if (this.#aspectRatio >= 1) { - style.minHeight = `${RESIZER_SIZE}px`; - style.minWidth = `${Math.round(this.#aspectRatio * RESIZER_SIZE)}px`; - } else { - style.minWidth = `${RESIZER_SIZE}px`; - style.minHeight = `${Math.round(RESIZER_SIZE / this.#aspectRatio)}px`; - } - } - /** @inheritdoc */ static deserialize(data, parent, uiManager) { if (data instanceof InkAnnotationElement) { @@ -1146,7 +1122,7 @@ class InkEditor extends AnnotationEditor { const scaleFactor = editor.parentScale; const padding = data.thickness / 2; - editor.#aspectRatio = width / height; + editor.setAspectRatio(width, height); editor.#disableEditing = true; editor.#realWidth = Math.round(width); editor.#realHeight = Math.round(height); @@ -1180,8 +1156,8 @@ class InkEditor extends AnnotationEditor { } const bbox = editor.#getBbox(); - editor.#baseWidth = Math.max(RESIZER_SIZE, bbox[2] - bbox[0]); - editor.#baseHeight = Math.max(RESIZER_SIZE, bbox[3] - bbox[1]); + editor.#baseWidth = Math.max(AnnotationEditor.MIN_SIZE, bbox[2] - bbox[0]); + editor.#baseHeight = Math.max(AnnotationEditor.MIN_SIZE, bbox[3] - bbox[1]); editor.#setScaleFactor(width, height); return editor;