@visactor/vtable
Version:
canvas table width high performance
218 lines (210 loc) • 9.66 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: !0
}), exports.MenuHandler = exports.MenuType = void 0;
const vrender_1 = require("./../../vrender"), TABLE_EVENT_TYPE_1 = require("../../core/TABLE_EVENT_TYPE"), group_1 = require("../graphic/group"), icon_1 = require("../graphic/icon");
var MenuType;
!function(MenuType) {
MenuType.dropDown = "dropDown", MenuType.contextmenu = "contextmenu", MenuType.custom = "custom";
}(MenuType = exports.MenuType || (exports.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
};
class MenuHandler {
constructor(table) {
this._table = table, this._menuInstance = new group_1.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_1.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 vrender_1.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_1.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_1.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;
}
}
exports.MenuHandler = MenuHandler;
//# sourceMappingURL=menu.js.map