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