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 |