1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef nsSprocketLayout_h___ 8 #define nsSprocketLayout_h___ 9 10 #include "mozilla/Attributes.h" 11 #include "nsBoxLayout.h" 12 #include "nsCOMPtr.h" 13 #include "nsIFrame.h" 14 15 class nsBoxSize { 16 public: 17 nsBoxSize(); 18 19 nscoord pref; 20 nscoord min; 21 nscoord max; 22 nscoord flex; 23 nscoord left; 24 nscoord right; 25 bool collapsed; 26 bool bogus; 27 28 nsBoxSize* next; 29 30 void* operator new(size_t sz, nsBoxLayoutState& aState) noexcept(true); 31 void operator delete(void* aPtr, size_t sz); 32 }; 33 34 class nsComputedBoxSize { 35 public: 36 nsComputedBoxSize(); 37 38 nscoord size; 39 bool valid; 40 bool resized; 41 nsComputedBoxSize* next; 42 43 void* operator new(size_t sz, nsBoxLayoutState& aState) noexcept(true); 44 void operator delete(void* aPtr, size_t sz); 45 }; 46 47 #define GET_WIDTH(size, isHorizontal) (isHorizontal ? size.width : size.height) 48 #define GET_HEIGHT(size, isHorizontal) (isHorizontal ? size.height : size.width) 49 #define GET_X(size, isHorizontal) (isHorizontal ? size.x : size.y) 50 #define GET_Y(size, isHorizontal) (isHorizontal ? size.y : size.x) 51 #define GET_COORD(aX, aY, isHorizontal) (isHorizontal ? aX : aY) 52 53 #define SET_WIDTH(size, coord, isHorizontal) \ 54 if (isHorizontal) { \ 55 (size).width = (coord); \ 56 } else { \ 57 (size).height = (coord); \ 58 } 59 #define SET_HEIGHT(size, coord, isHorizontal) \ 60 if (isHorizontal) { \ 61 (size).height = (coord); \ 62 } else { \ 63 (size).width = (coord); \ 64 } 65 #define SET_X(size, coord, isHorizontal) \ 66 if (isHorizontal) { \ 67 (size).x = (coord); \ 68 } else { \ 69 (size).y = (coord); \ 70 } 71 #define SET_Y(size, coord, isHorizontal) \ 72 if (isHorizontal) { \ 73 (size).y = (coord); \ 74 } else { \ 75 (size).x = (coord); \ 76 } 77 78 #define SET_COORD(aX, aY, coord, isHorizontal) \ 79 if (isHorizontal) { \ 80 aX = (coord); \ 81 } else { \ 82 aY = (coord); \ 83 } 84 85 nsresult NS_NewSprocketLayout(nsCOMPtr<nsBoxLayout>& aNewLayout); 86 87 class nsSprocketLayout : public nsBoxLayout { 88 public: 89 friend nsresult NS_NewSprocketLayout(nsCOMPtr<nsBoxLayout>& aNewLayout); 90 static void Shutdown(); 91 92 NS_IMETHOD XULLayout(nsIFrame* aBox, nsBoxLayoutState& aState) override; 93 94 virtual nsSize GetXULPrefSize(nsIFrame* aBox, 95 nsBoxLayoutState& aBoxLayoutState) override; 96 virtual nsSize GetXULMinSize(nsIFrame* aBox, 97 nsBoxLayoutState& aBoxLayoutState) override; 98 virtual nsSize GetXULMaxSize(nsIFrame* aBox, 99 nsBoxLayoutState& aBoxLayoutState) override; 100 virtual nscoord GetAscent(nsIFrame* aBox, 101 nsBoxLayoutState& aBoxLayoutState) override; 102 103 nsSprocketLayout(); 104 105 static bool IsXULHorizontal(nsIFrame* aBox); 106 107 static void SetLargestSize(nsSize& aSize1, const nsSize& aSize2, 108 bool aIsHorizontal); 109 static void SetSmallestSize(nsSize& aSize1, const nsSize& aSize2, 110 bool aIsHorizontal); 111 112 static void AddLargestSize(nsSize& aSize, const nsSize& aSizeToAdd, 113 bool aIsHorizontal); 114 static void AddSmallestSize(nsSize& aSize, const nsSize& aSizeToAdd, 115 bool aIsHorizontal); 116 static void AddCoord(nscoord& aCoord, nscoord aCoordToAdd); 117 118 protected: 119 void ComputeChildsNextPosition(nsIFrame* aBox, const nscoord& aCurX, 120 const nscoord& aCurY, nscoord& aNextX, 121 nscoord& aNextY, const nsRect& aChildSize); 122 123 void ChildResized(nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aChild, 124 nsBoxSize* aChildBoxSize, 125 nsComputedBoxSize* aChildComputedBoxSize, 126 nsBoxSize* aBoxSizes, nsComputedBoxSize* aComputedBoxSizes, 127 const nsRect& aChildLayoutRect, nsRect& aChildActualRect, 128 nsRect& aContainingRect, int32_t aFlexes, bool& aFinished); 129 130 void AlignChildren(nsIFrame* aBox, nsBoxLayoutState& aState); 131 132 virtual void ComputeChildSizes(nsIFrame* aBox, nsBoxLayoutState& aState, 133 nscoord& aGivenSize, nsBoxSize* aBoxSizes, 134 nsComputedBoxSize*& aComputedBoxSizes); 135 136 virtual void PopulateBoxSizes(nsIFrame* aBox, 137 nsBoxLayoutState& aBoxLayoutState, 138 nsBoxSize*& aBoxSizes, nscoord& aMinSize, 139 nscoord& aMaxSize, int32_t& aFlexes); 140 141 virtual void InvalidateComputedSizes(nsComputedBoxSize* aComputedBoxSizes); 142 143 virtual bool GetDefaultFlex(int32_t& aFlex); 144 145 virtual void GetFrameState(nsIFrame* aBox, nsFrameState& aState); 146 147 private: 148 // because the sprocket layout manager has no instance variables. We 149 // can make a static one and reuse it everywhere. 150 static nsBoxLayout* gInstance; 151 }; 152 153 #endif 154