home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / macfe / gui / CHyperScroller.cp < prev    next >
Encoding:
Text File  |  1998-04-08  |  12.7 KB  |  481 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. #include "CHyperScroller.h"
  20. #include "UGraphicGizmos.h"
  21. #include "macgui.h"
  22.  
  23. const ResIDT cSizeBoxIconID = 29200;
  24.  
  25. //------------------------------------------------------------------------------
  26. // CHyperScroller
  27. //------------------------------------------------------------------------------
  28. #define FOCUSBOXWIDTH 3
  29.  
  30.  
  31. #include "CHTMLView.h"
  32.  
  33. CHyperScroller::CHyperScroller(LStream *inStream)
  34.     :    CConfigActiveScroller(inStream)
  35. {
  36.     fVerticalBar = NULL;
  37.     fHorizontalBar = NULL;
  38.     mHandleGrowIconManually = false;
  39.     
  40.     ResetExpansion();
  41. }
  42.  
  43.  
  44. void CHyperScroller::ResetExpansion(void)
  45. {
  46.     mExpanded.left = false;
  47.     mExpanded.top = false;
  48.     mExpanded.right = false;
  49.     mExpanded.bottom = false;
  50. }
  51.  
  52.  
  53. void CHyperScroller::ExpandLeft(void)
  54. {
  55.     mExpanded.left = true;
  56. }
  57.  
  58. void CHyperScroller::ExpandTop(void)
  59. {
  60.     mExpanded.top = true;
  61. }
  62.  
  63. void CHyperScroller::ExpandRight(void)
  64. {
  65.     mExpanded.right = true;
  66. }
  67.  
  68. void CHyperScroller::ExpandBottom(void)
  69. {
  70.     mExpanded.bottom = true;
  71. }
  72.  
  73.  
  74. void CHyperScroller::AdjustHyperViewBounds(void)
  75. {
  76.     Assert_(mScrollingView);
  77.     
  78.     if (!mScrollingView)
  79.     {
  80.         return;
  81.     }
  82.     
  83.     CHTMLView* theHyperView = dynamic_cast<CHTMLView*>(mScrollingView);
  84.     
  85.     SDimension16 theFrameSize;
  86.     GetFrameSize(theFrameSize);
  87.  
  88.     SDimension16 theHyperSize = theFrameSize;
  89.  
  90.     if (!mExpanded.top)
  91.         theHyperSize.height--;
  92.         
  93.     if (!mExpanded.left)
  94.         theHyperSize.width--;
  95.         
  96.     if (!mExpanded.bottom)
  97.         theHyperSize.height--;
  98.         
  99.     if (!mExpanded.right)
  100.         theHyperSize.width--;
  101.         
  102.     if (mVerticalBar != NULL)
  103.     {
  104.         theHyperSize.width -= (ScrollBar_Size - 1);
  105.         if (mExpanded.right)
  106.             theHyperSize.width--;
  107.     }
  108.  
  109.     if (mHorizontalBar != NULL)
  110.     {
  111.         theHyperSize.height -= (ScrollBar_Size - 1);
  112.         if (mExpanded.bottom)
  113.             theHyperSize.height--;
  114.     }
  115.  
  116.     Int32 theHorizOffset = 1;
  117.     Int32 theVertOffset = 1;
  118.     
  119.     if (mExpanded.top)
  120.         theVertOffset--;
  121.         
  122.     if (mExpanded.left)
  123.         theHorizOffset--;
  124.         
  125.     mScrollingView->PlaceInSuperFrameAt(theHorizOffset, theVertOffset, false);
  126.     mScrollingView->ResizeFrameTo(theHyperSize.width, theHyperSize.height, false);
  127. }
  128.  
  129. void CHyperScroller::AdjustScrollBars()
  130.     {
  131.         Boolean need_inherited_AdjustScrollbars = true;
  132.  
  133.             /*
  134.                 If there is no scrolling view, then we don't adjust anything (even though
  135.                 you might think we should) because there probably is about to be a scrolling
  136.                 view, and adjusting now will mess things up...
  137.             */
  138.  
  139.         if ( mScrollingView )
  140.             {
  141.                 Boolean hasHorizontal    = mHorizontalBar != NULL;
  142.                 Boolean hasVertical        = mVerticalBar != NULL;
  143.  
  144.                     // Unless told otherwise, assume we've got what we need.
  145.                 Boolean needHorizontal    = hasHorizontal;
  146.                 Boolean needVertical        = hasVertical;
  147.  
  148.                 CHTMLView* htmlView = dynamic_cast<CHTMLView*>(mScrollingView);
  149.                 if ( !htmlView || (htmlView->GetScrollMode()==LO_SCROLL_AUTO) )
  150.                     {
  151.                         switch ( htmlView->GetScrollMode() )
  152.                             {
  153.                                 case LO_SCROLL_NO:
  154.                                     needHorizontal = needVertical = false;
  155.                                     break;
  156.  
  157.                                 case LO_SCROLL_YES:
  158.                                     needHorizontal = needVertical = true;
  159.                                     break;
  160.  
  161.                                 case LO_SCROLL_AUTO:
  162.                                     {
  163.                                             /*
  164.                                                 ...if there is a scrolling view, and either it's not a |CHTMLView| or
  165.                                                 if it is a |CHTMLView|, it allows scrollbars... then figure out if we
  166.                                                 need scrollbars based on the size of the frame and image
  167.                                             */
  168.  
  169.                                         SDimension16 frameSize;
  170.                                         mScrollingView->GetFrameSize(frameSize);
  171.  
  172.                                         SDimension32 imageSize;
  173.                                         mScrollingView->GetImageSize(imageSize);
  174.  
  175.                                         needHorizontal    = imageSize.width > frameSize.width;
  176.                                         needVertical        = imageSize.height > frameSize.height;
  177.                                     }
  178.                                     break;
  179.                             }
  180.                     }
  181.  
  182.                 if ( (hasHorizontal != needHorizontal) || (hasVertical != needVertical) )
  183.                     {
  184.                         ShowScrollbars(needHorizontal, needVertical);
  185.                         need_inherited_AdjustScrollbars = false; // ...since |ShowScrollbars| calls it.
  186.                     }
  187.             }
  188.  
  189.         if ( need_inherited_AdjustScrollbars )
  190.             /*inherited*/    CConfigActiveScroller::AdjustScrollBars();
  191.     }
  192.  
  193. void CHyperScroller::RefreshSelf()
  194.         /*
  195.             ...refresh just the area occupied by me and my scrollers,
  196.             and not by my mScrollingView
  197.         */
  198.     {
  199.         if ( mHorizontalBar )
  200.             mHorizontalBar->Refresh();
  201.  
  202.         if ( mVerticalBar )
  203.             mVerticalBar->Refresh();
  204.  
  205. //        if ( mHorizontalBar && mVerticalBar )
  206.         if ((mHandleGrowIconManually && (mVerticalBar || mHorizontalBar)) || (mVerticalBar && mHorizontalBar))
  207.             {
  208.                 Rect R = CalcDummySizeBox();
  209.                 LocalToPortPoint(topLeft(R));
  210.                 LocalToPortPoint(botRight(R));
  211.                 InvalPortRect(&R);
  212.             }
  213.     }
  214.  
  215. // ÑÑ display control
  216. // Show/hide the controls
  217. // Adjust the hyperview size
  218. void CHyperScroller::ShowScrollbars( Boolean horiOn, Boolean vertOn )
  219. {
  220.     Boolean        hasHorizontal = mHorizontalBar != NULL;
  221.     Boolean        hasVertical = mVerticalBar != NULL;
  222.  
  223.     // Ñ quick check
  224.     if ((hasHorizontal == horiOn) && (hasVertical == vertOn))
  225.         return;
  226.  
  227.     SDimension16 theFrameSize;
  228.     GetFrameSize(theFrameSize);
  229.     
  230.     // Ñ vertical scrollbar
  231.     {
  232.         // Ñ adjustment for visiblity of horizontal scroller
  233.         // Ñ show/hide
  234.         if (mVerticalBar && !vertOn)
  235.             {
  236.             mVerticalBar->Hide();
  237.             fVerticalBar = mVerticalBar;
  238.             mVerticalBar = NULL;
  239.             }
  240.         else if (!mVerticalBar && vertOn)
  241.             {
  242.             mVerticalBar = fVerticalBar;
  243.             fVerticalBar = NULL;
  244.             if (mVerticalBar)
  245.                 mVerticalBar->Show();
  246.             }
  247.  
  248.         Int32 theVerticalSize = theFrameSize.height;
  249. //        if (hasHorizontal || horiOn)
  250.         if (mHandleGrowIconManually || hasHorizontal || horiOn)
  251.             theVerticalSize -= (ScrollBar_Size - 1);
  252.  
  253.         LStdControl* theBar = (mVerticalBar != NULL) ? mVerticalBar : fVerticalBar;
  254.         StFocusAndClipIfHidden theControlClip(theBar);
  255.         theBar->PlaceInSuperFrameAt((theFrameSize.width - ScrollBar_Size), 0, false);
  256.         theBar->ResizeFrameTo(ScrollBar_Size, theVerticalSize, false);
  257.  
  258.         if (mVerticalBar != NULL)
  259.             mVerticalBar->Refresh();
  260.     }
  261.  
  262.     // Ñ╩horizontal scrollbar
  263.     {
  264.  
  265.         if (mHorizontalBar && !horiOn)
  266.             {
  267.             mHorizontalBar->Hide();
  268.             fHorizontalBar = mHorizontalBar;
  269.             mHorizontalBar = NULL;
  270.             }
  271.         else if (!mHorizontalBar && horiOn)
  272.             {
  273.             mHorizontalBar = fHorizontalBar;
  274.             fHorizontalBar = NULL;
  275.             if (mHorizontalBar)
  276.                 mHorizontalBar->Show();
  277.             }
  278.  
  279.         Int32 theHorizontalSize = theFrameSize.width;
  280. //        if (hasVertical || vertOn)
  281.         if (mHandleGrowIconManually || hasVertical || vertOn)
  282.             theHorizontalSize -= (ScrollBar_Size - 1);
  283.  
  284.         LPane* theBar = (mHorizontalBar != NULL) ? mHorizontalBar : fHorizontalBar;
  285.         if ( theBar )
  286.         {
  287.             StFocusAndClipIfHidden theControlClip(theBar);
  288.             theBar->PlaceInSuperFrameAt(0, (theFrameSize.height - ScrollBar_Size), false);
  289.             theBar->ResizeFrameTo(theHorizontalSize, ScrollBar_Size, false);
  290.         }
  291.  
  292.         if (mHorizontalBar != NULL)
  293.             mHorizontalBar->Refresh();
  294.     }
  295.  
  296.     if ( mScrollingView )
  297.         AdjustHyperViewBounds();
  298.     CConfigActiveScroller::AdjustScrollBars(); // call inherited AdjustScrollBars(), as mine could call _this_ routine back
  299.  
  300.     // Ñ only refresh the little box. Refreshing the whole view causes flashes
  301. //    if (HasScrollbars())    
  302.     if ((mHandleGrowIconManually && (mVerticalBar || mHorizontalBar)) || (mVerticalBar && mHorizontalBar))    
  303.         {
  304.         Rect    sizeBox  = CalcDummySizeBox();
  305.         sizeBox.top += mFrameLocation.v;
  306.         sizeBox.bottom += mFrameLocation.v;
  307.         sizeBox.left += mFrameLocation.h;
  308.         sizeBox.right += mFrameLocation.h;
  309.         InvalPortRect( &sizeBox );
  310.         }
  311. }
  312.  
  313. // Calculates the position of the dummy size box
  314. Rect CHyperScroller::CalcDummySizeBox()
  315. {
  316.     Rect        r;    
  317.  
  318.     r.bottom = mFrameSize.height;
  319.     r.right = mFrameSize.width;
  320.     r.top = r.bottom - 16;
  321.     r.left = r.right - 16;
  322.  
  323.     return r;
  324. }
  325.  
  326. // This is the little box between the scrollers.
  327. // HyperView and windows draw it
  328. void CHyperScroller::DrawDummySizeBox()
  329. {
  330.     // We need to erase that little rect above the grow box
  331. //    if ( mHorizontalBar && mVerticalBar )
  332.     if ((mHandleGrowIconManually && (mVerticalBar || mHorizontalBar)) || (mVerticalBar && mHorizontalBar))
  333.     {
  334.         if ( !FocusDraw() )
  335.             return;
  336.         Rect theDummyFrame = CalcDummySizeBox();
  337.  
  338.         if ( IsActive() )
  339.         {
  340.             if (!mHandleGrowIconManually)
  341.             {
  342.                 SBevelColorDesc theTraits;
  343.                 UGraphicGizmos::LoadBevelTraits(1000, theTraits);
  344.  
  345.                 ::PmForeColor(theTraits.fillColor);
  346.                 ::PaintRect(&theDummyFrame);    
  347.  
  348.                 ::PmForeColor(eStdGrayBlack);
  349.                 ::FrameRect(&theDummyFrame);
  350.                 ::InsetRect(&theDummyFrame, 1, 1);
  351.                 UGraphicGizmos::BevelRect(theDummyFrame, 1, theTraits.topBevelColor, theTraits.bottomBevelColor);
  352.             }
  353.             else
  354.             {
  355.                 ::PlotIconID(&theDummyFrame, atAbsoluteCenter, ttNone, cSizeBoxIconID);
  356.             }
  357.         }
  358.         else
  359.         {
  360.             ::PmForeColor(eStdGrayWhite);
  361.             theDummyFrame.top += 1;
  362.             theDummyFrame.left += 1;
  363.             ::EraseRect(&theDummyFrame);
  364.         }
  365.     }
  366. }
  367.  
  368. void CHyperScroller::DrawEmptyScroller( LStdControl* scrollBar )
  369. {
  370.     Rect        frame;
  371.  
  372.     scrollBar->CalcPortFrameRect( frame );
  373.     PortToLocalPoint( topLeft( frame ) );
  374.     PortToLocalPoint( botRight( frame ) );
  375.     ::FrameRect( &frame );
  376.     ::InsetRect( &frame, 1, 1 );
  377.     ::EraseRect( &frame );
  378. }
  379.  
  380. // Empty scrollbar drawing copied from LScroller
  381. // Also draws the frame if needed
  382.  
  383. void CHyperScroller::DrawSelf(void)
  384. {
  385.     StColorPenState::Normalize();
  386.  
  387.     Rect theFrame;
  388.     CalcLocalFrameRect(theFrame);
  389.  
  390.     CHTMLView* theHyperView = dynamic_cast<CHTMLView*>(mScrollingView);
  391.  
  392.     Boolean bIsBorderless = theHyperView->IsBorderless();
  393.     if ((!mExpanded.top) && (!bIsBorderless))
  394.         {
  395.         ::MoveTo(theFrame.left, theFrame.top);
  396.         ::LineTo(theFrame.right, theFrame.top);
  397.         }
  398.         
  399.     if ((!mExpanded.left) && (!bIsBorderless))
  400.         {
  401.         ::MoveTo(theFrame.left, theFrame.top);
  402.         ::LineTo(theFrame.left, theFrame.bottom);
  403.         }
  404.  
  405.     if ((!mExpanded.bottom) && (!bIsBorderless))
  406.         {
  407.         ::MoveTo(theFrame.left, theFrame.bottom - 1);
  408.         ::LineTo(theFrame.right, theFrame.bottom - 1);
  409.         }    
  410.  
  411.     if ((!mExpanded.right) && (!bIsBorderless))
  412.         {
  413.         ::MoveTo(theFrame.right - 1, theFrame.top);
  414.         ::LineTo(theFrame.right - 1, theFrame.bottom - 1);
  415.         }    
  416.  
  417.     if (!IsActive())
  418.         {
  419.         UGraphics::SetFore(CPrefs::Black);
  420.         UGraphics::SetBack(CPrefs::WindowBkgnd);
  421.     
  422.         if (mVerticalBar)
  423.             DrawEmptyScroller(mVerticalBar);
  424.         if (mHorizontalBar)
  425.             DrawEmptyScroller(mHorizontalBar);
  426.         }
  427.  
  428. //    if (mVerticalBar && mHorizontalBar)
  429.     if ((mHandleGrowIconManually && (mVerticalBar || mHorizontalBar)) || (mVerticalBar && mHorizontalBar))
  430.         DrawDummySizeBox();
  431. }
  432.  
  433. // Adjust the position of the scrollbars by 1 pixel, so that they fix well.
  434. // This cannot be done inside the constructor, because -1 offset means that there are no scrollers
  435. void CHyperScroller::FinishCreateSelf()
  436. {
  437.     LScroller::FinishCreateSelf();
  438.     
  439. // FIX ME!!! put back in
  440. //    if (((CHTMLView*)mScrollingView)->GetScrollable() != LO_SCROLL_YES)
  441. //        ShowScrollbars( FALSE, FALSE );
  442.  
  443.     // Initially there is no content, so we don't need scroll bars
  444.     
  445.     ShowScrollbars(false, false);
  446. }
  447.  
  448. // 97-05-06 pkc -- override ActivateSelf so that we call draw dummy size box in active state.
  449. void CHyperScroller::ActivateSelf()
  450. {
  451.     inherited::ActivateSelf();
  452.  
  453.     // 97-06-06 pkc -- also check to see if we're visible
  454. //    if ((mVisible == triState_On) && mVerticalBar && mHorizontalBar)
  455.     if ((mVisible == triState_On) && ((mHandleGrowIconManually && (mVerticalBar || mHorizontalBar)) || (mVerticalBar && mHorizontalBar)))
  456.         DrawDummySizeBox();
  457. }
  458.  
  459. // 97-05-12 pkc -- override ClickSelf so that we can handle grow icon manually
  460. void CHyperScroller::ClickSelf(const SMouseDownEvent &inMouseDown)
  461. {
  462.     if(mHandleGrowIconManually)
  463.     {
  464.         Rect theDummyFrame = CalcDummySizeBox();
  465.         if (::PtInRect(inMouseDown.whereLocal, &theDummyFrame))
  466.         {
  467.             // Find our LWindow superview and call ClickInGrow
  468.             LView* superView = this;
  469.             LWindow* window;
  470.             do {
  471.                 superView = superView->GetSuperView();
  472.                 window = dynamic_cast<LWindow*>(superView);
  473.             } while (!window && superView);
  474.             if (window)
  475.                 window->ClickInGrow(inMouseDown.macEvent);
  476.         }
  477.     }
  478.     else
  479.         LView::ClickSelf(inMouseDown);
  480. }
  481.