Skip to content

Commit

Permalink
fix: Fix bug that caused fields in the flyout to use the main workspa…
Browse files Browse the repository at this point in the history
…ce's scale.
  • Loading branch information
gonfunko committed Oct 1, 2024
1 parent ec5b6e7 commit e26d30e
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 7 deletions.
2 changes: 1 addition & 1 deletion core/field_input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ export abstract class FieldInput<T extends InputTypes> extends Field<
'spellcheck',
this.spellcheck_ as AnyDuringMigration,
);
const scale = this.workspace_!.getScale();
const scale = this.workspace_!.getAbsoluteScale();
const fontSize = this.getConstants()!.FIELD_TEXT_FONTSIZE * scale + 'pt';
div!.style.fontSize = fontSize;
htmlInput.style.fontSize = fontSize;
Expand Down
63 changes: 58 additions & 5 deletions core/workspace_svg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import * as ContextMenu from './contextmenu.js';
import {ContextMenuRegistry} from './contextmenu_registry.js';
import * as dropDownDiv from './dropdowndiv.js';
import * as eventUtils from './events/utils.js';
import {Flyout} from './flyout_base.js';
import type {FlyoutButton} from './flyout_button.js';
import {Gesture} from './gesture.js';
import {Grid} from './grid.js';
Expand Down Expand Up @@ -2022,18 +2023,70 @@ export class WorkspaceSvg extends Workspace implements IASTNodeLocationSvg {
}

/**
* Get the workspace's zoom factor. If the workspace has a parent, we call
* into the parent to get the workspace scale.
* Get the workspace's zoom factor.
*
* @returns The workspace zoom factor. Units: (pixels / workspaceUnit).
*/
getScale(): number {
if (this.options.parentWorkspace) {
return this.options.parentWorkspace.getScale();
}
return this.scale;
}

/**
* Returns the absolute scale of the workspace.
*
* Workspace scaling is multiplicative; if a workspace B (e.g. a mutator editor)
* with scale Y is nested within a root workspace A with scale X, workspace B's
* effective scale is X * Y, because, as a child of A, it is already transformed
* by A's scaling factor, and then further transforms itself by its own scaling
* factor. Normally this Just Works, but for global elements (e.g. field
* editors) that are visually associated with a particular workspace but live at
* the top level of the DOM rather than being a child of their associated
* workspace, the absolute/effective scale may be needed to render
* appropriately.
*
* @param workspace The workspace to determine the absolute/effective scale of.
* @returns The absolute/effective scale of the given workspace.
*/
getAbsoluteScale() {
// Returns a workspace's own scale, without regard to multiplicative scaling.
const getLocalScale = (workspace: WorkspaceSvg): number => {
// Workspaces in flyouts may have a distinct scale; use this if relevant.
if (workspace.isFlyout) {
const flyout = workspace.targetWorkspace?.getFlyout();
if (flyout instanceof Flyout) {
return flyout.getFlyoutScale();
}
}

return workspace.getScale();
};

const computeScale = (workspace: WorkspaceSvg, scale: number): number => {
// If the workspace has no parent, or it does have a parent but is not
// actually a child of its parent workspace in the DOM (this is the case for
// flyouts in the main workspace), we're done; just return the scale so far
// multiplied by the workspace's own scale.
if (
!workspace.options.parentWorkspace ||
!workspace.options.parentWorkspace
.getSvgGroup()
.contains(workspace.getSvgGroup())
) {
return scale * getLocalScale(workspace);
}

// If there is a parent workspace, and this workspace is a child of it in
// the DOM, scales are multiplicative, so recurse up the workspace
// hierarchy.
return computeScale(
workspace.options.parentWorkspace,
scale * getLocalScale(workspace),
);
};

return computeScale(this, 1);
}

/**
* Scroll the workspace to a specified offset (in pixels), keeping in the
* workspace bounds. See comment on workspaceSvg.scrollX for more detail on
Expand Down
2 changes: 1 addition & 1 deletion tests/mocha/field_textinput_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ suite('Text Input Fields', function () {
setup(function () {
this.prepField = function (field) {
const workspace = {
getScale: function () {
getAbsoluteScale: function () {
return 1;
},
getRenderer: function () {
Expand Down

0 comments on commit e26d30e

Please sign in to comment.