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