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