diff options
Diffstat (limited to 'js/dojo/dojox/mobile/SpinWheelSlot.js')
| -rw-r--r-- | js/dojo/dojox/mobile/SpinWheelSlot.js | 328 |
1 files changed, 328 insertions, 0 deletions
diff --git a/js/dojo/dojox/mobile/SpinWheelSlot.js b/js/dojo/dojox/mobile/SpinWheelSlot.js new file mode 100644 index 0000000..d6322db --- /dev/null +++ b/js/dojo/dojox/mobile/SpinWheelSlot.js @@ -0,0 +1,328 @@ +//>>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 + } + }); +}); |
