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
|
// 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/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:
// 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_; }
// View overrides:
void Layout() 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_;
// 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_
|