views:

124

answers:

3

I am working through Aaron Hillegass' Cocoa Programming for Mac OS X and am doing the challenge for Chapter 18. Basically, the challenge is to write an app that can draw ovals using your mouse, and then additionally, add saving/loading and undo support. I'm trying to think of a good class design for this app that follows MVC. Here's what I had in mind:

Have a NSView-subclass that represents an oval (say JBOval) that I can use to easily draw an oval. Have a main view (JBDrawingView) that holds JBOvals and draws them.

The thing is that I wasn't sure how to add archiving. Should I archive each JBOval? I think this would work, but archiving an NSView doesn't seem very efficient. Any ideas on a better class design?

Thanks.

A: 

Your JBOval views would each be responsible for drawing themselves (basically drawing an oval path and filling it, within their bounds), but JBDrawingView would be responsible for mousing and dragging (and thereby sizing and positioning the JBOvals, which would be its subviews). The drawingView would do no drawing itself.

So far as archiving, you could either have a model class to represent each oval (such as its bounding rectangle, or any other dimensions you choose to represent each oval with). You could archive and unarchive these models to recreate your views.

Finally, I use the JB prefix too, so … :P at you.

jbrennan
+1  A: 

Having a whole NSView for each oval seems rather heavyweight to me. I would descend them from NSObject instead and just have them draw to the current view.

They could also know how to archive themselves, although at that point you'd probably want to think about pulling them out of the view and thinking of them more as part of your model.

walkytalky
+1  A: 

Have a NSView-subclass that represents an oval (say JBOval) that I can use to easily draw an oval.

That doesn't sound very MVC. “JBOval” sounds like a model class to me.

Have a main view (JBDrawingView) that holds JBOvals and draws them.

I do like this part.

My suggestion is to have each model object (JBOval, etc.) able to create a Bézier path representing itself. The JBDrawingView (and you should come up with a better name for that, as all views draw by definition) should ask each model object for its Bézier path, fill settings, and stroke settings, and draw the object accordingly.

This keeps the knowledge of how to draw (the path, line width, colors, etc.) in the various shape classes where they belong, while also keeping the actual drawing code in the view layer where it belongs.

The answer to where to put archiving code should be intuitively obvious from this point.

Peter Hosey