diff options
author | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-10 18:22:10 +0000 |
---|---|---|
committer | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-10 18:22:10 +0000 |
commit | bb2d4f889359d68e27d0091f795003bd5578362b (patch) | |
tree | f635069081a9cca75dd875b7ebc37dd066f6e26f | |
parent | 8fbbe47f8271a1e2c112d1f8dd3ee5fb35a0edca (diff) | |
download | chromium_src-bb2d4f889359d68e27d0091f795003bd5578362b.zip chromium_src-bb2d4f889359d68e27d0091f795003bd5578362b.tar.gz chromium_src-bb2d4f889359d68e27d0091f795003bd5578362b.tar.bz2 |
Add tooltip support to Windows tables.
This doesn't actually make use of the functionality yet, but we get a nice benefit for free: by turning this on, we automatically get "labeltips" (see comments in the code) for all elided items in tables.
BUG=43259
TEST=Hover any elided item in a table and it should display a tooltip with the full item text atop it.
Review URL: http://codereview.chromium.org/2012006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@46832 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | app/table_model.h | 7 | ||||
-rw-r--r-- | views/controls/table/native_table_win.cc | 50 | ||||
-rw-r--r-- | views/controls/table/table_view.cc | 48 |
3 files changed, 96 insertions, 9 deletions
diff --git a/app/table_model.h b/app/table_model.h index b2a07a1..82bb9af 100644 --- a/app/table_model.h +++ b/app/table_model.h @@ -40,6 +40,13 @@ class TableModel { // no bitmap. virtual SkBitmap GetIcon(int row); + // Returns the tooltip, if any, to show for a particular row. If there are + // multiple columns in the row, this will only be shown when hovering over + // column zero. + virtual std::wstring GetTooltip(int row) { + return std::wstring(); + } + // Returns true if the TableView has groups. Groups provide a way to visually // delineate the rows in a table view. When groups are enabled table view // shows a visual separator for each group, followed by all the rows in diff --git a/views/controls/table/native_table_win.cc b/views/controls/table/native_table_win.cc index a30d1bf..1b0806e 100644 --- a/views/controls/table/native_table_win.cc +++ b/views/controls/table/native_table_win.cc @@ -295,9 +295,48 @@ bool NativeTableWin::ProcessMessage(UINT message, WPARAM w_param, break; } - case LVN_MARQUEEBEGIN: // We don't want the marque selection. + case LVN_MARQUEEBEGIN: // We don't want the marquee selection. return true; + case LVN_GETINFOTIP: { + // This is called when the user hovers items in column zero. + // * If the text in this column is not fully visible, the dwFlags + // field will be set to 0, and pszText will contain the full text. + // If you return without making any changes, this text will be + // displayed in a "labeltip" - a bubble that's overlaid (at the + // correct alignment!) on the item. If you return with a different + // pszText, it will be displayed as a tooltip if nonempty. + // * Otherwise, dwFlags will be LVGIT_UNFOLDED and pszText will be + // empty. On return, if pszText is nonempty, it will be displayed + // as a labeltip if dwFlags has been changed to 0 (even if it bears + // no resemblance to the item text), or as a tooltip otherwise. + // + // Once the tooltip for an item has been obtained, this will not be + // called again until the user hovers a different item. If after that + // the original item is hovered a second time, this will be called. + // + // When the user hovers items in other columns, they will be "unfolded" + // (displayed as labeltips) when necessary, but this function will + // never be called. + // + // Changing the LVS_EX_INFOTIP extended style to LVS_EX_LABELTIP will + // cause all of the above to be true except that this function will not + // be called when dwFlags would be LVGIT_UNFOLDED. Removing it entirely + // will disable all of the above behavior. + NMLVGETINFOTIP* info_tip = reinterpret_cast<NMLVGETINFOTIP*>(hdr); + std::wstring tooltip = table_->model()->GetTooltip(info_tip->iItem); + CHECK(info_tip->cchTextMax >= 2); + if (tooltip.length() >= static_cast<size_t>(info_tip->cchTextMax)) { + // Elide the tooltip if necessary. + tooltip.erase(info_tip->cchTextMax - 2); // Ellipsis + '\0' + const wchar_t kEllipsis = L'\x2026'; + tooltip += kEllipsis; + } + if (!tooltip.empty()) + wcscpy_s(info_tip->pszText, tooltip.length() + 1, tooltip.c_str()); + return true; + } + default: break; } @@ -327,10 +366,11 @@ void NativeTableWin::CreateNativeControl() { table_->GetWidget()->GetNativeView(), NULL, NULL, NULL); - // Reduce overdraw/flicker artifacts by double buffering. Make the selection - // extend across the row. - ListView_SetExtendedListViewStyle(hwnd, - LVS_EX_DOUBLEBUFFER | LVS_EX_FULLROWSELECT); + // Reduce overdraw/flicker artifacts by double buffering. Support tooltips + // and display elided items completely on hover (see comments in OnNotify() + // under LVN_GETINFOTIP). Make the selection extend across the row. + ListView_SetExtendedListViewStyle(list_view_, + LVS_EX_DOUBLEBUFFER | LVS_EX_INFOTIP | LVS_EX_FULLROWSELECT); l10n_util::AdjustUIFontForWindow(hwnd); NativeControlCreated(hwnd); diff --git a/views/controls/table/table_view.cc b/views/controls/table/table_view.cc index 73ea02c..c1d07d9 100644 --- a/views/controls/table/table_view.cc +++ b/views/controls/table/table_view.cc @@ -791,10 +791,11 @@ HWND TableView::CreateNativeControl(HWND parent_container) { 0, 0, width(), height(), parent_container, NULL, NULL, NULL); - // Reduce overdraw/flicker artifacts by double buffering. Make the selection - // extend across the row. + // Reduce overdraw/flicker artifacts by double buffering. Support tooltips + // and display elided items completely on hover (see comments in OnNotify() + // under LVN_GETINFOTIP). Make the selection extend across the row. ListView_SetExtendedListViewStyle(list_view_, - LVS_EX_DOUBLEBUFFER | LVS_EX_FULLROWSELECT); + LVS_EX_DOUBLEBUFFER | LVS_EX_INFOTIP | LVS_EX_FULLROWSELECT); l10n_util::AdjustUIFontForWindow(list_view_); // Add the columns. @@ -1053,9 +1054,48 @@ LRESULT TableView::OnNotify(int w_param, LPNMHDR hdr) { break; } - case LVN_MARQUEEBEGIN: // We don't want the marque selection. + case LVN_MARQUEEBEGIN: // We don't want the marquee selection. return 1; + case LVN_GETINFOTIP: { + // This is called when the user hovers items in column zero. + // * If the text in this column is not fully visible, the dwFlags field + // will be set to 0, and pszText will contain the full text. If you + // return without making any changes, this text will be displayed in a + // "labeltip" - a bubble that's overlaid (at the correct alignment!) + // on the item. If you return with a different pszText, it will be + // displayed as a tooltip if nonempty. + // * Otherwise, dwFlags will be LVGIT_UNFOLDED and pszText will be + // empty. On return, if pszText is nonempty, it will be displayed as + // a labeltip if dwFlags has been changed to 0 (even if it bears no + // resemblance to the item text), or as a tooltip otherwise. + // + // Once the tooltip for an item has been obtained, this will not be called + // again until the user hovers a different item. If after that the + // original item is hovered a second time, this will be called. + // + // When the user hovers items in other columns, they will be "unfolded" + // (displayed as labeltips) when necessary, but this function will never + // be called. + // + // Changing the LVS_EX_INFOTIP extended style to LVS_EX_LABELTIP will + // cause all of the above to be true except that this function will not be + // called when dwFlags would be LVGIT_UNFOLDED. Removing it entirely will + // disable all of the above behavior. + NMLVGETINFOTIP* info_tip = reinterpret_cast<NMLVGETINFOTIP*>(hdr); + std::wstring tooltip = + model_->GetTooltip(view_to_model(info_tip->iItem)); + CHECK(info_tip->cchTextMax >= 2); + if (tooltip.length() >= static_cast<size_t>(info_tip->cchTextMax)) { + tooltip.erase(info_tip->cchTextMax - 2); // Ellipsis + '\0' + const wchar_t kEllipsis = L'\x2026'; + tooltip += kEllipsis; + } + if (!tooltip.empty()) + wcscpy_s(info_tip->pszText, tooltip.length() + 1, tooltip.c_str()); + return 1; + } + default: break; } |