Roassal2 RTDraggable grid and synchronized movement

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

Roassal2 RTDraggable grid and synchronized movement

Peter Uhnak
While playing with RTMultiLine I thought that it would be nice to have option for RTDraggable elements to snap to a grid / move only by fixed increments - for example the position could only be divisible by 10 (grid size would be 10), so dragging from 20@10 to 26@4 would jump to 30@0. Is something like this possible with current implementation?

The second question is: is it possible for element to subscribe for position updates of another element? (I.e. element A watches for movement of element B and moves accordingly). I know I could add both of them to a composite shape or RTGroup (RTDraggable>>groupToDrag:), however I would prefer something more loosely coupled.

In RTDraggable>>initializeElement: i found
" element when: TRMouseDragging do: [ :e | e element translateBy: e step. e signalUpdate ]"
however it is commented out so perhaps there some other way?

Peter
Reply | Threaded
Open this post in threaded view
|

Re: Roassal2 RTDraggable grid and synchronized movement

Peter Uhnak
Addendum: generally when it comes to Mouse events, using TRMouse* events should be the way to go? E.g. I want to add a control point when I click somewhere on the line so I could subscribe for TRMouseRightClick announcement. My question however is whether using TRachert events is ok. Shouldn't this be handled at Roassal level as it was done in Roassal1 (ROMouseRightClick)?


On Thu, Jul 31, 2014 at 9:58 PM, Peter Uhnák <[hidden email]> wrote:
While playing with RTMultiLine I thought that it would be nice to have option for RTDraggable elements to snap to a grid / move only by fixed increments - for example the position could only be divisible by 10 (grid size would be 10), so dragging from 20@10 to 26@4 would jump to 30@0. Is something like this possible with current implementation?

The second question is: is it possible for element to subscribe for position updates of another element? (I.e. element A watches for movement of element B and moves accordingly). I know I could add both of them to a composite shape or RTGroup (RTDraggable>>groupToDrag:), however I would prefer something more loosely coupled.

In RTDraggable>>initializeElement: i found
" element when: TRMouseDragging do: [ :e | e element translateBy: e step. e signalUpdate ]"
however it is commented out so perhaps there some other way?

Peter

Reply | Threaded
Open this post in threaded view
|

Re: Roassal2 RTDraggable grid and synchronized movement

abergel
In reply to this post by Peter Uhnak
Hi Peter!

> While playing with RTMultiLine I thought that it would be nice to have option for RTDraggable elements to snap to a grid / move only by fixed increments - for example the position could only be divisible by 10 (grid size would be 10), so dragging from 20@10 to 26@4 would jump to 30@0. Is something like this possible with current implementation?


I first thought this would be easy. But actually it is not.
The way to achieve the snap on grid behavior is to have an indirection in the Trachel classes. Each trachel shape knows its position (the position is contained in the matrix attached to each shape). The snap-on-grid means you need to slightly process the matrix coordinate. Maybe there are other way to do this, but it does not look like. Changing Trachel because of this seems a bit overkill...

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



On Jul 31, 2014, at 3:58 PM, Peter Uhnák <[hidden email]> wrote:

> While playing with RTMultiLine I thought that it would be nice to have option for RTDraggable elements to snap to a grid / move only by fixed increments - for example the position could only be divisible by 10 (grid size would be 10), so dragging from 20@10 to 26@4 would jump to 30@0. Is something like this possible with current implementation?
>
> The second question is: is it possible for element to subscribe for position updates of another element? (I.e. element A watches for movement of element B and moves accordingly). I know I could add both of them to a composite shape or RTGroup (RTDraggable>>groupToDrag:), however I would prefer something more loosely coupled.
>
> In RTDraggable>>initializeElement: i found
> " element when: TRMouseDragging do: [ :e | e element translateBy: e step. e signalUpdate ]"
> however it is commented out so perhaps there some other way?
>
> Peter


Reply | Threaded
Open this post in threaded view
|

Re: Roassal2 RTDraggable grid and synchronized movement

abergel
In reply to this post by Peter Uhnak
The second question is: is it possible for element to subscribe for position updates of another element? (I.e. element A watches for movement of element B and moves accordingly). I know I could add both of them to a composite shape or RTGroup (RTDraggable>>groupToDrag:), however I would prefer something more loosely coupled.

In RTDraggable>>initializeElement: i found
" element when: TRMouseDragging do: [ :e | e element translateBy: e step. e signalUpdate ]"
however it is commented out so perhaps there some other way?

Yes you can. Not using events, but Trachel callbacks. 

Consider the example:
-=-=-=-=-=-=-=-=-=-=-=-=
| v |
v := RTView new.

es := RTEllipse elementsOn: Collection withAllSubclasses.
v addAll: es.

es @ (RTLabelled new text: #numberOfMethods).
es @ RTPopup @ RTDraggable.

RTMetricNormalizer new
elements: es;
normalizeSize: #numberOfMethods min: 5 max: 20 using: #sqrt.
RTFlowLayout new gapSize: 15; on: es.

v
-=-=-=-=-=-=-=-=-=-=-=-=

When you move a circle, the label moves as well. There is a ‘constraint’ that says the label sticks to the circle


The class TRConstraint contains many utility methods you may enjoy to define constraints between elements.
For example:

TRConstraint  class >> stick: aShape onTheTopLeftOf: anotherShape
| b |
self move: aShape onTheTopLeftOf: anotherShape. 
b := [ :shape :step | self move: aShape onTheTopLeftOf: anotherShape ].
anotherShape addCallback: (TRTranslationCallback block: b).
anotherShape addCallback: (TRExtentCallback block: b) 

Let us know if you have further question.

Cheers,
Alexandre

Reply | Threaded
Open this post in threaded view
|

Re: Roassal2 RTDraggable grid and synchronized movement

abergel
In reply to this post by Peter Uhnak
Hi Peter,

Events are emitted by Trachel directly. Roassal does not emit event itself. But it can define callbacks for these events. 

Being able to define multiline by clicking on a line is very valuable.

go go go! And ask question if you are blocked.

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



On Jul 31, 2014, at 4:26 PM, Peter Uhnák <[hidden email]> wrote:

Addendum: generally when it comes to Mouse events, using TRMouse* events should be the way to go? E.g. I want to add a control point when I click somewhere on the line so I could subscribe for TRMouseRightClick announcement. My question however is whether using TRachert events is ok. Shouldn't this be handled at Roassal level as it was done in Roassal1 (ROMouseRightClick)?


On Thu, Jul 31, 2014 at 9:58 PM, Peter Uhnák <[hidden email]> wrote:
While playing with RTMultiLine I thought that it would be nice to have option for RTDraggable elements to snap to a grid / move only by fixed increments - for example the position could only be divisible by 10 (grid size would be 10), so dragging from 20@10 to 26@4 would jump to 30@0. Is something like this possible with current implementation?

The second question is: is it possible for element to subscribe for position updates of another element? (I.e. element A watches for movement of element B and moves accordingly). I know I could add both of them to a composite shape or RTGroup (RTDraggable>>groupToDrag:), however I would prefer something more loosely coupled.

In RTDraggable>>initializeElement: i found
" element when: TRMouseDragging do: [ :e | e element translateBy: e step. e signalUpdate ]"
however it is commented out so perhaps there some other way?

Peter


Reply | Threaded
Open this post in threaded view
|

Re: Roassal2 RTDraggable grid and synchronized movement

Peter Uhnak
In reply to this post by abergel
Hi Alex,

While the "snap to grid" might be complicated I thought of simpler solution that might be achievable purely at Roassal level without the need to change Trachel classes. You can look at Umlet, since I am trying to copy it's grid behavior here.
Basically you don't move objects with mouse immediately but only after fixed increments. However I've encountered a problem with TRMouseDragging>>step, since I would probably need to continuously sum the individual steps and then reset them when dragging has started.

Here is a _very_ crude prototype:
---------------------
"i subclassed RTDraggable and changed initializeElement: method as follows"
initializeElement: element
| sum gridSize |
gridSize := 20.
sum := 0 @ 0.
element
when: TRMouseDragging
do: [ :e | 
| d t |
t := RTGroup withAll: groupToDrag.
(t includes: element)
ifFalse: [ t add: element ].
d := element view canvas camera distanceFromPixelToSpace: e step.
sum := sum + d.
"move element only in increments of gridSize"
d := gridSize * ((sum x / gridSize) truncated @ (sum y / gridSize) truncated).
sum := sum - d.
t translateBy: d.
e signalUpdate ]
---------------------

and here is a demo utilizing it

-----------------------------
| v e1 e2 line gridSize  b1 b2 b3 b4 edge |
v := RTView new.

"draw grid"
gridSize := 20.

(-20 to: 20) do: [ :i |
b1 := RTBox element.
b2 := RTBox element.
b3 := RTBox element.
b4 := RTBox element.
b1 translateTo: (i * gridSize) @ -1000. "top side"
b2 translateTo: (i * gridSize) @ 1000. "bottom side"
b3 translateTo: -1000 @ (i * gridSize). "left side"
b4 translateTo: 1000 @ (i * gridSize). "right side"
"vertical line"
edge := RTLine edgeFrom: b1 to: b2.
v add: edge.
"horizontal line"
edge := RTLine edgeFrom: b3 to: b4.
v add: edge.
].

e1 := (RTEllipse new size: 30; color: Color magenta) element.
e1 translateTo: -20 @ 0.
e1 @ RGGridDraggable.

e2 := (RTEllipse new size: 30; color: Color magenta) element.
e2 translateTo: 20 @ 0.
e2 @ RGGridDraggable.

(line := RTLine edgeFrom: e1 to: e2) shape color:Color black.

v add: e1; add: e2; add: line.

v open.
-----------------------------

Obviously it needs a lot of fine-tuning and such. Since RTInteraction (RTDraggable) instances are not created directly the gridSize would have to be stored probably class side. Also there is a problem with resetting the "sum" variable when dragging starts. (There is no TRMouseDragStart event as far as I've seen). And also drawing the grid itself the way I've done is very brutal and doesn't really work if I want to move the canvas camera (perhaps image pattern as a background would work better).

What are your thoughts on this?

Peter




On Fri, Aug 1, 2014 at 4:07 PM, Alexandre Bergel <[hidden email]> wrote:
Hi Peter!

> While playing with RTMultiLine I thought that it would be nice to have option for RTDraggable elements to snap to a grid / move only by fixed increments - for example the position could only be divisible by 10 (grid size would be 10), so dragging from 20@10 to 26@4 would jump to 30@0. Is something like this possible with current implementation?


I first thought this would be easy. But actually it is not.
The way to achieve the snap on grid behavior is to have an indirection in the Trachel classes. Each trachel shape knows its position (the position is contained in the matrix attached to each shape). The snap-on-grid means you need to slightly process the matrix coordinate. Maybe there are other way to do this, but it does not look like. Changing Trachel because of this seems a bit overkill...

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



On Jul 31, 2014, at 3:58 PM, Peter Uhnák <[hidden email]> wrote:

> While playing with RTMultiLine I thought that it would be nice to have option for RTDraggable elements to snap to a grid / move only by fixed increments - for example the position could only be divisible by 10 (grid size would be 10), so dragging from 20@10 to 26@4 would jump to 30@0. Is something like this possible with current implementation?
>
> The second question is: is it possible for element to subscribe for position updates of another element? (I.e. element A watches for movement of element B and moves accordingly). I know I could add both of them to a composite shape or RTGroup (RTDraggable>>groupToDrag:), however I would prefer something more loosely coupled.
>
> In RTDraggable>>initializeElement: i found
> "     element when: TRMouseDragging do: [ :e | e element translateBy: e step. e signalUpdate ]"
> however it is commented out so perhaps there some other way?
>
> Peter



Reply | Threaded
Open this post in threaded view
|

Re: Roassal2 RTDraggable grid and synchronized movement

abergel
This is an excellent start.

Do you need the grid? If yes, then I can add this to Roassal. It is easy to define an interaction that define a grid. 

I have added event to signal the beginning and ending of a dragging-and-dropping.
Here is an example:
-=-=-=-=-=-=-=-=
| v e |
v := RTView new.
e := (RTEllipse new size: 30) element.
e @ RTDraggable.
v add: e.
e when: TRMouseDragStart do: [ :evt | Transcript show: evt printString; cr. evt element trachelShape color: Color red. v signalUpdate ].
e when: TRMouseDragEnd do: [ :evt | Transcript show: evt printString; cr ].
v  open
-=-=-=-=-=-=-=-=

Let me know whether this helps.

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



On Aug 1, 2014, at 2:36 PM, Peter Uhnák <[hidden email]> wrote:

Hi Alex,

While the "snap to grid" might be complicated I thought of simpler solution that might be achievable purely at Roassal level without the need to change Trachel classes. You can look at Umlet, since I am trying to copy it's grid behavior here.
Basically you don't move objects with mouse immediately but only after fixed increments. However I've encountered a problem with TRMouseDragging>>step, since I would probably need to continuously sum the individual steps and then reset them when dragging has started.

Here is a _very_ crude prototype:
---------------------
"i subclassed RTDraggable and changed initializeElement: method as follows"
initializeElement: element
| sum gridSize |
gridSize := 20.
sum := 0 @ 0.
element
when: TRMouseDragging
do: [ :e | 
| d t |
t := RTGroup withAll: groupToDrag.
(t includes: element)
ifFalse: [ t add: element ].
d := element view canvas camera distanceFromPixelToSpace: e step.
sum := sum + d.
"move element only in increments of gridSize"
d := gridSize * ((sum x / gridSize) truncated @ (sum y / gridSize) truncated).
sum := sum - d.
t translateBy: d.
e signalUpdate ]
---------------------

and here is a demo utilizing it

-----------------------------
| v e1 e2 line gridSize  b1 b2 b3 b4 edge |
v := RTView new.

"draw grid"
gridSize := 20.

(-20 to: 20) do: [ :i |
b1 := RTBox element.
b2 := RTBox element.
b3 := RTBox element.
b4 := RTBox element.
b1 translateTo: (i * gridSize) @ -1000. "top side"
b2 translateTo: (i * gridSize) @ 1000. "bottom side"
b3 translateTo: -1000 @ (i * gridSize). "left side"
b4 translateTo: 1000 @ (i * gridSize). "right side"
"vertical line"
edge := RTLine edgeFrom: b1 to: b2.
v add: edge.
"horizontal line"
edge := RTLine edgeFrom: b3 to: b4.
v add: edge.
].

e1 := (RTEllipse new size: 30; color: Color magenta) element.
e1 translateTo: -20 @ 0.
e1 @ RGGridDraggable.

e2 := (RTEllipse new size: 30; color: Color magenta) element.
e2 translateTo: 20 @ 0.
e2 @ RGGridDraggable.

(line := RTLine edgeFrom: e1 to: e2) shape color:Color black.

v add: e1; add: e2; add: line.

v open.
-----------------------------

Obviously it needs a lot of fine-tuning and such. Since RTInteraction (RTDraggable) instances are not created directly the gridSize would have to be stored probably class side. Also there is a problem with resetting the "sum" variable when dragging starts. (There is no TRMouseDragStart event as far as I've seen). And also drawing the grid itself the way I've done is very brutal and doesn't really work if I want to move the canvas camera (perhaps image pattern as a background would work better).

What are your thoughts on this?

Peter




On Fri, Aug 1, 2014 at 4:07 PM, Alexandre Bergel <[hidden email]> wrote:
Hi Peter!

> While playing with RTMultiLine I thought that it would be nice to have option for RTDraggable elements to snap to a grid / move only by fixed increments - for example the position could only be divisible by 10 (grid size would be 10), so dragging from 20@10 to 26@4 would jump to 30@0. Is something like this possible with current implementation?


I first thought this would be easy. But actually it is not.
The way to achieve the snap on grid behavior is to have an indirection in the Trachel classes. Each trachel shape knows its position (the position is contained in the matrix attached to each shape). The snap-on-grid means you need to slightly process the matrix coordinate. Maybe there are other way to do this, but it does not look like. Changing Trachel because of this seems a bit overkill...

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



On Jul 31, 2014, at 3:58 PM, Peter Uhnák <[hidden email]> wrote:

> While playing with RTMultiLine I thought that it would be nice to have option for RTDraggable elements to snap to a grid / move only by fixed increments - for example the position could only be divisible by 10 (grid size would be 10), so dragging from 20@10 to 26@4 would jump to 30@0. Is something like this possible with current implementation?
>
> The second question is: is it possible for element to subscribe for position updates of another element? (I.e. element A watches for movement of element B and moves accordingly). I know I could add both of them to a composite shape or RTGroup (RTDraggable>>groupToDrag:), however I would prefer something more loosely coupled.
>
> In RTDraggable>>initializeElement: i found
> "     element when: TRMouseDragging do: [ :e | e element translateBy: e step. e signalUpdate ]"
> however it is commented out so perhaps there some other way?
>
> Peter




Reply | Threaded
Open this post in threaded view
|

Re: Roassal2 RTDraggable grid and synchronized movement

Tudor Girba-2
I really love this discussion :)

Doru


On Fri, Aug 1, 2014 at 11:36 PM, Alexandre Bergel <[hidden email]> wrote:
This is an excellent start.

Do you need the grid? If yes, then I can add this to Roassal. It is easy to define an interaction that define a grid. 

I have added event to signal the beginning and ending of a dragging-and-dropping.
Here is an example:
-=-=-=-=-=-=-=-=
| v e |
v := RTView new.
e := (RTEllipse new size: 30) element.
e @ RTDraggable.
v add: e.
e when: TRMouseDragStart do: [ :evt | Transcript show: evt printString; cr. evt element trachelShape color: Color red. v signalUpdate ].
e when: TRMouseDragEnd do: [ :evt | Transcript show: evt printString; cr ].
v  open
-=-=-=-=-=-=-=-=

Let me know whether this helps.

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



On Aug 1, 2014, at 2:36 PM, Peter Uhnák <[hidden email]> wrote:

Hi Alex,

While the "snap to grid" might be complicated I thought of simpler solution that might be achievable purely at Roassal level without the need to change Trachel classes. You can look at Umlet, since I am trying to copy it's grid behavior here.
Basically you don't move objects with mouse immediately but only after fixed increments. However I've encountered a problem with TRMouseDragging>>step, since I would probably need to continuously sum the individual steps and then reset them when dragging has started.

Here is a _very_ crude prototype:
---------------------
"i subclassed RTDraggable and changed initializeElement: method as follows"
initializeElement: element
| sum gridSize |
gridSize := 20.
sum := 0 @ 0.
element
when: TRMouseDragging
do: [ :e | 
| d t |
t := RTGroup withAll: groupToDrag.
(t includes: element)
ifFalse: [ t add: element ].
d := element view canvas camera distanceFromPixelToSpace: e step.
sum := sum + d.
"move element only in increments of gridSize"
d := gridSize * ((sum x / gridSize) truncated @ (sum y / gridSize) truncated).
sum := sum - d.
t translateBy: d.
e signalUpdate ]
---------------------

and here is a demo utilizing it

-----------------------------
| v e1 e2 line gridSize  b1 b2 b3 b4 edge |
v := RTView new.

"draw grid"
gridSize := 20.

(-20 to: 20) do: [ :i |
b1 := RTBox element.
b2 := RTBox element.
b3 := RTBox element.
b4 := RTBox element.
b1 translateTo: (i * gridSize) @ -1000. "top side"
b2 translateTo: (i * gridSize) @ 1000. "bottom side"
b3 translateTo: -1000 @ (i * gridSize). "left side"
b4 translateTo: 1000 @ (i * gridSize). "right side"
"vertical line"
edge := RTLine edgeFrom: b1 to: b2.
v add: edge.
"horizontal line"
edge := RTLine edgeFrom: b3 to: b4.
v add: edge.
].

e1 := (RTEllipse new size: 30; color: Color magenta) element.
e1 translateTo: -20 @ 0.
e1 @ RGGridDraggable.

e2 := (RTEllipse new size: 30; color: Color magenta) element.
e2 translateTo: 20 @ 0.
e2 @ RGGridDraggable.

(line := RTLine edgeFrom: e1 to: e2) shape color:Color black.

v add: e1; add: e2; add: line.

v open.
-----------------------------

Obviously it needs a lot of fine-tuning and such. Since RTInteraction (RTDraggable) instances are not created directly the gridSize would have to be stored probably class side. Also there is a problem with resetting the "sum" variable when dragging starts. (There is no TRMouseDragStart event as far as I've seen). And also drawing the grid itself the way I've done is very brutal and doesn't really work if I want to move the canvas camera (perhaps image pattern as a background would work better).

What are your thoughts on this?

Peter




On Fri, Aug 1, 2014 at 4:07 PM, Alexandre Bergel <[hidden email]> wrote:
Hi Peter!

> While playing with RTMultiLine I thought that it would be nice to have option for RTDraggable elements to snap to a grid / move only by fixed increments - for example the position could only be divisible by 10 (grid size would be 10), so dragging from 20@10 to 26@4 would jump to 30@0. Is something like this possible with current implementation?


I first thought this would be easy. But actually it is not.
The way to achieve the snap on grid behavior is to have an indirection in the Trachel classes. Each trachel shape knows its position (the position is contained in the matrix attached to each shape). The snap-on-grid means you need to slightly process the matrix coordinate. Maybe there are other way to do this, but it does not look like. Changing Trachel because of this seems a bit overkill...

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



On Jul 31, 2014, at 3:58 PM, Peter Uhnák <[hidden email]> wrote:

> While playing with RTMultiLine I thought that it would be nice to have option for RTDraggable elements to snap to a grid / move only by fixed increments - for example the position could only be divisible by 10 (grid size would be 10), so dragging from 20@10 to 26@4 would jump to 30@0. Is something like this possible with current implementation?
>
> The second question is: is it possible for element to subscribe for position updates of another element? (I.e. element A watches for movement of element B and moves accordingly). I know I could add both of them to a composite shape or RTGroup (RTDraggable>>groupToDrag:), however I would prefer something more loosely coupled.
>
> In RTDraggable>>initializeElement: i found
> "     element when: TRMouseDragging do: [ :e | e element translateBy: e step. e signalUpdate ]"
> however it is commented out so perhaps there some other way?
>
> Peter







--

"Every thing has its own flow"
Reply | Threaded
Open this post in threaded view
|

Re: Roassal2 RTDraggable grid and synchronized movement

abergel
In reply to this post by Peter Uhnak
Hi Peter,

How things are going with having a snapOnGrid behavior?

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



On Aug 1, 2014, at 2:36 PM, Peter Uhnák <[hidden email]> wrote:

Hi Alex,

While the "snap to grid" might be complicated I thought of simpler solution that might be achievable purely at Roassal level without the need to change Trachel classes. You can look at Umlet, since I am trying to copy it's grid behavior here.
Basically you don't move objects with mouse immediately but only after fixed increments. However I've encountered a problem with TRMouseDragging>>step, since I would probably need to continuously sum the individual steps and then reset them when dragging has started.

Here is a _very_ crude prototype:
---------------------
"i subclassed RTDraggable and changed initializeElement: method as follows"
initializeElement: element
| sum gridSize |
gridSize := 20.
sum := 0 @ 0.
element
when: TRMouseDragging
do: [ :e | 
| d t |
t := RTGroup withAll: groupToDrag.
(t includes: element)
ifFalse: [ t add: element ].
d := element view canvas camera distanceFromPixelToSpace: e step.
sum := sum + d.
"move element only in increments of gridSize"
d := gridSize * ((sum x / gridSize) truncated @ (sum y / gridSize) truncated).
sum := sum - d.
t translateBy: d.
e signalUpdate ]
---------------------

and here is a demo utilizing it

-----------------------------
| v e1 e2 line gridSize  b1 b2 b3 b4 edge |
v := RTView new.

"draw grid"
gridSize := 20.

(-20 to: 20) do: [ :i |
b1 := RTBox element.
b2 := RTBox element.
b3 := RTBox element.
b4 := RTBox element.
b1 translateTo: (i * gridSize) @ -1000. "top side"
b2 translateTo: (i * gridSize) @ 1000. "bottom side"
b3 translateTo: -1000 @ (i * gridSize). "left side"
b4 translateTo: 1000 @ (i * gridSize). "right side"
"vertical line"
edge := RTLine edgeFrom: b1 to: b2.
v add: edge.
"horizontal line"
edge := RTLine edgeFrom: b3 to: b4.
v add: edge.
].

e1 := (RTEllipse new size: 30; color: Color magenta) element.
e1 translateTo: -20 @ 0.
e1 @ RGGridDraggable.

e2 := (RTEllipse new size: 30; color: Color magenta) element.
e2 translateTo: 20 @ 0.
e2 @ RGGridDraggable.

(line := RTLine edgeFrom: e1 to: e2) shape color:Color black.

v add: e1; add: e2; add: line.

v open.
-----------------------------

Obviously it needs a lot of fine-tuning and such. Since RTInteraction (RTDraggable) instances are not created directly the gridSize would have to be stored probably class side. Also there is a problem with resetting the "sum" variable when dragging starts. (There is no TRMouseDragStart event as far as I've seen). And also drawing the grid itself the way I've done is very brutal and doesn't really work if I want to move the canvas camera (perhaps image pattern as a background would work better).

What are your thoughts on this?

Peter




On Fri, Aug 1, 2014 at 4:07 PM, Alexandre Bergel <[hidden email]> wrote:
Hi Peter!

> While playing with RTMultiLine I thought that it would be nice to have option for RTDraggable elements to snap to a grid / move only by fixed increments - for example the position could only be divisible by 10 (grid size would be 10), so dragging from 20@10 to 26@4 would jump to 30@0. Is something like this possible with current implementation?


I first thought this would be easy. But actually it is not.
The way to achieve the snap on grid behavior is to have an indirection in the Trachel classes. Each trachel shape knows its position (the position is contained in the matrix attached to each shape). The snap-on-grid means you need to slightly process the matrix coordinate. Maybe there are other way to do this, but it does not look like. Changing Trachel because of this seems a bit overkill...

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



On Jul 31, 2014, at 3:58 PM, Peter Uhnák <[hidden email]> wrote:

> While playing with RTMultiLine I thought that it would be nice to have option for RTDraggable elements to snap to a grid / move only by fixed increments - for example the position could only be divisible by 10 (grid size would be 10), so dragging from 20@10 to 26@4 would jump to 30@0. Is something like this possible with current implementation?
>
> The second question is: is it possible for element to subscribe for position updates of another element? (I.e. element A watches for movement of element B and moves accordingly). I know I could add both of them to a composite shape or RTGroup (RTDraggable>>groupToDrag:), however I would prefer something more loosely coupled.
>
> In RTDraggable>>initializeElement: i found
> "     element when: TRMouseDragging do: [ :e | e element translateBy: e step. e signalUpdate ]"
> however it is commented out so perhaps there some other way?
>
> Peter




Reply | Threaded
Open this post in threaded view
|

Re: Roassal2 RTDraggable grid and synchronized movement

Peter Uhnak
Hi Alex,

unfortunately I've been quite busy with other stuff however it's on my todo list so I'm planning to get back to it later this week.
I'll keep you posted.

Peter


On Fri, Aug 8, 2014 at 11:57 PM, Alexandre Bergel <[hidden email]> wrote:
Hi Peter,

How things are going with having a snapOnGrid behavior?

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



On Aug 1, 2014, at 2:36 PM, Peter Uhnák <[hidden email]> wrote:

Hi Alex,

While the "snap to grid" might be complicated I thought of simpler solution that might be achievable purely at Roassal level without the need to change Trachel classes. You can look at Umlet, since I am trying to copy it's grid behavior here.
Basically you don't move objects with mouse immediately but only after fixed increments. However I've encountered a problem with TRMouseDragging>>step, since I would probably need to continuously sum the individual steps and then reset them when dragging has started.

Here is a _very_ crude prototype:
---------------------
"i subclassed RTDraggable and changed initializeElement: method as follows"
initializeElement: element
| sum gridSize |
gridSize := 20.
sum := 0 @ 0.
element
when: TRMouseDragging
do: [ :e | 
| d t |
t := RTGroup withAll: groupToDrag.
(t includes: element)
ifFalse: [ t add: element ].
d := element view canvas camera distanceFromPixelToSpace: e step.
sum := sum + d.
"move element only in increments of gridSize"
d := gridSize * ((sum x / gridSize) truncated @ (sum y / gridSize) truncated).
sum := sum - d.
t translateBy: d.
e signalUpdate ]
---------------------

and here is a demo utilizing it

-----------------------------
| v e1 e2 line gridSize  b1 b2 b3 b4 edge |
v := RTView new.

"draw grid"
gridSize := 20.

(-20 to: 20) do: [ :i |
b1 := RTBox element.
b2 := RTBox element.
b3 := RTBox element.
b4 := RTBox element.
b1 translateTo: (i * gridSize) @ -1000. "top side"
b2 translateTo: (i * gridSize) @ 1000. "bottom side"
b3 translateTo: -1000 @ (i * gridSize). "left side"
b4 translateTo: 1000 @ (i * gridSize). "right side"
"vertical line"
edge := RTLine edgeFrom: b1 to: b2.
v add: edge.
"horizontal line"
edge := RTLine edgeFrom: b3 to: b4.
v add: edge.
].

e1 := (RTEllipse new size: 30; color: Color magenta) element.
e1 translateTo: -20 @ 0.
e1 @ RGGridDraggable.

e2 := (RTEllipse new size: 30; color: Color magenta) element.
e2 translateTo: 20 @ 0.
e2 @ RGGridDraggable.

(line := RTLine edgeFrom: e1 to: e2) shape color:Color black.

v add: e1; add: e2; add: line.

v open.
-----------------------------

Obviously it needs a lot of fine-tuning and such. Since RTInteraction (RTDraggable) instances are not created directly the gridSize would have to be stored probably class side. Also there is a problem with resetting the "sum" variable when dragging starts. (There is no TRMouseDragStart event as far as I've seen). And also drawing the grid itself the way I've done is very brutal and doesn't really work if I want to move the canvas camera (perhaps image pattern as a background would work better).

What are your thoughts on this?

Peter




On Fri, Aug 1, 2014 at 4:07 PM, Alexandre Bergel <[hidden email]> wrote:
Hi Peter!

> While playing with RTMultiLine I thought that it would be nice to have option for RTDraggable elements to snap to a grid / move only by fixed increments - for example the position could only be divisible by 10 (grid size would be 10), so dragging from 20@10 to 26@4 would jump to 30@0. Is something like this possible with current implementation?


I first thought this would be easy. But actually it is not.
The way to achieve the snap on grid behavior is to have an indirection in the Trachel classes. Each trachel shape knows its position (the position is contained in the matrix attached to each shape). The snap-on-grid means you need to slightly process the matrix coordinate. Maybe there are other way to do this, but it does not look like. Changing Trachel because of this seems a bit overkill...

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



On Jul 31, 2014, at 3:58 PM, Peter Uhnák <[hidden email]> wrote:

> While playing with RTMultiLine I thought that it would be nice to have option for RTDraggable elements to snap to a grid / move only by fixed increments - for example the position could only be divisible by 10 (grid size would be 10), so dragging from 20@10 to 26@4 would jump to 30@0. Is something like this possible with current implementation?
>
> The second question is: is it possible for element to subscribe for position updates of another element? (I.e. element A watches for movement of element B and moves accordingly). I know I could add both of them to a composite shape or RTGroup (RTDraggable>>groupToDrag:), however I would prefer something more loosely coupled.
>
> In RTDraggable>>initializeElement: i found
> "     element when: TRMouseDragging do: [ :e | e element translateBy: e step. e signalUpdate ]"
> however it is commented out so perhaps there some other way?
>
> Peter





Reply | Threaded
Open this post in threaded view
|

Re: Roassal2 RTDraggable grid and synchronized movement

abergel
Ok, excellent!

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



On Aug 11, 2014, at 4:37 AM, Peter Uhnák <[hidden email]> wrote:

Hi Alex,

unfortunately I've been quite busy with other stuff however it's on my todo list so I'm planning to get back to it later this week.
I'll keep you posted.

Peter


On Fri, Aug 8, 2014 at 11:57 PM, Alexandre Bergel <[hidden email]> wrote:
Hi Peter,

How things are going with having a snapOnGrid behavior?

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



On Aug 1, 2014, at 2:36 PM, Peter Uhnák <[hidden email]> wrote:

Hi Alex,

While the "snap to grid" might be complicated I thought of simpler solution that might be achievable purely at Roassal level without the need to change Trachel classes. You can look at Umlet, since I am trying to copy it's grid behavior here.
Basically you don't move objects with mouse immediately but only after fixed increments. However I've encountered a problem with TRMouseDragging>>step, since I would probably need to continuously sum the individual steps and then reset them when dragging has started.

Here is a _very_ crude prototype:
---------------------
"i subclassed RTDraggable and changed initializeElement: method as follows"
initializeElement: element
| sum gridSize |
gridSize := 20.
sum := 0 @ 0.
element
when: TRMouseDragging
do: [ :e | 
| d t |
t := RTGroup withAll: groupToDrag.
(t includes: element)
ifFalse: [ t add: element ].
d := element view canvas camera distanceFromPixelToSpace: e step.
sum := sum + d.
"move element only in increments of gridSize"
d := gridSize * ((sum x / gridSize) truncated @ (sum y / gridSize) truncated).
sum := sum - d.
t translateBy: d.
e signalUpdate ]
---------------------

and here is a demo utilizing it

-----------------------------
| v e1 e2 line gridSize  b1 b2 b3 b4 edge |
v := RTView new.

"draw grid"
gridSize := 20.

(-20 to: 20) do: [ :i |
b1 := RTBox element.
b2 := RTBox element.
b3 := RTBox element.
b4 := RTBox element.
b1 translateTo: (i * gridSize) @ -1000. "top side"
b2 translateTo: (i * gridSize) @ 1000. "bottom side"
b3 translateTo: -1000 @ (i * gridSize). "left side"
b4 translateTo: 1000 @ (i * gridSize). "right side"
"vertical line"
edge := RTLine edgeFrom: b1 to: b2.
v add: edge.
"horizontal line"
edge := RTLine edgeFrom: b3 to: b4.
v add: edge.
].

e1 := (RTEllipse new size: 30; color: Color magenta) element.
e1 translateTo: -20 @ 0.
e1 @ RGGridDraggable.

e2 := (RTEllipse new size: 30; color: Color magenta) element.
e2 translateTo: 20 @ 0.
e2 @ RGGridDraggable.

(line := RTLine edgeFrom: e1 to: e2) shape color:Color black.

v add: e1; add: e2; add: line.

v open.
-----------------------------

Obviously it needs a lot of fine-tuning and such. Since RTInteraction (RTDraggable) instances are not created directly the gridSize would have to be stored probably class side. Also there is a problem with resetting the "sum" variable when dragging starts. (There is no TRMouseDragStart event as far as I've seen). And also drawing the grid itself the way I've done is very brutal and doesn't really work if I want to move the canvas camera (perhaps image pattern as a background would work better).

What are your thoughts on this?

Peter




On Fri, Aug 1, 2014 at 4:07 PM, Alexandre Bergel <[hidden email]> wrote:
Hi Peter!

> While playing with RTMultiLine I thought that it would be nice to have option for RTDraggable elements to snap to a grid / move only by fixed increments - for example the position could only be divisible by 10 (grid size would be 10), so dragging from 20@10 to 26@4 would jump to 30@0. Is something like this possible with current implementation?


I first thought this would be easy. But actually it is not.
The way to achieve the snap on grid behavior is to have an indirection in the Trachel classes. Each trachel shape knows its position (the position is contained in the matrix attached to each shape). The snap-on-grid means you need to slightly process the matrix coordinate. Maybe there are other way to do this, but it does not look like. Changing Trachel because of this seems a bit overkill...

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



On Jul 31, 2014, at 3:58 PM, Peter Uhnák <[hidden email]> wrote:

> While playing with RTMultiLine I thought that it would be nice to have option for RTDraggable elements to snap to a grid / move only by fixed increments - for example the position could only be divisible by 10 (grid size would be 10), so dragging from 20@10 to 26@4 would jump to 30@0. Is something like this possible with current implementation?
>
> The second question is: is it possible for element to subscribe for position updates of another element? (I.e. element A watches for movement of element B and moves accordingly). I know I could add both of them to a composite shape or RTGroup (RTDraggable>>groupToDrag:), however I would prefer something more loosely coupled.
>
> In RTDraggable>>initializeElement: i found
> "     element when: TRMouseDragging do: [ :e | e element translateBy: e step. e signalUpdate ]"
> however it is commented out so perhaps there some other way?
>
> Peter






Reply | Threaded
Open this post in threaded view
|

Re: Roassal2 RTDraggable grid and synchronized movement

Peter Uhnak
I've finally found my way back to it; I added it to same repo as my multiline http://smalltalkhub.com/#!/~peteruhnak/RoassalPrototypes/ ; there's also an example in class side.

However there are two main issues:
* drawing of the grid is crude, I created an interaction but I haven't seen any way how to draw repeated patterns. But perhaps that's wrong way of looking at it. Maybe some "fixed" shape that would always fill up the visible view and would move with the camera?

* there are two interactions - one for adding the grid to the view, second for adding gridded movement to elements. But how does one pass the grid size from the former to the latter?
One idea would be that the RPGridView would add the size of the grid to RTView somehow and when element is added it would look for this value. But I don't think it's possible to add extra parameters to classes from different packages (compared to adding extra messages).

Peter


On Mon, Aug 11, 2014 at 5:10 PM, Alexandre Bergel <[hidden email]> wrote:
Ok, excellent!

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



On Aug 11, 2014, at 4:37 AM, Peter Uhnák <[hidden email]> wrote:

Hi Alex,

unfortunately I've been quite busy with other stuff however it's on my todo list so I'm planning to get back to it later this week.
I'll keep you posted.

Peter


On Fri, Aug 8, 2014 at 11:57 PM, Alexandre Bergel <[hidden email]> wrote:
Hi Peter,

How things are going with having a snapOnGrid behavior?

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



On Aug 1, 2014, at 2:36 PM, Peter Uhnák <[hidden email]> wrote:

Hi Alex,

While the "snap to grid" might be complicated I thought of simpler solution that might be achievable purely at Roassal level without the need to change Trachel classes. You can look at Umlet, since I am trying to copy it's grid behavior here.
Basically you don't move objects with mouse immediately but only after fixed increments. However I've encountered a problem with TRMouseDragging>>step, since I would probably need to continuously sum the individual steps and then reset them when dragging has started.

Here is a _very_ crude prototype:
---------------------
"i subclassed RTDraggable and changed initializeElement: method as follows"
initializeElement: element
| sum gridSize |
gridSize := 20.
sum := 0 @ 0.
element
when: TRMouseDragging
do: [ :e | 
| d t |
t := RTGroup withAll: groupToDrag.
(t includes: element)
ifFalse: [ t add: element ].
d := element view canvas camera distanceFromPixelToSpace: e step.
sum := sum + d.
"move element only in increments of gridSize"
d := gridSize * ((sum x / gridSize) truncated @ (sum y / gridSize) truncated).
sum := sum - d.
t translateBy: d.
e signalUpdate ]
---------------------

and here is a demo utilizing it

-----------------------------
| v e1 e2 line gridSize  b1 b2 b3 b4 edge |
v := RTView new.

"draw grid"
gridSize := 20.

(-20 to: 20) do: [ :i |
b1 := RTBox element.
b2 := RTBox element.
b3 := RTBox element.
b4 := RTBox element.
b1 translateTo: (i * gridSize) @ -1000. "top side"
b2 translateTo: (i * gridSize) @ 1000. "bottom side"
b3 translateTo: -1000 @ (i * gridSize). "left side"
b4 translateTo: 1000 @ (i * gridSize). "right side"
"vertical line"
edge := RTLine edgeFrom: b1 to: b2.
v add: edge.
"horizontal line"
edge := RTLine edgeFrom: b3 to: b4.
v add: edge.
].

e1 := (RTEllipse new size: 30; color: Color magenta) element.
e1 translateTo: -20 @ 0.
e1 @ RGGridDraggable.

e2 := (RTEllipse new size: 30; color: Color magenta) element.
e2 translateTo: 20 @ 0.
e2 @ RGGridDraggable.

(line := RTLine edgeFrom: e1 to: e2) shape color:Color black.

v add: e1; add: e2; add: line.

v open.
-----------------------------

Obviously it needs a lot of fine-tuning and such. Since RTInteraction (RTDraggable) instances are not created directly the gridSize would have to be stored probably class side. Also there is a problem with resetting the "sum" variable when dragging starts. (There is no TRMouseDragStart event as far as I've seen). And also drawing the grid itself the way I've done is very brutal and doesn't really work if I want to move the canvas camera (perhaps image pattern as a background would work better).

What are your thoughts on this?

Peter




On Fri, Aug 1, 2014 at 4:07 PM, Alexandre Bergel <[hidden email]> wrote:
Hi Peter!

> While playing with RTMultiLine I thought that it would be nice to have option for RTDraggable elements to snap to a grid / move only by fixed increments - for example the position could only be divisible by 10 (grid size would be 10), so dragging from 20@10 to 26@4 would jump to 30@0. Is something like this possible with current implementation?


I first thought this would be easy. But actually it is not.
The way to achieve the snap on grid behavior is to have an indirection in the Trachel classes. Each trachel shape knows its position (the position is contained in the matrix attached to each shape). The snap-on-grid means you need to slightly process the matrix coordinate. Maybe there are other way to do this, but it does not look like. Changing Trachel because of this seems a bit overkill...

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



On Jul 31, 2014, at 3:58 PM, Peter Uhnák <[hidden email]> wrote:

> While playing with RTMultiLine I thought that it would be nice to have option for RTDraggable elements to snap to a grid / move only by fixed increments - for example the position could only be divisible by 10 (grid size would be 10), so dragging from 20@10 to 26@4 would jump to 30@0. Is something like this possible with current implementation?
>
> The second question is: is it possible for element to subscribe for position updates of another element? (I.e. element A watches for movement of element B and moves accordingly). I know I could add both of them to a composite shape or RTGroup (RTDraggable>>groupToDrag:), however I would prefer something more loosely coupled.
>
> In RTDraggable>>initializeElement: i found
> "     element when: TRMouseDragging do: [ :e | e element translateBy: e step. e signalUpdate ]"
> however it is commented out so perhaps there some other way?
>
> Peter