UNPKG

@visactor/vtable

Version:

canvas table width high performance

216 lines (208 loc) 9.44 kB
import { Text } from "./../../vrender"; import { TABLE_EVENT_TYPE } from "../../core/TABLE_EVENT_TYPE"; import { Group } from "../graphic/group"; import { Icon } from "../graphic/icon"; export var MenuType; !function(MenuType) { MenuType.dropDown = "dropDown", MenuType.contextmenu = "contextmenu", MenuType.custom = "custom"; }(MenuType || (MenuType = {})); const menuStyle = { fontSize: 12, fontFamily: "Arial,sans-serif", color: "#000", highlightColor: "#2E68CF", hoverBgColor: "#EEE", lineHeight: 30, bgColor: "#FFF", cornerRadius: 4, borderWidth: .5, borderColor: "#CCC", menuPadding: 6, menuItemPadding: 9, maxLineWidth: 200 }; export class MenuHandler { constructor(table) { this._table = table, this._menuInstance = new Group({ x: 0, y: 0, fill: menuStyle.bgColor, stroke: menuStyle.borderColor, cornerRadius: menuStyle.cornerRadius, lineWidth: menuStyle.borderWidth }), this._menuInfo = { x: -1, y: -1, col: -1, row: -1, type: MenuType.dropDown, menuInfo: [], highlightIndex: -1 }; } bindTableComponent(componentGroup) { componentGroup.appendChild(this._menuInstance), this.bindEvent(); } release() {} attach(x, y, col, row, type, menuInfo) { if (type === MenuType.dropDown && this.checkDropDownMenuChange(col, row)) { const tableMenuInfo = this.getMenuInfo(col, row, type); if (!tableMenuInfo) return; const {menuInfo: menuInfo, highlightIndex: highlightIndex} = tableMenuInfo; this.updateMenuInfo(col, row, type, menuInfo, highlightIndex), this.updateMenuInstance(menuInfo, highlightIndex); } else if (type === MenuType.contextmenu && this.checkContextMenuChange(x, y)) { const tableMenuInfo = this.getMenuInfo(col, row, type); if (!tableMenuInfo) return; const {menuInfo: menuInfo, highlightIndex: highlightIndex} = tableMenuInfo; this.updateMenuInfo(col, row, type, menuInfo, highlightIndex), this.updateMenuInstance(menuInfo, highlightIndex); } this.updatePosition(x - this._table.scenegraph.x, y - this._table.scenegraph.y), this.addToScene(); } updateMenuInfo(col, row, type, menuInfo, highlightIndex) { this._menuInfo.col = col, this._menuInfo.row = row, this._menuInfo.type = type, this._menuInfo.menuInfo = menuInfo, this._menuInfo.highlightIndex = highlightIndex; } checkDropDownMenuChange(col, row) { const {type: type, col: curCol, row: curRow} = this._menuInfo; return type !== MenuType.dropDown || col !== curCol || row !== curRow; } checkContextMenuChange(x, y) { var _a; const {type: type, menuInfo: menuInfo} = this._menuInfo; return type !== MenuType.contextmenu || menuInfo !== (null === (_a = this._table.internalProps.menu) || void 0 === _a ? void 0 : _a.contextMenuItems); } updateMenuInstance(menuInfo, highlightIndex) { this._menuInstance.removeAllChild(); let y = menuStyle.menuPadding; const x = menuStyle.menuPadding; let maxWidth = 0; menuInfo.forEach(((item, index) => { var _a, _b; const isisHighlight = highlightIndex === index; let icon, text; "string" == typeof item ? text = item : "object" == typeof item && (text = item.text, icon = isisHighlight ? item.selectedIcon : item.icon); const group = new Group({ y: y, x: x, height: menuStyle.lineHeight, fill: menuStyle.bgColor }); group.role = "menu-item", this._menuInstance.appendChild(group), group.stateProxy = stateName => "hover" === stateName ? { fill: menuStyle.hoverBgColor } : { fill: menuStyle.bgColor }, group.addEventListener("pointerenter", (e => { group.addState("hover", !0, !1), this._table.scenegraph.updateNextFrame(); })), group.addEventListener("pointerleave", (e => { group.removeState("hover", !1), this._table.scenegraph.updateNextFrame(); })); const textMark = new Text({ x: menuStyle.menuItemPadding, y: menuStyle.menuItemPadding, fill: isisHighlight ? menuStyle.highlightColor : menuStyle.color, text: text, textBaseline: "top", fontSize: menuStyle.fontSize, fontFamily: menuStyle.fontFamily, pickable: !1, maxLineWidth: menuStyle.maxLineWidth, ellipsis: "…" }); if (group.addChild(textMark), icon) { textMark.AABBBounds.height(); const iconWidth = null !== (_a = icon.width) && void 0 !== _a ? _a : 16, iconHeight = null !== (_b = icon.height) && void 0 !== _b ? _b : 16, iconMark = new Icon({ x: menuStyle.menuItemPadding, y: (menuStyle.lineHeight - iconHeight) / 2, width: iconWidth, height: iconHeight, image: icon.svg, pickable: !1 }); iconMark.role = "menu-icon", group.insertBefore(iconMark, textMark), textMark.setAttribute("x", iconWidth + menuStyle.menuItemPadding); } maxWidth = Math.max(group.AABBBounds.width(), maxWidth), y += menuStyle.lineHeight; })), this._menuInstance.setAttributes({ width: maxWidth + 2 * menuStyle.menuItemPadding + 2 * menuStyle.menuPadding, height: y + menuStyle.menuPadding }), this._menuInstance.forEachChildren((itemGroup => { itemGroup.setAttribute("width", maxWidth + 2 * menuStyle.menuItemPadding); })); } updatePosition(x, y) { this._menuInstance.setAttributes({ x: this._menuInfo.type === MenuType.dropDown ? x - this._menuInstance.attribute.width : x, y: y }), this._menuInfo.x = MenuType.dropDown ? x - this._menuInstance.attribute.width : x, this._menuInfo.y = y; } addToScene() { this._table.scenegraph.updateNextFrame(); } detach() { this._menuInstance.setAttributes({ x: -1e3, y: -1e3 }), this._table.scenegraph.updateNextFrame(); } getMenuInfo(col, row, type) { var _a; if (type === MenuType.dropDown) { let dropDownMenu = this._table.globalDropDownMenu; dropDownMenu = this._table._getHeaderLayoutMap(col, row).dropDownMenu, "function" == typeof dropDownMenu && (dropDownMenu = dropDownMenu({ row: row, col: col, table: this._table })); let highlightIndex = -1; if (Array.isArray(dropDownMenu)) for (let i = 0; i < dropDownMenu.length; i++) if (this._table._dropDownMenuIsHighlight(col, row, i)) { highlightIndex = i; break; } return { menuInfo: dropDownMenu, highlightIndex: highlightIndex }; } if (type === MenuType.contextmenu) { const contextmenu = null === (_a = this._table.internalProps.menu) || void 0 === _a ? void 0 : _a.contextMenuItems; let menuInfo; if (Array.isArray(contextmenu)) menuInfo = contextmenu; else if ("function" == typeof contextmenu) { const {field: field} = this._table.isHeader(col, row) ? this._table.getHeaderDefine(col, row) : this._table.getBodyColumnDefine(col, row); menuInfo = contextmenu(field, row, col); } return { menuInfo: menuInfo, highlightIndex: -1 }; } } bindEvent() { this._menuInstance.addEventListener("click", (e => { const {target: target} = e; if (target && "menu-item" === target.role) { const resultMenuInfo = this.getEventInfo(target), resultTableInfo = this._table.getMenuInfo(this._menuInfo.col, this._menuInfo.row, this._menuInfo.type), result = Object.assign(resultMenuInfo, resultTableInfo); result.event = e.nativeEvent, this._table.fireListeners(TABLE_EVENT_TYPE.DROPDOWN_MENU_CLICK, result); } })); } getEventInfo(target) { const parent = target.parent; let index = 0; parent.forEachChildren(((child, i) => child === target && (index = i - 1, !0))); const text = "string" == typeof this._menuInfo.menuInfo[index] ? this._menuInfo.menuInfo[index] : this._menuInfo.menuInfo[index].text, menuKey = "string" == typeof this._menuInfo.menuInfo[index] ? text : this._menuInfo.menuInfo[index].menuKey || text; return { col: this._menuInfo.col, row: this._menuInfo.row, dropDownIndex: index, highlight: index === this._menuInfo.highlightIndex, text: text, menuKey: menuKey }; } get bounds() { return this._menuInstance.globalAABBBounds; } } //# sourceMappingURL=menu.js.map