Logo-small Paint Canvas

Our paint canvas is a Morph instance. As we can not draw directly into a Morph, we use a FormCanvas object to draw into it. When the Morph needs to be updated, the FormCanvas content is copied in the Morph canvas. Our paint canvas comes with two instances, one is a FormCanvas, the other a Color:


Morph subclass: #PaintCanvas
instanceVariableNames: 'area paintingColor'
classVariableNames: ''
poolDictionaries: ''
category: 'PharoCollaborActiveBook-GUI'

The area instance is initialized as a FormCanvas, with a default size identical to the Morph extent:

^ area ifNil: [
area := FormCanvas extent: self extent.
self clear.

It is filled with white color:

self area fillColor: Color white.
self changed

Update operation

The #changed message informs the morph something changed and redrawing is necessary. The drawing itself only consists to copy the area content in the rendering Morph canvas:

drawOn: aCanvas
aCanvas drawImage: self area form at: self position

Now you should remember the announcement we added in our main application window (if no, read the previous section about the Painter). This announcement states the message #extent: is sent to our Paint Canvas at WindowResize announcement. Now we need to override the #extent: method here:

extent: aPoint
| newArea |
super extent: aPoint.
newArea := FormCanvas extent: aPoint.
fillColor: Color white;
drawImage: self area form at: 0@0.
area := newArea

Here, we just create a FormCanvas matching the new window extent, then we copy the content of the old FormCanvas in the new one.

Mouse handling and drawing operation

To effectively paint we need to handle mouse operations. First we inform we want to handle the mouse down event whatever the clicked button:

handlesMouseDown: evt
^ true

Then when the mouse is moved, we paint in our FormCanvas:

mouseMove: anEvent
   self area 
fillOval: (Rectangle
center: anEvent cursorPoint - self position
extent: 4@4)
color: self paintingColor.
self changed.

User Contributed Notes

hilaire.fernandes (13 June 2010, 3:14 am)

Take a look at Morph>>invalidRect: as opposed to #changed for more optimal screen updates if required

Add a Note
