/*
**      Newton Developer Technical Support Sample Code
**
**      Thumbnail-1, Shows how to use clRemoteView with a "live" clEditView
**
**      by Bob Ebert, Newton Developer Technical Support
**
**      Copyright © 1995 by Apple Computer, Inc.  All rights reserved.
**
**      You may incorporate this sample code into your applications without
**      restriction.  This sample code has been provided "AS IS" and the
**      responsibility for its operation is 100% yours.  You are not
**      permitted to modify and redistribute the source as "DTS Sample Code."
**      If you are going to re-distribute the source, we require that you
**      make it clear in the source that the code was descended from
**      Apple-provided sample code, but that you've made changes.
*/

This sample illustrates several useful things.

1) how to use a clRemoteView to do scaling.
2) how to hook a clRemoteView up to a clEditView (which takes extra work)
3) RecToggle, Status Bar buttons, Hardware Independent Sizing, etc.

HOW TO USE A CLREMOTEVIEW TO DO SCALING

clRemoteView is a very special purpose view class.  It draws its first
child view with that child's visible area scaled to fit exactly within the
remote view's visible area.  In the current release (1.3 as of this
sample), clRemoteViews can only be used to shrink their children, they
cannot be used to magnify.

clRemoteView works by setting up an internal transformation when the view
is opened, based on the child view's coordinates and it's coordinates. 
This transform is used when drawing the view's children, which results in
scaling.

Because clRemoteView bases its transform on the first child, and draws
only the first child, errors result if you try to give a clRemoteView more
than one (or less than one) child.  Lemma: clRemoteViews must have exactly
one child.

Because clRemoteView only sets up this transform information when it is
first opened, moving the view or its children causes strange results. 
Lemma:  Whenever you move a clRemoteView on the screen, you must close and
re-open it or it will not draw properly.

(If you'd like to experiment with "improper" drawing, try commenting out
the lines that close and re-open theRemoteView inside theFloater's
viewClickScript, and comment in the line that has theRemoteView:Dirty)

That's all there is to using a clRemoteView.  Give it a child and open it.


HOW TO HOOK A REMOTE VIEW UP TO AN EDIT VIEW

A common thing to want to do is to set up the contents of a clRemoteView
at run-time, possibly based on the contents of some other view, like a
clEditView.  Print Preview, for example, uses a clRemoteView with a print
format child to show a thumbnail view of the printed page.

A common clRemoteView-related mis-conception is that you can "point" the
remote view at another view, that is, put some other view in the remote
view's viewChildren or stepChildren slot, and it will scale that other
view into itself.  This is false.  Just like any other view class, a
clRemoteView creates its children when it is opened, and closes them when
it is closed.  If you try to put a view frame (as opposed to a template)
in the viewChildren or stepChildren slot of a remote view, you'll get bus
errors and other nasty view system exceptions.  Don't do this.  (For
further reading on views vs templates, I highly recommend the article
"Tales from the View System")

Recall that clEditViews work by creating new clParagraph and clPolygon
view children to hold the text, shapes, and ink that users create.  You
can get templates for these dynamically-created children by looking the
'viewChildren slot of the clEditView.

To make a clRemoteView reflect a "live" clEditView, we share the templates
between the edit and the remote view.  That is, when we open the remote
view, we set it's child's viewChildren slot to the same array that is in
the clEditView's viewChildren frame. Normally this could prevent quite a
problem, but clRemoteViews are "read only" and so we don't need to worry
about both views trying to update the same array.

If you look at theRemoteView's viewSetupChildrenScript, you'll see how
this is done. The remote view's child is a clView with the viewFormat,
viewLineSpacing, and viewChildren slots copied from the (open) clEditView.
 This is all OK.

But it's actually more complicated than that, because of a clRemoteView
bug.  To explain the bug, I need to describe a view system optimization. 
clParagraphViews are expensive, and so the view system attempts to avoid
drawing them when they are not visible.  To figure out if a view is
visible, the current system looks at the bounds of the view's parent and
the view's grandparent.  (Only two layers are looked at--another
optimization.) If the paragraph view is not within the bounds of its
parent or grandparent, it is not displayed.

Unfortunately, the clRemoteView's bounds are usually significantly smaller
than the bounds of it's child.  It must be that way for scaling to happen.
 The view system optimization that prevents drawing "clipped" views
doesn't take into account the transformation that clRemoteViews add, and
so text views inside the clRemoteView's "scaling" child may not show up.

To fix up this little optimization (which really helps most places) we
have to add two new layers between the remote view and the "scaling"
child.  These wrapper views provide a parent and a grandparent to the
scaling child, which fools the view system into thinking that all the
children of the scaling view really are visible, and so they're drawn,
scaled, into the clRemoteView.

(Without this, the text children only show up if they're in the upper
left-hand corner of the scaling child.  You can experiment with this
behavior by commenting out one (or both) of the "wrapper" children in
theRemoteView's viewSetupChildrenScript.)

These "wrapper" views aren't used for anything else, they're just there to
fool the view system optimizer, and so it's best to make them as
"lightweight" as possible. Plain old clViews with minimal formatting work
well.


RECTOGGLE, STATUS BAR BUTTONS, HARDWARE INDEPENDENT SIZING, ETC.

The sample attempts to follow all known style guidelines.  So the edit view
uses vAnythingAllowed, and we provide a protoRecToggle inside the status
bar.  Similarly the "Thumbnail" button is sibling-justified to the close
box.  Finally the main app's viewSetupFormScript takes into account the
varying sizes and does the right thing.
