Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(231)

Side by Side Diff: views/controls/table/table_view.h

Issue 8655001: views: Move table and tree directories to ui/views/controls/. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: exclude native_widget_win_unittest too Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « views/controls/table/native_table_wrapper.h ('k') | views/controls/table/table_view.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 VIEWS_CONTROLS_TABLE_TABLE_VIEW_H_
6 #define VIEWS_CONTROLS_TABLE_TABLE_VIEW_H_
7 #pragma once
8
9 #include <map>
10 #include <vector>
11
12 #include "base/gtest_prod_util.h"
13 #include "base/string16.h"
14 #include "build/build_config.h"
15 #include "third_party/skia/include/core/SkColor.h"
16 #include "ui/base/keycodes/keyboard_codes.h"
17 #include "ui/base/models/table_model_observer.h"
18 #include "views/views_export.h"
19
20 #if defined(OS_WIN)
21 #include <windows.h>
22
23 // TODO(port): remove the ifdef when native_control.h is ported.
24 #include "views/controls/native_control.h"
25
26 typedef struct tagNMLVCUSTOMDRAW NMLVCUSTOMDRAW;
27 #endif // defined(OS_WIN)
28
29 namespace gfx {
30 class Font;
31 }
32
33 namespace ui {
34 struct TableColumn;
35 class TableModel;
36 }
37
38 // A TableView is a view that displays multiple rows with any number of columns.
39 // TableView is driven by a TableModel. The model returns the contents
40 // to display. TableModel also has an Observer which is used to notify
41 // TableView of changes to the model so that the display may be updated
42 // appropriately.
43 //
44 // TableView itself has an observer that is notified when the selection
45 // changes.
46 //
47 // Tables may be sorted either by directly invoking SetSortDescriptors or by
48 // marking the column as sortable and the user doing a gesture to sort the
49 // contents. TableView itself maintains the sort so that the underlying model
50 // isn't effected.
51 //
52 // When a table is sorted the model coordinates do not necessarily match the
53 // view coordinates. All table methods are in terms of the model. If you need to
54 // convert to view coordinates use model_to_view.
55 //
56 // Sorting is done by a locale sensitive string sort. You can customize the
57 // sort by way of overriding CompareValues.
58 //
59 // TableView is a wrapper around the window type ListView in report mode.
60 namespace views {
61
62 class ListView;
63 class ListViewParent;
64 class TableView;
65 class TableViewObserver;
66
67 // The cells in the first column of a table can contain:
68 // - only text
69 // - a small icon (16x16) and some text
70 // - a check box and some text
71 enum TableTypes {
72 TEXT_ONLY = 0,
73 ICON_AND_TEXT,
74 CHECK_BOX_AND_TEXT
75 };
76
77 // Returned from SelectionBegin/SelectionEnd
78 class VIEWS_EXPORT TableSelectionIterator {
79 public:
80 TableSelectionIterator(TableView* view, int view_index);
81 TableSelectionIterator& operator=(const TableSelectionIterator& other);
82 bool operator==(const TableSelectionIterator& other);
83 bool operator!=(const TableSelectionIterator& other);
84 TableSelectionIterator& operator++();
85 int operator*();
86
87 private:
88 void UpdateModelIndexFromViewIndex();
89
90 TableView* table_view_;
91 int view_index_;
92
93 // The index in terms of the model. This is returned from the * operator. This
94 // is cached to avoid dependencies on the view_to_model mapping.
95 int model_index_;
96 };
97
98 #if defined(OS_WIN)
99 // TODO(port): Port TableView.
100 class VIEWS_EXPORT TableView : public NativeControl,
101 public ui::TableModelObserver {
102 public:
103 typedef TableSelectionIterator iterator;
104
105 // A helper struct for GetCellColors. Set |color_is_set| to true if color is
106 // set. See OnCustomDraw for more details on why we need this.
107 struct ItemColor {
108 bool color_is_set;
109 SkColor color;
110 };
111
112 // Describes a sorted column.
113 struct SortDescriptor {
114 SortDescriptor() : column_id(-1), ascending(true) {}
115 SortDescriptor(int column_id, bool ascending)
116 : column_id(column_id),
117 ascending(ascending) { }
118
119 // ID of the sorted column.
120 int column_id;
121
122 // Is the sort ascending?
123 bool ascending;
124 };
125
126 typedef std::vector<SortDescriptor> SortDescriptors;
127
128 // Creates a new table using the model and columns specified.
129 // The table type applies to the content of the first column (text, icon and
130 // text, checkbox and text).
131 // When autosize_columns is true, columns always fill the available width. If
132 // false, columns are not resized when the table is resized. An extra empty
133 // column at the right fills the remaining space.
134 // When resizable_columns is true, users can resize columns by dragging the
135 // separator on the column header. NOTE: Right now this is always true. The
136 // code to set it false is still in place to be a base for future, better
137 // resizing behavior (see http://b/issue?id=874646 ), but no one uses or
138 // tests the case where this flag is false.
139 // Note that setting both resizable_columns and autosize_columns to false is
140 // probably not a good idea, as there is no way for the user to increase a
141 // column's size in that case.
142 TableView(ui::TableModel* model, const std::vector<ui::TableColumn>& columns,
143 TableTypes table_type, bool single_selection,
144 bool resizable_columns, bool autosize_columns);
145 virtual ~TableView();
146
147 // Assigns a new model to the table view, detaching the old one if present.
148 // If |model| is NULL, the table view cannot be used after this call. This
149 // should be called in the containing view's destructor to avoid destruction
150 // issues when the model needs to be deleted before the table.
151 void SetModel(ui::TableModel* model);
152 ui::TableModel* model() const { return model_; }
153
154 // Resorts the contents.
155 void SetSortDescriptors(const SortDescriptors& sort_descriptors);
156
157 // Current sort.
158 const SortDescriptors& sort_descriptors() const { return sort_descriptors_; }
159
160 // Returns the number of rows in the TableView.
161 int RowCount() const;
162
163 // Returns the number of selected rows.
164 int SelectedRowCount();
165
166 // Selects the specified item, making sure it's visible.
167 void Select(int model_row);
168
169 // Sets the selected state of an item (without sending any selection
170 // notifications). Note that this routine does NOT set the focus to the
171 // item at the given index.
172 void SetSelectedState(int model_row, bool state);
173
174 // Sets the focus to the item at the given index.
175 void SetFocusOnItem(int model_row);
176
177 // Returns the first selected row in terms of the model.
178 int FirstSelectedRow();
179
180 // Returns true if the item at the specified index is selected.
181 bool IsItemSelected(int model_row);
182
183 // Returns true if the item at the specified index has the focus.
184 bool ItemHasTheFocus(int model_row);
185
186 // Returns an iterator over the selection. The iterator proceeds from the
187 // last index to the first.
188 //
189 // NOTE: the iterator iterates over the visual order (but returns coordinates
190 // in terms of the model).
191 iterator SelectionBegin();
192 iterator SelectionEnd();
193
194 // ui::TableModelObserver methods.
195 virtual void OnModelChanged();
196 virtual void OnItemsChanged(int start, int length);
197 virtual void OnItemsAdded(int start, int length);
198 virtual void OnItemsRemoved(int start, int length);
199
200 void SetObserver(TableViewObserver* observer) {
201 table_view_observer_ = observer;
202 }
203 TableViewObserver* observer() const { return table_view_observer_; }
204
205 // Replaces the set of known columns without changing the current visible
206 // columns.
207 void SetColumns(const std::vector<ui::TableColumn>& columns);
208 void AddColumn(const ui::TableColumn& col);
209 bool HasColumn(int id);
210
211 // Sets which columns (by id) are displayed. All transient size and position
212 // information is lost.
213 void SetVisibleColumns(const std::vector<int>& columns);
214 void SetColumnVisibility(int id, bool is_visible);
215 bool IsColumnVisible(int id) const;
216
217 // Resets the size of the columns based on the sizes passed to the
218 // constructor. Your normally needn't invoked this, it's done for you the
219 // first time the TableView is given a valid size.
220 void ResetColumnSizes();
221
222 // Sometimes we may want to size the TableView to a specific width and
223 // height.
224 virtual gfx::Size GetPreferredSize();
225 void SetPreferredSize(const gfx::Size& size);
226
227 // Is the table sorted?
228 bool is_sorted() const { return !sort_descriptors_.empty(); }
229
230 // Maps from the index in terms of the model to that of the view.
231 int ModelToView(int model_index) const;
232
233 // Maps from the index in terms of the view to that of the model.
234 int ViewToModel(int view_index) const;
235
236 // Sets the text to display on top of the table. This is useful if the table
237 // is empty and you want to inform the user why.
238 void SetAltText(const string16& alt_text);
239
240 protected:
241 // Overriden to return the position of the first selected row.
242 virtual gfx::Point GetKeyboardContextMenuLocation() OVERRIDE;
243
244 // Subclasses that want to customize the colors of a particular row/column,
245 // must invoke this passing in true. The default value is false, such that
246 // GetCellColors is never invoked.
247 void SetCustomColorsEnabled(bool custom_colors_enabled);
248
249 // Notification from the ListView that the selected state of an item has
250 // changed.
251 virtual void OnSelectedStateChanged();
252
253 // Notification from the ListView that the used double clicked the table.
254 virtual void OnDoubleClick();
255
256 // Notification from the ListView that the user middle clicked the table.
257 virtual void OnMiddleClick();
258
259 // Overridden from NativeControl. Notifies the observer.
260 virtual bool OnKeyDown(ui::KeyboardCode virtual_keycode) OVERRIDE;
261
262 // View override.
263 virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
264
265 // Invoked to customize the colors or font at a particular cell. If you
266 // change the colors or font, return true. This is only invoked if
267 // SetCustomColorsEnabled(true) has been invoked.
268 virtual bool GetCellColors(int model_row,
269 int column,
270 ItemColor* foreground,
271 ItemColor* background,
272 LOGFONT* logfont);
273
274 // Subclasses that want to perform some custom painting (on top of the regular
275 // list view painting) should return true here and implement the PostPaint
276 // method.
277 virtual bool ImplementPostPaint() { return false; }
278 // Subclasses can implement in this method extra-painting for cells.
279 virtual void PostPaint(int model_row, int column, bool selected,
280 const gfx::Rect& bounds, HDC device_context) { }
281 virtual void PostPaint() {}
282
283 virtual HWND CreateNativeControl(HWND parent_container);
284
285 virtual LRESULT OnNotify(int w_param, LPNMHDR l_param);
286
287 // Used to sort the two rows. Returns a value < 0, == 0 or > 0 indicating
288 // whether the row2 comes before row1, row2 is the same as row1 or row1 comes
289 // after row2. This invokes CompareValues on the model with the sorted column.
290 virtual int CompareRows(int model_row1, int model_row2);
291
292 // Called before sorting. This does nothing and is intended for subclasses
293 // that need to cache state used during sorting.
294 virtual void PrepareForSort() {}
295
296 // Returns the width of the specified column by id, or -1 if the column isn't
297 // visible.
298 int GetColumnWidth(int column_id);
299
300 // Returns the offset from the top of the client area to the start of the
301 // content.
302 int content_offset() const { return content_offset_; }
303
304 // Draws the alt_text_. Does nothing if there is no alt_text_.
305 void PaintAltText();
306
307 // Size (width and height) of images.
308 static const int kImageSize;
309
310 private:
311 // Direction of a sort.
312 enum SortDirection {
313 ASCENDING_SORT,
314 DESCENDING_SORT,
315 NO_SORT
316 };
317
318 // We need this wrapper to pass the table view to the windows proc handler
319 // when subclassing the list view and list view header, as the reinterpret
320 // cast from GetWindowLongPtr would break the pointer if it is pointing to a
321 // subclass (in the OO sense of TableView).
322 struct TableViewWrapper {
323 explicit TableViewWrapper(TableView* view) : table_view(view) { }
324 TableView* table_view;
325 };
326
327 friend class ListViewParent;
328 friend class TableSelectionIterator;
329 friend class GroupModelTableViewTest;
330 FRIEND_TEST_ALL_PREFIXES(GroupModelTableViewTest, ShiftSelectAcrossGroups);
331 FRIEND_TEST_ALL_PREFIXES(GroupModelTableViewTest, ShiftSelectSameGroup);
332
333 LRESULT OnCustomDraw(NMLVCUSTOMDRAW* draw_info);
334
335 // Invoked when the user clicks on a column to toggle the sort order. If
336 // column_id is the primary sorted column the direction of the sort is
337 // toggled, otherwise column_id is made the primary sorted column.
338 void ToggleSortOrder(int column_id);
339
340 // Updates the lparam of each of the list view items to be the model index.
341 // If length is > 0, all items with an index >= start get offset by length.
342 // This is used during sorting to determine how the items were sorted.
343 void UpdateItemsLParams(int start, int length);
344
345 // Does the actual sort and updates the mappings (view_to_model and
346 // model_to_view) appropriately.
347 void SortItemsAndUpdateMapping();
348
349 // Selects multiple items from the current view row to the marked view row
350 // (implements shift-click behavior). |view_index| is the most recent row
351 // that the user clicked on, and so there is no guarantee that
352 // |view_index| > |mark_view_index| or vice-versa. Returns false if the
353 // selection attempt was rejected because it crossed group boundaries.
354 bool SelectMultiple(int view_index, int mark_view_index);
355
356 // Method invoked by ListView to compare the two values. Invokes CompareRows.
357 static int CALLBACK SortFunc(LPARAM model_index_1_p,
358 LPARAM model_index_2_p,
359 LPARAM table_view_param);
360
361 // Method invoked by ListView when sorting back to natural state. Returns
362 // model_index_1_p - model_index_2_p.
363 static int CALLBACK NaturalSortFunc(LPARAM model_index_1_p,
364 LPARAM model_index_2_p,
365 LPARAM table_view_param);
366
367 // Resets the sort image displayed for the specified column.
368 void ResetColumnSortImage(int column_id, SortDirection direction);
369
370 // Adds a new column.
371 void InsertColumn(const ui::TableColumn& tc, int index);
372
373 // Update headers and internal state after columns have changed
374 void OnColumnsChanged();
375
376 // Updates the ListView with values from the model. See UpdateListViewCache0
377 // for a complete description.
378 // This turns off redrawing, and invokes UpdateListViewCache0 to do the
379 // actual updating.
380 void UpdateListViewCache(int start, int length, bool add);
381
382 // Updates ListView with values from the model.
383 // If add is true, this adds length items starting at index start.
384 // If add is not true, the items are not added, the but the values in the
385 // range start - [start + length] are updated from the model.
386 void UpdateListViewCache0(int start, int length, bool add);
387
388 // Returns the index of the selected item before |view_index|, or -1 if
389 // |view_index| is the first selected item.
390 //
391 // WARNING: this returns coordinates in terms of the view, NOT the model.
392 int PreviousSelectedViewIndex(int view_index);
393
394 // Returns the last selected view index in the table view, or -1 if the table
395 // is empty, or nothing is selected.
396 //
397 // WARNING: this returns coordinates in terms of the view, NOT the model.
398 int LastSelectedViewIndex();
399
400 // The TableColumn visible at position pos.
401 const ui::TableColumn& GetColumnAtPosition(int pos);
402
403 // Window procedure of the list view class. We subclass the list view to
404 // ignore WM_ERASEBKGND, which gives smoother painting during resizing.
405 static LRESULT CALLBACK TableWndProc(HWND window,
406 UINT message,
407 WPARAM w_param,
408 LPARAM l_param);
409
410 // Window procedure of the header class. We subclass the header of the table
411 // to disable resizing of columns.
412 static LRESULT CALLBACK TableHeaderWndProc(HWND window, UINT message,
413 WPARAM w_param, LPARAM l_param);
414
415 // Updates content_offset_ from the position of the header.
416 void UpdateContentOffset();
417
418 // Reloads the groups from the model if there is one and it has groups.
419 void UpdateGroups();
420
421 // Returns the bounds of the alt text.
422 gfx::Rect GetAltTextBounds();
423
424 // Returns the font used for alt text.
425 gfx::Font GetAltTextFont();
426
427 // Overriden in order to update the column sizes, which can only be sized
428 // accurately when the native control is available.
429 virtual void VisibilityChanged(View* starting_from, bool is_visible);
430
431 ui::TableModel* model_;
432 TableTypes table_type_;
433 TableViewObserver* table_view_observer_;
434
435 // An ordered list of id's into |all_columns_| representing current visible
436 // columns.
437 std::vector<int> visible_columns_;
438
439 // Mapping of an int id to a TableColumn representing all possible columns.
440 std::map<int, ui::TableColumn> all_columns_;
441
442 // Cached value of columns_.size()
443 int column_count_;
444
445 // Selection mode.
446 bool single_selection_;
447
448 // If true, any events that would normally be propagated to the observer
449 // are ignored. For example, if this is true and the selection changes in
450 // the listview, the observer is not notified.
451 bool ignore_listview_change_;
452
453 // Reflects the value passed to SetCustomColorsEnabled.
454 bool custom_colors_enabled_;
455
456 // Whether or not columns should automatically be resized to fill the
457 // the available width when the list view is resized.
458 bool autosize_columns_;
459
460 // Whether or not the user can resize columns.
461 bool resizable_columns_;
462
463 // Whether the column sizes have been determined.
464 bool column_sizes_valid_;
465
466 // NOTE: While this has the name View in it, it's not a view. Rather it's
467 // a wrapper around the List-View window.
468 HWND list_view_;
469
470 // The list view's header original proc handler. It is required when
471 // subclassing.
472 WNDPROC header_original_handler_;
473
474 // Window procedure of the listview before we subclassed it.
475 WNDPROC original_handler_;
476
477 // A wrapper around 'this' used when "subclassing" the list view and header.
478 TableViewWrapper table_view_wrapper_;
479
480 // A custom font we use when overriding the font type for a specific cell.
481 HFONT custom_cell_font_;
482
483 // The preferred size of the table view.
484 gfx::Size preferred_size_;
485
486 int content_offset_;
487
488 // Current sort.
489 SortDescriptors sort_descriptors_;
490
491 // Mappings used when sorted.
492 scoped_array<int> view_to_model_;
493 scoped_array<int> model_to_view_;
494
495 string16 alt_text_;
496
497 DISALLOW_COPY_AND_ASSIGN(TableView);
498 };
499 #endif // defined(OS_WIN)
500
501 } // namespace views
502
503 #endif // VIEWS_CONTROLS_TABLE_TABLE_VIEW_H_
OLDNEW
« no previous file with comments | « views/controls/table/native_table_wrapper.h ('k') | views/controls/table/table_view.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698