1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_VIEWS_CONTROLS_TABLE_TABLE_VIEW_VIEWS_H_
#define UI_VIEWS_CONTROLS_TABLE_TABLE_VIEW_VIEWS_H_
#include <vector>
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "ui/base/models/list_selection_model.h"
#include "ui/base/models/table_model.h"
#include "ui/base/models/table_model_observer.h"
#include "ui/gfx/font_list.h"
#include "ui/views/view.h"
#include "ui/views/views_export.h"
// A TableView is a view that displays multiple rows with any number of columns.
// TableView is driven by a TableModel. The model returns the contents
// to display. TableModel also has an Observer which is used to notify
// TableView of changes to the model so that the display may be updated
// appropriately.
//
// TableView itself has an observer that is notified when the selection
// changes.
//
// When a table is sorted the model coordinates do not necessarily match the
// view coordinates. All table methods are in terms of the model. If you need to
// convert to view coordinates use ModelToView().
//
// Sorting is done by a locale sensitive string sort. You can customize the
// sort by way of overriding TableModel::CompareValues().
namespace views {
struct GroupRange;
class TableGrouper;
class TableHeader;
class TableViewObserver;
class TableViewRowBackgroundPainter;
class TableViewTestHelper;
// The cells in the first column of a table can contain:
// - only text
// - a small icon (16x16) and some text
// - a check box and some text
enum TableTypes {
TEXT_ONLY = 0,
ICON_AND_TEXT,
};
class VIEWS_EXPORT TableView
: public views::View,
public ui::TableModelObserver {
public:
// Internal class name.
static const char kViewClassName[];
// Used to track a visible column. Useful only for the header.
struct VIEWS_EXPORT VisibleColumn {
VisibleColumn();
~VisibleColumn();
// The column.
ui::TableColumn column;
// Starting x-coordinate of the column.
int x;
// Width of the column.
int width;
};
// Describes a sorted column.
struct VIEWS_EXPORT SortDescriptor {
SortDescriptor() : column_id(-1), ascending(true) {}
SortDescriptor(int column_id, bool ascending)
: column_id(column_id),
ascending(ascending) {}
// ID of the sorted column.
int column_id;
// Is the sort ascending?
bool ascending;
};
typedef std::vector<SortDescriptor> SortDescriptors;
// Creates a new table using the model and columns specified.
// The table type applies to the content of the first column (text, icon and
// text, checkbox and text).
TableView(ui::TableModel* model,
const std::vector<ui::TableColumn>& columns,
TableTypes table_type,
bool single_selection);
~TableView() override;
// Assigns a new model to the table view, detaching the old one if present.
// If |model| is NULL, the table view cannot be used after this call. This
// should be called in the containing view's destructor to avoid destruction
// issues when the model needs to be deleted before the table.
void SetModel(ui::TableModel* model);
ui::TableModel* model() const { return model_; }
// Returns a new ScrollView that contains the receiver.
View* CreateParentIfNecessary();
void SetRowBackgroundPainter(
scoped_ptr<TableViewRowBackgroundPainter> painter);
// Sets the TableGrouper. TableView does not own |grouper| (common use case is
// to have TableModel implement TableGrouper).
void SetGrouper(TableGrouper* grouper);
// Returns the number of rows in the TableView.
int RowCount() const;
// Returns the number of selected rows.
// TODO(sky): remove this and force callers to use selection_model().
int SelectedRowCount();
// Selects the specified item, making sure it's visible.
void Select(int model_row);
// Returns the first selected row in terms of the model.
int FirstSelectedRow();
const ui::ListSelectionModel& selection_model() const {
return selection_model_;
}
// Changes the visibility of the specified column (by id).
void SetColumnVisibility(int id, bool is_visible);
bool IsColumnVisible(int id) const;
// Adds the specified column. |col| is not made visible.
void AddColumn(const ui::TableColumn& col);
// Returns true if the column with the specified id is known (either visible
// or not).
bool HasColumn(int id) const;
// TODO(sky): rename to set_observer().
void SetObserver(TableViewObserver* observer) {
table_view_observer_ = observer;
}
TableViewObserver* observer() const { return table_view_observer_; }
const std::vector<VisibleColumn>& visible_columns() const {
return visible_columns_;
}
// Sets the width of the column. |index| is in terms of |visible_columns_|.
void SetVisibleColumnWidth(int index, int width);
// Toggles the sort order of the specified visible column index.
void ToggleSortOrder(int visible_column_index);
const SortDescriptors& sort_descriptors() const { return sort_descriptors_; }
bool is_sorted() const { return !sort_descriptors_.empty(); }
// Maps from the index in terms of the model to that of the view.
int ModelToView(int model_index) const;
// Maps from the index in terms of the view to that of the model.
int ViewToModel(int view_index) const;
int row_height() const { return row_height_; }
void set_select_on_remove(bool select_on_remove) {
select_on_remove_ = select_on_remove;
}
// View overrides:
void Layout() override;
const char* GetClassName() const override;
gfx::Size GetPreferredSize() const override;
bool OnKeyPressed(const ui::KeyEvent& event) override;
bool OnMousePressed(const ui::MouseEvent& event) override;
void OnGestureEvent(ui::GestureEvent* event) override;
bool GetTooltipText(const gfx::Point& p,
base::string16* tooltip) const override;
bool GetTooltipTextOrigin(const gfx::Point& p,
gfx::Point* loc) const override;
void GetAccessibleState(ui::AXViewState* state) override;
// ui::TableModelObserver overrides:
void OnModelChanged() override;
void OnItemsChanged(int start, int length) override;
void OnItemsAdded(int start, int length) override;
void OnItemsRemoved(int start, int length) override;
protected:
// View overrides:
gfx::Point GetKeyboardContextMenuLocation() override;
void OnPaint(gfx::Canvas* canvas) override;
void OnFocus() override;
void OnBlur() override;
private:
friend class TableViewTestHelper;
struct GroupSortHelper;
struct SortHelper;
// Used during painting to determine the range of cells that need to be
// painted.
// NOTE: the row indices returned by this are in terms of the view and column
// indices in terms of |visible_columns_|.
struct VIEWS_EXPORT PaintRegion {
PaintRegion();
~PaintRegion();
int min_row;
int max_row;
int min_column;
int max_column;
};
// Used by AdvanceSelection() to determine the direction to change the
// selection.
enum AdvanceDirection {
ADVANCE_DECREMENT,
ADVANCE_INCREMENT,
};
// Invoked when the number of rows changes in some way.
void NumRowsChanged();
// Resets the sort descriptions.
void SetSortDescriptors(const SortDescriptors& sort_descriptors);
// Does the actual sort and updates the mappings (|view_to_model_| and
// |model_to_view_|) appropriately.
void SortItemsAndUpdateMapping();
// Used to sort the two rows. Returns a value < 0, == 0 or > 0 indicating
// whether the row2 comes before row1, row2 is the same as row1 or row1 comes
// after row2. This invokes CompareValues on the model with the sorted column.
int CompareRows(int model_row1, int model_row2);
// Returns the bounds of the specified row.
gfx::Rect GetRowBounds(int row) const;
// Returns the bounds of the specified cell. |visible_column_index| indexes
// into |visible_columns_|.
gfx::Rect GetCellBounds(int row, int visible_column_index) const;
// Adjusts |bounds| based on where the text should be painted. |bounds| comes
// from GetCellBounds() and |visible_column_index| is the corresponding column
// (in terms of |visible_columns_|).
void AdjustCellBoundsForText(int visible_column_index,
gfx::Rect* bounds) const;
// Creates |header_| if necessary.
void CreateHeaderIfNecessary();
// Updates the |x| and |width| of each of the columns in |visible_columns_|.
void UpdateVisibleColumnSizes();
// Returns the cells that need to be painted for the specified region.
// |bounds| is in terms of |this|.
PaintRegion GetPaintRegion(const gfx::Rect& bounds) const;
// Returns the bounds that need to be painted based on the clip set on
// |canvas|.
gfx::Rect GetPaintBounds(gfx::Canvas* canvas) const;
// Invokes SchedulePaint() for the selected rows.
void SchedulePaintForSelection();
// Returns the TableColumn matching the specified id.
ui::TableColumn FindColumnByID(int id) const;
// Sets the selection to the specified index (in terms of the view).
void SelectByViewIndex(int view_index);
// Sets the selection model to |new_selection|.
void SetSelectionModel(const ui::ListSelectionModel& new_selection);
// Advances the selection (from the active index) in the specified direction.
void AdvanceSelection(AdvanceDirection direction);
// Sets |model| appropriately based on a event.
void ConfigureSelectionModelForEvent(const ui::LocatedEvent& event,
ui::ListSelectionModel* model) const;
// Set the selection state of row at |view_index| to |select|, additionally
// any other rows in the GroupRange containing |view_index| are updated as
// well. This does not change the anchor or active index of |model|.
void SelectRowsInRangeFrom(int view_index,
bool select,
ui::ListSelectionModel* model) const;
// Returns the range of the specified model index. If a TableGrouper has not
// been set this returns a group with a start of |model_index| and length of
// 1.
GroupRange GetGroupRange(int model_index) const;
// Used by both GetTooltipText methods. Returns true if there is a tooltip and
// sets |tooltip| and/or |tooltip_origin| as appropriate, each of which may be
// NULL.
bool GetTooltipImpl(const gfx::Point& location,
base::string16* tooltip,
gfx::Point* tooltip_origin) const;
ui::TableModel* model_;
std::vector<ui::TableColumn> columns_;
// The set of visible columns. The values of these point to |columns_|. This
// may contain a subset of |columns_|.
std::vector<VisibleColumn> visible_columns_;
// The header. This is only created if more than one column is specified or
// the first column has a non-empty title.
TableHeader* header_;
const TableTypes table_type_;
const bool single_selection_;
// If |select_on_remove_| is true: when a selected item is removed, if the
// removed item is not the last item, select its next one; otherwise select
// its previous one if there is an item.
// If |select_on_remove_| is false: when a selected item is removed, no item
// is selected then.
bool select_on_remove_ = true;
// TODO(sky): rename to observer_.
TableViewObserver* table_view_observer_;
// The selection, in terms of the model.
ui::ListSelectionModel selection_model_;
gfx::FontList font_list_;
int row_height_;
// Width of the ScrollView last time Layout() was invoked. Used to determine
// when we should invoke UpdateVisibleColumnSizes().
int last_parent_width_;
// The width we layout to. This may differ from |last_parent_width_|.
int layout_width_;
// Current sort.
SortDescriptors sort_descriptors_;
// Mappings used when sorted.
std::vector<int> view_to_model_;
std::vector<int> model_to_view_;
scoped_ptr<TableViewRowBackgroundPainter> row_background_painter_;
TableGrouper* grouper_;
// True if in SetVisibleColumnWidth().
bool in_set_visible_column_width_;
DISALLOW_COPY_AND_ASSIGN(TableView);
};
} // namespace views
#endif // UI_VIEWS_CONTROLS_TABLE_TABLE_VIEW_VIEWS_H_
|