1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef ScrollbarActivity_h___
8 #define ScrollbarActivity_h___
10 #include "mozilla/Assertions.h"
12 #include "nsIDOMEventListener.h"
15 class nsIScrollbarMediator
;
30 * This class manages scrollbar behavior that imitates the native Mac OS X
31 * Lion overlay scrollbar behavior: Scrollbars are only shown while "scrollbar
32 * activity" occurs, and they're hidden with a fade animation after a short
35 * Scrollbar activity has these states:
37 * Scrollbars are hidden.
39 * Scrollbars are visible and being operated on in some way, for example
40 * because they're hovered or pressed.
41 * - active, but waiting for fade out
42 * Scrollbars are still completely visible but are about to fade away.
44 * Scrollbars are subject to a fade-out animation.
46 * Initial scrollbar activity needs to be reported by the scrollbar holder that
47 * owns the ScrollbarActivity instance. This needs to happen via a call to
48 * ActivityOccurred(), for example when the current scroll position or the size
49 * of the scroll area changes.
51 * As soon as scrollbars are visible, the ScrollbarActivity class manages the
52 * rest of the activity behavior: It ensures that mouse motions inside the
53 * scroll area keep the scrollbars visible, and that scrollbars don't fade away
54 * while they're being hovered / dragged. It also sets a sticky hover attribute
55 * on the most recently hovered scrollbar.
57 * ScrollbarActivity falls into hibernation after the scrollbars have faded
58 * out. It only starts acting after the next call to ActivityOccurred() /
62 class ScrollbarActivity final
: public nsIDOMEventListener
{
64 explicit ScrollbarActivity(nsIScrollbarMediator
* aScrollableFrame
)
65 : mScrollableFrame(aScrollableFrame
) {
66 MOZ_ASSERT(mScrollableFrame
);
70 NS_DECL_NSIDOMEVENTLISTENER
74 void ActivityOccurred();
75 void ActivityStarted();
76 void ActivityStopped();
78 bool IsActive() const { return mNestedActivityCounter
; }
81 virtual ~ScrollbarActivity() = default;
83 void StartFadeTimer();
84 void CancelFadeTimer();
86 void HandleEventForScrollbar(const nsAString
& aType
, nsIContent
* aTarget
,
87 dom::Element
* aScrollbar
,
88 bool* aStoredHoverState
);
90 void StartListeningForScrollbarEvents();
91 void StartListeningForScrollAreaEvents();
92 void StopListeningForScrollbarEvents();
93 void StopListeningForScrollAreaEvents();
94 void AddScrollbarEventListeners(dom::EventTarget
* aScrollbar
);
95 void RemoveScrollbarEventListeners(dom::EventTarget
* aScrollbar
);
97 void HoveredScrollbar(dom::Element
* aScrollbar
);
99 dom::Element
* GetScrollbarContent(bool aVertical
);
100 dom::Element
* GetHorizontalScrollbar() { return GetScrollbarContent(false); }
101 dom::Element
* GetVerticalScrollbar() { return GetScrollbarContent(true); }
103 nsIScrollbarMediator
* const mScrollableFrame
;
104 nsCOMPtr
<dom::EventTarget
> mHorizontalScrollbar
; // null while inactive
105 nsCOMPtr
<dom::EventTarget
> mVerticalScrollbar
; // null while inactive
106 nsCOMPtr
<nsITimer
> mFadeTimer
;
107 uint32_t mNestedActivityCounter
= 0;
108 // This boolean is true from the point activity starts to the point BeginFade
109 // runs, and effectively reflects the "active" attribute of the scrollbar.
110 bool mScrollbarEffectivelyVisible
= false;
111 bool mListeningForScrollbarEvents
= false;
112 bool mListeningForScrollAreaEvents
= false;
113 bool mHScrollbarHovered
= false;
114 bool mVScrollbarHovered
= false;
117 } // namespace layout
118 } // namespace mozilla
120 #endif /* ScrollbarActivity_h___ */