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