home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / mac / UserInterface / CBevelView.cp < prev    next >
Encoding:
Text File  |  1998-04-08  |  10.8 KB  |  388 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. #ifdef PowerPlant_PCH
  20. #include PowerPlant_PCH
  21. #endif
  22.  
  23. #include "CBevelView.h"
  24.  
  25. #include <LStream.h>
  26. #include <UDrawingState.h>
  27. #include <UDrawingUtils.h>
  28. #include <UResourceMgr.h>
  29. #include <LArrayIterator.h>
  30. #include <URegions.h>
  31.  
  32.     
  33. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  34. //    Ñ    
  35. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  36.  
  37. CBevelView::CBevelView(LStream *inStream)
  38.     :    LView(inStream),
  39.         mBevelList(sizeof(SSubBevel)),
  40.         mBevelGrowIcon(true)
  41. {
  42.     *inStream >> mMainBevel;
  43.     
  44.     ResIDT theBevelResID;
  45.     *inStream >> theBevelResID;
  46.     
  47.     if (theBevelResID != 0)
  48.         {
  49.         StResource theBevelRes(ResType_BevelDescList, theBevelResID);
  50.  
  51.             {
  52.                 StHandleLocker theLock(theBevelRes);
  53.                 LDataStream theBevelStream(*theBevelRes.mResourceH, ::GetHandleSize(theBevelRes));
  54.                     
  55.                 SSubBevel theDesc;
  56.                 ::SetRect(&theDesc.cachedLocalFrame, 0, 0, 0, 0);            
  57.                 while (!theBevelStream.AtEnd())
  58.                     {
  59.                     theBevelStream >> theDesc.paneID;
  60.                     theBevelStream >> theDesc.bevelLevel;
  61.                     mBevelList.InsertItemsAt(1, LArray::index_Last, &theDesc);
  62.                     }
  63.             }
  64.         }
  65.                             
  66.     mNeedsRecalc = true;
  67.     SetRefreshAllWhenResized(false);
  68. }
  69.  
  70. CBevelView::~CBevelView()
  71. {
  72. }
  73.  
  74. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  75. //    Ñ    
  76. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  77.  
  78. void CBevelView::FinishCreateSelf(void)
  79. {
  80.     CalcBevelRegion();
  81.     CalcBevelMask();
  82. }
  83.  
  84. void CBevelView::ResizeFrameBy(
  85.     Int16            inWidthDelta,
  86.     Int16            inHeightDelta,
  87.     Boolean            inRefresh)
  88. {
  89.  
  90.     if ((inWidthDelta == 0) && (inHeightDelta == 0)) return;    // Don't need any changes
  91.  
  92.     if (inRefresh)
  93.         {
  94.         // Force an update on the region that represents the main bevel area and
  95.         // subframes
  96.         InvalMainFrame();
  97.         InvalSubFrames();
  98.  
  99.         // We need to flag the resize because we know we're going to redraw.  If we
  100.         // don't, the gray area will get drawing in it's pre-resize shape.
  101.         if (inRefresh)
  102.             mNeedsRecalc = true;
  103.  
  104.         LView::ResizeFrameBy(inWidthDelta, inHeightDelta, inRefresh);
  105.         CalcBevelRegion();
  106.         CalcBevelMask();
  107.  
  108.  
  109.         // Force an update on the region that represents the main bevel area and
  110.         // subframes
  111.         InvalMainFrame();
  112.         InvalSubFrames();
  113.         }
  114.     else
  115.         {
  116.         LView::ResizeFrameBy(inWidthDelta, inHeightDelta, inRefresh);
  117.         CalcBevelRegion();
  118.         CalcBevelMask();
  119.         }
  120. }
  121.  
  122. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  123. //    Ñ    
  124. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  125.  
  126. void CBevelView::DrawSelf(void)
  127. {
  128.     if (mNeedsRecalc)
  129.         CalcBevelRegion();
  130.         
  131.     StColorPenState theState;
  132.     theState.Normalize();
  133.         
  134.     StClipRgnState theClipSaver(mBevelRegion);
  135.     
  136.     DrawBeveledFill();
  137.     DrawBeveledFrame();
  138.  
  139.     LArrayIterator iterator(mBevelList, LArrayIterator::from_Start);
  140.     SSubBevel theBevelDesc;
  141.     while (iterator.Next(&theBevelDesc))
  142.         {
  143.         Boolean visible = CalcSubpaneLocalRect(theBevelDesc.paneID, theBevelDesc.cachedLocalFrame);
  144.         if (visible)
  145.             DrawBeveledSub(theBevelDesc);
  146.         }        
  147. }
  148.  
  149. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  150. //    Ñ    
  151. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  152.  
  153. Boolean CBevelView::CalcSubpaneLocalRect(PaneIDT inPaneID, Rect& subFrame)
  154. {
  155.     // Handle the growbox case first, as it's not really a pane at all.
  156.     if (inPaneID == '$Grw')
  157.     {
  158.         subFrame = (*static_cast<RgnHandle>(mBevelRegion))->rgnBBox;
  159.         subFrame.top = subFrame.bottom - 15;
  160.         subFrame.left = subFrame.right - 15;
  161.         // return true (means visible) if mBevelGrowIcon is true
  162.         return mBevelGrowIcon;
  163.     }
  164.     LPane *theSub = FindPaneByID(inPaneID);
  165.     if (theSub && theSub->IsVisible())
  166.     {
  167.         theSub->CalcPortFrameRect(subFrame);
  168.         PortToLocalPoint(topLeft(subFrame));
  169.         PortToLocalPoint(botRight(subFrame));
  170.         return true;
  171.     }
  172.     return false;
  173. }
  174.  
  175. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  176. //    Ñ    
  177. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  178. void CBevelView::CalcBevelRegion(void)
  179. {
  180.     // If we can't focus, we cant establish a coordinate scheme and make
  181.     // subpane position calculations.  So leave the recalc flag set.
  182.     if (!FocusExposed(false))
  183.         {
  184.         mNeedsRecalc = true;
  185.         return;
  186.         }
  187.  
  188.     StRegion theSavedGrayRgn(mBevelRegion);
  189.         
  190.     // Get the current frame of the gray bevel view.
  191.     // and convert the rectangle to a region
  192.     Rect grayFrame;
  193.     CalcLocalFrameRect(grayFrame);
  194.     ::RectRgn(mBevelRegion, &grayFrame);
  195.  
  196.     // Rip through the sub-panes to define the region that will
  197.     // be gray when the gray bevel view is drawn.
  198.     mBevelList.Lock();
  199.     StRegion theUtilRgn;
  200.     for (ArrayIndexT theIndex = LArray::index_First; theIndex <= mBevelList.GetCount(); theIndex++)
  201.     {
  202.         SSubBevel* theBevelDesc = (SSubBevel*)mBevelList.GetItemPtr(theIndex);
  203.         Boolean visible = CalcSubpaneLocalRect(theBevelDesc->paneID, theBevelDesc->cachedLocalFrame);
  204.         if (visible)
  205.         {
  206.             ::RectRgn(theUtilRgn, &theBevelDesc->cachedLocalFrame);
  207.             ::DiffRgn(mBevelRegion, theUtilRgn, mBevelRegion);        
  208.         }
  209.             
  210.         // if the pane was not found we are assuming that we don't want to
  211.         // clear the gray area underneath that pane.
  212.     }
  213.         
  214.     mBevelList.Unlock();
  215.     mNeedsRecalc = false;
  216.  
  217.     // Calculate the difference between the old an new gray
  218.     // areas and invalidate the newly exposed stuff.    
  219. //    ::DiffRgn(theSavedGrayRgn, mBevelRegion, theSavedGrayRgn);
  220. //    InvalPortRgn(theSavedGrayRgn);
  221. }
  222.  
  223. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  224. //    Ñ    
  225. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  226.  
  227. void CBevelView::InvalMainFrame(void)
  228. {
  229.     Rect theFrame;
  230.     CalcPortFrameRect(theFrame);
  231.  
  232.     StRegion theInvalidRgn(theFrame);
  233.     ::InsetRect(&theFrame, mMainBevel, mMainBevel);
  234.     
  235.     StRegion theInsetRgn(theFrame);
  236.     ::DiffRgn(theInvalidRgn, theInsetRgn, theInvalidRgn);
  237.  
  238.     InvalPortRgn(theInvalidRgn);
  239. }
  240.  
  241. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  242. //    Ñ    
  243. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  244.  
  245. void CBevelView::InvalSubFrames(void)
  246. {
  247.     StRegion theInvalidRgn, theFrameRgn, theInsetRgn;
  248.     ::SetEmptyRgn(theInvalidRgn);
  249.     
  250.     LArrayIterator iterator(mBevelList, LArrayIterator::from_Start);
  251.     SSubBevel theBevelDesc;
  252.     while (iterator.Next(&theBevelDesc))
  253.     {
  254.         Rect theSubFrame = theBevelDesc.cachedLocalFrame;
  255.         ::RectRgn(theFrameRgn, &theSubFrame);
  256.  
  257.         Int16 theInsetLevel = theBevelDesc.bevelLevel;
  258.  
  259.         if (theInsetLevel < 0)
  260.             theInsetLevel = -theInsetLevel;
  261.             
  262.         ::InsetRect(&theSubFrame, -(theInsetLevel), -(theInsetLevel));
  263.         ::RectRgn(theInsetRgn, &theSubFrame);
  264.         
  265.         ::DiffRgn(theInsetRgn, theFrameRgn, theFrameRgn);
  266.  
  267.  
  268.         ::UnionRgn(theInvalidRgn, theFrameRgn, theInvalidRgn);
  269.     }
  270.  
  271.     // Convert region to port coordinates
  272.     
  273.     Point offset = { 0, 0 };
  274.     LocalToPortPoint(offset);
  275.     ::OffsetRgn(theInvalidRgn, offset.h, offset.v);
  276.  
  277.     InvalPortRgn(theInvalidRgn);
  278. }
  279.  
  280. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  281. //    Ñ    
  282. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  283.  
  284. void CBevelView::CalcBevelMask(void)
  285. {
  286.     ::SetEmptyRgn(mBevelMaskRegion);
  287.     StRegion theFrameRgn, theInsetRgn;
  288.     
  289.     LArrayIterator iterator(mBevelList, LArrayIterator::from_Start);
  290.     SSubBevel theBevelDesc;
  291.     while (iterator.Next(&theBevelDesc))
  292.     {
  293.         Rect theSubFrame;
  294.         if ( CalcSubpaneLocalRect(theBevelDesc.paneID, theSubFrame) ) {
  295.             ::RectRgn(theFrameRgn, &theSubFrame);
  296.  
  297.             Int16 theInsetLevel = theBevelDesc.bevelLevel;
  298.  
  299.             if (theInsetLevel < 0)
  300.                 theInsetLevel = -theInsetLevel;
  301.             
  302.             ::InsetRect(&theSubFrame, -(theInsetLevel), -(theInsetLevel));
  303.             ::RectRgn(theInsetRgn, &theSubFrame);
  304.         
  305.             ::DiffRgn(theInsetRgn, theFrameRgn, theFrameRgn);
  306.  
  307.  
  308.             ::UnionRgn(mBevelMaskRegion, theFrameRgn, mBevelMaskRegion);
  309.         }
  310.     }
  311.     
  312.     // Convert region to port coordinates
  313.     Point offset = { 0, 0 };
  314.     LocalToPortPoint(offset);
  315.     ::OffsetRgn(mBevelMaskRegion, offset.h, offset.v);
  316. }
  317.  
  318. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  319. //    Ñ    
  320. //
  321. //    This method should be called anytime beveled subpanes are changed directly (i.e.
  322. //     calling the pane's method directly, such as ResizeFrameBy(), MoveBy(), etc.)
  323. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  324.  
  325. void CBevelView::SubPanesChanged(Boolean inRefresh)
  326. {
  327.     // Invalidate old bevel mask
  328.     
  329.     if (inRefresh)
  330.         InvalPortRgn(mBevelMaskRegion);
  331.     
  332.     // Calculate new masks
  333.  
  334.     CalcBevelRegion();
  335.     CalcBevelMask();
  336.     
  337.     // Invalidate new bevel mask
  338.  
  339.     if (inRefresh)
  340.         InvalPortRgn(mBevelMaskRegion);
  341. }
  342.  
  343.  
  344. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  345. //    Ñ                                                    [ static ]
  346. //
  347. //    This is a safe, but ugly way of telling any enclosing GrayBevelView
  348. //    that the panes have moved.  The subPane is the starting point for an
  349. //    upwards search.
  350. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  351.  
  352. void CBevelView::SubPanesChanged(LPane* inSubPane, Boolean inRefresh)
  353. {
  354.     LPane* super = inSubPane;
  355.     do {
  356.         super = super->GetSuperView();
  357.         if (!super) break;
  358.         CBevelView* graySuper = dynamic_cast<CBevelView*>(super);
  359.         if (graySuper)
  360.         {
  361.             graySuper->SubPanesChanged(inRefresh);
  362.             break;
  363.         }
  364.     } while (true);
  365. }
  366.  
  367.  
  368. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  369. //    Ñ    
  370. //
  371. //    This method should be called to turn on bevelling of the grow icon area
  372. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  373. void CBevelView::BevelGrowIcon()
  374. {
  375.     mBevelGrowIcon = true;
  376.     SubPanesChanged();
  377. }
  378.  
  379. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  380. //    Ñ    
  381. //
  382. //    This method should be called to stop us from bevelling the grow icon area
  383. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  384. void CBevelView::DontBevelGrowIcon()
  385. {
  386.     mBevelGrowIcon = false;
  387.     SubPanesChanged();
  388. }