Status: New
Owner: ---- Labels: Type-Defect Priority-Medium New issue 842 by [hidden email]: ROTranslatingShape mouse hotspot mis-alignment http://code.google.com/p/moose-technology/issues/detail?id=842 Fix attached related to the following mail-posts Also attached are before and after snapshots from ROExample>>nestingTranslate. Ben Coman wrote: > I was trying to apply ROTranslatingShape to produce a label sitting above > the > children nodes. To understand it better how to get what I > need, I made ROExample>>nestingTranslate to show a permutation of the > order > the shapes can be applied. I have attached a screen snapshot and fileout > for > this. The case I am particularly interested in is el3. > The 'el0' case is the reference without any ROTranslatingShape. > When running the example hover near and over the inner elements to view > the > misalignment of the mouse hotspot. I have marked the approximate offset in > green in the snapshot. > I notice that the existing call chain goes... > ROView>>localElementAt: > ROElement>>elementAt: > ROElement>>contains: > ROElemenet>>bounds > ROShape>>extentFor: (union of extent of each shape) > It seems to me the hotspot misalignment is related to the translation > being > applied at the shape draw level whereas the #contains: checking is done > at the > element level. This relies on the union of the shape extents to set the > element bounds, but I can't see how that extent union could be modified to > account for the translation - particular in the case of a negative > translation > since extents throw away information > about any negative offset. > So I thought perhaps that the element #contains: checking needs might be > better chained through the shaped, so that the translation > could be applied similar to ROTranslatingShape>>chainedDrawOn:for: and > that > this would not cause any/much additional computation since all the shapes > were > being cycled through anyway for #extentFor: > Something like... > ROView>>localElementAt: > ROElement>>elementAt: > ROElement>>contains: > ROShape>>chainedContains:For: (for each shape) You can see in all case el1 to el8, the child elements have shifted in relation to el0. However the hotspot remains aligned with the location in el0. I think part of the problem is that ROChildrenShape is a ROAbstractEndingShape and is always at the end of the line - so the translation is applied to the children elements. Whereas it might work better if the position of the child elements was not affected by ROTranslatingShape, such that it becomes the reference for the position of any other translated shapes. This would require ROChildrenShape be always the first shape of an element, rather than always be the last shape. -------------------- The following code snippet... el := ROElement on: 1. (el + ROBorder + ROTranslatingShape + ROLabel ) inspect. produces shapes chained in order of: ROLabel-->ROTranslatingShape-->ROBorder-->ROChildrenShape. which seems reversed from what I would intuitively expect reading the code left to right. I think ideally the shape chain would be: ROChildrenShape-->ROBorder-->ROTranslatingShape-->ROLabel-->RONullShape Otherwise as in el1 you can see the position of the label is the same as el0, since the label has actually been drawn first prior to the translation, and instead the translation is applied to the border and child elements, the latter of which affects the mouse hotspot. Attachments: Roassal-BenComan.310.mcz 242 KB ROTranslatingShape-permutations-mouse-hotspot-broken.png 33.2 KB ROTranslatingShape-permutations-mouse-hotspot-fixed.png 29.8 KB _______________________________________________ Moose-dev mailing list [hidden email] https://www.iam.unibe.ch/mailman/listinfo/moose-dev |
Comment #1 on issue 842 by [hidden email]: ROTranslatingShape mouse hotspot mis-alignment http://code.google.com/p/moose-technology/issues/detail?id=842 Note however that while the mouse hotspot is fixed for the most inner nodes, hovering exactly over the "el1" text does not highlight this text and its element. I think it should, and that there is value in further consideration of ROShape>>chainedContains:For:. As another example of where the chained shape contains might be considered a benefit is the following script... | rawView view el | rawView := ROView new. el := ROElement new + ROBorder + (ROTranslatingShape new offset: 20 @ 20) + ROBox . el extent: 50 @ 50. el @ RODraggable @ ROLightlyHighlightable. rawView add: el. rawView open Referring to attached image, currently the hotspot is only the bordered square and not the filled in square. I think ideally the hotspot should extend to the filled square, but not the areas that I have marked with the red circles. Attachments: ROTranslatingShape-chained-shape-contains-example.png 1.1 KB _______________________________________________ Moose-dev mailing list [hidden email] https://www.iam.unibe.ch/mailman/listinfo/moose-dev |
Comment #2 on issue 842 by [hidden email]: ROTranslatingShape mouse hotspot mis-alignment http://code.google.com/p/moose-technology/issues/detail?id=842 Partial fix to extend the mouse hotspot to include translated shapes with new ROShape>>chainedContains:for: and friends. Check against script in Comment-1 and ROExample>>nestingTranslate. Need to review hovering just above the bottom border of el7 & el8 from ROExample>>nestingTranslate. Note there are several debugging Transcript outputs scattered through until this is resolved. (Actually if anyone was interested this provides an interesting display of how the Roassal internals work. Attachments: Roassal-BenComan.311.mcz 243 KB _______________________________________________ Moose-dev mailing list [hidden email] https://www.iam.unibe.ch/mailman/listinfo/moose-dev |
Comment #3 on issue 842 by [hidden email]: ROTranslatingShape mouse hotspot mis-alignment http://code.google.com/p/moose-technology/issues/detail?id=842 Just a couple peripheral things... 1. I notice when ROExample>>nestingTranslate is run by executing the script in its comment, for half-a-second elements el2 & el3 are slightly below el0, then they shift up to be in line with el0. 2. ROExample>>nestingTranslate shows that the offset shapes affect the growing of the parent element - which is really good. However if ROHorizontalLineLayout is changed to ROVerticalLineLayout, then it can be seen (for example with el1) that the offset shape (the label) is not included in the default spacing between elements. It would be really good if that can be done. Attachments: ROTranslatingShape-include-offset-shapes-in-spacing.png 5.4 KB _______________________________________________ Moose-dev mailing list [hidden email] https://www.iam.unibe.ch/mailman/listinfo/moose-dev |
[hidden email] wrote:
> > Comment #3 on issue 842 by [hidden email]: > ROTranslatingShape mouse hotspot mis-alignment > http://code.google.com/p/moose-technology/issues/detail?id=842 > > 2. ROExample>>nestingTranslate shows that the offset shapes affect the > growing of the parent element - which is really good. However if > ROHorizontalLineLayout is changed to ROVerticalLineLayout, then it can > be seen (for example with el1) that the offset shape (the label) is > not included in the default spacing between elements. It would be > really good if that can be done. > in case its of passing interest to anyone. However there is a good chance it is not completely accurate as I've had to move on since I found a temporary workaround just using a large gapSize between elements. <map version="0.9.0"> <!-- To view this file, download free mind mapping software FreeMind from http://freemind.sourceforge.net --> <node CREATED="1348365687124" ID="ID_407590633" MODIFIED="1348372494606" TEXT="Roassal
extents/bounds
static call graph"> <node CREATED="1348366239576" HGAP="28" ID="ID_583540211" MODIFIED="1348373009603" POSITION="right" TEXT="bounds" VSHIFT="-4"> <node CREATED="1348366291599" ID="ID_882109640" MODIFIED="1348373031155" TEXT="ROElement"> <arrowlink COLOR="#b300b0" DESTINATION="ID_65066810" ENDARROW="Default" ENDINCLINATION="481;20;" ID="Arrow_ID_1611521777" STARTARROW="None" STARTINCLINATION="504;0;"/> </node> </node> <node CREATED="1348365779855" ID="ID_424671415" MODIFIED="1348365859012" POSITION="right" TEXT="extent"> <node CREATED="1348365847232" ID="ID_1357288660" MODIFIED="1348373033231" TEXT="ROElement"> <arrowlink COLOR="#b300b0" DESTINATION="ID_65066810" ENDARROW="Default" ENDINCLINATION="412;0;" ID="Arrow_ID_1286865312" STARTARROW="None" STARTINCLINATION="392;0;"/> </node> </node> <node CREATED="1348367375179" ID="ID_533611708" MODIFIED="1348367463738" POSITION="right" TEXT="translateTo:"> <node CREATED="1348367395794" ID="ID_555466309" MODIFIED="1348368890904" TEXT="ROElement"/> </node> <node CREATED="1348366314187" ID="ID_1786421884" MODIFIED="1348367373542" POSITION="right" TEXT="setBounds:"> <node CREATED="1348366318469" ID="ID_1091050866" MODIFIED="1348373035904" TEXT="ROElement"> <arrowlink COLOR="#00b094" DESTINATION="ID_262527572" ENDARROW="Default" ENDINCLINATION="148;0;" ID="Arrow_ID_1310025220" STARTARROW="None" STARTINCLINATION="154;0;"/> </node> </node> <node CREATED="1348365860050" HGAP="19" ID="ID_1062407177" MODIFIED="1348368088049" POSITION="right" TEXT="extent:" VSHIFT="-6"> <node CREATED="1348365883284" ID="ID_1932766994" MODIFIED="1348372706148" TEXT="ROElement"> <arrowlink COLOR="#00b094" DESTINATION="ID_262527572" ENDARROW="Default" ENDINCLINATION="105;-23;" ID="Arrow_ID_582212272" STARTARROW="None" STARTINCLINATION="47;0;"/> </node> <node CREATED="1348365888745" HGAP="25" ID="ID_262527572" MODIFIED="1348373035905" TEXT="ROShape" VSHIFT="6"> <arrowlink COLOR="#1e35d6" DESTINATION="ID_1354410348" ENDARROW="Default" ENDINCLINATION="-88;-72;" ID="Arrow_ID_1078021106" STARTARROW="None" STARTINCLINATION="-101;-32;"/> <node CREATED="1348370798004" HGAP="17" ID="ID_62780719" MODIFIED="1348372967466" TEXT="next" VSHIFT="21"> <arrowlink COLOR="#00137a" DESTINATION="ID_262527572" ENDARROW="Default" ENDINCLINATION="-13;8;" ID="Arrow_ID_874688211" STARTARROW="None" STARTINCLINATION="-159;14;"/> </node> </node> <node CREATED="1348365873653" ID="ID_428517367" MODIFIED="1348373045333" TEXT="ROAbstractEndingShape" VSHIFT="10"> <arrowlink COLOR="#0016b3" DESTINATION="ID_1354410348" ENDARROW="Default" ENDINCLINATION="-89;-33;" ID="Arrow_ID_1116992237" STARTARROW="None" STARTINCLINATION="-150;-42;"/> </node> </node> <node CREATED="1348365901209" ID="ID_147440305" MODIFIED="1348376042743" POSITION="right" TEXT="extentFor:"> <node CREATED="1348365907453" ID="ID_1286191049" MODIFIED="1348370284462" TEXT="ROAbstractEndingShape"> <arrowlink COLOR="#0f13b4" DESTINATION="ID_169013934" ENDARROW="Default" ENDINCLINATION="52;27;" ID="Arrow_ID_1102826168" STARTARROW="None" STARTINCLINATION="-224;28;"/> </node> <node CREATED="1348365922886" ID="ID_1015368496" MODIFIED="1348372624406" TEXT="ROAbstractLabel"> <arrowlink COLOR="#b300b0" DESTINATION="ID_65066810" ENDARROW="Default" ENDINCLINATION="79;0;" ID="Arrow_ID_69660225" STARTARROW="None" STARTINCLINATION="28;2;"/> <arrowlink COLOR="#008e11" DESTINATION="ID_467886359" ENDARROW="Default" ENDINCLINATION="134;0;" ID="Arrow_ID_186543847" STARTARROW="None" STARTINCLINATION="134;0;"/> </node> <node CREATED="1348365927290" ID="ID_65066810" MODIFIED="1348373033231" TEXT="ROShape"> <arrowlink COLOR="#1115be" DESTINATION="ID_169013934" ENDARROW="Default" ENDINCLINATION="398;86;" ID="Arrow_ID_1043809133" STARTARROW="None" STARTINCLINATION="-43;-2;"/> <node CREATED="1348366759312" HGAP="16" ID="ID_782408842" MODIFIED="1348370741380" TEXT="next" VSHIFT="20"> <arrowlink COLOR="#010590" DESTINATION="ID_65066810" ENDARROW="Default" ENDINCLINATION="-163;48;" ID="Arrow_ID_1226861375" STARTARROW="None" STARTINCLINATION="-141;6;"/> </node> </node> </node> <node CREATED="1348365932263" ID="ID_1980675748" MODIFIED="1348365940263" POSITION="right" TEXT="preferedExtentFor:"> <node CREATED="1348365941623" ID="ID_467886359" MODIFIED="1348370284892" TEXT="ROAbstractLabel"> <node CREATED="1348369249243" HGAP="236" ID="ID_898719256" MODIFIED="1348369745702" TEXT="height & width of string" VSHIFT="2"/> </node> <node CREATED="1348365949407" ID="ID_1641510169" MODIFIED="1348372570176" TEXT="ROShape"> <arrowlink COLOR="#b300b1" DESTINATION="ID_65066810" ENDARROW="Default" ENDINCLINATION="-14;9;" ID="Arrow_ID_860153035" STARTARROW="None" STARTINCLINATION="-86;-42;"/> </node> </node> <node CREATED="1348367464933" ID="ID_21077192" MODIFIED="1348368389358" POSITION="right" TEXT="chainedContains:for:"> <node CREATED="1348367476150" ID="ID_1112336940" MODIFIED="1348372754298" TEXT="ROShape"> <arrowlink COLOR="#b300b0" DESTINATION="ID_65066810" ENDARROW="Default" ENDINCLINATION="98;26;" ID="Arrow_ID_403699234" STARTARROW="None" STARTINCLINATION="286;-52;"/> <node CREATED="1348368522563" HGAP="13" ID="ID_1060078483" MODIFIED="1348369908430" TEXT="next" VSHIFT="22"> <arrowlink COLOR="#fc0f0f" DESTINATION="ID_1112336940" ENDARROW="Default" ENDINCLINATION="-28;18;" ID="Arrow_ID_1413146288" STARTARROW="None" STARTINCLINATION="-63;6;"/> </node> </node> <node CREATED="1348368334652" ID="ID_482176285" MODIFIED="1348368338475" TEXT="ROTranslatingShape"> <node CREATED="1348368360490" HGAP="202" ID="ID_1253146022" MODIFIED="1348369897284" TEXT="offset aPoint" VSHIFT="2"> <arrowlink COLOR="#f60f0f" DESTINATION="ID_1112336940" ENDARROW="Default" ENDINCLINATION="168;0;" ID="Arrow_ID_1145449197" STARTARROW="None" STARTINCLINATION="168;0;"/> </node> </node> <node CREATED="1348368328303" ID="ID_492410149" MODIFIED="1348368334245" TEXT="ROAbstractEndingShape"> <node CREATED="1348368346101" HGAP="182" ID="ID_88863356" MODIFIED="1348369705120" TEXT="returns false" VSHIFT="3"/> </node> </node> <node CREATED="1348368390326" ID="ID_1998669586" MODIFIED="1348368395333" POSITION="right" TEXT="contains:"> <node CREATED="1348368402218" ID="ID_1974251001" MODIFIED="1348369887775" TEXT="ROElement"> <arrowlink COLOR="#e9293f" DESTINATION="ID_1112336940" ENDARROW="Default" ENDINCLINATION="286;51;" ID="Arrow_ID_1056306972" STARTARROW="None" STARTINCLINATION="229;0;"/> </node> </node> <node CREATED="1348368717636" HGAP="28" ID="ID_1354410348" MODIFIED="1348373045333" POSITION="left" TEXT="set ivar extent" VSHIFT="-51"/> <node CREATED="1348369316540" HGAP="26" ID="ID_169013934" MODIFIED="1348372790656" POSITION="left" TEXT="return ivar extent" VSHIFT="54"/> <node CREATED="1348369994029" HGAP="31" ID="ID_459879344" MODIFIED="1348372795257" POSITION="left" TEXT="installedOn:" VSHIFT="140"> <node CREATED="1348369999331" HGAP="16" ID="ID_1106860186" MODIFIED="1348370500751" TEXT="ROShape" VSHIFT="-15"> <arrowlink COLOR="#087e00" DESTINATION="ID_1641510169" ENDARROW="Default" ENDINCLINATION="-58;7;" ID="Arrow_ID_1796050968" STARTARROW="None" STARTINCLINATION="-120;-23;"/> </node> </node> </node> </map> _______________________________________________ Moose-dev mailing list [hidden email] https://www.iam.unibe.ch/mailman/listinfo/moose-dev Roassal extent static call graph.pdf (127K) Download Attachment |
In reply to this post by moose-technology
Comment #4 on issue 842 by [hidden email]: ROTranslatingShape mouse hotspot mis-alignment http://code.google.com/p/moose-technology/issues/detail?id=842 Perhaps needing more consideration, previously the children were always drawn last and ended up on top of any shapes, whereas now they get drawn first and _might_ be overwritten by a later shape of the parent. Perhaps we need to be able to arrange the ROChildrenShape into the middle of the shape-chain. Or perhaps drawing children is special and done differently to the rest of the shapes, so that it is always drawn last but not affected by ROTranslateShape. Perhaps something roughly like.... ROAbstractElement>>drawOn: aCanvas shape chainedDrawOn: aCanvas for: self ROChildrenShape new drawOn: aCanvas for: self. _______________________________________________ Moose-dev mailing list [hidden email] https://www.iam.unibe.ch/mailman/listinfo/moose-dev |
Comment #5 on issue 842 by [hidden email]: ROTranslatingShape mouse hotspot mis-alignment http://code.google.com/p/moose-technology/issues/detail?id=842 > Perhaps we need to be able to arrange the ROChildrenShape into the middle > of the shape-chain. Following on from this, thought I would float the idea of considering ROChildrenShape as reference layer 0, then the current "plus sign" could be considered to be adding shapes layered above ROChildrenShape, while the a "minus sign" might be used to add shapes layered below ROChildrenShape (or the opposite orientation). So then you might have a script like... Here is a simple script to check the effect of changing where in the chain that ROChildrenShape is drawn. ------------------ | rawView outer | rawView := ROView new. outer := (ROElement spriteOn: 'outer') - (ROCircle new color: (Color lightGreen alpha: 0.95)) + ROTranslateShape + ROLabel. 1 to: 4 do: [ :n| outer add: (ROElement spriteOn: n)]. ROGridLayout on: outer elements. rawView add: outer. rawView open. ----------------- btw, what are the issues with each shape having its own offset initialized to 0@0, or using bounds rather than extent? _______________________________________________ Moose-dev mailing list [hidden email] https://www.iam.unibe.ch/mailman/listinfo/moose-dev |
Comment #6 on issue 842 by [hidden email]: ROTranslatingShape mouse hotspot mis-alignment http://code.google.com/p/moose-technology/issues/detail?id=842 > Perhaps we need to be able to arrange the ROChildrenShape into the middle > of the shape-chain. Following on from this, thought I would float the idea of considering ROChildrenShape as reference layer 0, then the current "plus sign" could be considered to be adding shapes layered above ROChildrenShape, while the a "minus sign" might be used to add shapes layered below ROChildrenShape (or the opposite orientation). So then you might have a script like... ------------------ | rawView outer | rawView := ROView new. outer := (ROElement spriteOn: 'outer') - (ROCircle new color: (Color lightGreen alpha: 0.95)) + ROTranslateShape + ROLabel. 1 to: 4 do: [ :n| outer add: (ROElement spriteOn: n)]. ROGridLayout on: outer elements. rawView add: outer. rawView open. ----------------- where the circle is drawn under the children elements, then the child elements are drawn, then the translation is applied to the label drawn on top. btw, what are the issues with each shape having its own offset initialized to 0@0, or using bounds rather than extent, where the origin could go negative? _______________________________________________ Moose-dev mailing list [hidden email] https://www.iam.unibe.ch/mailman/listinfo/moose-dev |
Comment #7 on issue 842 by [hidden email]: ROTranslatingShape mouse hotspot mis-alignment http://code.google.com/p/moose-technology/issues/detail?id=842 HOLD THE PRESS!!! After working through all of the above getting the label translation working at the shape level, I've come at it another way using translation at the element level instead. This gets me what I need to progress at the moment, allowing for some extended time to consider the above ideas - which are fairly major changes to the architecture but I think useful in other ways. Please review the attached mcz containing ROExample>>nestingTranslate2, and hopefully this is considered lower enough impact to push through quickly. Attachments: Roassal-BenComan.312.mcz 243 KB ROLayout#offsetBy.png 5.6 KB _______________________________________________ Moose-dev mailing list [hidden email] https://www.iam.unibe.ch/mailman/listinfo/moose-dev |
Comment #8 on issue 842 by [hidden email]: ROTranslatingShape mouse hotspot mis-alignment http://code.google.com/p/moose-technology/issues/detail?id=842 I started to work on this. This is a tough one. _______________________________________________ Moose-dev mailing list [hidden email] https://www.iam.unibe.ch/mailman/listinfo/moose-dev |
Comment #9 on issue 842 by [hidden email]: ROTranslatingShape mouse hotspot mis-alignment http://code.google.com/p/moose-technology/issues/detail?id=842 I know :). Thanks for the update. I've thrown a whole lot of ideas out there. Just a couple of minor new thoughts (not necessarily good ones) this morning... Depending on which way to go, if you are go the way of minus/plus... outer := (ROElement spriteOn: 'outer') - (ROCircle new color: (Color lightGreen alpha: 0.95)) + ROTranslateShape + ROLabel. then I was not completely clear what the intuitive result would be for multiple minuses chained together. Does a minus always push to the front? Or does it push immediately in front of ROChildren? Perhaps a more intuitive way would be to use only pluses with ROElement representing the position in the chain where the children are drawn... outer := (ROCircle new color: (Color lightGreen alpha: 0.95)) + (ROElement spriteOn: 'outer') + ROTranslateShape + ROLabel. _______________________________________________ Moose-dev mailing list [hidden email] https://www.iam.unibe.ch/mailman/listinfo/moose-dev |
Comment #10 on issue 842 by [hidden email]: ROTranslatingShape mouse hotspot mis-alignment http://code.google.com/p/moose-technology/issues/detail?id=842 btw, on review of above it looks like I didn't mention some of my musings about part of the problem being the use of extents throwing away information about negative position of shapes. I thought perhaps an offset stored per shapes, perhaps considered as a "negative extent", or shapes using bounds rather than extents might be required to make it work. This consideration of "negative" translation of shapes may intertwined with "negative" translation of elements in http://code.google.com/p/moose-technology/issues/detail?id=831 _______________________________________________ Moose-dev mailing list [hidden email] https://www.iam.unibe.ch/mailman/listinfo/moose-dev |
Comment #11 on issue 842 by [hidden email]: ROTranslatingShape mouse hotspot mis-alignment http://code.google.com/p/moose-technology/issues/detail?id=842 A little bit to go. With the following example, the node cannot be dragged by the blue square. Also any part of the red square outside the black square cannot be used for dragging. -------------- | el inner view | el := ROElement on: 1. el + ROBorder blue + (ROTranslatingShape offset: 20 @ 20) + ROBorder. el extent: 100 @ 100. el @ RODraggable. el @ ROPopup. inner := ROElement on: 2. inner + ROBorder red. inner extent: 50 @ 50. inner @ RODraggable. inner @ ROPopup. el add: inner. view := ROView new. view add: el. view open --------------- Just another thought. I wonder if some of the difficulty arises from the shape being drawn by one code execution path, and then the #extents and #contains being calculated by another code execution path - and whether this could be consolidated into one place... since by the end of the #drawOn:for: method it should know the final position and extent that it has drawn of itself, it could be required to set a a new 'offset' and existing ;extents' ivars in ROShape using local co-ordinates. Then all the #extent and #contains need to do is consider those stored values rather than doing a different calculation which currently seems not quite aligned. Also I notice in ROElement>>elementAt: you write "that in local co-ordinates aPoint = 0@0 refers to the top left of the [element] bounds." I presume you mean element bounds. Now my thinking might be naive, but I can't help feeling that this definition will cause difficulties. Since a shape with negative offset will move the bounds, so will move 0@0 and so what is the meaning of the negative offset? My thought is that conceptually, the local co-ordinate 0@0 aligns with the "element position" where that is not necessarily "element bounds topLeft" ...or are the issues with doing that way that I don't see. _______________________________________________ Moose-dev mailing list [hidden email] https://www.iam.unibe.ch/mailman/listinfo/moose-dev |
Updates:
Labels: Component-Roassal Comment #12 on issue 842 by [hidden email]: ROTranslatingShape mouse hotspot mis-alignment http://code.google.com/p/moose-technology/issues/detail?id=842 I agree with what you said. The state is the following: more I work on the translation shape, slower roassal become to be (e.g., each elementAt: and contains: need to go through the shape chain in case there is a ROTranslationShape somewhere) and more complex it become. Now, I am wondering whether subclassing ROElement will not be an easier way to solve your problem. Maybe something like ROCompositeElement. Does this make sense? _______________________________________________ Moose-dev mailing list [hidden email] https://www.iam.unibe.ch/mailman/listinfo/moose-dev |
Comment #13 on issue 842 by [hidden email]: ROTranslatingShape mouse hotspot mis-alignment http://code.google.com/p/moose-technology/issues/detail?id=842 Alexandre, This turned into a bit an essay, but it brings together a number of ideas I've developed in response to trialling ROTranslateShape. I know Mondrian seemed to have had lots of caches which made the architecture convoluted, however it may be reasonable for a distinction to be made between caching shape data and caching element layout data. (Would I be correct in saying that Mondrian had a lot less concept of shapes?) Elements are greatly affected by nesting and layouts, particularly dynamic layouts - whereas shapes should be at the end of the line, with no sub elements, and within the element-local-coordinates should not change much. Indeed stretching the concept, for "element shapes" (as opposed to "edge shapes") perhaps the drawing can be split into something like a #calculateShape and a #drawShape - where the "convention" is that #calculateShape is only called on "model-changed" and stores ALL PARAMETERS required to draw the shape in instance variables, while #drawShape is called in a tight rendering loop and the "convention" is that it should use NO temporary variables, but only can use only the exact parameters previously stored by #calculateShape. Further, #calculateShape would statically fix the bounds of each shape until the next "model changed" and cache that value into an ROElement ivar perhaps called "localBounds" - so that #containsPoint on needs one check per Element until a hit is found. This would avoid having to process every shape every cycle, which I think is a major part of the slowdown. Only after a hit within an anElement bounds would the shape bounds be double-checked to avoid an invalid hit - like the part where two offset squares don't overlap. I think the concept of translating shapes is important, but I am actually not sure if I like ROTranslateShape. Apart from the performance aspect, having trialled ROTranslatingShape I think it introduces more complexity than necessary. It also is more awkward and constraining than I would like - for instance if I want to offset four circles N,E,W,S from center, then I need to contend with reversing the cumulation of chained ROTranslatingShapes, rather than just dealing with four absolute offsets from center. With ROTranslatingShape I need to consider how the chained cumulative offset interacts with imposed layering of which shapes get drawn on top. With the proviso that I haven't much experience in the trenches with graphics programming, I can't help feeling that it would be simpler for each and every element shape to have its own offset. Then I could more easily add offset shapes to an element in the order convenient to the shape layering. I speculate that using such an offset variable would not be much more CPU load than the only other alternative of defining a new shape class for every general combination of offset shapes. In addition, I've been musing over whether this 'offset' ivar might be a point or a block, or might contain a class something like NullOffset which always returns 0@0; or StaticOffset which always returns a value stored in an instance variable; or StaticOffsetFromBottomOfElement, DynamicOffset which executes a block.stored in an instance variable. DynamicOffset might somehow be tuned into I have also been musing on whether ChildrenShape should REALLY be the central consideration. Using labels as an example, all the cases I can think of for positioning a label, they are dependent of the size of the ChildrenShape - eg placed under the children shape relies on ChildShape>>height; and placed to the right of the element relies on the ChildrenShape>>width and possibly >>height for central vertically alignment. Following on from this, I think ChildrenShape should always be calculated first, even if it is drawn in a middle layer. ROElement would always hold ROChildrenShape as its first shape, while ROChildrenShape would have two 'next' ivars - one for those shapes above it and one for those shapes below it. The position ROChildrenShape would be "defined" to be _always_ at 0@0 and tied directly to whatever is thought of as the "element" position, with all other shapes offset against it, including in the negative direction for labels appearing above the ChildrenShape. However if shapes can have a negative offset, then in line with my ideas about caching only the sum of shape bounds in the element, I speculate that the cleanest implementation would be for ROElement>>localBounds to also allow a negative origin, so that it could be the simple union of its ROShape>>bounds. Some ideas end in dead-ends. A possible path forward is to first revert the changes associated with ROTranslateShape. Then depending on how you view the ideas I presented above, prior to adding any shape translation, get ROElement negative bounds and negative translation working as per Issue 831. Then work individual offsets for shapes, which I believe may be dependent on Issue 831. Anyway, that is just how it appears to me without knowing what other architectural constraints you are working with. phew! (and whoops, that is a lot for you to digest.) hope some of that is helpful. cheers -ben _______________________________________________ Moose-dev mailing list [hidden email] https://www.iam.unibe.ch/mailman/listinfo/moose-dev |
Updates:
Status: Fixed Comment #14 on issue 842 by [hidden email]: ROTranslatingShape mouse hotspot mis-alignment http://code.google.com/p/moose-technology/issues/detail?id=842 Hi! Thanks for your post. It was inspiring. I spent a lot of time on think about the implication about having a translating shape and an offset. Neither approach has convinced me so far. The reason is the following: shapes are closely dependent from each other, meaning that the element is the only entity subject to layout, looking up subnodes, and responsible for its bounds. This model is quite simple, easy to understand, easy to debug. Adding a concept of offset breaks this nice small model. As soon as you want shapes to be next to each other, you need a kind of layout, at least to say that shape1 is on the left-hand side of shape2. However, layouts work only on elements. I came to the conclusion to not have translation or offset for shape. The source code has been reverted to the equivalent of what it was a couple of weeks ago. This is not I am against this idea, however I could not find a clean and appealing way to implement it without redesigning the shapes hierarchy. Subclassing ROElement should easily solve your problem although. I consider this issue as fixed so far. _______________________________________________ Moose-dev mailing list [hidden email] https://www.iam.unibe.ch/mailman/listinfo/moose-dev |
[hidden email] wrote:
> Updates: > Status: Fixed > > Comment #14 on issue 842 by [hidden email]: ROTranslatingShape > mouse hotspot mis-alignment > http://code.google.com/p/moose-technology/issues/detail?id=842 > > Hi! > > Thanks for your post. It was inspiring. I spent a lot of time on think > about the implication about having a translating shape and an offset. > Neither approach has convinced me so far. > > The reason is the following: shapes are closely dependent from each > other, meaning that the element is the only entity subject to layout, > looking up subnodes, and responsible for its bounds. This model is > quite simple, easy to understand, easy to debug. Adding a concept of > offset breaks this nice small model. > As soon as you want shapes to be next to each other, you need a kind > of layout, at least to say that shape1 is on the left-hand side of > shape2. However, layouts work only on elements. > > I came to the conclusion to not have translation or offset for shape. > The source code has been reverted to the equivalent of what it was a > couple of weeks ago. > This is not I am against this idea, however I could not find a clean > and appealing way to implement it without redesigning the shapes > hierarchy. > Subclassing ROElement should easily solve your problem although. > > I consider this issue as fixed so far. > > _______________________________________________ > Moose-dev mailing list > [hidden email] > https://www.iam.unibe.ch/mailman/listinfo/moose-dev > into trying to make it work. The recent example by Vanessa & yourself mixing 'forward' interaction with a VerticalLineLayout will probably satisfy a lot of my current needs. However I just want to lead your thinking in a slight different direction. For the purpose of provoking thought, I take some extreme points of view.... 1. 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. 2. "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." 3. 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 ? 4. 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. 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. Just food for thought... cheers -ben _______________________________________________ Moose-dev mailing list [hidden email] https://www.iam.unibe.ch/mailman/listinfo/moose-dev |
In reply to this post by moose-technology
[hidden email] wrote:
> Updates: > Status: Fixed > > Comment #14 on issue 842 by [hidden email]: ROTranslatingShape > mouse hotspot mis-alignment > http://code.google.com/p/moose-technology/issues/detail?id=842 > > Hi! > > Thanks for your post. It was inspiring. I spent a lot of time on think > about the implication about having a translating shape and an offset. > Neither approach has convinced me so far. > > The reason is the following: shapes are closely dependent from each > other, meaning that the element is the only entity subject to layout, > looking up subnodes, and responsible for its bounds. This model is > quite simple, easy to understand, easy to debug. Adding a concept of > offset breaks this nice small model. > As soon as you want shapes to be next to each other, you need a kind > of layout, at least to say that shape1 is on the left-hand side of > shape2. However, layouts work only on elements. > > I came to the conclusion to not have translation or offset for shape. > The source code has been reverted to the equivalent of what it was a > couple of weeks ago. > This is not I am against this idea, however I could not find a clean > and appealing way to implement it without redesigning the shapes > hierarchy. > Subclassing ROElement should easily solve your problem although. > > I consider this issue as fixed so far. > > _______________________________________________ > Moose-dev mailing list > [hidden email] > https://www.iam.unibe.ch/mailman/listinfo/moose-dev > if this is a bug or just my understanding. One of the things I liked about using shapes to offset labels is that ROLightlyHighlightable highlighted both the element and the label when I hovered over either. Referring to example below, if I add ROLightlyHighlightable to 'inner' or 'innerLabel' then nothing at all happens when I hover over either. However if I add ROLightlyHighlightable to 'outer' - the blue square displays only around the outside of the 'outer' element, and no change to the 'inner' and 'innerLabel'. -------------------------------- | view outter inner innerLabel | view := ROView new. outter := ROElement new + ROBorder white. outter @ RODraggable @ ROLightlyHighlightable . inner := ROElement sprite . innerLabel := ROElement labelOn: 'My sprite'. outter add: inner; add: innerLabel. inner forward. innerLabel forward. "We layout the things" ROVerticalLineLayout on: outter elements. view add: outter. view open _______________________________________________ Moose-dev mailing list [hidden email] https://www.iam.unibe.ch/mailman/listinfo/moose-dev |
> Upon further consideration of doing this at the Element level, not sure if this is a bug or just my understanding. One of the things I liked about using shapes to offset labels is that ROLightlyHighlightable highlighted both the element and the label when I hovered over either. Referring to example below, if I add ROLightlyHighlightable to 'inner' or 'innerLabel' then nothing at all happens when I hover over either. However if I add ROLightlyHighlightable to 'outer' - the blue square displays only around the outside of the 'outer' element, and no change to the 'inner' and 'innerLabel'.
> -------------------------------- > | view outter inner innerLabel | > view := ROView new. > > outter := ROElement new + ROBorder white. > outter @ RODraggable @ ROLightlyHighlightable . > > inner := ROElement sprite . > innerLabel := ROElement labelOn: 'My sprite'. > outter add: inner; add: innerLabel. > > inner forward. > innerLabel forward. > > "We layout the things" > ROVerticalLineLayout on: outter elements. > > view add: outter. > view open You said: "add ROLightlyHighlightable to 'inner' or 'innerLabel' then nothing at all happens when I hover over either" => This is normal since inner and innerLabel forward all the events. If you want to have have the highlight on the children element while preserving the drag and dropping of the compound, then you have the following script: -=-=-=-=-=-=-=-=-=-=-=-=-=-=-= | view outter inner innerLabel | view := ROView new. outter := ROElement new + ROBorder white. outter @ RODraggable @ ROLightlyHighlightable . inner := ROElement sprite . innerLabel := ROElement labelOn: 'My sprite'. outter add: inner; add: innerLabel. inner forward: ROMouseDragging. innerLabel forward: ROMouseDragging. inner @ ROLightlyHighlightable. innerLabel @ ROLightlyHighlightable. "We layout the things" ROVerticalLineLayout on: outter elements. view add: outter. view open -=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Cheers, Alexandre -- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;. _______________________________________________ Moose-dev mailing list [hidden email] https://www.iam.unibe.ch/mailman/listinfo/moose-dev |
In reply to this post by Ben Coman
> 1. 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) > 2. "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. > 3. 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. > 4. 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 -- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;. _______________________________________________ Moose-dev mailing list [hidden email] https://www.iam.unibe.ch/mailman/listinfo/moose-dev |
Free forum by Nabble | Edit this page |