/src/mozilla-central/layout/xul/tree/nsTreeBodyFrame.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #ifndef nsTreeBodyFrame_h |
8 | | #define nsTreeBodyFrame_h |
9 | | |
10 | | #include "mozilla/AtomArray.h" |
11 | | #include "mozilla/Attributes.h" |
12 | | |
13 | | #include "nsLeafBoxFrame.h" |
14 | | #include "nsITreeView.h" |
15 | | #include "nsIScrollbarMediator.h" |
16 | | #include "nsITimer.h" |
17 | | #include "nsIReflowCallback.h" |
18 | | #include "nsTArray.h" |
19 | | #include "nsTreeStyleCache.h" |
20 | | #include "nsTreeColumns.h" |
21 | | #include "nsDataHashtable.h" |
22 | | #include "imgIRequest.h" |
23 | | #include "imgINotificationObserver.h" |
24 | | #include "nsScrollbarFrame.h" |
25 | | #include "nsThreadUtils.h" |
26 | | #include "mozilla/LookAndFeel.h" |
27 | | |
28 | | class nsFontMetrics; |
29 | | class nsOverflowChecker; |
30 | | class nsTreeImageListener; |
31 | | |
32 | | namespace mozilla { |
33 | | namespace layout { |
34 | | class ScrollbarActivity; |
35 | | } // namespace layout |
36 | | } // namespace mozilla |
37 | | |
38 | | // An entry in the tree's image cache |
39 | | struct nsTreeImageCacheEntry |
40 | | { |
41 | 0 | nsTreeImageCacheEntry() = default; |
42 | | nsTreeImageCacheEntry(imgIRequest* aRequest, |
43 | | imgINotificationObserver* aListener) |
44 | | : request(aRequest) |
45 | | , listener(aListener) |
46 | 0 | { } |
47 | | |
48 | | nsCOMPtr<imgIRequest> request; |
49 | | nsCOMPtr<imgINotificationObserver> listener; |
50 | | }; |
51 | | |
52 | | // The actual frame that paints the cells and rows. |
53 | | class nsTreeBodyFrame final |
54 | | : public nsLeafBoxFrame |
55 | | , public nsIScrollbarMediator |
56 | | , public nsIReflowCallback |
57 | | { |
58 | | typedef mozilla::layout::ScrollbarActivity ScrollbarActivity; |
59 | | typedef mozilla::image::ImgDrawResult ImgDrawResult; |
60 | | |
61 | | public: |
62 | | explicit nsTreeBodyFrame(ComputedStyle* aStyle); |
63 | | ~nsTreeBodyFrame(); |
64 | | |
65 | | NS_DECL_QUERYFRAME |
66 | | NS_DECL_FRAMEARENA_HELPERS(nsTreeBodyFrame) |
67 | | |
68 | | // Callback handler methods for refresh driver based animations. |
69 | | // Calls to these functions are forwarded from nsTreeImageListener. These |
70 | | // mirror how nsImageFrame works. |
71 | | nsresult OnImageIsAnimated(imgIRequest* aRequest); |
72 | | |
73 | | // non-virtual signatures like nsITreeBodyFrame |
74 | | already_AddRefed<nsTreeColumns> Columns() const |
75 | 0 | { |
76 | 0 | RefPtr<nsTreeColumns> cols = mColumns; |
77 | 0 | return cols.forget(); |
78 | 0 | } |
79 | | already_AddRefed<nsITreeView> GetExistingView() const |
80 | 0 | { |
81 | 0 | nsCOMPtr<nsITreeView> view = mView; |
82 | 0 | return view.forget(); |
83 | 0 | } |
84 | | nsresult GetView(nsITreeView **aView); |
85 | | nsresult SetView(nsITreeView *aView); |
86 | 0 | bool GetFocused() const { return mFocused; } |
87 | | nsresult SetFocused(bool aFocused); |
88 | | nsresult GetTreeBody(mozilla::dom::Element **aElement); |
89 | | int32_t RowHeight() const; |
90 | | int32_t RowWidth(); |
91 | | int32_t GetHorizontalPosition() const; |
92 | | mozilla::Maybe<mozilla::CSSIntRegion> GetSelectionRegion(); |
93 | 0 | int32_t FirstVisibleRow() const { return mTopRowIndex; } |
94 | 0 | int32_t LastVisibleRow() const { return mTopRowIndex + mPageLength; } |
95 | 0 | int32_t PageLength() const { return mPageLength; } |
96 | | nsresult EnsureRowIsVisible(int32_t aRow); |
97 | | nsresult EnsureCellIsVisible(int32_t aRow, nsTreeColumn *aCol); |
98 | | void ScrollToRow(int32_t aRow); |
99 | | void ScrollByLines(int32_t aNumLines); |
100 | | void ScrollByPages(int32_t aNumPages); |
101 | | nsresult Invalidate(); |
102 | | nsresult InvalidateColumn(nsTreeColumn *aCol); |
103 | | nsresult InvalidateRow(int32_t aRow); |
104 | | nsresult InvalidateCell(int32_t aRow, nsTreeColumn *aCol); |
105 | | nsresult InvalidateRange(int32_t aStart, int32_t aEnd); |
106 | | int32_t GetRowAt(int32_t aX, int32_t aY); |
107 | | nsresult GetCellAt(int32_t aX, int32_t aY, int32_t *aRow, |
108 | | nsTreeColumn **aCol, nsACString &aChildElt); |
109 | | nsresult GetCoordsForCellItem(int32_t aRow, nsTreeColumn *aCol, |
110 | | const nsACString &aElt, |
111 | | int32_t *aX, int32_t *aY, |
112 | | int32_t *aWidth, int32_t *aHeight); |
113 | | nsresult IsCellCropped(int32_t aRow, nsTreeColumn *aCol, bool *aResult); |
114 | | nsresult RowCountChanged(int32_t aIndex, int32_t aCount); |
115 | | nsresult BeginUpdateBatch(); |
116 | | nsresult EndUpdateBatch(); |
117 | | nsresult ClearStyleAndImageCaches(); |
118 | | void RemoveImageCacheEntry(int32_t aRowIndex, nsTreeColumn* aCol); |
119 | | |
120 | | void CancelImageRequests(); |
121 | | |
122 | | void ManageReflowCallback(const nsRect& aRect, nscoord aHorzWidth); |
123 | | |
124 | | virtual nsSize GetXULMinSize(nsBoxLayoutState& aBoxLayoutState) override; |
125 | | virtual void SetXULBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRect, |
126 | | bool aRemoveOverflowArea = false) override; |
127 | | |
128 | | // nsIReflowCallback |
129 | | virtual bool ReflowFinished() override; |
130 | | virtual void ReflowCallbackCanceled() override; |
131 | | |
132 | | // nsIScrollbarMediator |
133 | | virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection, |
134 | | nsIScrollbarMediator::ScrollSnapMode aSnap |
135 | | = nsIScrollbarMediator::DISABLE_SNAP) override; |
136 | | virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection, |
137 | | nsIScrollbarMediator::ScrollSnapMode aSnap |
138 | | = nsIScrollbarMediator::DISABLE_SNAP) override; |
139 | | virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection, |
140 | | nsIScrollbarMediator::ScrollSnapMode aSnap |
141 | | = nsIScrollbarMediator::DISABLE_SNAP) override; |
142 | | virtual void RepeatButtonScroll(nsScrollbarFrame* aScrollbar) override; |
143 | | virtual void ThumbMoved(nsScrollbarFrame* aScrollbar, |
144 | | nscoord aOldPos, |
145 | | nscoord aNewPos) override; |
146 | 0 | virtual void ScrollbarReleased(nsScrollbarFrame* aScrollbar) override {} |
147 | 0 | virtual void VisibilityChanged(bool aVisible) override { Invalidate(); } |
148 | 0 | virtual nsIFrame* GetScrollbarBox(bool aVertical) override { |
149 | 0 | ScrollParts parts = GetScrollParts(); |
150 | 0 | return aVertical ? parts.mVScrollbar : parts.mHScrollbar; |
151 | 0 | } |
152 | | virtual void ScrollbarActivityStarted() const override; |
153 | | virtual void ScrollbarActivityStopped() const override; |
154 | 0 | virtual bool IsScrollbarOnRight() const override { |
155 | 0 | return (StyleVisibility()->mDirection == NS_STYLE_DIRECTION_LTR); |
156 | 0 | } |
157 | 0 | virtual bool ShouldSuppressScrollbarRepaints() const override { |
158 | 0 | return false; |
159 | 0 | } |
160 | | |
161 | | // Overridden from nsIFrame to cache our pres context. |
162 | | virtual void Init(nsIContent* aContent, |
163 | | nsContainerFrame* aParent, |
164 | | nsIFrame* aPrevInFlow) override; |
165 | | virtual void DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData) override; |
166 | | |
167 | | virtual nsresult GetCursor(const nsPoint& aPoint, |
168 | | nsIFrame::Cursor& aCursor) override; |
169 | | |
170 | | virtual nsresult HandleEvent(nsPresContext* aPresContext, |
171 | | mozilla::WidgetGUIEvent* aEvent, |
172 | | nsEventStatus* aEventStatus) override; |
173 | | |
174 | | virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, |
175 | | const nsDisplayListSet& aLists) override; |
176 | | |
177 | | virtual void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override; |
178 | | |
179 | | friend nsIFrame* NS_NewTreeBodyFrame(nsIPresShell* aPresShell); |
180 | | friend class nsTreeColumn; |
181 | | |
182 | | struct ScrollParts { |
183 | | nsScrollbarFrame* mVScrollbar; |
184 | | RefPtr<Element> mVScrollbarContent; |
185 | | nsScrollbarFrame* mHScrollbar; |
186 | | RefPtr<Element> mHScrollbarContent; |
187 | | nsIFrame* mColumnsFrame; |
188 | | nsIScrollableFrame* mColumnsScrollFrame; |
189 | | }; |
190 | | |
191 | | ImgDrawResult PaintTreeBody(gfxContext& aRenderingContext, |
192 | | const nsRect& aDirtyRect, nsPoint aPt, |
193 | | nsDisplayListBuilder* aBuilder); |
194 | | |
195 | 0 | nsITreeBoxObject* GetTreeBoxObject() const { return mTreeBoxObject; } |
196 | | |
197 | | // Get the base element, <tree> |
198 | | mozilla::dom::Element* GetBaseElement(); |
199 | | |
200 | 0 | bool GetVerticalOverflow() const { return mVerticalOverflow; } |
201 | 0 | bool GetHorizontalOverflow() const {return mHorizontalOverflow; } |
202 | | |
203 | | // This returns the property array where atoms are stored for style during |
204 | | // draw, whether the row currently being drawn is selected, hovered, etc. |
205 | | const mozilla::AtomArray& GetPropertyArrayForCurrentDrawingItem() |
206 | 0 | { |
207 | 0 | return mScratchArray; |
208 | 0 | } |
209 | | |
210 | | protected: |
211 | | friend class nsOverflowChecker; |
212 | | |
213 | | // This method paints a specific column background of the tree. |
214 | | ImgDrawResult PaintColumn(nsTreeColumn* aColumn, |
215 | | const nsRect& aColumnRect, |
216 | | nsPresContext* aPresContext, |
217 | | gfxContext& aRenderingContext, |
218 | | const nsRect& aDirtyRect); |
219 | | |
220 | | // This method paints a single row in the tree. |
221 | | ImgDrawResult PaintRow(int32_t aRowIndex, |
222 | | const nsRect& aRowRect, |
223 | | nsPresContext* aPresContext, |
224 | | gfxContext& aRenderingContext, |
225 | | const nsRect& aDirtyRect, |
226 | | nsPoint aPt, |
227 | | nsDisplayListBuilder* aBuilder); |
228 | | |
229 | | // This method paints a single separator in the tree. |
230 | | ImgDrawResult PaintSeparator(int32_t aRowIndex, |
231 | | const nsRect& aSeparatorRect, |
232 | | nsPresContext* aPresContext, |
233 | | gfxContext& aRenderingContext, |
234 | | const nsRect& aDirtyRect); |
235 | | |
236 | | // This method paints a specific cell in a given row of the tree. |
237 | | ImgDrawResult PaintCell(int32_t aRowIndex, |
238 | | nsTreeColumn* aColumn, |
239 | | const nsRect& aCellRect, |
240 | | nsPresContext* aPresContext, |
241 | | gfxContext& aRenderingContext, |
242 | | const nsRect& aDirtyRect, |
243 | | nscoord& aCurrX, |
244 | | nsPoint aPt, |
245 | | nsDisplayListBuilder* aBuilder); |
246 | | |
247 | | // This method paints the twisty inside a cell in the primary column of an tree. |
248 | | ImgDrawResult PaintTwisty(int32_t aRowIndex, |
249 | | nsTreeColumn* aColumn, |
250 | | const nsRect& aTwistyRect, |
251 | | nsPresContext* aPresContext, |
252 | | gfxContext& aRenderingContext, |
253 | | const nsRect& aDirtyRect, |
254 | | nscoord& aRemainingWidth, |
255 | | nscoord& aCurrX); |
256 | | |
257 | | // This method paints the image inside the cell of an tree. |
258 | | ImgDrawResult PaintImage(int32_t aRowIndex, |
259 | | nsTreeColumn* aColumn, |
260 | | const nsRect& aImageRect, |
261 | | nsPresContext* aPresContext, |
262 | | gfxContext& aRenderingContext, |
263 | | const nsRect& aDirtyRect, |
264 | | nscoord& aRemainingWidth, |
265 | | nscoord& aCurrX, |
266 | | nsDisplayListBuilder* aBuilder); |
267 | | |
268 | | // This method paints the text string inside a particular cell of the tree. |
269 | | ImgDrawResult PaintText(int32_t aRowIndex, |
270 | | nsTreeColumn* aColumn, |
271 | | const nsRect& aTextRect, |
272 | | nsPresContext* aPresContext, |
273 | | gfxContext& aRenderingContext, |
274 | | const nsRect& aDirtyRect, |
275 | | nscoord& aCurrX); |
276 | | |
277 | | // This method paints the checkbox inside a particular cell of the tree. |
278 | | ImgDrawResult PaintCheckbox(int32_t aRowIndex, |
279 | | nsTreeColumn* aColumn, |
280 | | const nsRect& aCheckboxRect, |
281 | | nsPresContext* aPresContext, |
282 | | gfxContext& aRenderingContext, |
283 | | const nsRect& aDirtyRect); |
284 | | |
285 | | // This method paints a drop feedback of the tree. |
286 | | ImgDrawResult PaintDropFeedback(const nsRect& aDropFeedbackRect, |
287 | | nsPresContext* aPresContext, |
288 | | gfxContext& aRenderingContext, |
289 | | const nsRect& aDirtyRect, |
290 | | nsPoint aPt); |
291 | | |
292 | | // This method is called with a specific ComputedStyle and rect to |
293 | | // paint the background rect as if it were a full-blown frame. |
294 | | ImgDrawResult PaintBackgroundLayer(ComputedStyle* aComputedStyle, |
295 | | nsPresContext* aPresContext, |
296 | | gfxContext& aRenderingContext, |
297 | | const nsRect& aRect, |
298 | | const nsRect& aDirtyRect); |
299 | | |
300 | | |
301 | | // An internal hit test. aX and aY are expected to be in twips in the |
302 | | // coordinate system of this frame. |
303 | | int32_t GetRowAtInternal(nscoord aX, nscoord aY); |
304 | | |
305 | | // Check for bidi characters in the text, and if there are any, ensure |
306 | | // that the prescontext is in bidi mode. |
307 | | void CheckTextForBidi(nsAutoString& aText); |
308 | | |
309 | | void AdjustForCellText(nsAutoString& aText, |
310 | | int32_t aRowIndex, |
311 | | nsTreeColumn* aColumn, |
312 | | gfxContext& aRenderingContext, |
313 | | nsFontMetrics& aFontMetrics, |
314 | | nsRect& aTextRect); |
315 | | |
316 | | // A helper used when hit testing. |
317 | | nsICSSAnonBoxPseudo* GetItemWithinCellAt(nscoord aX, |
318 | | const nsRect& aCellRect, |
319 | | int32_t aRowIndex, |
320 | | nsTreeColumn* aColumn); |
321 | | |
322 | | // An internal hit test. aX and aY are expected to be in twips in the |
323 | | // coordinate system of this frame. |
324 | | void GetCellAt(nscoord aX, nscoord aY, int32_t* aRow, nsTreeColumn** aCol, |
325 | | nsICSSAnonBoxPseudo** aChildElt); |
326 | | |
327 | | // Retrieve the area for the twisty for a cell. |
328 | | nsITheme* GetTwistyRect(int32_t aRowIndex, |
329 | | nsTreeColumn* aColumn, |
330 | | nsRect& aImageRect, |
331 | | nsRect& aTwistyRect, |
332 | | nsPresContext* aPresContext, |
333 | | ComputedStyle* aTwistyContext); |
334 | | |
335 | | // Fetch an image from the image cache. |
336 | | nsresult GetImage(int32_t aRowIndex, nsTreeColumn* aCol, bool aUseContext, |
337 | | ComputedStyle* aComputedStyle, bool& aAllowImageRegions, imgIContainer** aResult); |
338 | | |
339 | | // Returns the size of a given image. This size *includes* border and |
340 | | // padding. It does not include margins. |
341 | | nsRect GetImageSize(int32_t aRowIndex, nsTreeColumn* aCol, bool aUseContext, ComputedStyle* aComputedStyle); |
342 | | |
343 | | // Returns the destination size of the image, not including borders and padding. |
344 | | nsSize GetImageDestSize(ComputedStyle* aComputedStyle, bool useImageRegion, imgIContainer* image); |
345 | | |
346 | | // Returns the source rectangle of the image to be displayed. |
347 | | nsRect GetImageSourceRect(ComputedStyle* aComputedStyle, bool useImageRegion, imgIContainer* image); |
348 | | |
349 | | // Returns the height of rows in the tree. |
350 | | int32_t GetRowHeight(); |
351 | | |
352 | | // Returns our indentation width. |
353 | | int32_t GetIndentation(); |
354 | | |
355 | | // Calculates our width/height once border and padding have been removed. |
356 | | void CalcInnerBox(); |
357 | | |
358 | | // Calculate the total width of our scrollable portion |
359 | | nscoord CalcHorzWidth(const ScrollParts& aParts); |
360 | | |
361 | | // Looks up a ComputedStyle in the style cache. On a cache miss we resolve |
362 | | // the pseudo-styles passed in and place them into the cache. |
363 | | ComputedStyle* GetPseudoComputedStyle(nsICSSAnonBoxPseudo* aPseudoElement); |
364 | | |
365 | | // Retrieves the scrollbars and scrollview relevant to this treebody. We |
366 | | // traverse the frame tree under our base element, in frame order, looking |
367 | | // for the first relevant vertical scrollbar, horizontal scrollbar, and |
368 | | // scrollable frame (with associated content and scrollable view). These |
369 | | // are all volatile and should not be retained. |
370 | | ScrollParts GetScrollParts(); |
371 | | |
372 | | // Update the curpos of the scrollbar. |
373 | | void UpdateScrollbars(const ScrollParts& aParts); |
374 | | |
375 | | // Update the maxpos of the scrollbar. |
376 | | void InvalidateScrollbars(const ScrollParts& aParts, AutoWeakFrame& aWeakColumnsFrame); |
377 | | |
378 | | // Check overflow and generate events. |
379 | | void CheckOverflow(const ScrollParts& aParts); |
380 | | |
381 | | // Calls UpdateScrollbars, Invalidate aNeedsFullInvalidation if true, |
382 | | // InvalidateScrollbars and finally CheckOverflow. |
383 | | // returns true if the frame is still alive after the method call. |
384 | | bool FullScrollbarsUpdate(bool aNeedsFullInvalidation); |
385 | | |
386 | | // Use to auto-fill some of the common properties without the view having to do it. |
387 | | // Examples include container, open, selected, and focus. |
388 | | void PrefillPropertyArray(int32_t aRowIndex, nsTreeColumn* aCol); |
389 | | |
390 | | // Our internal scroll method, used by all the public scroll methods. |
391 | | nsresult ScrollInternal(const ScrollParts& aParts, int32_t aRow); |
392 | | nsresult ScrollToRowInternal(const ScrollParts& aParts, int32_t aRow); |
393 | | nsresult ScrollHorzInternal(const ScrollParts& aParts, int32_t aPosition); |
394 | | nsresult EnsureRowIsVisibleInternal(const ScrollParts& aParts, int32_t aRow); |
395 | | |
396 | | // Convert client pixels into appunits in our coordinate space. |
397 | | nsPoint AdjustClientCoordsToBoxCoordSpace(int32_t aX, int32_t aY); |
398 | | |
399 | | // Cache the box object |
400 | | void EnsureBoxObject(); |
401 | | |
402 | | void EnsureView(); |
403 | | |
404 | | nsresult GetCellWidth(int32_t aRow, nsTreeColumn* aCol, |
405 | | gfxContext* aRenderingContext, |
406 | | nscoord& aDesiredSize, nscoord& aCurrentSize); |
407 | | nscoord CalcMaxRowWidth(); |
408 | | |
409 | | // Translate the given rect horizontally from tree coordinates into the |
410 | | // coordinate system of our nsTreeBodyFrame. If clip is true, then clip the |
411 | | // rect to its intersection with mInnerBox in the horizontal direction. |
412 | | // Return whether the result has a nonempty intersection with mInnerBox |
413 | | // after projecting both onto the horizontal coordinate axis. |
414 | | bool OffsetForHorzScroll(nsRect& rect, bool clip); |
415 | | |
416 | | bool CanAutoScroll(int32_t aRowIndex); |
417 | | |
418 | | // Calc the row and above/below/on status given where the mouse currently is hovering. |
419 | | // Also calc if we're in the region in which we want to auto-scroll the tree. |
420 | | // A positive value of |aScrollLines| means scroll down, a negative value |
421 | | // means scroll up, a zero value means that we aren't in drag scroll region. |
422 | | void ComputeDropPosition(mozilla::WidgetGUIEvent* aEvent, |
423 | | int32_t* aRow, |
424 | | int16_t* aOrient, |
425 | | int16_t* aScrollLines); |
426 | | |
427 | 0 | void InvalidateDropFeedback(int32_t aRow, int16_t aOrientation) { |
428 | 0 | InvalidateRow(aRow); |
429 | 0 | if (aOrientation != nsITreeView::DROP_ON) |
430 | 0 | InvalidateRow(aRow + aOrientation); |
431 | 0 | } |
432 | | |
433 | | public: |
434 | | /** |
435 | | * Remove an nsITreeImageListener from being tracked by this frame. Only tree |
436 | | * image listeners that are created by this frame are tracked. |
437 | | * |
438 | | * @param aListener A pointer to an nsTreeImageListener to no longer |
439 | | * track. |
440 | | */ |
441 | | void RemoveTreeImageListener(nsTreeImageListener* aListener); |
442 | | |
443 | | protected: |
444 | | |
445 | | // Create a new timer. This method is used to delay various actions like |
446 | | // opening/closing folders or tree scrolling. |
447 | | // aID is type of the action, aFunc is the function to be called when |
448 | | // the timer fires and aType is type of timer - one shot or repeating. |
449 | | nsresult CreateTimer(const mozilla::LookAndFeel::IntID aID, |
450 | | nsTimerCallbackFunc aFunc, int32_t aType, |
451 | | nsITimer** aTimer, const char* aName); |
452 | | |
453 | | static void OpenCallback(nsITimer *aTimer, void *aClosure); |
454 | | |
455 | | static void CloseCallback(nsITimer *aTimer, void *aClosure); |
456 | | |
457 | | static void LazyScrollCallback(nsITimer *aTimer, void *aClosure); |
458 | | |
459 | | static void ScrollCallback(nsITimer *aTimer, void *aClosure); |
460 | | |
461 | | class ScrollEvent : public mozilla::Runnable { |
462 | | public: |
463 | | NS_DECL_NSIRUNNABLE |
464 | | explicit ScrollEvent(nsTreeBodyFrame* aInner) |
465 | | : mozilla::Runnable("nsTreeBodyFrame::ScrollEvent") |
466 | | , mInner(aInner) |
467 | 0 | { |
468 | 0 | } |
469 | 0 | void Revoke() { mInner = nullptr; } |
470 | | private: |
471 | | nsTreeBodyFrame* mInner; |
472 | | }; |
473 | | |
474 | | void PostScrollEvent(); |
475 | | void FireScrollEvent(); |
476 | | |
477 | | /** |
478 | | * Clear the pointer to this frame for all nsTreeImageListeners that were |
479 | | * created by this frame. |
480 | | */ |
481 | | void DetachImageListeners(); |
482 | | |
483 | | #ifdef ACCESSIBILITY |
484 | | /** |
485 | | * Fires 'treeRowCountChanged' event asynchronously. The event is a |
486 | | * CustomEvent that is used to expose the following information structures |
487 | | * via a property bag. |
488 | | * |
489 | | * @param aIndex the row index rows are added/removed from |
490 | | * @param aCount the number of added/removed rows (the sign points to |
491 | | * an operation, plus - addition, minus - removing) |
492 | | */ |
493 | | void FireRowCountChangedEvent(int32_t aIndex, int32_t aCount); |
494 | | |
495 | | /** |
496 | | * Fires 'treeInvalidated' event asynchronously. The event is a CustomEvent |
497 | | * that is used to expose the information structures described by method |
498 | | * arguments via a property bag. |
499 | | * |
500 | | * @param aStartRow the start index of invalidated rows, -1 means that |
501 | | * columns have been invalidated only |
502 | | * @param aEndRow the end index of invalidated rows, -1 means that columns |
503 | | * have been invalidated only |
504 | | * @param aStartCol the start invalidated column, nullptr means that only rows |
505 | | * have been invalidated |
506 | | * @param aEndCol the end invalidated column, nullptr means that rows have |
507 | | * been invalidated only |
508 | | */ |
509 | | void FireInvalidateEvent(int32_t aStartRow, int32_t aEndRow, |
510 | | nsTreeColumn *aStartCol, nsTreeColumn *aEndCol); |
511 | | #endif |
512 | | |
513 | | protected: // Data Members |
514 | | |
515 | | class Slots { |
516 | | public: |
517 | | Slots() |
518 | | : mDropAllowed(false) |
519 | | , mIsDragging(false) |
520 | | , mDropRow(-1) |
521 | | , mDropOrient(-1) |
522 | | , mScrollLines(0) |
523 | 0 | , mDragAction(0) { |
524 | 0 | } |
525 | | |
526 | 0 | ~Slots() { |
527 | 0 | if (mTimer) |
528 | 0 | mTimer->Cancel(); |
529 | 0 | } |
530 | | |
531 | | friend class nsTreeBodyFrame; |
532 | | |
533 | | protected: |
534 | | // If the drop is actually allowed here or not. |
535 | | bool mDropAllowed; |
536 | | |
537 | | // True while dragging over the tree. |
538 | | bool mIsDragging; |
539 | | |
540 | | // The row the mouse is hovering over during a drop. |
541 | | int32_t mDropRow; |
542 | | |
543 | | // Where we want to draw feedback (above/on this row/below) if allowed. |
544 | | int16_t mDropOrient; |
545 | | |
546 | | // Number of lines to be scrolled. |
547 | | int16_t mScrollLines; |
548 | | |
549 | | // The drag action that was received for this slot |
550 | | uint32_t mDragAction; |
551 | | |
552 | | // Timer for opening/closing spring loaded folders or scrolling the tree. |
553 | | nsCOMPtr<nsITimer> mTimer; |
554 | | |
555 | | // An array used to keep track of all spring loaded folders. |
556 | | nsTArray<int32_t> mArray; |
557 | | }; |
558 | | |
559 | | Slots* mSlots; |
560 | | |
561 | | nsRevocableEventPtr<ScrollEvent> mScrollEvent; |
562 | | |
563 | | RefPtr<ScrollbarActivity> mScrollbarActivity; |
564 | | |
565 | | // The cached box object parent. |
566 | | nsCOMPtr<nsITreeBoxObject> mTreeBoxObject; |
567 | | |
568 | | // Cached column information. |
569 | | RefPtr<nsTreeColumns> mColumns; |
570 | | |
571 | | // The current view for this tree widget. We get all of our row and cell data |
572 | | // from the view. |
573 | | nsCOMPtr<nsITreeView> mView; |
574 | | |
575 | | // A cache of all the ComputedStyles we have seen for rows and cells of the tree. This is a mapping from |
576 | | // a list of atoms to a corresponding ComputedStyle. This cache stores every combination that |
577 | | // occurs in the tree, so for n distinct properties, this cache could have 2 to the n entries |
578 | | // (the power set of all row properties). |
579 | | nsTreeStyleCache mStyleCache; |
580 | | |
581 | | // A hashtable that maps from URLs to image request/listener pairs. The URL |
582 | | // is provided by the view or by the ComputedStyle. The ComputedStyle |
583 | | // represents a resolved :-moz-tree-cell-image (or twisty) pseudo-element. |
584 | | // It maps directly to an imgIRequest. |
585 | | nsDataHashtable<nsStringHashKey, nsTreeImageCacheEntry> mImageCache; |
586 | | |
587 | | // A scratch array used when looking up cached ComputedStyles. |
588 | | mozilla::AtomArray mScratchArray; |
589 | | |
590 | | // The index of the first visible row and the # of rows visible onscreen. |
591 | | // The tree only examines onscreen rows, starting from |
592 | | // this index and going up to index+pageLength. |
593 | | int32_t mTopRowIndex; |
594 | | int32_t mPageLength; |
595 | | |
596 | | // The horizontal scroll position |
597 | | nscoord mHorzPosition; |
598 | | |
599 | | // The original desired horizontal width before changing it and posting a |
600 | | // reflow callback. In some cases, the desired horizontal width can first be |
601 | | // different from the current desired horizontal width, only to return to |
602 | | // the same value later during the same reflow. In this case, we can cancel |
603 | | // the posted reflow callback and prevent an unnecessary reflow. |
604 | | nscoord mOriginalHorzWidth; |
605 | | // Our desired horizontal width (the width for which we actually have tree |
606 | | // columns). |
607 | | nscoord mHorzWidth; |
608 | | // The amount by which to adjust the width of the last cell. |
609 | | // This depends on whether or not the columnpicker and scrollbars are present. |
610 | | nscoord mAdjustWidth; |
611 | | |
612 | | // Cached heights and indent info. |
613 | | nsRect mInnerBox; // 4-byte aligned |
614 | | int32_t mRowHeight; |
615 | | int32_t mIndentation; |
616 | | nscoord mStringWidth; |
617 | | |
618 | | int32_t mUpdateBatchNest; |
619 | | |
620 | | // Cached row count. |
621 | | int32_t mRowCount; |
622 | | |
623 | | // The row the mouse is hovering over. |
624 | | int32_t mMouseOverRow; |
625 | | |
626 | | // Whether or not we're currently focused. |
627 | | bool mFocused; |
628 | | |
629 | | // Do we have a fixed number of onscreen rows? |
630 | | bool mHasFixedRowCount; |
631 | | |
632 | | bool mVerticalOverflow; |
633 | | bool mHorizontalOverflow; |
634 | | |
635 | | bool mReflowCallbackPosted; |
636 | | |
637 | | // Set while we flush layout to take account of effects of |
638 | | // overflow/underflow event handlers |
639 | | bool mCheckingOverflow; |
640 | | |
641 | | // Hash table to keep track of which listeners we created and thus |
642 | | // have pointers to us. |
643 | | nsTHashtable<nsPtrHashKey<nsTreeImageListener> > mCreatedListeners; |
644 | | |
645 | | }; // class nsTreeBodyFrame |
646 | | |
647 | | #endif |