• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef UI_VIEWS_LAYOUT_BOX_LAYOUT_H_
6 #define UI_VIEWS_LAYOUT_BOX_LAYOUT_H_
7 
8 #include <map>
9 
10 #include "base/basictypes.h"
11 #include "base/compiler_specific.h"
12 #include "ui/gfx/insets.h"
13 #include "ui/views/layout/layout_manager.h"
14 
15 namespace gfx {
16 class Rect;
17 class Size;
18 }
19 
20 namespace views {
21 
22 class View;
23 
24 // A Layout manager that arranges child views vertically or horizontally in a
25 // side-by-side fashion with spacing around and between the child views. The
26 // child views are always sized according to their preferred size. If the
27 // host's bounds provide insufficient space, child views will be clamped.
28 // Excess space will not be distributed.
29 class VIEWS_EXPORT BoxLayout : public LayoutManager {
30  public:
31   enum Orientation {
32     kHorizontal,
33     kVertical,
34   };
35 
36   // This specifies where along the main axis the children should be laid out.
37   // e.g. a horizontal layout of MAIN_AXIS_ALIGNMENT_END will result in the
38   // child views being right-aligned.
39   enum MainAxisAlignment {
40     MAIN_AXIS_ALIGNMENT_START,
41     MAIN_AXIS_ALIGNMENT_CENTER,
42     MAIN_AXIS_ALIGNMENT_END,
43     // TODO(calamity): Add MAIN_AXIS_ALIGNMENT_JUSTIFY which spreads blank space
44     // in-between the child views.
45   };
46 
47   // This specifies where along the cross axis the children should be laid out.
48   // e.g. a horizontal layout of CROSS_AXIS_ALIGNMENT_END will result in the
49   // child views being bottom-aligned.
50   enum CrossAxisAlignment {
51     // This causes the child view to stretch to fit the host in the cross axis.
52     CROSS_AXIS_ALIGNMENT_STRETCH,
53     CROSS_AXIS_ALIGNMENT_START,
54     CROSS_AXIS_ALIGNMENT_CENTER,
55     CROSS_AXIS_ALIGNMENT_END,
56   };
57 
58   // Use |inside_border_horizontal_spacing| and
59   // |inside_border_vertical_spacing| to add additional space between the child
60   // view area and the host view border. |between_child_spacing| controls the
61   // space in between child views.
62   BoxLayout(Orientation orientation,
63             int inside_border_horizontal_spacing,
64             int inside_border_vertical_spacing,
65             int between_child_spacing);
66   virtual ~BoxLayout();
67 
set_main_axis_alignment(MainAxisAlignment main_axis_alignment)68   void set_main_axis_alignment(MainAxisAlignment main_axis_alignment) {
69     main_axis_alignment_ = main_axis_alignment;
70   }
71 
set_cross_axis_alignment(CrossAxisAlignment cross_axis_alignment)72   void set_cross_axis_alignment(CrossAxisAlignment cross_axis_alignment) {
73     cross_axis_alignment_ = cross_axis_alignment;
74   }
75 
set_inside_border_insets(const gfx::Insets & insets)76   void set_inside_border_insets(const gfx::Insets& insets) {
77     inside_border_insets_ = insets;
78   }
79 
set_minimum_cross_axis_size(int size)80   void set_minimum_cross_axis_size(int size) {
81     minimum_cross_axis_size_ = size;
82   }
83 
84   // Sets the flex weight for the given |view|. Using the preferred size as
85   // the basis, free space along the main axis is distributed to views in the
86   // ratio of their flex weights. Similarly, if the views will overflow the
87   // parent, space is subtracted in these ratios.
88   //
89   // A flex of 0 means this view is not resized. Flex values must not be
90   // negative.
91   void SetFlexForView(const View* view, int flex);
92 
93   // Clears the flex for the given |view|, causing it to use the default
94   // flex.
95   void ClearFlexForView(const View* view);
96 
97   // Sets the flex for views to use when none is specified.
98   void SetDefaultFlex(int default_flex);
99 
100   // Overridden from views::LayoutManager:
101   virtual void Installed(View* host) OVERRIDE;
102   virtual void Uninstalled(View* host) OVERRIDE;
103   virtual void ViewRemoved(View* host, View* view) OVERRIDE;
104   virtual void Layout(View* host) OVERRIDE;
105   virtual gfx::Size GetPreferredSize(const View* host) const OVERRIDE;
106   virtual int GetPreferredHeightForWidth(const View* host,
107                                          int width) const OVERRIDE;
108 
109  private:
110   // Returns the flex for the specified |view|.
111   int GetFlexForView(const View* view) const;
112 
113   // Returns the size and position along the main axis of |rect|.
114   int MainAxisSize(const gfx::Rect& rect) const;
115   int MainAxisPosition(const gfx::Rect& rect) const;
116 
117   // Sets the size and position along the main axis of |rect|.
118   void SetMainAxisSize(int size, gfx::Rect* rect) const;
119   void SetMainAxisPosition(int position, gfx::Rect* rect) const;
120 
121   // Returns the size and position along the cross axis of |rect|.
122   int CrossAxisSize(const gfx::Rect& rect) const;
123   int CrossAxisPosition(const gfx::Rect& rect) const;
124 
125   // Sets the size and position along the cross axis of |rect|.
126   void SetCrossAxisSize(int size, gfx::Rect* rect) const;
127   void SetCrossAxisPosition(int size, gfx::Rect* rect) const;
128 
129   // Returns the main axis size for the given view. |child_area_width| is needed
130   // to calculate the height of the view when the orientation is vertical.
131   int MainAxisSizeForView(const View* view, int child_area_width) const;
132 
133   // Returns the cross axis size for the given view.
134   int CrossAxisSizeForView(const View* view) const;
135 
136   // The preferred size for the dialog given the width of the child area.
137   gfx::Size GetPreferredSizeForChildWidth(const View* host,
138                                           int child_area_width) const;
139 
140   // The amount of space the layout requires in addition to any space for the
141   // child views.
142   gfx::Size NonChildSize(const View* host) const;
143 
144   const Orientation orientation_;
145 
146   // Spacing between child views and host view border.
147   gfx::Insets inside_border_insets_;
148 
149   // Spacing to put in between child views.
150   const int between_child_spacing_;
151 
152   // The alignment of children in the main axis. This is
153   // MAIN_AXIS_ALIGNMENT_START by default.
154   MainAxisAlignment main_axis_alignment_;
155 
156   // The alignment of children in the cross axis. This is
157   // CROSS_AXIS_ALIGNMENT_STRETCH by default.
158   CrossAxisAlignment cross_axis_alignment_;
159 
160   // A map of views to their flex weights.
161   std::map<const View*, int> flex_map_;
162 
163   // The flex weight for views if none is set. Defaults to 0.
164   int default_flex_;
165 
166   // The minimum cross axis size for the layout.
167   int minimum_cross_axis_size_;
168 
169   // The view that this BoxLayout is managing the layout for.
170   views::View* host_;
171 
172   DISALLOW_IMPLICIT_CONSTRUCTORS(BoxLayout);
173 };
174 
175 } // namespace views
176 
177 #endif  // UI_VIEWS_LAYOUT_BOX_LAYOUT_H_
178