js-draw
Version:
Draw pictures using a pen, touchscreen, or mouse! JS-draw is a drawing library for JavaScript and TypeScript.
220 lines (219 loc) • 8.16 kB
TypeScript
import Editor from '../Editor';
import { ToolbarLocalization } from './localization';
import { ActionButtonIcon } from './types';
import BaseWidget, { ToolbarWidgetTag } from './widgets/BaseWidget';
import { DispatcherEventListener } from '../EventDispatcher';
import { BaseTool } from '../lib';
export interface SpacerOptions {
grow: number;
minSize: string;
maxSize: string;
}
export type ToolbarActionButtonOptions = {
mustBeToplevel?: boolean;
autoDisableInReadOnlyEditors?: boolean;
};
/**
* Abstract base class for js-draw editor toolbars.
*
* See {@link Editor.addToolbar}, {@link makeDropdownToolbar}, and {@link makeEdgeToolbar}.
*/
export default abstract class AbstractToolbar {
#private;
protected editor: Editor;
private static colorisStarted;
protected localizationTable: ToolbarLocalization;
/** @internal */
constructor(editor: Editor, localizationTable: ToolbarLocalization);
private closeColorPickerOverlay;
private setupCloseColorPickerOverlay;
setupColorPickers(): void;
protected closeColorPickers(): void;
protected getWidgetUniqueId(widget: BaseWidget): string;
protected getWidgetFromId(id: string): BaseWidget | undefined;
/** Do **not** modify the return value. */
protected getAllWidgets(): Array<BaseWidget>;
/**
* Adds a spacer.
*
* **Toolbars can choose to ignore calls to `addSpacer`**.
*
* @example
* Adding a save button that moves to the very right edge of the toolbar
* while keeping the other buttons centered:
* ```ts
* const toolbar = editor.addToolbar(false);
*
* toolbar.addSpacer({ grow: 1 });
* toolbar.addDefaults();
* toolbar.addSpacer({ grow: 1 });
*
* toolbar.addActionButton({
* label: 'Save',
* icon: editor.icons.makeSaveIcon(),
* }, () => {
* saveCallback();
* });
* ```
*/
abstract addSpacer(options?: Partial<SpacerOptions>): void;
/**
* Adds an `ActionButtonWidget` or `BaseToolWidget`. The widget should not have already have a parent
* (i.e. its `addTo` method should not have been called).
*
* @example
* ```ts
* const toolbar = editor.addToolbar();
* const insertImageWidget = new InsertImageWidget(editor);
* toolbar.addWidget(insertImageWidget);
* ```
*/
addWidget(widget: BaseWidget): void;
/** Called by `addWidget`. Implement this to add a new widget to the toolbar. */
protected abstract addWidgetInternal(widget: BaseWidget): void;
/** Removes the given `widget` from this toolbar. */
removeWidget(widget: BaseWidget): void;
/** Called by `removeWidget`. Implement this to remove a new widget from the toolbar. */
protected abstract removeWidgetInternal(widget: BaseWidget): void;
private static rootToolbarId;
/** Returns a snapshot of the state of widgets in the toolbar. */
serializeState(): string;
/**
* Deserialize toolbar widgets from the given state.
* Assumes that toolbar widgets are in the same order as when state was serialized.
*/
deserializeState(state: string): void;
/**
* Called by `serializeState` to attach any additional JSONifyable data
* to the serialized result.
*
* @returns an object that can be converted to JSON with `JSON.stringify`.
*/
protected serializeInternal(): any;
/**
* Called by `deserializeState` with a version of the JSON outputted
* previously by `serializeInternal`.
*/
protected deserializeInternal(_json: any): void;
/**
* Creates, but does not add, an action button to this container.
*
* @see
* {@link addActionButton}
*/
protected makeActionButton(title: string | ActionButtonIcon, command: () => void, options?: ToolbarActionButtonOptions | boolean): BaseWidget;
/**
* Adds an action button with `title` to this toolbar (or to the given `parent` element).
*
* `options` can either be an object with properties `mustBeToplevel` and/or
* `autoDisableInReadOnlyEditors` or a boolean value. If a boolean, it is interpreted
* as being the value of `mustBeToplevel`.
*
* @return The added button.
*
* **Example**:
* ```ts,runnable
* import { Editor } from 'js-draw';
* const editor = new Editor(document.body);
* const toolbar = editor.addToolbar();
*
* function makeTrashIcon() {
* const container = document.createElement('div');
* container.textContent = '🗑️';
* return container;
* }
*
* toolbar.addActionButton({
* icon: makeTrashIcon(), // can be any Element not in the DOM
* label: 'Delete all',
* }, () => {
* alert('to-do!');
* });
*/
addActionButton(title: string | ActionButtonIcon, command: () => void, options?: ToolbarActionButtonOptions | boolean): BaseWidget;
/**
* Like {@link addActionButton}, except associates `tags` with the button that allow
* different toolbar styles to give the button tag-dependent styles.
*/
addTaggedActionButton(tags: (ToolbarWidgetTag | string)[], title: string | ActionButtonIcon, command: () => void, options?: ToolbarActionButtonOptions | boolean): BaseWidget;
/**
* Adds a save button that, when clicked, calls `saveCallback`.
*
* @example
* ```ts,runnable
* import { Editor, makeDropdownToolbar } from 'js-draw';
*
* const editor = new Editor(document.body);
* const toolbar = makeDropdownToolbar(editor);
*
* toolbar.addDefaults();
* toolbar.addSaveButton(() => alert('save clicked!'));
* ```
*
* `labelOverride` can optionally be used to change the `label` or `icon` of the button.
*/
addSaveButton(saveCallback: () => void, labelOverride?: Partial<ActionButtonIcon>): BaseWidget;
/**
* Adds an "Exit" button that, when clicked, calls `exitCallback`.
*
* **Note**: This is *roughly* equivalent to
* ```ts
* toolbar.addTaggedActionButton([ ToolbarWidgetTag.Exit ], {
* label: this.editor.localization.exit,
* icon: this.editor.icons.makeCloseIcon(),
*
* // labelOverride can be used to override label or icon.
* ...labelOverride,
* }, () => {
* exitCallback();
* });
* ```
* with some additional configuration.
*
* @final
*/
addExitButton(exitCallback: () => void, labelOverride?: Partial<ActionButtonIcon>): BaseWidget;
/**
* Adds undo and redo buttons that trigger the editor's built-in undo and redo
* functionality.
*/
addUndoRedoButtons(undoFirst?: boolean): void;
/**
* Adds widgets for pen/eraser/selection/text/pan-zoom primary tools.
*
* If `filter` returns `false` for a tool, no widget is added for that tool.
* See {@link addDefaultToolWidgets}
*/
addWidgetsForPrimaryTools(filter?: (tool: BaseTool) => boolean): void;
/**
* Adds toolbar widgets based on the enabled tools, and additional tool-like
* buttons (e.g. {@link DocumentPropertiesWidget} and {@link InsertImageWidget}).
*/
addDefaultToolWidgets(): void;
/**
* Adds widgets that don't correspond to tools, but do allow the user to control
* the editor in some way.
*
* By default, this includes {@link DocumentPropertiesWidget} and {@link InsertImageWidget}.
*/
addDefaultEditorControlWidgets(): void;
addDefaultActionButtons(): void;
/**
* Adds both the default tool widgets and action buttons.
*/
abstract addDefaults(): void;
/**
* Remove this toolbar from its container and clean up listeners.
* This should only be called **once** for a given toolbar.
*/
remove(): void;
/**
* Removes `listener` when {@link remove} is called.
*/
protected manageListener(listener: DispatcherEventListener): void;
/**
* Internal logic for {@link remove}. Implementers should remove the toolbar
* from its container.
*/
protected abstract onRemove(): void;
}