import { Selection, CenterLayout, shortcut, Widget, Controller, extend, createWidget, createWidgets, each, isFunction, isKey, isNotEmptyArray, createItems, isArray, remove, map, stripEL, makeArrayByArray, clone, deepClone, formatEL, isEmpty, concat, removeAt, deepContains, has, any, BehaviorFactory, Events } from "@/core"; import { TextButton } from "../single"; /** * Created by GUY on 2015/6/26. * @class ButtonGroup * @extends Widget */ @shortcut() export class ButtonGroup extends Widget { static xtype = "bi.button_group"; static EVENT_CHANGE = "EVENT_CHANGE"; static CHOOSE_TYPE_SINGLE = Selection.Single; static CHOOSE_TYPE_MULTI = Selection.Multi; static CHOOSE_TYPE_ALL = Selection.All; static CHOOSE_TYPE_NONE = Selection.None; static CHOOSE_TYPE_DEFAULT = Selection.Default; _defaultConfig() { return extend(super._defaultConfig(...arguments), { baseCls: "bi-button-group", behaviors: {}, items: [], value: "", chooseType: Selection.Single, layouts: [ { type: CenterLayout.xtype, hgap: 0, vgap: 0, } ], }); } render() { const { behaviors: optionsBehaviors, items: optionsItems, value } = this.options; const behaviors = {}; each(optionsBehaviors, (key, rule) => { behaviors[key] = BehaviorFactory.createBehavior(key, { rule, }); }); this.behaviors = behaviors; const items = isFunction(optionsItems) ? this.__watch(optionsItems, (context, newValue) => { this.populate(newValue); }) : optionsItems; this.populate(items); this.options.value = isFunction(value) ? this.__watch(value, (context, newValue) => { this.setValue(newValue); }) : value; if (isKey(value) || isNotEmptyArray(value)) { this.setValue(value); } } _createBtns(items) { let btns; Widget.execWithContext(this, () => { btns = createWidgets( createItems(items, { type: TextButton.xtype, }) ); }); return btns; } _btnsCreator(items) { const args = Array.prototype.slice.call(arguments); const { chooseType } = this.options; const buttons = this._createBtns(items); args[0] = buttons; each(this.behaviors, (i, behavior) => { behavior.doBehavior(...args); }); each(buttons, (i, btn) => { btn.on(Controller.EVENT_CHANGE, (...arg) => { const [type, value, obj] = arg; if (type === Events.CLICK) { switch (chooseType) { case ButtonGroup.CHOOSE_TYPE_SINGLE: this.setValue(btn.getValue()); break; case ButtonGroup.CHOOSE_TYPE_NONE: this.setValue([]); break; default: break; } this.fireEvent(Controller.EVENT_CHANGE, ...arg); this.fireEvent(ButtonGroup.EVENT_CHANGE, value, obj); } else { this.fireEvent(Controller.EVENT_CHANGE, ...arg); } }); btn.on(Events.DESTROY, () => { remove(this.buttons, btn); }); }); return buttons; } _packageBtns(btns) { const { layouts: optionsLayouts } = this.options; const layouts = isArray(optionsLayouts) ? optionsLayouts : [optionsLayouts]; for (let i = layouts.length - 1; i > 0; i--) { btns = map(btns, (k, it) => extend({}, layouts[i], { items: [ extend({}, layouts[i].el, { el: it, }) ], }) ); } return btns; } _packageSimpleItems(btns) { const { items } = this.options; return map(items, (i, item) => { if (stripEL(item) === item) { return btns[i]; } return extend({}, item, { el: btns[i], }); }); } _packageItems(items, packBtns) { return createItems(makeArrayByArray(items, {}), clone(packBtns)); } _packageLayout(items) { const { layouts } = this.options; const layout = deepClone(isArray(layouts) ? layouts[0] : layouts); let lay = formatEL(layout).el; while (lay && lay.items && !isEmpty(lay.items)) { lay = formatEL(lay.items[0]).el; } lay.items = items; return layout; } // 如果是一个简单的layout _isSimpleLayout() { const { layouts, items } = this.options; return isArray(layouts) ? layouts.length === 1 && !isArray(items[0]) : true; } doBehavior() { const args = Array.prototype.slice.call(arguments); args.unshift(this.buttons); each(this.behaviors, (i, behavior) => { behavior.doBehavior(...args); }); } prependItems(items) { const btns = this._btnsCreator(...arguments); this.buttons = concat(btns, this.buttons); if (this._isSimpleLayout() && this.layouts && this.layouts.prependItems) { this.layouts.prependItems(btns); return; } items = this._packageItems(items, this._packageBtns(btns)); this.layouts.prependItems(this._packageLayout(items).items); } addItems(items) { const btns = this._btnsCreator(...arguments); this.buttons = concat(this.buttons, btns); // 如果是一个简单的layout if (this._isSimpleLayout() && this.layouts && this.layouts.addItems) { this.layouts.addItems(btns); return; } items = this._packageItems(items, this._packageBtns(btns)); this.layouts.addItems(this._packageLayout(items).items); } removeItemAt(indexes) { removeAt(this.buttons, indexes); this.layouts.removeItemAt(indexes); } removeItems(values) { values = isArray(values) ? values : [values]; const deleted = []; each(this.buttons, (i, button) => { if (deepContains(values, button.getValue())) { deleted.push(i); } }); removeAt(this.buttons, deleted); this.layouts.removeItemAt(deleted); } populate(items) { items = items || []; this.empty(); this.options.items = items; this.buttons = this._btnsCreator(...arguments); if (this._isSimpleLayout()) { items = this._packageSimpleItems(this.buttons); } else { items = this._packageItems(items, this._packageBtns(this.buttons)); } this.layouts = createWidget(extend({ element: this }, this._packageLayout(items))); } setNotSelectedValue(v) { v = isArray(v) ? v : [v]; each(this.buttons, (i, item) => { if (deepContains(v, item.getValue())) { item.setSelected && item.setSelected(false); } else { item.setSelected && item.setSelected(true); } }); } setEnabledValue(v) { v = isArray(v) ? v : [v]; each(this.buttons, (i, item) => { if (deepContains(v, item.getValue())) { item.setEnable(true); } else { item.setEnable(false); } }); } setValue(v) { v = isArray(v) ? v : [v]; each(this.buttons, (i, item) => { if (deepContains(v, item.getValue())) { item.setSelected && item.setSelected(true); } else { item.setSelected && item.setSelected(false); } }); } setValueMap(map) { map = map || {}; each(this.buttons, (i, item) => { if (has(map, item.getValue())) { item.setSelected && item.setSelected(true); } else { item.setSelected && item.setSelected(false); } }); } setAllSelected(v) { each(this.getAllButtons(), (i, btn) => { (btn.setSelected || btn.setAllSelected).apply(btn, [v]); }); } getNotSelectedValue() { const v = []; each(this.buttons, (i, item) => { if (item.isEnabled() && !(item.isSelected && item.isSelected())) { v.push(item.getValue()); } }); return v; } getValue() { const v = []; each(this.buttons, (i, item) => { if (item.isEnabled() && item.isSelected && item.isSelected()) { v.push(item.getValue()); } }); return v; } getAllButtons() { return this.buttons; } getAllLeaves() { return this.buttons; } getSelectedButtons() { const btns = []; each(this.buttons, (i, item) => { if (item.isSelected && item.isSelected()) { btns.push(item); } }); return btns; } getNotSelectedButtons() { const btns = []; each(this.buttons, (i, item) => { if (item.isSelected && !item.isSelected()) { btns.push(item); } }); return btns; } getIndexByValue(value) { let index = -1; any(this.buttons, (i, item) => { if (item.isEnabled() && item.getValue() === value) { index = i; return true; } }); return index; } getNodeById(id) { let node; any(this.buttons, (i, item) => { if (item.isEnabled() && item.options.id === id) { node = item; return true; } }); return node; } getNodeByValue(value) { let node; any(this.buttons, (i, item) => { if (item.isEnabled() && item.getValue() === value) { node = item; return true; } }); return node; } /** * 滚动到指定的节点 */ scrollToValue(value, scrollIntoViewOptions) { const node = this.getNodeByValue(value); if (node) { node.element[0].scrollIntoView(scrollIntoViewOptions); } } empty() { super.empty(arguments); this.options.items = []; } destroy() { super.destroy(arguments); this.options.items = []; } }