diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-11 22:20:39 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-11 22:20:39 +0000 |
commit | d7d0b1aafad48193090a742be0a89c79fc7ddd9e (patch) | |
tree | 68b39b24a15f049edfa24d3e3c524f9c50f2105e /ui | |
parent | c5d58b7883b06a0869136596efed3da19b45e584 (diff) | |
download | chromium_src-d7d0b1aafad48193090a742be0a89c79fc7ddd9e.zip chromium_src-d7d0b1aafad48193090a742be0a89c79fc7ddd9e.tar.gz chromium_src-d7d0b1aafad48193090a742be0a89c79fc7ddd9e.tar.bz2 |
Attempt 2 at: Adds a trivial views based table implementation (only supports single
selection, even for grouptableview) and wires it up for hung renderer
and ssl client certificate.
Only change is adding OVERRIDEs.
BUG=109665
TEST=none
TBR=ben@chromium.org
Review URL: http://codereview.chromium.org/9187027
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@117305 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r-- | ui/views/controls/table/group_table_view.h | 4 | ||||
-rw-r--r-- | ui/views/controls/table/group_table_view_views.cc | 31 | ||||
-rw-r--r-- | ui/views/controls/table/group_table_view_views.h | 45 | ||||
-rw-r--r-- | ui/views/controls/table/table_view.h | 4 | ||||
-rw-r--r-- | ui/views/controls/table/table_view_unittest.cc | 9 | ||||
-rw-r--r-- | ui/views/controls/table/table_view_views.cc | 287 | ||||
-rw-r--r-- | ui/views/controls/table/table_view_views.h | 418 | ||||
-rw-r--r-- | ui/views/controls/table/table_view_win.cc | 4 | ||||
-rw-r--r-- | ui/views/controls/table/table_view_win.h | 4 | ||||
-rw-r--r-- | ui/views/examples/examples_window.cc | 9 | ||||
-rw-r--r-- | ui/views/examples/table_example.cc | 29 | ||||
-rw-r--r-- | ui/views/views.gyp | 24 |
12 files changed, 405 insertions, 463 deletions
diff --git a/ui/views/controls/table/group_table_view.h b/ui/views/controls/table/group_table_view.h index 4c4467d..104a563 100644 --- a/ui/views/controls/table/group_table_view.h +++ b/ui/views/controls/table/group_table_view.h @@ -6,8 +6,10 @@ #define UI_VIEWS_CONTROLS_TABLE_GROUP_TABLE_VIEW_H_ #pragma once -#if defined(OS_WIN) +#if defined(OS_WIN) && !defined(USE_AURA) #include "ui/views/controls/table/group_table_view_win.h" +#else +#include "ui/views/controls/table/group_table_view_views.h" #endif #endif // UI_VIEWS_CONTROLS_TABLE_GROUP_TABLE_VIEW_H_ diff --git a/ui/views/controls/table/group_table_view_views.cc b/ui/views/controls/table/group_table_view_views.cc new file mode 100644 index 0000000..b3fb06a --- /dev/null +++ b/ui/views/controls/table/group_table_view_views.cc @@ -0,0 +1,31 @@ +// 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. + +#include "ui/views/controls/table/group_table_view_views.h" + +#include "ui/views/controls/table/group_table_model.h" + +namespace views { + +const char GroupTableView::kViewClassName[] = "views/GroupTableView"; + +GroupTableView::GroupTableView(GroupTableModel* model, + const std::vector<ui::TableColumn>& columns, + TableTypes table_type, + bool single_selection, + bool resizable_columns, + bool autosize_columns, + bool draw_group_separators) + : TableView(model, columns, table_type, false, resizable_columns, + autosize_columns) { +} + +GroupTableView::~GroupTableView() { +} + +std::string GroupTableView::GetClassName() const { + return kViewClassName; +} + +} // namespace views diff --git a/ui/views/controls/table/group_table_view_views.h b/ui/views/controls/table/group_table_view_views.h index cccbfd5..74d205e 100644 --- a/ui/views/controls/table/group_table_view_views.h +++ b/ui/views/controls/table/group_table_view_views.h @@ -6,8 +6,6 @@ #define UI_VIEWS_CONTROLS_TABLE_GROUP_TABLE_VIEW_VIEWS_H_ #pragma once -#include "base/memory/weak_ptr.h" -#include "ui/base/models/table_model.h" #include "ui/views/controls/table/table_view.h" namespace views { @@ -19,8 +17,8 @@ class GroupTableModel; // perspective. Groups are visually separated by a horizontal line. class VIEWS_EXPORT GroupTableView : public TableView { public: - // The view class name. - static const char kViewClassName[]; + // The view class name. + static const char kViewClassName[]; GroupTableView(GroupTableModel* model, const std::vector<ui::TableColumn>& columns, @@ -29,44 +27,7 @@ class VIEWS_EXPORT GroupTableView : public TableView { bool draw_group_separators); virtual ~GroupTableView(); - virtual std::string GetClassName() const; - - protected: - // Notification from the ListView that the selected state of an item has - // changed. - void OnSelectedStateChanged(); - - // Extra-painting required to draw the separator line between groups. - virtual bool ImplementPostPaint() { return true; } - virtual void PostPaint(int model_row, int column, bool selected, - const gfx::Rect& bounds, HDC device_context); - - // In order to make keyboard navigation possible (using the Up and Down - // keys), we must take action when an arrow key is pressed. The reason we - // need to process this message has to do with the manner in which the focus - // needs to be set on a group item when a group is selected. - virtual bool OnKeyDown(ui::KeyboardCode virtual_keycode); - - // Overriden to make sure rows in the same group stay grouped together. - virtual int CompareRows(int model_row1, int model_row2); - - // Updates model_index_to_range_start_map_ from the model. - virtual void PrepareForSort(); - - private: - // Make the selection of group consistent. - void SyncSelection(); - - GroupTableModel* model_; - - // If true, draw separators between groups. - bool draw_group_separators_; - - // A factory to make the selection consistent among groups. - base::WeakPtrFactory<GroupTableView> sync_selection_factory_; - - // Maps from model row to start of group. - std::map<int,int> model_index_to_range_start_map_; + virtual std::string GetClassName() const OVERRIDE; DISALLOW_COPY_AND_ASSIGN(GroupTableView); }; diff --git a/ui/views/controls/table/table_view.h b/ui/views/controls/table/table_view.h index c7f0845..f3f71fd 100644 --- a/ui/views/controls/table/table_view.h +++ b/ui/views/controls/table/table_view.h @@ -6,8 +6,10 @@ #define UI_VIEWS_CONTROLS_TABLE_TABLE_VIEW_H_ #pragma once -#if defined(OS_WIN) +#if defined(OS_WIN) && !defined(USE_AURA) #include "ui/views/controls/table/table_view_win.h" +#else +#include "ui/views/controls/table/table_view_views.h" #endif #endif // UI_VIEWS_CONTROLS_TABLE_TABLE_VIEW_H_ diff --git a/ui/views/controls/table/table_view_unittest.cc b/ui/views/controls/table/table_view_unittest.cc index ba0ddac..ad5dec0 100644 --- a/ui/views/controls/table/table_view_unittest.cc +++ b/ui/views/controls/table/table_view_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// 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. @@ -6,11 +6,8 @@ #include "build/build_config.h" -#if defined(OS_WIN) #include <atlbase.h> // NOLINT #include <atlwin.h> // NOLINT -#endif - #include <vector> // NOLINT #include "base/compiler_specific.h" @@ -133,8 +130,6 @@ int TestTableModel::CompareValues(int row1, int row2, int column_id) { return rows_[row1][column_id] - rows_[row2][column_id]; } -#if defined(OS_WIN) - // TableViewTest --------------------------------------------------------------- class TableViewTest : public testing::Test, views::WidgetDelegate { @@ -465,6 +460,4 @@ TEST_F(NullModelTableViewTest, DISABLED_NullModel) { // to a NULL model we'll crash. } -#endif // OS_WIN - } // namespace views diff --git a/ui/views/controls/table/table_view_views.cc b/ui/views/controls/table/table_view_views.cc new file mode 100644 index 0000000..7ac75e5 --- /dev/null +++ b/ui/views/controls/table/table_view_views.cc @@ -0,0 +1,287 @@ +// 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. + +#include "ui/views/controls/table/table_view_views.h" + +#include "base/i18n/rtl.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "ui/base/models/table_model.h" +#include "ui/gfx/canvas_skia.h" +#include "ui/gfx/native_theme.h" +#include "ui/gfx/skia_util.h" +#include "ui/views/border.h" +#include "ui/views/controls/scroll_view.h" +#include "ui/views/controls/table/table_view_observer.h" + +// Padding around the text (on each side). +static const int kTextVerticalPadding = 3; +static const int kTextHorizontalPadding = 2; + +// TODO: these should come from native theme or something. +static const SkColor kSelectedBackgroundColor = SkColorSetRGB(0xEE, 0xEE, 0xEE); +static const SkColor kTextColor = SK_ColorBLACK; + +// Size of images. +static const int kImageSize = 16; + +// Padding between the image and text. +static const int kImageToTextPadding = 4; + +namespace views { + + +TableView::TableView(ui::TableModel* model, + const std::vector<ui::TableColumn>& columns, + TableTypes table_type, + bool single_selection, + bool resizable_columns, + bool autosize_columns) + : model_(model), + table_type_(table_type), + table_view_observer_(NULL), + selected_row_(-1), + row_height_(font_.GetHeight() + kTextVerticalPadding * 2) { + // This implementation only shows a single column. + DCHECK_EQ(1u, columns.size()); + // CHECK_BOX_AND_TEXT is not supported. + DCHECK(table_type == TEXT_ONLY || table_type == ICON_AND_TEXT); + set_focusable(true); + set_background(Background::CreateSolidBackground(SK_ColorWHITE)); +} + +TableView::~TableView() { + if (model_) + model_->SetObserver(NULL); +} + +void TableView::SetModel(ui::TableModel* model) { + if (model == model_) + return; + + if (model_) + model_->SetObserver(NULL); + model_ = model; + if (RowCount()) + selected_row_ = 0; + if (model_) + model_->SetObserver(this); +} + +View* TableView::CreateParentIfNecessary() { + ScrollView* scroll_view = new ScrollView; + scroll_view->SetContents(this); + scroll_view->set_border(Border::CreateSolidBorder( + 1, gfx::NativeTheme::instance()->GetSystemColor( + gfx::NativeTheme::kColorId_UnfocusedBorderColor))); + return scroll_view; +} + +int TableView::RowCount() const { + return model_ ? model_->RowCount() : 0; +} + +int TableView::SelectedRowCount() { + return selected_row_ != -1 ? 1 : 0; +} + +void TableView::Select(int model_row) { + if (!model_) + return; + + if (model_row == selected_row_) + return; + + DCHECK(model_row >= 0 && model_row < RowCount()); + selected_row_ = model_row; + if (selected_row_ != -1) + ScrollRectToVisible(GetRowBounds(selected_row_)); + SchedulePaint(); + if (table_view_observer_) + table_view_observer_->OnSelectionChanged(); +} + +int TableView::FirstSelectedRow() { + return selected_row_; +} + +void TableView::Layout() { + // We have to override Layout like this since we're contained in a ScrollView. + gfx::Size pref = GetPreferredSize(); + int width = pref.width(); + int height = pref.height(); + if (parent()) { + width = std::max(parent()->width(), width); + height = std::max(parent()->height(), height); + } + SetBounds(x(), y(), width, height); +} + +gfx::Size TableView::GetPreferredSize() { + return gfx::Size(50, RowCount() * row_height_); +} + +bool TableView::OnKeyPressed(const KeyEvent& event) { + if (!HasFocus()) + return false; + + switch (event.key_code()) { + case ui::VKEY_UP: + if (selected_row_ > 0) + Select(selected_row_ - 1); + else if (selected_row_ == -1 && RowCount()) + Select(RowCount() - 1); + return true; + + case ui::VKEY_DOWN: + if (selected_row_ == -1) { + if (RowCount()) + Select(0); + } else if (selected_row_ + 1 < RowCount()) { + Select(selected_row_ + 1); + } + return true; + + default: + break; + } + return false; +} + +bool TableView::OnMousePressed(const MouseEvent& event) { + RequestFocus(); + int row = event.y() / row_height_; + if (row >= 0 && row < RowCount()) { + Select(row); + if (table_view_observer_ && event.flags() & ui::EF_IS_DOUBLE_CLICK) + table_view_observer_->OnDoubleClick(); + } + return true; +} + +void TableView::OnModelChanged() { + if (RowCount()) + selected_row_ = 0; + else + selected_row_ = -1; + NumRowsChanged(); +} + +void TableView::OnItemsChanged(int start, int length) { + SchedulePaint(); +} + +void TableView::OnItemsAdded(int start, int length) { + if (selected_row_ >= start) + selected_row_ += length; + NumRowsChanged(); +} + +void TableView::OnItemsRemoved(int start, int length) { + bool notify_selection_changed = false; + if (selected_row_ >= (start + length)) { + selected_row_ -= length; + if (selected_row_ == 0 && RowCount() == 0) { + selected_row_ = -1; + notify_selection_changed = true; + } + } else if (selected_row_ >= start) { + selected_row_ = start; + if (selected_row_ == RowCount()) + selected_row_--; + notify_selection_changed = true; + } + if (table_view_observer_ && notify_selection_changed) + table_view_observer_->OnSelectionChanged(); +} + +gfx::Point TableView::GetKeyboardContextMenuLocation() { + int first_selected = FirstSelectedRow(); + gfx::Rect vis_bounds(GetVisibleBounds()); + int y = vis_bounds.height() / 2; + if (first_selected != -1) { + gfx::Rect cell_bounds(GetRowBounds(first_selected)); + if (cell_bounds.bottom() >= vis_bounds.y() && + cell_bounds.bottom() < vis_bounds.bottom()) { + y = cell_bounds.bottom(); + } + } + gfx::Point screen_loc(0, y); + if (base::i18n::IsRTL()) + screen_loc.set_x(width()); + ConvertPointToScreen(this, &screen_loc); + return screen_loc; +} + +void TableView::OnPaint(gfx::Canvas* canvas) { + // Don't invoke View::OnPaint so that we can render our own focus border. + OnPaintBackground(canvas); + + if (!RowCount()) + return; + + int min_y, max_y; + { + SkRect sk_clip_rect; + if (canvas->GetSkCanvas()->getClipBounds(&sk_clip_rect)) { + gfx::Rect clip_rect = gfx::SkRectToRect(sk_clip_rect); + min_y = clip_rect.y(); + max_y = clip_rect.bottom(); + } else { + gfx::Rect vis_bounds = GetVisibleBounds(); + min_y = vis_bounds.y(); + max_y = vis_bounds.bottom(); + } + } + + int min_row = std::min(RowCount() - 1, std::max(0, min_y / row_height_)); + int max_row = max_y / row_height_; + if (max_y % row_height_ != 0) + max_row++; + max_row = std::min(max_row, RowCount()); + for (int i = min_row; i < max_row; ++i) { + gfx::Rect row_bounds(GetRowBounds(i)); + if (i == selected_row_) { + canvas->FillRect(kSelectedBackgroundColor, row_bounds); + if (HasFocus()) + canvas->DrawFocusRect(row_bounds); + } + int text_x = kTextHorizontalPadding; + if (table_type_ == ICON_AND_TEXT) { + SkBitmap image = model_->GetIcon(i); + if (!image.isNull()) { + canvas->DrawBitmapInt( + image, 0, 0, image.width(), image.height(), + text_x, row_bounds.y() + (row_bounds.height() - kImageSize) / 2, + kImageSize, kImageSize, true); + } + text_x += kImageSize + kImageToTextPadding; + } + canvas->DrawStringInt(model_->GetText(i, 0), font_, kTextColor, + text_x, + row_bounds.y() + kTextVerticalPadding, + row_bounds.width() - text_x, + row_bounds.height() - kTextVerticalPadding * 2); + } +} + +void TableView::OnFocus() { + if (selected_row_ != -1) + SchedulePaintInRect(GetRowBounds(selected_row_)); +} + +void TableView::OnBlur() { + if (selected_row_ != -1) + SchedulePaintInRect(GetRowBounds(selected_row_)); +} + +void TableView::NumRowsChanged() { + PreferredSizeChanged(); + SchedulePaint(); +} + +gfx::Rect TableView::GetRowBounds(int row) { + return gfx::Rect(0, row * row_height_, width(), row_height_); +} + +} // namespace views diff --git a/ui/views/controls/table/table_view_views.h b/ui/views/controls/table/table_view_views.h index 4a3ae5f..3b7c4f6 100644 --- a/ui/views/controls/table/table_view_views.h +++ b/ui/views/controls/table/table_view_views.h @@ -6,30 +6,14 @@ #define UI_VIEWS_CONTROLS_TABLE_TABLE_VIEW_VIEWS_H_ #pragma once -#include <map> #include <vector> -#include "base/gtest_prod_util.h" -#include "base/string16.h" -#include "build/build_config.h" -#include "third_party/skia/include/core/SkColor.h" #include "ui/base/keycodes/keyboard_codes.h" #include "ui/base/models/table_model_observer.h" +#include "ui/gfx/font.h" +#include "ui/views/view.h" #include "ui/views/views_export.h" -#if defined(OS_WIN) -#include <windows.h> - -// TODO(port): remove the ifdef when native_control.h is ported. -#include "ui/views/controls/native_control.h" - -typedef struct tagNMLVCUSTOMDRAW NMLVCUSTOMDRAW; -#endif // defined(OS_WIN) - -namespace gfx { -class Font; -} - namespace ui { struct TableColumn; class TableModel; @@ -59,9 +43,6 @@ class TableModel; // TableView is a wrapper around the window type ListView in report mode. namespace views { -class ListView; -class ListViewParent; -class TableView; class TableViewObserver; // The cells in the first column of a table can contain: @@ -74,57 +55,9 @@ enum TableTypes { CHECK_BOX_AND_TEXT }; -// Returned from SelectionBegin/SelectionEnd -class VIEWS_EXPORT TableSelectionIterator { - public: - TableSelectionIterator(TableView* view, int view_index); - TableSelectionIterator& operator=(const TableSelectionIterator& other); - bool operator==(const TableSelectionIterator& other); - bool operator!=(const TableSelectionIterator& other); - TableSelectionIterator& operator++(); - int operator*(); - - private: - void UpdateModelIndexFromViewIndex(); - - TableView* table_view_; - int view_index_; - - // The index in terms of the model. This is returned from the * operator. This - // is cached to avoid dependencies on the view_to_model mapping. - int model_index_; -}; - -#if defined(OS_WIN) -// TODO(port): Port TableView. -class VIEWS_EXPORT TableView : public NativeControl, +class VIEWS_EXPORT TableView : public views::View, public ui::TableModelObserver { public: - typedef TableSelectionIterator iterator; - - // A helper struct for GetCellColors. Set |color_is_set| to true if color is - // set. See OnCustomDraw for more details on why we need this. - struct ItemColor { - bool color_is_set; - SkColor color; - }; - - // Describes a sorted column. - struct 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). @@ -139,9 +72,12 @@ class VIEWS_EXPORT TableView : public NativeControl, // Note that setting both resizable_columns and autosize_columns to false is // probably not a good idea, as there is no way for the user to increase a // column's size in that case. - TableView(ui::TableModel* model, const std::vector<ui::TableColumn>& columns, - TableTypes table_type, bool single_selection, - bool resizable_columns, bool autosize_columns); + TableView(ui::TableModel* model, + const std::vector<ui::TableColumn>& columns, + TableTypes table_type, + bool single_selection, + bool resizable_columns, + bool autosize_columns); virtual ~TableView(); // Assigns a new model to the table view, detaching the old one if present. @@ -151,11 +87,8 @@ class VIEWS_EXPORT TableView : public NativeControl, void SetModel(ui::TableModel* model); ui::TableModel* model() const { return model_; } - // Resorts the contents. - void SetSortDescriptors(const SortDescriptors& sort_descriptors); - - // Current sort. - const SortDescriptors& sort_descriptors() const { return sort_descriptors_; } + // Returns a new ScrollPane that contains the receiver. + View* CreateParentIfNecessary(); // Returns the number of rows in the TableView. int RowCount() const; @@ -166,337 +99,54 @@ class VIEWS_EXPORT TableView : public NativeControl, // Selects the specified item, making sure it's visible. void Select(int model_row); - // Sets the selected state of an item (without sending any selection - // notifications). Note that this routine does NOT set the focus to the - // item at the given index. - void SetSelectedState(int model_row, bool state); - - // Sets the focus to the item at the given index. - void SetFocusOnItem(int model_row); - // Returns the first selected row in terms of the model. int FirstSelectedRow(); - // Returns true if the item at the specified index is selected. - bool IsItemSelected(int model_row); - - // Returns true if the item at the specified index has the focus. - bool ItemHasTheFocus(int model_row); - - // Returns an iterator over the selection. The iterator proceeds from the - // last index to the first. - // - // NOTE: the iterator iterates over the visual order (but returns coordinates - // in terms of the model). - iterator SelectionBegin(); - iterator SelectionEnd(); - - // ui::TableModelObserver methods. - virtual void OnModelChanged(); - virtual void OnItemsChanged(int start, int length); - virtual void OnItemsAdded(int start, int length); - virtual void OnItemsRemoved(int start, int length); - void SetObserver(TableViewObserver* observer) { table_view_observer_ = observer; } TableViewObserver* observer() const { return table_view_observer_; } - // Replaces the set of known columns without changing the current visible - // columns. - void SetColumns(const std::vector<ui::TableColumn>& columns); - void AddColumn(const ui::TableColumn& col); - bool HasColumn(int id); - - // Sets which columns (by id) are displayed. All transient size and position - // information is lost. - void SetVisibleColumns(const std::vector<int>& columns); - void SetColumnVisibility(int id, bool is_visible); - bool IsColumnVisible(int id) const; - - // Resets the size of the columns based on the sizes passed to the - // constructor. Your normally needn't invoked this, it's done for you the - // first time the TableView is given a valid size. - void ResetColumnSizes(); + // View overrides: + virtual void Layout() OVERRIDE; + virtual gfx::Size GetPreferredSize() OVERRIDE; + virtual bool OnKeyPressed(const KeyEvent& event) OVERRIDE; + virtual bool OnMousePressed(const MouseEvent& event) OVERRIDE; - // Sometimes we may want to size the TableView to a specific width and - // height. - virtual gfx::Size GetPreferredSize(); - void SetPreferredSize(const gfx::Size& size); - - // Is the table sorted? - 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; - - // Sets the text to display on top of the table. This is useful if the table - // is empty and you want to inform the user why. - void SetAltText(const string16& alt_text); + // ui::TableModelObserver methods. + virtual void OnModelChanged() OVERRIDE; + virtual void OnItemsChanged(int start, int length) OVERRIDE; + virtual void OnItemsAdded(int start, int length) OVERRIDE; + virtual void OnItemsRemoved(int start, int length) OVERRIDE; protected: - // Overriden to return the position of the first selected row. + // View overrides: virtual gfx::Point GetKeyboardContextMenuLocation() OVERRIDE; - - // Subclasses that want to customize the colors of a particular row/column, - // must invoke this passing in true. The default value is false, such that - // GetCellColors is never invoked. - void SetCustomColorsEnabled(bool custom_colors_enabled); - - // Notification from the ListView that the selected state of an item has - // changed. - virtual void OnSelectedStateChanged(); - - // Notification from the ListView that the used double clicked the table. - virtual void OnDoubleClick(); - - // Notification from the ListView that the user middle clicked the table. - virtual void OnMiddleClick(); - - // Overridden from NativeControl. Notifies the observer. - virtual bool OnKeyDown(ui::KeyboardCode virtual_keycode) OVERRIDE; - - // View override. - virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE; - - // Invoked to customize the colors or font at a particular cell. If you - // change the colors or font, return true. This is only invoked if - // SetCustomColorsEnabled(true) has been invoked. - virtual bool GetCellColors(int model_row, - int column, - ItemColor* foreground, - ItemColor* background, - LOGFONT* logfont); - - // Subclasses that want to perform some custom painting (on top of the regular - // list view painting) should return true here and implement the PostPaint - // method. - virtual bool ImplementPostPaint() { return false; } - // Subclasses can implement in this method extra-painting for cells. - virtual void PostPaint(int model_row, int column, bool selected, - const gfx::Rect& bounds, HDC device_context) { } - virtual void PostPaint() {} - - virtual HWND CreateNativeControl(HWND parent_container); - - virtual LRESULT OnNotify(int w_param, LPNMHDR l_param); - - // 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. - virtual int CompareRows(int model_row1, int model_row2); - - // Called before sorting. This does nothing and is intended for subclasses - // that need to cache state used during sorting. - virtual void PrepareForSort() {} - - // Returns the width of the specified column by id, or -1 if the column isn't - // visible. - int GetColumnWidth(int column_id); - - // Returns the offset from the top of the client area to the start of the - // content. - int content_offset() const { return content_offset_; } - - // Draws the alt_text_. Does nothing if there is no alt_text_. - void PaintAltText(); - - // Size (width and height) of images. - static const int kImageSize; + virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; + virtual void OnFocus() OVERRIDE; + virtual void OnBlur() OVERRIDE; private: - // Direction of a sort. - enum SortDirection { - ASCENDING_SORT, - DESCENDING_SORT, - NO_SORT - }; - - // We need this wrapper to pass the table view to the windows proc handler - // when subclassing the list view and list view header, as the reinterpret - // cast from GetWindowLongPtr would break the pointer if it is pointing to a - // subclass (in the OO sense of TableView). - struct TableViewWrapper { - explicit TableViewWrapper(TableView* view) : table_view(view) { } - TableView* table_view; - }; - - friend class ListViewParent; - friend class TableSelectionIterator; - friend class GroupModelTableViewTest; - FRIEND_TEST_ALL_PREFIXES(GroupModelTableViewTest, ShiftSelectAcrossGroups); - FRIEND_TEST_ALL_PREFIXES(GroupModelTableViewTest, ShiftSelectSameGroup); - - LRESULT OnCustomDraw(NMLVCUSTOMDRAW* draw_info); - - // Invoked when the user clicks on a column to toggle the sort order. If - // column_id is the primary sorted column the direction of the sort is - // toggled, otherwise column_id is made the primary sorted column. - void ToggleSortOrder(int column_id); - - // Updates the lparam of each of the list view items to be the model index. - // If length is > 0, all items with an index >= start get offset by length. - // This is used during sorting to determine how the items were sorted. - void UpdateItemsLParams(int start, int length); - - // Does the actual sort and updates the mappings (view_to_model and - // model_to_view) appropriately. - void SortItemsAndUpdateMapping(); - - // Selects multiple items from the current view row to the marked view row - // (implements shift-click behavior). |view_index| is the most recent row - // that the user clicked on, and so there is no guarantee that - // |view_index| > |mark_view_index| or vice-versa. Returns false if the - // selection attempt was rejected because it crossed group boundaries. - bool SelectMultiple(int view_index, int mark_view_index); - - // Method invoked by ListView to compare the two values. Invokes CompareRows. - static int CALLBACK SortFunc(LPARAM model_index_1_p, - LPARAM model_index_2_p, - LPARAM table_view_param); - - // Method invoked by ListView when sorting back to natural state. Returns - // model_index_1_p - model_index_2_p. - static int CALLBACK NaturalSortFunc(LPARAM model_index_1_p, - LPARAM model_index_2_p, - LPARAM table_view_param); - - // Resets the sort image displayed for the specified column. - void ResetColumnSortImage(int column_id, SortDirection direction); - - // Adds a new column. - void InsertColumn(const ui::TableColumn& tc, int index); - - // Update headers and internal state after columns have changed - void OnColumnsChanged(); - - // Updates the ListView with values from the model. See UpdateListViewCache0 - // for a complete description. - // This turns off redrawing, and invokes UpdateListViewCache0 to do the - // actual updating. - void UpdateListViewCache(int start, int length, bool add); - - // Updates ListView with values from the model. - // If add is true, this adds length items starting at index start. - // If add is not true, the items are not added, the but the values in the - // range start - [start + length] are updated from the model. - void UpdateListViewCache0(int start, int length, bool add); - - // Returns the index of the selected item before |view_index|, or -1 if - // |view_index| is the first selected item. - // - // WARNING: this returns coordinates in terms of the view, NOT the model. - int PreviousSelectedViewIndex(int view_index); - - // Returns the last selected view index in the table view, or -1 if the table - // is empty, or nothing is selected. - // - // WARNING: this returns coordinates in terms of the view, NOT the model. - int LastSelectedViewIndex(); - - // The TableColumn visible at position pos. - const ui::TableColumn& GetColumnAtPosition(int pos); + // Invoked when the number of rows changes in some way. + void NumRowsChanged(); - // Window procedure of the list view class. We subclass the list view to - // ignore WM_ERASEBKGND, which gives smoother painting during resizing. - static LRESULT CALLBACK TableWndProc(HWND window, - UINT message, - WPARAM w_param, - LPARAM l_param); - - // Window procedure of the header class. We subclass the header of the table - // to disable resizing of columns. - static LRESULT CALLBACK TableHeaderWndProc(HWND window, UINT message, - WPARAM w_param, LPARAM l_param); - - // Updates content_offset_ from the position of the header. - void UpdateContentOffset(); - - // Reloads the groups from the model if there is one and it has groups. - void UpdateGroups(); - - // Returns the bounds of the alt text. - gfx::Rect GetAltTextBounds(); - - // Returns the font used for alt text. - gfx::Font GetAltTextFont(); - - // Overriden in order to update the column sizes, which can only be sized - // accurately when the native control is available. - virtual void VisibilityChanged(View* starting_from, bool is_visible); + // Returns the bounds of the specified row. + gfx::Rect GetRowBounds(int row); ui::TableModel* model_; - TableTypes table_type_; - TableViewObserver* table_view_observer_; - - // An ordered list of id's into |all_columns_| representing current visible - // columns. - std::vector<int> visible_columns_; - - // Mapping of an int id to a TableColumn representing all possible columns. - std::map<int, ui::TableColumn> all_columns_; - - // Cached value of columns_.size() - int column_count_; - - // Selection mode. - bool single_selection_; - // If true, any events that would normally be propagated to the observer - // are ignored. For example, if this is true and the selection changes in - // the listview, the observer is not notified. - bool ignore_listview_change_; + const TableTypes table_type_; - // Reflects the value passed to SetCustomColorsEnabled. - bool custom_colors_enabled_; - - // Whether or not columns should automatically be resized to fill the - // the available width when the list view is resized. - bool autosize_columns_; - - // Whether or not the user can resize columns. - bool resizable_columns_; - - // Whether the column sizes have been determined. - bool column_sizes_valid_; - - // NOTE: While this has the name View in it, it's not a view. Rather it's - // a wrapper around the List-View window. - HWND list_view_; - - // The list view's header original proc handler. It is required when - // subclassing. - WNDPROC header_original_handler_; - - // Window procedure of the listview before we subclassed it. - WNDPROC original_handler_; - - // A wrapper around 'this' used when "subclassing" the list view and header. - TableViewWrapper table_view_wrapper_; - - // A custom font we use when overriding the font type for a specific cell. - HFONT custom_cell_font_; - - // The preferred size of the table view. - gfx::Size preferred_size_; - - int content_offset_; + TableViewObserver* table_view_observer_; - // Current sort. - SortDescriptors sort_descriptors_; + int selected_row_; - // Mappings used when sorted. - scoped_array<int> view_to_model_; - scoped_array<int> model_to_view_; + gfx::Font font_; - string16 alt_text_; + int row_height_; DISALLOW_COPY_AND_ASSIGN(TableView); }; -#endif // defined(OS_WIN) } // namespace views diff --git a/ui/views/controls/table/table_view_win.cc b/ui/views/controls/table/table_view_win.cc index bb21443..1fdc104 100644 --- a/ui/views/controls/table/table_view_win.cc +++ b/ui/views/controls/table/table_view_win.cc @@ -102,6 +102,10 @@ void TableView::SetModel(ui::TableModel* model) { OnModelChanged(); } +View* TableView::CreateParentIfNecessary() { + return this; +} + void TableView::SetSortDescriptors(const SortDescriptors& sort_descriptors) { if (!sort_descriptors_.empty()) { ResetColumnSortImage(sort_descriptors_[0].column_id, diff --git a/ui/views/controls/table/table_view_win.h b/ui/views/controls/table/table_view_win.h index b0d4076..5ca0f01 100644 --- a/ui/views/controls/table/table_view_win.h +++ b/ui/views/controls/table/table_view_win.h @@ -151,6 +151,10 @@ class VIEWS_EXPORT TableView : public NativeControl, void SetModel(ui::TableModel* model); ui::TableModel* model() const { return model_; } + // Returns this. Provided for implementations that need to wrap this in a + // ScrollView. + View* CreateParentIfNecessary(); + // Resorts the contents. void SetSortDescriptors(const SortDescriptors& sort_descriptors); diff --git a/ui/views/examples/examples_window.cc b/ui/views/examples/examples_window.cc index 835ae1f..b43c516 100644 --- a/ui/views/examples/examples_window.cc +++ b/ui/views/examples/examples_window.cc @@ -28,6 +28,7 @@ #include "ui/views/examples/scroll_view_example.h" #include "ui/views/examples/single_split_view_example.h" #include "ui/views/examples/tabbed_pane_example.h" +#include "ui/views/examples/table_example.h" #include "ui/views/examples/text_example.h" #include "ui/views/examples/textfield_example.h" #include "ui/views/examples/throbber_example.h" @@ -39,11 +40,7 @@ #if !defined(USE_AURA) #include "ui/views/examples/menu_example.h" -#if defined(OS_WIN) -#include "ui/views/examples/table_example.h" #endif -#endif - namespace views { namespace examples { @@ -111,6 +108,7 @@ class ExamplesWindowContents : public views::WidgetDelegateView { // Adds all the individual examples to the tab strip. void AddExamples() { AddExample(new TreeViewExample); + AddExample(new TableExample); AddExample(new BubbleExample); AddExample(new ButtonExample); AddExample(new ComboboxExample); @@ -127,9 +125,6 @@ class ExamplesWindowContents : public views::WidgetDelegateView { AddExample(new ScrollViewExample); AddExample(new SingleSplitViewExample); AddExample(new TabbedPaneExample); -#if !defined(USE_AURA) && defined(OS_WIN) - AddExample(new TableExample); -#endif AddExample(new TextExample); AddExample(new TextfieldExample); AddExample(new ThrobberExample); diff --git a/ui/views/examples/table_example.cc b/ui/views/examples/table_example.cc index 7dfbb1e..2a8f695 100644 --- a/ui/views/examples/table_example.cc +++ b/ui/views/examples/table_example.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// 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. @@ -6,6 +6,7 @@ #include <vector> +#include "base/string_util.h" #include "base/utf_string_conversions.h" #include "third_party/skia/include/core/SkCanvas.h" #include "ui/views/controls/button/checkbox.h" @@ -42,10 +43,16 @@ void TableExample::CreateExampleView(View* container) { container->SetLayoutManager(layout); std::vector<ui::TableColumn> columns; - columns.push_back(ui::TableColumn(0, L"Fruit", ui::TableColumn::LEFT, 100)); - columns.push_back(ui::TableColumn(1, L"Color", ui::TableColumn::LEFT, 100)); - columns.push_back(ui::TableColumn(2, L"Origin", ui::TableColumn::LEFT, 100)); - columns.push_back(ui::TableColumn(3, L"Price", ui::TableColumn::LEFT, 100)); + columns.push_back(ui::TableColumn(0, ASCIIToUTF16("Fruit"), + ui::TableColumn::LEFT, 100)); +#if !defined(USE_AURA) + columns.push_back(ui::TableColumn(1, ASCIIToUTF16("Color"), + ui::TableColumn::LEFT, 100)); + columns.push_back(ui::TableColumn(2, ASCIIToUTF16("Origin"), + ui::TableColumn::LEFT, 100)); + columns.push_back(ui::TableColumn(3, ASCIIToUTF16("Price"), + ui::TableColumn::LEFT, 100)); +#endif table_ = new TableView(this, columns, ICON_AND_TEXT, true, true, true); table_->SetObserver(this); icon1_.setConfig(SkBitmap::kARGB_8888_Config, 16, 16); @@ -62,7 +69,7 @@ void TableExample::CreateExampleView(View* container) { column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, GridLayout::USE_PREF, 0, 0); layout->StartRow(1 /* expand */, 0); - layout->AddView(table_); + layout->AddView(table_->CreateParentIfNecessary()); column_set = layout->AddColumnSet(1); column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, @@ -104,10 +111,14 @@ SkBitmap TableExample::GetIcon(int row) { void TableExample::SetObserver(ui::TableModelObserver* observer) {} void TableExample::OnSelectionChanged() { - PrintStatus("Selection changed"); + PrintStatus("Selected: %s", + UTF16ToASCII(GetText(table_->FirstSelectedRow(), 0)).c_str()); } -void TableExample::OnDoubleClick() {} +void TableExample::OnDoubleClick() { + PrintStatus("Double Click: %s", + UTF16ToASCII(GetText(table_->FirstSelectedRow(), 0)).c_str()); +} void TableExample::OnMiddleClick() {} @@ -133,7 +144,9 @@ void TableExample::ButtonPressed(Button* sender, const Event& event) { index = 3; show = column4_visible_checkbox_->checked(); } +#if !defined(USE_AURA) table_->SetColumnVisibility(index, show); +#endif } } // namespace examples diff --git a/ui/views/views.gyp b/ui/views/views.gyp index 8fa0304..fec9a00 100644 --- a/ui/views/views.gyp +++ b/ui/views/views.gyp @@ -1,4 +1,4 @@ -# Copyright (c) 2011 The Chromium Authors. All rights reserved. +# 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. { @@ -207,10 +207,14 @@ 'controls/tabbed_pane/tabbed_pane_listener.h', 'controls/table/group_table_model.h', 'controls/table/group_table_view.h', + 'controls/table/group_table_view_views.cc', + 'controls/table/group_table_view_views.h', 'controls/table/group_table_view_win.cc', 'controls/table/group_table_view_win.h', 'controls/table/table_view.h', 'controls/table/table_view_observer.h', + 'controls/table/table_view_views.cc', + 'controls/table/table_view_views.h', 'controls/table/table_view_win.cc', 'controls/table/table_view_win.h', 'controls/textfield/gtk_views_entry.cc', @@ -437,6 +441,10 @@ 'controls/menu/menu_config_views.cc', 'controls/menu/menu_item_view_views.cc', 'controls/menu/menu_separator_views.cc', + 'controls/table/group_table_view_views.cc', + 'controls/table/group_table_view_views.h', + 'controls/table/table_view_views.cc', + 'controls/table/table_view_views.h', 'controls/tree/tree_view_views.cc', 'controls/tree/tree_view_views.h', ], @@ -540,6 +548,9 @@ ], }], ], + 'sources/': [ + ['exclude', 'controls/table/table_view_unittest.cc'], + ], }], ['OS=="win"', { 'link_settings': { @@ -659,17 +670,6 @@ 'include_dirs': [ '../third_party/wtl/include', ], - }, { # OS!="win" - 'sources/': [ - ['exclude', 'examples/table_example.cc'], - ['exclude', 'examples/table_example.h'], - ], - }], - ['use_aura==1', { - 'sources/': [ - ['exclude', 'examples/table_example.cc'], - ['exclude', 'examples/table_example.h'], - ], }], ], }, # target_name: views_examples_lib |