home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Think Class Libraries / CChoicesButton 1.0 / CChoicesButton.cp next >
Encoding:
Text File  |  1994-11-30  |  11.4 KB  |  316 lines  |  [TEXT/KAHL]

  1. /******************************************************************************
  2.  CChoicesButton.c
  3.  
  4.                             The ChoicesButton Class
  5.                             
  6.     A button that can make a window/dialog bigger (“More Choices”) or 
  7.     smaller (“Fewer Choices”). When More Choices is clicked, a range of 
  8.     view items, set with the SetViewsToHide method, will be hidden. Another
  9.     range of items, specified with the SetViewsToMoveUp method, will move
  10.     upwards so that the top of the highest of the items to be moved
  11.     is where the highest of the items that were hidden was. 
  12.     The bottom of the window enclosing the items will move up as
  13.     well. These effects will be reversed when the button is hit again.
  14.     This approach allows you to have a choices button that hides items
  15.     in the middle of the dialog window.
  16.     
  17.     Ordinarily, you will have at least one item to be moved up, the choices
  18.     button itself. However, if the choices button for some reason is on the 
  19.     top of the dialog, and the items to be hidden are at the bottom, then
  20.     to ensure that the window itself shrinks when items are hidden, you should
  21.     add an invisible item to the window, such that the top of the item is the
  22.     bottom of the lowest item that you want hidden. Then specify this item as
  23.     the only item to be moved up.
  24.     
  25.     If you wish the ChoicesButton dialog to do more than simply hide and
  26.     move items (for example, you want some items to change into other items,
  27.     or you want a whole new dialog setup) then you can override this class’s
  28.     DoFewerChoices and DoMoreChoices methods.
  29.     
  30.     You can create such a button in three ways: through a control template, 
  31.     dynamically, or through an overloaded dialog item. With only the last 
  32.     of these methods can you specify in the resource file the views that 
  33.     should be hidden and moved up.
  34.     
  35.     You should always create a window in the more choices state (i.e., so
  36.     that the button reads “Fewer Choices”). If you want the window to be
  37.     in the fewer choices state initially, then call the DoFewerChoices
  38.     method before the window becomes visible.
  39.             
  40.     SUPERCLASS = CButton
  41.     
  42.     Copyright © 1993 Michael Abramowicz. All rights reserved.
  43.  
  44.  ******************************************************************************/
  45.  
  46. #include "CChoicesButton.h"
  47.  
  48. /**** C O N S T R U C T I O N   M E T H O D S ****/
  49.  
  50. /******************************************************************************
  51.  IChoicesButton
  52.  
  53.         Initialize a ChoicesButton object from a control resource. Does not 
  54.         automatically specify which dialog items to hide when More Choices
  55.         is clicked, and which buttons to move up when that button is clicked.
  56.  ******************************************************************************/
  57.  
  58. void    CChoicesButton::IChoicesButton(
  59.     short            CNTLid,                /* CNTL resource ID                    */    
  60.     CView            *anEnclosure,        /* Enclosing view                    */
  61.     CBureaucrat        *aSupervisor)        /* Boss in chain of command            */
  62. {
  63.     inherited::IButton(CNTLid, anEnclosure, aSupervisor);
  64.     IChoicesButtonX();
  65. }
  66.  
  67. /******************************************************************************
  68.  INewChoicesButton
  69.  
  70.      Initialize a Choices button from dynamic parameters, rather than from a
  71.      CNTL resource. The button defaults to the “More Choices” setting.
  72. ******************************************************************************/
  73.  
  74. void CChoicesButton::INewChoicesButton( short aWidth, short aHeight, 
  75.                     short aHEncl, short aVEncl, StringPtr title, Boolean 
  76.                     fVisible, short procID, CView *anEnclosure, 
  77.                     CBureaucrat    *aSupervisor)
  78. {
  79.     inherited::INewButton( aWidth, aHeight, aHEncl, aVEncl, title,
  80.                 fVisible, procID, anEnclosure, aSupervisor);
  81.     IChoicesButtonX();
  82. }    /* CChoicesButton::INewButton */
  83.  
  84. /******************************************************************************
  85.  IChoicesButtonX
  86.  
  87.  Set default values for the choices button. By default, the dialog is set
  88.  to be big (i.e., “Fewer Choices” is the button text).
  89. ******************************************************************************/
  90.  
  91. void CChoicesButton::IChoicesButtonX( void)
  92. {
  93.     SetClickCmd(cmdToggleChoicesButton);
  94.     
  95.     firstToHide = -1;
  96.     lastToHide = -2;
  97.     
  98.     firstToMoveUp = -1;
  99.     lastToMoveUp = -2;
  100.     
  101.     dialogIsBig = TRUE;
  102.     UpdateButtonText();
  103. }
  104.  
  105. /******************************************************************************
  106.  IViewTemp {OVERRIDE}
  107.  
  108.         Initialize a choices button using a template
  109.  ******************************************************************************/
  110. void    CChoicesButton::IViewTemp(
  111.     CView            *anEnclosure,        /* Enclosing view                    */
  112.     CBureaucrat        *aSupervisor,        /* Boss in chain of command            */
  113.     Ptr                viewData)            /* Template with View data            */
  114. {
  115.     ChoicesButtonTempP  choicesTemp = (ChoicesButtonTempP) viewData;
  116.     PaneTemp            thePaneTemp = choicesTemp->sPaneTemp;
  117.     
  118.     INewChoicesButton(thePaneTemp.width, thePaneTemp.height,  
  119.         thePaneTemp.hEncl, thePaneTemp.vEncl, "\p", 
  120.         thePaneTemp.sViewTemp.visible != 0, pushButProc, anEnclosure, 
  121.         aSupervisor);
  122.         
  123.     SetViewsToHide(choicesTemp->firstToHide, choicesTemp->lastToHide);
  124.     SetViewsToMoveUp(choicesTemp->firstToMoveUp, choicesTemp->lastToMoveUp);
  125. }
  126.  
  127. /**** I N F O R M A T I O N  A N D  C O N T R O L  M E T H O D S ****/
  128.  
  129. /******************************************************************************
  130.  UpdateButtonText
  131.  
  132.  Updates the text of the button to read either “Fewer Choices” or “More
  133.  Choices,” as appropriate.
  134. ******************************************************************************/
  135.  
  136. void CChoicesButton::UpdateButtonText (void)
  137. {
  138.     Str255        buttonString;        /* “Fewer Choices” or “More Choices” */
  139.  
  140.     GetIndString(buttonString, kChoicesButtonStrings, dialogIsBig ? 1 : 2);
  141.     SetTitle(buttonString);
  142. }
  143.  
  144. /******************************************************************************
  145.  IsDialogBig
  146. ******************************************************************************/
  147.  
  148. Boolean CChoicesButton::IsDialogBig (void)
  149. {
  150.     return dialogIsBig;
  151. }
  152.  
  153. /******************************************************************************
  154.  SetViewsToHide
  155.  
  156.  Indicate which views to hide when the “Fewer Choices” button is hit. These
  157.  views must be numbered consecutively.
  158. ******************************************************************************/
  159.  
  160. void CChoicesButton::SetViewsToHide (long first, long last)
  161. {
  162.     firstToHide = first;
  163.     lastToHide = last;
  164. }
  165.  
  166. /******************************************************************************
  167.  SetViewsToMoveUp
  168.  
  169.  Indicate which views to move up when the “Fewer Choices” button is hit. These
  170.  views must be numbered consecutively. This button should be included among
  171.  these views.
  172. ******************************************************************************/
  173.  
  174. void CChoicesButton::SetViewsToMoveUp (long first, long last)
  175. {
  176.     firstToMoveUp = first;
  177.     lastToMoveUp = last;
  178. }
  179.  
  180. /**** C L I C K  H A N D L I N G  M E T H O D S ****/
  181.  
  182. /******************************************************************************
  183.  DoFewerChoices
  184.  
  185.  Hide items that should not be visible in the fewer choices mode, and move up
  186.  the items beneath those items so that there is no empty space in the dialog.
  187. ******************************************************************************/
  188.  
  189. void CChoicesButton::DoFewerChoices (void)
  190. {
  191.     CWindow        *theWindow;
  192.     CPane        *itemToHide, *itemToMove;
  193.     long        count;
  194.     long        highestItemToHide;
  195.     long        highestItemToMove;
  196.     LongRect    windowSizeLongRect;
  197.     Rect        windowSize;
  198.     
  199.         // Find the window enclosing the button by taking the item’s
  200.         // enclosure and then that item’s enclosure, etc. until a window
  201.         // is found.
  202.     theWindow = (CWindow *) itsEnclosure;
  203.     while (!member(theWindow, CWindow))
  204.         theWindow = (CWindow *) itsEnclosure->itsEnclosure;
  205.     
  206.         // Determine distance to move up by calculating the difference
  207.         // between the top of the highest item to be hidden and the highest
  208.         // item to be moved.
  209.     if ((firstToHide <= lastToHide) && (firstToMoveUp <= lastToMoveUp)) {
  210.                 /* Default variables determining the highest item in each range
  211.                 to the first item in each range. This is necessary since we need
  212.                 something to compare other items’ tops to. */
  213.         highestItemToHide = ((CPane *) theWindow->FindViewByID(firstToHide))->vEncl;
  214.         highestItemToMove = ((CPane *) theWindow->FindViewByID(firstToMoveUp))->vEncl;
  215.                 /* Determine the top of the items to hide. */
  216.         for (count = firstToHide + 1; count <= lastToHide; count++) {
  217.             itemToHide = (CPane *) theWindow->FindViewByID(count);
  218.             if (itemToHide->vEncl < highestItemToHide)
  219.                 highestItemToHide = itemToHide->vEncl;
  220.         }
  221.                 /* Determine the top of the items to move up. */
  222.         for (count = firstToMoveUp + 1; count <= lastToMoveUp; count++) {
  223.             itemToMove = (CPane *) theWindow->FindViewByID(count);
  224.             if (itemToMove->vEncl < highestItemToMove)
  225.                 highestItemToHide = itemToMove->vEncl;
  226.         }
  227.                 /* Put the difference in an instance variable. */
  228.         distanceToMove = highestItemToMove - highestItemToHide;
  229.     }
  230.     else
  231.         distanceToMove = 0;        /* Can’t compute distance to move. */
  232.  
  233.         // Adjust the bottom of the window containing the items
  234.     theWindow->GetInterior(&windowSizeLongRect);
  235.     LongToQDRect(&windowSizeLongRect, &windowSize);
  236.     theWindow->ChangeSize(windowSize.right - windowSize.left, 
  237.                 windowSize.bottom - windowSize.top - distanceToMove);
  238.  
  239.         // Switch the choices button to say “More Choices”
  240.     dialogIsBig = FALSE;
  241.     UpdateButtonText();
  242.     
  243.         // Hide the items to be hidden.
  244.     for (count = firstToHide; count <= lastToHide; count++) {
  245.         itemToHide = (CPane *) theWindow->FindViewByID(count);
  246.         itemToHide->Hide();
  247.     }
  248.     
  249.         // Move the items to be moved.
  250.     for (count = firstToMoveUp; count <= lastToMoveUp; count++) {
  251.         itemToMove = (CPane *) theWindow->FindViewByID(count);
  252.         itemToMove->Offset(0, 0 - distanceToMove, TRUE);
  253.     }
  254. }
  255.  
  256. /******************************************************************************
  257.  DoMoreChoices
  258.  
  259.  Restore all hidden items, and move the items that moved up back down.
  260. ******************************************************************************/
  261.  
  262. void CChoicesButton::DoMoreChoices (void)
  263. {
  264.     CWindow        *theWindow;
  265.     CPane        *itemToShow, *itemToMove;
  266.     long        count;
  267.     LongRect    windowSizeLongRect;
  268.     Rect        windowSize;
  269.     
  270.         // Find the window enclosing the button by taking the item’s
  271.         // enclosure and then that item’s enclosure, etc. until a window
  272.         // is found.
  273.     theWindow = (CWindow *) itsEnclosure;
  274.     while (!member(theWindow, CWindow))
  275.         theWindow = (CWindow *) itsEnclosure->itsEnclosure;
  276.     
  277.         // Adjust the bottom of the window containing the items
  278.     theWindow->GetInterior(&windowSizeLongRect);
  279.     LongToQDRect(&windowSizeLongRect, &windowSize);
  280.     theWindow->ChangeSize(windowSize.right - windowSize.left, 
  281.                 windowSize.bottom - windowSize.top + distanceToMove);
  282.     
  283.         // Switch the choices button to say “Fewer Choices”
  284.     dialogIsBig = TRUE;
  285.     UpdateButtonText();
  286.     
  287.         // Show the items that need to be shown. 
  288.     for (count = firstToHide; count <= lastToHide; count++) {
  289.         itemToShow = (CPane *) theWindow->FindViewByID(count);
  290.         itemToShow->Show();
  291.     }
  292.  
  293.         // Move the items to be moved.
  294.     for (count = firstToMoveUp; count <= lastToMoveUp; count++) {
  295.         itemToMove = (CPane *) theWindow->FindViewByID(count);
  296.         itemToMove->Offset(0, 0 + distanceToMove, TRUE);
  297.     }
  298. }
  299.  
  300. /******************************************************************************
  301.  DoGoodClick {OVERRIDE}
  302.  
  303.         Respond to a click in the button by changing the dialog as appropriate.
  304.  ******************************************************************************/
  305.  
  306. void    CChoicesButton::DoGoodClick(
  307.     short        whichPart)                /* Will always be inButton            */
  308. {
  309.     if (clickCmd == cmdToggleChoicesButton) {
  310.                                         /* Issue the appropriate command    */
  311.         if (dialogIsBig)
  312.             DoFewerChoices();
  313.         else
  314.             DoMoreChoices();
  315.     }
  316. }