home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-06-15 | 23.7 KB | 999 lines | [TEXT/CWIE] |
- /*
-
- File: Window.cp
- Project: Sprocket Framework 1.1 (DR2), released 6/15/96
- Contains: Base class which support all aspects of an on-screen window
- To Do: Make sure invisible windows can be created & managed
- Fix activate bugs when showing and hiding windows
- Window positioning methods (getters and setters)
- Changes to support AEObject model
-
- Sprocket Major Contributors:
- ----------------------------
- Dave Falkenburg, producer of Sprocket 1.0
- Bill Hayden, producer of Sprocket 1.1
- Steve Sisak, producer of the upcoming Sprocket 2.0
-
- Pete Alexander Steve Falkenburg Randy Thelen
- Eric Berdahl Nitin Ganatra Chris K. Thomas
- Marshall Clow Dave Hershey Leonard Rosenthal
- Tim Craycroft Dave Mark Dean Yu
- David denBoer Gary Powell
- Cameron Esfahani Jon Summers Apple Computer, Inc.
-
- Comments, Additions, or Corrections:
- ------------------------------------
- Bill Hayden, Nikol Software <nikol@codewell.com>
-
- */
-
-
- #include "Sprocket.h"
- #include "Window.h"
-
-
- RgnHandle TWindow::fgScratchRgn = nil;
- short TWindow::fgNumWindows = 0;
-
-
- const short kFloatingWindowKind = 1000;
- const short kNormalWindowKind = 1001;
- const WindowRef kNoFloatingWindows = (WindowRef) -1;
-
- const short kScreenEdgeSlop = 4;
- const short kSpaceForFinderIcons = 64;
- const short kMinimumTitleBarHeight = 21;
- const short kMinimumWindowSize = 32;
-
- static void HiliteShowHideFloatingWindows(Boolean hiliting,Boolean hiding);
-
- static void FindScreenRectWithLargestPartOfWindow(WindowRef aWindow,Rect *theBestScreenRect, GDHandle * theBestDevice);
- static pascal void CalculateWindowAreaOnDevice(short depth,short deviceFlags,GDHandle targetDevice,long userData);
-
- struct CalcWindowAreaDeviceLoopUserData
- {
- GDHandle fScreenWithLargestPartOfWindow;
- long fLargestArea;
- Rect fWindowBounds;
- };
-
-
-
-
-
- TWindow::TWindow()
- {
- fIsDialogWindow = false;
-
- if (fgScratchRgn == nil)
- fgScratchRgn = NewRgn();
-
- fgNumWindows++;
- }
-
-
- TWindow::~TWindow()
- {
- if ((--fgNumWindows <= 0) && (fgScratchRgn != nil))
- {
- DisposeRgn(fgScratchRgn);
- fgScratchRgn = nil;
- }
- }
-
-
- void TWindow::CreateWindow(WindowType typeOfWindowToCreate /* = kNormalWindow */)
- {
- WindowRef behindWindow, oldFrontMostWindow;
-
- if (typeOfWindowToCreate == kModalWindow)
- {
- behindWindow = (WindowRef) -1;
- oldFrontMostWindow = FrontWindow();
-
- fWindowType = kModalWindow;
- }
- else if (typeOfWindowToCreate == kFloatingWindow)
- {
- behindWindow = (WindowRef) -1;
- oldFrontMostWindow = FrontWindow();
-
- fWindowType = kFloatingWindow;
- }
- else if (typeOfWindowToCreate == kNormalWindow)
- {
- behindWindow = LastFloatingWindow();
-
- fWindowType = kNormalWindow;
-
- if (behindWindow == kNoFloatingWindows)
- oldFrontMostWindow = FrontNonFloatingWindow(); // •••
- else
- oldFrontMostWindow = GetNextWindow ( behindWindow );
- }
-
- fWindow = this->MakeNewWindow(behindWindow);
- fIsVisible = IsWindowVisible ( fWindow );
-
- if (fWindow)
- {
- SetWRefCon(fWindow,(long) this);
-
- if (typeOfWindowToCreate == kModalWindow)
- {
- SetWindowKind ( fWindow, kNormalWindowKind );
-
- HiliteAndActivateWindow(fWindow,true);
-
- HiliteWindowsForModalDialog(false);
- ShowWindow(fWindow);
- HiliteAndActivateWindow(fWindow,true);
- }
- else if (typeOfWindowToCreate == kFloatingWindow)
- {
- SetWindowKind ( fWindow, kFloatingWindowKind );
-
- // make sure the other window stays hilited
- if (oldFrontMostWindow)
- HiliteAndActivateWindow(oldFrontMostWindow,true);
- }
- else if (typeOfWindowToCreate == kNormalWindow)
- {
- SetWindowKind ( fWindow, kNormalWindowKind );
-
- // unhighlight the old front window
- if (oldFrontMostWindow)
- HiliteAndActivateWindow(oldFrontMostWindow,false);
-
- // hilite the new window…
- HiliteAndActivateWindow(fWindow,true);
- }
- }
- }
-
-
- void
- TWindow::AdjustCursor(EventRecord * /* anEvent */)
- {
- }
-
- void
- TWindow::Idle(EventRecord * /* anEvent */)
- {
- }
-
- void
- TWindow::Activate(Boolean /* activating */)
- {
- }
-
- void
- TWindow::Draw(void)
- {
- }
-
- void
- TWindow::Click(EventRecord * /* anEvent */)
- {
- this->Select();
- }
-
- void
- TWindow::KeyDown(EventRecord * /* anEvent */)
- {
- }
-
-
- Boolean TWindow::Select(void)
- {
- WindowRef currentFrontWindow;
-
- if (fWindowType == kNormalWindow)
- currentFrontWindow = FrontNonFloatingWindow();
- else
- currentFrontWindow = FrontWindow();
-
- if (currentFrontWindow != fWindow)
- {
- TWindow* front = GetWindowObject(currentFrontWindow);
-
- if (front->fWindowType == kModalWindow)
- {
- SysBeep(1);
- return false; // window is not a legal destination for clicks
- }
- else if (fWindowType == kFloatingWindow)
- BringToFront( fWindow );
- else
- {
- WindowRef lastFloater = LastFloatingWindow();
-
- // Deactivate the window currently in front.
-
- HiliteAndActivateWindow(currentFrontWindow, false);
-
- if (lastFloater == kNoFloatingWindows)
- {
- // If there are no floating windows,
- // just call SelectWindow like the good ol’ days
-
- SelectWindow(fWindow);
- }
- else
- {
- // Bring it behind the last floating window and activate it.
- // Note that Inside Mac 1 states that you need to call PaintOne() and CalcVis() on a
- // window if you are using SendBehind() to bring it closer to the front. With System 7,
- // this is no longer necessary.
-
- SendBehind( fWindow, lastFloater);
- }
-
- // Hilite the new front window
-
- HiliteAndActivateWindow(fWindow,true);
- }
- }
-
- return true; // window is a legal destination for clicks
- }
-
-
- void TWindow::Drag(Point startPoint)
- {
- GrafPtr savePort;
- KeyMap theKeyMap;
- Boolean commandKeyDown = false;
- long dragResult;
- WindowRef currentFrontWindow;
-
- if (fWindowType == kNormalWindow)
- currentFrontWindow = FrontNonFloatingWindow();
- else
- currentFrontWindow = FrontWindow();
-
- if (currentFrontWindow != fWindow)
- {
- TWindow* front = GetWindowObject(currentFrontWindow);
-
- if (front->fWindowType == kModalWindow)
- {
- SysBeep(1);
- return; // window is not a legal drag
- }
- }
-
- if (WaitMouseUp()) // de-bounce?
- {
- // Set up the Window Manager port.
-
- GetPort(&savePort);
- SetPort(gWindowManagerPort);
- SetClip(GetGrayRgn());
-
- // Check to see if the command key is down.
-
- GetKeys(theKeyMap);
- commandKeyDown = ((theKeyMap[1] & 0x8000) != 0);
-
- if (commandKeyDown)
- {
- // We’re not going to change window ordering,
- // so make sure that we don’t drag in front of
- // other windows which may be in front of ours.
-
- ClipAbove(fWindow);
- }
- else if (fWindowType != kFloatingWindow)
- {
- // We’re dragging a normal window, so make sure
- // that we don’t drag in front of any floating
- // windows.
-
- ClipAbove(FrontNonFloatingWindow());
- }
-
- // Drag an outline of the window around the desktop.
- // NOTE: DragGrayRgn destroys the region passed in, so make a copy
-
- GetWindowStructureRgn(fWindow, fgScratchRgn);
- dragResult = DragGrayRgn(fgScratchRgn, startPoint, &gDeskRectangle, &gDeskRectangle, noConstraint, nil);
-
- SetPort(savePort); // Get back to old port
-
- if ((dragResult != 0) && (dragResult != 0x80008000))
- {
- this->Nudge((short) (dragResult & 0xFFFF),(short) (dragResult >> 16));
- }
- }
-
- if (!commandKeyDown)
- Select();
- }
-
-
-
- void TWindow::Nudge(short horizontalDistance, short verticalDistance)
- {
- short newHorizontalPosition, newVerticalPosition;
- RgnHandle tempRgn = NewRgn ();
-
- GetWindowContentRgn ( fWindow, tempRgn );
- newHorizontalPosition = (short) (**tempRgn).rgnBBox.left + horizontalDistance;
- newVerticalPosition = (short) (**tempRgn).rgnBBox.top + verticalDistance;
- DisposeRgn ( tempRgn );
-
- ::MoveWindow(fWindow, newHorizontalPosition, newVerticalPosition, false);
- }
-
-
-
- void TWindow::Grow(Point startPoint)
- {
- GrafPtr oldPort;
- long newSize;
- Rect oldWindowRect,resizeLimits;
-
- GetPort(&oldPort);
-
- GetWindowSizeLimits(&resizeLimits);
- newSize = GrowWindow(fWindow,startPoint, &resizeLimits);
- if (newSize)
- {
- oldWindowRect = GetWindowPort ( fWindow )->portRect;
- SizeWindow ( fWindow, (short) newSize, (short) (newSize >> 16), true );
- SetPortWindowPort ( fWindow );
- resizeLimits = GetWindowPort ( fWindow )->portRect;
- this->AdjustForNewWindowSize(&oldWindowRect, &resizeLimits);
- }
-
- SetPort(oldPort);
- }
-
-
- void TWindow::Zoom(short zoomState)
- {
- GrafPtr oldPort;
- FontInfo systemFontInfo;
- short titleBarHeight;
- Rect bestScreenRect,perfectWindowRect,scratchRect;
- short amountOffscreen;
- // WindowPeek windowAsWindowPeek = (WindowPeek) fWindow;
- GDHandle bestDevice;
-
- GetPort(&oldPort);
-
- // Figure out the height of the title bar so we can properly position
- // a window. The algorithm is stolen from the System 7.x 'WDEF' (0)
- //
- // This probably isn’t the best thing to do: A better way might be
- // to diff the structure and content region rectangles?
-
- SetPort(gWindowManagerPort);
- GetFontInfo(&systemFontInfo);
- titleBarHeight = (short) (systemFontInfo.ascent + systemFontInfo.descent + 4);
- if ((titleBarHeight % 2) == 1)
- titleBarHeight--;
- if (titleBarHeight < kMinimumTitleBarHeight)
- titleBarHeight = kMinimumTitleBarHeight;
-
-
- // Only do the voodoo magic if we are really “zooming” the window.
-
- if (zoomState == inZoomOut)
- {
- FindScreenRectWithLargestPartOfWindow(fWindow,&bestScreenRect,&bestDevice);
- bestScreenRect.top += titleBarHeight;
-
- this->GetPerfectWindowSize(&perfectWindowRect);
- OffsetRect(&perfectWindowRect,-perfectWindowRect.left,-perfectWindowRect.top);
-
- // Take the zero-pinned perfect window size and move it to
- // the top left of the window’s content region.
-
- RgnHandle tempRgn = NewRgn ();
- GetWindowContentRgn ( fWindow, tempRgn );
- OffsetRect ( &perfectWindowRect,
- (**tempRgn).rgnBBox.left, (**tempRgn).rgnBBox.top );
- DisposeRgn ( tempRgn );
-
-
- // Does perfectWindowRect fit completely on the best screen?
-
- SectRect(&perfectWindowRect, &bestScreenRect, &scratchRect);
- if (!EqualRect(&perfectWindowRect, &scratchRect))
- {
- // SectRect sez perfectWindowRect doesn’t completely fit
- // on the screen, so bump the window so that more of it fits.
-
- // Make sure that the left edge of perfectWindowRect is forced
- // onto the best screen. This is in case we are bumping
- // the window to the right.
-
- amountOffscreen = bestScreenRect.left - perfectWindowRect.left;
- if (amountOffscreen > 0)
- {
- perfectWindowRect.left += amountOffscreen;
- perfectWindowRect.right += amountOffscreen;
- }
-
- // Make sure that the left edge of perfectWindowRect is forced
- // onto the best screen. This is in case we are bumping
- // the window downward to a new screen.
-
- amountOffscreen = bestScreenRect.top - perfectWindowRect.top;
- if (amountOffscreen > 0)
- {
- perfectWindowRect.top += amountOffscreen;
- perfectWindowRect.bottom += amountOffscreen;
- }
-
- // If right edge of window falls off the screen,
- // Move window to the left until the right edge IS on the screen
- // OR the left edge is at bestScreenRect.left
-
- amountOffscreen = perfectWindowRect.right - bestScreenRect.right;
- if (amountOffscreen > 0)
- {
- // Are we going to push the left edge offscreen? If so, change the
- // offset so we move the window all the way over to the left.
-
- if ((perfectWindowRect.left - amountOffscreen) < bestScreenRect.left)
- amountOffscreen = perfectWindowRect.left - bestScreenRect.left;
-
- perfectWindowRect.left -= amountOffscreen;
- perfectWindowRect.right -= amountOffscreen;
- }
-
- // If bottom edge of window falls off the screen,
- // Move window to up until the bottom edge IS on the screen
- // OR the top edge is at bestScreenRect.top
-
- amountOffscreen = perfectWindowRect.bottom - bestScreenRect.bottom;
- if (amountOffscreen > 0)
- {
- // Are we going to push the top edge offscreen? If so, change the
- // offset so we move the window just to the top.
-
- if ((perfectWindowRect.top - amountOffscreen) < bestScreenRect.top)
- amountOffscreen = perfectWindowRect.top - bestScreenRect.top;
-
- perfectWindowRect.top -= amountOffscreen;
- perfectWindowRect.bottom -= amountOffscreen;
- }
-
- SectRect(&perfectWindowRect, &bestScreenRect, &scratchRect);
- if (!EqualRect(&perfectWindowRect, &scratchRect))
- {
- // The edges of the window still fall offscreen,
- // so make the window smaller until it fits.
-
- if (perfectWindowRect.bottom > bestScreenRect.bottom)
- perfectWindowRect.bottom = bestScreenRect.bottom;
-
- // If the right edge is still falling off,
- // save space for Finder’s disk icons as well.
-
- if (perfectWindowRect.right > bestScreenRect.right)
- {
- perfectWindowRect.right = bestScreenRect.right;
-
- // If we were on the main screen, leave room for Finder icons, too.
-
- if (bestDevice == GetMainDevice())
- perfectWindowRect.right -= kSpaceForFinderIcons;
- }
- }
- }
-
- // Stash our new rectangle inside of the Window’s dataHandle
- // so that ZoomWindow does the right thing.
-
- // (**((WStateDataHandle) (windowAsWindowPeek->dataHandle))).stdState = perfectWindowRect;
- SetWindowStandardState ( fWindow, &perfectWindowRect );
- }
-
- // HEY YOU! Don’t forget to set the port to the window being zoomed
- // Why, you ask? Because IM-IV-50 says to; otherwise you die
-
- SetPortWindowPort ( fWindow );
-
- Rect oldWindowRect = GetWindowPort ( fWindow )->portRect;
- ZoomWindow(fWindow,zoomState,false);
- Rect newWindowRect = GetWindowPort ( fWindow )->portRect;
- this->AdjustForNewWindowSize(&oldWindowRect,&newWindowRect);
-
- SetPort(oldPort);
- }
-
-
-
- void TWindow::ShowHide(Boolean showFlag)
- {
- // Here we need the “::” in front of ShowHide to indicate we are calling
- // the global function, and not the method ShowHide. Unintended recursion
- // can do bad things to the unsuspecting programmer.
-
- // Some C++ programmers would always prepend the “::” on function calls.
-
- ::ShowHide(fWindow,showFlag);
- fIsVisible = showFlag;
- }
-
-
-
- Boolean TWindow::EventFilter(EventRecord * /* theEvent */)
- {
- return false;
- }
-
-
-
- void TWindow::GetPerfectWindowSize(Rect *perfectSize)
- {
- *perfectSize = qd.screenBits.bounds;
- }
-
-
-
- void TWindow::GetWindowSizeLimits(Rect *limits)
- {
- limits->top = limits->left = kMinimumWindowSize;
- limits->right = gDeskRectangle.right - gDeskRectangle.left;
- limits->bottom = gDeskRectangle.bottom - gDeskRectangle.top;
- }
-
-
-
- void TWindow::AdjustForNewWindowSize(Rect * /* oldRect */, Rect * /* newSize */)
- {
- }
-
-
-
- Boolean TWindow::IsVisible(void)
- {
- return fIsVisible;
- }
-
-
-
- Boolean TWindow::CanClose(Boolean /* quitting */)
- {
- return true;
- }
-
-
-
- Boolean TWindow::Close(void)
- {
- WindowRef newFrontWindow = nil;
-
- if (FrontNonFloatingWindow() == fWindow)
- newFrontWindow = GetNextWindow ( fWindow );
-
- this->Activate(false);
-
- if (fIsDialogWindow)
- DisposeDialog((DialogRef) fWindow);
- else
- DisposeWindow(fWindow);
-
- if (fWindowType == kModalWindow)
- HiliteWindowsForModalDialog(true);
-
- if (newFrontWindow)
- HiliteAndActivateWindow(newFrontWindow,true);
-
- return true;
- }
-
-
- Boolean TWindow::DeleteAfterClose(void)
- {
- return true;
- }
-
-
- void TWindow::AdjustMenusBeforeMenuSelection(void)
- {
- }
-
-
- Boolean TWindow::DoMenuSelection(short /* menu */, short /* item */)
- {
- return false;
- }
-
-
-
- Boolean TWindow::DoCommand(CommandID theCommand)
- {
- if (theCommand == cClose)
- {
- if (this->CanClose(false) && this->Close() && this->DeleteAfterClose())
- delete this;
- return true;
- }
-
- return false;
- }
-
-
- void TWindow::ClickAndDrag(EventRecord * anEvent)
- {
- // By default, we just convert to local coordinates
- // and call the window’s Click method.
-
- GlobalToLocal(&anEvent->where);
- this->Click(anEvent);
- }
-
-
- OSErr TWindow::HandleDrag(DragTrackingMessage dragMessage,DragReference theDrag)
- {
- OSErr result = dragNotAcceptedErr;
-
- switch (dragMessage)
- {
- case dragTrackingEnterWindow:
- result = this->DragEnterWindow(theDrag);
- break;
-
- case dragTrackingInWindow:
- result = this->DragInWindow(theDrag);
- break;
-
- case dragTrackingLeaveWindow:
- result = this->DragLeaveWindow(theDrag);
- break;
-
- default:
- break;
- }
-
- return result;
- }
-
-
- OSErr TWindow::DragEnterWindow(DragReference /* theDrag */)
- {
- return dragNotAcceptedErr;
- }
-
-
- OSErr TWindow::DragInWindow(DragReference /* theDrag */)
- {
- return dragNotAcceptedErr;
- }
-
-
- OSErr TWindow::DragLeaveWindow(DragReference /* theDrag */)
- {
- return dragNotAcceptedErr;
- }
-
-
- OSErr TWindow::HandleDrop(DragReference /* theDrag */)
- {
- return dragNotAcceptedErr;
- }
-
-
-
- Boolean TWindow::IsPointInContentRgn( Point pt )
- {
- GetWindowContentRgn(fWindow, fgScratchRgn);
- Boolean result = PtInRgn( pt, fgScratchRgn );
- return result;
- }
-
-
-
- Boolean TWindow::IsMouseInContentRgn( DragReference dragRef )
- {
- Point globalMouse;
- OSErr err;
-
- err = GetDragMouse( dragRef, &globalMouse, 0L );
-
- if ( err == noErr )
- return( this->IsPointInContentRgn( globalMouse ) );
- else
- return( false );
- }
-
-
-
- Rect TWindow::GetContentsBounds(void)
- {
- Rect r;
-
- GetWindowContentRgn(fWindow, fgScratchRgn);
- r = (**fgScratchRgn).rgnBBox;
- return r;
- }
-
-
-
- ///////////////////////////////////////////////////////////////////////////
- //
- // Utility Functions used for floating windows
- //
-
- TWindow* GetWindowObject(WindowRef aWindow)
- {
- short wKind;
-
- if (aWindow != nil)
- {
- wKind = GetWindowKind ( aWindow );
-
- if (wKind >= userKind)
- {
- // All windowKinds >= userKind are based upon TWindow
-
- return (TWindow *) GetWRefCon(aWindow);
- }
- }
- return (TWindow *) nil;
- }
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Utility functions
-
-
- pascal WindowRef
- GetNewColorOrBlackAndWhiteWindow(short windowID, void *wStorage, WindowRef behind)
- {
- if (gHasColorQuickdraw)
- return GetNewCWindow(windowID,wStorage,behind);
- else
- return GetNewWindow(windowID,wStorage,behind);
- }
-
-
- pascal WindowRef
- NewColorOrBlackAndWhiteWindow(void *wStorage, const Rect *boundsRect, ConstStr255Param title, Boolean visible, short theProc, WindowRef behind, Boolean goAwayFlag, long refCon)
- {
- if (gHasColorQuickdraw)
- return NewCWindow(wStorage,boundsRect,title,visible,theProc,behind,goAwayFlag,refCon);
- else
- return NewWindow(wStorage,boundsRect,title,visible,theProc,behind,goAwayFlag,refCon);
- }
-
-
-
- void DrawJustTheGrowIcon(WindowRef aWindow)
- {
- GrafPtr savedPort;
- Rect growBoxRect;
-
- GetPort(&savedPort);
- SetPortWindowPort ( aWindow );
- GetClip(TWindow::fgScratchRgn);
-
- // clip to just the bottom right corner of the window
- growBoxRect = GetWindowPort ( aWindow )->portRect;
- growBoxRect.top = growBoxRect.bottom - kScrollbarWidth;
- growBoxRect.left = growBoxRect.right - kScrollbarWidth;
- ClipRect(&growBoxRect);
-
- if (aWindow == FrontWindow())
- DrawGrowIcon(aWindow);
- else
- {
- InsetRect(&growBoxRect, 2, 2);
- EraseRect(&growBoxRect);
- }
-
- SetClip(TWindow::fgScratchRgn);
- SetPort(savedPort);
- }
-
-
-
- WindowRef LastFloatingWindow(void)
- {
- WindowRef aWindow = FrontWindow();
- WindowRef lastFloater = (WindowRef) kNoFloatingWindows;
-
- while ( aWindow != nil && GetWindowKind ( aWindow ) == kFloatingWindowKind )
- {
- if ( IsWindowVisible ( aWindow ))
- lastFloater = (WindowRef) aWindow;
-
- aWindow = GetNextWindow ( aWindow );
- }
-
- return lastFloater;
- }
-
-
-
- WindowRef FrontNonFloatingWindow(void)
- {
- WindowRef aWindow = (WindowRef) LMGetWindowList ();
-
- // Skip over floating windows
- while ( aWindow != nil && GetWindowKind ( aWindow ) == kFloatingWindowKind )
- aWindow = GetNextWindow ( aWindow );
-
- // Skip over invisible, but otherwise normal windows
- while (aWindow != nil && !IsWindowVisible ( aWindow ))
- aWindow = GetNextWindow ( aWindow );
-
- return aWindow;
- }
-
-
- void HiliteAndActivateWindow(WindowRef aWindow,Boolean active)
- {
- GrafPtr oldPort;
- TWindow * wobj = GetWindowObject(aWindow);
-
- if (aWindow)
- {
- HiliteWindow(aWindow,active);
-
- if (wobj != nil)
- {
- GetPort(&oldPort);
- SetPortWindowPort ( aWindow );
- wobj->Activate(active);
- SetPort(oldPort);
- }
- }
- }
-
- void SuspendResumeWindows(Boolean resuming)
- {
- // When we suspend/resume, hide/show all the visible floaters
-
- HiliteShowHideFloatingWindows(resuming,true);
- }
-
- void HiliteWindowsForModalDialog(Boolean hiliting)
- {
- // When we display a modal dialog, we need to unhighlight
- // all visible floaters. We also need to re-hilite them
- // afterwards.
-
- HiliteShowHideFloatingWindows(hiliting,false);
- }
-
- void HiliteShowHideFloatingWindows(Boolean hiliting, Boolean dohiding)
- {
- WindowRef aWindow;
- TWindow * wobj;
-
- HiliteAndActivateWindow(FrontNonFloatingWindow(), hiliting);
-
- aWindow = (WindowRef) LMGetWindowList();
- while ( aWindow != nil && GetWindowKind ( aWindow ) == kFloatingWindowKind )
- {
- wobj = GetWindowObject ( aWindow );
-
- // If we are hiding or showing, only hide/show windows
- // that were visible to begin with.
-
- // NOTE: We use our copy of the visible flag so we can
- // automatically show floaters on a resume event.
-
- // NOTE: Since this isn’t a method of TWindow, we don’t
- // really need the “::” on ShowHide, but as long
- // as we’re trying to avoid ambiguity.
-
- if (dohiding && (wobj != nil) && (wobj->IsVisible()))
- ::ShowHide(aWindow,hiliting);
-
- // All floaters are hilited if any floater is hilited
-
- HiliteWindow( aWindow,hiliting);
- aWindow = GetNextWindow ( aWindow );
- }
- }
-
-
- ///////////////////////////////////////////////////////////////////////////
- //
- // Routines used for dealing with windows and multiple screens
- //
-
- pascal void
- CalculateWindowAreaOnDevice(short /* depth */,short /* deviceFlags */,GDHandle targetDevice,long userData)
- {
- CalcWindowAreaDeviceLoopUserData * deviceLoopDataPtr;
- long windowAreaOnThisScreen;
- Rect windowRectOnThisScreen;
-
- deviceLoopDataPtr = (CalcWindowAreaDeviceLoopUserData *) userData;
-
- SectRect(&deviceLoopDataPtr->fWindowBounds, &(**targetDevice).gdRect,&windowRectOnThisScreen);
- OffsetRect(&windowRectOnThisScreen,-windowRectOnThisScreen.left,-windowRectOnThisScreen.top);
- windowAreaOnThisScreen = windowRectOnThisScreen.right * windowRectOnThisScreen.bottom;
-
- if (windowAreaOnThisScreen > deviceLoopDataPtr->fLargestArea)
- {
- deviceLoopDataPtr->fLargestArea = windowAreaOnThisScreen;
- deviceLoopDataPtr->fScreenWithLargestPartOfWindow = targetDevice;
- }
- }
-
-
- DeviceLoopDrawingUPP CallCalcWindowAreaOnDevice = NewDeviceLoopDrawingProc(&CalculateWindowAreaOnDevice);
-
-
- void
- FindScreenRectWithLargestPartOfWindow(WindowRef aWindow,Rect *theBestScreenRect,GDHandle * theBestDevice)
- {
- RgnHandle copyOfWindowStrucRgn;
- CalcWindowAreaDeviceLoopUserData deviceLoopData;
-
- // Use DeviceLoop to find out what GDevice contains the largest
- // portion of the supplied window.
- //
- // NOTE: Assumes thePort == the Window Manager Port because we using
- // the window strucRgn, not contRgn.
-
- deviceLoopData.fScreenWithLargestPartOfWindow = nil;
- deviceLoopData.fLargestArea = -1;
-
- RgnHandle tempRgn = NewRgn ();
- GetWindowContentRgn ( aWindow, tempRgn );
- deviceLoopData.fWindowBounds = (**tempRgn).rgnBBox;
- DisposeRgn ( tempRgn );
-
- copyOfWindowStrucRgn = NewRgn();
- GetWindowStructureRgn ( aWindow, copyOfWindowStrucRgn );
-
- DeviceLoop(copyOfWindowStrucRgn,CallCalcWindowAreaOnDevice,(long) &deviceLoopData,singleDevices);
-
- DisposeRgn(copyOfWindowStrucRgn);
-
- *theBestDevice = deviceLoopData.fScreenWithLargestPartOfWindow;
- *theBestScreenRect = (**(deviceLoopData.fScreenWithLargestPartOfWindow)).gdRect;
-
- // Leave some space around the edges of the screen so window look good, AND
- // if the best device is the main screen, leave space for the Menubar
-
- InsetRect(theBestScreenRect,kScreenEdgeSlop,kScreenEdgeSlop);
- if (GetMainDevice() == deviceLoopData.fScreenWithLargestPartOfWindow)
- theBestScreenRect->top += GetMBarHeight();
- }
-
-
- ///////////////////////////////////////////////////////////////////////////
- //
- // Drag Manager callback routines which dispatch to a window’s method
- //
-
- pascal OSErr
- CallWindowDragTrackingHandler(DragTrackingMessage dragMessage,WindowRef theWindow,void * /* refCon */,DragReference theDrag)
- {
- TWindow *wobj = GetWindowObject(theWindow);
-
- if (wobj)
- return(wobj->HandleDrag(dragMessage,theDrag));
- else
- return dragNotAcceptedErr;
- }
-
-
- pascal OSErr
- CallWindowDragReceiveHandler(WindowRef theWindow,void * /* refCon */,DragReference theDrag)
- {
- TWindow *wobj = GetWindowObject(theWindow);
-
- if (wobj)
- return(wobj->HandleDrop(theDrag));
- else
- return dragNotAcceptedErr;
- }
-
-
-
-
-