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.
268 lines
8.1 KiB
268 lines
8.1 KiB
define([ |
|
"dojo/_base/kernel", |
|
"dojo/_base/array", |
|
"dojo/_base/config", |
|
"dojo/_base/connect", |
|
"dojo/_base/declare", |
|
"dojo/_base/lang", |
|
"dojo/_base/window", |
|
"dojo/dom", |
|
"dijit/registry" |
|
], function(kernel, array, config, connect, declare, lang, win, dom, registry){ |
|
|
|
// module: |
|
// dojox/mobile/ScreenSizeAware |
|
|
|
kernel.experimental("dojox.mobile.ScreenSizeAware"); // should consider support for other UI layout patterns |
|
|
|
var cls = declare("dojox.mobile.ScreenSizeAware", null, { |
|
// summary: |
|
// A module to make a screen size aware application. |
|
// description: |
|
// This module helps for creating applications that transform their |
|
// UI layout according to the screen size. It assumes that the |
|
// application consists of two horizontally split panes, and the |
|
// left pane has a list widget. If you require this module in such an |
|
// application, in a tablet-sized screen, the application shows a horizontally |
|
// split view whose left pane is a list widget. |
|
// In a phone-sized screen, the application shows a list widget that fills the screen. |
|
// |
|
// example: |
|
// | <span data-dojo-type="dojox.mobile.ScreenSizeAware"></span> |
|
// | <div data-dojo-type="dojox.mobile.FixedSplitter" data-dojo-props='orientation:"H"'> |
|
// | <div data-dojo-type="dojox.mobile.Container" style="width:300px;"> |
|
// | <div id="leftView" data-dojo-type="dojox.mobile.ScrollableView"> |
|
// | <h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Left Pane</h1> |
|
// | <ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='stateful:true'> |
|
// | <li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='label:"View1", moveTo:"view1"'></li> |
|
// | .... |
|
// | </ul> |
|
// | </div> |
|
// | </div> |
|
// | <div data-dojo-type="dojox.mobile.Container"> |
|
// | <div id="view1" data-dojo-type="dojox.mobile.ScrollableView"> |
|
// | <h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"Home", moveTo:"leftView"'>Right Pane</h1> |
|
// | .... |
|
// | </div> |
|
// | </div> |
|
// | </div> |
|
|
|
// splitterId: String |
|
// The id of the FixedSplitter. |
|
splitterId: "", |
|
|
|
// leftPaneId: String |
|
// The id of the left pane. |
|
leftPaneId: "", |
|
|
|
// rightPaneId: String |
|
// The id of the right pane. |
|
rightPaneId: "", |
|
|
|
// leftViewId: String |
|
// The id of the left View. |
|
leftViewId: "", |
|
|
|
// leftListId: String |
|
// The id of the list widget in the left view. |
|
leftListId: "", |
|
|
|
constructor: function(/*Object?*/options){ |
|
// summary: |
|
// Creates a new instance of the class. |
|
// options: |
|
// Contains properties to be set. |
|
if (options){ |
|
lang.mixin(this, options); |
|
} |
|
connect.subscribe("/dojox/mobile/screenSize/tablet", this, function(dim){ |
|
this.transformUI("tablet"); |
|
}); |
|
connect.subscribe("/dojox/mobile/screenSize/phone", this, function(dim){ |
|
this.transformUI("phone"); |
|
}); |
|
}, |
|
|
|
init: function(){ |
|
// summary: |
|
// Initializes the application. |
|
if(this._initialized){ return; } |
|
this._initialized = true; |
|
|
|
// analyze the page structure |
|
this.splitter = this.splitterId ? registry.byId(this.splitterId) : |
|
array.filter(registry.findWidgets(win.body()), |
|
function(c){ return c.declaredClass.indexOf("Splitter") !== -1; })[0]; |
|
if(!this.splitter){ |
|
console.error("Splitter not found."); |
|
return; |
|
} |
|
|
|
this.leftPane = this.leftPaneId ? registry.byId(this.leftPaneId) : |
|
this.splitter.getChildren()[0]; |
|
if(!this.leftPane){ |
|
console.error("Left pane not found."); |
|
return; |
|
} |
|
|
|
this.rightPane = this.rightPaneId ? registry.byId(this.rightPaneId) : |
|
this.splitter.getChildren()[1]; |
|
if(!this.rightPane){ |
|
console.error("Right pane not found."); |
|
return; |
|
} |
|
|
|
this.leftView = this.leftViewId ? registry.byId(this.leftViewId) : |
|
array.filter(registry.findWidgets(this.leftPane.containerNode), |
|
function(c){ return c.declaredClass.indexOf("View") !== -1; })[0]; |
|
if(!this.leftView){ |
|
console.error("Left view not found."); |
|
return; |
|
} |
|
|
|
this.leftList = this.leftListId ? registry.byId(this.leftListId) : |
|
array.filter(registry.findWidgets(this.leftView.containerNode), |
|
function(c){ return c.declaredClass.indexOf("List") !== -1 || |
|
c.declaredClass.indexOf("IconContainer") !== -1; })[0]; |
|
if(!this.leftList){ |
|
console.error("Left list not found."); |
|
return; |
|
} |
|
}, |
|
|
|
isPhone: function(){ |
|
// summary: |
|
// Returns true if the current mode set by transformUI(mode) is "phone". |
|
return this._currentMode === "phone"; // Boolean |
|
}, |
|
|
|
getShowingView: function(){ |
|
// summary: |
|
// Returns the view currently shown. |
|
var firstView = |
|
array.filter(this.rightPane.getChildren(), function(c){ return c.declaredClass.indexOf("View") !== -1; })[0]; |
|
if(!firstView){ return null; } |
|
return firstView.getShowingView() || |
|
array.filter(this.rightPane.getChildren(), function(c){ return c.selected; })[0] || |
|
firstView; |
|
}, |
|
|
|
updateStateful: function(){ |
|
// summary: |
|
// Updates the stateful property of the list widget in the left-side pane. |
|
this.leftList.set("stateful", !this.isPhone()); |
|
}, |
|
|
|
getDestinationId: function(item){ |
|
// summary: |
|
// Returns the id of the target view of the given item. |
|
return item.moveTo; |
|
}, |
|
|
|
updateBackButton: function(){ |
|
// summary: |
|
// Updates the back button. |
|
array.forEach(this.leftList.getChildren(), function(item){ |
|
var id = this.getDestinationId(item); |
|
var view = registry.byId(id); |
|
if(view){ |
|
var heading = array.filter(view.getChildren(), function(c){ return c.declaredClass.indexOf("Heading") !== -1; })[0]; |
|
if(heading.backButton){ |
|
heading.backButton.domNode.style.display = this.isPhone() ? "" : "none"; |
|
} |
|
if(heading.backBtnNode){ // TODO: remove this block later |
|
heading.backBtnNode.style.display = this.isPhone() ? "" : "none"; |
|
} |
|
} |
|
}, this); |
|
}, |
|
|
|
updateTransition: function(){ |
|
// summary: |
|
// Updates the transition property of the items in the left-side widget. |
|
var transition = this.isPhone() ? "slide" : "none"; |
|
array.forEach(this.leftList.getChildren(), function(item){ |
|
item.set("transition", transition); |
|
}); |
|
}, |
|
|
|
moveList: function(){ |
|
// summary: |
|
// Places the list widget. If the current mode is "phone", it |
|
// places the list widget in the right pane, otherwise in the left pane. |
|
var to = this.isPhone() ? this.rightPane: this.leftPane; |
|
to.containerNode.appendChild(this.leftView.domNode); |
|
}, |
|
|
|
showLeftView: function(){ |
|
// summary: |
|
// Shows the left-side view. |
|
this.leftPane.domNode.style.display = this.isPhone() ? "none" : ""; |
|
this.leftView.show(); |
|
}, |
|
|
|
showRightView: function(){ |
|
// summary: |
|
// Shows the right-side view. |
|
if(this.isPhone()){ return; } |
|
var view = this.getShowingView(); |
|
if(view){ |
|
view.show(); |
|
}else{ |
|
this.leftItemSelected(); |
|
} |
|
}, |
|
|
|
updateSelectedItem: function(){ |
|
// summary: |
|
// Updates the selected item. |
|
var id; |
|
var view = this.getShowingView(); |
|
if(view && !this.isPhone()){ |
|
id = view.id; |
|
} |
|
if(id){ |
|
var items = array.filter(this.leftList.getChildren(), |
|
function(item){ return this.getDestinationId(item) === id; }, this); |
|
if(items && items.length > 0){ |
|
items[0].set("selected", true); |
|
} |
|
}else{ |
|
this.leftList.deselectAll && this.leftList.deselectAll(); |
|
} |
|
}, |
|
|
|
leftItemSelected: function(/*Event*/ /*===== e =====*/){ |
|
// summary: |
|
// Function called when an item in the left-side list is selected. |
|
}, |
|
|
|
transformUI: function(/*String*/mode){ |
|
// summary: |
|
// Applies an UI mode. |
|
// mode: |
|
// If this argument is "phone", sets the UI in phone mode, otherwise |
|
// in tablet mode. |
|
this.init(); |
|
if(mode === this._currentMode){ return; } |
|
this._currentMode = mode; |
|
this.updateStateful(); |
|
this.updateBackButton(); |
|
this.updateTransition(); |
|
this.moveList(); |
|
this.showLeftView(); |
|
this.showRightView(); |
|
this.updateSelectedItem(); |
|
} |
|
}); |
|
|
|
cls._instance = null; |
|
cls.getInstance = function(){ |
|
if(!cls._instance){ |
|
cls._instance = new cls(); |
|
} |
|
return cls._instance; |
|
}; |
|
|
|
return cls; |
|
});
|
|
|