[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 { 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.

View File

@ -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;