[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.
This commit is contained in:
Calixte Denizet 2023-07-05 18:09:53 +02:00
parent 66fc19b272
commit caf3462911
2 changed files with 54 additions and 33 deletions

View File

@ -21,6 +21,11 @@
import { bindEvents, ColorManager } from "./tools.js"; import { bindEvents, ColorManager } from "./tools.js";
import { FeatureTest, shadow, unreachable } from "../../shared/util.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 * @typedef {Object} AnnotationEditorParameters
* @property {AnnotationEditorUIManager} uiManager - the global manager * @property {AnnotationEditorUIManager} uiManager - the global manager
@ -34,6 +39,8 @@ import { FeatureTest, shadow, unreachable } from "../../shared/util.js";
* Base class for editors. * Base class for editors.
*/ */
class AnnotationEditor { class AnnotationEditor {
#aspectRatio = 0;
#boundFocusin = this.focusin.bind(this); #boundFocusin = this.focusin.bind(this);
#boundFocusout = this.focusout.bind(this); #boundFocusout = this.focusout.bind(this);
@ -614,6 +621,44 @@ class AnnotationEditor {
this.parent.setActiveEditor(null); 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. // This class is used to fake an editor which has been deleted.

View File

@ -22,17 +22,10 @@ import { AnnotationEditor } from "./editor.js";
import { InkAnnotationElement } from "../annotation_layer.js"; import { InkAnnotationElement } from "../annotation_layer.js";
import { opacityToHex } from "./tools.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. * Basic draw editor in order to generate an Ink annotation.
*/ */
class InkEditor extends AnnotationEditor { class InkEditor extends AnnotationEditor {
#aspectRatio = 0;
#baseHeight = 0; #baseHeight = 0;
#baseWidth = 0; #baseWidth = 0;
@ -795,7 +788,7 @@ class InkEditor extends AnnotationEditor {
this.#setCanvasDims(); this.#setCanvasDims();
this.setDims(this.width * parentWidth, this.height * parentHeight); this.setDims(this.width * parentWidth, this.height * parentHeight);
this.#redraw(); this.#redraw();
this.#setMinDims(); this.setMinDims();
this.div.classList.add("disabled"); this.div.classList.add("disabled");
} else { } else {
this.div.classList.add("editing"); this.div.classList.add("editing");
@ -839,13 +832,7 @@ class InkEditor extends AnnotationEditor {
this.canvas.style.visibility = "hidden"; this.canvas.style.visibility = "hidden";
if ( height = this.getHeight(width, height);
this.#aspectRatio &&
Math.abs(this.#aspectRatio - width / height) > 1e-2
) {
height = Math.ceil(width / this.#aspectRatio);
this.setDims(width, height);
}
const [parentWidth, parentHeight] = this.parentDimensions; const [parentWidth, parentHeight] = this.parentDimensions;
this.width = width / parentWidth; this.width = width / parentWidth;
@ -1086,8 +1073,8 @@ class InkEditor extends AnnotationEditor {
const bbox = this.#getBbox(); const bbox = this.#getBbox();
const padding = this.#getPadding(); const padding = this.#getPadding();
this.#baseWidth = Math.max(RESIZER_SIZE, bbox[2] - bbox[0]); this.#baseWidth = Math.max(AnnotationEditor.MIN_SIZE, bbox[2] - bbox[0]);
this.#baseHeight = Math.max(RESIZER_SIZE, bbox[3] - bbox[1]); this.#baseHeight = Math.max(AnnotationEditor.MIN_SIZE, bbox[3] - bbox[1]);
const width = Math.ceil(padding + this.#baseWidth * this.scaleFactor); const width = Math.ceil(padding + this.#baseWidth * this.scaleFactor);
const height = Math.ceil(padding + this.#baseHeight * this.scaleFactor); const height = Math.ceil(padding + this.#baseHeight * this.scaleFactor);
@ -1096,8 +1083,8 @@ class InkEditor extends AnnotationEditor {
this.width = width / parentWidth; this.width = width / parentWidth;
this.height = height / parentHeight; this.height = height / parentHeight;
this.#aspectRatio = width / height; this.setAspectRatio(width, height);
this.#setMinDims(); this.setMinDims();
const prevTranslationX = this.translationX; const prevTranslationX = this.translationX;
const prevTranslationY = this.translationY; 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 */ /** @inheritdoc */
static deserialize(data, parent, uiManager) { static deserialize(data, parent, uiManager) {
if (data instanceof InkAnnotationElement) { if (data instanceof InkAnnotationElement) {
@ -1146,7 +1122,7 @@ class InkEditor extends AnnotationEditor {
const scaleFactor = editor.parentScale; const scaleFactor = editor.parentScale;
const padding = data.thickness / 2; const padding = data.thickness / 2;
editor.#aspectRatio = width / height; editor.setAspectRatio(width, height);
editor.#disableEditing = true; editor.#disableEditing = true;
editor.#realWidth = Math.round(width); editor.#realWidth = Math.round(width);
editor.#realHeight = Math.round(height); editor.#realHeight = Math.round(height);
@ -1180,8 +1156,8 @@ class InkEditor extends AnnotationEditor {
} }
const bbox = editor.#getBbox(); const bbox = editor.#getBbox();
editor.#baseWidth = Math.max(RESIZER_SIZE, bbox[2] - bbox[0]); editor.#baseWidth = Math.max(AnnotationEditor.MIN_SIZE, bbox[2] - bbox[0]);
editor.#baseHeight = Math.max(RESIZER_SIZE, bbox[3] - bbox[1]); editor.#baseHeight = Math.max(AnnotationEditor.MIN_SIZE, bbox[3] - bbox[1]);
editor.#setScaleFactor(width, height); editor.#setScaleFactor(width, height);
return editor; return editor;