Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add IIcon interface, and related interfaces #7054

Merged
merged 5 commits into from
May 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion core/field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import * as userAgent from './utils/useragent.js';
import * as utilsXml from './utils/xml.js';
import * as WidgetDiv from './widgetdiv.js';
import type {WorkspaceSvg} from './workspace_svg.js';
import {ISerializable} from './interfaces/i_serializable.js';

/**
* A function that is called to validate changes to the field's value before
Expand All @@ -68,7 +69,7 @@ export type FieldValidator<T = any> = (newValue: T) => T|null|undefined;
export abstract class Field<T = any> implements IASTNodeLocationSvg,
IASTNodeLocationWithBlock,
IKeyboardAccessible,
IRegistrable {
IRegistrable, ISerializable {
/**
* To overwrite the default value which is set in **Field**, directly update
* the prototype.
Expand Down
20 changes: 20 additions & 0 deletions core/interfaces/i_has_bubble.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* @license
* Copyright 2023 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/


export interface IHasBubble {
/** @return True if the bubble is currently open, false otherwise. */
isBubbleVisible(): boolean;

/** Sets whether the bubble is open or not. */
setBubbleVisible(visible: boolean): void;
}

/** Type guard that checks whether the given object is a IHasBubble. */
export function hasBubble(obj: any): obj is IHasBubble {
return obj.isBubbleVisible !== undefined &&
obj.setBubbleVisible !== undefined;
}
92 changes: 92 additions & 0 deletions core/interfaces/i_icon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/**
* @license
* Copyright 2023 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

import type {Coordinate} from '../utils/coordinate.js';
import type {Size} from '../utils/size.js';


export interface IIcon {
/**
* @return the string representing the type of the icon.
* E.g. 'comment', 'warning', etc. This string should also be used when
* registering the icon class.
*/
getType(): string;

/**
* Creates the SVG elements for the icon that will live on the block.
*
* @param pointerdownListener An event listener that must be attached to the
* root SVG element by the implementation of `initView`. Used by Blockly's
* gesture system to properly handle clicks and drags.
*/
initView(pointerdownListener: (e: PointerEvent) => void): void;

/**
* Disposes of any elements of the icon.
*
* @remarks
*
* In particular, if this icon is currently showing a bubble, this should be
* used to hide it.
*/
dispose(): void;

/**
* @return the "weight" of the icon, which determines the static order which
* icons should be rendered in. More positive numbers are rendered farther
* toward the end of the block.
*/
getWeight(): number;

/** @return The dimensions of the icon for use in rendering. */
getSize(): Size;

/** Notifies the icon that the block's colour has changed. */
applyColour(): void;

/** Notifies the icon that the block's editability has changed. */
updateEditable(): void;

/** Notifies the icon that the block's collapsed-ness has changed. */
updateCollapsed(): void;

/**
* @return Whether this icon is shown when the block is collapsed. Used
* to allow renderers to account for padding.
*/
isShownWhenCollapsed(): boolean;

/**
* Notifies the icon where it is relative to its block's top-start, in
* workspace units.
*/
setOffsetInBlock(offset: Coordinate): void;

/**
* Notifies the icon that it has changed locations.
*
* @param blockOrigin The location of this icon's block's top-start corner
* in workspace coordinates.
*/
onLocationChange(blockOrigin: Coordinate): void;

/**
* Notifies the icon that it has been clicked.
*/
onClick(): void;
}

/** Type guard that checks whether the given object is an IIcon. */
export function isIcon(obj: any): obj is IIcon {
return obj.getType !== undefined && obj.initView !== undefined &&
obj.dispose !== undefined && obj.getWeight !== undefined &&
obj.getSize !== undefined && obj.applyColour !== undefined &&
obj.updateEditable !== undefined && obj.updateCollapsed !== undefined &&
obj.isShownWhenCollapsed !== undefined &&
obj.setOffsetInBlock !== undefined &&
obj.onLocationChange !== undefined && obj.onClick !== undefined;
}
29 changes: 29 additions & 0 deletions core/interfaces/i_serializable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* @license
* Copyright 2023 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/


export interface ISerializable {
/**
* @param doFullSerialization If true, this signals that any backing data
* structures used by this ISerializable should also be serialized. This
* is used for copy-paste.
* @return a JSON serializable value that records the icon's state.
*/
saveState(doFullSerialization: boolean): any;

/**
* Takes in a JSON serializable value and sets the ISerializable's state
* based on that.
*
* @param state The state to apply to the ISerializable.
*/
loadState(state: any): void;
}

/** Type guard that checks whether the given object is a ISerializable. */
export function isSerializable(obj: any): obj is ISerializable {
return obj.saveState !== undefined && obj.loadState !== undefined;
}