Line data Source code
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/. */
5 :
6 : #ifndef nsSliderFrame_h__
7 : #define nsSliderFrame_h__
8 :
9 : #include "mozilla/Attributes.h"
10 : #include "nsRepeatService.h"
11 : #include "nsBoxFrame.h"
12 : #include "nsIAtom.h"
13 : #include "nsCOMPtr.h"
14 : #include "nsITimer.h"
15 : #include "nsIDOMEventListener.h"
16 :
17 : class nsITimer;
18 : class nsSliderFrame;
19 :
20 : nsIFrame* NS_NewSliderFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
21 :
22 : class nsSliderMediator final : public nsIDOMEventListener
23 : {
24 : public:
25 :
26 : NS_DECL_ISUPPORTS
27 :
28 : nsSliderFrame* mSlider;
29 :
30 4 : explicit nsSliderMediator(nsSliderFrame* aSlider) { mSlider = aSlider; }
31 :
32 0 : virtual void SetSlider(nsSliderFrame* aSlider) { mSlider = aSlider; }
33 :
34 : NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) override;
35 :
36 : protected:
37 0 : virtual ~nsSliderMediator() {}
38 : };
39 :
40 : class nsSliderFrame final : public nsBoxFrame
41 : {
42 : public:
43 18 : NS_DECL_FRAMEARENA_HELPERS(nsSliderFrame)
44 : NS_DECL_QUERYFRAME
45 :
46 : friend class nsSliderMediator;
47 :
48 : explicit nsSliderFrame(nsStyleContext* aContext);
49 : virtual ~nsSliderFrame();
50 :
51 : #ifdef DEBUG_FRAME_DUMP
52 0 : virtual nsresult GetFrameName(nsAString& aResult) const override {
53 0 : return MakeFrameName(NS_LITERAL_STRING("SliderFrame"), aResult);
54 : }
55 : #endif
56 :
57 : virtual nsSize GetXULPrefSize(nsBoxLayoutState& aBoxLayoutState) override;
58 : virtual nsSize GetXULMinSize(nsBoxLayoutState& aBoxLayoutState) override;
59 : virtual nsSize GetXULMaxSize(nsBoxLayoutState& aBoxLayoutState) override;
60 : NS_IMETHOD DoXULLayout(nsBoxLayoutState& aBoxLayoutState) override;
61 :
62 : // nsIFrame overrides
63 : virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
64 :
65 : virtual void BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder,
66 : const nsRect& aDirtyRect,
67 : const nsDisplayListSet& aLists) override;
68 :
69 : virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
70 : const nsRect& aDirtyRect,
71 : const nsDisplayListSet& aLists) override;
72 :
73 : virtual nsresult AttributeChanged(int32_t aNameSpaceID,
74 : nsIAtom* aAttribute,
75 : int32_t aModType) override;
76 :
77 : virtual void Init(nsIContent* aContent,
78 : nsContainerFrame* aParent,
79 : nsIFrame* asPrevInFlow) override;
80 :
81 :
82 : virtual nsresult HandleEvent(nsPresContext* aPresContext,
83 : mozilla::WidgetGUIEvent* aEvent,
84 : nsEventStatus* aEventStatus) override;
85 :
86 : // nsContainerFrame overrides
87 : virtual void SetInitialChildList(ChildListID aListID,
88 : nsFrameList& aChildList) override;
89 : virtual void AppendFrames(ChildListID aListID,
90 : nsFrameList& aFrameList) override;
91 : virtual void InsertFrames(ChildListID aListID,
92 : nsIFrame* aPrevFrame,
93 : nsFrameList& aFrameList) override;
94 : virtual void RemoveFrame(ChildListID aListID,
95 : nsIFrame* aOldFrame) override;
96 :
97 : nsresult StartDrag(nsIDOMEvent* aEvent);
98 : nsresult StopDrag();
99 :
100 : void StartAPZDrag(mozilla::WidgetGUIEvent* aEvent);
101 :
102 : static int32_t GetCurrentPosition(nsIContent* content);
103 : static int32_t GetMinPosition(nsIContent* content);
104 : static int32_t GetMaxPosition(nsIContent* content);
105 : static int32_t GetIncrement(nsIContent* content);
106 : static int32_t GetPageIncrement(nsIContent* content);
107 : static int32_t GetIntegerAttribute(nsIContent* content, nsIAtom* atom, int32_t defaultValue);
108 : void EnsureOrient();
109 :
110 : NS_IMETHOD HandlePress(nsPresContext* aPresContext,
111 : mozilla::WidgetGUIEvent* aEvent,
112 : nsEventStatus* aEventStatus) override;
113 :
114 0 : NS_IMETHOD HandleMultiplePress(nsPresContext* aPresContext,
115 : mozilla::WidgetGUIEvent* aEvent,
116 : nsEventStatus* aEventStatus,
117 : bool aControlHeld) override
118 : {
119 0 : return NS_OK;
120 : }
121 :
122 0 : NS_IMETHOD HandleDrag(nsPresContext* aPresContext,
123 : mozilla::WidgetGUIEvent* aEvent,
124 : nsEventStatus* aEventStatus) override
125 : {
126 0 : return NS_OK;
127 : }
128 :
129 : NS_IMETHOD HandleRelease(nsPresContext* aPresContext,
130 : mozilla::WidgetGUIEvent* aEvent,
131 : nsEventStatus* aEventStatus) override;
132 :
133 : // Return the ratio the scrollbar thumb should move in proportion to the
134 : // scrolled frame.
135 : float GetThumbRatio() const;
136 :
137 : // Notify the slider frame than an async scrollbar drag requested in
138 : // StartAPZDrag() was rejected by APZ, and the slider frame should
139 : // fall back to main-thread dragging.
140 : void AsyncScrollbarDragRejected();
141 :
142 : bool OnlySystemGroupDispatch(mozilla::EventMessage aMessage) const override;
143 :
144 : private:
145 :
146 : bool GetScrollToClick();
147 : nsIFrame* GetScrollbar();
148 : bool ShouldScrollForEvent(mozilla::WidgetGUIEvent* aEvent);
149 : bool ShouldScrollToClickForEvent(mozilla::WidgetGUIEvent* aEvent);
150 : bool IsEventOverThumb(mozilla::WidgetGUIEvent* aEvent);
151 :
152 : void PageUpDown(nscoord change);
153 : void SetCurrentThumbPosition(nsIContent* aScrollbar, nscoord aNewPos, bool aIsSmooth,
154 : bool aMaySnap);
155 : void SetCurrentPosition(nsIContent* aScrollbar, int32_t aNewPos, bool aIsSmooth);
156 : void SetCurrentPositionInternal(nsIContent* aScrollbar, int32_t pos,
157 : bool aIsSmooth);
158 : void CurrentPositionChanged();
159 :
160 : void DragThumb(bool aGrabMouseEvents);
161 : void AddListener();
162 : void RemoveListener();
163 : bool isDraggingThumb();
164 :
165 : void SuppressDisplayport();
166 : void UnsuppressDisplayport();
167 :
168 0 : void StartRepeat() {
169 0 : nsRepeatService::GetInstance()->Start(Notify, this,
170 0 : mContent->OwnerDoc(),
171 0 : NS_LITERAL_CSTRING("nsSliderFrame"));
172 0 : }
173 0 : void StopRepeat() {
174 0 : nsRepeatService::GetInstance()->Stop(Notify, this);
175 0 : }
176 : void Notify();
177 0 : static void Notify(void* aData) {
178 0 : (static_cast<nsSliderFrame*>(aData))->Notify();
179 0 : }
180 : void PageScroll(nscoord aChange);
181 :
182 : nsPoint mDestinationPoint;
183 : RefPtr<nsSliderMediator> mMediator;
184 :
185 : float mRatio;
186 :
187 : nscoord mDragStart;
188 : nscoord mThumbStart;
189 :
190 : int32_t mCurPos;
191 :
192 : nscoord mChange;
193 :
194 : bool mDragFinished;
195 :
196 : // true if an attribute change has been caused by the user manipulating the
197 : // slider. This allows notifications to tell how a slider's current position
198 : // was changed.
199 : bool mUserChanged;
200 :
201 : // true if we've handed off the scrolling to APZ. This means that we should
202 : // ignore scrolling events as the position will be updated by APZ. If we were
203 : // to process these events then the scroll position update would conflict
204 : // causing the scroll position to jump.
205 : bool mScrollingWithAPZ;
206 :
207 : // true if displayport suppression is active, for more performant
208 : // scrollbar-dragging behaviour.
209 : bool mSuppressionActive;
210 :
211 : static bool gMiddlePref;
212 : static int32_t gSnapMultiplier;
213 : }; // class nsSliderFrame
214 :
215 : #endif
|