I have a Form where I change pixel colours using Form>>pixelValueAt:put:.
The Form exists inside an SpImagePresenter. After having changed the pixels,
I want to redraw the Form in an #updatePresenters method to show the
changes, but I haven't been able to figure out how to do this. If I inspect
the Form it is clear that the pixels have been changed, so the problem is in
the #updatePresenters mwthod. I have tried different variations on this
theme without success:
updatePresenter
| canvas |
"Get the canvas of the Form:"
canvas := imagePresenter image form getCanvas.
adapter widget drawSubmorphsOn: canvas
Any suggestions would be very welcome.
Kind regards,
Mikael
Hi Mikael
If my understanding is correct, you're using SpImagePresenter to display a Form.
You then have made some changes to the Form and you want to show its new face.
Why don't you set the image again in your presenter ?
Something like image image: yourUpdatedForm
.
You can even update the Form of your presenter directly like:
image image: (image image pixelValueAt: 10@10 put: (image image pixelValueFor: Color red))
image being an instance of SpImagePresenter.
Renaud
Mar 7, 2025, 13:53 by mikael.svane@fridhem.org:
I have a Form where I change pixel colours using Form>>pixelValueAt:put:. The Form exists inside an SpImagePresenter. After having changed the pixels, I want to redraw the Form in an #updatePresenters method to show the changes, but I haven’t been able to figure out how to do this. If I inspect the Form it is clear that the pixels have been changed, so the problem is in the #updatePresenters mwthod. I have tried different variations on this theme without success:
updatePresenter
| canvas |
“Get the canvas of the Form:”
canvas := imagePresenter image form getCanvas.
adapter widget drawSubmorphsOn: canvas
Any suggestions would be very welcome.
Kind regards,
Mikael
Hi Mikael
I do not know the answer so I tried to find it.
Indeed the superclass>>updatePresenter is empty :(
Let us see what esteban will reply.
Now I tried to check the morphic back end.
Now writing directly on the canvas this way does not look the right way.
Did you try with
SpMorphPresenter
or
SpRoassalPresenter because you have access to the cairo canvas.
While browsing the code of the SpMorphicROassalAdapter I saw
widget sessionChanged.
SpAbstractMorphicAdapter I saw changed.
changed
^ self widgetDo: [ :w | w changed ]
I also saw in SpAbstractAdapter isRedrawable so I wonder if it should not be true on the Adapter corresponding to the SpImagePresenter (if any)
BTW the SpMorphicAthensAdapter defines a method redraw (Athens is the cairo wrapper used also in Roassal)
Reading the code of SpMorphicImageAdapter >> buildWidget
| alphaImage |
alphaImage := AlphaImageMorph new.
alphaImage model: self.
alphaImage
getImageSelector: #getImage;
vResizing: #spaceFill;
hResizing: #spaceFill;
layout: self layoutValue;
dragEnabled: self dragEnabled;
dropEnabled: self dropEnabled;
setBalloonText: self help;
update: #getImage.
self model
whenImageChangeDo: [
alphaImage image:
(self getImage ifNil: [ Form extent: 1 @ 1 depth: 32 ]) ];
whenAutoScaleChangeDo: [ widget layout: self layoutValue ].
^ alphaImage
It feels like we should reassign the image:
Did you try something like
updatePresenter
self image: self image?
On 7 Mar 2025, at 18:11, Mikael Svane mikael.svane@fridhem.org wrote:
I have a Form where I change pixel colours using Form>>pixelValueAt:put:. The Form exists inside an SpImagePresenter. After having changed the pixels, I want to redraw the Form in an #updatePresenters method to show the changes, but I haven’t been able to figure out how to do this. If I inspect the Form it is clear that the pixels have been changed, so the problem is in the #updatePresenters mwthod. I have tried different variations on this theme without success:
updatePresenter
| canvas |
“Get the canvas of the Form:”
canvas := imagePresenter image form getCanvas.
adapter widget drawSubmorphsOn: canvas
Any suggestions would be very welcome.
Kind regards,
Mikael
Hi,
This is a corner case that is not considered in Spec design: In fact
what you are doing is changing the content of the model and you need the
presenter to react to it.
Indeed, as Stef says the solution is to re-set the image to the image
presenter when performing the change:
myPresenter image: modifiedForm.
You may think something like that should be done in the
updatePresenter
message (but updatePresenter does not has a mean in
"widget" presenters).... or like the refresh
message for lists/tables,
and you would be right (I will add a refresh message to
SpImagePresenter). But at the end, it will end up doing exactly that, so
you are safe workaround it the thing :)
Esteban
On 3/8/25 21:03, sducasseatwork--- via Pharo-users wrote:
Hi Mikael
I do not know the answer so I tried to find it.
Indeed the superclass>>updatePresenter is empty :(
Let us see what esteban will reply.
Now I tried to check the morphic back end.
Now writing directly on the canvas this way does not look the right way.
Did you try with
SpMorphPresenter
or
SpRoassalPresenter because you have access to the cairo canvas.
While browsing the code of the SpMorphicROassalAdapter I saw
widget sessionChanged.
SpAbstractMorphicAdapter I saw changed.
changed
^ self widgetDo: [ :w | w changed ]
I also saw in SpAbstractAdapter isRedrawable so I wonder if it should
not be true on the Adapter corresponding to the SpImagePresenter (if any)
BTW the SpMorphicAthensAdapter defines a method redraw (Athens is the
cairo wrapper used also in Roassal)
Reading the code of SpMorphicImageAdapter >> buildWidget
| alphaImage |
alphaImage := AlphaImageMorph new.
alphaImage model: self.
alphaImage
getImageSelector: #getImage;
vResizing: #spaceFill;
hResizing: #spaceFill;
layout: self layoutValue;
dragEnabled: self dragEnabled;
dropEnabled: self dropEnabled;
setBalloonText: self help;
update: #getImage.
self model
whenImageChangeDo: [
alphaImage image:
(self getImage ifNil: [ Form extent: 1 @ 1 depth: 32 ]) ];
whenAutoScaleChangeDo: [ widget layout: self layoutValue ].
^ alphaImage
It feels like we should reassign the image:
Did you try something like
updatePresenter
self image: self image?
On 7 Mar 2025, at 18:11, Mikael Svane mikael.svane@fridhem.org wrote:
I have a Form where I change pixel colours using
Form>>pixelValueAt:put:. The Form exists inside an SpImagePresenter.
After having changed the pixels, I want to redraw the Form in an
#updatePresenters method to show the changes, but I haven’t been able
to figure out how to do this. If I inspect the Form it is clear that
the pixels have been changed, so the problem is in the
#updatePresenters mwthod. I have tried different variations on this
theme without success:
updatePresenter
| canvas |
“Get the canvas of the Form:”
canvas := imagePresenter image form getCanvas.
adapter widget drawSubmorphsOn: canvas
Any suggestions would be very welcome.
Kind regards,
Mikael