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