1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is Mozilla Communicator client code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * David W. Hyatt (hyatt@netscape.com) (Original Author)
24 : * Joe Hewitt (hewitt@netscape.com)
25 : * Mike Pinkerton (pinkerton@netscape.com)
26 : *
27 : * Alternatively, the contents of this file may be used under the terms of
28 : * either of the GNU General Public License Version 2 or later (the "GPL"),
29 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 : * in which case the provisions of the GPL or the LGPL are applicable instead
31 : * of those above. If you wish to allow use of your version of this file only
32 : * under the terms of either the GPL or the LGPL, and not to allow others to
33 : * use your version of this file under the terms of the MPL, indicate your
34 : * decision by deleting the provisions above and replace them with the notice
35 : * and other provisions required by the GPL or the LGPL. If you do not delete
36 : * the provisions above, a recipient may use your version of this file under
37 : * the terms of any one of the MPL, the GPL or the LGPL.
38 : *
39 : * ***** END LICENSE BLOCK ***** */
40 :
41 : #ifndef nsListBoxBodyFrame_h
42 : #define nsListBoxBodyFrame_h
43 :
44 : #include "nsCOMPtr.h"
45 : #include "nsBoxFrame.h"
46 : #include "nsIListBoxObject.h"
47 : #include "nsIScrollbarMediator.h"
48 : #include "nsIReflowCallback.h"
49 : #include "nsBoxLayoutState.h"
50 : #include "nsThreadUtils.h"
51 : #include "nsPIBoxObject.h"
52 :
53 : class nsPresContext;
54 : class nsListScrollSmoother;
55 : nsIFrame* NS_NewListBoxBodyFrame(nsIPresShell* aPresShell,
56 : nsStyleContext* aContext);
57 :
58 : class nsListBoxBodyFrame : public nsBoxFrame,
59 : public nsIScrollbarMediator,
60 : public nsIReflowCallback
61 : {
62 : nsListBoxBodyFrame(nsIPresShell* aPresShell, nsStyleContext* aContext,
63 : nsBoxLayout* aLayoutManager);
64 : virtual ~nsListBoxBodyFrame();
65 :
66 : public:
67 : NS_DECL_QUERYFRAME_TARGET(nsListBoxBodyFrame)
68 : NS_DECL_QUERYFRAME
69 : NS_DECL_FRAMEARENA_HELPERS
70 :
71 : // non-virtual nsIListBoxObject
72 : nsresult GetRowCount(PRInt32 *aResult);
73 : nsresult GetNumberOfVisibleRows(PRInt32 *aResult);
74 : nsresult GetIndexOfFirstVisibleRow(PRInt32 *aResult);
75 : nsresult EnsureIndexIsVisible(PRInt32 aRowIndex);
76 : nsresult ScrollToIndex(PRInt32 aRowIndex);
77 : nsresult ScrollByLines(PRInt32 aNumLines);
78 : nsresult GetItemAtIndex(PRInt32 aIndex, nsIDOMElement **aResult);
79 : nsresult GetIndexOfItem(nsIDOMElement *aItem, PRInt32 *aResult);
80 :
81 : friend nsIFrame* NS_NewListBoxBodyFrame(nsIPresShell* aPresShell,
82 : nsStyleContext* aContext);
83 :
84 : // nsIFrame
85 : NS_IMETHOD Init(nsIContent* aContent,
86 : nsIFrame* aParent,
87 : nsIFrame* aPrevInFlow);
88 : virtual void DestroyFrom(nsIFrame* aDestructRoot);
89 :
90 : NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID, nsIAtom* aAttribute, PRInt32 aModType);
91 :
92 : // nsIScrollbarMediator
93 : NS_IMETHOD PositionChanged(nsScrollbarFrame* aScrollbar, PRInt32 aOldIndex, PRInt32& aNewIndex);
94 : NS_IMETHOD ScrollbarButtonPressed(nsScrollbarFrame* aScrollbar, PRInt32 aOldIndex, PRInt32 aNewIndex);
95 : NS_IMETHOD VisibilityChanged(bool aVisible);
96 :
97 : // nsIReflowCallback
98 : virtual bool ReflowFinished();
99 : virtual void ReflowCallbackCanceled();
100 :
101 : // nsIBox
102 : NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState);
103 : virtual void MarkIntrinsicWidthsDirty();
104 :
105 : virtual nsSize GetMinSizeForScrollArea(nsBoxLayoutState& aBoxLayoutState);
106 : virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState);
107 :
108 : // size calculation
109 : PRInt32 GetRowCount();
110 0 : PRInt32 GetRowHeightAppUnits() { return mRowHeight; }
111 : PRInt32 GetFixedRowSize();
112 : void SetRowHeight(nscoord aRowHeight);
113 : nscoord GetYPosition();
114 : nscoord GetAvailableHeight();
115 : nscoord ComputeIntrinsicWidth(nsBoxLayoutState& aBoxLayoutState);
116 :
117 : // scrolling
118 : nsresult InternalPositionChangedCallback();
119 : nsresult InternalPositionChanged(bool aUp, PRInt32 aDelta);
120 : // Process pending position changed events, then do the position change.
121 : // This can wipe out the frametree.
122 : nsresult DoInternalPositionChangedSync(bool aUp, PRInt32 aDelta);
123 : // Actually do the internal position change. This can wipe out the frametree
124 : nsresult DoInternalPositionChanged(bool aUp, PRInt32 aDelta);
125 : nsListScrollSmoother* GetSmoother();
126 : void VerticalScroll(PRInt32 aDelta);
127 :
128 : // frames
129 : nsIFrame* GetFirstFrame();
130 : nsIFrame* GetLastFrame();
131 :
132 : // lazy row creation and destruction
133 : void CreateRows();
134 : void DestroyRows(PRInt32& aRowsToLose);
135 : void ReverseDestroyRows(PRInt32& aRowsToLose);
136 : nsIBox* GetFirstItemBox(PRInt32 aOffset, bool* aCreated);
137 : nsIBox* GetNextItemBox(nsIBox* aBox, PRInt32 aOffset, bool* aCreated);
138 : bool ContinueReflow(nscoord height);
139 : NS_IMETHOD ListBoxAppendFrames(nsFrameList& aFrameList);
140 : NS_IMETHOD ListBoxInsertFrames(nsIFrame* aPrevFrame, nsFrameList& aFrameList);
141 : void OnContentInserted(nsPresContext* aPresContext, nsIContent* aContent);
142 : void OnContentRemoved(nsPresContext* aPresContext, nsIContent* aContainer,
143 : nsIFrame* aChildFrame, nsIContent* aOldNextSibling);
144 :
145 : void GetListItemContentAt(PRInt32 aIndex, nsIContent** aContent);
146 : void GetListItemNextSibling(nsIContent* aListItem, nsIContent** aContent, PRInt32& aSiblingIndex);
147 :
148 : void PostReflowCallback();
149 :
150 0 : bool SetBoxObject(nsPIBoxObject* aBoxObject)
151 : {
152 0 : NS_ENSURE_TRUE(!mBoxObject, false);
153 0 : mBoxObject = aBoxObject;
154 0 : return true;
155 : }
156 :
157 : virtual bool SupportsOrdinalsInChildren();
158 :
159 0 : virtual bool ComputesOwnOverflowArea() { return true; }
160 :
161 : protected:
162 : class nsPositionChangedEvent;
163 : friend class nsPositionChangedEvent;
164 :
165 : class nsPositionChangedEvent : public nsRunnable
166 0 : {
167 : public:
168 0 : nsPositionChangedEvent(nsListBoxBodyFrame* aFrame,
169 : bool aUp, PRInt32 aDelta) :
170 0 : mFrame(aFrame), mUp(aUp), mDelta(aDelta)
171 0 : {}
172 :
173 0 : NS_IMETHOD Run()
174 : {
175 0 : if (!mFrame) {
176 0 : return NS_OK;
177 : }
178 :
179 0 : mFrame->mPendingPositionChangeEvents.RemoveElement(this);
180 :
181 0 : return mFrame->DoInternalPositionChanged(mUp, mDelta);
182 : }
183 :
184 0 : void Revoke() {
185 0 : mFrame = nsnull;
186 0 : }
187 :
188 : nsListBoxBodyFrame* mFrame;
189 : bool mUp;
190 : PRInt32 mDelta;
191 : };
192 :
193 : void ComputeTotalRowCount();
194 : void RemoveChildFrame(nsBoxLayoutState &aState, nsIFrame *aChild);
195 :
196 : nsTArray< nsRefPtr<nsPositionChangedEvent> > mPendingPositionChangeEvents;
197 : nsCOMPtr<nsPIBoxObject> mBoxObject;
198 :
199 : // frame markers
200 : nsWeakFrame mTopFrame;
201 : nsIFrame* mBottomFrame;
202 : nsIFrame* mLinkupFrame;
203 :
204 : nsListScrollSmoother* mScrollSmoother;
205 :
206 : PRInt32 mRowsToPrepend;
207 :
208 : // row height
209 : PRInt32 mRowCount;
210 : nscoord mRowHeight;
211 : nscoord mAvailableHeight;
212 : nscoord mStringWidth;
213 :
214 : // scrolling
215 : PRInt32 mCurrentIndex; // Row-based
216 : PRInt32 mOldIndex;
217 : PRInt32 mYPosition;
218 : PRInt32 mTimePerRow;
219 :
220 : // row height
221 : bool mRowHeightWasSet;
222 : // scrolling
223 : bool mScrolling;
224 : bool mAdjustScroll;
225 :
226 : bool mReflowCallbackPosted;
227 : };
228 :
229 : #endif // nsListBoxBodyFrame_h
|