fineui是帆软报表和BI产品线所使用的前端框架。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

500 lines
16 KiB

import {
Layout,
AbsoluteLayout,
emptyFn,
shortcut,
extend,
isFunction,
createWidget,
Widget,
isObject,
Controller,
isIE,
getIEVersion,
nextTick,
isKey,
isNull,
DOM,
debounce,
KeyCode,
EVENT_RESPONSE_TIME,
Events,
Actions
} from "@/core";
import { BubbleCombo } from "@/case/combo/bubblecombo/combo.bubble";
import { Single } from "../0.single";
import { BubblePopupBarView, TextBubblePopupBarView } from "@/case/combo/bubblecombo/popup.bubble";
/**
* guy
* @class BasicButton
* @extends Single
*
* 一般的button父级
*/
@shortcut()
export class BasicButton extends Single {
static xtype = "bi.basic_button";
static EVENT_CHANGE = "BasicButton.EVENT_CHANGE";
_defaultConfig() {
const conf = super._defaultConfig(...arguments);
return extend(conf, {
_baseCls: `${conf._baseCls || ""} bi-basic-button${conf.invalid ? "" : " cursor-pointer"}${
isIE() && getIEVersion() < 10 ? " hack" : ""
}`,
// el: {} // 可以通过el来创建button元素
value: "",
stopEvent: false,
stopPropagation: false,
selected: false,
once: false, // 点击一次选中有效,再点无效
forceSelected: false, // 点击即选中, 选中了就不会被取消,与once的区别是forceSelected不影响事件的触发
forceNotSelected: false, // 无论怎么点击都不会被选中
disableSelected: false, // 使能选中
shadow: false,
isShadowShowingOnSelected: false, // 选中状态下是否显示阴影
trigger: null,
handler: emptyFn,
bubble: null,
debounce: true,
});
}
_init() {
const opts = this.options;
opts.selected = isFunction(opts.selected)
? this.__watch(opts.selected, (context, newValue) => {
this.setSelected(newValue);
})
: opts.selected;
super._init(arguments);
if (opts.shadow) {
this._createShadow();
}
if (opts.level) {
this.element.addClass(`button-${opts.level}`);
}
}
_initRef() {
if (this.options.selected === true) {
this.setSelected(true);
}
// 延迟绑定事件,这样可以将自己绑定的事情优先执行
nextTick(() => {
!this.isDestroyed() && this.bindEvent();
});
super._initRef.apply(this, arguments);
}
// 默认render方法
render() {
return this.options.el;
}
_createShadow() {
const o = this.options;
const assertMask = () => {
if (!this.$mask) {
this.$mask = createWidget(isObject(o.shadow) ? o.shadow : {}, {
type: Layout.xtype,
cls: "bi-button-mask",
});
this.$mask.invisible();
createWidget({
type: AbsoluteLayout.xtype,
element: this,
items: [
{
el: this.$mask,
left: 0,
right: 0,
top: 0,
bottom: 0,
}
],
});
}
};
this.element.mouseup(() => {
if (!this._hover && !o.isShadowShowingOnSelected) {
assertMask();
this.$mask.invisible();
}
});
this.element.on(`mouseenter.${this.getName()}`, e => {
if (this.element.__isMouseInBounds__(e)) {
if (this.isEnabled() && !this._hover && (o.isShadowShowingOnSelected || !this.isSelected())) {
assertMask();
this.$mask.visible();
}
}
});
this.element.on(`mousemove.${this.getName()}`, e => {
if (!this.element.__isMouseInBounds__(e)) {
if (this.isEnabled() && !this._hover) {
assertMask();
this.$mask.invisible();
}
}
});
this.element.on(`mouseleave.${this.getName()}`, () => {
if (this.isEnabled() && !this._hover) {
assertMask();
this.$mask.invisible();
}
});
}
bindEvent() {
const o = this.options;
let hand = this.handle();
if (!hand) {
return;
}
hand = hand.element;
const getBubble = () => {
const bubble = o.bubble;
if (isFunction(bubble)) {
return bubble();
}
return bubble;
};
const clk = e => {
ev(e);
if (!this.isEnabled() || !this.isValid()) {
return;
}
if (this.isOnce() && this.isSelected()) {
return;
}
if (isKey(o.bubble) || isFunction(o.bubble)) {
if (isNull(this.combo)) {
let popup;
createWidget({
type: AbsoluteLayout.xtype,
element: this,
items: [
{
el: {
type: BubbleCombo.xtype,
trigger: "",
// bubble的提示不需要一直存在在界面上
destroyWhenHide: true,
ref: _ref => {
this.combo = _ref;
},
el: {
type: Layout.xtype,
height: "100%",
},
popup: {
type: TextBubblePopupBarView.xtype,
text: getBubble(),
ref: _ref => {
popup = _ref;
},
listeners: [
{
eventName: BubblePopupBarView.EVENT_CLICK_TOOLBAR_BUTTON,
action: (...args) => {
const [v] = args;
this.combo.hideView();
if (v) {
onClick.apply(this, args);
}
},
}
],
},
listeners: [
{
eventName: BubbleCombo.EVENT_BEFORE_POPUPVIEW,
action() {
popup.populate(getBubble());
},
}
],
},
left: 0,
right: 0,
bottom: 0,
top: 0,
}
],
});
}
if (this.combo.isViewVisible()) {
this.combo.hideView();
} else {
this.combo.showView();
}
return;
}
onClick.apply(this, arguments);
};
const triggerArr = (o.trigger || "").split(",");
triggerArr.forEach(trigger => {
let mouseDown = false;
let selected = false;
let interval;
switch (trigger) {
case "mouseup":
hand.mousedown(() => {
mouseDown = true;
});
hand.mouseup(e => {
if (mouseDown === true) {
clk(e);
}
mouseDown = false;
ev(e);
});
break;
case "mousedown":
// let mouseDown = false;
hand.mousedown(e => {
// if (e.button === 0) {
Widget._renderEngine.createElement(document).bind(`mouseup.${this.getName()}`, e => {
// if (e.button === 0) {
if (
DOM.isExist(this) &&
!hand.__isMouseInBounds__(e) &&
mouseDown === true &&
!selected
) {
// self.setSelected(!self.isSelected());
this._trigger();
}
mouseDown = false;
Widget._renderEngine.createElement(document).unbind(`mouseup.${this.getName()}`);
// }
});
if (mouseDown === true) {
return;
}
if (this.isSelected()) {
selected = true;
} else {
clk(e);
}
mouseDown = true;
ev(e);
// }
});
hand.mouseup(e => {
// if (e.button === 0) {
if (DOM.isExist(this) && mouseDown === true && selected === true) {
clk(e);
}
mouseDown = false;
selected = false;
Widget._renderEngine.createElement(document).unbind(`mouseup.${this.getName()}`);
// }
});
break;
case "dblclick":
hand.dblclick(clk);
break;
case "lclick":
hand.mousedown(e => {
Widget._renderEngine.createElement(document).bind(`mouseup.${this.getName()}`, () => {
interval && clearInterval(interval);
interval = null;
mouseDown = false;
Widget._renderEngine.createElement(document).unbind(`mouseup.${this.getName()}`);
});
if (mouseDown === true) {
return;
}
if (!this.isEnabled() || !this.isValid()) {
return;
}
if (this.isOnce() && this.isSelected()) {
return;
}
interval = setInterval(() => {
clk(e);
}, 180);
mouseDown = true;
ev(e);
});
break;
default:
if (o.stopEvent || o.stopPropagation) {
hand.mousedown(e => {
ev(e);
});
}
hand.click(clk);
// enter键等同于点击
o.attributes &&
o.attributes.zIndex >= 0 &&
hand.keyup(e => {
if (e.keyCode === KeyCode.ENTER) {
clk(e);
}
});
break;
}
});
// 之后的300ms点击无效
const onClick = o.debounce
? debounce(this._doClick, EVENT_RESPONSE_TIME, {
leading: true,
trailing: false,
})
: this._doClick;
function ev(e) {
if (o.stopEvent) {
e.stopEvent();
}
if (o.stopPropagation) {
e.stopPropagation();
}
}
}
_trigger(e) {
const o = this.options;
if (!this.isEnabled()) {
return;
}
if (!this.isDisableSelected()) {
this.isForceSelected()
? this.setSelected(true)
: this.isForceNotSelected()
? this.setSelected(false)
: this.setSelected(!this.isSelected());
}
if (this.isValid()) {
const v = this.getValue();
o.handler.call(this, v, this, e);
this.fireEvent(Controller.EVENT_CHANGE, Events.CLICK, v, this, e);
this.fireEvent(BasicButton.EVENT_CHANGE, v, this);
if (o.action) {
Actions.runAction(o.action, "click", o, this);
}
Actions.runGlobalAction("click", o, this);
}
}
_doClick(e) {
if (!this.isEnabled() || !this.isValid()) {
return;
}
const isIntercepted = this.beforeClick(e);
// 如果事件已经被消费掉了,就不再触发点击事件
if (isIntercepted) {
return;
}
this._trigger(e);
if (this.isEnabled() && this.isValid()) {
this.doClick(e);
}
}
/**
* 子类可以得写这个方法,如果返回为 true,则可以阻止 handler 的触发
*/
beforeClick() {}
doClick() {}
handle() {
return this;
}
hover() {
this._hover = true;
this.handle().element.addClass("hover");
if (this.options.shadow) {
this.$mask && this.$mask.setVisible(true);
}
}
dishover() {
this._hover = false;
this.handle().element.removeClass("hover");
if (this.options.shadow) {
this.$mask && this.$mask.setVisible(false);
}
}
setSelected(b) {
const o = this.options;
o.selected = b;
if (b) {
this.handle().element.addClass("active");
} else {
this.handle().element.removeClass("active");
}
if (o.shadow && !o.isShadowShowingOnSelected) {
this.$mask && this.$mask.setVisible(false);
}
this.options.setSelected && this.options.setSelected.call(this, b);
}
isSelected() {
return this.options.selected;
}
isOnce() {
return this.options.once;
}
isForceSelected() {
return this.options.forceSelected;
}
isForceNotSelected() {
return this.options.forceNotSelected;
}
isDisableSelected() {
return this.options.disableSelected;
}
setText(text) {
this.options.text = text;
this.options.setText && this.options.setText.call(this, text);
}
getText() {
return this.options.text;
}
_setEnable(enable) {
super._setEnable(...arguments);
if (enable === true) {
this.element.removeClass("base-disabled disabled");
} else if (enable === false) {
this.element.addClass("base-disabled disabled");
}
if (!enable) {
if (this.options.shadow) {
this.$mask && this.$mask.setVisible(false);
}
}
}
empty() {
Widget._renderEngine.createElement(document).unbind(`mouseup.${this.getName()}`);
super.empty(...arguments);
}
}