Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

fixed layout problems of stack view by creating dynamic layouts.

  • Loading branch information...
commit c1cb0585aff9198f7da012887b19bb80e8bf6cec 1 parent 7507172
@jantuitman authored
View
25 lib/scripts/arrays.js
@@ -0,0 +1,25 @@
+App5.module('arrays',function (globals) {
+
+ var arrays=globals;
+
+ arrays.indexOf=function (arr,el) {
+ for (var i=0;i<arr.length;i++) {
+ if (arr[i]===el) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ arrays.remove=function (arr,el) {
+ var i=arrays.indexOf(arr,el);
+ if (i > -1 ) {
+ return arr.splice(i,1);
+ }
+ else {
+ return arr;
+ }
+ }
+
+
+});
View
37 lib/scripts/bus.js
@@ -1,8 +1,11 @@
-App5.module('bus',function (globals) {
+App5
+.require('arrays')
+.module('bus',function (globals) {
+ var arrays=App5.modules.arrays;
- var handlers={};
- var elements={};
+ var handlers={}; //array of handler functions per channel.
+ var elements={}; // array of {handler:,channel:} per element.
var count=0;
$(document).bind('DOMNodeRemoved',function (e) {
@@ -10,27 +13,11 @@ App5.module('bus',function (globals) {
var a=elements[e.target.id];
if (a!=null) {
for (var i=0;i<a.length;i++) {
-
-
if (handlers[a[i].channel]) {
- var arr=handlers[a[i].channel];
- for (var j=0;j<arr.length;j++) {
- if (arr[j]==a[i].handler) {
- count--;
- console.log(" DECREASING,"+e.target.id+" number of listeners = "+count);
- arr.splice(j,1);
- }
- }
+ arrays.remove(handlers[a[i].channel],a[i].handler);
}
}
- /*
- for (var i=0;i<a.length;i++) {
- count--;
- console.log(" DECREASING,"+e.target.id+" number of listeners = "+count);
- delete handlers[a[i]];
- }
- */
delete elements[e.target.id];
}
}
@@ -48,7 +35,7 @@ App5.module('bus',function (globals) {
}
}
- // deprecated. refactoring needed.
+ // deprecated. refactoring needed. use listen2 instead.
globals.listen=function(channel,handler) {
count++;
console.log(channel+" number of listeners = "+count);
@@ -68,6 +55,14 @@ App5.module('bus',function (globals) {
elements[id].push({ handler: handler, channel : channel });
}
+ globals.removeListener=function(channel,handler) {
+ arrays.remove(handlers[channel],handler);
+ // TODO: also remove handler from the elements structure? the elements structure
+ // currently is only used for garbage collection so it does not seem to be to wrong
+ // to skip it.
+
+ }
+
// deprecated. refactoring needed.
View
77 lib/scripts/layout.js
@@ -44,7 +44,10 @@ App5
function Layout(el,provider,dir) {
this.target=el;
this.provider=provider;
+ this.providingEvent='';
this.dir=dir;
+ this.eventName=null; // dynamic layout will set this to the event that triggers the layout.
+ this.func=null; // dynamic layout will set this to a listener function that will have to be cleaned up when the layout is destroyed.
if (this.target.get(0).style.width != "") {
this.width=parseInt(this.target.get(0).style.width,10)
}
@@ -55,7 +58,7 @@ App5
else this.height=null;
}
- Layout.prototype.resize=function( ) {
+ Layout.prototype.resize=function(sizer ) {
var self=this;
var totalNeeded=0;
var totalAvailable=0;
@@ -92,12 +95,21 @@ App5
this.target.css("height",h+"px")
}
*/
-
- if (this.provider=='nested') {
- w=this.target.width();
- h=this.target.height();
+ console.log("doing layout of "+this.target.attr('id')+" provider = "+this.provider);
+ if (this.provider=='nested' || this.provider=='dynamic') {
+ // nested layouts: the width/height needs to be set by the parent.
+ // dynamic layouts: the width/height needs to be returned by the sizer function.
+ if (sizer) {
+ var obj=sizer();
+ w=obj.width();
+ h=obj.height();
+ }
+ else {
+ w=this.target.width();
+ h=this.target.height();
+ }
}
- else {
+ else if (this.provider=='window') {
if (this.width !=null) {
w=this.width;
}
@@ -113,8 +125,11 @@ App5
h=$(window).height();
this.target.css("height",h+"px")
}
-
}
+ else {
+ throw new Error("unknown layout providing option '"+provider+"'");
+ }
+
if (this.dir=="custom") {
// fire custom event on this node.
if (this.target.attr('id') !=null) bus.publish('app5.layout.resize.'+this.target.attr('id'),{});
@@ -292,6 +307,7 @@ App5
}
+ /** creates a layout that depends on the window **/
globals.create=function(el,options) {
var defaults={ dir : 'vertical', provider: 'window'}
var opts=$.extend(defaults,options);
@@ -299,12 +315,53 @@ App5
window.setTimeout(function () { layout.resize()},1);
}
- globals.nested=function(el,width,height) {
+ /** creates a layout that depends on a parentElement
+ this layout will never be triggered directly by an event.
+ However, if the parentElement is a layout itself, it will layout its child
+ containers.
+ */
+ globals.nested=function(el) {
var layout=createLayout(el,'nested',el.attr('data-layout-container'));
- el.css({ 'width' : width, 'height' : height });
+ //el.css({ 'width' : width, 'height' : height });
window.setTimeout(function () { layout.resize()},1);
}
-
+
+ /**
+ creates a layout that listens to another element.
+ parameters:
+ parentElement : the element that is used
+ el - the element on which to create the layout.
+ sizer (OPTIONAL) - a function that is called by the layout whenever a resize is triggered.
+ the sizer function must return an object that has width and height methods.
+ if sizer is not specified it will return the parentElement.
+ */
+ globals.dynamic=function(parentElement,el,sizer) {
+ if (sizer==null) sizer=function () {
+ //alert("In sizer : parentelement ("+parentElement.attr('id')+") currently has height "+parentElement.height());
+ return parentElement;
+ }
+ var layout=createLayout(el,'dynamic',el.attr('data-layout-container'));
+ layout.eventName='app5.layout.resize.'+parentElement.attr('id');
+ layout.func=function() {
+ layout.resize(sizer);
+ }
+ bus.listen2(layout.eventName,parentElement,layout.func);
+ layout.resize(sizer);
+ }
+
+ globals.destroy=function(element) {
+ var layout = layouts[element.attr('id')];
+ if (layout==null) {
+ console.log('WARNING: found no layout for '+element.attr('id'));
+ return;
+ }
+ if (layout.provider=='dynamic') {
+ bus.removeListener(layout.eventName,layout.func);
+ }
+ delete layouts[element.attr('id')];
+
+ }
+
return globals;
View
21 lib/scripts/stackview.js
@@ -14,7 +14,7 @@ App5
function StackView(el,options) {
this.el=el.css({"overflow": "hidden"});
- this.scrollerId=+el.attr('id')+'_scroller';
+ this.scrollerId=el.attr('id')+'_scroller';
this.scroller=$('<div id="'+this.scrollerId+'"/>'); //scroller div.
this.el.append(this.scroller);
this.scroller.css({"position":"absolute", width: this.el.width()+'px', height: this.el.height()+'px' });
@@ -139,7 +139,7 @@ App5
that.position.push(that.xPos);
if (view.attr('data-layout-container') != null) {
view.css({"position" : "absolute", "left" : that.xPos +"px"});
- layout.nested(view,that.el.width(),that.el.height())
+ layout.dynamic(this.el,view)
}
else {
view.css({"position" : "absolute", "left" : that.xPos +"px", width: that.el.width(), height: that.el.height() });
@@ -164,6 +164,7 @@ App5
var pr=_scrollTo(that,pos);
if (that.views.length > 0) {
var vw=that.views.pop();
+ layout.destroy(vw);
vw.remove();
that.position.pop();
}
@@ -181,6 +182,11 @@ App5
*/
StackView.prototype.replaceView=function(view,direction) {
console.log("direction "+direction);
+ var self=this;
+ for (var i=0;i<this.views.length;i++) {
+ console.log("destroying layout of "+this.views[i].attr('id'));
+ layout.destroy(this.views[i]);
+ }
if ((direction=="forward" || direction =="back") && this.views.length > 0) {
var x=0;
@@ -191,8 +197,9 @@ App5
x=this.xPosLeft-this.el.width();
}
if (view.attr('data-layout-container') != null) {
- view.css({"position" : "absolute", "left" : x +"px"});
- layout.nested(view,this.el.width(),this.el.height())
+ //view.css({"position" : "absolute", "left" : x +"px"});
+ view.css({"position" : "absolute", "left" : x +"px", width: this.el.width(), height: this.el.height() });
+ layout.dynamic(this.el,view)
}
else {
view.css({"position" : "absolute", "left" : x +"px", width: this.el.width(), height: this.el.height() });
@@ -219,8 +226,10 @@ App5
this.xPosLeft=0;
this.xPos=this.el.width();
if (view.attr('data-layout-container') != null) {
- view.css({"position" : "absolute", "left" : "0px"});
- layout.nested(view,x,this.el.height())
+ //view.css({"position" : "absolute", "left" : "0px"});
+ console.log(" replacing a view while my ("+this.el.attr('id')+") own width = "+this.el.width());
+ view.css({"position" : "absolute", "left" : x +"px", width: this.el.width(), height: this.el.height() });
+ layout.dynamic(this.el,view)
}
else {
view.css({"position" : "absolute", "left" : "0px", width: x, height: this.el.height() });
Please sign in to comment.
Something went wrong with that request. Please try again.