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 /** 8 9 Eric D Vaughan 10 nsBoxFrame is a frame that can lay its children out either vertically or 11 horizontally. It lays them out according to a min max or preferred size. 12 13 **/ 14 15 #ifndef nsBoxFrame_h___ 16 #define nsBoxFrame_h___ 17 18 #include "mozilla/Attributes.h" 19 #include "nsCOMPtr.h" 20 #include "nsContainerFrame.h" 21 #include "nsBoxLayout.h" 22 23 class nsBoxLayoutState; 24 25 namespace mozilla { 26 namespace gfx { 27 class DrawTarget; 28 } // namespace gfx 29 } // namespace mozilla 30 31 nsIFrame* NS_NewBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, 32 bool aIsRoot, nsBoxLayout* aLayoutManager); 33 nsIFrame* NS_NewBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); 34 35 class nsBoxFrame : public nsContainerFrame { 36 protected: 37 typedef mozilla::gfx::DrawTarget DrawTarget; 38 39 public: 40 NS_DECL_FRAMEARENA_HELPERS(nsBoxFrame) 41 #ifdef DEBUG 42 NS_DECL_QUERYFRAME 43 #endif 44 45 friend nsIFrame* NS_NewBoxFrame(nsIPresShell* aPresShell, 46 nsStyleContext* aContext, bool aIsRoot, 47 nsBoxLayout* aLayoutManager); 48 friend nsIFrame* NS_NewBoxFrame(nsIPresShell* aPresShell, 49 nsStyleContext* aContext); 50 51 // gets the rect inside our border and debug border. If you wish to paint 52 // inside a box call this method to get the rect so you don't draw on the 53 // debug border or outer border. 54 SetXULLayoutManager(nsBoxLayout * aLayout)55 virtual void SetXULLayoutManager(nsBoxLayout* aLayout) override { 56 mLayoutManager = aLayout; 57 } GetXULLayoutManager()58 virtual nsBoxLayout* GetXULLayoutManager() override { return mLayoutManager; } 59 60 virtual nsresult XULRelayoutChildAtOrdinal(nsIFrame* aChild) override; 61 62 virtual nsSize GetXULPrefSize(nsBoxLayoutState& aBoxLayoutState) override; 63 virtual nsSize GetXULMinSize(nsBoxLayoutState& aBoxLayoutState) override; 64 virtual nsSize GetXULMaxSize(nsBoxLayoutState& aBoxLayoutState) override; 65 virtual nscoord GetXULFlex() override; 66 virtual nscoord GetXULBoxAscent(nsBoxLayoutState& aBoxLayoutState) override; 67 #ifdef DEBUG_LAYOUT 68 virtual nsresult SetXULDebug(nsBoxLayoutState& aBoxLayoutState, 69 bool aDebug) override; 70 virtual nsresult GetXULDebug(bool& aDebug) override; 71 #endif GetXULVAlign()72 virtual Valignment GetXULVAlign() const override { return mValign; } GetXULHAlign()73 virtual Halignment GetXULHAlign() const override { return mHalign; } 74 NS_IMETHOD DoXULLayout(nsBoxLayoutState& aBoxLayoutState) override; 75 ComputesOwnOverflowArea()76 virtual bool ComputesOwnOverflowArea() override { return false; } 77 78 // ----- child and sibling operations --- 79 80 // ----- public methods ------- 81 82 virtual void Init(nsIContent* aContent, nsContainerFrame* aParent, 83 nsIFrame* aPrevInFlow) override; 84 85 virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute, 86 int32_t aModType) override; 87 88 virtual void MarkIntrinsicISizesDirty() override; 89 virtual nscoord GetMinISize(gfxContext* aRenderingContext) override; 90 virtual nscoord GetPrefISize(gfxContext* aRenderingContext) override; 91 92 virtual void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, 93 const ReflowInput& aReflowInput, 94 nsReflowStatus& aStatus) override; 95 96 virtual void SetInitialChildList(ChildListID aListID, 97 nsFrameList& aChildList) override; 98 virtual void AppendFrames(ChildListID aListID, 99 nsFrameList& aFrameList) override; 100 virtual void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, 101 nsFrameList& aFrameList) override; 102 virtual void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) override; 103 104 virtual nsContainerFrame* GetContentInsertionFrame() override; 105 106 virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) override; 107 IsFrameOfType(uint32_t aFlags)108 virtual bool IsFrameOfType(uint32_t aFlags) const override { 109 // record that children that are ignorable whitespace should be excluded 110 // (When content was loaded via the XUL content sink, it's already 111 // been excluded, but we need this for when the XUL namespace is used 112 // in other MIME types or when the XUL CSS display types are used with 113 // non-XUL elements.) 114 115 // This is bogus, but it's what we've always done. 116 // (Given that we're replaced, we need to say we're a replaced element 117 // that contains a block so ReflowInput doesn't tell us to be 118 // NS_INTRINSICSIZE wide.) 119 return nsContainerFrame::IsFrameOfType( 120 aFlags & ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock | 121 eXULBox | nsIFrame::eExcludesIgnorableWhitespace)); 122 } 123 124 #ifdef DEBUG_FRAME_DUMP 125 virtual nsresult GetFrameName(nsAString& aResult) const override; 126 #endif 127 128 virtual void DidReflow(nsPresContext* aPresContext, 129 const ReflowInput* aReflowInput) override; 130 131 virtual bool HonorPrintBackgroundSettings() override; 132 133 // virtual so nsStackFrame, nsButtonBoxFrame, nsSliderFrame and nsMenuFrame 134 // can override it 135 virtual void BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, 136 const nsDisplayListSet& aLists); 137 138 virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, 139 const nsDisplayListSet& aLists) override; 140 141 #ifdef DEBUG_LAYOUT 142 virtual void SetDebugOnChildList(nsBoxLayoutState& aState, nsIFrame* aChild, 143 bool aDebug); 144 nsresult DisplayDebugInfoFor(nsIFrame* aBox, nsPoint& aPoint); 145 #endif 146 147 static nsresult LayoutChildAt(nsBoxLayoutState& aState, nsIFrame* aBox, 148 const nsRect& aRect); 149 150 /** 151 * Utility method to redirect events on descendants to this frame. 152 * Supports 'allowevents' attribute on descendant elements to allow those 153 * elements and their descendants to receive events. 154 */ 155 void WrapListsInRedirector(nsDisplayListBuilder* aBuilder, 156 const nsDisplayListSet& aIn, 157 const nsDisplayListSet& aOut); 158 159 /** 160 * This defaults to true, but some box frames (nsListBoxBodyFrame for 161 * example) don't support ordinals in their children. 162 */ 163 virtual bool SupportsOrdinalsInChildren(); 164 165 /** 166 * Return our wrapper block, if any. 167 */ 168 void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override; 169 170 private: nsBoxFrame(nsStyleContext * aContext)171 explicit nsBoxFrame(nsStyleContext* aContext) 172 : nsBoxFrame(aContext, kClassID, false, nullptr) {} 173 174 protected: 175 nsBoxFrame(nsStyleContext* aContext, ClassID aID, bool aIsRoot = false, 176 nsBoxLayout* aLayoutManager = nullptr); 177 virtual ~nsBoxFrame(); 178 179 #ifdef DEBUG_LAYOUT 180 virtual void GetBoxName(nsAutoString& aName) override; 181 void PaintXULDebugBackground(gfxContext& aRenderingContext, nsPoint aPt); 182 void PaintXULDebugOverlay(DrawTarget& aRenderingContext, nsPoint aPt); 183 #endif 184 185 virtual bool GetInitialEqualSize(bool& aEqualSize); 186 virtual void GetInitialOrientation(bool& aIsHorizontal); 187 virtual void GetInitialDirection(bool& aIsNormal); 188 virtual bool GetInitialHAlignment(Halignment& aHalign); 189 virtual bool GetInitialVAlignment(Valignment& aValign); 190 virtual bool GetInitialAutoStretch(bool& aStretch); 191 192 virtual void DestroyFrom(nsIFrame* aDestructRoot, 193 PostDestroyData& aPostDestroyData) override; 194 195 nsSize mPrefSize; 196 nsSize mMinSize; 197 nsSize mMaxSize; 198 nscoord mFlex; 199 nscoord mAscent; 200 201 nsCOMPtr<nsBoxLayout> mLayoutManager; 202 203 // Get the point associated with this event. Returns true if a single valid 204 // point was found. Otherwise false. 205 bool GetEventPoint(mozilla::WidgetGUIEvent* aEvent, nsPoint& aPoint); 206 // Gets the event coordinates relative to the widget offset associated with 207 // this frame. Return true if a single valid point was found. 208 bool GetEventPoint(mozilla::WidgetGUIEvent* aEvent, 209 mozilla::LayoutDeviceIntPoint& aPoint); 210 211 protected: 212 void RegUnregAccessKey(bool aDoReg); 213 214 void CheckBoxOrder(); 215 216 private: 217 #ifdef DEBUG_LAYOUT 218 nsresult SetXULDebug(nsPresContext* aPresContext, bool aDebug); 219 bool GetInitialDebug(bool& aDebug); 220 void GetDebugPref(); 221 222 void GetDebugBorder(nsMargin& aInset); 223 void GetDebugPadding(nsMargin& aInset); 224 void GetDebugMargin(nsMargin& aInset); 225 226 nsresult GetFrameSizeWithMargin(nsIFrame* aBox, nsSize& aSize); 227 228 void PixelMarginToTwips(nsMargin& aMarginPixels); 229 230 void GetValue(nsPresContext* aPresContext, const nsSize& a, const nsSize& b, 231 char* value); 232 void GetValue(nsPresContext* aPresContext, int32_t a, int32_t b, char* value); 233 void DrawSpacer(nsPresContext* aPresContext, DrawTarget& aDrawTarget, 234 bool aHorizontal, int32_t flex, nscoord x, nscoord y, 235 nscoord size, nscoord spacerSize); 236 void DrawLine(DrawTarget& aDrawTarget, bool aHorizontal, nscoord x1, 237 nscoord y1, nscoord x2, nscoord y2); 238 void FillRect(DrawTarget& aDrawTarget, bool aHorizontal, nscoord x, nscoord y, 239 nscoord width, nscoord height); 240 #endif 241 virtual void UpdateMouseThrough(); 242 243 void CacheAttributes(); 244 245 // instance variables. 246 Halignment mHalign; 247 Valignment mValign; 248 249 #ifdef DEBUG_LAYOUT 250 static bool gDebug; 251 static nsIFrame* mDebugChild; 252 #endif 253 254 }; // class nsBoxFrame 255 256 #endif 257