home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / macfe / gui / CToolbarPatternBevelView.cp < prev    next >
Encoding:
Text File  |  1998-04-08  |  9.0 KB  |  276 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. // CToolbarPatternBevelView.cp
  20.  
  21. #include <LArrayIterator.h>
  22.  
  23. #include "CToolbarPatternBevelView.h"
  24. #include "CToolbarButton.h"
  25. #include "StRegionHandle.h"
  26.  
  27. #include <stddef.h>
  28.  
  29. // Bug #79175
  30. // Change the update command status so that the "Show/Hide Component Bar" works
  31. CToolbarPatternBevelView::CToolbarPatternBevelView(LStream* inStream)
  32. :    CPatternBevelView(inStream)
  33. {
  34.     LCommander::SetUpdateCommandStatus(true);
  35. }
  36.  
  37. // Bug #79175
  38. // Change the update command status so that the "Show/Hide Component Bar" works
  39. CToolbarPatternBevelView::~CToolbarPatternBevelView()
  40. {
  41.     LCommander::SetUpdateCommandStatus(true);
  42. }
  43.  
  44. void CToolbarPatternBevelView::HandleModeChange( Int8 inNewMode, SDimension16& outSizeChange )
  45.     {
  46.         CalcArrangement(false, inNewMode, outSizeChange);
  47.     }
  48.  
  49. void CToolbarPatternBevelView::RotateArrangement( SDimension16& outSizeChange )
  50.     {
  51.         CalcArrangement(true, Int8(), outSizeChange);
  52.     }
  53.  
  54. void CToolbarPatternBevelView::CalcArrangement( Boolean inRotateArrangement, Int8 inNewMode, SDimension16& outSizeChange)
  55.     /*
  56.         Note: either rotates the arrangement _or else_ changes the mode, but not both.
  57.  
  58.         ...treats |CToolbarButtons| sub-views as though they are layed out in a grid
  59.         whose cell-size is the maximum height and width of any of them.  In a mode change,
  60.         their sizes change, the grid must be recalculated, and the buttons moved
  61.         appropriately.
  62.     */
  63. {
  64.     size_t                number_of_buttons = 0;
  65.     SDimension16    old_cell_size={ 0, 0 }, new_cell_size={ 0, 0 };
  66.     SDimension16    grid_origin;
  67.  
  68.         /*
  69.             Iterate over the |CToolbarButtons| within me, _twice_...
  70.         */
  71.  
  72.         // ...once to calculate the old and new grid cell-size, and change the mode of each button;
  73.     LPane* current_subview_ptr = 0;
  74.     for ( LArrayIterator iter(mSubPanes); iter.Next(¤t_subview_ptr); )
  75.         if ( CToolbarButton* button = dynamic_cast<CToolbarButton*>(current_subview_ptr) )
  76.             {
  77.                 ++number_of_buttons;
  78.  
  79.                 SDimension16 button_size;
  80.  
  81.                     // Use the pre-ChangeMode size of this button to calculate |old_cell_size|
  82.                 button->GetFrameSize(button_size);
  83.  
  84.  
  85.                     /*
  86.                         The origin of the grid is the remainder when dividing the maximum sized
  87.                         cells offset by its size (independently for x and y).
  88.                     */
  89.  
  90.                 Boolean recalc_origin_x = button_size.width > old_cell_size.width;
  91.                 Boolean recalc_origin_y = button_size.height > old_cell_size.height;
  92.  
  93.                 if ( recalc_origin_x || recalc_origin_y )
  94.                     {
  95.                         Rect button_rect;
  96.                         button->CalcLocalFrameRect(button_rect);
  97.  
  98.                         if ( recalc_origin_x )
  99.                             {
  100.                                 old_cell_size.width = button_size.width;
  101.                                 grid_origin.width = button_rect.left - (button_size.width * (button_rect.left / button_size.width));
  102.                             }
  103.                         else // recalc_origin_y
  104.                             {
  105.                                 old_cell_size.height = button_size.height;
  106.                                 grid_origin.height = button_rect.top - (button_size.height * (button_rect.top / button_size.height));
  107.                             }
  108.                     }
  109.  
  110.  
  111.                 if ( !inRotateArrangement )
  112.                     {
  113.                         button->ChangeMode(inNewMode, SDimension16());
  114.  
  115.                             // ...and the post-ChangeMode size for |new_cell_size|
  116.                         button->GetFrameSize(button_size);
  117.                         if ( new_cell_size.width < button_size.width )
  118.                             new_cell_size.width = button_size.width;
  119.                         if ( new_cell_size.height < button_size.height )
  120.                             new_cell_size.height = button_size.height;
  121.                     }
  122.             }
  123.  
  124.     if ( inRotateArrangement )
  125.         new_cell_size = old_cell_size;
  126.  
  127.  
  128.     Int16 number_of_columns    = 0;
  129.     Int16 number_of_rows        = 0;
  130.  
  131.         // ...and again (if buttons were found in the first pass) to actually move them.
  132.     if ( number_of_buttons > 0 )
  133.         {
  134.             for ( LArrayIterator iter(mSubPanes); (number_of_buttons > 0) && iter.Next(¤t_subview_ptr); )
  135.                 if ( CToolbarButton* button = dynamic_cast<CToolbarButton*>(current_subview_ptr) )
  136.                     {
  137.                         --number_of_buttons;
  138.  
  139.                             // Determine which cell this button occupies.  It hasn't been moved yet, so use |old_cell_size|, and the buttons top-left.
  140.                         Rect button_rect;
  141.                         button->CalcLocalFrameRect(button_rect);
  142.                         Int16 column    = (button_rect.left - grid_origin.width) / old_cell_size.width;
  143.                         Int16 row            = (button_rect.top - grid_origin.height) / old_cell_size.height;
  144.  
  145.                         if ( inRotateArrangement )
  146.                             {
  147.                                 Int16 temp = column;
  148.                                 column = row;
  149.                                 row = temp;
  150.                             }
  151.  
  152.                         if ( number_of_columns <= column )
  153.                             number_of_columns = column + 1;
  154.                         if ( number_of_rows <= row )
  155.                             number_of_rows = row + 1;
  156.  
  157.                             // Calculate the padding needed to center this button within a (new-size) cell.
  158.                         SDimension16 button_size;
  159.                         button->GetFrameSize(button_size);
  160.                         Int16    horizontal_padding    = (new_cell_size.width - button_size.width) / 2;
  161.                         Int16 vertical_padding        = (new_cell_size.height - button_size.height) / 2;
  162.  
  163.                             // Calculate the buttons new position within its superview (i.e., within |me|)
  164.                         Int32 x = grid_origin.width + (column * new_cell_size.width) + horizontal_padding;
  165.                         Int32 y = grid_origin.height + (row * new_cell_size.height) + vertical_padding;
  166.  
  167.                         button->PlaceInSuperFrameAt(x, y, true);    // ...only moves if it has to
  168.                     }
  169.         }
  170.  
  171.     Int16 old_number_of_columns    = inRotateArrangement ? number_of_rows : number_of_columns;
  172.     Int16 old_number_of_rows        = inRotateArrangement ? number_of_columns : number_of_rows;
  173.  
  174.     outSizeChange.width        = (number_of_columns    * new_cell_size.width)    - (old_number_of_columns    * old_cell_size.width);
  175.     outSizeChange.height    = (number_of_rows            * new_cell_size.height)    - (old_number_of_rows            * old_cell_size.height);
  176. }
  177.  
  178. #pragma mark -
  179.  
  180. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  181. //    Ñ FocusDraw
  182. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  183. //    Set up coordinates system and clipping region
  184. //
  185. //    Panes rely on their superview to focus them. When a Pane requests
  186. //    focus for drawing, we set the clipping region to the revealed
  187. //    portion of that Pane's Frame minus the Frames of all sibling Panes
  188. //    that are in front of that Pane.
  189.  
  190. Boolean
  191. CToolbarPatternBevelView::FocusDraw(
  192.     LPane    *inSubPane)
  193. {
  194.     Boolean        revealed = true;
  195.     
  196.     if (inSubPane == nil) {            // Focus this view
  197.         revealed = LView::FocusDraw();
  198.         
  199.     } else {                        // Focus a SubPane
  200.     
  201.         if (EstablishPort()) {        // Set current Mac Port    
  202.             sInFocusView = nil;        // Saved focus is now invalid
  203.                 
  204.                                     // Set up local coordinate system
  205.             ::SetOrigin(mPortOrigin.h, mPortOrigin.v);
  206.             
  207.                                     // Build clipping region
  208.                                     
  209.                                     // Start with the intersection of the
  210.                                     //   revealed rect of this View with the
  211.                                     //   Frame of the SubPane
  212.             Rect    subRect;
  213.             inSubPane->CalcPortFrameRect(subRect);
  214.             
  215.             if (!::SectRect(&subRect, &mRevealedRect, &subRect)) {
  216.                                     // No intersection, so subpane is
  217.                                     //   not revealed. Set empty clip.
  218.                 ::ClipRect(&subRect);
  219.                 return false;
  220.             }
  221.             
  222.                                     // SubPane is revealed. Make region
  223.                                     //   from the intersection.
  224.             StRegionHandle    clipR;
  225.             ::RectRgn(clipR, &subRect);
  226.             
  227.                 // Determine first sibling which is in front of this SubPane.
  228.             ArrayIndexT        subIndex = 0;            
  229.             LPane*            thePane = nil;
  230.             
  231.             {
  232.                 LArrayIterator    iterator(mSubPanes, LArrayIterator::from_Start);
  233.                 while (iterator.Next(&thePane))
  234.                 {    
  235.                     subIndex++;
  236.                     if (thePane == inSubPane)
  237.                         break;
  238.                 }
  239.             }
  240.  
  241.                 // Subtract Frames of all sibling Panes (which are visible)
  242.                 // that are in front of this SubPane (i.e., come after the
  243.                 // SubPane in this View's list of SubPanes.
  244.             
  245.             StRegionHandle    siblingR;
  246.             LArrayIterator    iterator(mSubPanes, subIndex);
  247.             Rect            siblingFrame;
  248.             
  249.             while (iterator.Next(&thePane))
  250.             {                    
  251.                 if (thePane->IsVisible() && thePane->CalcPortFrameRect(siblingFrame))
  252.                 {
  253.                                     // Subtract sibling's Frame from
  254.                                     //   the clipping region
  255.                     ::RectRgn(siblingR, &siblingFrame);
  256.                     ::DiffRgn(clipR, siblingR, clipR);
  257.                 }
  258.             }
  259.  
  260.                                     // Convert Clip region from Port to
  261.                                     //   Local coords and set it
  262.             ::OffsetRgn(clipR, mPortOrigin.h, mPortOrigin.v);
  263.             ::SetClip(clipR);
  264.             
  265.             revealed = !::EmptyRgn(clipR);
  266.  
  267.         } else {
  268.             SignalPStr_("\pFocus View with no GrafPort");
  269.             revealed = false;
  270.         }
  271.     
  272.     }
  273.     
  274.     return revealed;
  275. }
  276.