Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/views/find_bar_win.h" | |
| 6 | |
| 7 #include "app/slide_animation.h" | |
| 8 #include "chrome/browser/browser.h" | |
| 9 #include "chrome/browser/browser_process.h" | |
| 10 #include "chrome/browser/find_bar_controller.h" | |
| 11 #include "chrome/browser/renderer_host/render_view_host.h" | |
| 12 #include "chrome/browser/view_ids.h" | |
| 13 #include "chrome/browser/views/find_bar_view.h" | |
| 14 #include "chrome/browser/views/frame/browser_view.h" | |
| 15 #include "chrome/browser/tab_contents/tab_contents.h" | |
| 16 #include "chrome/browser/tab_contents/tab_contents_view.h" | |
| 17 #include "views/focus/external_focus_tracker.h" | |
| 18 #include "views/focus/view_storage.h" | |
| 19 #include "views/controls/scrollbar/native_scroll_bar.h" | |
| 20 #include "views/widget/root_view.h" | |
| 21 | |
| 22 #if defined(OS_WIN) | |
| 23 #include "views/widget/widget_win.h" | |
| 24 #else | |
| 25 #include "views/widget/widget_gtk.h" | |
| 26 #endif | |
| 27 | |
| 28 // static | |
| 29 bool FindBarWin::disable_animations_during_testing_ = false; | |
| 30 | |
| 31 // Host is the actual widget containing FindBarView. | |
| 32 #if defined(OS_WIN) | |
| 33 class FindBarWin::Host : public views::WidgetWin { | |
| 34 public: | |
| 35 explicit Host(FindBarWin* find_bar) : find_bar_(find_bar) { | |
| 36 // Don't let WidgetWin manage our lifetime. We want our lifetime to | |
| 37 // coincide with TabContents. | |
| 38 set_delete_on_destroy(false); | |
| 39 set_window_style(WS_CHILD | WS_CLIPCHILDREN); | |
| 40 set_window_ex_style(WS_EX_TOPMOST); | |
| 41 } | |
| 42 | |
| 43 void OnFinalMessage(HWND window) { | |
| 44 find_bar_->OnFinalMessage(); | |
| 45 } | |
| 46 | |
| 47 private: | |
| 48 FindBarWin* find_bar_; | |
| 49 | |
| 50 DISALLOW_COPY_AND_ASSIGN(Host); | |
| 51 }; | |
| 52 #else | |
| 53 class FindBarWin::Host : public views::WidgetGtk { | |
| 54 public: | |
| 55 explicit Host(FindBarWin* find_bar) | |
| 56 : WidgetGtk(TYPE_CHILD), | |
| 57 find_bar_(find_bar) { | |
| 58 // Don't let WidgetWin manage our lifetime. We want our lifetime to | |
| 59 // coincide with TabContents. | |
| 60 set_delete_on_destroy(false); | |
| 61 } | |
| 62 | |
| 63 void OnDestroy(GtkWidget* widget) { | |
| 64 find_bar_->OnFinalMessage(); | |
| 65 } | |
| 66 | |
| 67 private: | |
| 68 FindBarWin* find_bar_; | |
| 69 | |
| 70 DISALLOW_COPY_AND_ASSIGN(Host); | |
| 71 }; | |
| 72 #endif | |
| 73 | |
| 74 namespace browser { | |
| 75 | |
| 76 // Declared in browser_dialogs.h so others don't have to depend on our header. | |
| 77 FindBar* CreateFindBar(BrowserView* browser_view) { | |
| 78 return new FindBarWin(browser_view); | |
| 79 } | |
| 80 | |
| 81 } // namespace browser | |
| 82 | |
| 83 //////////////////////////////////////////////////////////////////////////////// | |
| 84 // FindBarWin, public: | |
| 85 | |
| 86 FindBarWin::FindBarWin(BrowserView* browser_view) | |
| 87 : browser_view_(browser_view), | |
| 88 find_dialog_animation_offset_(0), | |
| 89 esc_accel_target_registered_(false), | |
| 90 find_bar_controller_(NULL) { | |
| 91 view_ = new FindBarView(this); | |
| 92 | |
| 93 // Initialize the host. | |
| 94 host_.reset(new Host(this)); | |
| 95 host_->Init(browser_view->GetWidget()->GetNativeView(), gfx::Rect()); | |
| 96 host_->SetContentsView(view_); | |
| 97 | |
| 98 // Start listening to focus changes, so we can register and unregister our | |
| 99 // own handler for Escape. | |
| 100 focus_manager_ = | |
| 101 views::FocusManager::GetFocusManagerForNativeView(host_->GetNativeView()); | |
| 102 if (focus_manager_) { | |
| 103 focus_manager_->AddFocusChangeListener(this); | |
| 104 | |
| 105 // Stores the currently focused view, and tracks focus changes so that we | |
| 106 // can restore focus when the find box is closed. | |
| 107 focus_tracker_.reset(new views::ExternalFocusTracker(view_, | |
| 108 focus_manager_)); | |
| 109 } else { | |
| 110 // In some cases (see bug http://crbug.com/17056) it seems we may not have | |
| 111 // a focus manager. Please reopen the bug if you hit this. | |
| 112 NOTREACHED(); | |
| 113 } | |
| 114 | |
| 115 // Start the process of animating the opening of the window. | |
| 116 animation_.reset(new SlideAnimation(this)); | |
| 117 } | |
| 118 | |
| 119 FindBarWin::~FindBarWin() { | |
| 120 } | |
| 121 | |
| 122 // TODO(brettw) this should not be so complicated. The view should really be in | |
| 123 // charge of these regions. CustomFrameWindow will do this for us. It will also | |
| 124 // let us set a path for the window region which will avoid some logic here. | |
| 125 void FindBarWin::UpdateWindowEdges(const gfx::Rect& new_pos) { | |
| 126 #if defined(OS_WIN) | |
| 127 // |w| is used to make it easier to create the part of the polygon that curves | |
| 128 // the right side of the Find window. It essentially keeps track of the | |
| 129 // x-pixel position of the right-most background image inside the view. | |
| 130 // TODO(finnur): Let the view tell us how to draw the curves or convert | |
| 131 // this to a CustomFrameWindow. | |
| 132 int w = new_pos.width() - 6; // -6 positions us at the left edge of the | |
| 133 // rightmost background image of the view. | |
| 134 | |
| 135 // This polygon array represents the outline of the background image for the | |
| 136 // dialog. Basically, it encompasses only the visible pixels of the | |
| 137 // concatenated find_dlg_LMR_bg images (where LMR = [left | middle | right]). | |
| 138 static const POINT polygon[] = { | |
| 139 {0, 0}, {0, 1}, {2, 3}, {2, 29}, {4, 31}, | |
| 140 {4, 32}, {w+0, 32}, | |
| 141 {w+0, 31}, {w+1, 31}, {w+3, 29}, {w+3, 3}, {w+6, 0} | |
| 142 }; | |
| 143 | |
| 144 // Find the largest x and y value in the polygon. | |
| 145 int max_x = 0, max_y = 0; | |
| 146 for (int i = 0; i < arraysize(polygon); i++) { | |
| 147 max_x = std::max(max_x, static_cast<int>(polygon[i].x)); | |
| 148 max_y = std::max(max_y, static_cast<int>(polygon[i].y)); | |
| 149 } | |
| 150 | |
| 151 // We then create the polygon and use SetWindowRgn to force the window to draw | |
| 152 // only within that area. This region may get reduced in size below. | |
| 153 HRGN region = CreatePolygonRgn(polygon, arraysize(polygon), ALTERNATE); | |
| 154 | |
| 155 // Are we animating? | |
| 156 if (find_dialog_animation_offset_ > 0) { | |
| 157 // The animation happens in two steps: First, we clip the window and then in | |
| 158 // GetDialogPosition we offset the window position so that it still looks | |
| 159 // attached to the toolbar as it grows. We clip the window by creating a | |
| 160 // rectangle region (that gradually increases as the animation progresses) | |
| 161 // and find the intersection between the two regions using CombineRgn. | |
| 162 | |
| 163 // |y| shrinks as the animation progresses from the height of the view down | |
| 164 // to 0 (and reverses when closing). | |
| 165 int y = find_dialog_animation_offset_; | |
| 166 // |y| shrinking means the animation (visible) region gets larger. In other | |
| 167 // words: the rectangle grows upward (when the dialog is opening). | |
| 168 HRGN animation_region = CreateRectRgn(0, y, max_x, max_y); | |
| 169 // |region| will contain the intersected parts after calling this function: | |
| 170 CombineRgn(region, animation_region, region, RGN_AND); | |
| 171 DeleteObject(animation_region); | |
| 172 | |
| 173 // Next, we need to increase the region a little bit to account for the | |
| 174 // curved edges that the view will draw to make it look like grows out of | |
| 175 // the toolbar. | |
| 176 POINT left_curve[] = { | |
| 177 {0, y+0}, {0, y+1}, {2, y+3}, {2, y+0}, {0, y+0} | |
| 178 }; | |
| 179 POINT right_curve[] = { | |
| 180 {w+3, y+3}, {w+6, y+0}, {w+3, y+0}, {w+3, y+3} | |
| 181 }; | |
| 182 | |
| 183 // Combine the region for the curve on the left with our main region. | |
| 184 HRGN r = CreatePolygonRgn(left_curve, arraysize(left_curve), ALTERNATE); | |
| 185 CombineRgn(region, r, region, RGN_OR); | |
| 186 DeleteObject(r); | |
| 187 | |
| 188 // Combine the region for the curve on the right with our main region. | |
| 189 r = CreatePolygonRgn(right_curve, arraysize(right_curve), ALTERNATE); | |
| 190 CombineRgn(region, r, region, RGN_OR); | |
| 191 DeleteObject(r); | |
| 192 } | |
| 193 | |
| 194 // Now see if we need to truncate the region because parts of it obscures | |
| 195 // the main window border. | |
| 196 gfx::Rect dialog_bounds; | |
| 197 GetDialogBounds(&dialog_bounds); | |
| 198 | |
| 199 // Calculate how much our current position overlaps our boundaries. If we | |
| 200 // overlap, it means we have too little space to draw the whole dialog and | |
| 201 // we allow overwriting the scrollbar before we start truncating our dialog. | |
| 202 // | |
| 203 // TODO(brettw) this constant is evil. This is the amount of room we've added | |
| 204 // to the window size, when we set the region, it can change the size. | |
| 205 static const int kAddedWidth = 7; | |
| 206 int difference = (new_pos.right() - kAddedWidth) - | |
| 207 dialog_bounds.width() - | |
| 208 views::NativeScrollBar::GetVerticalScrollBarWidth() + | |
| 209 1; | |
| 210 if (difference > 0) { | |
| 211 POINT exclude[4] = {0}; | |
| 212 exclude[0].x = max_x - difference; // Top left corner. | |
| 213 exclude[0].y = 0; | |
| 214 | |
| 215 exclude[1].x = max_x; // Top right corner. | |
| 216 exclude[1].y = 0; | |
| 217 | |
| 218 exclude[2].x = max_x; // Bottom right corner. | |
| 219 exclude[2].y = max_y; | |
| 220 | |
| 221 exclude[3].x = max_x - difference; // Bottom left corner. | |
| 222 exclude[3].y = max_y; | |
| 223 | |
| 224 // Subtract this region from the original region. | |
| 225 HRGN exclude_rgn = CreatePolygonRgn(exclude, arraysize(exclude), ALTERNATE); | |
| 226 int result = CombineRgn(region, region, exclude_rgn, RGN_DIFF); | |
| 227 DeleteObject(exclude_rgn); | |
| 228 } | |
| 229 | |
| 230 // The system now owns the region, so we do not delete it. | |
| 231 host_->SetWindowRgn(region, TRUE); // TRUE = Redraw. | |
| 232 #endif | |
| 233 } | |
| 234 | |
| 235 void FindBarWin::Show() { | |
| 236 if (disable_animations_during_testing_) { | |
| 237 animation_->Reset(1); | |
| 238 MoveWindowIfNecessary(gfx::Rect(), true); | |
| 239 } else { | |
| 240 animation_->Reset(); | |
| 241 animation_->Show(); | |
| 242 } | |
| 243 } | |
| 244 | |
| 245 void FindBarWin::SetFocusAndSelection() { | |
| 246 view_->SetFocusAndSelection(); | |
| 247 } | |
| 248 | |
| 249 bool FindBarWin::IsAnimating() { | |
| 250 return animation_->IsAnimating(); | |
| 251 } | |
| 252 | |
| 253 void FindBarWin::Hide(bool animate) { | |
| 254 if (animate && !disable_animations_during_testing_) { | |
| 255 animation_->Reset(1.0); | |
| 256 animation_->Hide(); | |
| 257 } else { | |
| 258 host_->Hide(); | |
| 259 } | |
| 260 } | |
| 261 | |
| 262 void FindBarWin::ClearResults(const FindNotificationDetails& results) { | |
| 263 view_->UpdateForResult(results, string16()); | |
| 264 } | |
| 265 | |
| 266 void FindBarWin::StopAnimation() { | |
| 267 animation_->End(); | |
| 268 } | |
| 269 | |
| 270 void FindBarWin::SetFindText(const string16& find_text) { | |
| 271 view_->SetFindText(find_text); | |
| 272 } | |
| 273 | |
| 274 bool FindBarWin::IsFindBarVisible() { | |
| 275 return host_->IsVisible(); | |
| 276 } | |
| 277 | |
| 278 void FindBarWin::MoveWindowIfNecessary(const gfx::Rect& selection_rect, | |
| 279 bool no_redraw) { | |
| 280 // We only move the window if one is active for the current TabContents. If we | |
| 281 // don't check this, then SetDialogPosition below will end up making the Find | |
| 282 // Bar visible. | |
| 283 if (!find_bar_controller_->tab_contents() || | |
| 284 !find_bar_controller_->tab_contents()->find_ui_active()) { | |
| 285 return; | |
| 286 } | |
| 287 | |
| 288 gfx::Rect new_pos = GetDialogPosition(selection_rect); | |
| 289 SetDialogPosition(new_pos, no_redraw); | |
| 290 | |
| 291 // May need to redraw our frame to accommodate bookmark bar styles. | |
| 292 view_->SchedulePaint(); | |
| 293 } | |
| 294 | |
| 295 #if defined(OS_WIN) | |
| 296 bool FindBarWin::MaybeForwardKeystrokeToWebpage( | |
| 297 UINT message, TCHAR key, UINT flags) { | |
| 298 // We specifically ignore WM_CHAR. See http://crbug.com/10509. | |
| 299 if (message != WM_KEYDOWN && message != WM_KEYUP) | |
| 300 return false; | |
|
Finnur
2009/09/21 17:11:47
Dave, this code got dropped when this was moved to
| |
| 301 | |
| 302 switch (key) { | |
| 303 case VK_HOME: | |
| 304 case VK_END: | |
| 305 // Ctrl+Home and Ctrl+End should be forwarded to the page. | |
| 306 if (GetKeyState(VK_CONTROL) >= 0) | |
| 307 return false; // Ctrl not pressed: Abort. Otherwise fall through. | |
| 308 case VK_UP: | |
| 309 case VK_DOWN: | |
| 310 case VK_PRIOR: // Page up | |
| 311 case VK_NEXT: // Page down | |
| 312 break; // The keys above are the ones we want to forward to the page. | |
| 313 default: | |
| 314 return false; | |
| 315 } | |
| 316 | |
| 317 TabContents* contents = find_bar_controller_->tab_contents(); | |
| 318 if (!contents) | |
| 319 return false; | |
| 320 | |
| 321 RenderViewHost* render_view_host = contents->render_view_host(); | |
| 322 | |
| 323 // Make sure we don't have a text field element interfering with keyboard | |
| 324 // input. Otherwise Up and Down arrow key strokes get eaten. "Nom Nom Nom". | |
| 325 render_view_host->ClearFocusedNode(); | |
| 326 | |
| 327 HWND hwnd = contents->GetContentNativeView(); | |
| 328 render_view_host->ForwardKeyboardEvent( | |
| 329 NativeWebKeyboardEvent(hwnd, message, key, 0)); | |
| 330 return true; | |
| 331 } | |
| 332 #endif | |
| 333 | |
| 334 void FindBarWin::OnFinalMessage() { | |
| 335 // TODO(beng): Destroy the RootView before destroying the Focus Manager will | |
| 336 // allow us to remove this method. | |
| 337 | |
| 338 // We are exiting, so we no longer need to monitor focus changes. | |
| 339 focus_manager_->RemoveFocusChangeListener(this); | |
| 340 | |
| 341 // Destroy the focus tracker now, otherwise by the time we're destroyed the | |
| 342 // focus manager the focus tracker is referencing may have already been | |
| 343 // destroyed resulting in the focus tracker trying to reference a deleted | |
| 344 // focus manager. | |
| 345 focus_tracker_.reset(NULL); | |
| 346 }; | |
| 347 | |
| 348 bool FindBarWin::IsVisible() { | |
| 349 return host_->IsVisible(); | |
| 350 } | |
| 351 | |
| 352 //////////////////////////////////////////////////////////////////////////////// | |
| 353 // FindBarWin, views::FocusChangeListener implementation: | |
| 354 | |
| 355 void FindBarWin::FocusWillChange(views::View* focused_before, | |
| 356 views::View* focused_now) { | |
| 357 // First we need to determine if one or both of the views passed in are child | |
| 358 // views of our view. | |
| 359 bool our_view_before = focused_before && view_->IsParentOf(focused_before); | |
| 360 bool our_view_now = focused_now && view_->IsParentOf(focused_now); | |
| 361 | |
| 362 // When both our_view_before and our_view_now are false, it means focus is | |
| 363 // changing hands elsewhere in the application (and we shouldn't do anything). | |
| 364 // Similarly, when both are true, focus is changing hands within the Find | |
| 365 // window (and again, we should not do anything). We therefore only need to | |
| 366 // look at when we gain initial focus and when we loose it. | |
| 367 if (!our_view_before && our_view_now) { | |
| 368 // We are gaining focus from outside the Find window so we must register | |
| 369 // a handler for Escape. | |
| 370 RegisterEscAccelerator(); | |
| 371 } else if (our_view_before && !our_view_now) { | |
| 372 // We are losing focus to something outside our window so we restore the | |
| 373 // original handler for Escape. | |
| 374 UnregisterEscAccelerator(); | |
| 375 } | |
| 376 } | |
| 377 | |
| 378 //////////////////////////////////////////////////////////////////////////////// | |
| 379 // FindBarWin, views::AcceleratorTarget implementation: | |
| 380 | |
| 381 bool FindBarWin::AcceleratorPressed(const views::Accelerator& accelerator) { | |
| 382 #if defined(OS_WIN) | |
| 383 DCHECK(accelerator.GetKeyCode() == VK_ESCAPE); // We only expect Escape key. | |
| 384 #endif | |
| 385 // This will end the Find session and hide the window, causing it to loose | |
| 386 // focus and in the process unregister us as the handler for the Escape | |
| 387 // accelerator through the FocusWillChange event. | |
| 388 find_bar_controller_->EndFindSession(); | |
| 389 | |
| 390 return true; | |
| 391 } | |
| 392 | |
| 393 //////////////////////////////////////////////////////////////////////////////// | |
| 394 // FindBarWin, AnimationDelegate implementation: | |
| 395 | |
| 396 void FindBarWin::AnimationProgressed(const Animation* animation) { | |
| 397 // First, we calculate how many pixels to slide the window. | |
| 398 gfx::Size pref_size = view_->GetPreferredSize(); | |
| 399 find_dialog_animation_offset_ = | |
| 400 static_cast<int>((1.0 - animation_->GetCurrentValue()) * | |
| 401 pref_size.height()); | |
| 402 | |
| 403 // This call makes sure it appears in the right location, the size and shape | |
| 404 // is correct and that it slides in the right direction. | |
| 405 gfx::Rect find_dlg_rect = GetDialogPosition(gfx::Rect()); | |
| 406 SetDialogPosition(find_dlg_rect, false); | |
| 407 | |
| 408 // Let the view know if we are animating, and at which offset to draw the | |
| 409 // edges. | |
| 410 view_->animation_offset(find_dialog_animation_offset_); | |
| 411 view_->SchedulePaint(); | |
| 412 } | |
| 413 | |
| 414 void FindBarWin::AnimationEnded(const Animation* animation) { | |
| 415 // Place the find bar in its fully opened state. | |
| 416 find_dialog_animation_offset_ = 0; | |
| 417 | |
| 418 if (!animation_->IsShowing()) { | |
| 419 // Animation has finished closing. | |
| 420 host_->Hide(); | |
| 421 } else { | |
| 422 // Animation has finished opening. | |
| 423 } | |
| 424 } | |
| 425 | |
| 426 void FindBarWin::GetThemePosition(gfx::Rect* bounds) { | |
| 427 *bounds = GetDialogPosition(gfx::Rect()); | |
| 428 gfx::Rect toolbar_bounds = browser_view_->GetToolbarBounds(); | |
| 429 gfx::Rect tab_strip_bounds = browser_view_->GetTabStripBounds(); | |
| 430 bounds->Offset(-toolbar_bounds.x(), -tab_strip_bounds.y()); | |
| 431 } | |
| 432 | |
| 433 //////////////////////////////////////////////////////////////////////////////// | |
| 434 // FindBarTesting implementation: | |
| 435 | |
| 436 bool FindBarWin::GetFindBarWindowInfo(gfx::Point* position, | |
| 437 bool* fully_visible) { | |
| 438 if (!find_bar_controller_ || | |
| 439 #if defined(OS_WIN) | |
| 440 !::IsWindow(host_->GetNativeView())) { | |
| 441 #else | |
| 442 false) { | |
| 443 // TODO(sky): figure out linux side. | |
| 444 #endif | |
| 445 *position = gfx::Point(); | |
| 446 *fully_visible = false; | |
| 447 return false; | |
| 448 } | |
| 449 | |
| 450 gfx::Rect window_rect; | |
| 451 host_->GetBounds(&window_rect, true); | |
| 452 *position = window_rect.origin(); | |
| 453 *fully_visible = host_->IsVisible() && !IsAnimating(); | |
| 454 return true; | |
| 455 } | |
| 456 | |
| 457 void FindBarWin::GetDialogBounds(gfx::Rect* bounds) { | |
| 458 DCHECK(bounds); | |
| 459 // The BrowserView does Layout for the components that we care about | |
| 460 // positioning relative to, so we ask it to tell us where we should go. | |
| 461 *bounds = browser_view_->GetFindBarBoundingBox(); | |
| 462 } | |
| 463 | |
| 464 gfx::Rect FindBarWin::GetDialogPosition(gfx::Rect avoid_overlapping_rect) { | |
| 465 // Find the area we have to work with (after accounting for scrollbars, etc). | |
| 466 gfx::Rect dialog_bounds; | |
| 467 GetDialogBounds(&dialog_bounds); | |
| 468 if (dialog_bounds.IsEmpty()) | |
| 469 return gfx::Rect(); | |
| 470 | |
| 471 // Ask the view how large an area it needs to draw on. | |
| 472 gfx::Size prefsize = view_->GetPreferredSize(); | |
| 473 | |
| 474 // Place the view in the top right corner of the dialog boundaries (top left | |
| 475 // for RTL languages). | |
| 476 gfx::Rect view_location; | |
| 477 int x = view_->UILayoutIsRightToLeft() ? | |
| 478 dialog_bounds.x() : dialog_bounds.width() - prefsize.width(); | |
| 479 int y = dialog_bounds.y(); | |
| 480 view_location.SetRect(x, y, prefsize.width(), prefsize.height()); | |
| 481 | |
| 482 // When we get Find results back, we specify a selection rect, which we | |
| 483 // should strive to avoid overlapping. But first, we need to offset the | |
| 484 // selection rect (if one was provided). | |
| 485 if (!avoid_overlapping_rect.IsEmpty()) { | |
| 486 // For comparison (with the Intersects function below) we need to account | |
| 487 // for the fact that we draw the Find dialog relative to the window, | |
| 488 // whereas the selection rect is relative to the page. | |
| 489 #if defined(OS_WIN) | |
| 490 RECT frame_rect = {0}, webcontents_rect = {0}; | |
| 491 ::GetWindowRect(host_->GetParent(), &frame_rect); | |
| 492 ::GetWindowRect( | |
| 493 find_bar_controller_->tab_contents()->view()->GetNativeView(), | |
| 494 &webcontents_rect); | |
| 495 avoid_overlapping_rect.Offset(0, webcontents_rect.top - frame_rect.top); | |
| 496 #else | |
| 497 NOTIMPLEMENTED(); | |
| 498 #endif | |
| 499 } | |
| 500 | |
| 501 gfx::Rect new_pos = FindBarController::GetLocationForFindbarView( | |
| 502 view_location, dialog_bounds, avoid_overlapping_rect); | |
| 503 | |
| 504 // While we are animating, the Find window will grow bottoms up so we need to | |
| 505 // re-position the dialog so that it appears to grow out of the toolbar. | |
| 506 if (find_dialog_animation_offset_ > 0) | |
| 507 new_pos.Offset(0, std::min(0, -find_dialog_animation_offset_)); | |
| 508 | |
| 509 return new_pos; | |
| 510 } | |
| 511 | |
| 512 void FindBarWin::SetDialogPosition(const gfx::Rect& new_pos, bool no_redraw) { | |
| 513 if (new_pos.IsEmpty()) | |
| 514 return; | |
| 515 | |
| 516 // Make sure the window edges are clipped to just the visible region. We need | |
| 517 // to do this before changing position, so that when we animate the closure | |
| 518 // of it it doesn't look like the window crumbles into the toolbar. | |
| 519 UpdateWindowEdges(new_pos); | |
| 520 | |
| 521 #if defined(OS_WIN) | |
| 522 gfx::Rect window_rect; | |
| 523 host_->GetBounds(&window_rect, true); | |
| 524 DWORD swp_flags = SWP_NOOWNERZORDER; | |
| 525 if (!window_rect.IsEmpty()) | |
| 526 swp_flags |= SWP_NOSIZE; | |
| 527 if (no_redraw) | |
| 528 swp_flags |= SWP_NOREDRAW; | |
| 529 if (!host_->IsVisible()) | |
| 530 swp_flags |= SWP_SHOWWINDOW; | |
| 531 | |
| 532 ::SetWindowPos(host_->GetNativeView(), HWND_TOP, new_pos.x(), new_pos.y(), | |
| 533 new_pos.width(), new_pos.height(), swp_flags); | |
| 534 #else | |
| 535 host_->SetBounds(new_pos); | |
| 536 #endif | |
| 537 } | |
| 538 | |
| 539 void FindBarWin::RestoreSavedFocus() { | |
| 540 if (focus_tracker_.get() == NULL) { | |
| 541 // TODO(brettw) Focus() should be on TabContentsView. | |
| 542 find_bar_controller_->tab_contents()->Focus(); | |
| 543 } else { | |
| 544 focus_tracker_->FocusLastFocusedExternalView(); | |
| 545 } | |
| 546 } | |
| 547 | |
| 548 FindBarTesting* FindBarWin::GetFindBarTesting() { | |
| 549 return this; | |
| 550 } | |
| 551 | |
| 552 void FindBarWin::RegisterEscAccelerator() { | |
| 553 #if defined(OS_WIN) | |
| 554 DCHECK(!esc_accel_target_registered_); | |
| 555 views::Accelerator escape(VK_ESCAPE, false, false, false); | |
| 556 focus_manager_->RegisterAccelerator(escape, this); | |
| 557 esc_accel_target_registered_ = true; | |
| 558 #else | |
| 559 NOTIMPLEMENTED(); | |
| 560 #endif | |
| 561 } | |
| 562 | |
| 563 void FindBarWin::UnregisterEscAccelerator() { | |
| 564 #if defined(OS_WIN) | |
| 565 DCHECK(esc_accel_target_registered_); | |
| 566 views::Accelerator escape(VK_ESCAPE, false, false, false); | |
| 567 focus_manager_->UnregisterAccelerator(escape, this); | |
| 568 esc_accel_target_registered_ = false; | |
| 569 #else | |
| 570 NOTIMPLEMENTED(); | |
| 571 #endif | |
| 572 } | |
| 573 | |
| 574 void FindBarWin::UpdateUIForFindResult(const FindNotificationDetails& result, | |
| 575 const string16& find_text) { | |
| 576 view_->UpdateForResult(result, find_text); | |
| 577 | |
| 578 // We now need to check if the window is obscuring the search results. | |
| 579 if (!result.selection_rect().IsEmpty()) | |
| 580 MoveWindowIfNecessary(result.selection_rect(), false); | |
| 581 | |
| 582 // Once we find a match we no longer want to keep track of what had | |
| 583 // focus. EndFindSession will then set the focus to the page content. | |
| 584 if (result.number_of_matches() > 0) | |
| 585 focus_tracker_.reset(NULL); | |
| 586 } | |
| 587 | |
| 588 void FindBarWin::AudibleAlert() { | |
| 589 #if defined(OS_WIN) | |
| 590 MessageBeep(MB_OK); | |
| 591 #else | |
| 592 NOTIMPLEMENTED(); | |
| 593 #endif | |
| 594 } | |
| OLD | NEW |