home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 …ember: Reference Library / Apple Developer Reference Library (December 1999) (Disk 1).iso / pc / technical documentation / develop / develop issue 26 / develop issue 26 code / truffles - display mgr. / superfly source / superflytoolwindow.cp < prev    next >
Encoding:
Text File  |  1996-06-13  |  8.7 KB  |  321 lines

  1. /*
  2.     File:        SuperFlyToolWindow.cp
  3.  
  4.     Contains:    A tool palette with floating heads that follows the GDevice
  5.                 when it moves or resizes.
  6.                 
  7.     Written by: Kent Miller
  8.     
  9.     Copyright:    © 1996 Apple Computer
  10.     
  11.     Notes:        Dave Falkenburg and I were talking about some behavior that
  12.                 some floating windows (like Control Strip) have when the display 
  13.                 resizes.  If the window ends up somewhere on an active screen,
  14.                 the Display Manager's default window moving code won't attempt to 
  15.                 keep the window relative to its previous position.
  16.                 
  17.                 We think the behavior you really want is for the floating
  18.                 window to move to the position in the new graphics world
  19.                 relative to where it was in the old world.  That is, if
  20.                 your Control Strip is in the bottom right of the display before
  21.                 the world changed, it should be on the bottom right of the same
  22.                 display in the new world.  (Maybe it should follow the menu bar
  23.                 if it is on the main screen when the menu bar moves?)
  24.                 
  25.                 This file is meant to be a first crack at trying to be smart about
  26.                 the placement of a tool palette when the world changes.  It will
  27.                 try to remain in the same place on the same device it was on when
  28.                 the devices get resized or rearranged.
  29.                 
  30.                 It exhibits weird behavior with the large tool palette when the 
  31.                 screen changes sizes.  Try it out with 2 displays turning mirroring
  32.                 on & off and see what I mean.  How could this be made better?
  33.             
  34.                 The Toolbar's WDEF is the Infinity Windoid by Troy Gaul.  Email
  35.                 tgaul@halcyon.com for more information.
  36.                 
  37.     Change History (most recent first):
  38.  
  39.  */
  40.  
  41. #include <Displays.h>
  42. #include <Icons.h>
  43. #include <QDOffscreen.h>
  44.  
  45.  
  46. #include "Window.h"
  47. #include "SuperFly.h"
  48. #include "SuperFlyToolWindow.h"
  49.  
  50. TSuperFlyToolWindow::TSuperFlyToolWindow()
  51.     {
  52.     this->CreateWindow(kFloatingWindow);
  53.     }
  54.  
  55. TSuperFlyToolWindow::~TSuperFlyToolWindow()
  56.     {
  57.     }
  58.  
  59.     
  60. void
  61. TSuperFlyToolWindow::Drag(Point startPoint)
  62. //I stole this from Window.cp in Sprocket and stripped out the part that
  63. //checked for window type since I know it's a floating window.
  64.     {
  65.     GrafPtr        savePort;
  66.     KeyMap        theKeyMap;
  67.     long        dragResult;
  68.     Boolean        commandKeyDown = false;
  69.     
  70.     if (WaitMouseUp())        //    de-bounce?
  71.         {
  72.         // Set up the Window Manager port.
  73.     
  74.         GetPort(&savePort);
  75.         SetPort(gWindowManagerPort);
  76.         SetClip(GetGrayRgn());
  77.  
  78.         // Check to see if the command key is down.
  79.     
  80.         GetKeys(theKeyMap);
  81.         commandKeyDown = ((theKeyMap[1] & 0x8000) != 0);
  82.         
  83.         ClipAbove(FrontNormalWindow());
  84.  
  85.         //    Drag an outline of the window around the desktop.
  86.         //    NOTE: DragGrayRgn destroys the region passed in, so make a copy
  87.  
  88.         RgnHandle    tempRgn = NewRgn();
  89.  
  90.         GetWindowStructureRgn(fWindow, tempRgn);
  91.         dragResult = DragGrayRgn(tempRgn, startPoint, &gDeskRectangle, &gDeskRectangle, noConstraint, nil);
  92.  
  93.         DisposeRgn(tempRgn);    
  94.  
  95.         SetPort(savePort);    //    Get back to old port
  96.  
  97.         if ((dragResult != 0) && (dragResult != 0x80008000))
  98.             this->Nudge((short) (dragResult & 0xFFFF),(short) (dragResult >> 16));
  99.         }
  100.  
  101.     if (!commandKeyDown)
  102.         this->Select();
  103.         
  104.     //The reason I overrode this method was so after I moved the toolbar, I could determine
  105.     //which display the toolbar was on and save its rectangle.
  106.     this->CalculateRelativePosition();
  107.     }
  108.  
  109. WindowPtr
  110. TSuperFlyToolWindow::MakeNewWindow(WindowPtr behindWindow)
  111.     {
  112.     Rect         r;
  113.     WindowPtr    theWindow;
  114.     GDHandle    mainGD;
  115.     
  116.     SetRect(&r, 50,50,100,300);
  117.     
  118.     theWindow = this->GetNewWindow(1027, nil, behindWindow);
  119.     
  120.     if (theWindow != nil)
  121.         {
  122.         SetWTitle(theWindow, "\p");
  123.         SizeWindow(theWindow, kToolButtonSize, (kToolButtonSize*kNumIcons)+3, true);
  124.         ShowWindow(theWindow);
  125.         mainGD = GetMainDevice();
  126.         this->myStrucRect = (**((WindowPeek) theWindow)->strucRgn).rgnBBox;
  127.         this->oldScreenRect = (**mainGD).gdRect;
  128.         DMGetDisplayIDByGDevice(mainGD, &this->theID, false);
  129.         }
  130.     return(theWindow);
  131.     }
  132.  
  133.  
  134. void
  135. TSuperFlyToolWindow::Draw(void)
  136.     {
  137.     RGBColor      myGray = {0xCCCC,0xCCCC,0xCCCC};
  138.     GrafPtr        savePort;
  139.     PicHandle    thePicture;
  140.     Rect        theToolRect = {0, 0, 63, 63};
  141.     SInt16        i;
  142.     
  143.     GetPort(&savePort);
  144.     SetPort(this->fWindow);
  145.     
  146.     ForeColor(blackColor);
  147.     BackColor(whiteColor);
  148.     
  149.     for(i=0; i<kNumIcons; i++)
  150.         {
  151.         thePicture = GetPicture(kIconBase+i);        
  152.         if (thePicture != nil)
  153.             {
  154.             DrawPicture(thePicture, &theToolRect);
  155.             MoveTo( 0, ( (kToolButtonSize+1) *i)+kToolButtonSize +1);
  156.             Line(kToolButtonSize,0);
  157.             }
  158.         OffsetRect(&theToolRect,0,kToolButtonSize+2);
  159.         }
  160.  
  161.     SetPort(savePort);
  162.     
  163.     }
  164.     
  165. void
  166. TSuperFlyToolWindow::Click(EventRecord * anEvent)
  167. //Not meant to be an example of how to to drag manager code
  168.     {
  169.     DragReference    theDrag;
  170.     Rect            dragBounds;
  171.     RgnHandle        dragRgn;
  172.     RgnHandle        tempRgn;
  173.     RgnHandle        imageRgn;
  174.     
  175.     SInt16            whichHead;
  176.     PicHandle        theHead;
  177.     GrafPtr            savePort;
  178.     UInt8            saveHState;
  179.     
  180.     theDrag = 0;
  181.     dragRgn = nil;
  182.     tempRgn = nil;
  183.     imageRgn = nil;
  184.     theHead = nil;
  185.  
  186.     
  187.     if (!gHasDragManager)
  188.         return;
  189.  
  190.     GetPort(&savePort);
  191.     SetPort(this->fWindow);
  192.  
  193.     if (!WaitMouseMoved(anEvent->where))
  194.         goto badExit;
  195.  
  196.     whichHead = (anEvent->where.v / (kToolButtonSize+1));  //zero based
  197.     theHead = GetPicture(kIconBase+whichHead);
  198.     if (theHead == nil)
  199.         goto badExit;
  200.  
  201.     if (noErr != NewDrag(&theDrag))
  202.         goto badExit;
  203.  
  204.     saveHState = HGetState((Handle) theHead);
  205.     HLock((Handle) theHead);
  206.     AddDragItemFlavor(theDrag, 1, 'PICT', *theHead, GetHandleSize((Handle)theHead), 0);
  207.     HSetState((Handle) theHead, saveHState);
  208.  
  209.     //What is the Rect of this particular head?
  210.     dragBounds.top = whichHead * (kToolButtonSize+1);
  211.     dragBounds.bottom = dragBounds.top + kToolButtonSize;
  212.     dragBounds.left = 0;
  213.     dragBounds.right = kToolButtonSize;
  214.     LocalToGlobal( (Point *) &dragBounds.top);
  215.     LocalToGlobal( (Point *) &dragBounds.bottom);
  216.     LocalToGlobal( (Point *) &anEvent->where);
  217.  
  218.     dragRgn = NewRgn();
  219.     RectRgn(dragRgn, &dragBounds);
  220.     tempRgn = NewRgn();
  221.     CopyRgn(dragRgn, tempRgn);
  222.     InsetRgn(tempRgn, 1, 1);
  223.     DiffRgn(dragRgn, tempRgn, dragRgn);
  224.  
  225.     TrackDrag(theDrag, anEvent, dragRgn);
  226.  
  227.     GlobalToLocal( (Point *) &anEvent->where);
  228.  
  229. badExit:
  230.     SetPort( savePort);
  231.     if (theHead) ReleaseResource( (Handle) theHead);
  232.     if (theDrag) (void) DisposeDrag(theDrag);
  233.     if (dragRgn) DisposeRgn(dragRgn);
  234.     if (tempRgn) DisposeRgn(tempRgn);
  235.     }
  236.  
  237. Boolean
  238. TSuperFlyToolWindow::Close()
  239.     {
  240.     gMyToolWindow = nil;
  241.     return TWindow::Close();
  242.     }
  243.  
  244.  
  245. void
  246. TSuperFlyToolWindow::CalculateRelativePosition(void)
  247.     {
  248.     GDHandle    bestGD, oldGD;
  249.     WindowPeek    windowAsWindowPeek = (WindowPeek) this->fWindow;
  250.     Rect        r;
  251.  
  252.     FindScreenRectWithLargestPartOfWindow(this->fWindow,&r,&bestGD);
  253.     this->oldScreenRect = (**bestGD).gdRect;
  254.     //Is my current position still on the display I was on?  If so, then don't
  255.     //change my stored ID. This is necessary when you turn mirroring off and on.
  256.     //Since the Tool bar is on 2 GDevices, the tool bar could "hop" gdevices depending
  257.     //on which one was first in the device list.
  258.     DMGetGDeviceByDisplayID(this->theID, &oldGD, false);
  259.     if (! SectRect(&(**oldGD).gdRect, &(**bestGD).gdRect, &r) )
  260.         DMGetDisplayIDByGDevice(bestGD, &this->theID, false);
  261.     this->myStrucRect = (**(windowAsWindowPeek)->strucRgn).rgnBBox;
  262.     }
  263.     
  264.     
  265. void
  266. TSuperFlyToolWindow::MoveToRelativePosition(void)
  267.     {
  268.     GDHandle    toolGD;
  269.     WindowPeek    windowAsWindowPeek = (WindowPeek) fWindow;
  270.     SInt16        newH, newV, right, left, top, bottom, titleBarHeight, err;
  271.     
  272.     //Has the device I was on moved in global space or changed sizes?
  273.     err = DMGetGDeviceByDisplayID(this->theID, &toolGD, false);
  274.     if (err != noErr)
  275.         {
  276.         //my GDevice might have disappeared so I'll put the toolbar on the main device
  277.         toolGD = GetMainDevice();
  278.         this->theID = DMGetDisplayIDByGDevice(toolGD, &this->theID, false);
  279.         }
  280.     
  281.     //How far was I from the right?
  282.     right = oldScreenRect.right - this->myStrucRect.right;
  283.     //Left?
  284.     left = this->myStrucRect.left - oldScreenRect.left;
  285.     //Top?
  286.     top = this->myStrucRect.top - oldScreenRect.top;
  287.     //Bottom?
  288.     bottom = oldScreenRect.bottom - this->myStrucRect.bottom;
  289.     
  290.     PinAtZero(right);
  291.     PinAtZero(left);
  292.     PinAtZero(top);
  293.     PinAtZero(bottom);
  294.     
  295.     //Was I closer to the left or right before?
  296.     if (right < left) 
  297.         //If I was closer to the right, I want to hug the right
  298.         newH = (**toolGD).gdRect.right - right - (this->myStrucRect.right - this->myStrucRect.left);
  299.     else
  300.         newH = (**toolGD).gdRect.left + left;
  301.         
  302.     //Was I closer to the top or bottom before?
  303.     if (top < bottom)
  304.         newV = (**toolGD).gdRect.top + top;
  305.     else
  306.         newV = (**toolGD).gdRect.bottom - bottom - (this->myStrucRect.bottom - this->myStrucRect.top);
  307.     
  308.     //Account for the title bar.
  309.     titleBarHeight = (**windowAsWindowPeek->contRgn).rgnBBox.top - (**windowAsWindowPeek->strucRgn).rgnBBox.top;
  310.     newV += titleBarHeight;
  311.  
  312.     //Would my new tool palette be behind the menu bar?
  313.     if (TestDeviceAttribute(toolGD, mainScreen))
  314.         {
  315.         if ( newV < LMGetMBarHeight())
  316.             newV += LMGetMBarHeight();
  317.         }
  318.     
  319.     MoveWindow(this->fWindow, newH, newV, false);
  320.     this->CalculateRelativePosition();
  321.     }