- It is not entirely true to say "an element is responsible for its bounds" since ROElement>>bounds immediately calls ROShape>>extentFor: Shapes seem to actually end up responsible for an element's bounds.
Well... Before I started to experiment with the translation shape, the class ROElement had a variable bounds. And there were no ROShape>>extentFor: I left it as it does no harm so far (but it may when we will consider performances)
- "Shapes are closely dependent from each other" is not necessarily true. I know some of my examples created a high dependency between "shapes relative to other shapes" but I think that was due to a poor approach. I think a conceptual distinction could be made between Elements that require layouts to arrange their position "relative to other Elements", and Shapes which arrange their position only "relative to the owning Element."
consider: el := ROElement new + ROBox + ROBorder. el extent: 20 @ 20.
Currently, each shape knows its next shape since they form a chain. el delegates the extension by 20@20 to its shape, itself delegating to its next shape and so on. They are closely interacting.
- Saying "Element is the only entity subject to layout" is a bit like saying "Element is the only entity subject to translation." However that is not entirely true. ROAbstractChildrenShape>>drawChildrenOn:for: makes use of translation. In a way I can't quite define, this ChildrenShape architecture makes me uncomfortable. Perhaps it may have something to do with Layout directly affecting the size of a Shape, namely the ROChildrenShape. It is the dynamic size of this component against labels need to aligned top/bottom/left/right/center/etc which creates the "close dependency" between shapes. Perhaps also it is that all the other Shapes eventually call some primitive executed on aCanvas. Whereas the ChildrenShapes don't do any direct drawing themselves but translate the drawing of the other shapes based on the results of the layouts. Perhaps also it is similar to your indication that "ROElement is the only entity subject to looking up subnodes", where this clean concept is broken by ROAbstractChildrenShape>>subElementsAt:forElement: cycling through subnodes.
How about if ROChildrenShape was not a shape, and something else controled cycling through subnodes ?
It could be. I haven't investigating this option that closely.
- I want to create a ROLabelBelowChildren (similar to my ROCenteredLabel), but currently this is problematic since which bounds do I use? I think it would be very useful (and a clean design) to split the bounds concept into 'childLayoutBounds' and 'outerBounds'. Currently there is no 'childLayoutBounds' and hence (I think...) the 'outerBounds' is determined from the Layout only. However if I then start drawing myLabel at 'outerBounds y', how do I incorporate my label into the outerBounds of the element. I speculate that 'outerBounds := (outerBounds x) @ (outerBounds y + myLabel height)' will end up heading towards infinity due to accumulating from #contains at every mouse movement. What I propose is that outerBounds is determined from Layout plus Shapes.
Currently, if you want to know the encompassing bounds of the children, you need to put them all in a new roelement.
The execution might look something like... a. Innermost Leaf Elements determine their outerBounds from their shapes only. b. Parent Element applies Layout based on outerBounds of child elements, which sets the Parent's childLayoutBounds. c. Parent's Shapes are independent from any other shape, but may freely offset from childLayoutBounds . d. Parent's outerBounds is determined from the union of childLayoutBounds and Parent's Shapes.
You can give a try, but it is hard to keep the bound mechanism stays on its feet when playing with it.
Thanks for the discussion
Cheers, Alexandre