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.
 
 
 

420 lines
12 KiB

/**
*
* 表格滚动条
*
* Created by GUY on 2016/1/12.
* @class BI.GridTableScrollbar
* @extends BI.Widget
*/
BI.GridTableScrollbar = BI.inherit(BI.Widget, {
_const: {
FACE_MARGIN: 4,
FACE_MARGIN_2: 4 * 2,
FACE_SIZE_MIN: 30,
KEYBOARD_SCROLL_AMOUNT: 40
},
_defaultConfig: function () {
return BI.extend(BI.GridTableScrollbar.superclass._defaultConfig.apply(this, arguments), {
baseCls: "scrollbar-layout-main public-scrollbar-main",
attributes: {
tabIndex: 0
},
contentSize: 0,
defaultPosition: 0,
isOpaque: false,
orientation: "vertical",
position: 0,
size: 0
});
},
render: function () {
var self = this, o = this.options;
this.focused = false;
this.isDragging = false;
this.face = BI.createWidget({
type: "bi.layout",
cls: "scrollbar-layout-face public-scrollbar-face "
+ (this._isHorizontal() ? "scrollbar-layout-face-horizontal" : "scrollbar-layout-face-vertical")
});
this.contextLayout = BI.createWidget({
type: "bi.absolute",
element: this,
items: [{
el: this.face,
left: 0,
top: 0
}]
});
},
mounted: function () {
var self = this, o = this.options;
var onWheel = o.orientation === "horizontal" ? this._onWheelX : this._onWheelY;
this._wheelHandler = new BI.WheelHandler(
BI.bind(onWheel, this),
BI.bind(this._shouldHandleX, this),
BI.bind(this._shouldHandleY, this)
);
this._mouseMoveTracker = new BI.MouseMoveTracker(
BI.bind(this._onMouseMove, this),
BI.bind(this._onMouseMoveEnd, this),
document
);
this.element.on("mousedown", BI.bind(this._onMouseDown, this));
this.element.on("mousewheel", function (e) {
self._wheelHandler.onWheel(e.originalEvent);
});
this.element.on("keydown", BI.bind(this._onKeyDown, this));
this.element.on("focus", function () {
self.focused = true;
self._populate();
});
this.element.on("blur", function () {
self.focused = false;
self._populate();
});
if (this._isHorizontal()) {
this.element.addClass("scrollbar-layout-main-horizontal");
} else {
this.element.addClass("scrollbar-layout-main-vertical");
}
this._populate();
},
_isHorizontal: function () {
return this.options.orientation === "horizontal";
},
_getScale: function () {
var o = this.options;
var scale = o.size / o.contentSize;
var faceSize = o.size * scale;
if (faceSize < this._const.FACE_SIZE_MIN) {
scale = (o.size - this._const.FACE_SIZE_MIN) / (o.contentSize - o.size);
}
return scale;
},
_getFaceSize: function () {
var o = this.options;
var scale = o.size / o.contentSize;
var faceSize = o.size * scale;
if (faceSize < this._const.FACE_SIZE_MIN) {
faceSize = this._const.FACE_SIZE_MIN;
}
return faceSize;
},
_shouldHandleX: function (delta) {
return this.options.orientation === "horizontal" ?
this._shouldHandleChange(delta) :
false;
},
_shouldHandleY: function (delta) {
return this.options.orientation !== "horizontal" ?
this._shouldHandleChange(delta) :
false;
},
_shouldHandleChange: function (delta) {
return this.options.position + delta !== this.options.position;
},
_onWheelY: function (deltaX, deltaY) {
this._onWheel(deltaY);
},
_onWheelX: function (deltaX, deltaY) {
this._onWheel(deltaX);
},
_onWheel: function (delta) {
var maxPosition = this.options.contentSize - this.options.size;
this.options.position += delta;
if (this.options.position < 0) {
this.options.position = 0;
} else if (this.options.position > maxPosition) {
this.options.position = maxPosition;
}
this._populate();
this.fireEvent(BI.GridTableScrollbar.EVENT_SCROLL, this.options.position);
},
_onMouseDown: function (e) {
if (e.target !== this.face.element[0]) {
var position = this._isHorizontal() ? e.offsetX : e.offsetY;
position /= this._getScale();
this.options.position = BI.clamp(position - (this._getFaceSize() * 0.5 / this._getScale()), 0, this.options.contentSize - this.options.size);
this._populate();
this.fireEvent(BI.GridTableScrollbar.EVENT_SCROLL, this.options.position);
} else {
this._mouseMoveTracker.captureMouseMoves(e);
}
try {
this.element[0].focus();
} catch (e) {
}
},
_onMouseMove: function (deltaX, deltaY) {
var delta = this._isHorizontal() ? deltaX : deltaY;
delta /= this._getScale();
this.options.position = BI.clamp(this.options.position + delta, 0, this.options.contentSize - this.options.size);
this.isDragging = this._mouseMoveTracker.isDragging();
this._populate();
this.fireEvent(BI.GridTableScrollbar.EVENT_SCROLL, this.options.position);
},
_onMouseMoveEnd: function (event) {
this._mouseMoveTracker.releaseMouseMoves();
if (this.isDragging === true) {
this.isDragging = false;
this._populate();
}
},
_onKeyDown: function (event) {
var Keys = {
BACKSPACE: 8,
TAB: 9,
RETURN: 13,
ALT: 18,
ESC: 27,
SPACE: 32,
PAGE_UP: 33,
PAGE_DOWN: 34,
END: 35,
HOME: 36,
LEFT: 37,
UP: 38,
RIGHT: 39,
DOWN: 40,
DELETE: 46,
COMMA: 188,
PERIOD: 190,
A: 65,
Z: 90,
ZERO: 48,
NUMPAD_0: 96,
NUMPAD_9: 105
};
var keyCode = event.keyCode;
if (keyCode === Keys.TAB) {
return;
}
var distance = 40;
var direction = 0;
if (this._isHorizontal()) {
switch (keyCode) {
case Keys.HOME:
direction = -1;
distance = this.options.contentSize;
break;
case Keys.LEFT:
direction = -1;
break;
case Keys.RIGHT:
direction = 1;
break;
default:
return;
}
}
if (!this._isHorizontal()) {
switch (keyCode) {
case Keys.SPACE:
if (event.shiftKey) {
direction = -1;
} else {
direction = 1;
}
break;
case Keys.HOME:
direction = -1;
distance = this.options.contentSize;
break;
case Keys.UP:
direction = -1;
break;
case Keys.DOWN:
direction = 1;
break;
case Keys.PAGE_UP:
direction = -1;
distance = this.options.size;
break;
case Keys.PAGE_DOWN:
direction = 1;
distance = this.options.size;
break;
default:
return;
}
}
this.options.position = BI.clamp(this.options.position + (distance * direction), 0, this.options.contentSize - this.options.size);
event.preventDefault();
this._populate();
this.fireEvent(BI.GridTableScrollbar.EVENT_SCROLL, this.options.position);
},
_populate: function () {
var self = this, o = this.options;
if (o.size < 1 || o.contentSize <= o.size) {
this.setVisible(false);
return;
}
this.setVisible(true);
var size = o.size;
var isHorizontal = this._isHorizontal();
var isActive = this.focused || this.isDragging;
var faceSize = this._getFaceSize();
var isOpaque = o.isOpaque;
this.element[isOpaque === true ? "addClass" : "removeClass"]("public-scrollbar-main-opaque");
this.element[isActive === true ? "addClass" : "removeClass"]("public-scrollbar-main-active");
this.face.element[isActive === true ? "addClass" : "removeClass"]("public-scrollbar-face-active");
var position = o.position * this._getScale() + this._const.FACE_MARGIN;
var items = this.contextLayout.attr("items");
if (isHorizontal) {
this.setWidth(size);
this.face.setWidth(faceSize - this._const.FACE_MARGIN_2);
items[0].left = position;
items[0].top = 0;
} else {
this.setHeight(size);
this.face.setHeight(faceSize - this._const.FACE_MARGIN_2);
items[0].left = 0;
items[0].top = position;
}
this.contextLayout.attr("items", items);
this.contextLayout.resize();
},
setContentSize: function (contentSize) {
this.options.contentSize = contentSize;
},
setPosition: function (position) {
this.options.position = position;
},
setSize: function (size) {
this.options.size = size;
},
populate: function () {
this._populate();
}
});
BI.GridTableScrollbar.SIZE = 10;
BI.GridTableScrollbar.EVENT_SCROLL = "EVENT_SCROLL";
BI.shortcut("bi.grid_table_scrollbar", BI.GridTableScrollbar);
BI.GridTableHorizontalScrollbar = BI.inherit(BI.Widget, {
_const: {
FACE_MARGIN: 4,
FACE_MARGIN_2: 4 * 2,
FACE_SIZE_MIN: 30,
KEYBOARD_SCROLL_AMOUNT: 40
},
_defaultConfig: function () {
return BI.extend(BI.GridTableHorizontalScrollbar.superclass._defaultConfig.apply(this, arguments), {
attributes: {
tabIndex: 0
},
contentSize: 0,
position: 0,
size: 0
});
},
_init: function () {
BI.GridTableHorizontalScrollbar.superclass._init.apply(this, arguments);
var self = this, o = this.options;
this.scrollbar = BI.createWidget({
type: "bi.grid_table_scrollbar",
orientation: "horizontal",
isOpaque: true,
position: o.position,
contentSize: o.contentSize,
size: o.size
});
this.scrollbar.on(BI.GridTableScrollbar.EVENT_SCROLL, function () {
self.fireEvent(BI.GridTableHorizontalScrollbar.EVENT_SCROLL, arguments);
});
BI.createWidget({
type: "bi.absolute",
cls: "horizontal-scrollbar",
element: this,
width: o.size,
height: BI.GridTableScrollbar.SIZE,
items: [{
el: {
type: "bi.absolute",
scrollable: false,
height: BI.GridTableScrollbar.SIZE,
items: [{
el: this.scrollbar,
left: 0,
top: 0
}]
},
top: 0,
left: 0,
right: 0
}]
});
},
setContentSize: function (contentSize) {
this.options.contentSize = contentSize;
this.scrollbar.setContentSize(contentSize);
},
setPosition: function (position) {
this.options.position = position;
this.scrollbar.setPosition(position);
},
setSize: function (size) {
this.setWidth(size);
this.options.size = size;
this.scrollbar.setSize(size);
},
populate: function () {
this.scrollbar.populate();
var o = this.options;
if (o.size < 1 || o.contentSize <= o.size) {
this.setVisible(false);
return;
}
this.setVisible(true);
}
});
BI.GridTableHorizontalScrollbar.EVENT_SCROLL = "EVENT_SCROLL";
BI.shortcut("bi.grid_table_horizontal_scrollbar", BI.GridTableHorizontalScrollbar);