LeftRightArranger is terrible

edited January 2014 in General
A previous post mentioned LeftRightArranger as a starting point for learning custom arrangers. I would suggest someone create a working left right arranger instead, and point such a topic at that.

The code in question is
var i,c,b;
if (this.container.getPanels().length==1){
    b = {};
    b[this.axisPosition] = this.margin;
    this.arrangeControl(this.container.getPanels()[0], b);
    return;
}
var o = Math.floor(this.container.getPanels().length/2);
var c$ = this.getOrderedControls(Math.floor(inIndex)-o);
var box = this.containerBounds[this.axisSize] - this.margin -this.margin;
var e = this.margin - box * o;
for (i=0; (c=c$[i]); i++) {
    b = {};
    b[this.axisPosition] = e;
    this.arrangeControl(c, b);
    e += box;
}
If you can explain that, more power to you. If you can fix it such that it works for a 2 panel test case (no wrap) so that the 2nd panel comes in from the right instead of the left, even better. Best would be to fix it so when panel content is not a solid-fill you don't see the wrap panels zooming underneath the topmost panels (for any number of panels). Pretty simple test cases...

Comments

  • edited January 2014
    Terrible seems a bit harsh but it does seem to have a bug with 2 panels.

    Here's my explanation of the code. Ben & team can of course correct me.
    arrange: function(inC, inIndex) {
    	var i,c,b;
    
    	// special case for single panel, just position it and return
    	if (this.container.getPanels().length==1){
    		b = {};
    		b[this.axisPosition] = this.margin;
    		this.arrangeControl(this.container.getPanels()[0], b);
    		return;
    	}
    
    	// start laying out the panels. the goal is to evenly split the panels
    	// so that half are to the left of the selected panel and half are to
    	// the right.
    
    	// so 'o' is the mid-point
    	var o = Math.floor(this.container.getPanels().length/2);
    
    	// getOrderedControls returns the list of panels offset by
    	// the given index. in this case, we're reordering by the selected
    	// index but further offset by the midpoint. this shifts the first
    	// control rendered to be the furthest away if the array were to wrap.
    	// This ensures that there are panels on both sides of the selected
    	// panel (even though you may not be able to swipe it right if
    	// the selected index is 0).
    
    	// For example, if inIndex = 1 and there are 6 panels, c$ would look
    	// something like [4,5,0,1,2,3]
    	var c$ = this.getOrderedControls(Math.floor(inIndex)-o);
    
    	// calculate the size of a panel
    	var box = this.containerBounds[this.axisSize] - this.margin -this.margin;
    
    	// calculate the left position. In the above example, this is how '4'
    	// is pushed 3 'boxes' to the left.
    	var e = this.margin - box * o;
    	for (i=0; (c=c$[i]); i++) {
    		b = {};
    		b[this.axisPosition] = e;
    		this.arrangeControl(c, b);
    		e += box;
    	}
    }
    Here's a simpler version of LeftRightArranger that doesn't support wrapping but is a bit easier to understand.

    http://jsfiddle.net/ryanjduffy/NbLm2/2/

    p.s. @unwiredben seems to be a bug with Panels that the narrow class isn't removed when the Panels is resized. I patched that in the above example as well.
  • We'd gladly take the commented version as a pull request... better explaining parts of the core code is something we need desperately.
  • This is great, thanks! It's good being timezone(s) behind you so I'm greeted in the morning with the answer to the problem that was keeping me up... :)
Sign In or Register to comment.