michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /** michael@0: michael@0: Eric D Vaughan michael@0: nsBoxFrame is a frame that can lay its children out either vertically or horizontally. michael@0: It lays them out according to a min max or preferred size. michael@0: michael@0: **/ michael@0: michael@0: #ifndef nsBoxFrame_h___ michael@0: #define nsBoxFrame_h___ michael@0: michael@0: #include "mozilla/Attributes.h" michael@0: #include "nsCOMPtr.h" michael@0: #include "nsContainerFrame.h" michael@0: #include "nsBoxLayout.h" michael@0: michael@0: class nsBoxLayoutState; michael@0: michael@0: nsIFrame* NS_NewBoxFrame(nsIPresShell* aPresShell, michael@0: nsStyleContext* aContext, michael@0: bool aIsRoot, michael@0: nsBoxLayout* aLayoutManager); michael@0: nsIFrame* NS_NewBoxFrame(nsIPresShell* aPresShell, michael@0: nsStyleContext* aContext); michael@0: michael@0: class nsBoxFrame : public nsContainerFrame michael@0: { michael@0: public: michael@0: NS_DECL_FRAMEARENA_HELPERS michael@0: #ifdef DEBUG michael@0: NS_DECL_QUERYFRAME_TARGET(nsBoxFrame) michael@0: NS_DECL_QUERYFRAME michael@0: #endif michael@0: michael@0: friend nsIFrame* NS_NewBoxFrame(nsIPresShell* aPresShell, michael@0: nsStyleContext* aContext, michael@0: bool aIsRoot, michael@0: nsBoxLayout* aLayoutManager); michael@0: friend nsIFrame* NS_NewBoxFrame(nsIPresShell* aPresShell, michael@0: nsStyleContext* aContext); michael@0: michael@0: // gets the rect inside our border and debug border. If you wish to paint inside a box michael@0: // call this method to get the rect so you don't draw on the debug border or outer border. michael@0: michael@0: virtual void SetLayoutManager(nsBoxLayout* aLayout) MOZ_OVERRIDE { mLayoutManager = aLayout; } michael@0: virtual nsBoxLayout* GetLayoutManager() MOZ_OVERRIDE { return mLayoutManager; } michael@0: michael@0: virtual nsresult RelayoutChildAtOrdinal(nsBoxLayoutState& aState, nsIFrame* aChild) MOZ_OVERRIDE; michael@0: michael@0: virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; michael@0: virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; michael@0: virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; michael@0: virtual nscoord GetFlex(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; michael@0: virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; michael@0: #ifdef DEBUG_LAYOUT michael@0: virtual nsresult SetDebug(nsBoxLayoutState& aBoxLayoutState, bool aDebug) MOZ_OVERRIDE; michael@0: virtual nsresult GetDebug(bool& aDebug) MOZ_OVERRIDE; michael@0: #endif michael@0: virtual Valignment GetVAlign() const MOZ_OVERRIDE { return mValign; } michael@0: virtual Halignment GetHAlign() const MOZ_OVERRIDE { return mHalign; } michael@0: NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; michael@0: michael@0: virtual bool ComputesOwnOverflowArea() MOZ_OVERRIDE { return false; } michael@0: michael@0: // ----- child and sibling operations --- michael@0: michael@0: // ----- public methods ------- michael@0: michael@0: virtual void Init(nsIContent* aContent, michael@0: nsIFrame* aParent, michael@0: nsIFrame* asPrevInFlow) MOZ_OVERRIDE; michael@0: michael@0: michael@0: virtual nsresult AttributeChanged(int32_t aNameSpaceID, michael@0: nsIAtom* aAttribute, michael@0: int32_t aModType) MOZ_OVERRIDE; michael@0: michael@0: virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE; michael@0: virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; michael@0: virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; michael@0: michael@0: virtual nsresult Reflow(nsPresContext* aPresContext, michael@0: nsHTMLReflowMetrics& aDesiredSize, michael@0: const nsHTMLReflowState& aReflowState, michael@0: nsReflowStatus& aStatus) MOZ_OVERRIDE; michael@0: michael@0: virtual nsresult AppendFrames(ChildListID aListID, michael@0: nsFrameList& aFrameList) MOZ_OVERRIDE; michael@0: michael@0: virtual nsresult InsertFrames(ChildListID aListID, michael@0: nsIFrame* aPrevFrame, michael@0: nsFrameList& aFrameList) MOZ_OVERRIDE; michael@0: michael@0: virtual nsresult RemoveFrame(ChildListID aListID, michael@0: nsIFrame* aOldFrame) MOZ_OVERRIDE; michael@0: michael@0: virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE; michael@0: michael@0: virtual nsresult SetInitialChildList(ChildListID aListID, michael@0: nsFrameList& aChildList) MOZ_OVERRIDE; michael@0: michael@0: virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE; michael@0: michael@0: virtual nsIAtom* GetType() const MOZ_OVERRIDE; michael@0: michael@0: virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE michael@0: { michael@0: // record that children that are ignorable whitespace should be excluded michael@0: // (When content was loaded via the XUL content sink, it's already michael@0: // been excluded, but we need this for when the XUL namespace is used michael@0: // in other MIME types or when the XUL CSS display types are used with michael@0: // non-XUL elements.) michael@0: michael@0: // This is bogus, but it's what we've always done. michael@0: // (Given that we're replaced, we need to say we're a replaced element michael@0: // that contains a block so nsHTMLReflowState doesn't tell us to be michael@0: // NS_INTRINSICSIZE wide.) michael@0: return nsContainerFrame::IsFrameOfType(aFlags & michael@0: ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock | eXULBox | michael@0: nsIFrame::eExcludesIgnorableWhitespace)); michael@0: } michael@0: michael@0: #ifdef DEBUG_FRAME_DUMP michael@0: virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; michael@0: #endif michael@0: michael@0: virtual nsresult DidReflow(nsPresContext* aPresContext, michael@0: const nsHTMLReflowState* aReflowState, michael@0: nsDidReflowStatus aStatus) MOZ_OVERRIDE; michael@0: michael@0: virtual bool HonorPrintBackgroundSettings() MOZ_OVERRIDE; michael@0: michael@0: virtual ~nsBoxFrame(); michael@0: michael@0: nsBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, bool aIsRoot = false, nsBoxLayout* aLayoutManager = nullptr); michael@0: michael@0: // virtual so nsStackFrame, nsButtonBoxFrame, nsSliderFrame and nsMenuFrame michael@0: // can override it michael@0: virtual void BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, michael@0: const nsRect& aDirtyRect, michael@0: const nsDisplayListSet& aLists); michael@0: michael@0: virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, michael@0: const nsRect& aDirtyRect, michael@0: const nsDisplayListSet& aLists) MOZ_OVERRIDE; michael@0: michael@0: #ifdef DEBUG_LAYOUT michael@0: virtual void SetDebugOnChildList(nsBoxLayoutState& aState, nsIFrame* aChild, bool aDebug); michael@0: nsresult DisplayDebugInfoFor(nsIFrame* aBox, michael@0: nsPoint& aPoint); michael@0: #endif michael@0: michael@0: static nsresult LayoutChildAt(nsBoxLayoutState& aState, nsIFrame* aBox, const nsRect& aRect); michael@0: michael@0: /** michael@0: * Utility method to redirect events on descendants to this frame. michael@0: * Supports 'allowevents' attribute on descendant elements to allow those michael@0: * elements and their descendants to receive events. michael@0: */ michael@0: void WrapListsInRedirector(nsDisplayListBuilder* aBuilder, michael@0: const nsDisplayListSet& aIn, michael@0: const nsDisplayListSet& aOut); michael@0: michael@0: /** michael@0: * This defaults to true, but some box frames (nsListBoxBodyFrame for michael@0: * example) don't support ordinals in their children. michael@0: */ michael@0: virtual bool SupportsOrdinalsInChildren(); michael@0: michael@0: protected: michael@0: #ifdef DEBUG_LAYOUT michael@0: virtual void GetBoxName(nsAutoString& aName) MOZ_OVERRIDE; michael@0: void PaintXULDebugBackground(nsRenderingContext& aRenderingContext, michael@0: nsPoint aPt); michael@0: void PaintXULDebugOverlay(nsRenderingContext& aRenderingContext, michael@0: nsPoint aPt); michael@0: #endif michael@0: michael@0: virtual bool GetInitialEqualSize(bool& aEqualSize); michael@0: virtual void GetInitialOrientation(bool& aIsHorizontal); michael@0: virtual void GetInitialDirection(bool& aIsNormal); michael@0: virtual bool GetInitialHAlignment(Halignment& aHalign); michael@0: virtual bool GetInitialVAlignment(Valignment& aValign); michael@0: virtual bool GetInitialAutoStretch(bool& aStretch); michael@0: michael@0: virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; michael@0: michael@0: nsSize mPrefSize; michael@0: nsSize mMinSize; michael@0: nsSize mMaxSize; michael@0: nscoord mFlex; michael@0: nscoord mAscent; michael@0: michael@0: nsCOMPtr mLayoutManager; michael@0: michael@0: // Get the point associated with this event. Returns true if a single valid michael@0: // point was found. Otherwise false. michael@0: bool GetEventPoint(mozilla::WidgetGUIEvent* aEvent, nsPoint& aPoint); michael@0: // Gets the event coordinates relative to the widget offset associated with michael@0: // this frame. Return true if a single valid point was found. michael@0: bool GetEventPoint(mozilla::WidgetGUIEvent* aEvent, nsIntPoint& aPoint); michael@0: michael@0: protected: michael@0: void RegUnregAccessKey(bool aDoReg); michael@0: michael@0: NS_HIDDEN_(void) CheckBoxOrder(); michael@0: michael@0: private: michael@0: michael@0: #ifdef DEBUG_LAYOUT michael@0: nsresult SetDebug(nsPresContext* aPresContext, bool aDebug); michael@0: bool GetInitialDebug(bool& aDebug); michael@0: void GetDebugPref(nsPresContext* aPresContext); michael@0: michael@0: void GetDebugBorder(nsMargin& aInset); michael@0: void GetDebugPadding(nsMargin& aInset); michael@0: void GetDebugMargin(nsMargin& aInset); michael@0: michael@0: nsresult GetFrameSizeWithMargin(nsIFrame* aBox, nsSize& aSize); michael@0: michael@0: void PixelMarginToTwips(nsPresContext* aPresContext, nsMargin& aMarginPixels); michael@0: michael@0: void GetValue(nsPresContext* aPresContext, const nsSize& a, const nsSize& b, char* value); michael@0: void GetValue(nsPresContext* aPresContext, int32_t a, int32_t b, char* value); michael@0: void DrawSpacer(nsPresContext* aPresContext, nsRenderingContext& aRenderingContext, bool aHorizontal, int32_t flex, nscoord x, nscoord y, nscoord size, nscoord spacerSize); michael@0: void DrawLine(nsRenderingContext& aRenderingContext, bool aHorizontal, nscoord x1, nscoord y1, nscoord x2, nscoord y2); michael@0: void FillRect(nsRenderingContext& aRenderingContext, bool aHorizontal, nscoord x, nscoord y, nscoord width, nscoord height); michael@0: #endif michael@0: virtual void UpdateMouseThrough(); michael@0: michael@0: void CacheAttributes(); michael@0: michael@0: // instance variables. michael@0: Halignment mHalign; michael@0: Valignment mValign; michael@0: michael@0: #ifdef DEBUG_LAYOUT michael@0: static bool gDebug; michael@0: static nsIFrame* mDebugChild; michael@0: #endif michael@0: michael@0: }; // class nsBoxFrame michael@0: michael@0: #endif michael@0: