blob: a1574ced7ce46bc5b4d04d9b733179b24f88066d [file] [log] [blame]
[email protected]403e4632010-01-29 22:34:121// Copyright (c) 2010 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]2362e4f2009-05-08 00:34:055#ifndef VIEWS_GRID_LAYOUT_H_
6#define VIEWS_GRID_LAYOUT_H_
[email protected]32b76ef2010-07-26 23:08:247#pragma once
initial.commit09911bf2008-07-26 23:55:298
9#include <string>
10#include <vector>
11
[email protected]2362e4f2009-05-08 00:34:0512#include "views/layout_manager.h"
13#include "views/view.h"
initial.commit09911bf2008-07-26 23:55:2914
[email protected]3a483452009-12-23 08:56:2015namespace gfx {
16class Insets;
17}
18
initial.commit09911bf2008-07-26 23:55:2919// GridLayout is a LayoutManager that positions child Views in a grid. You
20// define the structure of the Grid first, then add the Views.
21// The following creates a trivial grid with two columns separated by
22// a column with padding:
23// ColumnSet* columns = layout->AddColumnSet(0); // Give this column an
24// // identifier of 0.
25// columns->AddColumn(FILL, // Views are horizontally resized to fill column.
26// FILL, // Views starting in this column are vertically
27// // resized.
28// 1, // This column has a resize weight of 1.
29// USE_PREF, // Use the preferred size of the view.
30// 0, // Ignored for USE_PREF.
31// 0); // A minimum width of 0.
32// columns->AddPaddingColumn(0, // The padding column is not resizable.
33// 10); // And has a width of 10 pixels.
34// columns->AddColumn(FILL, FILL, 0, USE_PREF, 0, 0);
35// Now add the views:
36// // First start a row.
37// layout->StartRow(0, // This row isn't vertically resizable.
38// 0); // The column set to use for this row.
39// layout->AddView(v1);
40// Notice you need not skip over padding columns, that's done for you.
41// layout->AddView(v2);
42//
43// When adding a Column you give it the default alignment for all views
44// originating in that column. You can override this for specific views
45// when adding them. For example, the following forces a View to have
46// a horizontal and vertical alignment of leading regardless of that defined
47// for the column:
48// layout->AddView(v1, 1, 1, LEADING, LEADING);
49//
50// If the View using GridLayout is given a size bigger than the preferred,
51// columns and rows with a resize percent > 0 are resized. Each column/row
52// is given resize_percent / total_resize_percent * extra_pixels extra
53// pixels. Only Views with an Alignment of FILL are given extra space, others
54// are aligned in the provided space.
55//
56// GridLayout allows you to define multiple column sets. When you start a
57// new row you specify the id of the column set the row is to use.
58//
59// GridLayout allows you to force columns to have the same width. This is
60// done using the LinkColumnSizes method.
61//
62// AddView takes care of adding the View to the View the GridLayout was
63// created with.
[email protected]c2dacc92008-10-16 23:51:3864namespace views {
initial.commit09911bf2008-07-26 23:55:2965
66class Column;
67class ColumnSet;
68class Row;
69class View;
70
71struct ViewState;
72
73class GridLayout : public LayoutManager {
74 public:
75 // An enumeration of the possible alignments supported by GridLayout.
76 enum Alignment {
77 // Leading equates to left along the horizontal axis, and top along the
78 // vertical axis.
79 LEADING,
80
81 // Centers the view along the axis.
82 CENTER,
83
84 // Trailing equals to right along the horizontal axis, and bottom along
85 // the vertical axis.
86 TRAILING,
87
88 // The view is resized to fill the space.
[email protected]a1360162009-11-30 21:19:0789 FILL,
90
91 // The view is aligned along the baseline. This is only valid for the
92 // vertical axis.
93 BASELINE
initial.commit09911bf2008-07-26 23:55:2994 };
95
96 // An enumeration of the possible ways the size of a column may be obtained.
97 enum SizeType {
98 // The column size is fixed.
99 FIXED,
100
101 // The preferred size of the view is used to determine the column size.
102 USE_PREF
103 };
104
105 explicit GridLayout(View* host);
106 virtual ~GridLayout();
107
108 // Sets the insets. All views are placed relative to these offsets.
109 void SetInsets(int top, int left, int bottom, int right);
[email protected]3a483452009-12-23 08:56:20110 void SetInsets(const gfx::Insets& insets);
initial.commit09911bf2008-07-26 23:55:29111
112 // Creates a new column set with the specified id and returns it.
113 // The id is later used when starting a new row.
114 // GridLayout takes ownership of the ColumnSet and will delete it when
115 // the GridLayout is deleted.
116 ColumnSet* AddColumnSet(int id);
117
118 // Adds a padding row. Padding rows typically don't have any views, and
119 // but are used to provide vertical white space between views.
120 // Size specifies the height of the row.
121 void AddPaddingRow(float vertical_resize, int size);
122
123 // A convenience for AddPaddingRow followed by StartRow.
124 void StartRowWithPadding(float vertical_resize, int column_set_id,
125 float padding_resize, int padding);
126
127 // Starts a new row with the specified column set.
128 void StartRow(float vertical_resize, int column_set_id);
129
130 // Advances past columns. Use this when the current column should not
131 // contain any views.
132 void SkipColumns(int col_count);
133
134 // Adds a view using the default alignment from the column. The added
135 // view has a column and row span of 1.
136 // As a convenience this adds the view to the host. The view becomes owned
137 // by the host, and NOT this GridLayout.
138 void AddView(View* view);
139
140 // Adds a view using the default alignment from the column.
141 // As a convenience this adds the view to the host. The view becomes owned
142 // by the host, and NOT this GridLayout.
143 void AddView(View* view, int col_span, int row_span);
144
145 // Adds a view with the specified alignment and spans.
146 // As a convenience this adds the view to the host. The view becomes owned
147 // by the host, and NOT this GridLayout.
148 void AddView(View* view, int col_span, int row_span, Alignment h_align,
[email protected]72d1e592009-03-10 17:39:46149 Alignment v_align);
initial.commit09911bf2008-07-26 23:55:29150
151 // Adds a view with the specified alignment and spans. If
152 // pref_width/pref_height is > 0 then the preferred width/height of the view
153 // is fixed to the specified value.
154 // As a convenience this adds the view to the host. The view becomes owned
155 // by the host, and NOT this GridLayout.
156 void AddView(View* view, int col_span, int row_span,
157 Alignment h_align, Alignment v_align,
158 int pref_width, int pref_height);
159
160 // Notification we've been installed on a particular host. Checks that host
161 // is the same as the View supplied in the constructor.
162 virtual void Installed(View* host);
163
164 // Notification we've been uninstalled on a particular host. Checks that host
165 // is the same as the View supplied in the constructor.
166 virtual void Uninstalled(View* host);
167
168 // Notification that a view has been added.
169 virtual void ViewAdded(View* host, View* view);
170
171 // Notification that a view has been removed.
172 virtual void ViewRemoved(View* host, View* view);
173
174 // Layouts out the components.
175 virtual void Layout(View* host);
176
177 // Returns the preferred size for the GridLayout.
[email protected]154f8bc2008-10-15 18:02:30178 virtual gfx::Size GetPreferredSize(View* host);
initial.commit09911bf2008-07-26 23:55:29179
180 virtual int GetPreferredHeightForWidth(View* host, int width);
181
182 private:
183 // As both Layout and GetPreferredSize need to do nearly the same thing,
184 // they both call into this method. This sizes the Columns/Rows as
185 // appropriate. If layout is true, width/height give the width/height the
186 // of the host, otherwise they are ignored.
[email protected]f8617192010-07-05 07:57:10187 void SizeRowsAndColumns(bool layout, int width, int height, gfx::Size* pref);
initial.commit09911bf2008-07-26 23:55:29188
189 // Calculates the master columns of all the column sets. See Column for
190 // a description of what a master column is.
191 void CalculateMasterColumnsIfNecessary();
192
193 // This is called internally from AddView. It adds the ViewState to the
194 // appropriate structures, and updates internal fields such as next_column_.
195 void AddViewState(ViewState* view_state);
196
197 // Returns the column set for the specified id, or NULL if one doesn't exist.
198 ColumnSet* GetColumnSet(int id);
199
200 // Adds the Row to rows_, as well as updating next_column_,
201 // current_row_col_set ...
202 void AddRow(Row* row);
203
204 // As the name says, updates the remaining_height of the ViewState for
205 // all Rows the supplied ViewState touches.
206 void UpdateRemainingHeightFromRows(ViewState* state);
207
208 // If the view state's remaining height is > 0, it is distributed among
209 // the rows the view state touches. This is used during layout to make
210 // sure the Rows can accommodate a view.
211 void DistributeRemainingHeight(ViewState* state);
212
213 // Advances next_column_ past any padding columns.
214 void SkipPaddingColumns();
215
216 // Returns the column set of the last non-padding row.
217 ColumnSet* GetLastValidColumnSet();
218
219 // The view we were created with. We don't own this.
220 View* const host_;
221
222 // Whether or not we've calculated the master/linked columns.
223 bool calculated_master_columns_;
224
225 // Used to verify a view isn't added with a row span that expands into
226 // another column structure.
227 int remaining_row_span_;
228
229 // Current row.
230 int current_row_;
231
232 // Current column.
233 int next_column_;
234
235 // Column set for the current row. This is null for padding rows.
236 ColumnSet* current_row_col_set_;
237
238 // Insets.
239 int top_inset_;
240 int bottom_inset_;
241 int left_inset_;
242 int right_inset_;
243
244 // Set to true when adding a View.
245 bool adding_view_;
246
247 // ViewStates. This is ordered by row_span in ascending order.
248 std::vector<ViewState*> view_states_;
249
250 // ColumnSets.
251 std::vector<ColumnSet*> column_sets_;
252
253 // Rows.
254 std::vector<Row*> rows_;
255
[email protected]a1360162009-11-30 21:19:07256 DISALLOW_COPY_AND_ASSIGN(GridLayout);
initial.commit09911bf2008-07-26 23:55:29257};
258
259// ColumnSet is used to define a set of columns. GridLayout may have any
260// number of ColumnSets. You don't create a ColumnSet directly, instead
261// use the AddColumnSet method of GridLayout.
262class ColumnSet {
263 public:
264 ~ColumnSet();
265
266 // Adds a column for padding. When adding views, padding columns are
267 // automatically skipped. For example, if you create a column set with
268 // two columns separated by a padding column, the first AddView automatically
269 // skips past the padding column. That is, to add two views, do:
270 // layout->AddView(v1); layout->AddView(v2);, not:
271 // layout->AddView(v1); layout->SkipColumns(1); layout->AddView(v2);
272 void AddPaddingColumn(float resize_percent, int width);
273
274 // Adds a column. The alignment gives the default alignment for views added
275 // with no explicit alignment. fixed_width gives a specific width for the
276 // column, and is only used if size_type == FIXED. min_width gives the
277 // minimum width for the column.
[email protected]403e4632010-01-29 22:34:12278 //
279 // If none of the columns in a columnset are resizable, the views are only
280 // made as wide as the widest views in each column, even if extra space is
281 // provided. In other words, GridLayout does not automatically resize views
282 // unless the column is marked as resizable.
initial.commit09911bf2008-07-26 23:55:29283 void AddColumn(GridLayout::Alignment h_align,
284 GridLayout::Alignment v_align,
285 float resize_percent,
286 GridLayout::SizeType size_type,
287 int fixed_width,
288 int min_width);
289
290 // Forces the specified columns to have the same size. The size of
291 // linked columns is that of the max of the specified columns. This
292 // must end with -1. For example, the following forces the first and
293 // second column to have the same size:
294 // LinkColumnSizes(0, 1, -1);
295 void LinkColumnSizes(int first, ...);
296
297 // ID of this ColumnSet.
298 int id() const { return id_; }
299
300 int num_columns() { return static_cast<int>(columns_.size()); }
301
302 private:
303 friend class GridLayout;
304
305 explicit ColumnSet(int id);
306
307 void AddColumn(GridLayout::Alignment h_align,
308 GridLayout::Alignment v_align,
309 float resize_percent,
310 GridLayout::SizeType size_type,
311 int fixed_width,
312 int min_width,
313 bool is_padding);
314
315 void AddViewState(ViewState* view_state);
316
317 // Set description of these.
318 void CalculateMasterColumns();
319 void AccumulateMasterColumns();
320
321 // Sets the size of each linked column to be the same.
322 void UnifySameSizedColumnSizes();
323
324 // Updates the remaining width field of the ViewState from that of the
325 // columns the view spans.
326 void UpdateRemainingWidth(ViewState* view_state);
327
328 // Makes sure the columns touched by view state are big enough for the
329 // view.
330 void DistributeRemainingWidth(ViewState* view_state);
331
332 // Returns the total size needed for this ColumnSet.
333 int LayoutWidth();
334
335 // Returns the width of the specified columns.
336 int GetColumnWidth(int start_col, int col_span);
337
338 // Updates the x coordinate of each column from the previous ones.
339 // NOTE: this doesn't include the insets.
340 void ResetColumnXCoordinates();
341
342 // Calculate the preferred width of each view in this column set, as well
343 // as updating the remaining_width.
344 void CalculateSize();
345
346 // Distributes delta amoung the resizable columns.
347 void Resize(int delta);
348
349 // ID for this columnset.
350 const int id_;
351
352 // The columns.
353 std::vector<Column*> columns_;
354
355 // The ViewStates. This is sorted based on column_span in ascending
356 // order.
357 std::vector<ViewState*> view_states_;
358
359 // The master column of those columns that are linked. See Column
360 // for a description of what the master column is.
361 std::vector<Column*> master_columns_;
362
[email protected]a1360162009-11-30 21:19:07363 DISALLOW_COPY_AND_ASSIGN(ColumnSet);
initial.commit09911bf2008-07-26 23:55:29364};
365
[email protected]c2dacc92008-10-16 23:51:38366} // namespace views
initial.commit09911bf2008-07-26 23:55:29367
[email protected]3984b4b2009-12-01 23:07:00368#endif // VIEWS_GRID_LAYOUT_H_