dojo.provide("dojox.layout.RotatorContainer");
dojo.require("dojo.fx");
dojo.require("dijit.layout.StackContainer");
dojo.require("dijit.layout.StackController");
dojo.require("dijit._Widget");
dojo.require("dijit._Templated");
dojo.require("dijit._Contained");
dojo.declare("dojox.layout.RotatorContainer",
[dijit.layout.StackContainer, dijit._Templated], {
// summary:
// Extends a StackContainer to automatically transition between children
// and display navigation in the form of tabs or a pager.
//
// description:
// The RotatorContainer cycles through the children with a transition.
//
// published topics:
// [widgetId]-update - Notifies pager(s) that a child has changed.
// Parameters:
// /*boolean*/ playing - true if playing, false if paused
// /*int*/ current - current selected child
// /*int*/ total - total number of children
//
// example:
// |
// |
// | Pane 1!
// |
// |
// | Pane 2!
// |
// |
// | Pane 3 with overrided transitionDelay!
// |
// |
templateString: '
',
// showTabs: Boolean
// Sets the display of the tabs. The tabs are actually a StackController.
// The child's title is used for the tab's label.
showTabs: true,
// transitionDelay: int
// The delay in milliseconds before transitioning to the next child.
transitionDelay: 5000,
// transition: String
// The type of transition to perform when switching children.
// A null transition will transition instantly.
transition: "fade",
// transitionDuration: int
// The duration of the transition in milliseconds.
transitionDuration: 1000,
// autoStart: Boolean
// Starts the timer to transition children upon creation.
autoStart: true,
// suspendOnHover: Boolean
// Pause the rotator when the mouse hovers over it.
suspendOnHover: false,
// pauseOnManualChange: Boolean
// Pause the rotator when the tab is changed or the pager's next/previous
// buttons are clicked.
pauseOnManualChange: null,
// reverse: Boolean
// Causes the rotator to rotate in reverse order.
reverse: false,
// pagerId: String
// ID the pager widget.
pagerId: "",
// cycles: int
// Number of cycles before pausing.
cycles: -1,
// pagerClass: String
// The declared Class of the Pager used for this Widget
pagerClass: "dojox.layout.RotatorPager",
postCreate: function(){
// summary: Initializes the DOM nodes, tabs, and transition stuff.
this.inherited(arguments);
// force this DOM node to a relative position and make sure the children are absolute positioned
dojo.style(this.domNode, "position", "relative");
// validate the cycles counter
if(this.cycles-0 == this.cycles && this.cycles != -1){
// we need to add 1 because we decrement cycles before the animation starts
this.cycles++;
}else{
this.cycles = -1;
}
// if they didn't specify the pauseOnManualChange, then we want it to be the opposite of
// the suspendOnHover since it doesn't make sense to do both, unless you really want to
if(this.pauseOnManualChange === null){
this.pauseOnManualChange = !this.suspendOnHover;
}
// create the stack controller if we are using tabs
var id = this.id || "rotator"+(new Date()).getTime(),
sc = new dijit.layout.StackController({ containerId:id }, this.tabNode);
this.tabNode = sc.domNode;
this._stackController = sc;
dojo.style(this.tabNode, "display", this.showTabs ? "" : "none");
// if the controller's tabs are clicked, check if we should pause and reset the cycle counter
this.connect(sc, "onButtonClick","_manualChange");
// set up our topic listeners
this._subscriptions = [
dojo.subscribe(this.id+"-cycle", this, "_cycle"),
dojo.subscribe(this.id+"-state", this, "_state")
];
// make sure the transition duration isn't less than the transition delay
var d = Math.round(this.transitionDelay * 0.75);
if(d < this.transitionDuration){
this.transitionDuration = d;
}
// wire up the mouse hover events
if(this.suspendOnHover){
this.connect(this.domNode, "onmouseover", "_onMouseOver");
this.connect(this.domNode, "onmouseout", "_onMouseOut");
}
},
startup: function(){
// summary: Initializes the pagers.
if(this._started){ return; }
// check if the pager is defined within the rotator container
var c = this.getChildren();
for(var i=0, len=c.length; i
if(c[i].declaredClass == this.pagerClass){
this.pagerNode.appendChild(c[i].domNode);
break;
}
}
// process the child widgets
this.inherited(arguments);
// check if we should start automatically
if(this.autoStart){
// start playing
setTimeout(dojo.hitch(this, "_play"), 10);
}else{
// update the pagers with the initial state
this._updatePager();
}
},
destroy: function(){
// summary: Unsubscribe to all of our topics
dojo.forEach(this._subscriptions, dojo.unsubscribe);
this.inherited(arguments);
},
_setShowTabsAttr: function(/*anything*/value){
this.showTabs = value;
dojo.style(this.tabNode, "display", value ? "" : "none");
},
_updatePager: function(){
// summary: Notify the pager's current and total numbers.
var c = this.getChildren();
dojo.publish(this.id+"-update", [this._playing, dojo.indexOf(c, this.selectedChildWidget)+1, c.length]);
},
_onMouseOver: function(){
// summary: Triggered when the mouse is moved over the rotator container.
// temporarily suspend the cycling, but don't officially pause it
this._resetTimer();
this._over = true;