diff options
author | flackr@chromium.org <flackr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-11 19:33:45 +0000 |
---|---|---|
committer | flackr@chromium.org <flackr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-11 19:33:45 +0000 |
commit | a50ef0211408cff79eb0dcea21dfd4df04c9a284 (patch) | |
tree | d81725a87e2e71e47d2c8df374cfbb73b00239bd /ui | |
parent | 13c843c7fc703383a7f7a2dc06bb6939bc9ebc54 (diff) | |
download | chromium_src-a50ef0211408cff79eb0dcea21dfd4df04c9a284.zip chromium_src-a50ef0211408cff79eb0dcea21dfd4df04c9a284.tar.gz chromium_src-a50ef0211408cff79eb0dcea21dfd4df04c9a284.tar.bz2 |
Revert 117228 - 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.
This broke linux chromeos clang compile: http://build.chromium.org/p/chromium.chromiumos/builders/Linux%20Clang%20%28ChromeOS%20dbg%29/builds/5737/steps/compile/logs/stdio
BUG=109665
TEST=none
R=ben@chromium.org
Review URL: http://codereview.chromium.org/9181019
TBR=sky@chromium.org
Review URL: http://codereview.chromium.org/9190013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@117258 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 | 39 | ||||
-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 | 416 | ||||
-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, 459 insertions, 401 deletions
diff --git a/ui/views/controls/table/group_table_view.h b/ui/views/controls/table/group_table_view.h index 104a563..4c4467d 100644 --- a/ui/views/controls/table/group_table_view.h +++ b/ui/views/controls/table/group_table_view.h @@ -6,10 +6,8 @@ #define UI_VIEWS_CONTROLS_TABLE_GROUP_TABLE_VIEW_H_ #pragma once -#if defined(OS_WIN) && !defined(USE_AURA) +#if defined(OS_WIN) #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 deleted file mode 100644 index b3fb06a..0000000 --- a/ui/views/controls/table/group_table_view_views.cc +++ /dev/null @@ -1,31 +0,0 @@ -// 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 d5f69ad..cccbfd5 100644 --- a/ui/views/controls/table/group_table_view_views.h +++ b/ui/views/controls/table/group_table_view_views.h @@ -6,6 +6,8 @@ #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 { @@ -29,6 +31,43 @@ class VIEWS_EXPORT GroupTableView : public TableView { 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_; + DISALLOW_COPY_AND_ASSIGN(GroupTableView); }; diff --git a/ui/views/controls/table/table_view.h b/ui/views/controls/table/table_view.h index f3f71fd..c7f0845 100644 --- a/ui/views/controls/table/table_view.h +++ b/ui/views/controls/table/table_view.h @@ -6,10 +6,8 @@ #define UI_VIEWS_CONTROLS_TABLE_TABLE_VIEW_H_ #pragma once -#if defined(OS_WIN) && !defined(USE_AURA) +#if defined(OS_WIN) #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 ad5dec0..ba0ddac 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) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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,8 +6,11 @@ #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" @@ -130,6 +133,8 @@ 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 { @@ -460,4 +465,6 @@ 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 deleted file mode 100644 index 7ac75e5..0000000 --- a/ui/views/controls/table/table_view_views.cc +++ /dev/null @@ -1,287 +0,0 @@ -// 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 c5012d6..4a3ae5f 100644 --- a/ui/views/controls/table/table_view_views.h +++ b/ui/views/controls/table/table_view_views.h @@ -6,14 +6,30 @@ #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; @@ -43,6 +59,9 @@ 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: @@ -55,9 +74,57 @@ enum TableTypes { CHECK_BOX_AND_TEXT }; -class VIEWS_EXPORT TableView : public views::View, +// 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, 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). @@ -72,12 +139,9 @@ class VIEWS_EXPORT TableView : public views::View, // 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. @@ -87,8 +151,11 @@ class VIEWS_EXPORT TableView : public views::View, void SetModel(ui::TableModel* model); ui::TableModel* model() const { return model_; } - // Returns a new ScrollPane that contains the receiver. - View* CreateParentIfNecessary(); + // Resorts the contents. + void SetSortDescriptors(const SortDescriptors& sort_descriptors); + + // Current sort. + const SortDescriptors& sort_descriptors() const { return sort_descriptors_; } // Returns the number of rows in the TableView. int RowCount() const; @@ -99,19 +166,30 @@ class VIEWS_EXPORT TableView : public views::View, // 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(); - void SetObserver(TableViewObserver* observer) { - table_view_observer_ = observer; - } - TableViewObserver* observer() const { return table_view_observer_; } + // 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); - // 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; + // 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(); @@ -119,34 +197,306 @@ class VIEWS_EXPORT TableView : public views::View, 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(); + + // 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); + protected: - // View overrides: + // Overriden to return the position of the first selected row. virtual gfx::Point GetKeyboardContextMenuLocation() OVERRIDE; - virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; - virtual void OnFocus() OVERRIDE; - virtual void OnBlur() 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; private: - // Invoked when the number of rows changes in some way. - void NumRowsChanged(); + // Direction of a sort. + enum SortDirection { + ASCENDING_SORT, + DESCENDING_SORT, + NO_SORT + }; - // Returns the bounds of the specified row. - gfx::Rect GetRowBounds(int row); + // 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; + }; - ui::TableModel* model_; + 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); - const TableTypes table_type_; + // 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); + + ui::TableModel* model_; + TableTypes table_type_; TableViewObserver* table_view_observer_; - int selected_row_; + // 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_; + + // 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_; + + // Current sort. + SortDescriptors sort_descriptors_; - gfx::Font font_; + // Mappings used when sorted. + scoped_array<int> view_to_model_; + scoped_array<int> model_to_view_; - int row_height_; + string16 alt_text_; 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 1fdc104..bb21443 100644 --- a/ui/views/controls/table/table_view_win.cc +++ b/ui/views/controls/table/table_view_win.cc @@ -102,10 +102,6 @@ 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 5ca0f01..b0d4076 100644 --- a/ui/views/controls/table/table_view_win.h +++ b/ui/views/controls/table/table_view_win.h @@ -151,10 +151,6 @@ 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 b43c516..835ae1f 100644 --- a/ui/views/examples/examples_window.cc +++ b/ui/views/examples/examples_window.cc @@ -28,7 +28,6 @@ #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" @@ -40,7 +39,11 @@ #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 { @@ -108,7 +111,6 @@ 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); @@ -125,6 +127,9 @@ 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 2a8f695..7dfbb1e 100644 --- a/ui/views/examples/table_example.cc +++ b/ui/views/examples/table_example.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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,7 +6,6 @@ #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" @@ -43,16 +42,10 @@ void TableExample::CreateExampleView(View* container) { container->SetLayoutManager(layout); std::vector<ui::TableColumn> columns; - 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 + 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)); table_ = new TableView(this, columns, ICON_AND_TEXT, true, true, true); table_->SetObserver(this); icon1_.setConfig(SkBitmap::kARGB_8888_Config, 16, 16); @@ -69,7 +62,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_->CreateParentIfNecessary()); + layout->AddView(table_); column_set = layout->AddColumnSet(1); column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, @@ -111,14 +104,10 @@ SkBitmap TableExample::GetIcon(int row) { void TableExample::SetObserver(ui::TableModelObserver* observer) {} void TableExample::OnSelectionChanged() { - PrintStatus("Selected: %s", - UTF16ToASCII(GetText(table_->FirstSelectedRow(), 0)).c_str()); + PrintStatus("Selection changed"); } -void TableExample::OnDoubleClick() { - PrintStatus("Double Click: %s", - UTF16ToASCII(GetText(table_->FirstSelectedRow(), 0)).c_str()); -} +void TableExample::OnDoubleClick() {} void TableExample::OnMiddleClick() {} @@ -144,9 +133,7 @@ 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 fec9a00..8fa0304 100644 --- a/ui/views/views.gyp +++ b/ui/views/views.gyp @@ -1,4 +1,4 @@ -# Copyright (c) 2012 The Chromium Authors. All rights reserved. +# Copyright (c) 2011 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,14 +207,10 @@ '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', @@ -441,10 +437,6 @@ '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', ], @@ -548,9 +540,6 @@ ], }], ], - 'sources/': [ - ['exclude', 'controls/table/table_view_unittest.cc'], - ], }], ['OS=="win"', { 'link_settings': { @@ -670,6 +659,17 @@ '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 |