michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim: set ts=2 et sw=2 tw=80: */ michael@0: michael@0: /* This Source Code is subject to the terms of the Mozilla Public License michael@0: * version 2.0 (the "License"). You can obtain a copy of the License at michael@0: * http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* rendering object for CSS "display: flex" */ michael@0: michael@0: #ifndef nsFlexContainerFrame_h___ michael@0: #define nsFlexContainerFrame_h___ michael@0: michael@0: #include "nsContainerFrame.h" michael@0: michael@0: namespace mozilla { michael@0: template class LinkedList; michael@0: } michael@0: michael@0: nsIFrame* NS_NewFlexContainerFrame(nsIPresShell* aPresShell, michael@0: nsStyleContext* aContext); michael@0: michael@0: typedef nsContainerFrame nsFlexContainerFrameSuper; michael@0: michael@0: class nsFlexContainerFrame : public nsFlexContainerFrameSuper { michael@0: public: michael@0: NS_DECL_FRAMEARENA_HELPERS michael@0: NS_DECL_QUERYFRAME_TARGET(nsFlexContainerFrame) michael@0: NS_DECL_QUERYFRAME michael@0: michael@0: // Factory method: michael@0: friend nsIFrame* NS_NewFlexContainerFrame(nsIPresShell* aPresShell, michael@0: nsStyleContext* aContext); michael@0: michael@0: // Forward-decls of helper classes michael@0: class FlexItem; michael@0: class FlexLine; michael@0: class FlexboxAxisTracker; michael@0: class StrutInfo; michael@0: michael@0: // nsIFrame overrides michael@0: virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, michael@0: const nsRect& aDirtyRect, michael@0: const nsDisplayListSet& aLists) 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 nscoord michael@0: GetMinWidth(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE; michael@0: virtual nscoord michael@0: GetPrefWidth(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE; michael@0: michael@0: virtual nsIAtom* GetType() const MOZ_OVERRIDE; michael@0: #ifdef DEBUG_FRAME_DUMP michael@0: virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; michael@0: #endif michael@0: // Flexbox-specific public methods michael@0: bool IsHorizontal(); michael@0: michael@0: protected: michael@0: // Protected constructor & destructor michael@0: nsFlexContainerFrame(nsStyleContext* aContext) : michael@0: nsFlexContainerFrameSuper(aContext) michael@0: {} michael@0: virtual ~nsFlexContainerFrame(); michael@0: michael@0: /* michael@0: * This method does the bulk of the flex layout, implementing the algorithm michael@0: * described at: michael@0: * http://dev.w3.org/csswg/css-flexbox/#layout-algorithm michael@0: * (with a few initialization pieces happening in the caller, Reflow(). michael@0: * michael@0: * Since this is a helper for Reflow(), this takes all the same parameters michael@0: * as Reflow(), plus a few more parameters that Reflow() sets up for us. michael@0: * michael@0: * (The logic behind the division of work between Reflow and DoFlexLayout is michael@0: * as follows: DoFlexLayout() begins at the step that we have to jump back michael@0: * to, if we find any visibility:collapse children, and Reflow() does michael@0: * everything before that point.) michael@0: */ michael@0: nsresult DoFlexLayout(nsPresContext* aPresContext, michael@0: nsHTMLReflowMetrics& aDesiredSize, michael@0: const nsHTMLReflowState& aReflowState, michael@0: nsReflowStatus& aStatus, michael@0: nscoord aContentBoxMainSize, michael@0: nscoord aAvailableHeightForContent, michael@0: nsTArray& aStruts, michael@0: const FlexboxAxisTracker& aAxisTracker); michael@0: michael@0: /** michael@0: * Checks whether our child-frame list "mFrames" is sorted, using the given michael@0: * IsLessThanOrEqual function, and sorts it if it's not already sorted. michael@0: * michael@0: * XXXdholbert Once we support pagination, we need to make this function michael@0: * check our continuations as well (or wrap it in a function that does). michael@0: * michael@0: * @return true if we had to sort mFrames, false if it was already sorted. michael@0: */ michael@0: template michael@0: bool SortChildrenIfNeeded(); michael@0: michael@0: // Protected flex-container-specific methods / member-vars michael@0: #ifdef DEBUG michael@0: void SanityCheckAnonymousFlexItems() const; michael@0: #endif // DEBUG michael@0: michael@0: // Returns a new FlexItem for the given child frame, allocated on the heap. michael@0: // Caller is responsible for managing the FlexItem's lifetime. michael@0: FlexItem* GenerateFlexItemForChild(nsPresContext* aPresContext, michael@0: nsIFrame* aChildFrame, michael@0: const nsHTMLReflowState& aParentReflowState, michael@0: const FlexboxAxisTracker& aAxisTracker); michael@0: michael@0: // Returns nsresult because we might have to reflow aFlexItem.Frame() (to michael@0: // get its vertical intrinsic size in a vertical flexbox), and if that michael@0: // reflow fails (returns a failure nsresult), we want to bail out. michael@0: nsresult ResolveFlexItemMaxContentSizing(nsPresContext* aPresContext, michael@0: FlexItem& aFlexItem, michael@0: const nsHTMLReflowState& aParentReflowState, michael@0: const FlexboxAxisTracker& aAxisTracker); michael@0: michael@0: // Creates FlexItems for all of our child frames, arranged in a list of michael@0: // FlexLines. These are returned by reference in |aLines|. Our actual michael@0: // return value has to be |nsresult|, in case we have to reflow a child michael@0: // to establish its flex base size and that reflow fails. michael@0: nsresult GenerateFlexLines(nsPresContext* aPresContext, michael@0: const nsHTMLReflowState& aReflowState, michael@0: nscoord aContentBoxMainSize, michael@0: nscoord aAvailableHeightForContent, michael@0: const nsTArray& aStruts, michael@0: const FlexboxAxisTracker& aAxisTracker, michael@0: mozilla::LinkedList& aLines); michael@0: michael@0: nscoord GetMainSizeFromReflowState(const nsHTMLReflowState& aReflowState, michael@0: const FlexboxAxisTracker& aAxisTracker); michael@0: michael@0: nscoord ComputeCrossSize(const nsHTMLReflowState& aReflowState, michael@0: const FlexboxAxisTracker& aAxisTracker, michael@0: nscoord aSumLineCrossSizes, michael@0: nscoord aAvailableHeightForContent, michael@0: bool* aIsDefinite, michael@0: nsReflowStatus& aStatus); michael@0: michael@0: nsresult SizeItemInCrossAxis(nsPresContext* aPresContext, michael@0: const FlexboxAxisTracker& aAxisTracker, michael@0: nsHTMLReflowState& aChildReflowState, michael@0: FlexItem& aItem); michael@0: michael@0: bool mChildrenHaveBeenReordered; // Have we ever had to reorder our kids michael@0: // to satisfy their 'order' values? michael@0: }; michael@0: michael@0: #endif /* nsFlexContainerFrame_h___ */