home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C++ / Frameworks / MacZoop 1.1 / More Classes / ZScroller.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-03  |  16.3 KB  |  525 lines  |  [TEXT/CWIE]

  1. /*************************************************************************************************
  2. *
  3. *
  4. *            ObjectMacZapp        -- a standard Mac OOP application template
  5. *
  6. *
  7. *
  8. *            ZScroller.cpp        -- a window with scrollbars
  9. *
  10. *
  11. *
  12. *
  13. *
  14. *            © 1996, Graham Cox
  15. *
  16. *
  17. *
  18. *
  19. *************************************************************************************************/
  20.  
  21.  
  22. #include    "ZScroller.h"
  23. #include    "ZErrors.h"
  24.  
  25.  
  26. static pascal void     ScrollBarZProc(ControlHandle theControl, short partCode);
  27. static pascal void    ThumbZProc();
  28.  
  29. static ControlActionUPP        gScrollbarProc = NewControlActionProc(ScrollBarZProc);
  30. static ControlHandle        gCurrentScrollbar = NULL;
  31.  
  32. /*--------------------------------***  CONSTRUCTOR  ***---------------------------------*/
  33.  
  34. ZScroller::ZScroller(ZCommander* aBoss, short windID, Boolean hasHScroll, Boolean hasVScroll)
  35.     : ZWindow(aBoss, windID)
  36. {
  37.     theHBar = NULL;
  38.     theVBar = NULL;
  39.     SetRect(&scrollBounds,0,0,0,0);
  40.     hScale = 1;
  41.     vScale = 1;
  42.     
  43.     hasHBar = hasHScroll;
  44.     hasVBar = hasVScroll;
  45. }
  46.  
  47.  
  48. /*--------------------------------***  INITZWINDOW  ***---------------------------------*/
  49. /*    
  50.  
  51. overrides the base ZWindow to initialise the scrollbars as well
  52.  
  53. ----------------------------------------------------------------------------------------*/
  54.  
  55. void    ZScroller::InitZWindow()
  56. {
  57.     inherited::InitZWindow();        // do the basic initialisation
  58.     
  59.     MakeScrollbars();            // make the scrollbar controls
  60. }
  61.  
  62.  
  63.  
  64. /*----------------------------------***  ACTIVATE  ***----------------------------------*/
  65. /*    
  66.  
  67. overrides ZWindow to show the scrollbars when the window state changes
  68.  
  69. ----------------------------------------------------------------------------------------*/
  70.  
  71. void    ZScroller::Activate()
  72. {
  73.     if (hasVBar)
  74.         ShowControl(theVBar);
  75.         
  76.     if (hasHBar)
  77.         ShowControl(theHBar);
  78.     
  79.     inherited::Activate();
  80. }
  81.  
  82.  
  83. /*---------------------------------***  DEACTIVATE  ***---------------------------------*/
  84. /*    
  85.  
  86. overrides ZWindow to hide the scrollbars when the window state changes
  87.  
  88. ----------------------------------------------------------------------------------------*/
  89.  
  90.  
  91. void    ZScroller::Deactivate()
  92. {
  93.     if (hasVBar)
  94.         HideControl(theVBar);
  95.         
  96.     if (hasHBar)
  97.         HideControl(theHBar);
  98.         
  99.     inherited::Deactivate();
  100. }
  101.  
  102.  
  103.  
  104. /*------------------------------------***  DRAW  ***------------------------------------*/
  105. /*    
  106.  
  107. overrides ZWindow to draw the content allowing for the scroll and the scrollbars themselves
  108.  
  109. ----------------------------------------------------------------------------------------*/
  110.  
  111. void    ZScroller::Draw()
  112. {
  113.     // need to set the origin to the scroll position here
  114.     
  115.     Rect    content;
  116.     short    fH, fV;
  117.     
  118.     GetContentRect(&content);
  119.     SetOriginToScroll();
  120.     
  121.     GetPosition(&fH, &fV);
  122.     OffsetRect(&content, fH, fV);
  123.     ClipRect(&content);
  124.  
  125.     DrawContent();
  126.     
  127.     SetOrigin(0,0);
  128.     ClipRect(&macWindow->portRect);        
  129.     DrawControls(macWindow);
  130.     DrawGrow();
  131. }
  132.  
  133.  
  134. /*----------------------------------***  DRAWGROW  ***----------------------------------*/
  135. /*    
  136.  
  137. overrides ZWindow to draw the grow box, allowing for the actual scrollbars present
  138.  
  139. ----------------------------------------------------------------------------------------*/
  140.  
  141.  
  142. void    ZScroller::DrawGrow()
  143. {
  144.     // overrides the standard method to clip down to the growbox. This prevents
  145.     // scrollbar lines being drawn when there are no scrollbars in one dimension
  146.  
  147.     Rect    growBoxRect = macWindow->portRect;
  148.     
  149.     if (! hasVBar)
  150.         growBoxRect.top = growBoxRect.bottom - kStdScrollbarWidth;
  151.         
  152.     if (! hasHBar)
  153.         growBoxRect.left = growBoxRect.right - kStdScrollbarWidth;
  154.         
  155.     ClipRect(&growBoxRect);
  156.     DrawGrowIcon(macWindow);
  157.     ClipRect(&macWindow->portRect);
  158. }
  159.  
  160.  
  161.  
  162. /*------------------------------------***  CLICK  ***-----------------------------------*/
  163. /*    
  164.  
  165. overrides ZWindow to handle clicks in the scrollbars and perform the scrolling
  166.  
  167. ----------------------------------------------------------------------------------------*/
  168.  
  169. void    ZScroller::Click(Point mouse, short modifiers)
  170. {
  171.     // handle a click in the content and also the scrollbar clicks
  172.     
  173.     short            partCode,curValue;
  174.     ControlHandle    hitCtl;
  175.     
  176.     partCode = FindControl(mouse, macWindow, &hitCtl);
  177.     
  178.     if(theVBar, vPosition);
  179.         
  180.     Draw();
  181. }
  182.  
  183.  
  184.  
  185. /*-------------------------------***  GETCONTENTRECT  ***-------------------------------*/
  186. /*    
  187.  
  188. get the scrollable portion of the window- the bit you can see, less the scrollbars.
  189.  
  190. ----------------------------------------------------------------------------------------*/
  191.  
  192. void    ZScroller::GetContentRect(Rect* aRect)
  193. {
  194.     // returns the scrollable part of the window. The bit without the scrollbars.
  195.  
  196.     *aRect = macWindow->portRect;
  197.     if (hasVBar)
  198.         aRect->right -= kStdScrollbarWidth;
  199.         
  200.     if (hasHBar)
  201.         aRect->bottom -= kStdScrollbarWidth;
  202. }
  203.  
  204.  
  205.  
  206. /*---------------------------***  CALCULATECONTROLPARAMS  ***---------------------------*/
  207. /*    
  208.  
  209. sets the scrollbar maximums to correctly scroll the scrollarea. This is called when the
  210. scrollbounds or the window frame area changes.
  211.  
  212. ----------------------------------------------------------------------------------------*/
  213.  
  214. void    ZScroller::CalculateControlParams()
  215. {
  216.     // this sets the maximums of the scrollbar to the difference between the content rect and
  217.     // the scrollbounds.
  218.     
  219.     Rect    content;
  220.     short    hMax,vMax;
  221.     
  222.     GetContentRect(&content);
  223.     
  224.     hMax = scrollBounds.right - scrollBounds.left - content.right - content.left;
  225.     vMax = scrollBounds.bottom - scrollBounds.top - content.bottom - content.top;
  226.     
  227.     if (hMax < 0)
  228.         hMax = 0;
  229.         
  230.     if (vMax < 0)
  231.         vMax = 0;
  232.         
  233.     if (hasHBar)
  234.         SetControlMaximum(theHBar, hMax);
  235.         
  236.     if (hasVBar)
  237.         SetControlMaximum(theVBar, vMax);
  238. }
  239.  
  240.  
  241.  
  242. /*-------------------------------***  MAKESCROLLBARS  ***-------------------------------*/
  243. /*    
  244.  
  245. creates the scrollbars as part of the initialisation
  246.  
  247. ----------------------------------------------------------------------------------------*/
  248.  
  249. void    ZScroller::MakeScrollbars()
  250. {
  251.     // create the scrollbar controls initially. This is done by calling NewControl. We
  252.     // figure out the control rects from the window portrect.
  253.     
  254.     Rect    barRect;
  255.     Rect    wPortRect;
  256.     
  257.     wPortRect = macWindow->portRect;
  258.     
  259.     if (hasHBar)
  260.     {
  261.         barRect = wPortRect;
  262.         barRect.right -= kStdScrollbarWidth - 1;
  263.         barRect.top = barRect.bottom - kStdScrollbarWidth - 1;
  264.         barRect.left -= 1;
  265.         OffsetRect(&barRect,0,1);
  266.         
  267.         FailNIL(theHBar = NewControl(macWindow, &barRect, NULL, FALSE, 0, 0, 0, scrollBarProc, (long) this));
  268.     }
  269.     
  270.     if (hasVBar)
  271.     {
  272.         barRect = wPortRect;
  273.         barRect.bottom -= kStdScrollbarWidth - 1;
  274.         barRect.left = barRect.right - kStdScrollbarWidth - 1;
  275.         barRect.top -= 1;
  276.         OffsetRect(&barRect,1,0);
  277.  
  278.         FailNIL(theVBar = NewControl(macWindow, &barRect, NULL, FALSE, 0, 0, 0, scrollBarProc, (long) this));
  279.     }
  280. }
  281.  
  282.  
  283.  
  284. /*-------------------------------***  MOVESCROLLBARS  ***-------------------------------*/
  285. /*    
  286.  
  287. moves the scrollbars to the edges of the window. Called when the window frame size changes.
  288. The scrollbars should generally be hidden before this operation. This then reshows them if
  289. the window is active, and recomputes the max values. If the scroll position is forced to
  290. change as a result, this redraws the content in the correct position.
  291.  
  292. ----------------------------------------------------------------------------------------*/
  293.  
  294. void    ZScroller::MoveScrollbars()
  295. {
  296.     // move the scrollbars after the window size has changed. They should be hidden beforehand
  297.     // and then shown afterwards. This will only show them if the window is active.
  298.     
  299.     Rect        wPortRect;
  300.     short        w,h,hVal = 0,vVal = 0;
  301.     Boolean        isActive;
  302.     
  303.     wPortRect = macWindow->portRect;
  304.     isActive = IsWindowHilited(macWindow);    // using Copland type macro
  305.     
  306.     if (hasHBar)
  307.     {
  308.         hVal = GetControlValue(theHBar);
  309.  
  310.         w = wPortRect.right - wPortRect.left - kStdScrollbarWidth + 2;
  311.         h = kStdScrollbarWidth + 1;
  312.         
  313.         SizeControl(theHBar, w, h );
  314.         MoveControl(theHBar, wPortRect.left - 1, wPortRect.bottom - kStdScrollbarWidth);
  315.         
  316.         if (isActive)
  317.             ShowControl(theHBar);
  318.         
  319.         ValidRect(&(*theHBar)->contrlRect);
  320.     }
  321.     
  322.     if (hasVBar)
  323.     {
  324.         vVal = GetControlValue(theVBar);
  325.         
  326.         h = wPortRect.bottom - wPortRect.top - kStdScrollbarWidth + 2;
  327.         w = kStdScrollbarWidth + 1;
  328.         
  329.         SizeControl(theVBar, w, h );
  330.         MoveControl(theVBar, wPortRect.right - kStdScrollbarWidth,  wPortRect.top - 1 );
  331.         
  332.         if (isActive)
  333.             ShowControl(theVBar);
  334.             
  335.         ValidRect(&(*theVBar)->contrlRect);
  336.     }
  337.     
  338.     CalculateControlParams();    // recompute maximums
  339.     
  340.     if (hasVBar)
  341.         vVal -= GetControlValue(theVBar);
  342.         
  343.     if (hasHBar)
  344.         hVal -= GetControlValue(theHBar);
  345.     
  346.     // if the value of the control changed as a result of altering the maximum, we need to
  347.     // ensure that the contents are scrolled to the right place.
  348.         
  349.     if (hVal || vVal)
  350.     {
  351.         GetContentRect(&wPortRect);
  352.         EraseRect(&wPortRect);
  353.     }
  354. }
  355.  
  356.  
  357.  
  358. /*---------------------------------***  POSTSCROLL  ***---------------------------------*/
  359. /*    
  360.  
  361. You can override this if you are interested in getting called after the thumb of a
  362. scrollbar was dragged.
  363.  
  364. ----------------------------------------------------------------------------------------*/
  365.  
  366. void    ZScroller::PostScroll()
  367. {
  368. }
  369.  
  370.  
  371. /*------------------------------------***  SCROLL  ***----------------------------------*/
  372. /*    
  373.  
  374. shifts the content by dH and dV, updating the revealed area. This is called by the scroll
  375. bar callback function to implement continous scrolling.
  376.  
  377. ----------------------------------------------------------------------------------------*/
  378.  
  379. void    ZScroller::Scroll(short dH, short dV)
  380. {
  381.     // scrolls the content rect. This calls scrollrect to move the majority of the
  382.     // pixels, then calls DrawContent to fill in the rest.
  383.     
  384.     RgnHandle    updateRgn,saveClip;
  385.     Rect        content;
  386.     short        fH,fV;
  387.     
  388.     GetContentRect(&content);
  389.     updateRgn = NewRgn();
  390.     
  391.     GetClip(saveClip = NewRgn());
  392.     ScrollRect(&content, dH, dV, updateRgn);
  393.     
  394.     // need to set the origin of the view to the new location
  395.     
  396.     SetOriginToScroll();
  397.     
  398.     // offset the update region to allow for the origin
  399.     
  400.     GetPosition(&fH, &fV);
  401.     OffsetRgn(updateRgn, fH, fV);
  402.     SetClip(updateRgn);
  403.     
  404.     // draw the update region
  405.     
  406.     DrawContent();
  407.     
  408.     // restore the zero origin
  409.     
  410.     SetOrigin(0,0);
  411.     SetClip(saveClip);
  412.     
  413.     DisposeRgn(saveClip);
  414.     DisposeRgn(updateRgn);
  415. }
  416.  
  417.  
  418. /*-----------------------------***  SETORIGINTOSCROLL  ***------------------------------*/
  419. /*    
  420.  
  421. sets the origin of the grafport to the correct scroll position. This is done to ensure
  422. that the contents get drawn in the right place regardless of where they are scrolled to.
  423.  
  424. ----------------------------------------------------------------------------------------*/
  425.  
  426. void    ZScroller::SetOriginToScroll()
  427. {
  428.     short vOrigin = 0;
  429.     short hOrigin = 0;
  430.     
  431.     if (hasVBar)
  432.         vOrigin = GetControlValue(theVBar);
  433.         
  434.     if (hasHBar)
  435.         hOrigin = GetControlValue(theHBar);
  436.         
  437.     SetOrigin(hOrigin, vOrigin);
  438. }
  439.  
  440.  
  441. /*-------------------------------***  SCROLLHANDLER  ***--------------------------------*/
  442. /*    
  443.  
  444. scrollbar callback function actually changes the scrollbar value as scrolling progresses
  445. and scrolls the content accordingly.
  446.  
  447. ----------------------------------------------------------------------------------------*/
  448.  
  449. void    ZScroller::ScrollHandler(ControlHandle aCtl, short partCode)
  450. {
  451.     // this actually peforms the scroll of the content rect
  452.     
  453.     short        curValue,page;
  454.     Boolean        hitIsVertical;
  455.     Rect        content;
  456.     
  457.     curValue = GetControlValue(aCtl);
  458.     
  459.     // are we scrolling the horizontal or the vertical bar? Find out by comparing
  460.     // the control with one of our data members
  461.     
  462.     hitIsVertical = (aCtl == theVBar);
  463.     
  464.     // calculate the page amount. This is the height or width of the window less one
  465.     // scale amount.
  466.         
  467.     GetContentRect(&content);
  468.     
  469.     if (hitIsVertical)
  470.         page = content.bottom - content.top - vScale;
  471.     else
  472.         page = content.right - content.left - hScale;     
  473.     
  474.     switch (partCode)
  475.     {
  476.         case kControlUpButtonPart:
  477.             SetControlValue(aCtl, GetControlValue(aCtl) - (hitIsVertical? vScale : hScale));
  478.             break;
  479.         case kControlDownButtonPart:
  480.             SetControlValue(aCtl, GetControlValue(aCtl) + (hitIsVertical? vScale : hScale));
  481.             break;
  482.         case kControlPageUpPart:
  483.             SetControlValue(aCtl, GetControlValue(aCtl) - page);
  484.             break;
  485.         case kControlPageDownPart:
  486.             SetControlValue(aCtl, GetControlValue(aCtl) + page);
  487.             break;
  488.     }
  489.  
  490.     curValue -= GetControlValue(aCtl);
  491.     
  492.     if (hitIsVertical)
  493.         Scroll(0, curValue);
  494.     else
  495.         Scroll(curValue, 0);
  496. }
  497.  
  498.  
  499.  
  500.  
  501.  
  502.  
  503.  
  504.  
  505. static pascal void    ScrollBarZProc(ControlHandle theControl, short partCode)
  506. {
  507.     // action proc for passing scrolling callbacks back to the object.
  508.     
  509.     ZScroller*    aScroller = (ZScroller*) GetCRefCon(theControl);
  510.     
  511.     if (aScroller)
  512.         aScroller->ScrollHandler(theControl, partCode);
  513. }
  514.  
  515.  
  516.  
  517. static pascal void    ThumbZProc()
  518. {
  519.  
  520.  
  521.  
  522.  
  523. }
  524.  
  525.