| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "views/widget/tooltip_manager.h" | 5 #include "views/widget/tooltip_manager_win.h" |
| 6 | 6 |
| 7 #include <windowsx.h> | 7 #include <windowsx.h> |
| 8 #include <limits> | 8 #include <limits> |
| 9 | 9 |
| 10 #include "app/gfx/text_elider.h" | 10 #include "app/gfx/text_elider.h" |
| 11 #include "app/l10n_util.h" | 11 #include "app/l10n_util.h" |
| 12 #include "app/l10n_util_win.h" | 12 #include "app/l10n_util_win.h" |
| 13 #include "app/win_util.h" | 13 #include "app/win_util.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/message_loop.h" | 15 #include "base/message_loop.h" |
| 16 #include "views/view.h" | 16 #include "views/view.h" |
| 17 #include "views/widget/root_view.h" | 17 #include "views/widget/root_view.h" |
| 18 #include "views/widget/widget.h" | 18 #include "views/widget/widget.h" |
| 19 | 19 |
| 20 namespace views { | 20 namespace views { |
| 21 | 21 |
| 22 //static | 22 static int tooltip_height_ = 0; |
| 23 int TooltipManager::tooltip_height_ = 0; | |
| 24 | 23 |
| 25 // Default timeout for the tooltip displayed using keyboard. | 24 // Default timeout for the tooltip displayed using keyboard. |
| 26 // Timeout is mentioned in milliseconds. | 25 // Timeout is mentioned in milliseconds. |
| 27 static const int kDefaultTimeout = 4000; | 26 static const int kDefaultTimeout = 4000; |
| 28 | 27 |
| 29 // Maximum number of lines we allow in the tooltip. | 28 // Maximum number of lines we allow in the tooltip. |
| 30 static const int kMaxLines = 6; | 29 static const int kMaxLines = 6; |
| 31 | 30 |
| 32 // Maximum number of characters we allow in a tooltip. | 31 // Maximum number of characters we allow in a tooltip. |
| 33 static const int kMaxTooltipLength = 1024; | 32 static const int kMaxTooltipLength = 1024; |
| 34 | 33 |
| 35 // Breaks |text| along line boundaries, placing each line of text into lines. | 34 // Breaks |text| along line boundaries, placing each line of text into lines. |
| 36 static void SplitTooltipString(const std::wstring& text, | 35 static void SplitTooltipString(const std::wstring& text, |
| 37 std::vector<std::wstring>* lines) { | 36 std::vector<std::wstring>* lines) { |
| 38 size_t index = 0; | 37 size_t index = 0; |
| 39 size_t next_index; | 38 size_t next_index; |
| 40 while ((next_index = text.find(TooltipManager::GetLineSeparator(), index)) | 39 while ((next_index = text.find(TooltipManagerWin::GetLineSeparator(), index)) |
| 41 != std::wstring::npos && lines->size() < kMaxLines) { | 40 != std::wstring::npos && lines->size() < kMaxLines) { |
| 42 lines->push_back(text.substr(index, next_index - index)); | 41 lines->push_back(text.substr(index, next_index - index)); |
| 43 index = next_index + TooltipManager::GetLineSeparator().size(); | 42 index = next_index + TooltipManagerWin::GetLineSeparator().size(); |
| 44 } | 43 } |
| 45 if (next_index != text.size() && lines->size() < kMaxLines) | 44 if (next_index != text.size() && lines->size() < kMaxLines) |
| 46 lines->push_back(text.substr(index, text.size() - index)); | 45 lines->push_back(text.substr(index, text.size() - index)); |
| 47 } | 46 } |
| 48 | 47 |
| 49 // static | 48 // static |
| 50 int TooltipManager::GetTooltipHeight() { | 49 int TooltipManager::GetTooltipHeight() { |
| 51 DCHECK(tooltip_height_ > 0); | 50 DCHECK(tooltip_height_ > 0); |
| 52 return tooltip_height_; | 51 return tooltip_height_; |
| 53 } | 52 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 71 } | 70 } |
| 72 | 71 |
| 73 // static | 72 // static |
| 74 const std::wstring& TooltipManager::GetLineSeparator() { | 73 const std::wstring& TooltipManager::GetLineSeparator() { |
| 75 static const std::wstring* separator = NULL; | 74 static const std::wstring* separator = NULL; |
| 76 if (!separator) | 75 if (!separator) |
| 77 separator = new std::wstring(L"\r\n"); | 76 separator = new std::wstring(L"\r\n"); |
| 78 return *separator; | 77 return *separator; |
| 79 } | 78 } |
| 80 | 79 |
| 81 TooltipManager::TooltipManager(Widget* widget, HWND parent) | 80 TooltipManagerWin::TooltipManagerWin(Widget* widget) |
| 82 : widget_(widget), | 81 : widget_(widget), |
| 83 parent_(parent), | |
| 84 last_mouse_x_(-1), | 82 last_mouse_x_(-1), |
| 85 last_mouse_y_(-1), | 83 last_mouse_y_(-1), |
| 86 tooltip_showing_(false), | 84 tooltip_showing_(false), |
| 87 last_tooltip_view_(NULL), | 85 last_tooltip_view_(NULL), |
| 88 last_view_out_of_sync_(false), | 86 last_view_out_of_sync_(false), |
| 89 tooltip_width_(0), | 87 tooltip_width_(0), |
| 90 keyboard_tooltip_hwnd_(NULL), | 88 keyboard_tooltip_hwnd_(NULL), |
| 91 #pragma warning(suppress: 4355) | 89 #pragma warning(suppress: 4355) |
| 92 keyboard_tooltip_factory_(this) { | 90 keyboard_tooltip_factory_(this) { |
| 93 DCHECK(widget && parent); | 91 DCHECK(widget); |
| 92 DCHECK(widget->GetNativeView()); |
| 94 Init(); | 93 Init(); |
| 95 } | 94 } |
| 96 | 95 |
| 97 TooltipManager::~TooltipManager() { | 96 TooltipManagerWin::~TooltipManagerWin() { |
| 98 if (tooltip_hwnd_) | 97 if (tooltip_hwnd_) |
| 99 DestroyWindow(tooltip_hwnd_); | 98 DestroyWindow(tooltip_hwnd_); |
| 100 if (keyboard_tooltip_hwnd_) | 99 if (keyboard_tooltip_hwnd_) |
| 101 DestroyWindow(keyboard_tooltip_hwnd_); | 100 DestroyWindow(keyboard_tooltip_hwnd_); |
| 102 } | 101 } |
| 103 | 102 |
| 104 void TooltipManager::Init() { | 103 void TooltipManagerWin::Init() { |
| 105 // Create the tooltip control. | 104 // Create the tooltip control. |
| 106 tooltip_hwnd_ = CreateWindowEx( | 105 tooltip_hwnd_ = CreateWindowEx( |
| 107 WS_EX_TRANSPARENT | l10n_util::GetExtendedTooltipStyles(), | 106 WS_EX_TRANSPARENT | l10n_util::GetExtendedTooltipStyles(), |
| 108 TOOLTIPS_CLASS, NULL, TTS_NOPREFIX, 0, 0, 0, 0, | 107 TOOLTIPS_CLASS, NULL, TTS_NOPREFIX, 0, 0, 0, 0, |
| 109 parent_, NULL, NULL, NULL); | 108 GetParent(), NULL, NULL, NULL); |
| 110 | 109 |
| 111 l10n_util::AdjustUIFontForWindow(tooltip_hwnd_); | 110 l10n_util::AdjustUIFontForWindow(tooltip_hwnd_); |
| 112 | 111 |
| 113 // This effectively turns off clipping of tooltips. We need this otherwise | 112 // This effectively turns off clipping of tooltips. We need this otherwise |
| 114 // multi-line text (\r\n) won't work right. The size doesn't really matter | 113 // multi-line text (\r\n) won't work right. The size doesn't really matter |
| 115 // (just as long as its bigger than the monitor's width) as we clip to the | 114 // (just as long as its bigger than the monitor's width) as we clip to the |
| 116 // screen size before rendering. | 115 // screen size before rendering. |
| 117 SendMessage(tooltip_hwnd_, TTM_SETMAXTIPWIDTH, 0, | 116 SendMessage(tooltip_hwnd_, TTM_SETMAXTIPWIDTH, 0, |
| 118 std::numeric_limits<short>::max()); | 117 std::numeric_limits<short>::max()); |
| 119 | 118 |
| 120 // Add one tool that is used for all tooltips. | 119 // Add one tool that is used for all tooltips. |
| 121 toolinfo_.cbSize = sizeof(toolinfo_); | 120 toolinfo_.cbSize = sizeof(toolinfo_); |
| 122 toolinfo_.uFlags = TTF_TRANSPARENT | TTF_IDISHWND; | 121 toolinfo_.uFlags = TTF_TRANSPARENT | TTF_IDISHWND; |
| 123 toolinfo_.hwnd = parent_; | 122 toolinfo_.hwnd = GetParent(); |
| 124 toolinfo_.uId = reinterpret_cast<UINT_PTR>(parent_); | 123 toolinfo_.uId = reinterpret_cast<UINT_PTR>(GetParent()); |
| 125 // Setting this tells windows to call parent_ back (using a WM_NOTIFY | 124 // Setting this tells windows to call GetParent() back (using a WM_NOTIFY |
| 126 // message) for the actual tooltip contents. | 125 // message) for the actual tooltip contents. |
| 127 toolinfo_.lpszText = LPSTR_TEXTCALLBACK; | 126 toolinfo_.lpszText = LPSTR_TEXTCALLBACK; |
| 128 SetRectEmpty(&toolinfo_.rect); | 127 SetRectEmpty(&toolinfo_.rect); |
| 129 SendMessage(tooltip_hwnd_, TTM_ADDTOOL, 0, (LPARAM)&toolinfo_); | 128 SendMessage(tooltip_hwnd_, TTM_ADDTOOL, 0, (LPARAM)&toolinfo_); |
| 130 } | 129 } |
| 131 | 130 |
| 132 void TooltipManager::UpdateTooltip() { | 131 gfx::NativeView TooltipManagerWin::GetParent() { |
| 132 return widget_->GetNativeView(); |
| 133 } |
| 134 |
| 135 void TooltipManagerWin::UpdateTooltip() { |
| 133 // Set last_view_out_of_sync_ to indicate the view is currently out of sync. | 136 // Set last_view_out_of_sync_ to indicate the view is currently out of sync. |
| 134 // This doesn't update the view under the mouse immediately as it may cause | 137 // This doesn't update the view under the mouse immediately as it may cause |
| 135 // timing problems. | 138 // timing problems. |
| 136 last_view_out_of_sync_ = true; | 139 last_view_out_of_sync_ = true; |
| 137 last_tooltip_view_ = NULL; | 140 last_tooltip_view_ = NULL; |
| 138 // Hide the tooltip. | 141 // Hide the tooltip. |
| 139 SendMessage(tooltip_hwnd_, TTM_POP, 0, 0); | 142 SendMessage(tooltip_hwnd_, TTM_POP, 0, 0); |
| 140 } | 143 } |
| 141 | 144 |
| 142 void TooltipManager::TooltipTextChanged(View* view) { | 145 void TooltipManagerWin::TooltipTextChanged(View* view) { |
| 143 if (view == last_tooltip_view_) | 146 if (view == last_tooltip_view_) |
| 144 UpdateTooltip(last_mouse_x_, last_mouse_y_); | 147 UpdateTooltip(last_mouse_x_, last_mouse_y_); |
| 145 } | 148 } |
| 146 | 149 |
| 147 LRESULT TooltipManager::OnNotify(int w_param, NMHDR* l_param, bool* handled) { | 150 LRESULT TooltipManagerWin::OnNotify(int w_param, |
| 151 NMHDR* l_param, |
| 152 bool* handled) { |
| 148 *handled = false; | 153 *handled = false; |
| 149 if (l_param->hwndFrom == tooltip_hwnd_ && keyboard_tooltip_hwnd_ == NULL) { | 154 if (l_param->hwndFrom == tooltip_hwnd_ && keyboard_tooltip_hwnd_ == NULL) { |
| 150 switch (l_param->code) { | 155 switch (l_param->code) { |
| 151 case TTN_GETDISPINFO: { | 156 case TTN_GETDISPINFO: { |
| 152 if (last_view_out_of_sync_) { | 157 if (last_view_out_of_sync_) { |
| 153 // View under the mouse is out of sync, determine it now. | 158 // View under the mouse is out of sync, determine it now. |
| 154 RootView* root_view = widget_->GetRootView(); | 159 RootView* root_view = widget_->GetRootView(); |
| 155 last_tooltip_view_ = root_view->GetViewForPoint( | 160 last_tooltip_view_ = root_view->GetViewForPoint( |
| 156 gfx::Point(last_mouse_x_, last_mouse_y_)); | 161 gfx::Point(last_mouse_x_, last_mouse_y_)); |
| 157 last_view_out_of_sync_ = false; | 162 last_view_out_of_sync_ = false; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 return 0; | 217 return 0; |
| 213 } | 218 } |
| 214 default: | 219 default: |
| 215 // Fall through. | 220 // Fall through. |
| 216 break; | 221 break; |
| 217 } | 222 } |
| 218 } | 223 } |
| 219 return 0; | 224 return 0; |
| 220 } | 225 } |
| 221 | 226 |
| 222 bool TooltipManager::SetTooltipPosition(int text_x, int text_y) { | 227 bool TooltipManagerWin::SetTooltipPosition(int text_x, int text_y) { |
| 223 // NOTE: this really only tests that the y location fits on screen, but that | 228 // NOTE: this really only tests that the y location fits on screen, but that |
| 224 // is good enough for our usage. | 229 // is good enough for our usage. |
| 225 | 230 |
| 226 // Calculate the bounds the tooltip will get. | 231 // Calculate the bounds the tooltip will get. |
| 227 gfx::Point view_loc; | 232 gfx::Point view_loc; |
| 228 View::ConvertPointToScreen(last_tooltip_view_, &view_loc); | 233 View::ConvertPointToScreen(last_tooltip_view_, &view_loc); |
| 229 RECT bounds = { view_loc.x() + text_x, | 234 RECT bounds = { view_loc.x() + text_x, |
| 230 view_loc.y() + text_y, | 235 view_loc.y() + text_y, |
| 231 view_loc.x() + text_x + tooltip_width_, | 236 view_loc.x() + text_x + tooltip_width_, |
| 232 view_loc.y() + line_count_ * GetTooltipHeight() }; | 237 view_loc.y() + line_count_ * GetTooltipHeight() }; |
| 233 SendMessage(tooltip_hwnd_, TTM_ADJUSTRECT, TRUE, (LPARAM)&bounds); | 238 SendMessage(tooltip_hwnd_, TTM_ADJUSTRECT, TRUE, (LPARAM)&bounds); |
| 234 | 239 |
| 235 // Make sure the rectangle completely fits on the current monitor. If it | 240 // Make sure the rectangle completely fits on the current monitor. If it |
| 236 // doesn't, return false so that windows positions the tooltip at the | 241 // doesn't, return false so that windows positions the tooltip at the |
| 237 // default location. | 242 // default location. |
| 238 gfx::Rect monitor_bounds = | 243 gfx::Rect monitor_bounds = |
| 239 win_util::GetMonitorBoundsForRect(gfx::Rect(bounds.left,bounds.right, | 244 win_util::GetMonitorBoundsForRect(gfx::Rect(bounds.left,bounds.right, |
| 240 0, 0)); | 245 0, 0)); |
| 241 if (!monitor_bounds.Contains(gfx::Rect(bounds))) { | 246 if (!monitor_bounds.Contains(gfx::Rect(bounds))) { |
| 242 return false; | 247 return false; |
| 243 } | 248 } |
| 244 | 249 |
| 245 ::SetWindowPos(tooltip_hwnd_, NULL, bounds.left, bounds.top, 0, 0, | 250 ::SetWindowPos(tooltip_hwnd_, NULL, bounds.left, bounds.top, 0, 0, |
| 246 SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE); | 251 SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE); |
| 247 return true; | 252 return true; |
| 248 } | 253 } |
| 249 | 254 |
| 250 int TooltipManager::CalcTooltipHeight() { | 255 int TooltipManagerWin::CalcTooltipHeight() { |
| 251 // Ask the tooltip for it's font. | 256 // Ask the tooltip for it's font. |
| 252 int height; | 257 int height; |
| 253 HFONT hfont = reinterpret_cast<HFONT>( | 258 HFONT hfont = reinterpret_cast<HFONT>( |
| 254 SendMessage(tooltip_hwnd_, WM_GETFONT, 0, 0)); | 259 SendMessage(tooltip_hwnd_, WM_GETFONT, 0, 0)); |
| 255 if (hfont != NULL) { | 260 if (hfont != NULL) { |
| 256 HDC dc = GetDC(tooltip_hwnd_); | 261 HDC dc = GetDC(tooltip_hwnd_); |
| 257 HFONT previous_font = static_cast<HFONT>(SelectObject(dc, hfont)); | 262 HFONT previous_font = static_cast<HFONT>(SelectObject(dc, hfont)); |
| 258 int last_map_mode = SetMapMode(dc, MM_TEXT); | 263 int last_map_mode = SetMapMode(dc, MM_TEXT); |
| 259 TEXTMETRIC font_metrics; | 264 TEXTMETRIC font_metrics; |
| 260 GetTextMetrics(dc, &font_metrics); | 265 GetTextMetrics(dc, &font_metrics); |
| 261 height = font_metrics.tmHeight; | 266 height = font_metrics.tmHeight; |
| 262 // To avoid the DC referencing font_handle_, select the previous font. | 267 // To avoid the DC referencing font_handle_, select the previous font. |
| 263 SelectObject(dc, previous_font); | 268 SelectObject(dc, previous_font); |
| 264 SetMapMode(dc, last_map_mode); | 269 SetMapMode(dc, last_map_mode); |
| 265 ReleaseDC(NULL, dc); | 270 ReleaseDC(NULL, dc); |
| 266 } else { | 271 } else { |
| 267 // Tooltip is using the system font. Use gfx::Font, which should pick | 272 // Tooltip is using the system font. Use gfx::Font, which should pick |
| 268 // up the system font. | 273 // up the system font. |
| 269 height = gfx::Font().height(); | 274 height = gfx::Font().height(); |
| 270 } | 275 } |
| 271 // Get the margins from the tooltip | 276 // Get the margins from the tooltip |
| 272 RECT tooltip_margin; | 277 RECT tooltip_margin; |
| 273 SendMessage(tooltip_hwnd_, TTM_GETMARGIN, 0, (LPARAM)&tooltip_margin); | 278 SendMessage(tooltip_hwnd_, TTM_GETMARGIN, 0, (LPARAM)&tooltip_margin); |
| 274 return height + tooltip_margin.top + tooltip_margin.bottom; | 279 return height + tooltip_margin.top + tooltip_margin.bottom; |
| 275 } | 280 } |
| 276 | 281 |
| 277 void TooltipManager::TrimTooltipToFit(std::wstring* text, | 282 void TooltipManagerWin::TrimTooltipToFit(std::wstring* text, |
| 278 int* max_width, | 283 int* max_width, |
| 279 int* line_count, | 284 int* line_count, |
| 280 int position_x, | 285 int position_x, |
| 281 int position_y, | 286 int position_y, |
| 282 HWND window) { | 287 HWND window) { |
| 283 *max_width = 0; | 288 *max_width = 0; |
| 284 *line_count = 0; | 289 *line_count = 0; |
| 285 | 290 |
| 286 // Clamp the tooltip length to kMaxTooltipLength so that we don't | 291 // Clamp the tooltip length to kMaxTooltipLength so that we don't |
| 287 // accidentally DOS the user with a mega tooltip (since Windows doesn't seem | 292 // accidentally DOS the user with a mega tooltip (since Windows doesn't seem |
| 288 // to do this itself). | 293 // to do this itself). |
| 289 if (text->length() > kMaxTooltipLength) | 294 if (text->length() > kMaxTooltipLength) |
| 290 *text = text->substr(0, kMaxTooltipLength); | 295 *text = text->substr(0, kMaxTooltipLength); |
| 291 | 296 |
| 292 // Determine the available width for the tooltip. | 297 // Determine the available width for the tooltip. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 319 *text = elided_text; | 324 *text = elided_text; |
| 320 return; | 325 return; |
| 321 } | 326 } |
| 322 if (!result.empty()) | 327 if (!result.empty()) |
| 323 result.append(GetLineSeparator()); | 328 result.append(GetLineSeparator()); |
| 324 result.append(elided_text); | 329 result.append(elided_text); |
| 325 } | 330 } |
| 326 *text = result; | 331 *text = result; |
| 327 } | 332 } |
| 328 | 333 |
| 329 void TooltipManager::UpdateTooltip(int x, int y) { | 334 void TooltipManagerWin::UpdateTooltip(int x, int y) { |
| 330 RootView* root_view = widget_->GetRootView(); | 335 RootView* root_view = widget_->GetRootView(); |
| 331 View* view = root_view->GetViewForPoint(gfx::Point(x, y)); | 336 View* view = root_view->GetViewForPoint(gfx::Point(x, y)); |
| 332 if (view != last_tooltip_view_) { | 337 if (view != last_tooltip_view_) { |
| 333 // NOTE: This *must* be sent regardless of the visibility of the tooltip. | 338 // NOTE: This *must* be sent regardless of the visibility of the tooltip. |
| 334 // It triggers Windows to ask for the tooltip again. | 339 // It triggers Windows to ask for the tooltip again. |
| 335 SendMessage(tooltip_hwnd_, TTM_POP, 0, 0); | 340 SendMessage(tooltip_hwnd_, TTM_POP, 0, 0); |
| 336 last_tooltip_view_ = view; | 341 last_tooltip_view_ = view; |
| 337 } else if (last_tooltip_view_ != NULL) { | 342 } else if (last_tooltip_view_ != NULL) { |
| 338 // Tooltip is showing, and mouse is over the same view. See if the tooltip | 343 // Tooltip is showing, and mouse is over the same view. See if the tooltip |
| 339 // text has changed. | 344 // text has changed. |
| 340 gfx::Point view_point(x, y); | 345 gfx::Point view_point(x, y); |
| 341 View::ConvertPointToView(root_view, last_tooltip_view_, &view_point); | 346 View::ConvertPointToView(root_view, last_tooltip_view_, &view_point); |
| 342 std::wstring new_tooltip_text; | 347 std::wstring new_tooltip_text; |
| 343 if (last_tooltip_view_->GetTooltipText(view_point.x(), view_point.y(), | 348 if (last_tooltip_view_->GetTooltipText(view_point.x(), view_point.y(), |
| 344 &new_tooltip_text) && | 349 &new_tooltip_text) && |
| 345 new_tooltip_text != tooltip_text_) { | 350 new_tooltip_text != tooltip_text_) { |
| 346 // The text has changed, hide the popup. | 351 // The text has changed, hide the popup. |
| 347 SendMessage(tooltip_hwnd_, TTM_POP, 0, 0); | 352 SendMessage(tooltip_hwnd_, TTM_POP, 0, 0); |
| 348 if (!new_tooltip_text.empty() && tooltip_showing_) { | 353 if (!new_tooltip_text.empty() && tooltip_showing_) { |
| 349 // New text is valid, show the popup. | 354 // New text is valid, show the popup. |
| 350 SendMessage(tooltip_hwnd_, TTM_POPUP, 0, 0); | 355 SendMessage(tooltip_hwnd_, TTM_POPUP, 0, 0); |
| 351 } | 356 } |
| 352 } | 357 } |
| 353 } | 358 } |
| 354 } | 359 } |
| 355 | 360 |
| 356 void TooltipManager::OnMouse(UINT u_msg, WPARAM w_param, LPARAM l_param) { | 361 void TooltipManagerWin::OnMouse(UINT u_msg, WPARAM w_param, LPARAM l_param) { |
| 357 int x = GET_X_LPARAM(l_param); | 362 int x = GET_X_LPARAM(l_param); |
| 358 int y = GET_Y_LPARAM(l_param); | 363 int y = GET_Y_LPARAM(l_param); |
| 359 | 364 |
| 360 if (u_msg >= WM_NCMOUSEMOVE && u_msg <= WM_NCXBUTTONDBLCLK) { | 365 if (u_msg >= WM_NCMOUSEMOVE && u_msg <= WM_NCXBUTTONDBLCLK) { |
| 361 // NC message coordinates are in screen coordinates. | 366 // NC message coordinates are in screen coordinates. |
| 362 gfx::Rect frame_bounds; | 367 gfx::Rect frame_bounds; |
| 363 widget_->GetBounds(&frame_bounds, true); | 368 widget_->GetBounds(&frame_bounds, true); |
| 364 x -= frame_bounds.x(); | 369 x -= frame_bounds.x(); |
| 365 y -= frame_bounds.y(); | 370 y -= frame_bounds.y(); |
| 366 } | 371 } |
| 367 | 372 |
| 368 if (u_msg != WM_MOUSEMOVE || last_mouse_x_ != x || last_mouse_y_ != y) { | 373 if (u_msg != WM_MOUSEMOVE || last_mouse_x_ != x || last_mouse_y_ != y) { |
| 369 last_mouse_x_ = x; | 374 last_mouse_x_ = x; |
| 370 last_mouse_y_ = y; | 375 last_mouse_y_ = y; |
| 371 HideKeyboardTooltip(); | 376 HideKeyboardTooltip(); |
| 372 UpdateTooltip(x, y); | 377 UpdateTooltip(x, y); |
| 373 } | 378 } |
| 374 // Forward the message onto the tooltip. | 379 // Forward the message onto the tooltip. |
| 375 MSG msg; | 380 MSG msg; |
| 376 msg.hwnd = parent_; | 381 msg.hwnd = GetParent(); |
| 377 msg.message = u_msg; | 382 msg.message = u_msg; |
| 378 msg.wParam = w_param; | 383 msg.wParam = w_param; |
| 379 msg.lParam = l_param; | 384 msg.lParam = l_param; |
| 380 SendMessage(tooltip_hwnd_, TTM_RELAYEVENT, 0, (LPARAM)&msg); | 385 SendMessage(tooltip_hwnd_, TTM_RELAYEVENT, 0, (LPARAM)&msg); |
| 381 } | 386 } |
| 382 | 387 |
| 383 void TooltipManager::ShowKeyboardTooltip(View* focused_view) { | 388 void TooltipManagerWin::ShowKeyboardTooltip(View* focused_view) { |
| 384 if (tooltip_showing_) { | 389 if (tooltip_showing_) { |
| 385 SendMessage(tooltip_hwnd_, TTM_POP, 0, 0); | 390 SendMessage(tooltip_hwnd_, TTM_POP, 0, 0); |
| 386 tooltip_text_.clear(); | 391 tooltip_text_.clear(); |
| 387 } | 392 } |
| 388 HideKeyboardTooltip(); | 393 HideKeyboardTooltip(); |
| 389 std::wstring tooltip_text; | 394 std::wstring tooltip_text; |
| 390 if (!focused_view->GetTooltipText(0, 0, &tooltip_text)) | 395 if (!focused_view->GetTooltipText(0, 0, &tooltip_text)) |
| 391 return; | 396 return; |
| 392 gfx::Rect focused_bounds = focused_view->bounds(); | 397 gfx::Rect focused_bounds = focused_view->bounds(); |
| 393 gfx::Point screen_point; | 398 gfx::Point screen_point; |
| 394 focused_view->ConvertPointToScreen(focused_view, &screen_point); | 399 focused_view->ConvertPointToScreen(focused_view, &screen_point); |
| 395 gfx::Point relative_point_coordinates; | 400 gfx::Point relative_point_coordinates; |
| 396 focused_view->ConvertPointToWidget(focused_view, &relative_point_coordinates); | 401 focused_view->ConvertPointToWidget(focused_view, &relative_point_coordinates); |
| 397 keyboard_tooltip_hwnd_ = CreateWindowEx( | 402 keyboard_tooltip_hwnd_ = CreateWindowEx( |
| 398 WS_EX_TRANSPARENT | l10n_util::GetExtendedTooltipStyles(), | 403 WS_EX_TRANSPARENT | l10n_util::GetExtendedTooltipStyles(), |
| 399 TOOLTIPS_CLASS, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL); | 404 TOOLTIPS_CLASS, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL); |
| 400 SendMessage(keyboard_tooltip_hwnd_, TTM_SETMAXTIPWIDTH, 0, | 405 SendMessage(keyboard_tooltip_hwnd_, TTM_SETMAXTIPWIDTH, 0, |
| 401 std::numeric_limits<short>::max()); | 406 std::numeric_limits<short>::max()); |
| 402 int tooltip_width; | 407 int tooltip_width; |
| 403 int line_count; | 408 int line_count; |
| 404 TrimTooltipToFit(&tooltip_text, &tooltip_width, &line_count, | 409 TrimTooltipToFit(&tooltip_text, &tooltip_width, &line_count, |
| 405 relative_point_coordinates.x(), | 410 relative_point_coordinates.x(), |
| 406 relative_point_coordinates.y(), keyboard_tooltip_hwnd_); | 411 relative_point_coordinates.y(), keyboard_tooltip_hwnd_); |
| 407 TOOLINFO keyboard_toolinfo; | 412 TOOLINFO keyboard_toolinfo; |
| 408 memset(&keyboard_toolinfo, 0, sizeof(keyboard_toolinfo)); | 413 memset(&keyboard_toolinfo, 0, sizeof(keyboard_toolinfo)); |
| 409 keyboard_toolinfo.cbSize = sizeof(keyboard_toolinfo); | 414 keyboard_toolinfo.cbSize = sizeof(keyboard_toolinfo); |
| 410 keyboard_toolinfo.hwnd = parent_; | 415 keyboard_toolinfo.hwnd = GetParent(); |
| 411 keyboard_toolinfo.uFlags = TTF_TRACK | TTF_TRANSPARENT | TTF_IDISHWND ; | 416 keyboard_toolinfo.uFlags = TTF_TRACK | TTF_TRANSPARENT | TTF_IDISHWND ; |
| 412 keyboard_toolinfo.lpszText = const_cast<WCHAR*>(tooltip_text.c_str()); | 417 keyboard_toolinfo.lpszText = const_cast<WCHAR*>(tooltip_text.c_str()); |
| 413 SendMessage(keyboard_tooltip_hwnd_, TTM_ADDTOOL, 0, | 418 SendMessage(keyboard_tooltip_hwnd_, TTM_ADDTOOL, 0, |
| 414 reinterpret_cast<LPARAM>(&keyboard_toolinfo)); | 419 reinterpret_cast<LPARAM>(&keyboard_toolinfo)); |
| 415 SendMessage(keyboard_tooltip_hwnd_, TTM_TRACKACTIVATE, TRUE, | 420 SendMessage(keyboard_tooltip_hwnd_, TTM_TRACKACTIVATE, TRUE, |
| 416 reinterpret_cast<LPARAM>(&keyboard_toolinfo)); | 421 reinterpret_cast<LPARAM>(&keyboard_toolinfo)); |
| 417 if (!tooltip_height_) | 422 if (!tooltip_height_) |
| 418 tooltip_height_ = CalcTooltipHeight(); | 423 tooltip_height_ = CalcTooltipHeight(); |
| 419 RECT rect_bounds = {screen_point.x(), | 424 RECT rect_bounds = {screen_point.x(), |
| 420 screen_point.y() + focused_bounds.height(), | 425 screen_point.y() + focused_bounds.height(), |
| 421 screen_point.x() + tooltip_width, | 426 screen_point.x() + tooltip_width, |
| 422 screen_point.y() + focused_bounds.height() + | 427 screen_point.y() + focused_bounds.height() + |
| 423 line_count * tooltip_height_ }; | 428 line_count * tooltip_height_ }; |
| 424 gfx::Rect monitor_bounds = | 429 gfx::Rect monitor_bounds = |
| 425 win_util::GetMonitorBoundsForRect(gfx::Rect(rect_bounds)); | 430 win_util::GetMonitorBoundsForRect(gfx::Rect(rect_bounds)); |
| 426 rect_bounds = gfx::Rect(rect_bounds).AdjustToFit(monitor_bounds).ToRECT(); | 431 rect_bounds = gfx::Rect(rect_bounds).AdjustToFit(monitor_bounds).ToRECT(); |
| 427 ::SetWindowPos(keyboard_tooltip_hwnd_, NULL, rect_bounds.left, | 432 ::SetWindowPos(keyboard_tooltip_hwnd_, NULL, rect_bounds.left, |
| 428 rect_bounds.top, 0, 0, | 433 rect_bounds.top, 0, 0, |
| 429 SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE); | 434 SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE); |
| 430 MessageLoop::current()->PostDelayedTask(FROM_HERE, | 435 MessageLoop::current()->PostDelayedTask(FROM_HERE, |
| 431 keyboard_tooltip_factory_.NewRunnableMethod( | 436 keyboard_tooltip_factory_.NewRunnableMethod( |
| 432 &TooltipManager::DestroyKeyboardTooltipWindow, keyboard_tooltip_hwnd_), | 437 &TooltipManagerWin::DestroyKeyboardTooltipWindow, |
| 438 keyboard_tooltip_hwnd_), |
| 433 kDefaultTimeout); | 439 kDefaultTimeout); |
| 434 } | 440 } |
| 435 | 441 |
| 436 void TooltipManager::HideKeyboardTooltip() { | 442 void TooltipManagerWin::HideKeyboardTooltip() { |
| 437 if (keyboard_tooltip_hwnd_ != NULL) { | 443 if (keyboard_tooltip_hwnd_ != NULL) { |
| 438 SendMessage(keyboard_tooltip_hwnd_, WM_CLOSE, 0, 0); | 444 SendMessage(keyboard_tooltip_hwnd_, WM_CLOSE, 0, 0); |
| 439 keyboard_tooltip_hwnd_ = NULL; | 445 keyboard_tooltip_hwnd_ = NULL; |
| 440 } | 446 } |
| 441 } | 447 } |
| 442 | 448 |
| 443 void TooltipManager::DestroyKeyboardTooltipWindow(HWND window_to_destroy) { | 449 void TooltipManagerWin::DestroyKeyboardTooltipWindow(HWND window_to_destroy) { |
| 444 if (keyboard_tooltip_hwnd_ == window_to_destroy) | 450 if (keyboard_tooltip_hwnd_ == window_to_destroy) |
| 445 HideKeyboardTooltip(); | 451 HideKeyboardTooltip(); |
| 446 } | 452 } |
| 447 | 453 |
| 448 } // namespace views | 454 } // namespace views |
| OLD | NEW |