ROTranslatingShape mouse hotspot mis-alignment

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

ROTranslatingShape mouse hotspot mis-alignment

Ben Coman

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)

cheers, Ben



'From Pharo1.4 of 18 April 2012 [Latest update: #14457] on 22 September 2012 at 9:41:20 pm'!

!ROExample methodsFor: 'nesting' stamp: 'BenComan 9/22/2012 17:04'!
nestingTranslate
"
self new nestingTranslate
"
       
| rawView outer el0 el1 el2 el3 el4  el5 el6 el7 el8 |
rawView := ROView new @ RODraggable.

el0 := (ROElement on:
'el0,  
border,
label') + ROBorder + ROLabel  @ RODraggable @ ROLightlyHighlightable.
el0 extent: 50@50.
1 to: 4 do: [ :n | el0 add: (ROElement spriteOn: n) @ ROLightlyHighlightable ].
ROGridLayout on: el0 elements .

el1 := (ROElement on:
'el1,
border,
positive translation,
label') + ROBorder + (ROTranslatingShape new offset: 0 @ 20) + ROLabel  @ RODraggable @ ROLightlyHighlightable.
el1 extent: 50@50.
1 to: 4 do: [ :n | el1 add: (ROElement spriteOn: n) @ ROLightlyHighlightable ].
ROGridLayout on: el1 elements .

el2 := (ROElement on:  
'el2,
border,
label,
positive translation') + ROBorder + ROLabel + (ROTranslatingShape new offset: 0 @ 20)  @ RODraggable @ ROLightlyHighlightable.  
el2 extent: 50@50.
1 to: 4 do: [ :n | el2 add: (ROElement spriteOn: n) @ ROLightlyHighlightable ].
ROGridLayout on: el2 elements .

el3 := (ROElement on:
'el3,
border,
negative translation,
label') + ROBorder + (ROTranslatingShape new offset: 0 @ 20 negated)  + ROLabel @ RODraggable @ ROLightlyHighlightable.  
el3 extent: 50@50.
1 to: 4 do: [ :n | el3 add: (ROElement spriteOn: n) @ ROLightlyHighlightable ].
ROGridLayout on: el3 elements .

el4 := (ROElement on:
'el4,
border,
label,
negative translation') + ROBorder + ROLabel + (ROTranslatingShape new offset: 0 @ 20 negated) @ RODraggable @ ROLightlyHighlightable.
el4 extent: 50@50.
1 to: 4 do: [ :n | el4 add: (ROElement spriteOn: n) @ ROLightlyHighlightable ].
ROGridLayout on: el4 elements .

el5 := (ROElement on:
'el5,
positive translation,
label,
border') + (ROTranslatingShape new offset: 0 @ 20) + ROLabel + ROBorder @ RODraggable @ ROLightlyHighlightable.
el5 extent: 50@50.
1 to: 4 do: [ :n | el5 add: (ROElement spriteOn: n) @ ROLightlyHighlightable ].
ROGridLayout on: el5 elements .  

el6 := (ROElement on:  
'el6,
label,
positive translation,
border,') + ROLabel + (ROTranslatingShape new offset: 0 @ 20) + ROBorder  @ RODraggable @ ROLightlyHighlightable.  
el6 extent: 50@50.
1 to: 4 do: [ :n | el6 add: (ROElement spriteOn: n) @ ROLightlyHighlightable ].
ROGridLayout on: el6 elements .

el7 := (ROElement on:
'el7,
negative translation,
label,
border') + (ROTranslatingShape new offset: 0 @ 20 negated)  + ROLabel + ROBorder @ RODraggable @ ROLightlyHighlightable.  
el7 extent: 50@50.
1 to: 4 do: [ :n | el7 add: (ROElement spriteOn: n) @ ROLightlyHighlightable ].
ROGridLayout on: el7 elements .

el8 := (ROElement on:
'el8,
label,
negative translation,
border') + ROLabel + (ROTranslatingShape new offset: 0 @ 20 negated) + ROBorder @ RODraggable @ ROLightlyHighlightable.
el8 extent: 50@50.
1 to: 4 do: [ :n | el8 add: (ROElement spriteOn: n) @ ROLightlyHighlightable ].
ROGridLayout on: el8 elements .



outer := (ROElement spriteOn: 'outer') addAll: { el0. el1. el2. el3. el4. el5. el6. el7. el8 }.
rawView add: outer.
ROHorizontalLineLayout on: outer elements.
rawView open ! !


_______________________________________________
Moose-dev mailing list
[hidden email]
https://www.iam.unibe.ch/mailman/listinfo/moose-dev

ROTranslatingShape permutations.png (42K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: ROTranslatingShape mouse hotspot mis-alignment

Ben Coman
Just some commentary on the different cases - mainly thinking out loud to clarify my own thoughts...

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.

cheers, Ben

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)

cheers, Ben






_______________________________________________ Moose-dev mailing list [hidden email] https://www.iam.unibe.ch/mailman/listinfo/moose-dev


_______________________________________________
Moose-dev mailing list
[hidden email]
https://www.iam.unibe.ch/mailman/listinfo/moose-dev
Reply | Threaded
Open this post in threaded view
|

Re: ROTranslatingShape mouse hotspot mis-alignment

abergel
Hi Ben,

This issue gave me a very hard time. Here what I have done:
  - the children shape is not a subclass of ending shape. You can create an instance of an element without a children shape with "ROElement bare". You then be able to organize the shape chain as you wish.
  - I worked very hard on the translate shape. Making the event work properly is not an easy task. Try the following:
        | el inner view |
        el := ROElement on: 1.
        el + (ROTranslatingShape offset: 20 @ 20) + ROBorder new.
        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

Let me know how it goes.

Cheers,
Alexandre


On Sep 22, 2012, at 12:24 PM, Ben Coman <[hidden email]> wrote:

> Just some commentary on the different cases - mainly thinking out loud to clarify my own thoughts...
>
> 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.
>
> cheers, Ben
>
> 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)
>>
>> cheers, Ben
>>
>>
>>
>>
>> <Mail Attachment.png>
>>
>> _______________________________________________
>> Moose-dev mailing list
>>
>> [hidden email]
>> https://www.iam.unibe.ch/mailman/listinfo/moose-dev
>
> _______________________________________________
> Moose-dev mailing list
> [hidden email]
> https://www.iam.unibe.ch/mailman/listinfo/moose-dev

--
_,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:
Alexandre Bergel  http://www.bergel.eu
^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.



_______________________________________________
Moose-dev mailing list
[hidden email]
https://www.iam.unibe.ch/mailman/listinfo/moose-dev
Reply | Threaded
Open this post in threaded view
|

Re: ROTranslatingShape mouse hotspot mis-alignment

Ben Coman
I could see that it wouldn't be easy, and really appreciate the effort.
There is a bit to go still, which I comment on in the issue tracker.


Alexandre Bergel wrote:

> Hi Ben,
>
> This issue gave me a very hard time. Here what I have done:
>   - the children shape is not a subclass of ending shape. You can create an instance of an element without a children shape with "ROElement bare". You then be able to organize the shape chain as you wish.
>   - I worked very hard on the translate shape. Making the event work properly is not an easy task. Try the following:
> | el inner view |
> el := ROElement on: 1.
> el + (ROTranslatingShape offset: 20 @ 20) + ROBorder new.
> 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
>
> Let me know how it goes.
>
> Cheers,
> Alexandre
>
>
> On Sep 22, 2012, at 12:24 PM, Ben Coman <[hidden email]> wrote:
>
>  
>> Just some commentary on the different cases - mainly thinking out loud to clarify my own thoughts...
>>
>> 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.
>>
>> cheers, Ben
>>
>> 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)
>>>
>>> cheers, Ben
>>>
>>>      

_______________________________________________
Moose-dev mailing list
[hidden email]
https://www.iam.unibe.ch/mailman/listinfo/moose-dev