1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
|
FlowLayout {
var <bounds, <>margin, <>gap;
var <>left, <>top, <>maxHeight,<>maxRight;
*new { arg bounds, margin, gap;
^super.newCopyArgs(bounds, margin, gap).init
}
init {
gap = gap ? Point(4,4);
margin = margin ? Point(4,4);
this.reset;
}
reset {
maxRight = left = bounds.left + margin.x;
top = bounds.top + margin.y;
maxHeight = 0;
}
place { arg view;
var height, width,vbounds;
vbounds = view.bounds;
width = vbounds.width;
height = vbounds.height;
if ((left + width) > (bounds.right - margin.x), { this.nextLine; });
view.bounds = Rect(left, top, width, height);
maxRight = max(maxRight,left + width);
left = left + width + gap.x;
maxHeight = max(maxHeight, height);
}
nextLine {
left = bounds.left + margin.x;
top = top + maxHeight + gap.y;
maxHeight = 0;
}
shift { arg x=0, y=0;
left = left + x;
top = top + y;
}
innerBounds {
^bounds.insetBy(margin.x * 2,margin.y * 2)
}
bounds_ { arg b;
var d;
left = left + ( d = (b.left - bounds.left));
maxRight = maxRight + (d);
top = top + (d = (b.top - bounds.top));
maxHeight = maxHeight + (d);
bounds = b;
// and then you need to re-place all views
// but nextLine will be broken, see FlowView
}
currentBounds {
var currentBounds;
currentBounds = bounds;
currentBounds.height = top + maxHeight;
^currentBounds
}
// rounded out to the nearest rect + margin
used {
^Rect(bounds.left,bounds.top,
maxRight + margin.x - bounds.left,
(top + maxHeight + margin.y ) - bounds.top)
}
// largest allocatable rect starting in the current row
// going down as far as possible
indentedRemaining {
var inb;
inb = this.innerBounds;
^Rect(left,top,
inb.width - (left - inb.left - margin.x),
inb.height - (top - inb.top - margin.y))
}
}
|