| OLD | NEW |
| (Empty) |
| 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_list.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() const 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 base::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 base::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::FontList font_list_; | |
| 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_ | |
| OLD | NEW |