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 |