mirror of
https://github.com/google/blockly.git
synced 2026-01-09 01:50:11 +01:00
feat: Add support for inflating flyout separators. (#8592)
* feat: Add support for inflating flyout separators. * chore: Add license. * chore: Add TSDoc. * refactor: Allow specifying an axis for flyout separators.
This commit is contained in:
61
core/flyout_separator.ts
Normal file
61
core/flyout_separator.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2024 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type {IBoundedElement} from './interfaces/i_bounded_element.js';
|
||||
import {Rect} from './utils/rect.js';
|
||||
|
||||
/**
|
||||
* Representation of a gap between elements in a flyout.
|
||||
*/
|
||||
export class FlyoutSeparator implements IBoundedElement {
|
||||
private x = 0;
|
||||
private y = 0;
|
||||
|
||||
/**
|
||||
* Creates a new separator.
|
||||
*
|
||||
* @param gap The amount of space this separator should occupy.
|
||||
* @param axis The axis along which this separator occupies space.
|
||||
*/
|
||||
constructor(
|
||||
private gap: number,
|
||||
private axis: SeparatorAxis,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Returns the bounding box of this separator.
|
||||
*
|
||||
* @returns The bounding box of this separator.
|
||||
*/
|
||||
getBoundingRectangle(): Rect {
|
||||
switch (this.axis) {
|
||||
case SeparatorAxis.X:
|
||||
return new Rect(this.y, this.y, this.x, this.x + this.gap);
|
||||
case SeparatorAxis.Y:
|
||||
return new Rect(this.y, this.y + this.gap, this.x, this.x);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Repositions this separator.
|
||||
*
|
||||
* @param dx The distance to move this separator on the X axis.
|
||||
* @param dy The distance to move this separator on the Y axis.
|
||||
* @param _reason The reason this move was initiated.
|
||||
*/
|
||||
moveBy(dx: number, dy: number, _reason?: string[]) {
|
||||
this.x += dx;
|
||||
this.y += dy;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Representation of an axis along which a separator occupies space.
|
||||
*/
|
||||
export const enum SeparatorAxis {
|
||||
X = 'x',
|
||||
Y = 'y',
|
||||
}
|
||||
69
core/separator_flyout_inflater.ts
Normal file
69
core/separator_flyout_inflater.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2024 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type {IFlyoutInflater} from './interfaces/i_flyout_inflater.js';
|
||||
import type {IBoundedElement} from './interfaces/i_bounded_element.js';
|
||||
import type {WorkspaceSvg} from './workspace_svg.js';
|
||||
import {FlyoutSeparator, SeparatorAxis} from './flyout_separator.js';
|
||||
import type {SeparatorInfo} from './utils/toolbox.js';
|
||||
import * as registry from './registry.js';
|
||||
|
||||
/**
|
||||
* Class responsible for creating separators for flyouts.
|
||||
*/
|
||||
export class SeparatorFlyoutInflater implements IFlyoutInflater {
|
||||
/**
|
||||
* Inflates a dummy flyout separator.
|
||||
*
|
||||
* The flyout automatically creates separators between every element with a
|
||||
* size determined by calling gapForElement on the relevant inflater.
|
||||
* Additionally, users can explicitly add separators in the flyout definition.
|
||||
* When separators (implicitly or explicitly created) follow one another, the
|
||||
* gap of the last one propagates backwards and flattens to one separator.
|
||||
* This flattening is not additive; if there are initially separators of 2, 3,
|
||||
* and 4 pixels, after normalization there will be one separator of 4 pixels.
|
||||
* Therefore, this method returns a zero-width separator, which will be
|
||||
* replaced by the one implicitly created by the flyout based on the value
|
||||
* returned by gapForElement, which knows the default gap, unlike this method.
|
||||
*
|
||||
* @param _state A JSON representation of a flyout separator.
|
||||
* @param flyoutWorkspace The workspace the separator belongs to.
|
||||
* @returns A newly created FlyoutSeparator.
|
||||
*/
|
||||
load(_state: Object, flyoutWorkspace: WorkspaceSvg): IBoundedElement {
|
||||
const flyoutAxis = flyoutWorkspace.targetWorkspace?.getFlyout()
|
||||
?.horizontalLayout
|
||||
? SeparatorAxis.X
|
||||
: SeparatorAxis.Y;
|
||||
return new FlyoutSeparator(0, flyoutAxis);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of the separator. See `load` for more details.
|
||||
*
|
||||
* @param state A JSON representation of a flyout separator.
|
||||
* @param defaultGap The default spacing for flyout items.
|
||||
* @returns The desired size of the separator.
|
||||
*/
|
||||
gapForElement(state: Object, defaultGap: number): number {
|
||||
const separatorState = state as SeparatorInfo;
|
||||
const newGap = parseInt(String(separatorState['gap']));
|
||||
return newGap ?? defaultGap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disposes of the given separator. Intentional no-op.
|
||||
*
|
||||
* @param _element The flyout separator to dispose of.
|
||||
*/
|
||||
disposeElement(_element: IBoundedElement): void {}
|
||||
}
|
||||
|
||||
registry.register(
|
||||
registry.Type.FLYOUT_INFLATER,
|
||||
'sep',
|
||||
SeparatorFlyoutInflater,
|
||||
);
|
||||
Reference in New Issue
Block a user