layout/xul/nsScrollBoxFrame.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/xul/nsScrollBoxFrame.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,176 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#include "nsCOMPtr.h"
    1.10 +#include "nsPresContext.h"
    1.11 +#include "nsGkAtoms.h"
    1.12 +#include "nsButtonBoxFrame.h"
    1.13 +#include "nsITimer.h"
    1.14 +#include "nsRepeatService.h"
    1.15 +#include "mozilla/MouseEvents.h"
    1.16 +#include "nsIContent.h"
    1.17 +
    1.18 +using namespace mozilla;
    1.19 +
    1.20 +class nsAutoRepeatBoxFrame : public nsButtonBoxFrame
    1.21 +{
    1.22 +public:
    1.23 +  NS_DECL_FRAMEARENA_HELPERS
    1.24 +
    1.25 +  friend nsIFrame* NS_NewAutoRepeatBoxFrame(nsIPresShell* aPresShell,
    1.26 +                                            nsStyleContext* aContext);
    1.27 +
    1.28 +  virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
    1.29 +
    1.30 +  virtual nsresult AttributeChanged(int32_t aNameSpaceID,
    1.31 +                                    nsIAtom* aAttribute,
    1.32 +                                    int32_t aModType) MOZ_OVERRIDE;
    1.33 +
    1.34 +  virtual nsresult HandleEvent(nsPresContext* aPresContext,
    1.35 +                               WidgetGUIEvent* aEvent,
    1.36 +                               nsEventStatus* aEventStatus) MOZ_OVERRIDE;
    1.37 +
    1.38 +  NS_IMETHOD HandlePress(nsPresContext* aPresContext,
    1.39 +                         WidgetGUIEvent* aEvent,
    1.40 +                         nsEventStatus* aEventStatus) MOZ_OVERRIDE;
    1.41 +
    1.42 +  NS_IMETHOD HandleRelease(nsPresContext* aPresContext,
    1.43 +                           WidgetGUIEvent* aEvent,
    1.44 +                           nsEventStatus* aEventStatus) MOZ_OVERRIDE;
    1.45 +
    1.46 +protected:
    1.47 +  nsAutoRepeatBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext):
    1.48 +    nsButtonBoxFrame(aPresShell, aContext) {}
    1.49 +  
    1.50 +  void StartRepeat() {
    1.51 +    if (IsActivatedOnHover()) {
    1.52 +      // No initial delay on hover.
    1.53 +      nsRepeatService::GetInstance()->Start(Notify, this, 0);
    1.54 +    } else {
    1.55 +      nsRepeatService::GetInstance()->Start(Notify, this);
    1.56 +    }
    1.57 +  }
    1.58 +  void StopRepeat() {
    1.59 +    nsRepeatService::GetInstance()->Stop(Notify, this);
    1.60 +  }
    1.61 +  void Notify();
    1.62 +  static void Notify(void* aData) {
    1.63 +    static_cast<nsAutoRepeatBoxFrame*>(aData)->Notify();
    1.64 +  }
    1.65 +
    1.66 +  bool mTrustedEvent;
    1.67 +  
    1.68 +  bool IsActivatedOnHover();
    1.69 +};
    1.70 +
    1.71 +nsIFrame*
    1.72 +NS_NewAutoRepeatBoxFrame (nsIPresShell* aPresShell, nsStyleContext* aContext)
    1.73 +{
    1.74 +  return new (aPresShell) nsAutoRepeatBoxFrame (aPresShell, aContext);
    1.75 +}
    1.76 +
    1.77 +NS_IMPL_FRAMEARENA_HELPERS(nsAutoRepeatBoxFrame)
    1.78 +
    1.79 +nsresult
    1.80 +nsAutoRepeatBoxFrame::HandleEvent(nsPresContext* aPresContext,
    1.81 +                                  WidgetGUIEvent* aEvent,
    1.82 +                                  nsEventStatus* aEventStatus)
    1.83 +{  
    1.84 +  NS_ENSURE_ARG_POINTER(aEventStatus);
    1.85 +  if (nsEventStatus_eConsumeNoDefault == *aEventStatus) {
    1.86 +    return NS_OK;
    1.87 +  }
    1.88 +
    1.89 +  switch(aEvent->message)
    1.90 +  {
    1.91 +    // repeat mode may be "hover" for repeating while the mouse is hovering
    1.92 +    // over the element, otherwise repetition is done while the element is
    1.93 +    // active (pressed).
    1.94 +    case NS_MOUSE_ENTER:
    1.95 +    case NS_MOUSE_ENTER_SYNTH:
    1.96 +      if (IsActivatedOnHover()) {
    1.97 +        StartRepeat();
    1.98 +        mTrustedEvent = aEvent->mFlags.mIsTrusted;
    1.99 +      }
   1.100 +      break;
   1.101 +
   1.102 +    case NS_MOUSE_EXIT:
   1.103 +    case NS_MOUSE_EXIT_SYNTH:
   1.104 +      // always stop on mouse exit
   1.105 +      StopRepeat();
   1.106 +      // Not really necessary but do this to be safe
   1.107 +      mTrustedEvent = false;
   1.108 +      break;
   1.109 +
   1.110 +    case NS_MOUSE_CLICK: {
   1.111 +      WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
   1.112 +      if (mouseEvent->IsLeftClickEvent()) {
   1.113 +        // skip button frame handling to prevent click handling
   1.114 +        return nsBoxFrame::HandleEvent(aPresContext, mouseEvent, aEventStatus);
   1.115 +      }
   1.116 +      break;
   1.117 +    }
   1.118 +  }
   1.119 +     
   1.120 +  return nsButtonBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
   1.121 +}
   1.122 +
   1.123 +NS_IMETHODIMP
   1.124 +nsAutoRepeatBoxFrame::HandlePress(nsPresContext* aPresContext,
   1.125 +                                  WidgetGUIEvent* aEvent,
   1.126 +                                  nsEventStatus* aEventStatus)
   1.127 +{
   1.128 +  if (!IsActivatedOnHover()) {
   1.129 +    StartRepeat();
   1.130 +    mTrustedEvent = aEvent->mFlags.mIsTrusted;
   1.131 +    DoMouseClick(aEvent, mTrustedEvent);
   1.132 +  }
   1.133 +
   1.134 +  return NS_OK;
   1.135 +}
   1.136 +
   1.137 +NS_IMETHODIMP 
   1.138 +nsAutoRepeatBoxFrame::HandleRelease(nsPresContext* aPresContext,
   1.139 +                                    WidgetGUIEvent* aEvent,
   1.140 +                                    nsEventStatus* aEventStatus)
   1.141 +{
   1.142 +  if (!IsActivatedOnHover()) {
   1.143 +    StopRepeat();
   1.144 +  }
   1.145 +  return NS_OK;
   1.146 +}
   1.147 +
   1.148 +nsresult
   1.149 +nsAutoRepeatBoxFrame::AttributeChanged(int32_t aNameSpaceID,
   1.150 +                                       nsIAtom* aAttribute,
   1.151 +                                       int32_t aModType)
   1.152 +{
   1.153 +  if (aAttribute == nsGkAtoms::type) {
   1.154 +    StopRepeat();
   1.155 +  }
   1.156 +  return NS_OK;
   1.157 +}
   1.158 +
   1.159 +void
   1.160 +nsAutoRepeatBoxFrame::Notify()
   1.161 +{
   1.162 +  DoMouseClick(nullptr, mTrustedEvent);
   1.163 +}
   1.164 +
   1.165 +void
   1.166 +nsAutoRepeatBoxFrame::DestroyFrom(nsIFrame* aDestructRoot)
   1.167 +{
   1.168 +  // Ensure our repeat service isn't going... it's possible that a scrollbar can disappear out
   1.169 +  // from under you while you're in the process of scrolling.
   1.170 +  StopRepeat();
   1.171 +  nsButtonBoxFrame::DestroyFrom(aDestructRoot);
   1.172 +}
   1.173 +
   1.174 +bool
   1.175 +nsAutoRepeatBoxFrame::IsActivatedOnHover()
   1.176 +{
   1.177 +  return mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::repeat,
   1.178 +                               nsGkAtoms::hover, eCaseMatters);
   1.179 +}

mercurial