home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 October: Mac OS SDK / Dev.CD Oct 00 SDK1.toast / Development Kits / Mac OS / Appearance SDK 1.0.4 / Appearance Sample Code / Source / FinderWindow.cp < prev    next >
Encoding:
Text File  |  1999-07-16  |  11.7 KB  |  423 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        FinderWindow.cp
  3.  
  4.     Contains:    Finder window simulating using the Appearance Manager.
  5.  
  6.     Version:    Appearance 1.0 SDK
  7.  
  8.     Copyright:    © 1997 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     File Ownership:
  11.  
  12.         DRI:                Edward Voas
  13.  
  14.         Other Contact:        7 of 9, Borg Collective
  15.  
  16.         Technology:            OS Technologies Group
  17.  
  18.     Writers:
  19.  
  20.         (edv)    Ed Voas
  21.  
  22.     Change History (most recent first):
  23.  
  24.          <1>     9/11/97    edv        First checked in.
  25. */
  26.  
  27. //
  28. //    This module demonstrates an Appearance adoption example for a Finder-like window.
  29. //    It uses actual Appearance Manager primitives to draw some of the window elements,
  30. //    such as the window header and placard. Normally, it would be best to use the
  31. //    window header and placard controls, since they take care of enabling and disabling
  32. //    themselves. This, however, is a good example of how to use lower level routines
  33. //    and still be theme savvy.
  34. //
  35. //    Although this window has scroll bars, it doesn't actually scroll anything. It's
  36. //    more an example of getting the visual appearance together.
  37. //
  38.  
  39. #include <MacWindows.h>
  40. #include "FinderWindow.h"
  41. #include "Appearance.h"
  42. #include "ColorPenState.h"
  43. #include "Assertions.h"
  44.  
  45. #define width( r )        ( (r).right - (r).left )
  46. #define height( r )        ( (r).bottom - (r).top )
  47.  
  48. FinderWindow::FinderWindow() : BaseWindow( 128 )
  49. {                
  50.     Rect        rect;
  51.     
  52.         // Note the use of the new defProc constants here.
  53.         // This eliminates the need to go thru the mapping
  54.         // CDEF for scroll bars, which would normally happen
  55.         // after calling RegisterAppearanceClient.
  56.         
  57.     CalcVertScrollBarRect( rect );
  58.     fVertScrollBar = NewControl( fWindow, &rect, "\p", true, 0, 0, 100, kControlScrollBarProc, 0 );
  59.     
  60.     CalcHorizScrollBarRect( rect );
  61.     fHorizScrollBar = NewControl( fWindow, &rect, "\p", true, 0, 0, 100, kControlScrollBarProc, 0 );    
  62. }
  63.  
  64. FinderWindow::~FinderWindow()
  65. {
  66.     if ( fVertScrollBar )
  67.         DisposeControl( fVertScrollBar );
  68.     
  69.     if ( fHorizScrollBar )
  70.         DisposeControl( fHorizScrollBar );
  71. }
  72.  
  73. //————————————————————————————————————————————————————————————————————————————————————
  74. //    • Activate
  75. //————————————————————————————————————————————————————————————————————————————————————
  76. //    Activates the contents of the window.
  77. //
  78. void
  79. FinderWindow::Activate( EventRecord& )
  80. {
  81.     Rect        rect = fWindow->portRect;
  82.     
  83.     SetPort( fWindow );
  84.     InsetRect( &rect, -1, -1 );
  85.     rect.bottom = rect.top + 40;
  86.     ::DrawThemeWindowHeader( &rect, kThemeStateActive );
  87.     ValidRect( &rect );
  88.     
  89.     DrawPlacard( kThemeStateActive, true );
  90.  
  91.         // Here we use the new ActivateControl call. We
  92.         // could have still used HiliteControl, but this
  93.         // is much more straightforward. It also works
  94.         // right with and without embedding, so it's a
  95.         // real good idea to start using it.
  96.         
  97.     ActivateControl( fHorizScrollBar );
  98.     ActivateControl( fVertScrollBar );
  99. }
  100.  
  101. //————————————————————————————————————————————————————————————————————————————————————
  102. //    • Deactivate
  103. //————————————————————————————————————————————————————————————————————————————————————
  104. //    Deactivates the contents of the window.
  105. //
  106. void
  107. FinderWindow::Deactivate( EventRecord& )
  108. {
  109.     Rect        rect = fWindow->portRect;
  110.     
  111.     SetPort( fWindow );
  112.     InsetRect( &rect, -1, -1 );
  113.     rect.bottom = rect.top + 40;
  114.     ::DrawThemeWindowHeader( &rect, kThemeStateDisabled );
  115.     ValidRect( &rect );
  116.     
  117.     DrawPlacard( kThemeStateDisabled, true );
  118.     
  119.         // Here we use the new DeactivateControl call. We
  120.         // could have still used HiliteControl, but this
  121.         // is much more straightforward. It also works
  122.         // right with and without embedding, so it's a
  123.         // real good idea to start using it.
  124.         
  125.     DeactivateControl( fHorizScrollBar );
  126.     DeactivateControl( fVertScrollBar );
  127. }
  128.  
  129. //————————————————————————————————————————————————————————————————————————————————————
  130. //    • Draw
  131. //————————————————————————————————————————————————————————————————————————————————————
  132. //    Draws our window. Appearance Manager calls handle multiple devices properly. We
  133. //    need to call DeviceLoop to handle drawing our list view, though.
  134. //
  135. void
  136. FinderWindow::Draw()
  137. {
  138.     Rect                    rect = fWindow->portRect;
  139.     ThemeDrawState            drawState;
  140.     RgnHandle                rgn;
  141.     DeviceLoopDrawingUPP    proc;
  142.     
  143.     UpdateControls( fWindow, fWindow->visRgn );
  144.     
  145.     drawState = ((WindowPeek)fWindow)->hilited ? kThemeStateActive : kThemeStateDisabled;
  146.     
  147.     ::SetPort( fWindow );
  148.     ::InsetRect( &rect, -1, -1 );
  149.     rect.bottom = rect.top + 40;
  150.     ::DrawThemeWindowHeader( &rect, drawState );
  151.     
  152.     GetContentRect( rect );
  153.  
  154.     rgn = NewRgn();
  155.     RectRgn( rgn, &rect );
  156.     
  157.     proc = NewDeviceLoopDrawingProc( DrawListView );
  158.     DeviceLoop( rgn, proc, (long)this, 0 );
  159.     DisposeRoutineDescriptor( proc );
  160.     
  161.     DisposeRgn( rgn );
  162.  
  163.     DrawPlacard( drawState, false );
  164. }
  165.  
  166. //————————————————————————————————————————————————————————————————————————————————————
  167. //    • DrawListView
  168. //————————————————————————————————————————————————————————————————————————————————————
  169. //    Draws our list view columns, using the correct theme brushes.
  170. //
  171. pascal void
  172. FinderWindow::DrawListView( SInt16 depth, SInt16 flags, GDHandle /*device*/, long userData )
  173. {
  174.     FinderWindow*    window = (FinderWindow*)userData;
  175.     Rect            rect;
  176.     ColorPenState    state;
  177.     SInt16            baseLine;
  178.     
  179.     window->GetContentRect( rect );
  180.     
  181.         // Because the brushes used by the Appearance Manager could
  182.         // be colors or patterns, our GetColorAndPenState routine
  183.         // always saves the current background pattern as well as the
  184.         // fore and back colors.
  185.         
  186.     ::GetColorAndPenState( &state );
  187.  
  188.     ::SetThemeBackground( kThemeListViewBackgroundBrush, depth, (flags & gdDevType) != 0 );
  189.     ::EraseRect( &rect );
  190.     
  191.     rect.left += 40;
  192.     rect.right = rect.left + 120;
  193.     
  194.     ::SetThemeBackground( kThemeListViewSortColumnBackgroundBrush, depth, (flags & gdDevType) != 0 );
  195.     ::EraseRect( &rect );
  196.  
  197.     ::SetThemePen( kThemeListViewSeparatorBrush, depth, (flags & gdDevType) != 0 );
  198.  
  199.     window->GetContentRect( rect );
  200.     
  201.     for ( baseLine = rect.top; baseLine <= rect.bottom; baseLine += 15 )
  202.     {
  203.         ::MoveTo( rect.left, baseLine );
  204.         ::LineTo( rect.right - 1, baseLine );
  205.     }
  206.     
  207.     ::SetColorAndPenState( &state );
  208. }
  209.  
  210. //————————————————————————————————————————————————————————————————————————————————————
  211. //    • Resize
  212. //————————————————————————————————————————————————————————————————————————————————————
  213. //    Resize our window to the appropriate size specified in width and height. Make sure
  214. //    the scroll bars are repositioned properly.
  215. //
  216. void
  217. FinderWindow::Resize( SInt16 width, SInt16 height )
  218. {
  219.     Rect        horizRect, vertRect;
  220.     
  221.     if ( width > width( fWindow->portRect ) )
  222.     {
  223.         Rect    temp = fWindow->portRect;
  224.         
  225.         temp.left = temp.right - 5;
  226.         temp.bottom = 40;
  227.         InvalRect( &temp );
  228.     }
  229.     InvalidateScrollBars();
  230.     InvalidatePlacard();
  231.     
  232.     BaseWindow::Resize( width, height );
  233.     
  234.     InvalidateScrollBars();
  235.     InvalidatePlacard();
  236.     
  237.     CalcHorizScrollBarRect( horizRect );
  238.     CalcVertScrollBarRect( vertRect );
  239.     
  240.     MoveControl( fHorizScrollBar, horizRect.left, horizRect.top );
  241.     MoveControl( fVertScrollBar, vertRect.left, vertRect.top );
  242.     SizeControl( fHorizScrollBar, width( horizRect ), height( horizRect ) );
  243.     SizeControl( fVertScrollBar, width( vertRect ), height( vertRect ) );
  244. }
  245.  
  246. //————————————————————————————————————————————————————————————————————————————————————
  247. //    • HandleClick
  248. //————————————————————————————————————————————————————————————————————————————————————
  249. //    Simple routine to handle scroll bar tracking, even though they don't do anything.
  250. //
  251. void
  252. FinderWindow::HandleClick( EventRecord& event )
  253. {
  254.     ControlHandle        control;
  255.     SInt16                part;
  256.     Point                localPt;
  257.     ControlActionUPP    actionProc;
  258.     
  259.     SetPort( fWindow );
  260.     localPt = event.where;
  261.     GlobalToLocal( &localPt );
  262.     
  263.     part = FindControl( localPt, fWindow, &control );
  264.     switch ( part )
  265.     {
  266.         case kControlUpButtonPart:
  267.         case kControlDownButtonPart:
  268.         case kControlPageUpPart:
  269.         case kControlPageDownPart:
  270.             actionProc = NewControlActionProc( ScrollBarAction );
  271.             TrackControl( control, localPt, actionProc );
  272.             DisposeRoutineDescriptor( actionProc );
  273.             break;
  274.         
  275.         case kControlIndicatorPart:
  276.             TrackControl( control, localPt, (ControlActionUPP)-1L );
  277.             break;
  278.     }
  279. }
  280.  
  281. //————————————————————————————————————————————————————————————————————————————————————
  282. //    • GetContentRect
  283. //————————————————————————————————————————————————————————————————————————————————————
  284. //    Get our content rect, which is the area not including the scroll bars and the
  285. //    window header. It is basically the list view area.
  286. //
  287. void
  288. FinderWindow::GetContentRect( Rect& rect )
  289. {
  290.     rect = fWindow->portRect;
  291.     
  292.     rect.bottom -= 15;
  293.     rect.right -= 15;
  294.     rect.top += 39;
  295. }
  296.  
  297. //————————————————————————————————————————————————————————————————————————————————————
  298. //    • DrawPlacard
  299. //————————————————————————————————————————————————————————————————————————————————————
  300. //    Draws our placard next to the horizontal scroll bar.
  301. //
  302. void
  303. FinderWindow::DrawPlacard( ThemeDrawState state, Boolean validate )
  304. {
  305.     Rect        rect;
  306.     
  307.     rect = fWindow->portRect;
  308.     
  309.     rect.bottom++;
  310.     rect.left--;
  311.     rect.top = rect.bottom - 16;
  312.     rect.right = 121;
  313.     
  314.     ::DrawThemePlacard( &rect, state );
  315.     if ( validate )
  316.         ValidRect( &rect );
  317. }
  318.  
  319. //————————————————————————————————————————————————————————————————————————————————————
  320. //    • InvalidateScrollBars
  321. //————————————————————————————————————————————————————————————————————————————————————
  322. //    Invalidates the scroll bar areas.
  323. //
  324. void
  325. FinderWindow::InvalidateScrollBars()
  326. {
  327.     Rect        tempRect;
  328.     
  329.     SetPort( fWindow );
  330.     CalcHorizScrollBarRect( tempRect );
  331.     InvalRect( &tempRect );
  332.     EraseRect( &tempRect );
  333.     
  334.     CalcVertScrollBarRect( tempRect );
  335.     InvalRect( &tempRect );
  336.     EraseRect( &tempRect );
  337. }
  338.  
  339. //————————————————————————————————————————————————————————————————————————————————————
  340. //    • InvalidatePlacard
  341. //————————————————————————————————————————————————————————————————————————————————————
  342. //    Invalidates the placard area.
  343. //
  344. void
  345. FinderWindow::InvalidatePlacard()
  346. {
  347.     Rect        rect;
  348.     
  349.     rect = fWindow->portRect;
  350.     
  351.     rect.bottom++;
  352.     rect.top = rect.bottom - 16;
  353.     rect.right = 121;
  354.     rect.left--;
  355.  
  356.     InvalRect( &rect );
  357.     EraseRect( &rect );
  358. }
  359.  
  360. //————————————————————————————————————————————————————————————————————————————————————
  361. //    • CalcHorizScrollBarRect
  362. //————————————————————————————————————————————————————————————————————————————————————
  363. //    Calculates the position where the horizontal scroll bar should be placed.
  364. //
  365. void
  366. FinderWindow::CalcHorizScrollBarRect( Rect& rect )
  367. {
  368.     rect = fWindow->portRect;
  369.     rect.bottom++;
  370.     rect.left = rect.left + 120;
  371.     rect.top = rect.bottom - 16;
  372.     rect.right -= 14;
  373. }
  374.  
  375. //————————————————————————————————————————————————————————————————————————————————————
  376. //    • CalcVertScrollBarRect
  377. //————————————————————————————————————————————————————————————————————————————————————
  378. //    Calculates the position where the vertical scroll bar should be placed.
  379. //
  380. void
  381. FinderWindow::CalcVertScrollBarRect( Rect& rect )
  382. {
  383.     rect = fWindow->portRect;
  384.     rect.right++;
  385.     rect.left = rect.right - 16;
  386.     rect.bottom -= 14;
  387.     rect.top = 38;
  388. }
  389.  
  390. //————————————————————————————————————————————————————————————————————————————————————
  391. //    • ScrollBarAction
  392. //————————————————————————————————————————————————————————————————————————————————————
  393. //    A simple callback to give some feedback when clicking the scroll arrows or page
  394. //    up/down areas.
  395. //
  396. pascal void
  397. FinderWindow::ScrollBarAction( ControlHandle control, SInt16 part )
  398. {
  399.     switch ( part )
  400.     {
  401.         case kControlUpButtonPart:
  402.             if ( GetControlValue( control) > GetControlMinimum( control ) )
  403.                 SetControlValue( control, GetControlValue( control ) - 1 );
  404.             break;
  405.         
  406.         case kControlDownButtonPart:
  407.             if ( GetControlValue( control) < GetControlMaximum( control ) )
  408.                 SetControlValue( control, GetControlValue( control ) + 1 );
  409.             break;
  410.             
  411.         case kControlPageUpPart:
  412.             if ( GetControlValue( control) > GetControlMinimum( control ) )
  413.                 SetControlValue( control, GetControlValue( control ) - 10 );
  414.             break;
  415.             
  416.         case kControlPageDownPart:
  417.             if ( GetControlValue( control) < GetControlMaximum( control ) )
  418.                 SetControlValue( control, GetControlValue( control ) + 10 );
  419.             break;
  420.     }            
  421. }
  422.  
  423.