[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