| 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 <limits> | 5 #include <limits> |
| 6 | 6 |
| 7 #include "chrome/common/gfx/chrome_font.h" | 7 #include "chrome/common/gfx/chrome_font.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "chrome/common/l10n_util.h" | 10 #include "chrome/common/l10n_util.h" |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 reinterpret_cast<NMTTDISPINFOW*>(l_param); | 156 reinterpret_cast<NMTTDISPINFOW*>(l_param); |
| 157 // Initialize the string, if we have a valid tooltip the string will | 157 // Initialize the string, if we have a valid tooltip the string will |
| 158 // get reset below. | 158 // get reset below. |
| 159 tooltip_info->szText[0] = TEXT('\0'); | 159 tooltip_info->szText[0] = TEXT('\0'); |
| 160 tooltip_text_.clear(); | 160 tooltip_text_.clear(); |
| 161 tooltip_info->lpszText = NULL; | 161 tooltip_info->lpszText = NULL; |
| 162 clipped_text_.clear(); | 162 clipped_text_.clear(); |
| 163 if (last_tooltip_view_ != NULL) { | 163 if (last_tooltip_view_ != NULL) { |
| 164 tooltip_text_.clear(); | 164 tooltip_text_.clear(); |
| 165 // Mouse is over a View, ask the View for it's tooltip. | 165 // Mouse is over a View, ask the View for it's tooltip. |
| 166 CPoint view_loc(last_mouse_x_, last_mouse_y_); | 166 gfx::Point view_loc(last_mouse_x_, last_mouse_y_); |
| 167 View::ConvertPointToView(view_container_->GetRootView(), | 167 View::ConvertPointToView(view_container_->GetRootView(), |
| 168 last_tooltip_view_, &view_loc); | 168 last_tooltip_view_, &view_loc); |
| 169 if (last_tooltip_view_->GetTooltipText(view_loc.x, view_loc.y, | 169 if (last_tooltip_view_->GetTooltipText(view_loc.x(), view_loc.y(), |
| 170 &tooltip_text_) && | 170 &tooltip_text_) && |
| 171 !tooltip_text_.empty()) { | 171 !tooltip_text_.empty()) { |
| 172 // View has a valid tip, copy it into TOOLTIPINFO. | 172 // View has a valid tip, copy it into TOOLTIPINFO. |
| 173 clipped_text_ = tooltip_text_; | 173 clipped_text_ = tooltip_text_; |
| 174 TrimTooltipToFit(&clipped_text_, &tooltip_width_, &line_count_, | 174 TrimTooltipToFit(&clipped_text_, &tooltip_width_, &line_count_, |
| 175 last_mouse_x_, last_mouse_y_, tooltip_hwnd_); | 175 last_mouse_x_, last_mouse_y_, tooltip_hwnd_); |
| 176 tooltip_info->lpszText = const_cast<WCHAR*>(clipped_text_.c_str()); | 176 tooltip_info->lpszText = const_cast<WCHAR*>(clipped_text_.c_str()); |
| 177 } else { | 177 } else { |
| 178 tooltip_text_.clear(); | 178 tooltip_text_.clear(); |
| 179 } | 179 } |
| 180 } | 180 } |
| 181 *handled = true; | 181 *handled = true; |
| 182 return 0; | 182 return 0; |
| 183 } | 183 } |
| 184 case TTN_POP: | 184 case TTN_POP: |
| 185 tooltip_showing_ = false; | 185 tooltip_showing_ = false; |
| 186 *handled = true; | 186 *handled = true; |
| 187 return 0; | 187 return 0; |
| 188 case TTN_SHOW: { | 188 case TTN_SHOW: { |
| 189 *handled = true; | 189 *handled = true; |
| 190 tooltip_showing_ = true; | 190 tooltip_showing_ = true; |
| 191 // The tooltip is about to show, allow the view to position it | 191 // The tooltip is about to show, allow the view to position it |
| 192 CPoint text_origin; | 192 CPoint text_origin; |
| 193 if (tooltip_height_ == 0) | 193 if (tooltip_height_ == 0) |
| 194 tooltip_height_ = CalcTooltipHeight(); | 194 tooltip_height_ = CalcTooltipHeight(); |
| 195 CPoint view_loc(last_mouse_x_, last_mouse_y_); | 195 gfx::Point view_loc(last_mouse_x_, last_mouse_y_); |
| 196 View::ConvertPointToView(view_container_->GetRootView(), | 196 View::ConvertPointToView(view_container_->GetRootView(), |
| 197 last_tooltip_view_, &view_loc); | 197 last_tooltip_view_, &view_loc); |
| 198 if (last_tooltip_view_->GetTooltipTextOrigin( | 198 if (last_tooltip_view_->GetTooltipTextOrigin( |
| 199 view_loc.x, view_loc.y, &text_origin) && | 199 view_loc.x(), view_loc.y(), &text_origin) && |
| 200 SetTooltipPosition(text_origin.x, text_origin.y)) { | 200 SetTooltipPosition(text_origin.x, text_origin.y)) { |
| 201 // Return true, otherwise the rectangle we specified is ignored. | 201 // Return true, otherwise the rectangle we specified is ignored. |
| 202 return TRUE; | 202 return TRUE; |
| 203 } | 203 } |
| 204 return 0; | 204 return 0; |
| 205 } | 205 } |
| 206 default: | 206 default: |
| 207 // Fall through. | 207 // Fall through. |
| 208 break; | 208 break; |
| 209 } | 209 } |
| 210 } | 210 } |
| 211 return 0; | 211 return 0; |
| 212 } | 212 } |
| 213 | 213 |
| 214 bool TooltipManager::SetTooltipPosition(int text_x, int text_y) { | 214 bool TooltipManager::SetTooltipPosition(int text_x, int text_y) { |
| 215 // NOTE: this really only tests that the y location fits on screen, but that | 215 // NOTE: this really only tests that the y location fits on screen, but that |
| 216 // is good enough for our usage. | 216 // is good enough for our usage. |
| 217 | 217 |
| 218 // Calculate the bounds the tooltip will get. | 218 // Calculate the bounds the tooltip will get. |
| 219 CPoint view_loc(0, 0); | 219 gfx::Point view_loc; |
| 220 View::ConvertPointToScreen(last_tooltip_view_, &view_loc); | 220 View::ConvertPointToScreen(last_tooltip_view_, &view_loc); |
| 221 RECT bounds = { view_loc.x + text_x, | 221 RECT bounds = { view_loc.x() + text_x, |
| 222 view_loc.y + text_y, | 222 view_loc.y() + text_y, |
| 223 view_loc.x + text_x + tooltip_width_, | 223 view_loc.x() + text_x + tooltip_width_, |
| 224 view_loc.y + line_count_ * GetTooltipHeight() }; | 224 view_loc.y() + line_count_ * GetTooltipHeight() }; |
| 225 SendMessage(tooltip_hwnd_, TTM_ADJUSTRECT, TRUE, (LPARAM)&bounds); | 225 SendMessage(tooltip_hwnd_, TTM_ADJUSTRECT, TRUE, (LPARAM)&bounds); |
| 226 | 226 |
| 227 // Make sure the rectangle completely fits on the current monitor. If it | 227 // Make sure the rectangle completely fits on the current monitor. If it |
| 228 // doesn't, return false so that windows positions the tooltip at the | 228 // doesn't, return false so that windows positions the tooltip at the |
| 229 // default location. | 229 // default location. |
| 230 gfx::Rect monitor_bounds = | 230 gfx::Rect monitor_bounds = |
| 231 win_util::GetMonitorBoundsForRect(gfx::Rect(bounds.left,bounds.right, | 231 win_util::GetMonitorBoundsForRect(gfx::Rect(bounds.left,bounds.right, |
| 232 0, 0)); | 232 0, 0)); |
| 233 if (!monitor_bounds.Contains(gfx::Rect(bounds))) { | 233 if (!monitor_bounds.Contains(gfx::Rect(bounds))) { |
| 234 return false; | 234 return false; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 *max_width = 0; | 275 *max_width = 0; |
| 276 *line_count = 0; | 276 *line_count = 0; |
| 277 | 277 |
| 278 // Clamp the tooltip length to kMaxTooltipLength so that we don't | 278 // Clamp the tooltip length to kMaxTooltipLength so that we don't |
| 279 // accidentally DOS the user with a mega tooltip (since Windows doesn't seem | 279 // accidentally DOS the user with a mega tooltip (since Windows doesn't seem |
| 280 // to do this itself). | 280 // to do this itself). |
| 281 if (text->length() > kMaxTooltipLength) | 281 if (text->length() > kMaxTooltipLength) |
| 282 *text = text->substr(0, kMaxTooltipLength); | 282 *text = text->substr(0, kMaxTooltipLength); |
| 283 | 283 |
| 284 // Determine the available width for the tooltip. | 284 // Determine the available width for the tooltip. |
| 285 CPoint screen_loc(position_x, position_y); | 285 gfx::Point screen_loc(position_x, position_y); |
| 286 View::ConvertPointToScreen(view_container_->GetRootView(), &screen_loc); | 286 View::ConvertPointToScreen(view_container_->GetRootView(), &screen_loc); |
| 287 gfx::Rect monitor_bounds = | 287 gfx::Rect monitor_bounds = |
| 288 win_util::GetMonitorBoundsForRect(gfx::Rect(screen_loc.x, screen_loc.y, | 288 win_util::GetMonitorBoundsForRect(gfx::Rect(screen_loc.x(), screen_loc.y()
, |
| 289 0, 0)); | 289 0, 0)); |
| 290 RECT tooltip_margin; | 290 RECT tooltip_margin; |
| 291 SendMessage(window, TTM_GETMARGIN, 0, (LPARAM)&tooltip_margin); | 291 SendMessage(window, TTM_GETMARGIN, 0, (LPARAM)&tooltip_margin); |
| 292 const int available_width = monitor_bounds.width() - tooltip_margin.left - | 292 const int available_width = monitor_bounds.width() - tooltip_margin.left - |
| 293 tooltip_margin.right; | 293 tooltip_margin.right; |
| 294 if (available_width <= 0) | 294 if (available_width <= 0) |
| 295 return; | 295 return; |
| 296 | 296 |
| 297 // Split the string. | 297 // Split the string. |
| 298 std::vector<std::wstring> lines; | 298 std::vector<std::wstring> lines; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 321 RootView* root_view = view_container_->GetRootView(); | 321 RootView* root_view = view_container_->GetRootView(); |
| 322 View* view = root_view->GetViewForPoint(CPoint(x, y)); | 322 View* view = root_view->GetViewForPoint(CPoint(x, y)); |
| 323 if (view != last_tooltip_view_) { | 323 if (view != last_tooltip_view_) { |
| 324 // NOTE: This *must* be sent regardless of the visibility of the tooltip. | 324 // NOTE: This *must* be sent regardless of the visibility of the tooltip. |
| 325 // It triggers Windows to ask for the tooltip again. | 325 // It triggers Windows to ask for the tooltip again. |
| 326 SendMessage(tooltip_hwnd_, TTM_POP, 0, 0); | 326 SendMessage(tooltip_hwnd_, TTM_POP, 0, 0); |
| 327 last_tooltip_view_ = view; | 327 last_tooltip_view_ = view; |
| 328 } else if (last_tooltip_view_ != NULL) { | 328 } else if (last_tooltip_view_ != NULL) { |
| 329 // Tooltip is showing, and mouse is over the same view. See if the tooltip | 329 // Tooltip is showing, and mouse is over the same view. See if the tooltip |
| 330 // text has changed. | 330 // text has changed. |
| 331 CPoint view_point(x, y); | 331 gfx::Point view_point(x, y); |
| 332 View::ConvertPointToView(root_view, last_tooltip_view_, &view_point); | 332 View::ConvertPointToView(root_view, last_tooltip_view_, &view_point); |
| 333 std::wstring new_tooltip_text; | 333 std::wstring new_tooltip_text; |
| 334 if (last_tooltip_view_->GetTooltipText(view_point.x, view_point.y, | 334 if (last_tooltip_view_->GetTooltipText(view_point.x(), view_point.y(), |
| 335 &new_tooltip_text) && | 335 &new_tooltip_text) && |
| 336 new_tooltip_text != tooltip_text_) { | 336 new_tooltip_text != tooltip_text_) { |
| 337 // The text has changed, hide the popup. | 337 // The text has changed, hide the popup. |
| 338 SendMessage(tooltip_hwnd_, TTM_POP, 0, 0); | 338 SendMessage(tooltip_hwnd_, TTM_POP, 0, 0); |
| 339 if (!new_tooltip_text.empty() && tooltip_showing_) { | 339 if (!new_tooltip_text.empty() && tooltip_showing_) { |
| 340 // New text is valid, show the popup. | 340 // New text is valid, show the popup. |
| 341 SendMessage(tooltip_hwnd_, TTM_POPUP, 0, 0); | 341 SendMessage(tooltip_hwnd_, TTM_POPUP, 0, 0); |
| 342 } | 342 } |
| 343 } | 343 } |
| 344 } | 344 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 374 void TooltipManager::ShowKeyboardTooltip(View* focused_view) { | 374 void TooltipManager::ShowKeyboardTooltip(View* focused_view) { |
| 375 if (tooltip_showing_) { | 375 if (tooltip_showing_) { |
| 376 SendMessage(tooltip_hwnd_, TTM_POP, 0, 0); | 376 SendMessage(tooltip_hwnd_, TTM_POP, 0, 0); |
| 377 tooltip_text_.clear(); | 377 tooltip_text_.clear(); |
| 378 } | 378 } |
| 379 HideKeyboardTooltip(); | 379 HideKeyboardTooltip(); |
| 380 std::wstring tooltip_text; | 380 std::wstring tooltip_text; |
| 381 if (!focused_view->GetTooltipText(0, 0, &tooltip_text)) | 381 if (!focused_view->GetTooltipText(0, 0, &tooltip_text)) |
| 382 return; | 382 return; |
| 383 gfx::Rect focused_bounds = focused_view->bounds(); | 383 gfx::Rect focused_bounds = focused_view->bounds(); |
| 384 CPoint screen_point; | 384 gfx::Point screen_point; |
| 385 focused_view->ConvertPointToScreen(focused_view, &screen_point); | 385 focused_view->ConvertPointToScreen(focused_view, &screen_point); |
| 386 CPoint relative_point_coordinates; | 386 gfx::Point relative_point_coordinates; |
| 387 focused_view->ConvertPointToViewContainer(focused_view, | 387 focused_view->ConvertPointToViewContainer(focused_view, |
| 388 &relative_point_coordinates); | 388 &relative_point_coordinates); |
| 389 keyboard_tooltip_hwnd_ = CreateWindowEx( | 389 keyboard_tooltip_hwnd_ = CreateWindowEx( |
| 390 WS_EX_TRANSPARENT | l10n_util::GetExtendedTooltipStyles(), | 390 WS_EX_TRANSPARENT | l10n_util::GetExtendedTooltipStyles(), |
| 391 TOOLTIPS_CLASS, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL); | 391 TOOLTIPS_CLASS, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL); |
| 392 SendMessage(keyboard_tooltip_hwnd_, TTM_SETMAXTIPWIDTH, 0, | 392 SendMessage(keyboard_tooltip_hwnd_, TTM_SETMAXTIPWIDTH, 0, |
| 393 std::numeric_limits<short>::max()); | 393 std::numeric_limits<short>::max()); |
| 394 int tooltip_width; | 394 int tooltip_width; |
| 395 int line_count; | 395 int line_count; |
| 396 TrimTooltipToFit(&tooltip_text, &tooltip_width, &line_count, | 396 TrimTooltipToFit(&tooltip_text, &tooltip_width, &line_count, |
| 397 relative_point_coordinates.x, relative_point_coordinates.y, | 397 relative_point_coordinates.x(), |
| 398 keyboard_tooltip_hwnd_); | 398 relative_point_coordinates.y(), keyboard_tooltip_hwnd_); |
| 399 TOOLINFO keyboard_toolinfo; | 399 TOOLINFO keyboard_toolinfo; |
| 400 memset(&keyboard_toolinfo, 0, sizeof(keyboard_toolinfo)); | 400 memset(&keyboard_toolinfo, 0, sizeof(keyboard_toolinfo)); |
| 401 keyboard_toolinfo.cbSize = sizeof(keyboard_toolinfo); | 401 keyboard_toolinfo.cbSize = sizeof(keyboard_toolinfo); |
| 402 keyboard_toolinfo.hwnd = parent_; | 402 keyboard_toolinfo.hwnd = parent_; |
| 403 keyboard_toolinfo.uFlags = TTF_TRACK | TTF_TRANSPARENT | TTF_IDISHWND ; | 403 keyboard_toolinfo.uFlags = TTF_TRACK | TTF_TRANSPARENT | TTF_IDISHWND ; |
| 404 keyboard_toolinfo.lpszText = const_cast<WCHAR*>(tooltip_text.c_str()); | 404 keyboard_toolinfo.lpszText = const_cast<WCHAR*>(tooltip_text.c_str()); |
| 405 SendMessage(keyboard_tooltip_hwnd_, TTM_ADDTOOL, 0, | 405 SendMessage(keyboard_tooltip_hwnd_, TTM_ADDTOOL, 0, |
| 406 reinterpret_cast<LPARAM>(&keyboard_toolinfo)); | 406 reinterpret_cast<LPARAM>(&keyboard_toolinfo)); |
| 407 SendMessage(keyboard_tooltip_hwnd_, TTM_TRACKACTIVATE, TRUE, | 407 SendMessage(keyboard_tooltip_hwnd_, TTM_TRACKACTIVATE, TRUE, |
| 408 reinterpret_cast<LPARAM>(&keyboard_toolinfo)); | 408 reinterpret_cast<LPARAM>(&keyboard_toolinfo)); |
| 409 if (!tooltip_height_) | 409 if (!tooltip_height_) |
| 410 tooltip_height_ = CalcTooltipHeight(); | 410 tooltip_height_ = CalcTooltipHeight(); |
| 411 RECT rect_bounds = {screen_point.x, screen_point.y + focused_bounds.height(), | 411 RECT rect_bounds = {screen_point.x(), |
| 412 screen_point.x + tooltip_width, | 412 screen_point.y() + focused_bounds.height(), |
| 413 screen_point.y + focused_bounds.height() + | 413 screen_point.x() + tooltip_width, |
| 414 screen_point.y() + focused_bounds.height() + |
| 414 line_count * tooltip_height_ }; | 415 line_count * tooltip_height_ }; |
| 415 gfx::Rect monitor_bounds = | 416 gfx::Rect monitor_bounds = |
| 416 win_util::GetMonitorBoundsForRect(gfx::Rect(rect_bounds)); | 417 win_util::GetMonitorBoundsForRect(gfx::Rect(rect_bounds)); |
| 417 rect_bounds = gfx::Rect(rect_bounds).AdjustToFit(monitor_bounds).ToRECT(); | 418 rect_bounds = gfx::Rect(rect_bounds).AdjustToFit(monitor_bounds).ToRECT(); |
| 418 ::SetWindowPos(keyboard_tooltip_hwnd_, NULL, rect_bounds.left, | 419 ::SetWindowPos(keyboard_tooltip_hwnd_, NULL, rect_bounds.left, |
| 419 rect_bounds.top, 0, 0, | 420 rect_bounds.top, 0, 0, |
| 420 SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE); | 421 SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE); |
| 421 MessageLoop::current()->PostDelayedTask(FROM_HERE, | 422 MessageLoop::current()->PostDelayedTask(FROM_HERE, |
| 422 keyboard_tooltip_factory_.NewRunnableMethod( | 423 keyboard_tooltip_factory_.NewRunnableMethod( |
| 423 &TooltipManager::DestroyKeyboardTooltipWindow, keyboard_tooltip_hwnd_), | 424 &TooltipManager::DestroyKeyboardTooltipWindow, keyboard_tooltip_hwnd_), |
| 424 kDefaultTimeout); | 425 kDefaultTimeout); |
| 425 } | 426 } |
| 426 | 427 |
| 427 void TooltipManager::HideKeyboardTooltip() { | 428 void TooltipManager::HideKeyboardTooltip() { |
| 428 if (keyboard_tooltip_hwnd_ != NULL) { | 429 if (keyboard_tooltip_hwnd_ != NULL) { |
| 429 SendMessage(keyboard_tooltip_hwnd_, WM_CLOSE, 0, 0); | 430 SendMessage(keyboard_tooltip_hwnd_, WM_CLOSE, 0, 0); |
| 430 keyboard_tooltip_hwnd_ = NULL; | 431 keyboard_tooltip_hwnd_ = NULL; |
| 431 } | 432 } |
| 432 } | 433 } |
| 433 | 434 |
| 434 void TooltipManager::DestroyKeyboardTooltipWindow(HWND window_to_destroy) { | 435 void TooltipManager::DestroyKeyboardTooltipWindow(HWND window_to_destroy) { |
| 435 if (keyboard_tooltip_hwnd_ == window_to_destroy) | 436 if (keyboard_tooltip_hwnd_ == window_to_destroy) |
| 436 HideKeyboardTooltip(); | 437 HideKeyboardTooltip(); |
| 437 } | 438 } |
| 438 | 439 |
| 439 } // namespace ChromeViews | 440 } // namespace ChromeViews |
| OLD | NEW |