pharo-users@lists.pharo.org

Any question about pharo is welcome

View all threads

Converting global coordinates from a mouse event

MS
Mikael Svane
Sun, Mar 2, 2025 9:00 PM

I have a presenter that is a subclass of SpPresenterWithModel and it
contains, among other things, an ImagePresenter with an autoscaling image (a
Form). I want to capture mouse clicks on the image and get the coordinate of
the click relative to the upper left corner of the Form.

My #initializePresenter method looks like this:

initializePresenter

                       image := self newImage

                                                   image: self

emptyImage;

                                                   autoScale: true.

                       image eventHandler whenMouseDownDo: [ :event |

self handleMouseDown: event].

This works, and the #handleMouseDown: method is run whenever the mouse is
pressed on the ImagePresenter, but the MouseButtonEvent reports global
coordinates and I can't find out how to convert these to coordinates
relative to the Form that the ImagePresenter holds. I have googled and found
answers to similar old questions, but nothing that seems to apply to Spec2.

There must be a very simple solution to this, it's just that I can't seem to
find it.

Kind regards,

Mikael

I have a presenter that is a subclass of SpPresenterWithModel and it contains, among other things, an ImagePresenter with an autoscaling image (a Form). I want to capture mouse clicks on the image and get the coordinate of the click relative to the upper left corner of the Form. My #initializePresenter method looks like this: initializePresenter image := self newImage image: self emptyImage; autoScale: true. image eventHandler whenMouseDownDo: [ :event | self handleMouseDown: event]. This works, and the #handleMouseDown: method is run whenever the mouse is pressed on the ImagePresenter, but the MouseButtonEvent reports global coordinates and I can't find out how to convert these to coordinates relative to the Form that the ImagePresenter holds. I have googled and found answers to similar old questions, but nothing that seems to apply to Spec2. There must be a very simple solution to this, it's just that I can't seem to find it. Kind regards, Mikael
S
sducasseatwork@mailo.com
Tue, Mar 4, 2025 11:37 AM

I did a little search and I found

Morph >> globalPointToLocal: aPoint
^self point: aPoint from: nil

may be

image eventHandler whenMouseDownDo: [ :event |
                                                                               self handleMouseDown: event
							image globa…..

].

On 2 Mar 2025, at 22:00, Mikael Svane mikael.svane@fridhem.org wrote:

I have a presenter that is a subclass of SpPresenterWithModel and it contains, among other things, an ImagePresenter with an autoscaling image (a Form). I want to capture mouse clicks on the image and get the coordinate of the click relative to the upper left corner of the Form.

My #initializePresenter method looks like this:
initializePresenter
image := self newImage
image: self emptyImage;
autoScale: true.
image eventHandler whenMouseDownDo: [ :event |
self handleMouseDown: event].

This works, and the #handleMouseDown: method is run whenever the mouse is pressed on the ImagePresenter, but the MouseButtonEvent reports global coordinates and I can’t find out how to convert these to coordinates relative to the Form that the ImagePresenter holds. I have googled and found answers to similar old questions, but nothing that seems to apply to Spec2.

There must be a very simple solution to this, it’s just that I can’t seem to find it.

Kind regards,
Mikael

I did a little search and I found Morph >> globalPointToLocal: aPoint ^self point: aPoint from: nil may be > image eventHandler whenMouseDownDo: [ :event | > self handleMouseDown: event image globa….. > ]. > On 2 Mar 2025, at 22:00, Mikael Svane <mikael.svane@fridhem.org> wrote: > > I have a presenter that is a subclass of SpPresenterWithModel and it contains, among other things, an ImagePresenter with an autoscaling image (a Form). I want to capture mouse clicks on the image and get the coordinate of the click relative to the upper left corner of the Form. > > My #initializePresenter method looks like this: > initializePresenter > image := self newImage > image: self emptyImage; > autoScale: true. > image eventHandler whenMouseDownDo: [ :event | > self handleMouseDown: event]. > > This works, and the #handleMouseDown: method is run whenever the mouse is pressed on the ImagePresenter, but the MouseButtonEvent reports global coordinates and I can’t find out how to convert these to coordinates relative to the Form that the ImagePresenter holds. I have googled and found answers to similar old questions, but nothing that seems to apply to Spec2. > > There must be a very simple solution to this, it’s just that I can’t seem to find it. > > Kind regards, > Mikael
MS
Mikael Svane
Tue, Mar 4, 2025 9:46 PM

Thanks, but unfortunately that doesn’t work.

The object stored in the image variable is an ImagePresenter, not a Morph, so it doesn’t understand globalPointToLocal:. However, the ImagePresenter contains an adapter (an SpMorphicBoxAdapter) which has a variable called widget containing an AlphaImageMorph which must represent the image. But if I send the #globalPointToLocal: message to the AlphaImageMorph instance it just returns the same point that it was given as argument. This must be because Morph>>globalPointToLocal: is implemented as:

Morph>>globalPointToLocal: aPoint

                       ^self point: aPoint from: nil

and:

Morph>>point: aPoint from: aReferenceMorph

                       owner ifNil: [^ aPoint].

                       ^ (owner transformFrom: aReferenceMorph) globalPointToLocal: aPoint

Since these definitions are the only one in any of the Morph subclasses, aReferenceMorph will always be nil for all Morphs and Morph>>point: aPoint from: aReferenceMorph (and Morph>>globalPointToLocal:) will always return the same point that it was given as argument. This seems a bit strange.

After some more research, I found a similar question from 2012 where the #globalPointToLocal: method was apparently working:

http://forum.world.st/Mouse-handler-on-a-morph-td4603302.html

So at the moment I am not sure if #globalPointToLocal: is the intended way of transforming coordinates, perhaps with a bug, or if there is new way of transforming coordinates and this is just old code that has not been removed from the image. At first, I would have guessed that coordinate transformation should have been handled by the different Layouts used, but this doesn’t seem to be the case.

Any further suggestions are very welcome!

Kind regards,

Mikael

Från: sducasseatwork--- via Pharo-users [mailto:pharo-users@lists.pharo.org]
Skickat: den 4 mars 2025 12:37
Till: Any question about pharo is welcome
Kopia: sducasseatwork@mailo.com
Ämne: [Pharo-users] Re: Converting global coordinates from a mouse event

I did a little search and I found

Morph >> globalPointToLocal: aPoint

                  ^self point: aPoint from: nil

may be

image eventHandler whenMouseDownDo: [ :event |

                                                                              self handleMouseDown: event 

                                                                                                                                                                           image globa…..

].

On 2 Mar 2025, at 22:00, Mikael Svane mikael.svane@fridhem.org wrote:

I have a presenter that is a subclass of SpPresenterWithModel and it contains, among other things, an ImagePresenter with an autoscaling image (a Form). I want to capture mouse clicks on the image and get the coordinate of the click relative to the upper left corner of the Form.

My #initializePresenter method looks like this:

initializePresenter

                       image := self newImage

                                                   image: self emptyImage;

                                                   autoScale: true.

                       image eventHandler whenMouseDownDo: [ :event |

                                                                              self handleMouseDown: event].

This works, and the #handleMouseDown: method is run whenever the mouse is pressed on the ImagePresenter, but the MouseButtonEvent reports global coordinates and I can’t find out how to convert these to coordinates relative to the Form that the ImagePresenter holds. I have googled and found answers to similar old questions, but nothing that seems to apply to Spec2.

There must be a very simple solution to this, it’s just that I can’t seem to find it.

Kind regards,

Mikael

Thanks, but unfortunately that doesn’t work. The object stored in the image variable is an ImagePresenter, not a Morph, so it doesn’t understand globalPointToLocal:. However, the ImagePresenter contains an adapter (an SpMorphicBoxAdapter) which has a variable called widget containing an AlphaImageMorph which must represent the image. But if I send the #globalPointToLocal: message to the AlphaImageMorph instance it just returns the same point that it was given as argument. This must be because Morph>>globalPointToLocal: is implemented as: Morph>>globalPointToLocal: aPoint ^self point: aPoint from: nil and: Morph>>point: aPoint from: aReferenceMorph owner ifNil: [^ aPoint]. ^ (owner transformFrom: aReferenceMorph) globalPointToLocal: aPoint Since these definitions are the only one in any of the Morph subclasses, aReferenceMorph will always be nil for all Morphs and Morph>>point: aPoint from: aReferenceMorph (and Morph>>globalPointToLocal:) will always return the same point that it was given as argument. This seems a bit strange. After some more research, I found a similar question from 2012 where the #globalPointToLocal: method was apparently working: http://forum.world.st/Mouse-handler-on-a-morph-td4603302.html So at the moment I am not sure if #globalPointToLocal: is the intended way of transforming coordinates, perhaps with a bug, or if there is new way of transforming coordinates and this is just old code that has not been removed from the image. At first, I would have guessed that coordinate transformation should have been handled by the different Layouts used, but this doesn’t seem to be the case. Any further suggestions are very welcome! Kind regards, Mikael Från: sducasseatwork--- via Pharo-users [mailto:pharo-users@lists.pharo.org] Skickat: den 4 mars 2025 12:37 Till: Any question about pharo is welcome Kopia: sducasseatwork@mailo.com Ämne: [Pharo-users] Re: Converting global coordinates from a mouse event I did a little search and I found Morph >> globalPointToLocal: aPoint ^self point: aPoint from: nil may be image eventHandler whenMouseDownDo: [ :event | self handleMouseDown: event image globa….. ]. On 2 Mar 2025, at 22:00, Mikael Svane <mikael.svane@fridhem.org> wrote: I have a presenter that is a subclass of SpPresenterWithModel and it contains, among other things, an ImagePresenter with an autoscaling image (a Form). I want to capture mouse clicks on the image and get the coordinate of the click relative to the upper left corner of the Form. My #initializePresenter method looks like this: initializePresenter image := self newImage image: self emptyImage; autoScale: true. image eventHandler whenMouseDownDo: [ :event | self handleMouseDown: event]. This works, and the #handleMouseDown: method is run whenever the mouse is pressed on the ImagePresenter, but the MouseButtonEvent reports global coordinates and I can’t find out how to convert these to coordinates relative to the Form that the ImagePresenter holds. I have googled and found answers to similar old questions, but nothing that seems to apply to Spec2. There must be a very simple solution to this, it’s just that I can’t seem to find it. Kind regards, Mikael
RD
Renaud de Villemeur
Wed, Mar 5, 2025 1:13 AM

Hi Mikael

I assume you use spec with the Morphic underlying graphical library.

In your presenter: - anEvent position will give you the event position in the global world coordinate.

  • self adapter widget position. will give you the top left corner underlying Morph position in the global world coordinate.

anEvent position - self adapter widget position should give you the position you're looking for.

Renaud

Mar 3, 2025, 03:17 by mikael.svane@fridhem.org:

I have a presenter that is a subclass of SpPresenterWithModel and it contains, among other things, an ImagePresenter with an autoscaling image (a Form). I want to capture mouse clicks on the image and get the coordinate of the click relative to the upper left corner of the Form.

 

My #initializePresenter method looks like this:

initializePresenter

                           image := self newImage

                                                       image: self emptyImage;

                                                       autoScale: true.

                           image eventHandler whenMouseDownDo: [ :event |

                                                                                  self handleMouseDown: event].

 

This works, and the #handleMouseDown: method is run whenever the mouse is pressed on the ImagePresenter, but the MouseButtonEvent reports global coordinates and I can’t find out how to convert these to coordinates relative to the Form that the ImagePresenter holds. I have googled and found answers to similar old questions, but nothing that seems to apply to Spec2.

 

There must be a very simple solution to this, it’s just that I can’t seem to find it.

 

Kind regards,

Mikael

Hi Mikael I assume you use spec with the Morphic underlying graphical library. In your presenter: - `anEvent position` will give you the event position in the global world coordinate. - `self adapter widget position.` will give you the top left corner underlying Morph position in the global world coordinate. `anEvent position - self adapter widget position` should give you the position you're looking for. Renaud Mar 3, 2025, 03:17 by mikael.svane@fridhem.org: > > I have a presenter that is a subclass of SpPresenterWithModel and it contains, among other things, an ImagePresenter with an autoscaling image (a Form). I want to capture mouse clicks on the image and get the coordinate of the click relative to the upper left corner of the Form. > > >   > > > My #initializePresenter method looks like this: > > > initializePresenter > > >                            image := self newImage > > >                                                        image: self emptyImage; > > >                                                        autoScale: true. > > >                            image eventHandler whenMouseDownDo: [ :event | > > >                                                                                   self handleMouseDown: event]. > > >   > > > This works, and the #handleMouseDown: method is run whenever the mouse is pressed on the ImagePresenter, but the MouseButtonEvent reports global coordinates and I can’t find out how to convert these to coordinates relative to the Form that the ImagePresenter holds. I have googled and found answers to similar old questions, but nothing that seems to apply to Spec2. > > >   > > > There must be a very simple solution to this, it’s just that I can’t seem to find it. > > >   > > > Kind regards, > > > Mikael > >
MS
Mikael Svane
Wed, Mar 5, 2025 9:46 PM

Hi Renaud,

Yes, I use Spec with the Morphic graphical library and with the calculation that you described, I got the correct answer for the coordinates within the Morph representing the image (Form). Because I was using an autoscaling image, I had then to do one more step by scaling the local coordinates according to the scale of the image, but that was very easy.

Thanks!

Kind regards,

Mikael

Från: Renaud de Villemeur via Pharo-users [mailto:pharo-users@lists.pharo.org]
Skickat: den 5 mars 2025 02:13
Till: Any question about pharo is welcome
Kopia: Any question about pharo is welcome; Renaud de Villemeur
Ämne: [Pharo-users] Re: Converting global coordinates from a mouse event

Hi Mikael

I assume you use spec with the Morphic underlying graphical library.

In your presenter:

  • anEvent position will give you the event position in the global world coordinate.

  • self adapter widget position. will give you the top left corner underlying Morph position in the global world coordinate.

anEvent position - self adapter widget position should give you the position you're looking for.

Renaud

Mar 3, 2025, 03:17 by mikael.svane@fridhem.org:

I have a presenter that is a subclass of SpPresenterWithModel and it contains, among other things, an ImagePresenter with an autoscaling image (a Form). I want to capture mouse clicks on the image and get the coordinate of the click relative to the upper left corner of the Form.

My #initializePresenter method looks like this:

initializePresenter

                       image := self newImage

                                                   image: self emptyImage;

                                                   autoScale: true.

                       image eventHandler whenMouseDownDo: [ :event |

                                                                              self handleMouseDown: event].

This works, and the #handleMouseDown: method is run whenever the mouse is pressed on the ImagePresenter, but the MouseButtonEvent reports global coordinates and I can’t find out how to convert these to coordinates relative to the Form that the ImagePresenter holds. I have googled and found answers to similar old questions, but nothing that seems to apply to Spec2.

There must be a very simple solution to this, it’s just that I can’t seem to find it.

Kind regards,

Mikael

Hi Renaud, Yes, I use Spec with the Morphic graphical library and with the calculation that you described, I got the correct answer for the coordinates within the Morph representing the image (Form). Because I was using an autoscaling image, I had then to do one more step by scaling the local coordinates according to the scale of the image, but that was very easy. Thanks! Kind regards, Mikael Från: Renaud de Villemeur via Pharo-users [mailto:pharo-users@lists.pharo.org] Skickat: den 5 mars 2025 02:13 Till: Any question about pharo is welcome Kopia: Any question about pharo is welcome; Renaud de Villemeur Ämne: [Pharo-users] Re: Converting global coordinates from a mouse event Hi Mikael I assume you use spec with the Morphic underlying graphical library. In your presenter: - `anEvent position` will give you the event position in the global world coordinate. - `self adapter widget position.` will give you the top left corner underlying Morph position in the global world coordinate. `anEvent position - self adapter widget position` should give you the position you're looking for. Renaud Mar 3, 2025, 03:17 by mikael.svane@fridhem.org: I have a presenter that is a subclass of SpPresenterWithModel and it contains, among other things, an ImagePresenter with an autoscaling image (a Form). I want to capture mouse clicks on the image and get the coordinate of the click relative to the upper left corner of the Form. My #initializePresenter method looks like this: initializePresenter image := self newImage image: self emptyImage; autoScale: true. image eventHandler whenMouseDownDo: [ :event | self handleMouseDown: event]. This works, and the #handleMouseDown: method is run whenever the mouse is pressed on the ImagePresenter, but the MouseButtonEvent reports global coordinates and I can’t find out how to convert these to coordinates relative to the Form that the ImagePresenter holds. I have googled and found answers to similar old questions, but nothing that seems to apply to Spec2. There must be a very simple solution to this, it’s just that I can’t seem to find it. Kind regards, Mikael