1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef ScrollbarActivity_h___
7 #define ScrollbarActivity_h___
9 #include "mozilla/Attributes.h"
11 #include "nsIDOMEventListener.h"
12 #include "mozilla/TimeStamp.h"
13 #include "nsRefreshDriver.h"
16 class nsIScrollbarMediator
;
26 * This class manages scrollbar behavior that imitates the native Mac OS X
27 * Lion overlay scrollbar behavior: Scrollbars are only shown while "scrollbar
28 * activity" occurs, and they're hidden with a fade animation after a short
31 * Scrollbar activity has these states:
33 * Scrollbars are hidden.
35 * Scrollbars are visible and being operated on in some way, for example
36 * because they're hovered or pressed.
37 * - active, but waiting for fade out
38 * Scrollbars are still completely visible but are about to fade away.
40 * Scrollbars are subject to a fade-out animation.
42 * Initial scrollbar activity needs to be reported by the scrollbar holder that
43 * owns the ScrollbarActivity instance. This needs to happen via a call to
44 * ActivityOccurred(), for example when the current scroll position or the size
45 * of the scroll area changes.
47 * As soon as scrollbars are visible, the ScrollbarActivity class manages the
48 * rest of the activity behavior: It ensures that mouse motions inside the
49 * scroll area keep the scrollbars visible, and that scrollbars don't fade away
50 * while they're being hovered / dragged. It also sets a sticky hover attribute
51 * on the most recently hovered scrollbar.
53 * ScrollbarActivity falls into hibernation after the scrollbars have faded
54 * out. It only starts acting after the next call to ActivityOccurred() /
58 class ScrollbarActivity MOZ_FINAL
: public nsIDOMEventListener
,
59 public nsARefreshObserver
{
61 explicit ScrollbarActivity(nsIScrollbarMediator
* aScrollableFrame
)
62 : mScrollableFrame(aScrollableFrame
)
63 , mNestedActivityCounter(0)
66 , mListeningForScrollbarEvents(false)
67 , mListeningForScrollAreaEvents(false)
68 , mHScrollbarHovered(false)
69 , mVScrollbarHovered(false)
70 , mDisplayOnMouseMove(false)
71 , mScrollbarFadeBeginDelay(0)
72 , mScrollbarFadeDuration(0)
74 QueryLookAndFeelVals();
78 NS_DECL_NSIDOMEVENTLISTENER
82 void ActivityOccurred();
83 void ActivityStarted();
84 void ActivityStopped();
86 virtual void WillRefresh(TimeStamp aTime
) MOZ_OVERRIDE
;
88 static void FadeBeginTimerFired(nsITimer
* aTimer
, void* aSelf
) {
89 nsRefPtr
<ScrollbarActivity
> scrollbarActivity(
90 reinterpret_cast<ScrollbarActivity
*>(aSelf
));
91 scrollbarActivity
->BeginFade();
95 virtual ~ScrollbarActivity() {}
97 bool IsActivityOngoing()
98 { return mNestedActivityCounter
> 0; }
99 bool IsStillFading(TimeStamp aTime
);
100 void QueryLookAndFeelVals();
102 void HandleEventForScrollbar(const nsAString
& aType
,
104 nsIContent
* aScrollbar
,
105 bool* aStoredHoverState
);
107 void SetIsActive(bool aNewActive
);
108 bool SetIsFading(bool aNewFading
); // returns false if 'this' was destroyed
113 void StartFadeBeginTimer();
114 void CancelFadeBeginTimer();
116 void StartListeningForScrollbarEvents();
117 void StartListeningForScrollAreaEvents();
118 void StopListeningForScrollbarEvents();
119 void StopListeningForScrollAreaEvents();
120 void AddScrollbarEventListeners(nsIDOMEventTarget
* aScrollbar
);
121 void RemoveScrollbarEventListeners(nsIDOMEventTarget
* aScrollbar
);
123 void RegisterWithRefreshDriver();
124 void UnregisterFromRefreshDriver();
126 bool UpdateOpacity(TimeStamp aTime
); // returns false if 'this' was destroyed
127 void HoveredScrollbar(nsIContent
* aScrollbar
);
129 nsRefreshDriver
* GetRefreshDriver();
130 nsIContent
* GetScrollbarContent(bool aVertical
);
131 nsIContent
* GetHorizontalScrollbar() { return GetScrollbarContent(false); }
132 nsIContent
* GetVerticalScrollbar() { return GetScrollbarContent(true); }
134 const TimeDuration
FadeDuration() {
135 return TimeDuration::FromMilliseconds(mScrollbarFadeDuration
);
138 nsIScrollbarMediator
* mScrollableFrame
;
139 TimeStamp mFadeBeginTime
;
140 nsCOMPtr
<nsITimer
> mFadeBeginTimer
;
141 nsCOMPtr
<nsIDOMEventTarget
> mHorizontalScrollbar
; // null while inactive
142 nsCOMPtr
<nsIDOMEventTarget
> mVerticalScrollbar
; // null while inactive
143 int mNestedActivityCounter
;
146 bool mListeningForScrollbarEvents
;
147 bool mListeningForScrollAreaEvents
;
148 bool mHScrollbarHovered
;
149 bool mVScrollbarHovered
;
151 // LookAndFeel values we load on creation
152 bool mDisplayOnMouseMove
;
153 int mScrollbarFadeBeginDelay
;
154 int mScrollbarFadeDuration
;
157 } // namespace layout
158 } // namespace mozilla
160 #endif /* ScrollbarActivity_h___ */