[Drawkit] Zoom to bounding box

Graham Cox graham.cox at bigpond.com
Thu Apr 2 23:04:21 PDT 2009


On 03/04/2009, at 4:05 PM, Michael Caron wrote:

> I did see in GCZoomView that there was something called  
> "ZoomToRect". It didn't work as I expected it to, however. I'm  
> loading a document from an archived state and when I try to look for  
> the current drawing view from the DKDrawingView class method  
> "currentlyDrawingView", I get a nil back. How does one get the  
> current view so that I can do one of these ZoomToRect calls?

+currentlyDrawingView is used to obtain the view that's currently  
performing drawing - i.e. processing an update. It's only valid within  
a drawing method called from the view's -drawRect: method, and even  
then there are usually better ways to get the view (it's typically  
passed to all higher-level drawing methods). So I think that's a red- 
herring for you here.

How you obtain the view itself as a ready object will depend on your  
app architecture. Some apps will open multiple windows onto the same  
drawing, or have a splitter with different views of the drawing, or  
have multiple documents open at once. DrawKit makes no assumptions  
along these lines, so it leaves some of the high-level wiring-up to  
you. For example, a typical document based app that only has one view  
per document might just declare an IBOutlet to the main view in the  
document object and leave it to you to wire up in IB.  
DKDrawingDocument takes this approach for example (and returns the  
view from its -mainView method).

Where possible, use some form of the above to locate the view. Since  
you set up and manage it, it can be however makes the most sense for  
you. Alternatively, but not recommended, you can discover which views  
are ultimately associated with a given DKDrawing by iterating the  
array returned by the -controllers method, and asking each controller  
for its view. Note that the link between a drawing and a view is not  
magic - you forge that connection - unless you're using the automatic  
drawing creation methodology. Even in that case you would still  
typically have an outlet to the view that you can access from a  
suitable place.

> In the end I just decided to crop the drawing to the shape. I'm new  
> to the framework, so my implementation is probably a bit crude. I  
> keep an array of the drawable objects in my drawing so that I can  
> translate them to new coordinates after resizing the drawing to the  
> size of the bounding box. To translate all the objects, I just used  
> the -(void) DKDrawableObject offsetLocationByX:byY: method.

OK, this is a completely different thing to just displaying the  
drawing at some scale - this actually changes the content of the data  
model. Are you sure this is what you want? If so, then using the - 
offsetLocationByX:byY: is fine to move the objects, but it won't  
change their size. You can change an object's individual size using  
its -setSize: method, but for scaling multiple objects to fit some  
particular size this would be a lot of work, since each object has its  
own reference point that you'd need to compensate for the scale.  
Working so hard is a sure sign of not really working with the framework.

> I had tried to use the AffineTransforms, but they didn't appear to  
> do anything. Is there a special way to use those? After you apply a  
> transform to all objects in a layer, is there something else you  
> have to do?

It's not clear which affine transforms you are referring to.  
Transforms are used extensively in DK and in many cases in quite  
subtle ways. Without properly understanding them it's likely you'll  
end up with a broken mess. There is a method of DKObjectOwnerLayer  
that might help you here -applyTransformToObjects: which calls each  
object's -applyTransform: method with the transform you supply. This  
allows you to offset and scale all objects in a layer en masse (or  
rotate all objects around a common point), but you still have to know  
what you're doing with transforms to use it effectively. The Cocoa  
Drawing Guide has some info on the topic, as do most texts on computer  
graphics. To experiment, you could start with a simple transform that  
does a linear translation which should show you the objects shifting  
position. There's nothing special you need to do after calling the  
method - the views should update automatically.

For now I'd definitely recommend steering clear of methods that return  
transforms - don't override them to return something different without  
intimate knowledge of how they are used. Even I run afoul of that from  
time to time and I wrote it ;-)

--Graham




More information about the Drawkit mailing list