Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
CodeWarrior (OS 9)/ZoomRecter.c
/* |
File: ZoomRecter.c |
Contains: This snippet shows how to do "Finder" style zooming between two rectangles. |
The boolean flag "kZoomLarger" controls the proportional direction of the |
zooming. |
To get the two rectangles, you drag them out rubberbanded, and the zoom |
occurs between them. To quit, click the close box. |
If you want to do zooms between windows, open up a port with the dimensions |
of the desktop (from GetGrayRgn()). |
DON'T use this as a sample of how to do rubberband drawing!!! It's sort of |
hacked together bypassing the event mechanism and just using Button(). |
Written by: SF |
Copyright: Copyright © 1992-1999 by Apple Computer, Inc., All Rights Reserved. |
You may incorporate this Apple sample source code into your program(s) without |
restriction. This Apple sample source code has been provided "AS IS" and the |
responsibility for its operation is yours. You are not permitted to redistribute |
this Apple sample source code as "Apple sample source code" after having made |
changes. If you're going to re-distribute the source, we require that you make |
it clear in the source that the code was descended from Apple sample source |
code, but that you've made changes. |
Change History (most recent first): |
08/2000 JM Carbonized, non-Carbon code is commented out |
for demonstration purposes. Changed basic code |
significantly so it would simply work better..... |
7/14/1999 KG Updated for Metrowerks Codewarror Pro 2.1 |
*/ |
#include "CarbonPrefix.h" |
#include <Dialogs.h> |
#include <Fonts.h> |
#define kNumSteps 14 |
#define kRectsVisible 4 |
#define kZoomRatio .7 |
#define kDelayTicks 1 |
#define kZoomLarger true // change this to zoom "inward" |
void InitStuff(void); |
void ZoomRect(Boolean zoomOut,Rect *smallRect, Rect *bigRect); |
void CalcRect(Rect *theRect,Rect *smallRect,Rect *bigRect,double stepValue); |
//Boolean GetRects(Rect *zoomFrom,Rect *zoomTo); |
void FixRect(Rect *theRect,Rect *rightRect); |
void doEventLoop(); |
void GetRect(Rect *zoomFrom, Rect *zoomTo); |
Boolean gDone = false; |
WindowPtr gWindow; |
void main(void) |
{ |
Rect bounds = {44,12,330,500}/*,zoomFrom,zoomTo*/; |
//Rect tempRect1; //used for carbonization |
InitStuff(); |
gWindow = NewWindow(nil,&bounds,"\pDrag Two Rects to Zoom",true,documentProc,(WindowPtr)-1L,true,0); |
//SetPort(window); |
SetPortWindowPort(gWindow); |
/*do { |
if (GetRects(&zoomFrom,&zoomTo)) |
ZoomRect(kZoomLarger,&zoomFrom,&zoomTo); |
//EraseRect(&window->portRect); |
EraseRect(GetPortBounds(GetWindowPort(window), &tempRect1)); |
} |
while (!gDone);*/ |
doEventLoop(); |
FlushEvents(everyEvent,0); |
} |
void InitStuff(void) |
{ |
//InitGraf(&qd.thePort); |
//InitFonts(); |
//InitWindows(); |
//InitMenus(); |
//TEInit(); |
//InitDialogs(nil); |
InitCursor(); |
FlushEvents(everyEvent,0); |
} |
void ZoomRect(Boolean zoomLarger,Rect *smallRect, Rect *bigRect) |
{ |
double firstStep,stepValue,trailer,zoomRatio; |
short i,step; |
Rect curRect; |
unsigned long ticks; |
Pattern grayPattern; //used in carbonization |
RgnHandle rgnHandle = NewRgn(); |
GrafPtr oldPort; |
Rect tempRect1; |
GetPort(&oldPort); |
SetPort(GetWindowPort(gWindow)); |
//PenPat(&qd.gray); |
PenPat(GetQDGlobalsGray(&grayPattern)); |
PenMode(patXor); |
firstStep=kZoomRatio; |
for (i=0; i<kNumSteps; i++) { |
firstStep *= kZoomRatio; |
} |
if (!zoomLarger) { |
zoomRatio = 1.0/kZoomRatio; |
firstStep = 1.0-firstStep; |
} |
else |
zoomRatio = kZoomRatio; |
trailer = firstStep; |
stepValue = firstStep; |
for (step=0; step<(kNumSteps+kRectsVisible); step++) { |
// draw new frame |
if (step<kNumSteps) { |
stepValue /= zoomRatio; |
CalcRect(&curRect,smallRect,bigRect,stepValue); |
FrameRect(&curRect); |
} |
// erase old frame |
if (step>=kRectsVisible) { |
trailer /= zoomRatio; |
CalcRect(&curRect,smallRect,bigRect,trailer); |
FrameRect(&curRect); |
} |
QDFlushPortBuffer(GetWindowPort(gWindow), GetPortVisibleRegion(GetWindowPort(gWindow), rgnHandle)); |
Delay(kDelayTicks,&ticks); |
} |
PenNormal(); |
DisposeRgn(rgnHandle); |
smallRect->top = bigRect->top = -1; |
EraseRect(GetPortBounds(GetWindowPort(gWindow), &tempRect1)); |
SetPort(oldPort); |
} |
void CalcRect(Rect *theRect,Rect *smallRect,Rect *bigRect,double stepValue) |
{ |
theRect->left = smallRect->left + (short)((double)(bigRect->left-smallRect->left)*stepValue); |
theRect->top = smallRect->top + (short)((double)(bigRect->top-smallRect->top)*stepValue); |
theRect->right = smallRect->right + (short)((double)(bigRect->right-smallRect->right)*stepValue); |
theRect->bottom = smallRect->bottom + (short)((double)(bigRect->bottom-smallRect->bottom)*stepValue); |
} |
// Old version, would require that you drag 2 rects before letting the event loop continue |
/*Boolean GetRects(Rect *zoomFrom,Rect *zoomTo) |
{ |
short numRects = 0; |
//EventRecord ev; |
Rect theRect,drawRect; |
Point firstPt,curPt,oldPt,globalPt; |
//KeyMap theKeys; |
WindowPtr window; |
Boolean result = true; |
RgnHandle rgnHandle = NewRgn(); |
PenMode(patXor); |
do { |
while (!Button()) { |
GetMouse(&globalPt); |
LocalToGlobal(&globalPt); |
if ((FindWindow(globalPt,&window)==inGoAway) && window==FrontWindow()) { |
gDone = true; |
result = false; |
} |
GetMouse(&firstPt); |
oldPt = firstPt; |
SetRect(&theRect,firstPt.h,firstPt.v,firstPt.h,firstPt.v); |
} |
if (gDone) |
break; |
while (Button()) { |
GetMouse(&curPt); |
if (!EqualPt(curPt,oldPt)) { |
FixRect(&theRect,&drawRect); |
FrameRect(&drawRect); |
oldPt = curPt; |
theRect.right = curPt.h; |
theRect.bottom = curPt.v; |
FixRect(&theRect,&drawRect); |
FrameRect(&drawRect); |
} |
} |
FixRect(&theRect,&drawRect); |
if (numRects==0) |
*zoomFrom = drawRect; |
else |
*zoomTo = drawRect; |
numRects++; |
QDFlushPortBuffer(GetWindowPort(window), GetPortVisibleRegion(GetWindowPort(window), rgnHandle)); |
} while (numRects<2); |
PenNormal(); |
DisposeRgn(rgnHandle); |
return result; |
}*/ |
// New Version of GetRect(s), modified from original to only handle one dragged rect at a time. |
void GetRect(Rect *zoomFrom, Rect *zoomTo) |
{ |
static short numRects = 0; |
Rect theRect,drawRect; |
Point firstPt,curPt,oldPt; |
RgnHandle rgnHandle = NewRgn(); |
GrafPtr oldPort; |
GetPort(&oldPort); |
SetPort(GetWindowPort(gWindow)); |
PenMode(patXor); |
GetMouse(&firstPt); |
oldPt = firstPt; |
SetRect(&theRect,firstPt.h,firstPt.v,firstPt.h,firstPt.v); |
while (Button()) { |
GetMouse(&curPt); |
if (!EqualPt(curPt,oldPt)) { |
FixRect(&theRect,&drawRect); |
FrameRect(&drawRect); |
oldPt = curPt; |
theRect.right = curPt.h; |
theRect.bottom = curPt.v; |
FixRect(&theRect,&drawRect); |
FrameRect(&drawRect); |
QDFlushPortBuffer(GetWindowPort(gWindow), GetPortVisibleRegion(GetWindowPort(gWindow), rgnHandle)); |
} |
} |
FixRect(&theRect,&drawRect); |
if (numRects==0) |
*zoomFrom = drawRect; |
else |
*zoomTo = drawRect; |
numRects++; |
QDFlushPortBuffer(GetWindowPort(gWindow), GetPortVisibleRegion(GetWindowPort(gWindow), rgnHandle)); |
if (numRects >= 2) { |
ZoomRect(kZoomLarger, zoomFrom, zoomTo); |
numRects = 0; |
} |
PenNormal(); |
DisposeRgn(rgnHandle); |
SetPort(oldPort); |
} |
void FixRect(Rect *theRect,Rect *rightRect) |
{ |
if (theRect->right > theRect->left) { |
rightRect->right = theRect->right; |
rightRect->left = theRect->left; |
} |
else { |
rightRect->right = theRect->left; |
rightRect->left = theRect->right; |
} |
if (theRect->bottom > theRect->top) { |
rightRect->bottom = theRect->bottom; |
rightRect->top = theRect->top; |
} |
else { |
rightRect->bottom = theRect->top; |
rightRect->top = theRect->bottom; |
} |
} |
void doEventLoop() |
{ |
EventRecord anEvent; |
WindowPtr evtWind; |
short clickArea; |
Rect screenRect; |
Point thePoint; |
Rect zoomFrom, zoomTo; |
zoomFrom.top = zoomTo.top = -1; |
while (!gDone) |
{ |
if (WaitNextEvent( everyEvent, &anEvent, 0, nil )) |
{ |
if (anEvent.what == mouseDown) |
{ |
clickArea = FindWindow( anEvent.where, &evtWind ); |
if (clickArea == inDrag) |
{ |
GetRegionBounds( GetGrayRgn(), &screenRect ); |
DragWindow( evtWind, anEvent.where, &screenRect ); |
} |
else if (clickArea == inContent) |
{ |
if (evtWind != FrontWindow()) |
SelectWindow( evtWind ); |
else |
{ |
thePoint = anEvent.where; |
GlobalToLocal( &thePoint ); |
//Handle click in window content here |
GetRect(&zoomFrom, &zoomTo); |
} |
} |
else if (clickArea == inGoAway) |
if (TrackGoAway( evtWind, anEvent.where )) |
gDone = true; |
} |
else if (anEvent.what == updateEvt) |
{ |
evtWind = (WindowPtr)anEvent.message; |
SetPortWindowPort( evtWind ); |
BeginUpdate( evtWind ); |
//Call Draw Function here.... |
if (zoomFrom.top != -1) |
FrameRect(&zoomFrom); |
if (zoomTo.top != -1) |
FrameRect(&zoomTo); |
EndUpdate (evtWind); |
} |
} |
} |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-10-10