| Modifying a Program | Lesson 13 | Contents |
| We're going to add another class. This one, however, will be a subclass of Rect because our goal is to produce an object that draws a rounded rectangle. A rounded rectangle requires the same parameters as a rectangle with the addition of one more, the size of the ovals whose curvature rounds the corners. The oval's dimensions are determined by the number of pixels high and wide: |
| The Toolbox call, FrameRoundRect, expects these dimensions as two integers (2-byte values). Note that, while we pass the address of the Rect data (as for FrameRect), we pass the actual values for width and height (see Part II for more discussion of supplying parameters to Toolbox routines). Note also that we do not choose how to pass data; the Toolbox dictates those choices. We can conveniently store the oval's dimensions in a class-Point instance variable, or ivar. |
Since a rounded rectangle has so much in common with an ordinary rectangle (i.e., objects created by class Rect), the logical approach would be a subclass of class Rect called, say, class RndRect. It needs only the one additional ivar which we will name Ovalsize. By virtue of its inheritance from class Rect then, an object of class RndRect will have a total of three ivars: TopLeft, BotRight, and Ovalsize. TopLeft and BotRight refer to the corners the RndRect would have if it wasn't rounded— that is, the intersection points of the lines on which the sides lie. These points, of course, will actually lie outside the rounded corners.
Next, the class needs a method to store the oval values its object instances receive. The Ovalsize value for this class are stored by means of an INIT: method in the subclass RndRect. The values for the coordinate points (TopLeft and BotRight) can be initialized just like the points in class Rect, because the Put: method from class Rect is still available to an object of subclass RndRect. We will simply define the new ivar for RndRect that stores the oval values, and pass the burden of coordinate storage back onto the Put: method in its superclass.
Finally, the subclass RndRect needs a draw: method to act on the values stored in an object created from its own class. In this particular draw: method, ^base retrieves the "base" address of the current object, i.e. the address of the beginning of the object. In this case it is the address of the rectangle coordinates. The Toolbox uses this address to locate the values it uses as parameters. Next, the Ovalsize values are put on the stack in a form the Toolbox expects (using the int: method of class Point), and then the proper Macintosh Toolbox routine (FrameRoundRect) is called to do the actual drawing on the screen.
The subclass definition looks like this:
:class RNDRECT super{ rect }
point OvalSize
:m INIT: ( w h -- ) put: OvalSize ;m
:m DRAW: ( -- ) ^base get: Ovalsize FrameRoundRect ;m
;class
That's all that was needed to add an entirely new kind of object to Mops.
Once the class is defined, it is now ready for the creation of an object like:
RndRect Cynthia
To draw this object in a window ww, as we did in the previous lesson, you can do this (using either interactive entry in the Mops editing window or by inclusion in a source file with QuickEdit):
20 30 init: Cynthia 20 20 100 60 put: Cynthia window ww test: ww draw: Cynthia
|
The 20 and 30 values are the width and height of the oval in the rounded corners. The PUT: method is inherited from the superclass Rect, and sets the rectangle coordinate.
Observe how the addition of this subclass works within the structure of the overall program. |
|
Next, you'll be introduced to the powerful building blocks of Mops: the predefined classes.
| Previous Chapter | Contents | Next Chapter |
|---|---|---|
| ⇧ | ||
| This page online: http://PowerMops.com/MopsManual/Lessons/Chapter13.html | ||