webui-aria2/js/libs/dojox/mobile/SpinWheelSlot.js.uncompressed.js
2012-05-01 19:52:07 +08:00

329 lines
9.4 KiB
JavaScript

//>>built
define("dojox/mobile/SpinWheelSlot", [
"dojo/_base/declare",
"dojo/_base/window",
"dojo/dom-class",
"dojo/dom-construct",
"dijit/_Contained",
"dijit/_WidgetBase",
"./_ScrollableMixin"
], function(declare, win, domClass, domConstruct, Contained, WidgetBase, ScrollableMixin){
/*=====
var Contained = dijit._Contained;
var WidgetBase = dijit._WidgetBase;
var ScrollableMixin = dojox.mobile._ScrollableMixin;
=====*/
// module:
// dojox/mobile/SpinWheelSlot
// summary:
// A slot of a SpinWheel.
return declare("dojox.mobile.SpinWheelSlot", [WidgetBase, Contained, ScrollableMixin], {
// summary:
// A slot of a SpinWheel.
// description:
// SpinWheelSlot is a slot that is placed in the SpinWheel widget.
// items: Array
// An array of array of key-label paris.
// (e.g. [[0,"Jan"],[1,"Feb"],...] ) If key values for each label
// are not necessary, labels can be used instead.
items: [],
// labels: Array
// An array of labels to be displayed on the slot.
// (e.g. ["Jan","Feb",...] ) This is a simplified version of the
// items property.
labels: [],
// labelFrom: Number
// The start value of display values of the slot. This parameter is
// especially useful when slot has serial values.
labelFrom: 0,
// labelTo: Number
// The end value of display values of the slot.
labelTo: 0,
// value: String
// The initial value of the slot.
value: "",
/* internal properties */
maxSpeed: 500,
minItems: 15,
centerPos: 0,
scrollBar: false,
constraint: false,
allowNestedScrolls: false,
androidWorkaroud: false, // disable workaround in SpinWheel
buildRendering: function(){
this.inherited(arguments);
domClass.add(this.domNode, "mblSpinWheelSlot");
var i, j, idx;
if(this.labelFrom !== this.labelTo){
this.labels = [];
for(i = this.labelFrom, idx = 0; i <= this.labelTo; i++, idx++){
this.labels[idx] = String(i);
}
}
if(this.labels.length > 0){
this.items = [];
for(i = 0; i < this.labels.length; i++){
this.items.push([i, this.labels[i]]);
}
}
this.containerNode = domConstruct.create("DIV", {className:"mblSpinWheelSlotContainer"});
this.containerNode.style.height
= (win.global.innerHeight||win.doc.documentElement.clientHeight) * 2 + "px"; // must bigger than the screen
this.panelNodes = [];
for(var k = 0; k < 3; k++){
this.panelNodes[k] = domConstruct.create("DIV", {className:"mblSpinWheelSlotPanel"});
var len = this.items.length;
var n = Math.ceil(this.minItems / len);
for(j = 0; j < n; j++){
for(i = 0; i < len; i++){
domConstruct.create("DIV", {
className: "mblSpinWheelSlotLabel",
name: this.items[i][0],
innerHTML: this._cv ? this._cv(this.items[i][1]) : this.items[i][1]
}, this.panelNodes[k]);
}
}
this.containerNode.appendChild(this.panelNodes[k]);
}
this.domNode.appendChild(this.containerNode);
this.touchNode = domConstruct.create("DIV", {className:"mblSpinWheelSlotTouch"}, this.domNode);
this.setSelectable(this.domNode, false);
},
startup: function(){
this.inherited(arguments);
this.centerPos = this.getParent().centerPos;
var items = this.panelNodes[1].childNodes;
this._itemHeight = items[0].offsetHeight;
this.adjust();
},
adjust: function(){
// summary:
// Adjusts the position of slot panels.
var items = this.panelNodes[1].childNodes;
var adjustY;
for(var i = 0, len = items.length; i < len; i++){
var item = items[i];
if(item.offsetTop <= this.centerPos && this.centerPos < item.offsetTop + item.offsetHeight){
adjustY = this.centerPos - (item.offsetTop + Math.round(item.offsetHeight/2));
break;
}
}
var h = this.panelNodes[0].offsetHeight;
this.panelNodes[0].style.top = -h + adjustY + "px";
this.panelNodes[1].style.top = adjustY + "px";
this.panelNodes[2].style.top = h + adjustY + "px";
},
setInitialValue: function(){
// summary:
// Sets the initial value using this.value or the first item.
if(this.items.length > 0){
var val = (this.value !== "") ? this.value : this.items[0][1];
this.setValue(val);
}
},
getCenterPanel: function(){
// summary:
// Gets a panel that contains the currently selected item.
var pos = this.getPos();
for(var i = 0, len = this.panelNodes.length; i < len; i++){
var top = pos.y + this.panelNodes[i].offsetTop;
if(top <= this.centerPos && this.centerPos < top + this.panelNodes[i].offsetHeight){
return this.panelNodes[i];
}
}
return null;
},
setColor: function(/*String*/value){
// summary:
// Sets the color of the specified item as blue.
for(var i = 0, len = this.panelNodes.length; i < len; i++){
var items = this.panelNodes[i].childNodes;
for(var j = 0; j < items.length; j++){
if(items[j].innerHTML === String(value)){
domClass.add(items[j], "mblSpinWheelSlotLabelBlue");
}else{
domClass.remove(items[j], "mblSpinWheelSlotLabelBlue");
}
}
}
},
disableValues: function(/*Array*/values){
// summary:
// Makes the specified items grayed out.
for(var i = 0, len = this.panelNodes.length; i < len; i++){
var items = this.panelNodes[i].childNodes;
for(var j = 0; j < items.length; j++){
domClass.remove(items[j], "mblSpinWheelSlotLabelGray");
for(var k = 0; k < values.length; k++){
if(items[j].innerHTML === String(values[k])){
domClass.add(items[j], "mblSpinWheelSlotLabelGray");
break;
}
}
}
}
},
getCenterItem: function(){
// summary:
// Gets the currently selected item.
var pos = this.getPos();
var centerPanel = this.getCenterPanel();
if(centerPanel){
var top = pos.y + centerPanel.offsetTop;
var items = centerPanel.childNodes;
for(var i = 0, len = items.length; i < len; i++){
if(top + items[i].offsetTop <= this.centerPos && this.centerPos < top + items[i].offsetTop + items[i].offsetHeight){
return items[i];
}
}
}
return null;
},
getValue: function(){
// summary:
// Gets the currently selected value.
var item = this.getCenterItem();
return (item && item.innerHTML);
},
getKey: function(){
// summary:
// Gets the key for the currently selected value.
return this.getCenterItem().getAttribute("name");
},
setValue: function(newValue){
// summary:
// Sets the newValue to this slot.
var idx0, idx1;
var curValue = this.getValue();
if(!curValue){
this._penddingValue = newValue;
return;
}
this._penddingValue = undefined;
var n = this.items.length;
for(var i = 0; i < n; i++){
if(this.items[i][1] === String(curValue)){
idx0 = i;
}
if(this.items[i][1] === String(newValue)){
idx1 = i;
}
if(idx0 !== undefined && idx1 !== undefined){
break;
}
}
var d = idx1 - (idx0 || 0);
var m;
if(d > 0){
m = (d < n - d) ? -d : n - d;
}else{
m = (-d < n + d) ? -d : -(n + d);
}
var to = this.getPos();
to.y += m * this._itemHeight;
this.slideTo(to, 1);
},
getSpeed: function(){
// summary:
// Overrides dojox.mobile.scrollable.getSpeed().
var y = 0, n = this._time.length;
var delta = (new Date()).getTime() - this.startTime - this._time[n - 1];
if(n >= 2 && delta < 200){
var dy = this._posY[n - 1] - this._posY[(n - 6) >= 0 ? n - 6 : 0];
var dt = this._time[n - 1] - this._time[(n - 6) >= 0 ? n - 6 : 0];
y = this.calcSpeed(dy, dt);
}
return {x:0, y:y};
},
calcSpeed: function(/*Number*/d, /*Number*/t){
// summary:
// Overrides dojox.mobile.scrollable.calcSpeed().
var speed = this.inherited(arguments);
if(!speed){ return 0; }
var v = Math.abs(speed);
var ret = speed;
if(v > this.maxSpeed){
ret = this.maxSpeed*(speed/v);
}
return ret;
},
adjustDestination: function(to, pos){
// summary:
// Overrides dojox.mobile.scrollable.adjustDestination().
var h = this._itemHeight;
var j = to.y + Math.round(h/2);
var a = Math.abs(j);
var r = j >= 0 ? j % h : j % h + h;
to.y = j - r;
},
resize: function(e){
if(this._penddingValue){
this.setValue(this._penddingValue);
}
},
slideTo: function(/*Object*/to, /*Number*/duration, /*String*/easing){
// summary:
// Overrides dojox.mobile.scrollable.slideTo().
var pos = this.getPos();
var top = pos.y + this.panelNodes[1].offsetTop;
var bottom = top + this.panelNodes[1].offsetHeight;
var vh = this.domNode.parentNode.offsetHeight;
var t;
if(pos.y < to.y){ // going down
if(bottom > vh){
// move up the bottom panel
t = this.panelNodes[2];
t.style.top = this.panelNodes[0].offsetTop - this.panelNodes[0].offsetHeight + "px";
this.panelNodes[2] = this.panelNodes[1];
this.panelNodes[1] = this.panelNodes[0];
this.panelNodes[0] = t;
}
}else if(pos.y > to.y){ // going up
if(top < 0){
// move down the top panel
t = this.panelNodes[0];
t.style.top = this.panelNodes[2].offsetTop + this.panelNodes[2].offsetHeight + "px";
this.panelNodes[0] = this.panelNodes[1];
this.panelNodes[1] = this.panelNodes[2];
this.panelNodes[2] = t;
}
}
if(!this._initialized){
duration = 0; // to reduce flickers at start-up especially on android
this._initialized = true;
}else if(Math.abs(this._speed.y) < 40){
duration = 0.2;
}
this.inherited(arguments, [to, duration, easing]); // 2nd arg is to avoid excessive optimization by closure compiler
}
});
});