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.
5 #ifndef UI_VIEWS_CONTROLS_TABLE_TABLE_VIEW_VIEWS_H_
6 #define UI_VIEWS_CONTROLS_TABLE_TABLE_VIEW_VIEWS_H_
10 #include "base/memory/scoped_ptr.h"
11 #include "ui/base/models/list_selection_model.h"
12 #include "ui/base/models/table_model.h"
13 #include "ui/base/models/table_model_observer.h"
14 #include "ui/gfx/font_list.h"
15 #include "ui/views/view.h"
16 #include "ui/views/views_export.h"
18 // A TableView is a view that displays multiple rows with any number of columns.
19 // TableView is driven by a TableModel. The model returns the contents
20 // to display. TableModel also has an Observer which is used to notify
21 // TableView of changes to the model so that the display may be updated
24 // TableView itself has an observer that is notified when the selection
27 // When a table is sorted the model coordinates do not necessarily match the
28 // view coordinates. All table methods are in terms of the model. If you need to
29 // convert to view coordinates use ModelToView().
31 // Sorting is done by a locale sensitive string sort. You can customize the
32 // sort by way of overriding TableModel::CompareValues().
38 class TableViewObserver
;
39 class TableViewRowBackgroundPainter
;
40 class TableViewTestHelper
;
42 // The cells in the first column of a table can contain:
44 // - a small icon (16x16) and some text
45 // - a check box and some text
51 class VIEWS_EXPORT TableView
53 public ui::TableModelObserver
{
55 // Internal class name.
56 static const char kViewClassName
[];
58 // Used to track a visible column. Useful only for the header.
59 struct VIEWS_EXPORT VisibleColumn
{
64 ui::TableColumn column
;
66 // Starting x-coordinate of the column.
69 // Width of the column.
73 // Describes a sorted column.
74 struct VIEWS_EXPORT SortDescriptor
{
75 SortDescriptor() : column_id(-1), ascending(true) {}
76 SortDescriptor(int column_id
, bool ascending
)
77 : column_id(column_id
),
78 ascending(ascending
) {}
80 // ID of the sorted column.
83 // Is the sort ascending?
87 typedef std::vector
<SortDescriptor
> SortDescriptors
;
89 // Creates a new table using the model and columns specified.
90 // The table type applies to the content of the first column (text, icon and
91 // text, checkbox and text).
92 TableView(ui::TableModel
* model
,
93 const std::vector
<ui::TableColumn
>& columns
,
94 TableTypes table_type
,
95 bool single_selection
);
96 ~TableView() override
;
98 // Assigns a new model to the table view, detaching the old one if present.
99 // If |model| is NULL, the table view cannot be used after this call. This
100 // should be called in the containing view's destructor to avoid destruction
101 // issues when the model needs to be deleted before the table.
102 void SetModel(ui::TableModel
* model
);
103 ui::TableModel
* model() const { return model_
; }
105 // Returns a new ScrollView that contains the receiver.
106 View
* CreateParentIfNecessary();
108 void SetRowBackgroundPainter(
109 scoped_ptr
<TableViewRowBackgroundPainter
> painter
);
111 // Sets the TableGrouper. TableView does not own |grouper| (common use case is
112 // to have TableModel implement TableGrouper).
113 void SetGrouper(TableGrouper
* grouper
);
115 // Returns the number of rows in the TableView.
116 int RowCount() const;
118 // Returns the number of selected rows.
119 // TODO(sky): remove this and force callers to use selection_model().
120 int SelectedRowCount();
122 // Selects the specified item, making sure it's visible.
123 void Select(int model_row
);
125 // Returns the first selected row in terms of the model.
126 int FirstSelectedRow();
128 const ui::ListSelectionModel
& selection_model() const {
129 return selection_model_
;
132 // Changes the visibility of the specified column (by id).
133 void SetColumnVisibility(int id
, bool is_visible
);
134 bool IsColumnVisible(int id
) const;
136 // Adds the specified column. |col| is not made visible.
137 void AddColumn(const ui::TableColumn
& col
);
139 // Returns true if the column with the specified id is known (either visible
141 bool HasColumn(int id
) const;
143 // TODO(sky): rename to set_observer().
144 void SetObserver(TableViewObserver
* observer
) {
145 table_view_observer_
= observer
;
147 TableViewObserver
* observer() const { return table_view_observer_
; }
149 const std::vector
<VisibleColumn
>& visible_columns() const {
150 return visible_columns_
;
153 // Sets the width of the column. |index| is in terms of |visible_columns_|.
154 void SetVisibleColumnWidth(int index
, int width
);
156 // Toggles the sort order of the specified visible column index.
157 void ToggleSortOrder(int visible_column_index
);
159 const SortDescriptors
& sort_descriptors() const { return sort_descriptors_
; }
160 bool is_sorted() const { return !sort_descriptors_
.empty(); }
162 // Maps from the index in terms of the model to that of the view.
163 int ModelToView(int model_index
) const;
165 // Maps from the index in terms of the view to that of the model.
166 int ViewToModel(int view_index
) const;
168 int row_height() const { return row_height_
; }
171 void Layout() override
;
172 const char* GetClassName() const override
;
173 gfx::Size
GetPreferredSize() const override
;
174 bool OnKeyPressed(const ui::KeyEvent
& event
) override
;
175 bool OnMousePressed(const ui::MouseEvent
& event
) override
;
176 void OnGestureEvent(ui::GestureEvent
* event
) override
;
177 bool GetTooltipText(const gfx::Point
& p
,
178 base::string16
* tooltip
) const override
;
179 bool GetTooltipTextOrigin(const gfx::Point
& p
,
180 gfx::Point
* loc
) const override
;
181 void GetAccessibleState(ui::AXViewState
* state
) override
;
183 // ui::TableModelObserver overrides:
184 void OnModelChanged() override
;
185 void OnItemsChanged(int start
, int length
) override
;
186 void OnItemsAdded(int start
, int length
) override
;
187 void OnItemsRemoved(int start
, int length
) override
;
191 gfx::Point
GetKeyboardContextMenuLocation() override
;
192 void OnPaint(gfx::Canvas
* canvas
) override
;
193 void OnFocus() override
;
194 void OnBlur() override
;
197 friend class TableViewTestHelper
;
198 struct GroupSortHelper
;
201 // Used during painting to determine the range of cells that need to be
203 // NOTE: the row indices returned by this are in terms of the view and column
204 // indices in terms of |visible_columns_|.
205 struct VIEWS_EXPORT PaintRegion
{
215 // Used by AdvanceSelection() to determine the direction to change the
217 enum AdvanceDirection
{
222 // Invoked when the number of rows changes in some way.
223 void NumRowsChanged();
225 // Resets the sort descriptions.
226 void SetSortDescriptors(const SortDescriptors
& sort_descriptors
);
228 // Does the actual sort and updates the mappings (|view_to_model_| and
229 // |model_to_view_|) appropriately.
230 void SortItemsAndUpdateMapping();
232 // Used to sort the two rows. Returns a value < 0, == 0 or > 0 indicating
233 // whether the row2 comes before row1, row2 is the same as row1 or row1 comes
234 // after row2. This invokes CompareValues on the model with the sorted column.
235 int CompareRows(int model_row1
, int model_row2
);
237 // Returns the bounds of the specified row.
238 gfx::Rect
GetRowBounds(int row
) const;
240 // Returns the bounds of the specified cell. |visible_column_index| indexes
241 // into |visible_columns_|.
242 gfx::Rect
GetCellBounds(int row
, int visible_column_index
) const;
244 // Adjusts |bounds| based on where the text should be painted. |bounds| comes
245 // from GetCellBounds() and |visible_column_index| is the corresponding column
246 // (in terms of |visible_columns_|).
247 void AdjustCellBoundsForText(int visible_column_index
,
248 gfx::Rect
* bounds
) const;
250 // Creates |header_| if necessary.
251 void CreateHeaderIfNecessary();
253 // Updates the |x| and |width| of each of the columns in |visible_columns_|.
254 void UpdateVisibleColumnSizes();
256 // Returns the cells that need to be painted for the specified region.
257 // |bounds| is in terms of |this|.
258 PaintRegion
GetPaintRegion(const gfx::Rect
& bounds
) const;
260 // Returns the bounds that need to be painted based on the clip set on
262 gfx::Rect
GetPaintBounds(gfx::Canvas
* canvas
) const;
264 // Invokes SchedulePaint() for the selected rows.
265 void SchedulePaintForSelection();
267 // Returns the TableColumn matching the specified id.
268 ui::TableColumn
FindColumnByID(int id
) const;
270 // Sets the selection to the specified index (in terms of the view).
271 void SelectByViewIndex(int view_index
);
273 // Sets the selection model to |new_selection|.
274 void SetSelectionModel(const ui::ListSelectionModel
& new_selection
);
276 // Advances the selection (from the active index) in the specified direction.
277 void AdvanceSelection(AdvanceDirection direction
);
279 // Sets |model| appropriately based on a event.
280 void ConfigureSelectionModelForEvent(const ui::LocatedEvent
& event
,
281 ui::ListSelectionModel
* model
) const;
283 // Set the selection state of row at |view_index| to |select|, additionally
284 // any other rows in the GroupRange containing |view_index| are updated as
285 // well. This does not change the anchor or active index of |model|.
286 void SelectRowsInRangeFrom(int view_index
,
288 ui::ListSelectionModel
* model
) const;
290 // Returns the range of the specified model index. If a TableGrouper has not
291 // been set this returns a group with a start of |model_index| and length of
293 GroupRange
GetGroupRange(int model_index
) const;
295 // Used by both GetTooltipText methods. Returns true if there is a tooltip and
296 // sets |tooltip| and/or |tooltip_origin| as appropriate, each of which may be
298 bool GetTooltipImpl(const gfx::Point
& location
,
299 base::string16
* tooltip
,
300 gfx::Point
* tooltip_origin
) const;
302 ui::TableModel
* model_
;
304 std::vector
<ui::TableColumn
> columns_
;
306 // The set of visible columns. The values of these point to |columns_|. This
307 // may contain a subset of |columns_|.
308 std::vector
<VisibleColumn
> visible_columns_
;
310 // The header. This is only created if more than one column is specified or
311 // the first column has a non-empty title.
312 TableHeader
* header_
;
314 const TableTypes table_type_
;
316 const bool single_selection_
;
318 // TODO(sky): rename to observer_.
319 TableViewObserver
* table_view_observer_
;
321 // The selection, in terms of the model.
322 ui::ListSelectionModel selection_model_
;
324 gfx::FontList font_list_
;
328 // Width of the ScrollView last time Layout() was invoked. Used to determine
329 // when we should invoke UpdateVisibleColumnSizes().
330 int last_parent_width_
;
332 // The width we layout to. This may differ from |last_parent_width_|.
336 SortDescriptors sort_descriptors_
;
338 // Mappings used when sorted.
339 std::vector
<int> view_to_model_
;
340 std::vector
<int> model_to_view_
;
342 scoped_ptr
<TableViewRowBackgroundPainter
> row_background_painter_
;
344 TableGrouper
* grouper_
;
346 // True if in SetVisibleColumnWidth().
347 bool in_set_visible_column_width_
;
349 DISALLOW_COPY_AND_ASSIGN(TableView
);
354 #endif // UI_VIEWS_CONTROLS_TABLE_TABLE_VIEW_VIEWS_H_