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 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 return true; | 249 return true; |
246 } | 250 } |
247 | 251 |
248 void FindBarHost::GetDialogBounds(gfx::Rect* bounds) { | 252 void FindBarHost::GetDialogBounds(gfx::Rect* bounds) { |
249 DCHECK(bounds); | 253 DCHECK(bounds); |
250 // The BrowserView does Layout for the components that we care about | 254 // 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. | 255 // positioning relative to, so we ask it to tell us where we should go. |
252 *bounds = browser_view_->GetFindBarBoundingBox(); | 256 *bounds = browser_view_->GetFindBarBoundingBox(); |
253 } | 257 } |
254 | 258 |
| 259 void FindBarHost::UpdateWindowEdges(const gfx::Rect& new_pos) { |
| 260 // |w| is used to make it easier to create the part of the polygon that curves |
| 261 // the right side of the Find window. It essentially keeps track of the |
| 262 // x-pixel position of the right-most background image inside the view. |
| 263 // TODO(finnur): Let the view tell us how to draw the curves or convert |
| 264 // this to a CustomFrameWindow. |
| 265 int w = new_pos.width() - 6; // -6 positions us at the left edge of the |
| 266 // rightmost background image of the view. |
| 267 |
| 268 // This polygon array represents the outline of the background image for the |
| 269 // dialog. Basically, it encompasses only the visible pixels of the |
| 270 // concatenated find_dlg_LMR_bg images (where LMR = [left | middle | right]). |
| 271 static const Path::Point polygon[] = { |
| 272 {0, 0}, {0, 1}, {2, 3}, {2, 29}, {4, 31}, |
| 273 {4, 32}, {w+0, 32}, |
| 274 {w+0, 31}, {w+1, 31}, {w+3, 29}, {w+3, 3}, {w+6, 0} |
| 275 }; |
| 276 |
| 277 // Find the largest x and y value in the polygon. |
| 278 int max_x = 0, max_y = 0; |
| 279 for (size_t i = 0; i < arraysize(polygon); i++) { |
| 280 max_x = std::max(max_x, static_cast<int>(polygon[i].x)); |
| 281 max_y = std::max(max_y, static_cast<int>(polygon[i].y)); |
| 282 } |
| 283 |
| 284 // We then create the polygon and use SetWindowRgn to force the window to draw |
| 285 // only within that area. This region may get reduced in size below. |
| 286 Path path(polygon, arraysize(polygon)); |
| 287 ScopedRegion region(path.CreateNativeRegion()); |
| 288 |
| 289 // Are we animating? |
| 290 if (find_dialog_animation_offset_ > 0) { |
| 291 // The animation happens in two steps: First, we clip the window and then in |
| 292 // GetDialogPosition we offset the window position so that it still looks |
| 293 // attached to the toolbar as it grows. We clip the window by creating a |
| 294 // rectangle region (that gradually increases as the animation progresses) |
| 295 // and find the intersection between the two regions using CombineRgn. |
| 296 |
| 297 // |y| shrinks as the animation progresses from the height of the view down |
| 298 // to 0 (and reverses when closing). |
| 299 int y = find_dialog_animation_offset_; |
| 300 // |y| shrinking means the animation (visible) region gets larger. In other |
| 301 // words: the rectangle grows upward (when the dialog is opening). |
| 302 Path animation_path; |
| 303 SkRect animation_rect = { SkIntToScalar(0), SkIntToScalar(y), |
| 304 SkIntToScalar(max_x), SkIntToScalar(max_y) }; |
| 305 animation_path.addRect(animation_rect); |
| 306 ScopedRegion animation_region(animation_path.CreateNativeRegion()); |
| 307 region.Set(Path::IntersectRegions(animation_region.Get(), region.Get())); |
| 308 |
| 309 // Next, we need to increase the region a little bit to account for the |
| 310 // curved edges that the view will draw to make it look like grows out of |
| 311 // the toolbar. |
| 312 Path::Point left_curve[] = { |
| 313 {0, y+0}, {0, y+1}, {2, y+3}, {2, y+0}, {0, y+0} |
| 314 }; |
| 315 Path::Point right_curve[] = { |
| 316 {w+3, y+3}, {w+6, y+0}, {w+3, y+0}, {w+3, y+3} |
| 317 }; |
| 318 |
| 319 // Combine the region for the curve on the left with our main region. |
| 320 Path left_path(left_curve, arraysize(left_curve)); |
| 321 ScopedRegion r(left_path.CreateNativeRegion()); |
| 322 region.Set(Path::CombineRegions(r.Get(), region.Get())); |
| 323 |
| 324 // Combine the region for the curve on the right with our main region. |
| 325 Path right_path(right_curve, arraysize(right_curve)); |
| 326 region.Set(Path::CombineRegions(r.Get(), region.Get())); |
| 327 } |
| 328 |
| 329 // Now see if we need to truncate the region because parts of it obscures |
| 330 // the main window border. |
| 331 gfx::Rect dialog_bounds; |
| 332 GetDialogBounds(&dialog_bounds); |
| 333 |
| 334 // Calculate how much our current position overlaps our boundaries. If we |
| 335 // overlap, it means we have too little space to draw the whole dialog and |
| 336 // we allow overwriting the scrollbar before we start truncating our dialog. |
| 337 // |
| 338 // TODO(brettw) this constant is evil. This is the amount of room we've added |
| 339 // to the window size, when we set the region, it can change the size. |
| 340 static const int kAddedWidth = 7; |
| 341 int difference = (new_pos.right() - kAddedWidth) - |
| 342 dialog_bounds.width() - |
| 343 views::NativeScrollBar::GetVerticalScrollBarWidth() + |
| 344 1; |
| 345 if (difference > 0) { |
| 346 Path::Point exclude[4]; |
| 347 exclude[0].x = max_x - difference; // Top left corner. |
| 348 exclude[0].y = 0; |
| 349 |
| 350 exclude[1].x = max_x; // Top right corner. |
| 351 exclude[1].y = 0; |
| 352 |
| 353 exclude[2].x = max_x; // Bottom right corner. |
| 354 exclude[2].y = max_y; |
| 355 |
| 356 exclude[3].x = max_x - difference; // Bottom left corner. |
| 357 exclude[3].y = max_y; |
| 358 |
| 359 // Subtract this region from the original region. |
| 360 gfx::Path exclude_path(exclude, arraysize(exclude)); |
| 361 ScopedRegion exclude_region(exclude_path.CreateNativeRegion()); |
| 362 region.Set(Path::SubtractRegion(region.Get(), exclude_region.Get())); |
| 363 } |
| 364 |
| 365 // Window takes ownership of the region. |
| 366 host_->SetShape(region.release()); |
| 367 } |
| 368 |
255 gfx::Rect FindBarHost::GetDialogPosition(gfx::Rect avoid_overlapping_rect) { | 369 gfx::Rect FindBarHost::GetDialogPosition(gfx::Rect avoid_overlapping_rect) { |
256 // Find the area we have to work with (after accounting for scrollbars, etc). | 370 // Find the area we have to work with (after accounting for scrollbars, etc). |
257 gfx::Rect dialog_bounds; | 371 gfx::Rect dialog_bounds; |
258 GetDialogBounds(&dialog_bounds); | 372 GetDialogBounds(&dialog_bounds); |
259 if (dialog_bounds.IsEmpty()) | 373 if (dialog_bounds.IsEmpty()) |
260 return gfx::Rect(); | 374 return gfx::Rect(); |
261 | 375 |
262 // Ask the view how large an area it needs to draw on. | 376 // Ask the view how large an area it needs to draw on. |
263 gfx::Size prefsize = view_->GetPreferredSize(); | 377 gfx::Size prefsize = view_->GetPreferredSize(); |
264 | 378 |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 | 486 |
373 RenderViewHost* render_view_host = contents->render_view_host(); | 487 RenderViewHost* render_view_host = contents->render_view_host(); |
374 | 488 |
375 // Make sure we don't have a text field element interfering with keyboard | 489 // 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". | 490 // input. Otherwise Up and Down arrow key strokes get eaten. "Nom Nom Nom". |
377 render_view_host->ClearFocusedNode(); | 491 render_view_host->ClearFocusedNode(); |
378 NativeWebKeyboardEvent event = GetKeyboardEvent(contents, key_stroke); | 492 NativeWebKeyboardEvent event = GetKeyboardEvent(contents, key_stroke); |
379 render_view_host->ForwardKeyboardEvent(event); | 493 render_view_host->ForwardKeyboardEvent(event); |
380 return true; | 494 return true; |
381 } | 495 } |
OLD | NEW |