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