/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef nsTreeBodyFrame_h #define nsTreeBodyFrame_h #include "mozilla/Attributes.h" #include "nsLeafBoxFrame.h" #include "nsITreeView.h" #include "nsICSSPseudoComparator.h" #include "nsIScrollbarMediator.h" #include "nsITimer.h" #include "nsIReflowCallback.h" #include "nsTArray.h" #include "nsTreeStyleCache.h" #include "nsTreeColumns.h" #include "nsDataHashtable.h" #include "imgIRequest.h" #include "imgINotificationObserver.h" #include "nsScrollbarFrame.h" #include "nsThreadUtils.h" #include "mozilla/LookAndFeel.h" class nsFontMetrics; class nsOverflowChecker; class nsTreeImageListener; namespace mozilla { namespace layout { class ScrollbarActivity; } // namespace layout } // namespace mozilla // An entry in the tree's image cache struct nsTreeImageCacheEntry { nsTreeImageCacheEntry() {} nsTreeImageCacheEntry(imgIRequest *aRequest, imgINotificationObserver *aListener) : request(aRequest), listener(aListener) {} nsCOMPtr request; nsCOMPtr listener; }; // The actual frame that paints the cells and rows. class nsTreeBodyFrame final : public nsLeafBoxFrame , public nsICSSPseudoComparator , public nsIScrollbarMediator , public nsIReflowCallback { typedef mozilla::layout::ScrollbarActivity ScrollbarActivity; typedef mozilla::image::DrawResult DrawResult; public: explicit nsTreeBodyFrame(nsStyleContext* aContext); ~nsTreeBodyFrame(); NS_DECL_QUERYFRAME_TARGET(nsTreeBodyFrame) NS_DECL_QUERYFRAME NS_DECL_FRAMEARENA_HELPERS // Callback handler methods for refresh driver based animations. // Calls to these functions are forwarded from nsTreeImageListener. These // mirror how nsImageFrame works. nsresult OnImageIsAnimated(imgIRequest* aRequest); // non-virtual signatures like nsITreeBodyFrame already_AddRefed Columns() const { RefPtr cols = mColumns; return cols.forget(); } already_AddRefed GetExistingView() const { nsCOMPtr view = mView; return view.forget(); } nsresult GetView(nsITreeView **aView); nsresult SetView(nsITreeView *aView); bool GetFocused() const { return mFocused; } nsresult SetFocused(bool aFocused); nsresult GetTreeBody(nsIDOMElement **aElement); int32_t RowHeight() const; int32_t RowWidth(); int32_t GetHorizontalPosition() const; nsresult GetSelectionRegion(nsIScriptableRegion **aRegion); int32_t FirstVisibleRow() const { return mTopRowIndex; } int32_t LastVisibleRow() const { return mTopRowIndex + mPageLength; } int32_t PageLength() const { return mPageLength; } nsresult EnsureRowIsVisible(int32_t aRow); nsresult EnsureCellIsVisible(int32_t aRow, nsITreeColumn *aCol); nsresult ScrollToRow(int32_t aRow); nsresult ScrollByLines(int32_t aNumLines); nsresult ScrollByPages(int32_t aNumPages); nsresult ScrollToCell(int32_t aRow, nsITreeColumn *aCol); nsresult ScrollToColumn(nsITreeColumn *aCol); nsresult ScrollToHorizontalPosition(int32_t aValue); nsresult Invalidate(); nsresult InvalidateColumn(nsITreeColumn *aCol); nsresult InvalidateRow(int32_t aRow); nsresult InvalidateCell(int32_t aRow, nsITreeColumn *aCol); nsresult InvalidateRange(int32_t aStart, int32_t aEnd); nsresult InvalidateColumnRange(int32_t aStart, int32_t aEnd, nsITreeColumn *aCol); nsresult GetRowAt(int32_t aX, int32_t aY, int32_t *aValue); nsresult GetCellAt(int32_t aX, int32_t aY, int32_t *aRow, nsITreeColumn **aCol, nsACString &aChildElt); nsresult GetCoordsForCellItem(int32_t aRow, nsITreeColumn *aCol, const nsACString &aElt, int32_t *aX, int32_t *aY, int32_t *aWidth, int32_t *aHeight); nsresult IsCellCropped(int32_t aRow, nsITreeColumn *aCol, bool *aResult); nsresult RowCountChanged(int32_t aIndex, int32_t aCount); nsresult BeginUpdateBatch(); nsresult EndUpdateBatch(); nsresult ClearStyleAndImageCaches(); void CancelImageRequests(); void ManageReflowCallback(const nsRect& aRect, nscoord aHorzWidth); virtual nsSize GetXULMinSize(nsBoxLayoutState& aBoxLayoutState) override; virtual void SetXULBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRect, bool aRemoveOverflowArea = false) override; // nsIReflowCallback virtual bool ReflowFinished() override; virtual void ReflowCallbackCanceled() override; // nsICSSPseudoComparator virtual bool PseudoMatches(nsCSSSelector* aSelector) override; // nsIScrollbarMediator virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection, nsIScrollbarMediator::ScrollSnapMode aSnap = nsIScrollbarMediator::DISABLE_SNAP) override; virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection, nsIScrollbarMediator::ScrollSnapMode aSnap = nsIScrollbarMediator::DISABLE_SNAP) override; virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection, nsIScrollbarMediator::ScrollSnapMode aSnap = nsIScrollbarMediator::DISABLE_SNAP) override; virtual void RepeatButtonScroll(nsScrollbarFrame* aScrollbar) override; virtual void ThumbMoved(nsScrollbarFrame* aScrollbar, nscoord aOldPos, nscoord aNewPos) override; virtual void ScrollbarReleased(nsScrollbarFrame* aScrollbar) override {} virtual void VisibilityChanged(bool aVisible) override { Invalidate(); } virtual nsIFrame* GetScrollbarBox(bool aVertical) override { ScrollParts parts = GetScrollParts(); return aVertical ? parts.mVScrollbar : parts.mHScrollbar; } virtual void ScrollbarActivityStarted() const override; virtual void ScrollbarActivityStopped() const override; virtual bool IsScrollbarOnRight() const override { return (StyleVisibility()->mDirection == NS_STYLE_DIRECTION_LTR); } virtual bool ShouldSuppressScrollbarRepaints() const override { return false; } // Overridden from nsIFrame to cache our pres context. virtual void Init(nsIContent* aContent, nsContainerFrame* aParent, nsIFrame* aPrevInFlow) override; virtual void DestroyFrom(nsIFrame* aDestructRoot) override; virtual nsresult GetCursor(const nsPoint& aPoint, nsIFrame::Cursor& aCursor) override; virtual nsresult HandleEvent(nsPresContext* aPresContext, mozilla::WidgetGUIEvent* aEvent, nsEventStatus* aEventStatus) override; virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsDisplayListSet& aLists) override; virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) override; friend nsIFrame* NS_NewTreeBodyFrame(nsIPresShell* aPresShell); friend class nsTreeColumn; struct ScrollParts { nsScrollbarFrame* mVScrollbar; nsCOMPtr mVScrollbarContent; nsScrollbarFrame* mHScrollbar; nsCOMPtr mHScrollbarContent; nsIFrame* mColumnsFrame; nsIScrollableFrame* mColumnsScrollFrame; }; DrawResult PaintTreeBody(nsRenderingContext& aRenderingContext, const nsRect& aDirtyRect, nsPoint aPt); nsITreeBoxObject* GetTreeBoxObject() const { return mTreeBoxObject; } // Get the base element, or