Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 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 | 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 "chrome/browser/views/find_bar_host.h" | 5 #include "chrome/browser/views/find_bar_host.h" |
| 6 | 6 |
| 7 #include "app/gfx/path.h" | |
| 7 #include "app/slide_animation.h" | 8 #include "app/slide_animation.h" |
| 8 #include "base/keyboard_codes.h" | 9 #include "base/keyboard_codes.h" |
| 10 #include "base/scoped_handle.h" | |
| 9 #include "chrome/browser/browser.h" | 11 #include "chrome/browser/browser.h" |
| 10 #include "chrome/browser/browser_process.h" | 12 #include "chrome/browser/browser_process.h" |
| 11 #include "chrome/browser/find_bar_controller.h" | 13 #include "chrome/browser/find_bar_controller.h" |
| 12 #include "chrome/browser/renderer_host/render_view_host.h" | 14 #include "chrome/browser/renderer_host/render_view_host.h" |
| 13 #include "chrome/browser/view_ids.h" | 15 #include "chrome/browser/view_ids.h" |
| 14 #include "chrome/browser/views/find_bar_view.h" | 16 #include "chrome/browser/views/find_bar_view.h" |
| 15 #include "chrome/browser/views/frame/browser_view.h" | 17 #include "chrome/browser/views/frame/browser_view.h" |
| 16 #include "chrome/browser/tab_contents/tab_contents.h" | 18 #include "chrome/browser/tab_contents/tab_contents.h" |
| 17 #include "chrome/browser/tab_contents/tab_contents_view.h" | 19 #include "chrome/browser/tab_contents/tab_contents_view.h" |
| 18 #include "views/focus/external_focus_tracker.h" | 20 #include "views/focus/external_focus_tracker.h" |
| 19 #include "views/focus/view_storage.h" | 21 #include "views/focus/view_storage.h" |
| 20 #include "views/controls/scrollbar/native_scroll_bar.h" | 22 #include "views/controls/scrollbar/native_scroll_bar.h" |
| 21 #include "views/widget/root_view.h" | 23 #include "views/widget/root_view.h" |
| 22 | 24 |
| 23 // static | 25 // static |
| 24 bool FindBarHost::disable_animations_during_testing_ = false; | 26 bool FindBarHost::disable_animations_during_testing_ = false; |
| 25 | 27 |
| 28 using gfx::Path; | |
| 29 | |
| 26 namespace browser { | 30 namespace browser { |
| 27 | 31 |
| 28 // Declared in browser_dialogs.h so others don't have to depend on our header. | 32 // Declared in browser_dialogs.h so others don't have to depend on our header. |
| 29 FindBar* CreateFindBar(BrowserView* browser_view) { | 33 FindBar* CreateFindBar(BrowserView* browser_view) { |
| 30 return new FindBarHost(browser_view); | 34 return new FindBarHost(browser_view); |
| 31 } | 35 } |
| 32 | 36 |
| 33 } // namespace browser | 37 } // namespace browser |
| 34 | 38 |
| 35 //////////////////////////////////////////////////////////////////////////////// | 39 //////////////////////////////////////////////////////////////////////////////// |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 54 if (focus_manager_) { | 58 if (focus_manager_) { |
| 55 focus_manager_->AddFocusChangeListener(this); | 59 focus_manager_->AddFocusChangeListener(this); |
| 56 } else { | 60 } else { |
| 57 // In some cases (see bug http://crbug.com/17056) it seems we may not have | 61 // In some cases (see bug http://crbug.com/17056) it seems we may not have |
| 58 // a focus manager. Please reopen the bug if you hit this. | 62 // a focus manager. Please reopen the bug if you hit this. |
| 59 NOTREACHED(); | 63 NOTREACHED(); |
| 60 } | 64 } |
| 61 | 65 |
| 62 // Start the process of animating the opening of the window. | 66 // Start the process of animating the opening of the window. |
| 63 animation_.reset(new SlideAnimation(this)); | 67 animation_.reset(new SlideAnimation(this)); |
| 68 | |
| 69 | |
| 70 animation_->SetSlideDuration(5000); | |
| 64 } | 71 } |
| 65 | 72 |
| 66 FindBarHost::~FindBarHost() { | 73 FindBarHost::~FindBarHost() { |
| 67 focus_manager_->RemoveFocusChangeListener(this); | 74 focus_manager_->RemoveFocusChangeListener(this); |
| 68 focus_tracker_.reset(NULL); | 75 focus_tracker_.reset(NULL); |
| 69 } | 76 } |
| 70 | 77 |
| 71 void FindBarHost::Show() { | 78 void FindBarHost::Show() { |
| 72 // Stores the currently focused view, and tracks focus changes so that we can | 79 // Stores the currently focused view, and tracks focus changes so that we can |
| 73 // restore focus when the find box is closed. | 80 // restore focus when the find box is closed. |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 245 return true; | 252 return true; |
| 246 } | 253 } |
| 247 | 254 |
| 248 void FindBarHost::GetDialogBounds(gfx::Rect* bounds) { | 255 void FindBarHost::GetDialogBounds(gfx::Rect* bounds) { |
| 249 DCHECK(bounds); | 256 DCHECK(bounds); |
| 250 // The BrowserView does Layout for the components that we care about | 257 // The BrowserView does Layout for the components that we care about |
| 251 // positioning relative to, so we ask it to tell us where we should go. | 258 // positioning relative to, so we ask it to tell us where we should go. |
| 252 *bounds = browser_view_->GetFindBarBoundingBox(); | 259 *bounds = browser_view_->GetFindBarBoundingBox(); |
| 253 } | 260 } |
| 254 | 261 |
| 262 // TODO(brettw) this should not be so complicated. The view should really be in | |
|
Ben Goodger (Google)
2009/11/03 22:58:54
You can get rid of this comment now.
| |
| 263 // charge of these regions. CustomFrameWindow will do this for us. It will also | |
| 264 // let us set a path for the window region which will avoid some logic here. | |
| 265 void FindBarHost::UpdateWindowEdges(const gfx::Rect& new_pos) { | |
| 266 // |w| is used to make it easier to create the part of the polygon that curves | |
| 267 // the right side of the Find window. It essentially keeps track of the | |
| 268 // x-pixel position of the right-most background image inside the view. | |
| 269 // TODO(finnur): Let the view tell us how to draw the curves or convert | |
| 270 // this to a CustomFrameWindow. | |
| 271 int w = new_pos.width() - 6; // -6 positions us at the left edge of the | |
| 272 // rightmost background image of the view. | |
| 273 | |
| 274 // This polygon array represents the outline of the background image for the | |
| 275 // dialog. Basically, it encompasses only the visible pixels of the | |
| 276 // concatenated find_dlg_LMR_bg images (where LMR = [left | middle | right]). | |
| 277 static const Path::Point polygon[] = { | |
| 278 {0, 0}, {0, 1}, {2, 3}, {2, 29}, {4, 31}, | |
| 279 {4, 32}, {w+0, 32}, | |
| 280 {w+0, 31}, {w+1, 31}, {w+3, 29}, {w+3, 3}, {w+6, 0} | |
| 281 }; | |
| 282 | |
| 283 // Find the largest x and y value in the polygon. | |
| 284 int max_x = 0, max_y = 0; | |
| 285 for (size_t i = 0; i < arraysize(polygon); i++) { | |
| 286 max_x = std::max(max_x, static_cast<int>(polygon[i].x)); | |
| 287 max_y = std::max(max_y, static_cast<int>(polygon[i].y)); | |
| 288 } | |
| 289 | |
| 290 // We then create the polygon and use SetWindowRgn to force the window to draw | |
| 291 // only within that area. This region may get reduced in size below. | |
| 292 Path path(polygon, arraysize(polygon)); | |
| 293 ScopedRegion region(path.CreateNativeRegion()); | |
| 294 | |
| 295 // Are we animating? | |
| 296 if (find_dialog_animation_offset_ > 0) { | |
| 297 // The animation happens in two steps: First, we clip the window and then in | |
| 298 // GetDialogPosition we offset the window position so that it still looks | |
| 299 // attached to the toolbar as it grows. We clip the window by creating a | |
| 300 // rectangle region (that gradually increases as the animation progresses) | |
| 301 // and find the intersection between the two regions using CombineRgn. | |
| 302 | |
| 303 // |y| shrinks as the animation progresses from the height of the view down | |
| 304 // to 0 (and reverses when closing). | |
| 305 int y = find_dialog_animation_offset_; | |
| 306 // |y| shrinking means the animation (visible) region gets larger. In other | |
| 307 // words: the rectangle grows upward (when the dialog is opening). | |
| 308 Path animation_path; | |
| 309 SkRect animation_rect = { SkIntToScalar(0), SkIntToScalar(y), | |
| 310 SkIntToScalar(max_x), SkIntToScalar(max_y) }; | |
| 311 animation_path.addRect(animation_rect); | |
| 312 ScopedRegion animation_region(animation_path.CreateNativeRegion()); | |
| 313 region.Set(Path::IntersectRegions(animation_region.Get(), region.Get())); | |
| 314 | |
| 315 // Next, we need to increase the region a little bit to account for the | |
| 316 // curved edges that the view will draw to make it look like grows out of | |
| 317 // the toolbar. | |
| 318 Path::Point left_curve[] = { | |
| 319 {0, y+0}, {0, y+1}, {2, y+3}, {2, y+0}, {0, y+0} | |
| 320 }; | |
| 321 Path::Point right_curve[] = { | |
| 322 {w+3, y+3}, {w+6, y+0}, {w+3, y+0}, {w+3, y+3} | |
| 323 }; | |
| 324 | |
| 325 // Combine the region for the curve on the left with our main region. | |
| 326 Path left_path(left_curve, arraysize(left_curve)); | |
| 327 ScopedRegion r(left_path.CreateNativeRegion()); | |
| 328 region.Set(Path::CombineRegions(r.Get(), region.Get())); | |
| 329 | |
| 330 // Combine the region for the curve on the right with our main region. | |
| 331 Path right_path(right_curve, arraysize(right_curve)); | |
| 332 region.Set(Path::CombineRegions(r.Get(), region.Get())); | |
| 333 } | |
| 334 | |
| 335 // Now see if we need to truncate the region because parts of it obscures | |
| 336 // the main window border. | |
| 337 gfx::Rect dialog_bounds; | |
| 338 GetDialogBounds(&dialog_bounds); | |
| 339 | |
| 340 // Calculate how much our current position overlaps our boundaries. If we | |
| 341 // overlap, it means we have too little space to draw the whole dialog and | |
| 342 // we allow overwriting the scrollbar before we start truncating our dialog. | |
| 343 // | |
| 344 // TODO(brettw) this constant is evil. This is the amount of room we've added | |
| 345 // to the window size, when we set the region, it can change the size. | |
| 346 static const int kAddedWidth = 7; | |
| 347 int difference = (new_pos.right() - kAddedWidth) - | |
| 348 dialog_bounds.width() - | |
| 349 views::NativeScrollBar::GetVerticalScrollBarWidth() + | |
| 350 1; | |
| 351 if (difference > 0) { | |
| 352 Path::Point exclude[4]; | |
| 353 exclude[0].x = max_x - difference; // Top left corner. | |
| 354 exclude[0].y = 0; | |
| 355 | |
| 356 exclude[1].x = max_x; // Top right corner. | |
| 357 exclude[1].y = 0; | |
| 358 | |
| 359 exclude[2].x = max_x; // Bottom right corner. | |
| 360 exclude[2].y = max_y; | |
| 361 | |
| 362 exclude[3].x = max_x - difference; // Bottom left corner. | |
| 363 exclude[3].y = max_y; | |
| 364 | |
| 365 // Subtract this region from the original region. | |
| 366 gfx::Path exclude_path(exclude, arraysize(exclude)); | |
| 367 ScopedRegion exclude_region(exclude_path.CreateNativeRegion()); | |
| 368 region.Set(Path::SubtractRegion(region.Get(), exclude_region.Get())); | |
| 369 } | |
| 370 | |
| 371 // Window takes ownership of the region. | |
| 372 host_->SetShape(region.release()); | |
| 373 } | |
| 374 | |
| 255 gfx::Rect FindBarHost::GetDialogPosition(gfx::Rect avoid_overlapping_rect) { | 375 gfx::Rect FindBarHost::GetDialogPosition(gfx::Rect avoid_overlapping_rect) { |
| 256 // Find the area we have to work with (after accounting for scrollbars, etc). | 376 // Find the area we have to work with (after accounting for scrollbars, etc). |
| 257 gfx::Rect dialog_bounds; | 377 gfx::Rect dialog_bounds; |
| 258 GetDialogBounds(&dialog_bounds); | 378 GetDialogBounds(&dialog_bounds); |
| 259 if (dialog_bounds.IsEmpty()) | 379 if (dialog_bounds.IsEmpty()) |
| 260 return gfx::Rect(); | 380 return gfx::Rect(); |
| 261 | 381 |
| 262 // Ask the view how large an area it needs to draw on. | 382 // Ask the view how large an area it needs to draw on. |
| 263 gfx::Size prefsize = view_->GetPreferredSize(); | 383 gfx::Size prefsize = view_->GetPreferredSize(); |
| 264 | 384 |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 372 | 492 |
| 373 RenderViewHost* render_view_host = contents->render_view_host(); | 493 RenderViewHost* render_view_host = contents->render_view_host(); |
| 374 | 494 |
| 375 // Make sure we don't have a text field element interfering with keyboard | 495 // Make sure we don't have a text field element interfering with keyboard |
| 376 // input. Otherwise Up and Down arrow key strokes get eaten. "Nom Nom Nom". | 496 // input. Otherwise Up and Down arrow key strokes get eaten. "Nom Nom Nom". |
| 377 render_view_host->ClearFocusedNode(); | 497 render_view_host->ClearFocusedNode(); |
| 378 NativeWebKeyboardEvent event = GetKeyboardEvent(contents, key_stroke); | 498 NativeWebKeyboardEvent event = GetKeyboardEvent(contents, key_stroke); |
| 379 render_view_host->ForwardKeyboardEvent(event); | 499 render_view_host->ForwardKeyboardEvent(event); |
| 380 return true; | 500 return true; |
| 381 } | 501 } |
| OLD | NEW |