// frame.c // // This file implements a window type for the Common library // // by John D. de Boer #include "common.h" #include "cstring.h" #include "cyber.h" #include "disk.h" #include "frame.h" ToolboxObjectClassRef TDOCR = NULL; // reference for tape-deck control definition function, when it is present windprocptr NoWindAdjust; // call-back for menu adjustment when there are no windows open comdprocptr NoWindComd; // call-back for command IDs when there are no windows open static int WINDS; // the number of existing (not necessarily visible) windows static window ***WindList; // the windows static Handle NoWindMenus; // menubar to be display when no windows are open static voidprocptr NoWindSetup; // call-back for menu set-up when there are no windows open // Initialisation void initframe(void) { WINDS=0; WindList=(window ***)handle(0); NoWindMenus=NULL; NoWindSetup=NULL; NoWindAdjust=NULL; NoWindComd=NULL; } // Drawing with frame.c windows void initquartzcontext(CGContextRef Q, CGColorSpaceRef Space) { colour C; if (!Q) return; CGContextSetFillColorSpace(Q,Space); CGContextSetStrokeColorSpace(Q,Space); CGContextSelectFont(Q,"Geneva",11.0,kCGEncodingMacRoman); CGContextSetTextDrawingMode(Q,kCGTextFill); setcolour(&C,black); CGContextSetStrokeColor(Q,C.c); setcolour(&C,white); CGContextSetFillColor(Q,C.c); } static void initquartz(window *W) { CGrafPtr GP; WindowRef WP; OSStatus err; if (!W || W->q2d) return; WP=W->wmw; if (!WP) return; GP=GetWindowPort(WP); err=QDBeginCGContext(GP,&(W->q2d)); if (err!=noErr) halt(cat(2,"initquartz() error msg #",fig(err))); initquartzcontext(W->q2d,W->cs); W->inq=0; } static void oldquartz(window *W) { CGrafPtr GP; WindowRef WP; OSStatus err; if (!W || !W->q2d) return; WP=W->wmw; if (!WP) return; CGContextSynchronize(W->q2d);//nec? GP=GetWindowPort(WP); err=QDEndCGContext(GP,&(W->q2d)); W->q2d=NULL; } static void calcpage(window *W) { WindowRef WP; CGrafPtr GP; if (!W) return; WP=W->wmw; if (!WP) return; GP=GetWindowPort(WP); GetPortBounds(GP,&(W->qdpage)); if (W->vsb) W->qdpage.right -=W->thickness; if (W->hsb) W->qdpage.bottom-=W->thickness; cgrect(&(W->qdpage),&(W->page)); } static void beginquartz(window *W) { colour C; if (!W) return; if (!W->q2d) halt("beginquartz() error #1"); if (W->inq) halt("beginquartz() error #2"); CGContextSaveGState(W->q2d); if (W->hsb) CGContextTranslateCTM(W->q2d,0.0,W->thickness); cgrect(&(W->qdpage),&(W->page)); setcolour(&C,white); CGContextSetFillColor(W->q2d,C.c); if (W->erase) CGContextFillRect(W->q2d,W->page); CGContextClipToRect(W->q2d,W->page); W->inq=1; } static void endquartz(window *W) { if (!W || !W->q2d) return; if (!W->inq) halt("endquartz() error #1"); CGContextSynchronize(W->q2d);//nec? CGContextRestoreGState(W->q2d); W->inq=0; } void redraw(window *W) { if (!W || !W->draw) return; beginquartz(W); W->draw(W); endquartz(W); } void controlaction(window *W) { windprocptr SD; if (!W) return; SD=W->draw; W->draw=W->action; redraw(W); W->draw=SD; } // The control manager for frame.c void setcontrolwidth(window *W, int WIDTH) { // what app uses this? if (WIDTH>10) W->thickness=WIDTH; } void enablecontrol(ControlRef C, bool Enabled) { // not used? if (!C) return; HiliteControl(C,Enabled ? 0 : 255); } void setscrollbar(ControlRef C, int VAL, int MIN, int MAX) { if (!C) return; if (MAX=MAX) return 0.5; return (GetControlValue(C) - MIN) / (float)(MAX - MIN); } void setscrollfrac(ControlRef C, int MIN, int MAX) { int VAL; float Frac; if (!C) return; if (MAXleft,R->top); SizeControl(C,rectwidth(R),rectheight(R)); } void sizevertscroll(ControlRef C, int THICK) { WindowRef WP; CGrafPtr GP; Rect R; if (!C) return; WP=GetControlOwner(C); if (!WP) return; GP=GetWindowPort(WP); GetPortBounds(GP,&R); SizeControl(C,THICK + 1,rectheight(&R) - THICK + 2); MoveControl(C,R.right - THICK,R.top - 1); } void sizehorzscroll(ControlRef C, int THICK, int LEFTSPACE, bool Grow) { WindowRef WP; CGrafPtr GP; Rect R; int WIDTH; if (!C) return; WP=GetControlOwner(C); if (!WP) return; GP=GetWindowPort(WP); GetPortBounds(GP,&R); WIDTH= rectwidth(&R) - LEFTSPACE + 2 - (Grow ? THICK : 0); SizeControl(C,WIDTH,THICK + 1); MoveControl(C,R.left - 1 + LEFTSPACE,R.bottom - THICK); } void sizescrolls(window *W) { if (!W || !W->wmw) return; calcpage(W); if (W->vsb) sizevertscroll(W->vsb,W->thickness); if (W->hsb) sizehorzscroll(W->hsb,W->thickness,W->leftspace,W->resizable); } window *controlswindow(ControlRef C) { WindowRef WP; window **MP; int i; if (!C) return NULL; WP=GetControlOwner(C); if (!WP) return NULL; if (!WindList) return NULL; MP=*WindList; if (!MP) return NULL; for (i=0;iwmw==WP) return MP[i]; return NULL; } static void tapedeckrect(window *W, int POSN, Rect *R) { int SIZE; WindowRef WP; CGrafPtr GP; if (!W || !R) return; WP=W->wmw; if (!WP) return; GP=GetWindowPort(WP); GetPortBounds(GP,R); SIZE=W->thickness; R->top= R->bottom - SIZE; R->bottom+=1; R->left= (POSN * SIZE) - 1; R->right= (POSN + 1) * SIZE; } ControlRef newscroll(WindowRef WP, bool Vert, bool Vis) { /*CGrafPtr GP; OSStatus err;*/ ControlRef C; Rect R; if (!WP) return NULL; //GP=GetWindowPort(WP); GetPortBounds(GP,&R); SetRect(&R,0,0,SCROLLTHICK,SCROLLTHICK); C=NewControl(WP,&R,"\p",0,0,0,0,kControlScrollBarLiveProc,0); /*err=CreateScrollBarControl(WP,&R,0,0,0,SInt32 viewSize,1,NULL,&C); if (err) ...*/ if (!C) halt("newscroll() memory allocation error"); if (Vert) sizevertscroll(C,SCROLLTHICK); else sizehorzscroll(C,SCROLLTHICK,0,1); if (Vis) ShowControl(C); return C; } ControlRef commonbutton(window *W, int POSN, int VAR) { OSErr err; ControlDefSpec Spec; Collection Co; UInt16 var; Rect R; ControlRef C; int i,OLD; if (!W || !W->wmw || !TDOCR) return NULL; tapedeckrect(W,POSN,&R); W->leftspace=gtr(W->leftspace,R.right); Spec.defType=kControlDefObjectClass; Spec.u.classRef=TDOCR; Co=NewCollection(); var=VAR; err=AddCollectionItem(Co,'TVAR',0,sizeof(UInt16),&var); if (err) halt("commonbutton error #1"); err=CreateCustomControl(W->wmw,&R,&Spec,Co,&C); if (err) halt("commonbutton error #2"); DisposeCollection(Co); if (!W->row) W->row=(ControlRef **)handle(0); OLD=W->rownum; W->rownum=gtr(POSN + 1,W->rownum); minimumsize(W->row,W->rownum,sizeof(ControlRef)); for (i=OLD;irownum;i++) (*(W->row))[i]=NULL; (*(W->row))[POSN]=C; return C; } void givescrolls(window *W) { if (!W || !W->wmw) return; W->vsb=newscroll(W->wmw,1,1); W->hsb=newscroll(W->wmw,0,1); sizescrolls(W); } void givevertscroll(window *W) { if (!W || !W->wmw) return; W->vsb=newscroll(W->wmw,1,1); sizescrolls(W); } void givehorzscroll(window *W) { if (!W || !W->wmw) return; W->hsb=newscroll(W->wmw,0,1); sizescrolls(W); } int partincrement(int PART, int LINE, int PAGE) { switch (PART) { case kControlPageUpPart: return -PAGE; case kControlUpButtonPart: return -LINE; case kControlDownButtonPart: return LINE; case kControlPageDownPart: return PAGE; } return 0; } void movetapedeckrow(window *W) { ControlRef C; int i; Rect R; for (i=0;irownum;i++) { C=(*(W->row))[i]; if (!C) continue; tapedeckrect(W,i,&R); MoveControl(C,R.left,R.top); } } bool stilldown(mouseclick *M) { Point Pt; if (!M) return 0; if (M->res==kMouseTrackingMouseUp) return 0; //M->err=TrackMouseLocation(NULL,&(M->now),&(M->res)); M->err=TrackMouseLocationWithOptions(NULL,0,kEventDurationSecond / 60.0,&Pt,NULL,&(M->res)); M->now.x=Pt.h; M->now.y= height(M->wind->page) - Pt.v; return M->res!=kMouseTrackingMouseUp; } /* void trackmouse(mouseclick *M) { if (!M) return; M->err=TrackMouseLocation(NULL,&(M->now),&(M->res)); } void trackmousedelay(mouseclick *M, EventTimeout Delay) { if (!M) return; M->err=TrackMouseLocationWithOptions(NULL,0,Delay,&(M->now),NULL,&(M->res)); }*/ // The window manager for frame.c void postwindowmenus(window *W) { ClearMenuBar(); if (W) { if (W->setup) W->setup(); else if (W->menubar) SetMenuBar(W->menubar); if (W->adjust) W->adjust(W); } else { if (NoWindSetup) NoWindSetup(); else if (NoWindMenus) SetMenuBar(NoWindMenus); if (NoWindAdjust) NoWindAdjust(NULL); } } static void addtowindowlist(window *W) { if (!W || !WindList) return; fuzzyresize(WindList,WINDS + 1,sizeof(window *)); (*WindList)[WINDS++]=W; } static void removefromwindowlist(window *W) { window **MP; int i; if (!W || !WindList) return; MP=*WindList; if (!MP) return; for (i=0;iwmw==WP) return W; } return NULL; } window *frontmost(void) { WindowRef WP; WP=FrontNonFloatingWindow(); if (!WP) return NULL; return windowfromlist(WP); } static bool anotheropen(window *U) { window *W; int i; WindowRef WP; if (!WindList || !*WindList) return 0; for (i=0;iwmw; if (!WP) continue; if (IsWindowVisible(WP)) return 1; } return 0; } static void constrainwindow(window *W) { WindowPtr WP; Rect CR; OSStatus err; point Size; if (!W || !W->aspect) return; WP=W->wmw; if (!WP) return; err=GetWindowBounds(WP,kWindowContentRgn,&CR); if (err) return; Size.x= CR.right - CR.left; if (W->vsb) Size.x-=W->thickness; Size.y= CR.bottom - CR.top; if (W->hsb) Size.y-=W->thickness; W->aspect(&Size); if (W->vsb) Size.x+=W->thickness; CR.right= CR.left + Size.x; if (W->hsb) Size.y+=W->thickness; CR.bottom= CR.top + Size.y; err=SetWindowBounds(WP,kWindowContentRgn,&CR); } static void resizewindow(window *W) { if (!W) return; calcpage(W); oldquartz(W); initquartz(W); movetapedeckrow(W); sizescrolls(W); if (W->resize) W->resize(W); //W->erase=1; } // ? } static void blankwindow(window *W) { if (!W) return; W->q2d=NULL; W->cs=CGColorSpaceCreateDeviceRGB(); W->hsb=NULL; W->vsb=NULL; W->row=NULL; W->rownum=0; W->thickness=SCROLLTHICK; W->resizable=0; W->leftspace=0; W->proj=NULL; W->appdata=NULL; W->resize=NULL; W->aspect=NULL; W->draw=NULL; W->close=NULL; W->action=NULL; W->click=NULL; W->doubclick=NULL; W->move=NULL; W->wheel=NULL; W->numpages=NULL; W->print=NULL; W->pdfsize=NULL; W->drawpdf=NULL; W->setup=NULL; W->adjust=NULL; W->comd=NULL; W->key=NULL; W->modal=0; W->erase=1; W->menubar=NULL; W->settings=NULL; W->printing=0; } static void initwmw(window *W) { WindowRef WP; CGrafPtr GP; Rect R; if (!W) return; WP=W->wmw; if (!WP) return; GP=GetWindowPort(WP); GetPortBounds(GP,&R); W->qdpage=R; cgrect(&(W->qdpage),&(W->page)); /*saveuserrect(WP);*/ } static OSStatus activehandler(EventHandlerCallRef CallRef, EventRef E, void *UserData) { window *W; W=(window *)UserData; if (!W) return eventNotHandledErr; postwindowmenus(W); return noErr; } static OSStatus drawhandler(EventHandlerCallRef CallRef, EventRef E, void *UserData) { window *W; W=(window *)UserData; if (!W || !W->draw) return eventNotHandledErr; redraw(W); return noErr; } static OSStatus minsize(EventHandlerCallRef CallRef, EventRef E, void *UserData) { window *W; OSStatus err; Point Pt; W=(window *)UserData; if (!W) return eventNotHandledErr; Pt.h=240; Pt.v=180; // see also standardwindow() err=SetEventParameter(E,kEventParamDimensions,typeQDPoint,sizeof(Point),&Pt); return noErr; } static OSStatus growhandler(EventHandlerCallRef CallRef, EventRef E, void *UserData) { window *W; OSStatus err; UInt32 Attr; W=(window *)UserData; if (!W) return eventNotHandledErr; err=GetEventParameter(E,kEventParamAttributes,typeUInt32,NULL,sizeof(UInt32),NULL,&Attr); //if (!(Attr & kWindowBoundsChangeSizeChanged)) return eventNotHandledErr; if (W->aspect) constrainwindow(W); resizewindow(W); return noErr; } static OSStatus closehandler(EventHandlerCallRef CallRef, EventRef E, void *UserData) { window *W; //OSStatus err; W=(window *)UserData; if (!W) return eventNotHandledErr; if (!anotheropen(W)) postwindowmenus(NULL); if (!W->close) return eventNotHandledErr; W->close(W); return noErr; } static OSStatus wmovhandler(EventHandlerCallRef CallRef, EventRef E, void *UserData) { window *W; //OSStatus err; ControlRef RC; grafvars G; W=(window *)UserData; if (!W) return eventNotHandledErr; //err=GetRootControl(W->wmw,&RC); if (err) return eventNotHandledErr; //beep(); //err=SetControlVisibility(RC,1,1); //savegraf(&G); SetPortWindowPort(W->wmw); DrawControls(W->wmw); restoregraf(&G); return noErr; } static OSStatus clickhandler(EventHandlerCallRef CallRef, EventRef E, void *UserData) { window *W; WindowRef WP; mouseclick M; EventTime Time; OSStatus err; UInt32 mods; bool res; grafvars G; Point Pt; EventMouseButton BUTTON; W=(window *)UserData; if (!W || !W->click) return eventNotHandledErr; M.wind=W; WP=W->wmw; if (!WP || !IsWindowActive(WP)) return eventNotHandledErr; err=GetEventParameter(E,kEventParamMouseLocation,typeQDPoint,NULL,sizeof(Point),NULL,&Pt); // When kEventParamWindowMouseLocation becomes available, it will be in local coordinates already err=GetEventParameter(E,kEventParamMouseButton,typeMouseButton,NULL,sizeof(EventMouseButton),NULL,&BUTTON); savegraf(&G); SetPortWindowPort(WP); GlobalToLocal(&Pt); //restoregraf(&G); if (!PtInRect(Pt,&(W->qdpage))) { restoregraf(&G); return eventNotHandledErr; } M.point.x=Pt.h; M.point.y= height(M.wind->page) - Pt.v; err=GetEventParameter(E,kEventParamKeyModifiers,typeUInt32,NULL,sizeof(UInt32),NULL,&mods); M.right=(BUTTON==2); M.shift= (mods & shiftKey)!=0; M.cmnd= (mods & cmdKey)!=0; M.opt= (mods & optionKey)!=0; M.res=kMouseTrackingMouseDown; M.now=M.point; M.err=noErr; Time=GetEventTime(E); if (W->doubclick && Time>0 && Time < W->downtime + (GetDblTime() / 60.0)) res=W->doubclick(&M); else res=W->click(&M); W->downtime=Time; restoregraf(&G); return res ? noErr : eventNotHandledErr; } static OSStatus movehandler(EventHandlerCallRef CallRef, EventRef E, void *UserData) { window *W; WindowRef WP; mouseclick M; OSStatus err; bool res; grafvars G; Point Pt; W=(window *)UserData; if (!W || !W->move) return eventNotHandledErr; M.wind=W; WP=W->wmw; if (!WP || !IsWindowActive(WP)) return eventNotHandledErr; err=GetEventParameter(E,kEventParamMouseLocation,typeQDPoint,NULL,sizeof(Point),NULL,&Pt); // When kEventParamWindowMouseLocation becomes available, it will be in local coordinates already savegraf(&G); SetPortWindowPort(WP); GlobalToLocal(&Pt); restoregraf(&G); //if (!PtInRect(M.point,&(W->qdpage))) return eventNotHandledErr; M.point.x=Pt.h; M.point.y= height(W->page) - Pt.v; //M.point.y+=17;//? M.shift=0; M.cmnd=0; M.opt=0; res=W->move(&M); return res ? noErr : eventNotHandledErr; } static OSStatus wheelhandler(EventHandlerCallRef CallRef, EventRef E, void *UserData) { window *W; WindowRef WP; OSStatus err; bool res; EventMouseWheelAxis Axis; SInt32 DELTA; short DX,DY; W=(window *)UserData; if (!W || !W->wheel) return eventNotHandledErr; WP=W->wmw; if (!WP || !IsWindowActive(WP)) return eventNotHandledErr; err=GetEventParameter(E,kEventParamMouseWheelAxis,typeMouseWheelAxis,NULL,sizeof(EventMouseWheelAxis),NULL,&Axis); err=GetEventParameter(E,kEventParamMouseWheelDelta,typeSInt32,NULL,sizeof(SInt32),NULL,&DELTA); DX= (Axis==kEventMouseWheelAxisX) ? DELTA : 0; DY= (Axis==kEventMouseWheelAxisY) ? DELTA : 0; res=W->wheel(W,DX,DY); return res ? noErr : eventNotHandledErr; } static OSStatus keyhandler(EventHandlerCallRef CallRef, EventRef E, void *UserData) { window *W; WindowRef WP; keystroke K; OSStatus err; UInt32 mods; bool res; W=(window *)UserData; if (!W || !W->key) return eventNotHandledErr; K.wind=W; WP=W->wmw; if (!WP || !IsWindowActive(WP)) return eventNotHandledErr; err=GetEventParameter(E,kEventParamKeyMacCharCodes,typeChar,NULL,sizeof(char),NULL,&(K.c)); err=GetEventParameter(E,kEventParamKeyModifiers,typeUInt32,NULL,sizeof(UInt32),NULL,&mods); K.shift= (mods & shiftKey)!=0; K.opt= (mods & optionKey)!=0; res=W->key(&K); return res ? noErr : eventNotHandledErr; } static OSStatus rpthandler(EventHandlerCallRef CallRef, EventRef E, void *UserData) { return keyhandler(CallRef,E,UserData); } static void myhandler(EventTargetRef Target, window *W, UInt32 Class, UInt32 Kind, EventHandlerProcPtr P) { OSStatus err; EventTypeSpec ET; ET.eventClass=Class; ET.eventKind=Kind; err=InstallEventHandler(Target,NewEventHandlerUPP(P),1,&ET,W,NULL); } static window *standwindow(const char *Title, const Rect *Size, bool Grow, int CLASS) { window *W; OSStatus err; Rect R; WindowAttributes attrib; CFStringRef T; EventTargetRef Target; W=pointer(sizeof(window)); blankwindow(W); W->resizable=Grow; if (Size) R=*Size; else SetRect(&R,20,80,660,560); if (Grow) attrib= kWindowStandardDocumentAttributes;// | kWindowLiveResizeAttribute; else attrib= kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute; //attrib+=kWindowStandardHandlerAttribute; // done below with InstallStandardEventHandler() if (CLASS==kMovableModalWindowClass) attrib=0; err=CreateNewWindow(CLASS,attrib,&R,&(W->wmw)); if (err || !W->wmw) halt("standardwindow() error #2"); T=macstring(Title); err=SetWindowTitleWithCFString(W->wmw,T); CFRelease(T); Target=GetWindowEventTarget(W->wmw); err=InstallStandardEventHandler(Target); myhandler(Target,W,kEventClassWindow, kEventWindowActivated, &activehandler); myhandler(Target,W,kEventClassWindow, kEventWindowDrawContent, &drawhandler ); myhandler(Target,W,kEventClassWindow, kEventWindowGetMinimumSize,&minsize ); myhandler(Target,W,kEventClassWindow, kEventWindowBoundsChanged, &growhandler ); myhandler(Target,W,kEventClassWindow, kEventWindowClose, &closehandler ); myhandler(Target,W,kEventClassWindow, kEventWindowDragCompleted, &wmovhandler ); myhandler(Target,W,kEventClassMouse, kEventMouseDown, &clickhandler ); myhandler(Target,W,kEventClassMouse, kEventMouseMoved, &movehandler ); myhandler(Target,W,kEventClassMouse, kEventMouseWheelMoved, &wheelhandler ); myhandler(Target,W,kEventClassKeyboard,kEventRawKeyDown, &keyhandler ); myhandler(Target,W,kEventClassKeyboard,kEventRawKeyRepeat, &rpthandler ); initwmw(W); initquartz(W); addtowindowlist(W); return W; } window *customwindow(const char *Title, int WIDTH, int HEIGHT, bool Grow) { Rect R; SetRect(&R,20,80,20 + gtr(WIDTH,240),80 + gtr(HEIGHT,180)); return standwindow(Title,&R,Grow,kDocumentWindowClass); } window *standardwindow(const char *Title) { return customwindow(Title,800,600,1); } window *standarddialog(const char *Title, int WIDTH, int HEIGHT) { window *W; Rect R; Point P; P.h=512; P.v=384; SetRect(&R,P.h - (WIDTH / 2),P.v - (HEIGHT / 2),P.h + (WIDTH / 2),P.v + (HEIGHT / 2)); W=standwindow(Title,&R,0,kMovableModalWindowClass); W->modal=1; return W; } void oldwindow(window *W) { removefromwindowlist(W); oldquartz(W); if (W->wmw) DisposeWindow(W->wmw); /* This disposes ALL of its controls too. */ old(W); } // Installation of call-back routines for window-related events void installpaint(window *W, /*planeprocptr Plane,*/ windprocptr Draw) { if (!W) return; /*W->activate=Plane;*/ W->draw=Draw; } void installgrow(window *W, windprocptr Proc, aspectprocptr Aspect) { if (!W) return; W->resize=Proc; W->aspect=Aspect; } void installclick(window *W, clickprocptr Click, windprocptr Close, windprocptr Action) { if (!W) return; W->click=Click; W->close=Close; W->action=Action; } void installdouble(window *W, clickprocptr Double) { if (!W) return; W->doubclick=Double; } void installmousemove(window *W, clickprocptr Proc) { if (!W) return; W->move=Proc; } void installwheel(window *W, wheelprocptr Proc) { if (!W) return; W->wheel=Proc; } void installmenus(window *W, Handle MenuBar, voidprocptr Setup, windprocptr Adjust, comdprocptr Comd) { if (W) { W->menubar=MenuBar; W->setup=Setup; W->adjust=Adjust; W->comd=Comd; } else { NoWindMenus=MenuBar; NoWindSetup=Setup; NoWindAdjust=Adjust; NoWindComd=Comd; } } void installkey(window *W, keyprocptr Proc) { if (!W) return; W->key=Proc; } void installprint(window *W, numpgprocptr Num, printprocptr Draw) { if (!W) return; W->numpages=Num; W->print=Draw; } void installpict(window *W, pdfsizepp Size, windprocptr Draw) { if (!W) return; W->pdfsize=Size; W->drawpdf=Draw; } // void closewindow(window *W) { if (!W) return; if (W->close) W->close(W); } void concealwindow(window *W) { WindowRef WP; if (!W) return; WP=W->wmw; if (!WP) return; if (!IsWindowVisible(WP)) return; HideWindow(WP); } void revealwindow(window *W) { WindowRef WP; if (!W) return; WP=W->wmw; if (!WP) return; ShowWindow(WP); SelectWindow(WP); } bool windowseen(window *W) { WindowRef WP; if (!W) return 0; WP=W->wmw; if (!WP) return 0; return IsWindowVisible(WP); } void revealbehind(window *W, window *Front) { WindowRef WP; if (!W) return; WP=W->wmw; if (!WP) return; if (!Front || !Front->wmw || !windowseen(Front)) { revealwindow(W); return; } SendBehind(WP,Front->wmw); ShowWindow(WP); } void setwindowname(window *W, char *S) { WindowRef WP; Str255 PS; if (!W || !(WP=W->wmw) || !S) return; pascalstring(S,PS); SetWTitle(WP,PS); } void stackwindow(window *W, int PLACE) { /*grafvars G;*/ WindowRef WP; int DELTA; Rect R; if (!W) return; WP=W->wmw; if (!WP) return; /*savegraf(&G); SetPortWindowPort(WP);*/ findzoomrect(NULL,&R); DELTA= 8 * PLACE; R.left+=DELTA; R.top+=DELTA; MoveWindow(WP,R.left,R.top,1); /*saveuserrect(WP); restoregraf(&G);*/ } void tilewindow(window *W, int PLACE, int TOTAL, bool Horz) { Rect R; Point P; WindowRef WP; //grafvars G; CGrafPtr GP; int TITLEHEIGHT,ROWS,COLS,i,j,CELLS,EXTRA,WIDTH,HEIGHT; if (!W || !(WP=W->wmw)) return; if (!range(PLACE,TOTAL)) return; ROWS=1; if (TOTAL>1) ROWS=2; else if (TOTAL>4) ROWS=3; else if (TOTAL>9) ROWS=4; COLS= TOTAL / ROWS; if (COLS * ROWS < TOTAL) COLS++; if (!Horz) { j=COLS; COLS=ROWS; ROWS=j; } EXTRA= (COLS * ROWS) - TOTAL; i= PLACE / COLS; j= PLACE - (i * COLS); CELLS=1; if (PLACE == TOTAL - 1) CELLS= 1 + EXTRA; if (TOTAL==3) switch (PLACE) { case 0: i=0; j=0; CELLS=2; break; case 1: i= Horz ? 1 : 0; j= Horz ? 0 : 1; CELLS=1; break; case 2: i=1; j=1; CELLS=1; break; } findzoomrect(NULL,&R); TITLEHEIGHT=20; R.top-=TITLEHEIGHT; R.right+=5; R.bottom+=5; // to get the "full" rect back P.h= R.left + ((j * rectwidth(&R)) / COLS); P.v= R.top + ((i * rectheight(&R)) / ROWS); WIDTH= ((Horz ? CELLS : 1) * rectwidth(&R)) / COLS; HEIGHT= ((Horz ? 1 : CELLS) * rectheight(&R)) / ROWS; WIDTH-=5; HEIGHT-=5; P.v+=TITLEHEIGHT; HEIGHT-=TITLEHEIGHT; //SetRect(&R,0,0,WIDTH,HEIGHT); MoveWindow(WP,P.h,P.v,0); SizeWindow(WP,WIDTH,HEIGHT,0); if (W->aspect) constrainwindow(W); resizewindow(W); } // The menu manager for frame.c void truncatemenu(MenuRef M, int LEAVE) { int i,REM; if (!M) return; REM= CountMenuItems(M) - LEAVE; for (i=0;iwmw; if (!WP || !IsWindowVisible(WP)) continue; GetWTitle(WP,PS); AppendMenu(M,"\p "); TOTAL++; SetMenuItemText(M,TOTAL,PS); err=SetMenuItemCommandID(M,TOTAL,'Wind' + i); if (IsWindowHilited(WP)) CheckMenuItem(M,TOTAL,1); } } window *windowchoice(UInt32 C) { int i/*,TOTAL*/; window *W; WindowRef WP; i= C - 'Wind'; if (!range(i,WINDS)) return NULL; W=(*WindList)[i]; if (!W) return NULL; WP=W->wmw; if (!WP || !IsWindowVisible(WP)) return NULL; return W; /*TOTAL=0; for (i=0;iwmw; if (!WP || !IsWindowVisible(WP)) continue; TOTAL++; if (ITEM==TOTAL) return W; } return NULL;*/ }