//>>built define("dojox/app/scene", ["dojo/_base/kernel", "dojo/_base/declare", "dojo/_base/connect", "dojo/_base/array", "dojo/_base/Deferred", "dojo/_base/lang", "dojo/_base/sniff", "dojo/dom-style", "dojo/dom-geometry", "dojo/dom-class", "dojo/dom-construct", "dojo/dom-attr", "dojo/query", "dijit", "dojox", "dijit/_WidgetBase", "dijit/_TemplatedMixin", "dijit/_WidgetsInTemplateMixin", "dojox/css3/transit", "./animation", "./model", "./view", "./bind"], function(dojo,declare,connect, array,deferred,dlang,has,dstyle,dgeometry,cls,dconstruct,dattr,query,dijit,dojox,WidgetBase,Templated,WidgetsInTemplate,transit, anim, model, baseView, bind){ var marginBox2contentBox = function(/*DomNode*/ node, /*Object*/ mb){ // summary: // Given the margin-box size of a node, return its content box size. // Functions like dojo.contentBox() but is more reliable since it doesn't have // to wait for the browser to compute sizes. var cs = dstyle.getComputedStyle(node); var me = dgeometry.getMarginExtents(node, cs); var pb = dgeometry.getPadBorderExtents(node, cs); return { l: dstyle.toPixelValue(node, cs.paddingLeft), t: dstyle.toPixelValue(node, cs.paddingTop), w: mb.w - (me.w + pb.w), h: mb.h - (me.h + pb.h) }; }; var capitalize = function(word){ return word.substring(0,1).toUpperCase() + word.substring(1); }; var size = function(widget, dim){ // size the child var newSize = widget.resize ? widget.resize(dim) : dgeometry.setMarginBox(widget.domNode, dim); // record child's size if(newSize){ // if the child returned it's new size then use that dojo.mixin(widget, newSize); }else{ // otherwise, call marginBox(), but favor our own numbers when we have them. // the browser lies sometimes dojo.mixin(widget, dgeometry.getMarginBox(widget.domNode)); dojo.mixin(widget, dim); } }; return declare("dojox.app.scene", [dijit._WidgetBase, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], { isContainer: true, widgetsInTemplate: true, defaultView: "default", selectedChild: null, baseClass: "scene mblView", isFullScreen: false, defaultViewType: baseView, //Temporary work around for getting a null when calling getParent getParent: function(){return null;}, constructor: function(params,node){ this.children={}; if(params.parent){ this.parent=params.parent } if(params.app){ this.app = params.app; } }, buildRendering: function(){ this.inherited(arguments); dstyle.set(this.domNode, {width: "100%", "height": "100%"}); cls.add(this.domNode,"dijitContainer"); }, splitChildRef: function(childId){ var id = childId.split(","); if (id.length>0){ var to = id.shift(); }else{ console.warn("invalid child id passed to splitChildRef(): ", childId); } return { id:to || this.defaultView, next: id.join(',') } }, loadChild: function(childId,subIds){ // if no childId, load the default view if (!childId) { var parts = this.defaultView ? this.defaultView.split(",") : "default"; childId = parts.shift(); subIds = parts.join(','); } var cid = this.id+"_" + childId; if (this.children[cid]){ return this.children[cid]; } if (this.views&& this.views[childId]){ var conf = this.views[childId]; if (!conf.dependencies){conf.dependencies=[];} var deps = conf.template? conf.dependencies.concat(["dojo/text!app/"+conf.template]) : conf.dependencies.concat([]); var def = new deferred(); if (deps.length>0) { require(deps,function(){ def.resolve.call(def, arguments); }); }else{ def.resolve(true); } var loadChildDeferred = new deferred(); var self = this; deferred.when(def, function(){ var ctor; if (conf.type){ ctor=dojo.getObject(conf.type); }else if (self.defaultViewType){ ctor=self.defaultViewType; }else{ throw Error("Unable to find appropriate ctor for the base child class"); } var params = dojo.mixin({}, conf, { id: self.id + "_" + childId, templateString: conf.template?arguments[0][arguments[0].length-1]:"
", parent: self, app: self.app }) if (subIds){ params.defaultView=subIds; } var child = new ctor(params); //load child's model if it is not loaded before if(!child.loadedModels){ child.loadedModels = model(conf.models, self.loadedModels) //TODO need to find out a better way to get all bindable controls in a view bind([child], child.loadedModels); } var addResult = self.addChild(child); //publish /app/loadchild event //application can subscript this event to do user define operation like select TabBarButton, add dynamic script text etc. connect.publish("/app/loadchild", [child]); var promise; subIds = subIds.split(','); if ((subIds[0].length > 0) && (subIds.length > 1)) {//TODO join subIds promise = child.loadChild(subIds[0], subIds[1]); } else if (subIds[0].length > 0) { promise = child.loadChild(subIds[0], ""); } dojo.when(promise, function(){ loadChildDeferred.resolve(addResult) }); }); return loadChildDeferred; } throw Error("Child '" + childId + "' not found."); }, resize: function(changeSize,resultSize){ var node = this.domNode; // set margin box size, unless it wasn't specified, in which case use current size if(changeSize){ dgeometry.setMarginBox(node, changeSize); // set offset of the node if(changeSize.t){ node.style.top = changeSize.t + "px"; } if(changeSize.l){ node.style.left = changeSize.l + "px"; } } // If either height or width wasn't specified by the user, then query node for it. // But note that setting the margin box and then immediately querying dimensions may return // inaccurate results, so try not to depend on it. var mb = resultSize || {}; dojo.mixin(mb, changeSize || {}); // changeSize overrides resultSize if( !("h" in mb) || !("w" in mb) ){ mb = dojo.mixin(dgeometry.getMarginBox(node), mb); // just use dojo.marginBox() to fill in missing values } // Compute and save the size of my border box and content box // (w/out calling dojo.contentBox() since that may fail if size was recently set) var cs = dstyle.getComputedStyle(node); var me = dgeometry.getMarginExtents(node, cs); var be = dgeometry.getBorderExtents(node, cs); var bb = (this._borderBox = { w: mb.w - (me.w + be.w), h: mb.h - (me.h + be.h) }); var pe = dgeometry.getPadExtents(node, cs); this._contentBox = { l: dstyle.toPixelValue(node, cs.paddingLeft), t: dstyle.toPixelValue(node, cs.paddingTop), w: bb.w - pe.w, h: bb.h - pe.h }; // Callback for widget to adjust size of its children this.layout(); }, layout: function(){ var fullScreenScene,children,hasCenter; //console.log("fullscreen: ", this.selectedChild && this.selectedChild.isFullScreen); if (this.selectedChild && this.selectedChild.isFullScreen) { console.warn("fullscreen sceen layout"); /* fullScreenScene=true; children=[{domNode: this.selectedChild.domNode,region: "center"}]; dojo.query("> [region]",this.domNode).forEach(function(c){ if(this.selectedChild.domNode!==c.domNode){ dojo.style(c.domNode,"display","none"); } }) */ }else{ children = query("> [region]", this.domNode).map(function(node){ var w = dijit.getEnclosingWidget(node); if (w){return w;} return { domNode: node, region: dattr.get(node,"region") } }); if (this.selectedChild){ children = array.filter(children, function(c){ if (c.region=="center" && this.selectedChild && this.selectedChild.domNode!==c.domNode){ dstyle.set(c.domNode,"zIndex",25); dstyle.set(c.domNode,'display','none'); return false; }else if (c.region!="center"){ dstyle.set(c.domNode,"display",""); dstyle.set(c.domNode,"zIndex",100); } return c.domNode && c.region; },this); // this.selectedChild.region="center"; // dojo.attr(this.selectedChild.domNode,"region","center"); // dojo.style(this.selectedChild.domNode, "display",""); // dojo.style(this.selectedChild.domNode,"zIndex",50); // children.push({domNode: this.selectedChild.domNode, region: "center"}); // children.push(this.selectedChild); // console.log("children: ", children); }else{ array.forEach(children, function(c){ if (c && c.domNode && c.region=="center"){ dstyle.set(c.domNode,"zIndex",25); dstyle.set(c.domNode,'display','none'); } }); } } // We don't need to layout children if this._contentBox is null for the operation will do nothing. if (this._contentBox) { this.layoutChildren(this.domNode, this._contentBox, children); } array.forEach(this.getChildren(), function(child){ if (!child._started && child.startup){ child.startup(); } }); }, layoutChildren: function(/*DomNode*/ container, /*Object*/ dim, /*Widget[]*/ children, /*String?*/ changedRegionId, /*Number?*/ changedRegionSize){ // summary // Layout a bunch of child dom nodes within a parent dom node // container: // parent node // dim: // {l, t, w, h} object specifying dimensions of container into which to place children // children: // an array of Widgets or at least objects containing: // * domNode: pointer to DOM node to position // * region or layoutAlign: position to place DOM node // * resize(): (optional) method to set size of node // * id: (optional) Id of widgets, referenced from resize object, below. // changedRegionId: // If specified, the slider for the region with the specified id has been dragged, and thus // the region's height or width should be adjusted according to changedRegionSize // changedRegionSize: // See changedRegionId. // copy dim because we are going to modify it dim = dojo.mixin({}, dim); cls.add(container, "dijitLayoutContainer"); // Move "client" elements to the end of the array for layout. a11y dictates that the author // needs to be able to put them in the document in tab-order, but this algorithm requires that // client be last. TODO: move these lines to LayoutContainer? Unneeded other places I think. children = array.filter(children, function(item){ return item.region != "center" && item.layoutAlign != "client"; }) .concat(array.filter(children, function(item){ return item.region == "center" || item.layoutAlign == "client"; })); // set positions/sizes array.forEach(children, function(child){ var elm = child.domNode, pos = (child.region || child.layoutAlign); // set elem to upper left corner of unused space; may move it later var elmStyle = elm.style; elmStyle.left = dim.l+"px"; elmStyle.top = dim.t+"px"; elmStyle.position = "absolute"; cls.add(elm, "dijitAlign" + capitalize(pos)); // Size adjustments to make to this child widget var sizeSetting = {}; // Check for optional size adjustment due to splitter drag (height adjustment for top/bottom align // panes and width adjustment for left/right align panes. if(changedRegionId && changedRegionId == child.id){ sizeSetting[child.region == "top" || child.region == "bottom" ? "h" : "w"] = changedRegionSize; } // set size && adjust record of remaining space. // note that setting the width of a