LCOV - code coverage report
Current view: directory - layout/xul/base/src - nsScrollbarButtonFrame.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 130 0 0.0 %
Date: 2012-06-02 Functions: 12 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is Mozilla Communicator client code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *
      24                 :  * Alternatively, the contents of this file may be used under the terms of
      25                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      26                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      28                 :  * of those above. If you wish to allow use of your version of this file only
      29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      30                 :  * use your version of this file under the terms of the MPL, indicate your
      31                 :  * decision by deleting the provisions above and replace them with the notice
      32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      33                 :  * the provisions above, a recipient may use your version of this file under
      34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      35                 :  *
      36                 :  * ***** END LICENSE BLOCK ***** */
      37                 : 
      38                 : //
      39                 : // Eric Vaughan
      40                 : // Netscape Communications
      41                 : //
      42                 : // See documentation in associated header file
      43                 : //
      44                 : 
      45                 : #include "nsScrollbarButtonFrame.h"
      46                 : #include "nsPresContext.h"
      47                 : #include "nsIContent.h"
      48                 : #include "nsCOMPtr.h"
      49                 : #include "nsINameSpaceManager.h"
      50                 : #include "nsGkAtoms.h"
      51                 : #include "nsSliderFrame.h"
      52                 : #include "nsScrollbarFrame.h"
      53                 : #include "nsIScrollbarMediator.h"
      54                 : #include "nsRepeatService.h"
      55                 : #include "nsGUIEvent.h"
      56                 : #include "mozilla/LookAndFeel.h"
      57                 : 
      58                 : using namespace mozilla;
      59                 : 
      60                 : //
      61                 : // NS_NewToolbarFrame
      62                 : //
      63                 : // Creates a new Toolbar frame and returns it
      64                 : //
      65                 : nsIFrame*
      66               0 : NS_NewScrollbarButtonFrame (nsIPresShell* aPresShell, nsStyleContext* aContext)
      67                 : {
      68               0 :   return new (aPresShell) nsScrollbarButtonFrame(aPresShell, aContext);
      69                 : }
      70                 : 
      71               0 : NS_IMPL_FRAMEARENA_HELPERS(nsScrollbarButtonFrame)
      72                 : 
      73                 : NS_IMETHODIMP
      74               0 : nsScrollbarButtonFrame::HandleEvent(nsPresContext* aPresContext, 
      75                 :                                     nsGUIEvent* aEvent,
      76                 :                                     nsEventStatus* aEventStatus)
      77                 : {  
      78               0 :   NS_ENSURE_ARG_POINTER(aEventStatus);
      79                 : 
      80                 :   // If a web page calls event.preventDefault() we still want to
      81                 :   // scroll when scroll arrow is clicked. See bug 511075.
      82               0 :   if (!mContent->IsInNativeAnonymousSubtree() &&
      83                 :       nsEventStatus_eConsumeNoDefault == *aEventStatus) {
      84               0 :     return NS_OK;
      85                 :   }
      86                 : 
      87               0 :   switch (aEvent->message) {
      88                 :     case NS_MOUSE_BUTTON_DOWN:
      89               0 :       mCursorOnThis = true;
      90                 :       // if we didn't handle the press ourselves, pass it on to the superclass
      91               0 :       if (HandleButtonPress(aPresContext, aEvent, aEventStatus)) {
      92               0 :         return NS_OK;
      93                 :       }
      94               0 :       break;
      95                 :     case NS_MOUSE_BUTTON_UP:
      96               0 :       HandleRelease(aPresContext, aEvent, aEventStatus);
      97               0 :       break;
      98                 :     case NS_MOUSE_EXIT_SYNTH:
      99               0 :       mCursorOnThis = false;
     100               0 :       break;
     101                 :     case NS_MOUSE_MOVE: {
     102                 :       nsPoint cursor =
     103               0 :         nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this);
     104               0 :       nsRect frameRect(nsPoint(0, 0), GetSize());
     105               0 :       mCursorOnThis = frameRect.Contains(cursor);
     106                 :       break;
     107                 :     }
     108                 :   }
     109                 : 
     110               0 :   return nsButtonBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
     111                 : }
     112                 : 
     113                 : 
     114                 : bool
     115               0 : nsScrollbarButtonFrame::HandleButtonPress(nsPresContext* aPresContext, 
     116                 :                                           nsGUIEvent*     aEvent,
     117                 :                                           nsEventStatus*  aEventStatus)
     118                 : {
     119                 :   // Get the desired action for the scrollbar button.
     120                 :   LookAndFeel::IntID tmpAction;
     121               0 :   PRUint16 button = static_cast<nsMouseEvent*>(aEvent)->button;
     122               0 :   if (button == nsMouseEvent::eLeftButton) {
     123               0 :     tmpAction = LookAndFeel::eIntID_ScrollButtonLeftMouseButtonAction;
     124               0 :   } else if (button == nsMouseEvent::eMiddleButton) {
     125               0 :     tmpAction = LookAndFeel::eIntID_ScrollButtonMiddleMouseButtonAction;
     126               0 :   } else if (button == nsMouseEvent::eRightButton) {
     127               0 :     tmpAction = LookAndFeel::eIntID_ScrollButtonRightMouseButtonAction;
     128                 :   } else {
     129               0 :     return false;
     130                 :   }
     131                 : 
     132                 :   // Get the button action metric from the pres. shell.
     133                 :   PRInt32 pressedButtonAction;
     134               0 :   if (NS_FAILED(LookAndFeel::GetInt(tmpAction, &pressedButtonAction))) {
     135               0 :     return false;
     136                 :   }
     137                 : 
     138                 :   // get the scrollbar control
     139                 :   nsIFrame* scrollbar;
     140               0 :   GetParentWithTag(nsGkAtoms::scrollbar, this, scrollbar);
     141                 : 
     142               0 :   if (scrollbar == nsnull)
     143               0 :     return false;
     144                 : 
     145                 :   // get the scrollbars content node
     146               0 :   nsIContent* content = scrollbar->GetContent();
     147                 : 
     148                 :   static nsIContent::AttrValuesArray strings[] = { &nsGkAtoms::increment,
     149                 :                                                    &nsGkAtoms::decrement,
     150                 :                                                    nsnull };
     151                 :   PRInt32 index = mContent->FindAttrValueIn(kNameSpaceID_None,
     152                 :                                             nsGkAtoms::type,
     153               0 :                                             strings, eCaseMatters);
     154                 :   PRInt32 direction;
     155               0 :   if (index == 0) 
     156               0 :     direction = 1;
     157               0 :   else if (index == 1)
     158               0 :     direction = -1;
     159                 :   else
     160               0 :     return false;
     161                 : 
     162                 :   // Whether or not to repeat the click action.
     163               0 :   bool repeat = true;
     164                 :   // Use smooth scrolling by default.
     165               0 :   bool smoothScroll = true;
     166               0 :   switch (pressedButtonAction) {
     167                 :     case 0:
     168               0 :       mIncrement = direction * nsSliderFrame::GetIncrement(content);
     169               0 :       break;
     170                 :     case 1:
     171               0 :       mIncrement = direction * nsSliderFrame::GetPageIncrement(content);
     172               0 :       break;
     173                 :     case 2:
     174               0 :       if (direction == -1)
     175               0 :         mIncrement = -nsSliderFrame::GetCurrentPosition(content);
     176                 :       else
     177               0 :         mIncrement = nsSliderFrame::GetMaxPosition(content) - 
     178               0 :                      nsSliderFrame::GetCurrentPosition(content);
     179                 :       // Don't repeat or use smooth scrolling if scrolling to beginning or end
     180                 :       // of a page.
     181               0 :       repeat = smoothScroll = false;
     182               0 :       break;
     183                 :     case 3:
     184                 :     default:
     185                 :       // We were told to ignore this click, or someone assigned a non-standard
     186                 :       // value to the button's action.
     187               0 :       return false;
     188                 :   }
     189                 :   // set this attribute so we can style it later
     190               0 :   nsWeakFrame weakFrame(this);
     191               0 :   mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::active, NS_LITERAL_STRING("true"), true);
     192                 : 
     193               0 :   nsIPresShell::SetCapturingContent(mContent, CAPTURE_IGNOREALLOWED);
     194                 : 
     195               0 :   if (weakFrame.IsAlive()) {
     196               0 :     DoButtonAction(smoothScroll);
     197                 :   }
     198               0 :   if (repeat)
     199               0 :     StartRepeat();
     200               0 :   return true;
     201                 : }
     202                 : 
     203                 : NS_IMETHODIMP 
     204               0 : nsScrollbarButtonFrame::HandleRelease(nsPresContext* aPresContext, 
     205                 :                                       nsGUIEvent*     aEvent,
     206                 :                                       nsEventStatus*  aEventStatus)
     207                 : {
     208               0 :   nsIPresShell::SetCapturingContent(nsnull, 0);
     209                 :   // we're not active anymore
     210               0 :   mContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::active, true);
     211               0 :   StopRepeat();
     212               0 :   return NS_OK;
     213                 : }
     214                 : 
     215               0 : void nsScrollbarButtonFrame::Notify()
     216                 : {
     217                 :   // Since this is only going to get called if we're scrolling a page length
     218                 :   // or a line increment, we will always use smooth scrolling.
     219               0 :   if (mCursorOnThis ||
     220                 :       LookAndFeel::GetInt(
     221               0 :         LookAndFeel::eIntID_ScrollbarButtonAutoRepeatBehavior, 0)) {
     222               0 :     DoButtonAction(true);
     223                 :   }
     224               0 : }
     225                 : 
     226                 : void
     227               0 : nsScrollbarButtonFrame::MouseClicked(nsPresContext* aPresContext, nsGUIEvent* aEvent) 
     228                 : {
     229               0 :   nsButtonBoxFrame::MouseClicked(aPresContext, aEvent);
     230                 :   //MouseClicked();
     231               0 : }
     232                 : 
     233                 : void
     234               0 : nsScrollbarButtonFrame::DoButtonAction(bool aSmoothScroll) 
     235                 : {
     236                 :   // get the scrollbar control
     237                 :   nsIFrame* scrollbar;
     238               0 :   GetParentWithTag(nsGkAtoms::scrollbar, this, scrollbar);
     239                 : 
     240               0 :   if (scrollbar == nsnull)
     241               0 :     return;
     242                 : 
     243                 :   // get the scrollbars content node
     244               0 :   nsCOMPtr<nsIContent> content = scrollbar->GetContent();
     245                 : 
     246                 :   // get the current pos
     247               0 :   PRInt32 curpos = nsSliderFrame::GetCurrentPosition(content);
     248               0 :   PRInt32 oldpos = curpos;
     249                 : 
     250                 :   // get the max pos
     251               0 :   PRInt32 maxpos = nsSliderFrame::GetMaxPosition(content);
     252                 : 
     253                 :   // increment the given amount
     254               0 :   if (mIncrement)
     255               0 :     curpos += mIncrement;
     256                 : 
     257                 :   // make sure the current position is between the current and max positions
     258               0 :   if (curpos < 0)
     259               0 :     curpos = 0;
     260               0 :   else if (curpos > maxpos)
     261               0 :     curpos = maxpos;
     262                 : 
     263               0 :   nsScrollbarFrame* sb = do_QueryFrame(scrollbar);
     264               0 :   if (sb) {
     265               0 :     nsIScrollbarMediator* m = sb->GetScrollbarMediator();
     266               0 :     if (m) {
     267               0 :       m->ScrollbarButtonPressed(sb, oldpos, curpos);
     268                 :       return;
     269                 :     }
     270                 :   }
     271                 : 
     272                 :   // set the current position of the slider.
     273               0 :   nsAutoString curposStr;
     274               0 :   curposStr.AppendInt(curpos);
     275                 : 
     276               0 :   if (aSmoothScroll)
     277               0 :     content->SetAttr(kNameSpaceID_None, nsGkAtoms::smooth, NS_LITERAL_STRING("true"), false);
     278               0 :   content->SetAttr(kNameSpaceID_None, nsGkAtoms::curpos, curposStr, true);
     279               0 :   if (aSmoothScroll)
     280               0 :     content->UnsetAttr(kNameSpaceID_None, nsGkAtoms::smooth, false);
     281                 : }
     282                 : 
     283                 : nsresult
     284               0 : nsScrollbarButtonFrame::GetChildWithTag(nsPresContext* aPresContext,
     285                 :                                         nsIAtom* atom, nsIFrame* start,
     286                 :                                         nsIFrame*& result)
     287                 : {
     288                 :   // recursively search our children
     289               0 :   nsIFrame* childFrame = start->GetFirstPrincipalChild();
     290               0 :   while (nsnull != childFrame) 
     291                 :   {    
     292                 :     // get the content node
     293               0 :     nsIContent* child = childFrame->GetContent();
     294                 : 
     295               0 :     if (child) {
     296                 :       // see if it is the child
     297               0 :        if (child->Tag() == atom)
     298                 :        {
     299               0 :          result = childFrame;
     300                 : 
     301               0 :          return NS_OK;
     302                 :        }
     303                 :     }
     304                 : 
     305                 :      // recursive search the child
     306               0 :      GetChildWithTag(aPresContext, atom, childFrame, result);
     307               0 :      if (result != nsnull) 
     308               0 :        return NS_OK;
     309                 : 
     310               0 :     childFrame = childFrame->GetNextSibling();
     311                 :   }
     312                 : 
     313               0 :   result = nsnull;
     314               0 :   return NS_OK;
     315                 : }
     316                 : 
     317                 : nsresult
     318               0 : nsScrollbarButtonFrame::GetParentWithTag(nsIAtom* toFind, nsIFrame* start,
     319                 :                                          nsIFrame*& result)
     320                 : {
     321               0 :    while (start)
     322                 :    {
     323               0 :       start = start->GetParent();
     324                 : 
     325               0 :       if (start) {
     326                 :         // get the content node
     327               0 :         nsIContent* child = start->GetContent();
     328                 : 
     329               0 :         if (child && child->Tag() == toFind) {
     330               0 :           result = start;
     331               0 :           return NS_OK;
     332                 :         }
     333                 :       }
     334                 :    }
     335                 : 
     336               0 :    result = nsnull;
     337               0 :    return NS_OK;
     338                 : }
     339                 : 
     340                 : void
     341               0 : nsScrollbarButtonFrame::DestroyFrom(nsIFrame* aDestructRoot)
     342                 : {
     343                 :   // Ensure our repeat service isn't going... it's possible that a scrollbar can disappear out
     344                 :   // from under you while you're in the process of scrolling.
     345               0 :   StopRepeat();
     346               0 :   nsButtonBoxFrame::DestroyFrom(aDestructRoot);
     347               0 : }

Generated by: LCOV version 1.7