UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

600 lines (599 loc) • 24.1 kB
/** * DevExtreme (esm/ui/diagram/ui.diagram.toolbar.js) * Version: 21.1.4 * Build date: Mon Jun 21 2021 * * Copyright (c) 2012 - 2021 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ import $ from "../../core/renderer"; import Toolbar from "../toolbar"; import ContextMenu from "../context_menu"; import DiagramBar from "./diagram.bar"; import { extend } from "../../core/utils/extend"; import { hasWindow } from "../../core/utils/window"; import DiagramPanel from "./ui.diagram.panel"; import DiagramMenuHelper from "./ui.diagram.menu_helper"; import { getDiagram } from "./diagram.importer"; import "../select_box"; import "../color_box"; import "../check_box"; var ACTIVE_FORMAT_CLASS = "dx-format-active"; var DIAGRAM_TOOLBAR_CLASS = "dx-diagram-toolbar"; var DIAGRAM_TOOLBAR_SEPARATOR_CLASS = "dx-diagram-toolbar-separator"; var DIAGRAM_TOOLBAR_MENU_SEPARATOR_CLASS = "dx-diagram-toolbar-menu-separator"; var DIAGRAM_MOBILE_TOOLBAR_COLOR_BOX_OPENED_CLASS = "dx-diagram-mobile-toolbar-color-box-opened"; class DiagramToolbar extends DiagramPanel { _init() { this._commands = []; this._itemHelpers = {}; this._commandContextMenus = {}; this._contextMenuList = []; this._valueConverters = {}; this.bar = new DiagramToolbarBar(this); this._createOnInternalCommand(); this._createOnCustomCommand(); this._createOnSubMenuVisibilityChangingAction(); super._init() } _initMarkup() { super._initMarkup(); var isServerSide = !hasWindow(); if (!this.option("skipAdjustSize") && !isServerSide) { this.$element().width("") } this._commands = this._getCommands(); this._itemHelpers = {}; this._commandContextMenus = {}; this._contextMenuList = []; var $toolbar = this._createMainElement(); this._renderToolbar($toolbar); if (!this.option("skipAdjustSize") && !isServerSide) { var $toolbarContent = this.$element().find(".dx-toolbar-before"); this.$element().width($toolbarContent.width()) } } _createMainElement() { return $("<div>").addClass(DIAGRAM_TOOLBAR_CLASS).appendTo(this._$element) } _getCommands() { return this.option("commands") || [] } _renderToolbar($toolbar) { var beforeCommands = this._commands.filter(command => -1 === ["after", "center"].indexOf(command.position)); var centerCommands = this._commands.filter(command => "center" === command.position); var afterCommands = this._commands.filter(command => "after" === command.position); var dataSource = [].concat(this._prepareToolbarItems(beforeCommands, "before", this._executeCommand)).concat(this._prepareToolbarItems(centerCommands, "center", this._executeCommand)).concat(this._prepareToolbarItems(afterCommands, "after", this._executeCommand)); this._toolbarInstance = this._createComponent($toolbar, Toolbar, { dataSource: dataSource }) } _prepareToolbarItems(items, location, actionHandler) { return items.map(item => extend(true, { location: location, locateInMenu: this.option("locateInMenu") }, this._createItem(item, location, actionHandler), this._createItemOptions(item), this._createItemActionOptions(item, actionHandler))) } _createItem(item, location, actionHandler) { if (item.getCommandValue || item.getEditorValue || item.getEditorDisplayValue) { this._valueConverters[item.command] = { getCommandValue: item.getCommandValue, getEditorValue: item.getEditorValue, getEditorDisplayValue: item.getEditorDisplayValue } } if ("separator" === item.widget) { return { template: (data, index, element) => { $(element).addClass(DIAGRAM_TOOLBAR_SEPARATOR_CLASS) }, menuItemTemplate: (data, index, element) => { $(element).addClass(DIAGRAM_TOOLBAR_MENU_SEPARATOR_CLASS) } } } return { widget: item.widget || "dxButton", cssClass: item.cssClass, options: { stylingMode: this.option("buttonStylingMode"), type: this.option("buttonType"), text: item.text, hint: item.hint, icon: item.icon || item.iconUnchecked || item.iconChecked, iconChecked: item.iconChecked, iconUnchecked: item.iconUnchecked, onInitialized: e => this._onItemInitialized(e.component, item), onContentReady: e => this._onItemContentReady(e.component, item, actionHandler) } } } _createItemOptions(_ref) { var { widget: widget, command: command, items: items, valueExpr: valueExpr, displayExpr: displayExpr, showText: showText, hint: hint, icon: icon } = _ref; if ("dxSelectBox" === widget) { return this._createSelectBoxItemOptions(command, hint, items, valueExpr, displayExpr) } else if ("dxTextBox" === widget) { return this._createTextBoxItemOptions(command, hint) } else if ("dxColorBox" === widget) { return this._createColorBoxItemOptions(command, hint, icon) } else if (!widget || "dxButton" === widget) { return { showText: showText || "inMenu" } } } _createSelectBoxItemOptions(command, hint, items, valueExpr, displayExpr) { var options = this._createTextEditorItemOptions(hint); options = extend(true, options, { options: { dataSource: items, displayExpr: displayExpr || "text", valueExpr: valueExpr || "value", dropDownOptions: { container: this.option("container") } } }); var isSelectButton = items && items.every(i => void 0 !== i.icon); if (isSelectButton) { options = extend(true, options, { options: { fieldTemplate: (data, container) => { $("<i>").addClass(data && data.icon).appendTo(container); $("<div>").dxTextBox({ readOnly: true, stylingMode: "outlined" }).appendTo(container) }, itemTemplate: (data, index, container) => { $(container).attr("title", data.hint); return '<i class="'.concat(data.icon, '"></i>') } } }) } return options } _createTextBoxItemOptions(command, hint) { var options = this._createTextEditorItemOptions(hint); options = extend(true, options, { options: { readOnly: true, focusStateEnabled: false, hoverStateEnabled: false, buttons: [{ name: "dropDown", location: "after", options: { icon: "spindown", disabled: false, stylingMode: "text", onClick: e => { var contextMenu = this._commandContextMenus[command]; if (contextMenu) { this._toggleContextMenu(contextMenu) } } } }] } }); return options } _createColorBoxItemOptions(command, hint, icon) { var options = this._createTextEditorItemOptions(hint); if (icon) { options = extend(true, options, { options: { openOnFieldClick: true, fieldTemplate: (data, container) => { $("<i>").addClass(icon).css("borderBottomColor", data).appendTo(container); $("<div>").dxTextBox({ readOnly: true, stylingMode: "outlined" }).appendTo(container) } } }) } options = extend(true, options, { options: { dropDownOptions: { container: this.option("container") }, onOpened: () => { if (this.option("isMobileView")) { $("body").addClass(DIAGRAM_MOBILE_TOOLBAR_COLOR_BOX_OPENED_CLASS) } }, onClosed: () => { $("body").removeClass(DIAGRAM_MOBILE_TOOLBAR_COLOR_BOX_OPENED_CLASS) } } }); return options } _createTextEditorItemOptions(hint) { return { options: { stylingMode: this.option("editorStylingMode"), hint: hint } } } _createItemActionOptions(item, handler) { switch (item.widget) { case "dxSelectBox": case "dxColorBox": case "dxCheckBox": return { options: { onValueChanged: e => { var parameter = DiagramMenuHelper.getItemCommandParameter(this, item, e.component.option("value")); handler.call(this, item.command, item.name, parameter) } } }; case "dxTextBox": return {}; default: return { options: { onClick: e => { if (!item.items) { var parameter = DiagramMenuHelper.getItemCommandParameter(this, item); handler.call(this, item.command, item.name, parameter) } else { var contextMenu = e.component._contextMenu; if (contextMenu) { this._toggleContextMenu(contextMenu) } } } } } } } _toggleContextMenu(contextMenu) { this._contextMenuList.forEach(cm => { if (contextMenu !== cm) { cm.hide() } }); contextMenu.toggle() } _onItemInitialized(widget, item) { this._addItemHelper(item.command, new DiagramToolbarItemHelper(widget)) } _onItemContentReady(widget, item, actionHandler) { var { Browser: Browser } = getDiagram(); if (("dxButton" === widget.NAME || "dxTextBox" === widget.NAME) && item.items) { var $menuContainer = $("<div>").appendTo(this.$element()); widget._contextMenu = this._createComponent($menuContainer, ContextMenu, { items: item.items, target: widget.$element(), cssClass: DiagramMenuHelper.getContextMenuCssClass(), showEvent: "", closeOnOutsideClick: e => !Browser.TouchUI && 0 === $(e.target).closest(widget._contextMenu._dropDownButtonElement).length, focusStateEnabled: false, position: { at: "left bottom" }, itemTemplate: function(itemData, itemIndex, itemElement) { DiagramMenuHelper.getContextMenuItemTemplate(this, itemData, itemIndex, itemElement) }, onItemClick: _ref2 => { var { component: component, itemData: itemData } = _ref2; DiagramMenuHelper.onContextMenuItemClick(this, itemData, actionHandler.bind(this)); if (!itemData.items || !itemData.items.length) { component.hide() } }, onShowing: e => { if (this._showingSubMenu) { return } this._showingSubMenu = e.component; this._onSubMenuVisibilityChangingAction({ visible: true, component: this }); e.component.option("items", e.component.option("items")); delete this._showingSubMenu }, onInitialized: _ref3 => { var { component: component } = _ref3; return this._onContextMenuInitialized(component, item, widget) }, onDisposing: _ref4 => { var { component: component } = _ref4; return this._onContextMenuDisposing(component, item) } }); if (!Browser.TouchUI) { widget._contextMenu._dropDownButtonElement = widget.$element(); if ("dxTextBox" === widget.NAME) { widget._contextMenu._dropDownButtonElement = widget.getButton("dropDown").element() } } } } _onContextMenuInitialized(widget, item, rootWidget) { this._contextMenuList.push(widget); if (item.command) { this._commandContextMenus[item.command] = widget } this._addContextMenuHelper(item, widget, [], rootWidget) } _addItemHelper(command, helper) { if (void 0 !== command) { if (this._itemHelpers[command]) { throw new Error("Toolbar cannot contain duplicated commands.") } this._itemHelpers[command] = helper } } _addContextMenuHelper(item, widget, indexPath, rootWidget) { if (item.items) { item.items.forEach((subItem, index) => { var itemIndexPath = indexPath.concat(index); this._addItemHelper(subItem.command, new DiagramToolbarSubItemHelper(widget, itemIndexPath, subItem.command, rootWidget)); this._addContextMenuHelper(subItem, widget, itemIndexPath, rootWidget) }) } } _onContextMenuDisposing(widget, item) { this._contextMenuList.splice(this._contextMenuList.indexOf(widget), 1); delete this._commandContextMenus[item.command] } _executeCommand(command, name, value) { if (this._updateLocked) { return } if ("number" === typeof command) { var valueConverter = this._valueConverters[command]; if (valueConverter && valueConverter.getCommandValue) { value = valueConverter.getCommandValue(value) } this.bar.raiseBarCommandExecuted(command, value) } else if ("string" === typeof command) { this._onInternalCommandAction({ command: command }) } if (void 0 !== name) { this._onCustomCommandAction({ name: name }) } } _createOnInternalCommand() { this._onInternalCommandAction = this._createActionByOption("onInternalCommand") } _createOnCustomCommand() { this._onCustomCommandAction = this._createActionByOption("onCustomCommand") } _setItemEnabled(command, enabled) { if (command in this._itemHelpers) { var helper = this._itemHelpers[command]; if (helper.canUpdate(this._showingSubMenu)) { helper.setEnabled(enabled) } } } _setEnabled(enabled) { this._toolbarInstance.option("disabled", !enabled); this._contextMenuList.forEach(contextMenu => { contextMenu.option("disabled", !enabled) }) } _setItemValue(command, value) { try { this._updateLocked = true; if (command in this._itemHelpers) { var helper = this._itemHelpers[command]; if (helper.canUpdate(this._showingSubMenu)) { var valueConverter = this._valueConverters[command]; if (valueConverter && valueConverter.getEditorValue) { value = valueConverter.getEditorValue(value) } var displayValue; if (valueConverter && valueConverter.getEditorDisplayValue) { displayValue = valueConverter.getEditorDisplayValue(value) } var contextMenu = this._commandContextMenus[command]; helper.setValue(value, displayValue, contextMenu, contextMenu && command) } } } finally { this._updateLocked = false } } _setItemSubItems(command, items) { this._updateLocked = true; if (command in this._itemHelpers) { var helper = this._itemHelpers[command]; if (helper.canUpdate(this._showingSubMenu)) { var contextMenu = this._commandContextMenus[command]; helper.setItems(items, contextMenu, contextMenu && command) } } this._updateLocked = false } _createOnSubMenuVisibilityChangingAction() { this._onSubMenuVisibilityChangingAction = this._createActionByOption("onSubMenuVisibilityChanging") } _optionChanged(args) { switch (args.name) { case "isMobileView": $("body").removeClass(DIAGRAM_MOBILE_TOOLBAR_COLOR_BOX_OPENED_CLASS); this._invalidate(); break; case "onSubMenuVisibilityChanging": this._createOnSubMenuVisibilityChangingAction(); break; case "onInternalCommand": this._createOnInternalCommand(); break; case "onCustomCommand": this._createOnCustomCommand(); break; case "container": case "commands": this._invalidate(); break; case "export": break; default: super._optionChanged(args) } } _getDefaultOptions() { return extend(super._getDefaultOptions(), { isMobileView: false, export: { fileName: "Diagram", proxyUrl: void 0 }, locateInMenu: "auto", buttonStylingMode: "text", buttonType: "normal", editorStylingMode: "filled", skipAdjustSize: false }) } setCommandChecked(command, checked) { this._setItemValue(command, checked) } setCommandEnabled(command, enabled) { this._setItemEnabled(command, enabled) } } class DiagramToolbarBar extends DiagramBar { getCommandKeys() { return this._getKeys(this._owner._commands) } setItemValue(key, value) { this._owner._setItemValue(key, value) } setItemEnabled(key, enabled) { this._owner._setItemEnabled(key, enabled) } setEnabled(enabled) { this._owner._setEnabled(enabled) } setItemSubItems(key, items) { this._owner._setItemSubItems(key, items) } } class DiagramToolbarItemHelper { constructor(widget) { this._widget = widget } canUpdate(showingSubMenu) { return void 0 === showingSubMenu } setEnabled(enabled) { this._widget.option("disabled", !enabled) } setValue(value, displayValue, contextMenu, rootCommandKey) { if ("value" in this._widget.option()) { this._updateEditorValue(value, displayValue) } else if (void 0 !== value) { this._updateButtonValue(value) } if (contextMenu) { this._updateContextMenuItemValue(contextMenu, "", rootCommandKey, value) } } setItems(items, contextMenu, rootCommandKey) { if (contextMenu) { this._updateContextMenuItems(contextMenu, "", rootCommandKey, items) } else { this._updateEditorItems(items) } } _updateContextMenuItems(contextMenu, itemOptionText, rootCommandKey, items) { DiagramMenuHelper.updateContextMenuItems(contextMenu, itemOptionText, rootCommandKey, items) } _updateEditorItems(items) { if ("items" in this._widget.option()) { this._widget.option("items", items.map(item => ({ value: DiagramMenuHelper.getItemValue(item), text: item.text }))) } } _updateEditorValue(value, displayValue) { this._widget.option("value", value); if (!this._widget.option("selectedItem") && displayValue) { this._widget.option("value", displayValue) } } _updateButtonValue(value) { if (this._widget.option("iconChecked") && this._widget.option("iconUnchecked")) { this._widget.option("icon", value ? this._widget.option("iconChecked") : this._widget.option("iconUnchecked")) } else { this._widget.$element().toggleClass(ACTIVE_FORMAT_CLASS, value) } } _updateContextMenuItemValue(contextMenu, itemOptionText, rootCommandKey, value) { DiagramMenuHelper.updateContextMenuItemValue(contextMenu, itemOptionText, rootCommandKey, value) } } class DiagramToolbarSubItemHelper extends DiagramToolbarItemHelper { constructor(widget, indexPath, rootCommandKey, rootWidget) { super(widget); this._indexPath = indexPath; this._rootCommandKey = rootCommandKey; this._rootWidget = rootWidget } canUpdate(showingSubMenu) { return super.canUpdate(showingSubMenu) || showingSubMenu === this._widget } setEnabled(enabled) { this._widget.option(this._getItemOptionText() + "disabled", !enabled); var rootEnabled = this._hasEnabledCommandItems(this._widget.option("items")); this._rootWidget.option("disabled", !rootEnabled) } _hasEnabledCommandItems(items) { if (items) { return items.some(item => void 0 !== item.command && !item.disabled || this._hasEnabledCommandItems(item.items)) } return false } setValue(value) { this._updateContextMenuItemValue(this._widget, this._getItemOptionText(), this._rootCommandKey, value) } setItems(items) { this._updateContextMenuItems(this._widget, this._getItemOptionText(), this._rootCommandKey, items) } _getItemOptionText() { return DiagramMenuHelper.getItemOptionText(this._widget, this._indexPath) } } export default DiagramToolbar;