diff options
Diffstat (limited to 'layout/xul/nsListBoxBodyFrame.h')
-rw-r--r-- | layout/xul/nsListBoxBodyFrame.h | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/layout/xul/nsListBoxBodyFrame.h b/layout/xul/nsListBoxBodyFrame.h new file mode 100644 index 000000000..57bbf0257 --- /dev/null +++ b/layout/xul/nsListBoxBodyFrame.h @@ -0,0 +1,217 @@ +/* -*- 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 nsListBoxBodyFrame_h +#define nsListBoxBodyFrame_h + +#include "mozilla/Attributes.h" +#include "nsCOMPtr.h" +#include "nsBoxFrame.h" +#include "nsIScrollbarMediator.h" +#include "nsIReflowCallback.h" +#include "nsBoxLayoutState.h" +#include "nsThreadUtils.h" +#include "nsPIBoxObject.h" + +class nsPresContext; +class nsListScrollSmoother; +nsIFrame* NS_NewListBoxBodyFrame(nsIPresShell* aPresShell, + nsStyleContext* aContext); + +class nsListBoxBodyFrame final : public nsBoxFrame, + public nsIScrollbarMediator, + public nsIReflowCallback +{ + nsListBoxBodyFrame(nsStyleContext* aContext, + nsBoxLayout* aLayoutManager); + virtual ~nsListBoxBodyFrame(); + +public: + NS_DECL_QUERYFRAME_TARGET(nsListBoxBodyFrame) + NS_DECL_QUERYFRAME + NS_DECL_FRAMEARENA_HELPERS + + // non-virtual ListBoxObject + int32_t GetNumberOfVisibleRows(); + int32_t GetIndexOfFirstVisibleRow(); + nsresult EnsureIndexIsVisible(int32_t aRowIndex); + nsresult ScrollToIndex(int32_t aRowIndex); + nsresult ScrollByLines(int32_t aNumLines); + nsresult GetItemAtIndex(int32_t aIndex, nsIDOMElement **aResult); + nsresult GetIndexOfItem(nsIDOMElement *aItem, int32_t *aResult); + + friend nsIFrame* NS_NewListBoxBodyFrame(nsIPresShell* aPresShell, + nsStyleContext* aContext); + + // nsIFrame + virtual void Init(nsIContent* aContent, + nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) override; + virtual void DestroyFrom(nsIFrame* aDestructRoot) override; + + virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType) override; + + // nsIScrollbarMediator + virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode snapMode + = nsIScrollbarMediator::DISABLE_SNAP) override; + virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode snapMode + = nsIScrollbarMediator::DISABLE_SNAP) override; + virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection, + nsIScrollbarMediator::ScrollSnapMode snapMode + = nsIScrollbarMediator::DISABLE_SNAP) override; + virtual void RepeatButtonScroll(nsScrollbarFrame* aScrollbar) override; + virtual void ThumbMoved(nsScrollbarFrame* aScrollbar, + int32_t aOldPos, + int32_t aNewPos) override; + virtual void ScrollbarReleased(nsScrollbarFrame* aScrollbar) override {} + virtual void VisibilityChanged(bool aVisible) override; + virtual nsIFrame* GetScrollbarBox(bool aVertical) override; + 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; + } + + + // nsIReflowCallback + virtual bool ReflowFinished() override; + virtual void ReflowCallbackCanceled() override; + + NS_IMETHOD DoXULLayout(nsBoxLayoutState& aBoxLayoutState) override; + virtual void MarkIntrinsicISizesDirty() override; + + virtual nsSize GetXULMinSizeForScrollArea(nsBoxLayoutState& aBoxLayoutState) override; + virtual nsSize GetXULPrefSize(nsBoxLayoutState& aBoxLayoutState) override; + + // size calculation + int32_t GetRowCount(); + int32_t GetRowHeightAppUnits() { return mRowHeight; } + int32_t GetFixedRowSize(); + void SetRowHeight(nscoord aRowHeight); + nscoord GetYPosition(); + nscoord GetAvailableHeight(); + nscoord ComputeIntrinsicISize(nsBoxLayoutState& aBoxLayoutState); + + // scrolling + nsresult InternalPositionChangedCallback(); + nsresult InternalPositionChanged(bool aUp, int32_t aDelta); + // Process pending position changed events, then do the position change. + // This can wipe out the frametree. + nsresult DoInternalPositionChangedSync(bool aUp, int32_t aDelta); + // Actually do the internal position change. This can wipe out the frametree + nsresult DoInternalPositionChanged(bool aUp, int32_t aDelta); + nsListScrollSmoother* GetSmoother(); + void VerticalScroll(int32_t aDelta); + // Update the scroll index given a position, in CSS pixels + void UpdateIndex(int32_t aNewPos); + + // frames + nsIFrame* GetFirstFrame(); + nsIFrame* GetLastFrame(); + + // lazy row creation and destruction + void CreateRows(); + void DestroyRows(int32_t& aRowsToLose); + void ReverseDestroyRows(int32_t& aRowsToLose); + nsIFrame* GetFirstItemBox(int32_t aOffset, bool* aCreated); + nsIFrame* GetNextItemBox(nsIFrame* aBox, int32_t aOffset, bool* aCreated); + bool ContinueReflow(nscoord height); + NS_IMETHOD ListBoxAppendFrames(nsFrameList& aFrameList); + NS_IMETHOD ListBoxInsertFrames(nsIFrame* aPrevFrame, nsFrameList& aFrameList); + void OnContentInserted(nsIContent* aContent); + void OnContentRemoved(nsPresContext* aPresContext, nsIContent* aContainer, + nsIFrame* aChildFrame, nsIContent* aOldNextSibling); + + void GetListItemContentAt(int32_t aIndex, nsIContent** aContent); + void GetListItemNextSibling(nsIContent* aListItem, nsIContent** aContent, int32_t& aSiblingIndex); + + void PostReflowCallback(); + + bool SetBoxObject(nsPIBoxObject* aBoxObject) + { + NS_ENSURE_TRUE(!mBoxObject, false); + mBoxObject = aBoxObject; + return true; + } + + virtual bool SupportsOrdinalsInChildren() override; + + virtual bool ComputesOwnOverflowArea() override { return true; } + +protected: + class nsPositionChangedEvent; + friend class nsPositionChangedEvent; + + class nsPositionChangedEvent : public mozilla::Runnable + { + public: + nsPositionChangedEvent(nsListBoxBodyFrame* aFrame, + bool aUp, int32_t aDelta) : + mFrame(aFrame), mUp(aUp), mDelta(aDelta) + {} + + NS_IMETHOD Run() override + { + if (!mFrame) { + return NS_OK; + } + + mFrame->mPendingPositionChangeEvents.RemoveElement(this); + + return mFrame->DoInternalPositionChanged(mUp, mDelta); + } + + void Revoke() { + mFrame = nullptr; + } + + nsListBoxBodyFrame* mFrame; + bool mUp; + int32_t mDelta; + }; + + void ComputeTotalRowCount(); + int32_t ToRowIndex(nscoord aPos) const; + void RemoveChildFrame(nsBoxLayoutState &aState, nsIFrame *aChild); + + nsTArray< RefPtr<nsPositionChangedEvent> > mPendingPositionChangeEvents; + nsCOMPtr<nsPIBoxObject> mBoxObject; + + // frame markers + nsWeakFrame mTopFrame; + nsIFrame* mBottomFrame; + nsIFrame* mLinkupFrame; + + nsListScrollSmoother* mScrollSmoother; + + int32_t mRowsToPrepend; + + // row height + int32_t mRowCount; + nscoord mRowHeight; + nscoord mAvailableHeight; + nscoord mStringWidth; + + // scrolling + int32_t mCurrentIndex; // Row-based + int32_t mOldIndex; + int32_t mYPosition; + int32_t mTimePerRow; + + // row height + bool mRowHeightWasSet; + // scrolling + bool mScrolling; + bool mAdjustScroll; + + bool mReflowCallbackPosted; +}; + +#endif // nsListBoxBodyFrame_h |