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