From 778763974151316865ce9336eb5676745fa2792f Mon Sep 17 00:00:00 2001
From: "sky@chromium.org"
 <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>
Date: Wed, 30 Jan 2013 20:16:43 +0000
Subject: Makes TableViewViews show tooltips for cells whose text doesn't
 completely fit.

BUG=172840
TEST=none


Review URL: https://chromiumcodereview.appspot.com/12084068

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@179690 0039d316-1c4b-4281-b951-d872f2087c98
---
 ui/views/controls/table/table_header.cc     | 13 +-----
 ui/views/controls/table/table_header.h      |  3 --
 ui/views/controls/table/table_utils.cc      | 11 +++++
 ui/views/controls/table/table_utils.h       |  6 +++
 ui/views/controls/table/table_view_views.cc | 62 ++++++++++++++++++++++++++++-
 ui/views/controls/table/table_view_views.h  | 21 +++++++++-
 6 files changed, 98 insertions(+), 18 deletions(-)

(limited to 'ui/views')

diff --git a/ui/views/controls/table/table_header.cc b/ui/views/controls/table/table_header.cc
index 6d540bf..aafbee5 100644
--- a/ui/views/controls/table/table_header.cc
+++ b/ui/views/controls/table/table_header.cc
@@ -212,7 +212,7 @@ void TableHeader::OnMouseReleased(const ui::MouseEvent& event) {
   if (!was_resizing && event.IsOnlyLeftMouseButton() &&
       !table_->visible_columns().empty()) {
     const int x = GetMirroredXInView(event.x());
-    const int index = GetClosestColumn(x);
+    const int index = GetClosestVisibleColumnIndex(table_, x);
     const TableView::VisibleColumn& column(table_->visible_columns()[index]);
     if (x >= column.x && x < column.x + column.width && event.y() >= 0 &&
         event.y() < height())
@@ -228,21 +228,12 @@ void TableHeader::OnMouseCaptureLost() {
   resize_details_.reset();
 }
 
-int TableHeader::GetClosestColumn(int x) const {
-  const Columns& columns(table_->visible_columns());
-  for (size_t i = 0; i < columns.size(); ++i) {
-    if (x <= columns[i].x + columns[i].width)
-      return static_cast<int>(i);
-  }
-  return static_cast<int>(columns.size()) - 1;
-}
-
 int TableHeader::GetResizeColumn(int x) const {
   const Columns& columns(table_->visible_columns());
   if (columns.empty())
     return -1;
 
-  const int index = GetClosestColumn(x);
+  const int index = GetClosestVisibleColumnIndex(table_, x);
   DCHECK_NE(-1, index);
   const TableView::VisibleColumn& column(table_->visible_columns()[index]);
   if (index > 0 && x >= column.x - kResizePadding &&
diff --git a/ui/views/controls/table/table_header.h b/ui/views/controls/table/table_header.h
index b4970f3..ef10603 100644
--- a/ui/views/controls/table/table_header.h
+++ b/ui/views/controls/table/table_header.h
@@ -52,9 +52,6 @@ class VIEWS_EXPORT TableHeader : public views::View {
     int initial_width;
   };
 
-  // Returns the column closest to the specified x-coordinate.
-  int GetClosestColumn(int x) const;
-
   // Returns the column to resize given the specified x-coordinate, or -1 if |x|
   // is not in the resize range of any columns.
   int GetResizeColumn(int x) const;
diff --git a/ui/views/controls/table/table_utils.cc b/ui/views/controls/table/table_utils.cc
index b52e97d..1e730d0 100644
--- a/ui/views/controls/table/table_utils.cc
+++ b/ui/views/controls/table/table_utils.cc
@@ -7,6 +7,7 @@
 #include "base/logging.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/font.h"
+#include "ui/views/controls/table/table_view.h"
 
 namespace views {
 
@@ -100,4 +101,14 @@ int TableColumnAlignmentToCanvasAlignment(
   return gfx::Canvas::TEXT_ALIGN_LEFT;
 }
 
+int GetClosestVisibleColumnIndex(const TableView* table, int x) {
+  const std::vector<TableView::VisibleColumn>& columns(
+      table->visible_columns());
+  for (size_t i = 0; i < columns.size(); ++i) {
+    if (x <= columns[i].x + columns[i].width)
+      return static_cast<int>(i);
+  }
+  return static_cast<int>(columns.size()) - 1;
+}
+
 }  // namespace views
diff --git a/ui/views/controls/table/table_utils.h b/ui/views/controls/table/table_utils.h
index 74255ca..3c5d4c7 100644
--- a/ui/views/controls/table/table_utils.h
+++ b/ui/views/controls/table/table_utils.h
@@ -16,6 +16,8 @@ class Font;
 
 namespace views {
 
+class TableView;
+
 VIEWS_EXPORT extern const int kUnspecifiedColumnWidth;
 
 // Returns the width needed to display the contents of the specified column.
@@ -46,6 +48,10 @@ VIEWS_EXPORT std::vector<int> CalculateTableColumnSizes(
 // Converts a TableColumn::Alignment to the alignment for drawing the string.
 int TableColumnAlignmentToCanvasAlignment(ui::TableColumn::Alignment alignment);
 
+// Returns the index of the closest visible column index to |x|. Return value is
+// in terms of table->visible_columns().
+int GetClosestVisibleColumnIndex(const TableView* table, int x);
+
 }  // namespace views
 
 #endif  // UI_VIEWS_CONTROLS_TABLE_TABLE_UTILS_H_
diff --git a/ui/views/controls/table/table_view_views.cc b/ui/views/controls/table/table_view_views.cc
index 3e5fd08..5e3000c 100644
--- a/ui/views/controls/table/table_view_views.cc
+++ b/ui/views/controls/table/table_view_views.cc
@@ -381,6 +381,16 @@ bool TableView::OnMousePressed(const ui::MouseEvent& event) {
   return true;
 }
 
+bool TableView::GetTooltipText(const gfx::Point& p,
+                               string16* tooltip) const {
+  return GetTooltipImpl(p, tooltip, NULL);
+}
+
+bool TableView::GetTooltipTextOrigin(const gfx::Point& p,
+                                     gfx::Point* loc) const {
+  return GetTooltipImpl(p, NULL, loc);
+}
+
 void TableView::OnModelChanged() {
   selection_model_.Clear();
   NumRowsChanged();
@@ -604,17 +614,31 @@ int TableView::CompareRows(int model_row1, int model_row2) {
   return SwapCompareResult(sort_result, sort_descriptors_[0].ascending);
 }
 
-gfx::Rect TableView::GetRowBounds(int row) {
+gfx::Rect TableView::GetRowBounds(int row) const {
   return gfx::Rect(0, row * row_height_, width(), row_height_);
 }
 
-gfx::Rect TableView::GetCellBounds(int row, int visible_column_index) {
+gfx::Rect TableView::GetCellBounds(int row, int visible_column_index) const {
   if (!header_)
     return GetRowBounds(row);
   const VisibleColumn& vis_col(visible_columns_[visible_column_index]);
   return gfx::Rect(vis_col.x, row * row_height_, vis_col.width, row_height_);
 }
 
+void TableView::AdjustCellBoundsForText(int visible_column_index,
+                                        gfx::Rect* bounds) const {
+  int text_x = kTextHorizontalPadding + bounds->x();
+  if (visible_column_index == 0) {
+    if (grouper_)
+      text_x += kGroupingIndicatorSize + kTextHorizontalPadding;
+    if (table_type_ == ICON_AND_TEXT)
+      text_x += kImageSize + kTextHorizontalPadding;
+  }
+  bounds->set_x(text_x);
+  bounds->set_width(
+      std::max(0, bounds->right() - kTextHorizontalPadding - text_x));
+}
+
 void TableView::CreateHeaderIfNecessary() {
   // Only create a header if there is more than one column or the title of the
   // only column is not empty.
@@ -827,4 +851,38 @@ GroupRange TableView::GetGroupRange(int model_index) const {
   return range;
 }
 
+bool TableView::GetTooltipImpl(const gfx::Point& location,
+                               string16* tooltip,
+                               gfx::Point* tooltip_origin) const {
+  const int row = location.y() / row_height_;
+  if (row < 0 || row >= RowCount() || visible_columns_.empty())
+    return false;
+
+  const int x = GetMirroredXInView(location.x());
+  const int column = GetClosestVisibleColumnIndex(this, x);
+  if (x < visible_columns_[column].x ||
+      x > (visible_columns_[column].x + visible_columns_[column].width))
+    return false;
+
+  const string16 text(model_->GetText(ViewToModel(row),
+                                      visible_columns_[column].column.id));
+  if (text.empty())
+    return false;
+
+  gfx::Rect cell_bounds(GetCellBounds(row, column));
+  AdjustCellBoundsForText(column, &cell_bounds);
+  const int right = std::min(GetVisibleBounds().right(), cell_bounds.right());
+  if (right > cell_bounds.x() &&
+      font_.GetStringWidth(text) <= (right - cell_bounds.x()))
+    return false;
+
+  if (tooltip)
+    *tooltip = text;
+  if (tooltip_origin) {
+    tooltip_origin->SetPoint(cell_bounds.x(),
+                             cell_bounds.y() + kTextVerticalPadding);
+  }
+  return true;
+}
+
 }  // namespace views
diff --git a/ui/views/controls/table/table_view_views.h b/ui/views/controls/table/table_view_views.h
index f950eb1..5ce25f0 100644
--- a/ui/views/controls/table/table_view_views.h
+++ b/ui/views/controls/table/table_view_views.h
@@ -182,6 +182,10 @@ class VIEWS_EXPORT TableView
   virtual gfx::Size GetPreferredSize() OVERRIDE;
   virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE;
   virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
+  virtual bool GetTooltipText(const gfx::Point& p,
+                              string16* tooltip) const OVERRIDE;
+  virtual bool GetTooltipTextOrigin(const gfx::Point& p,
+                                    gfx::Point* loc) const OVERRIDE;
 
   // ui::TableModelObserver overrides:
   virtual void OnModelChanged() OVERRIDE;
@@ -238,11 +242,17 @@ class VIEWS_EXPORT TableView
   int CompareRows(int model_row1, int model_row2);
 
   // Returns the bounds of the specified row.
-  gfx::Rect GetRowBounds(int row);
+  gfx::Rect GetRowBounds(int row) const;
 
   // Returns the bounds of the specified cell. |visible_column_index| indexes
   // into |visible_columns_|.
-  gfx::Rect GetCellBounds(int row, int visible_column_index);
+  gfx::Rect GetCellBounds(int row, int visible_column_index) const;
+
+  // Adjusts |bounds| based on where the text should be painted. |bounds| comes
+  // from GetCellBounds() and |visible_column_index| is the corresponding column
+  // (in terms of |visible_columns_|).
+  void AdjustCellBoundsForText(int visible_column_index,
+                               gfx::Rect* bounds) const;
 
   // Creates |header_| if necessary.
   void CreateHeaderIfNecessary();
@@ -289,6 +299,13 @@ class VIEWS_EXPORT TableView
   // 1.
   GroupRange GetGroupRange(int model_index) const;
 
+  // Used by both GetTooltipText methods. Returns true if there is a tooltip and
+  // sets |tooltip| and/or |tooltip_origin| as appropriate, each of which may be
+  // NULL.
+  bool GetTooltipImpl(const gfx::Point& location,
+                      string16* tooltip,
+                      gfx::Point* tooltip_origin) const;
+
   ui::TableModel* model_;
 
   std::vector<ui::TableColumn> columns_;
-- 
cgit v1.1