home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 November: Tool Chest / Dev.CD Nov 98 TC.toast / Sample Code / Snippets / Toolbox / DragWindowGrid / Source / DrawCode.c < prev   
Encoding:
C/C++ Source or Header  |  1996-09-17  |  6.9 KB  |  260 lines  |  [TEXT/CWIE]

  1. #include <Windows.h>
  2. #include <QuickDraw.h>
  3. #include <TextUtils.h>
  4. #include <Fonts.h>
  5. #include <Memory.h>
  6.  
  7. void DragWindowGrid(WindowPtr win, Point pt);
  8. void DrawIt(WindowPtr win);
  9. pascal void DrawWindowContent(short pixelDepth, short dFlags, GDHandle theDevice, long theWin);
  10. void CreateNewWindow(void);
  11. void PreEventLoop(void);
  12. void DoUpdate(WindowPtr thisWindow);
  13. void PostEventLoop(void);
  14.  
  15. /*-------------------------------------------------------------------------------------
  16.  
  17.     DragWindowGrid- a big nasty function to Drag a window along grid lines.  
  18.     Note the elegant error handling.  You should change it to make your users happy.
  19.     
  20.     You can change the size of the 'grid rects' by changing the value of kIncrement.
  21.     
  22. */
  23. void DragWindowGrid(WindowPtr win, Point pt)
  24. {
  25.     RgnHandle    dragRgn, lastDragRgn, insetGray;
  26.     GrafPtr        oldPort, tmpPort;
  27.     Point        currPt, firstMulPoint, lastMulPoint, currMulPoint;
  28.     Boolean        frameHidden;
  29.     enum        {kIncrement = 16, kBorderInset = 4};
  30.  
  31.     // Set up our regions - init our variables.
  32.     dragRgn = NewRgn(); 
  33.     lastDragRgn = NewRgn(); 
  34.     insetGray = NewRgn();
  35.     if ((dragRgn == NULL) || (lastDragRgn == NULL) || (insetGray == NULL)) {
  36.         DebugStr("\pnot enough memory- bye!");
  37.         return;
  38.     }
  39.     CopyRgn(GetGrayRgn(), insetGray);
  40.     if (MemError() != noErr) {
  41.         DebugStr("\pnot enough memory- bye!");
  42.         return;
  43.     }
  44.  
  45.     InsetRgn(insetGray, kBorderInset, kBorderInset);
  46.     frameHidden = false;
  47.  
  48.     // Set up a port to draw into, and save off the old
  49.     tmpPort = (GrafPtr)NewPtr(sizeof(GrafPort));
  50.     if (tmpPort == NULL) {
  51.         DebugStr("\pnot enough memory- bye!");
  52.         return;
  53.     }
  54.     GetPort(&oldPort);
  55.     OpenPort(tmpPort);
  56.     CopyRgn(GetGrayRgn(), tmpPort->visRgn);
  57.     if (MemError() != noErr) {
  58.         DebugStr("\pnot enough memory- bye!");
  59.         return;
  60.     }
  61.     tmpPort->portRect = (*GetGrayRgn())->rgnBBox;
  62.     SetPort(tmpPort);
  63.     
  64.     PenMode(patXor);
  65.     PenPat(&qd.gray);
  66.  
  67.     // Set the incoming point to be on a multiple of kIncrement,
  68.     // to make later calculations easier.
  69.     currMulPoint.h = pt.h + (kIncrement/2);
  70.     currMulPoint.h /= kIncrement; currMulPoint.h *= kIncrement;
  71.     currMulPoint.v = pt.v + (kIncrement/2);
  72.     currMulPoint.v /= kIncrement; currMulPoint.v *= kIncrement;
  73.  
  74.     firstMulPoint = lastMulPoint = currMulPoint;
  75.  
  76.     CopyRgn(((WindowPeek)win)->strucRgn, dragRgn);
  77.     if (MemError() != noErr) {
  78.         DebugStr("\pnot enough memory- bye!");
  79.         return;
  80.     }
  81.  
  82.     CopyRgn(((WindowPeek)win)->strucRgn, lastDragRgn);
  83.     if (MemError() != noErr) {
  84.         DebugStr("\pnot enough memory- bye!");
  85.         return;
  86.     }
  87.  
  88.     // Draw the first framed region, which will follow the mouse
  89.     // on the screen
  90.     FrameRgn(lastDragRgn);
  91.  
  92.     while (WaitMouseUp() == true) {
  93.         // Now track the mouse, and when it moves enough make the framed
  94.         // region move as well.
  95.         GetMouse(&currPt);
  96.     
  97.         // Set the new point to be on a multiple of kIncrement
  98.         currMulPoint.h = currPt.h + (kIncrement/2);
  99.         currMulPoint.h /= kIncrement; currMulPoint.h *= kIncrement;
  100.         currMulPoint.v = currPt.v + (kIncrement/2);
  101.         currMulPoint.v /= kIncrement; currMulPoint.v *= kIncrement;
  102.  
  103.         // Should we be showing the frame region ??
  104.         if (PtInRgn(currPt, insetGray) == false) {
  105.             // It's somewhere near the edges, so hide the frame
  106.             if (frameHidden == false)
  107.                 // if it's not hidden already, hide it now
  108.                 FrameRgn(lastDragRgn);
  109.             frameHidden = true;
  110.         }
  111.         else {
  112.             // else, the frame should be shown if it's hidden
  113.             if (frameHidden == true) {
  114.                 FrameRgn(lastDragRgn);
  115.                 frameHidden = false;
  116.             }
  117.         }
  118.     
  119.         // Has the mouse moved ?
  120.         if (&currMulPoint != &lastMulPoint) {            
  121.             // The mouse coordinates have changed enough to adjust the window,
  122.             // so move the frame accordingly
  123.             OffsetRgn(dragRgn, currMulPoint.h - lastMulPoint.h, currMulPoint.v - lastMulPoint.v);
  124.  
  125.             if (frameHidden == false) {
  126.                 // Only show the frame if we're allowed to.
  127.                 FrameRgn(dragRgn);        
  128.                 FrameRgn(lastDragRgn);
  129.             }
  130.             lastMulPoint = currMulPoint;
  131.             CopyRgn(dragRgn, lastDragRgn);
  132.             if (MemError() != noErr) {
  133.                 DebugStr("\pnot enough memory- bye!");
  134.                 return;
  135.             }
  136.         }    
  137.     }
  138.     
  139.     if (frameHidden == false)
  140.         // If frameHidden is true, there's no need to erase the final
  141.         // frame.
  142.         FrameRgn(lastDragRgn);
  143.  
  144.     if ((&lastMulPoint != &firstMulPoint) && (frameHidden == false)) {
  145.         // The mouse has moved from its original position and is
  146.         // somewhere on the screen, so move the window accordingly.
  147.         Point    globalPt, diffPt, contPt = {0, 0};
  148.  
  149.         // Calculate the difference between the strucRgn's 0, 0 and
  150.         // the window's content region 0, 0.  Remember that MoveWindow
  151.         // moves the window's *content* to the coordinate specified, and
  152.         // we want to move the window's structure to fit in the lastDragRgn
  153.         SetPort(win);
  154.         // LocalToGlobal works much better when the port is set up...
  155.         LocalToGlobal(&contPt);
  156.         SetPort(tmpPort);
  157.         diffPt.h = contPt.h - (*((WindowPeek)win)->strucRgn)->rgnBBox.left;
  158.         diffPt.v = contPt.v - (*((WindowPeek)win)->strucRgn)->rgnBBox.top;
  159.         
  160.         globalPt.h = (*lastDragRgn)->rgnBBox.left;
  161.         globalPt.v = (*lastDragRgn)->rgnBBox.top;
  162.         LocalToGlobal(&globalPt);
  163.         globalPt.h += diffPt.h;
  164.         globalPt.v += diffPt.v;
  165.         MoveWindow(win, globalPt.h, globalPt.v, true);
  166.     }
  167.  
  168.     // Close the port and tear everything down
  169.     ClosePort(tmpPort);
  170.     SetPort(oldPort);
  171.     DisposeRgn(dragRgn);
  172.     DisposeRgn(insetGray);
  173.     DisposeRgn(lastDragRgn);
  174.     
  175. }
  176.  
  177.  
  178. /*-------------------------------------------------------------------------------------*/
  179.  
  180. void DrawIt(WindowPtr win)
  181. {
  182.     short         origFont, origSize;
  183.     
  184.     origFont = win->txFont;
  185.     origSize = win->txSize;
  186.     TextFont(courier);
  187.     TextSize(12);
  188.  
  189.     ForeColor(redColor);
  190.     PaintRect(&(*win).portRect);
  191.     ForeColor(blackColor);
  192.  
  193.     MoveTo(20, 20);
  194.     DrawString("\pDrag this window.");
  195.  
  196.     TextFont(origFont);
  197.     TextSize(origSize);
  198. }
  199.  
  200.  
  201. /*-------------------------------------------------------------------------------------*/
  202.  
  203. pascal void DrawWindowContent(short pixelDepth, short dFlags, GDHandle theDevice, long theWin)
  204. {
  205. #pragma unused (pixelDepth, dFlags, theDevice)
  206.     GrafPtr        savePort;
  207.  
  208.     GetPort(&savePort);
  209.     SetPort((GrafPtr)theWin);
  210.  
  211.     DrawIt((WindowPtr)theWin);
  212.  
  213.     SetPort(savePort);
  214. }
  215.  
  216.  
  217. /*-------------------------------------------------------------------------------------*/
  218.  
  219. void CreateNewWindow(void)
  220. {
  221.     Rect winDimension;
  222.     
  223.     SetRect(&winDimension, 60, 60, 460, 260);
  224.     (void)NewCWindow(0L, &winDimension, "\pSample", true, noGrowDocProc,
  225.                             (WindowPtr)-1L, true, 0L);
  226. }
  227.  
  228.  
  229. /*-------------------------------------------------------------------------------------*/
  230.  
  231. void PreEventLoop(void)
  232. {
  233.     CreateNewWindow();
  234. }
  235.  
  236.  
  237. /*-------------------------------------------------------------------------------------*/
  238.  
  239. void DoUpdate(WindowPtr thisWindow)
  240. {
  241.     static DeviceLoopDrawingUPP    procForDeviceLoop = nil;
  242.  
  243.     SetPort(thisWindow);
  244.  
  245.     if ( procForDeviceLoop == nil )
  246.         procForDeviceLoop = NewDeviceLoopDrawingProc(DrawWindowContent);    
  247.     
  248.     BeginUpdate(thisWindow);
  249.     DeviceLoop(thisWindow->visRgn, procForDeviceLoop, (long)thisWindow, singleDevices);
  250.     EndUpdate(thisWindow);
  251. }
  252.  
  253.  
  254. /*-------------------------------------------------------------------------------------*/
  255.  
  256. void PostEventLoop(void)
  257. {
  258. }
  259.  
  260.