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 nsListBoxBodyFrame_h
7 : #define nsListBoxBodyFrame_h
8 :
9 : #include "mozilla/Attributes.h"
10 : #include "nsCOMPtr.h"
11 : #include "nsBoxFrame.h"
12 : #include "nsIScrollbarMediator.h"
13 : #include "nsIReflowCallback.h"
14 : #include "nsBoxLayoutState.h"
15 : #include "nsThreadUtils.h"
16 : #include "nsPIBoxObject.h"
17 :
18 : class nsPresContext;
19 : class nsListScrollSmoother;
20 : nsIFrame* NS_NewListBoxBodyFrame(nsIPresShell* aPresShell,
21 : nsStyleContext* aContext);
22 :
23 : class nsListBoxBodyFrame final : public nsBoxFrame,
24 : public nsIScrollbarMediator,
25 : public nsIReflowCallback
26 : {
27 : nsListBoxBodyFrame(nsStyleContext* aContext,
28 : nsBoxLayout* aLayoutManager);
29 : virtual ~nsListBoxBodyFrame();
30 :
31 : public:
32 : NS_DECL_QUERYFRAME
33 0 : NS_DECL_FRAMEARENA_HELPERS(nsListBoxBodyFrame)
34 :
35 : // non-virtual ListBoxObject
36 : int32_t GetNumberOfVisibleRows();
37 : int32_t GetIndexOfFirstVisibleRow();
38 : nsresult EnsureIndexIsVisible(int32_t aRowIndex);
39 : nsresult ScrollToIndex(int32_t aRowIndex);
40 : nsresult ScrollByLines(int32_t aNumLines);
41 : nsresult GetItemAtIndex(int32_t aIndex, nsIDOMElement **aResult);
42 : nsresult GetIndexOfItem(nsIDOMElement *aItem, int32_t *aResult);
43 :
44 : friend nsIFrame* NS_NewListBoxBodyFrame(nsIPresShell* aPresShell,
45 : nsStyleContext* aContext);
46 :
47 : // nsIFrame
48 : virtual void Init(nsIContent* aContent,
49 : nsContainerFrame* aParent,
50 : nsIFrame* aPrevInFlow) override;
51 : virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
52 :
53 : virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType) override;
54 :
55 : // nsIScrollbarMediator
56 : virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection,
57 : nsIScrollbarMediator::ScrollSnapMode snapMode
58 : = nsIScrollbarMediator::DISABLE_SNAP) override;
59 : virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection,
60 : nsIScrollbarMediator::ScrollSnapMode snapMode
61 : = nsIScrollbarMediator::DISABLE_SNAP) override;
62 : virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection,
63 : nsIScrollbarMediator::ScrollSnapMode snapMode
64 : = nsIScrollbarMediator::DISABLE_SNAP) override;
65 : virtual void RepeatButtonScroll(nsScrollbarFrame* aScrollbar) override;
66 : virtual void ThumbMoved(nsScrollbarFrame* aScrollbar,
67 : int32_t aOldPos,
68 : int32_t aNewPos) override;
69 0 : virtual void ScrollbarReleased(nsScrollbarFrame* aScrollbar) override {}
70 : virtual void VisibilityChanged(bool aVisible) override;
71 : virtual nsIFrame* GetScrollbarBox(bool aVertical) override;
72 0 : virtual void ScrollbarActivityStarted() const override {}
73 0 : virtual void ScrollbarActivityStopped() const override {}
74 0 : virtual bool IsScrollbarOnRight() const override {
75 0 : return (StyleVisibility()->mDirection == NS_STYLE_DIRECTION_LTR);
76 : }
77 0 : virtual bool ShouldSuppressScrollbarRepaints() const override {
78 0 : return false;
79 : }
80 :
81 :
82 : // nsIReflowCallback
83 : virtual bool ReflowFinished() override;
84 : virtual void ReflowCallbackCanceled() override;
85 :
86 : NS_IMETHOD DoXULLayout(nsBoxLayoutState& aBoxLayoutState) override;
87 : virtual void MarkIntrinsicISizesDirty() override;
88 :
89 : virtual nsSize GetXULMinSizeForScrollArea(nsBoxLayoutState& aBoxLayoutState) override;
90 : virtual nsSize GetXULPrefSize(nsBoxLayoutState& aBoxLayoutState) override;
91 :
92 : // size calculation
93 : int32_t GetRowCount();
94 0 : int32_t GetRowHeightAppUnits() { return mRowHeight; }
95 : int32_t GetRowHeightPixels() const;
96 : int32_t GetFixedRowSize();
97 : void SetRowHeight(nscoord aRowHeight);
98 : nscoord GetYPosition();
99 : nscoord GetAvailableHeight();
100 : nscoord ComputeIntrinsicISize(nsBoxLayoutState& aBoxLayoutState);
101 :
102 : // scrolling
103 : nsresult InternalPositionChangedCallback();
104 : nsresult InternalPositionChanged(bool aUp, int32_t aDelta);
105 : // Process pending position changed events, then do the position change.
106 : // This can wipe out the frametree.
107 : nsresult DoInternalPositionChangedSync(bool aUp, int32_t aDelta);
108 : // Actually do the internal position change. This can wipe out the frametree
109 : nsresult DoInternalPositionChanged(bool aUp, int32_t aDelta);
110 : nsListScrollSmoother* GetSmoother();
111 : void VerticalScroll(int32_t aDelta);
112 : // Update the scroll index given a position, in CSS pixels
113 : void UpdateIndex(int32_t aNewPos);
114 :
115 : // frames
116 : nsIFrame* GetFirstFrame();
117 : nsIFrame* GetLastFrame();
118 :
119 : // lazy row creation and destruction
120 : void CreateRows();
121 : void DestroyRows(int32_t& aRowsToLose);
122 : void ReverseDestroyRows(int32_t& aRowsToLose);
123 : nsIFrame* GetFirstItemBox(int32_t aOffset, bool* aCreated);
124 : nsIFrame* GetNextItemBox(nsIFrame* aBox, int32_t aOffset, bool* aCreated);
125 : bool ContinueReflow(nscoord height);
126 : NS_IMETHOD ListBoxAppendFrames(nsFrameList& aFrameList);
127 : NS_IMETHOD ListBoxInsertFrames(nsIFrame* aPrevFrame, nsFrameList& aFrameList);
128 : void OnContentInserted(nsIContent* aContent);
129 : void OnContentRemoved(nsPresContext* aPresContext, nsIContent* aContainer,
130 : nsIFrame* aChildFrame, nsIContent* aOldNextSibling);
131 :
132 : void GetListItemContentAt(int32_t aIndex, nsIContent** aContent);
133 : void GetListItemNextSibling(nsIContent* aListItem, nsIContent** aContent, int32_t& aSiblingIndex);
134 :
135 : void PostReflowCallback();
136 :
137 0 : bool SetBoxObject(nsPIBoxObject* aBoxObject)
138 : {
139 0 : NS_ENSURE_TRUE(!mBoxObject, false);
140 0 : mBoxObject = aBoxObject;
141 0 : return true;
142 : }
143 :
144 : virtual bool SupportsOrdinalsInChildren() override;
145 :
146 0 : virtual bool ComputesOwnOverflowArea() override { return true; }
147 :
148 : protected:
149 : class nsPositionChangedEvent;
150 : friend class nsPositionChangedEvent;
151 :
152 0 : class nsPositionChangedEvent : public mozilla::Runnable
153 : {
154 : public:
155 0 : nsPositionChangedEvent(nsListBoxBodyFrame* aFrame, bool aUp, int32_t aDelta)
156 0 : : mozilla::Runnable("nsListBoxBodyFrame::nsPositionChangedEvent")
157 : , mFrame(aFrame)
158 : , mUp(aUp)
159 0 : , mDelta(aDelta)
160 0 : {}
161 :
162 0 : NS_IMETHOD Run() override
163 : {
164 0 : if (!mFrame) {
165 0 : return NS_OK;
166 : }
167 :
168 0 : mFrame->mPendingPositionChangeEvents.RemoveElement(this);
169 :
170 0 : return mFrame->DoInternalPositionChanged(mUp, mDelta);
171 : }
172 :
173 0 : void Revoke() {
174 0 : mFrame = nullptr;
175 0 : }
176 :
177 : nsListBoxBodyFrame* mFrame;
178 : bool mUp;
179 : int32_t mDelta;
180 : };
181 :
182 : void ComputeTotalRowCount();
183 : int32_t ToRowIndex(nscoord aPos) const;
184 : void RemoveChildFrame(nsBoxLayoutState &aState, nsIFrame *aChild);
185 :
186 : nsTArray< RefPtr<nsPositionChangedEvent> > mPendingPositionChangeEvents;
187 : nsCOMPtr<nsPIBoxObject> mBoxObject;
188 :
189 : // frame markers
190 : WeakFrame mTopFrame;
191 : nsIFrame* mBottomFrame;
192 : nsIFrame* mLinkupFrame;
193 :
194 : nsListScrollSmoother* mScrollSmoother;
195 :
196 : int32_t mRowsToPrepend;
197 :
198 : // row height
199 : int32_t mRowCount;
200 : nscoord mRowHeight;
201 : nscoord mAvailableHeight;
202 : nscoord mStringWidth;
203 :
204 : // scrolling
205 : int32_t mCurrentIndex; // Row-based
206 : int32_t mOldIndex;
207 : int32_t mYPosition;
208 : int32_t mTimePerRow;
209 :
210 : // row height
211 : bool mRowHeightWasSet;
212 : // scrolling
213 : bool mScrolling;
214 : bool mAdjustScroll;
215 :
216 : bool mReflowCallbackPosted;
217 : };
218 :
219 : #endif // nsListBoxBodyFrame_h
|