michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef ScrollbarActivity_h___ michael@0: #define ScrollbarActivity_h___ michael@0: michael@0: #include "mozilla/Attributes.h" michael@0: #include "nsCOMPtr.h" michael@0: #include "nsIDOMEventListener.h" michael@0: #include "mozilla/TimeStamp.h" michael@0: #include "nsRefreshDriver.h" michael@0: michael@0: class nsIContent; michael@0: class nsIScrollbarOwner; michael@0: class nsITimer; michael@0: class nsIAtom; michael@0: michael@0: namespace mozilla { michael@0: namespace layout { michael@0: michael@0: /** michael@0: * ScrollbarActivity michael@0: * michael@0: * This class manages scrollbar behavior that imitates the native Mac OS X michael@0: * Lion overlay scrollbar behavior: Scrollbars are only shown while "scrollbar michael@0: * activity" occurs, and they're hidden with a fade animation after a short michael@0: * delay. michael@0: * michael@0: * Scrollbar activity has these states: michael@0: * - inactive: michael@0: * Scrollbars are hidden. michael@0: * - ongoing activity: michael@0: * Scrollbars are visible and being operated on in some way, for example michael@0: * because they're hovered or pressed. michael@0: * - active, but waiting for fade out michael@0: * Scrollbars are still completely visible but are about to fade away. michael@0: * - fading out michael@0: * Scrollbars are subject to a fade-out animation. michael@0: * michael@0: * Initial scrollbar activity needs to be reported by the scrollbar holder that michael@0: * owns the ScrollbarActivity instance. This needs to happen via a call to michael@0: * ActivityOccurred(), for example when the current scroll position or the size michael@0: * of the scroll area changes. michael@0: * michael@0: * As soon as scrollbars are visible, the ScrollbarActivity class manages the michael@0: * rest of the activity behavior: It ensures that mouse motions inside the michael@0: * scroll area keep the scrollbars visible, and that scrollbars don't fade away michael@0: * while they're being hovered / dragged. It also sets a sticky hover attribute michael@0: * on the most recently hovered scrollbar. michael@0: * michael@0: * ScrollbarActivity falls into hibernation after the scrollbars have faded michael@0: * out. It only starts acting after the next call to ActivityOccurred() / michael@0: * ActivityStarted(). michael@0: */ michael@0: michael@0: class ScrollbarActivity : public nsIDOMEventListener, michael@0: public nsARefreshObserver { michael@0: public: michael@0: ScrollbarActivity(nsIScrollbarOwner* aScrollableFrame) michael@0: : mScrollableFrame(aScrollableFrame) michael@0: , mNestedActivityCounter(0) michael@0: , mIsActive(false) michael@0: , mIsFading(false) michael@0: , mListeningForScrollbarEvents(false) michael@0: , mListeningForScrollAreaEvents(false) michael@0: , mHScrollbarHovered(false) michael@0: , mVScrollbarHovered(false) michael@0: , mDisplayOnMouseMove(false) michael@0: , mScrollbarFadeBeginDelay(0) michael@0: , mScrollbarFadeDuration(0) michael@0: { michael@0: QueryLookAndFeelVals(); michael@0: } michael@0: michael@0: NS_DECL_ISUPPORTS michael@0: NS_DECL_NSIDOMEVENTLISTENER michael@0: michael@0: virtual ~ScrollbarActivity() {} michael@0: michael@0: void Destroy(); michael@0: michael@0: void ActivityOccurred(); michael@0: void ActivityStarted(); michael@0: void ActivityStopped(); michael@0: michael@0: virtual void WillRefresh(TimeStamp aTime) MOZ_OVERRIDE; michael@0: michael@0: static void FadeBeginTimerFired(nsITimer* aTimer, void* aSelf) { michael@0: nsRefPtr scrollbarActivity( michael@0: reinterpret_cast(aSelf)); michael@0: scrollbarActivity->BeginFade(); michael@0: } michael@0: michael@0: protected: michael@0: michael@0: bool IsActivityOngoing() michael@0: { return mNestedActivityCounter > 0; } michael@0: bool IsStillFading(TimeStamp aTime); michael@0: void QueryLookAndFeelVals(); michael@0: michael@0: void HandleEventForScrollbar(const nsAString& aType, michael@0: nsIContent* aTarget, michael@0: nsIContent* aScrollbar, michael@0: bool* aStoredHoverState); michael@0: michael@0: void SetIsActive(bool aNewActive); michael@0: bool SetIsFading(bool aNewFading); // returns false if 'this' was destroyed michael@0: michael@0: void BeginFade(); michael@0: void EndFade(); michael@0: michael@0: void StartFadeBeginTimer(); michael@0: void CancelFadeBeginTimer(); michael@0: michael@0: void StartListeningForScrollbarEvents(); michael@0: void StartListeningForScrollAreaEvents(); michael@0: void StopListeningForScrollbarEvents(); michael@0: void StopListeningForScrollAreaEvents(); michael@0: void AddScrollbarEventListeners(nsIDOMEventTarget* aScrollbar); michael@0: void RemoveScrollbarEventListeners(nsIDOMEventTarget* aScrollbar); michael@0: michael@0: void RegisterWithRefreshDriver(); michael@0: void UnregisterFromRefreshDriver(); michael@0: michael@0: bool UpdateOpacity(TimeStamp aTime); // returns false if 'this' was destroyed michael@0: void HoveredScrollbar(nsIContent* aScrollbar); michael@0: michael@0: nsRefreshDriver* GetRefreshDriver(); michael@0: nsIContent* GetScrollbarContent(bool aVertical); michael@0: nsIContent* GetHorizontalScrollbar() { return GetScrollbarContent(false); } michael@0: nsIContent* GetVerticalScrollbar() { return GetScrollbarContent(true); } michael@0: michael@0: const TimeDuration FadeDuration() { michael@0: return TimeDuration::FromMilliseconds(mScrollbarFadeDuration); michael@0: } michael@0: michael@0: nsIScrollbarOwner* mScrollableFrame; michael@0: TimeStamp mFadeBeginTime; michael@0: nsCOMPtr mFadeBeginTimer; michael@0: nsCOMPtr mHorizontalScrollbar; // null while inactive michael@0: nsCOMPtr mVerticalScrollbar; // null while inactive michael@0: int mNestedActivityCounter; michael@0: bool mIsActive; michael@0: bool mIsFading; michael@0: bool mListeningForScrollbarEvents; michael@0: bool mListeningForScrollAreaEvents; michael@0: bool mHScrollbarHovered; michael@0: bool mVScrollbarHovered; michael@0: michael@0: // LookAndFeel values we load on creation michael@0: bool mDisplayOnMouseMove; michael@0: int mScrollbarFadeBeginDelay; michael@0: int mScrollbarFadeDuration; michael@0: }; michael@0: michael@0: } // namespace layout michael@0: } // namespace mozilla michael@0: michael@0: #endif /* ScrollbarActivity_h___ */