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 "chrome/browser/find_bar_controller.h" | 7 #include "chrome/browser/find_bar_controller.h" |
8 #include "chrome/browser/renderer_host/render_view_host.h" | 8 #include "chrome/browser/renderer_host/render_view_host.h" |
9 #include "chrome/browser/tab_contents/tab_contents.h" | 9 #include "chrome/browser/tab_contents/tab_contents.h" |
10 #include "chrome/browser/tab_contents/tab_contents_view.h" | 10 #include "chrome/browser/tab_contents/tab_contents_view.h" |
11 #include "chrome/browser/views/frame/browser_view.h" | 11 #include "chrome/browser/views/frame/browser_view.h" |
12 #include "views/controls/scrollbar/native_scroll_bar.h" | 12 #include "views/controls/scrollbar/native_scroll_bar.h" |
13 #include "views/widget/widget_win.h" | 13 #include "views/widget/widget_win.h" |
14 | 14 |
15 // TODO(brettw) this should not be so complicated. The view should really be in | |
16 // charge of these regions. CustomFrameWindow will do this for us. It will also | |
17 // let us set a path for the window region which will avoid some logic here. | |
18 void FindBarHost::UpdateWindowEdges(const gfx::Rect& new_pos) { | |
19 // |w| is used to make it easier to create the part of the polygon that curves | |
20 // the right side of the Find window. It essentially keeps track of the | |
21 // x-pixel position of the right-most background image inside the view. | |
22 // TODO(finnur): Let the view tell us how to draw the curves or convert | |
23 // this to a CustomFrameWindow. | |
24 int w = new_pos.width() - 6; // -6 positions us at the left edge of the | |
25 // rightmost background image of the view. | |
26 | |
27 // This polygon array represents the outline of the background image for the | |
28 // dialog. Basically, it encompasses only the visible pixels of the | |
29 // concatenated find_dlg_LMR_bg images (where LMR = [left | middle | right]). | |
30 static const POINT polygon[] = { | |
31 {0, 0}, {0, 1}, {2, 3}, {2, 29}, {4, 31}, | |
32 {4, 32}, {w+0, 32}, | |
33 {w+0, 31}, {w+1, 31}, {w+3, 29}, {w+3, 3}, {w+6, 0} | |
34 }; | |
35 | |
36 // Find the largest x and y value in the polygon. | |
37 int max_x = 0, max_y = 0; | |
38 for (int i = 0; i < arraysize(polygon); i++) { | |
39 max_x = std::max(max_x, static_cast<int>(polygon[i].x)); | |
40 max_y = std::max(max_y, static_cast<int>(polygon[i].y)); | |
41 } | |
42 | |
43 // We then create the polygon and use SetWindowRgn to force the window to draw | |
44 // only within that area. This region may get reduced in size below. | |
45 HRGN region = CreatePolygonRgn(polygon, arraysize(polygon), ALTERNATE); | |
46 | |
47 // Are we animating? | |
48 if (find_dialog_animation_offset_ > 0) { | |
49 // The animation happens in two steps: First, we clip the window and then in | |
50 // GetDialogPosition we offset the window position so that it still looks | |
51 // attached to the toolbar as it grows. We clip the window by creating a | |
52 // rectangle region (that gradually increases as the animation progresses) | |
53 // and find the intersection between the two regions using CombineRgn. | |
54 | |
55 // |y| shrinks as the animation progresses from the height of the view down | |
56 // to 0 (and reverses when closing). | |
57 int y = find_dialog_animation_offset_; | |
58 // |y| shrinking means the animation (visible) region gets larger. In other | |
59 // words: the rectangle grows upward (when the dialog is opening). | |
60 HRGN animation_region = CreateRectRgn(0, y, max_x, max_y); | |
61 // |region| will contain the intersected parts after calling this function: | |
62 CombineRgn(region, animation_region, region, RGN_AND); | |
63 DeleteObject(animation_region); | |
64 | |
65 // Next, we need to increase the region a little bit to account for the | |
66 // curved edges that the view will draw to make it look like grows out of | |
67 // the toolbar. | |
68 POINT left_curve[] = { | |
69 {0, y+0}, {0, y+1}, {2, y+3}, {2, y+0}, {0, y+0} | |
70 }; | |
71 POINT right_curve[] = { | |
72 {w+3, y+3}, {w+6, y+0}, {w+3, y+0}, {w+3, y+3} | |
73 }; | |
74 | |
75 // Combine the region for the curve on the left with our main region. | |
76 HRGN r = CreatePolygonRgn(left_curve, arraysize(left_curve), ALTERNATE); | |
77 CombineRgn(region, r, region, RGN_OR); | |
78 DeleteObject(r); | |
79 | |
80 // Combine the region for the curve on the right with our main region. | |
81 r = CreatePolygonRgn(right_curve, arraysize(right_curve), ALTERNATE); | |
82 CombineRgn(region, r, region, RGN_OR); | |
83 DeleteObject(r); | |
84 } | |
85 | |
86 // Now see if we need to truncate the region because parts of it obscures | |
87 // the main window border. | |
88 gfx::Rect dialog_bounds; | |
89 GetDialogBounds(&dialog_bounds); | |
90 | |
91 // Calculate how much our current position overlaps our boundaries. If we | |
92 // overlap, it means we have too little space to draw the whole dialog and | |
93 // we allow overwriting the scrollbar before we start truncating our dialog. | |
94 // | |
95 // TODO(brettw) this constant is evil. This is the amount of room we've added | |
96 // to the window size, when we set the region, it can change the size. | |
97 static const int kAddedWidth = 7; | |
98 int difference = (new_pos.right() - kAddedWidth) - | |
99 dialog_bounds.width() - | |
100 views::NativeScrollBar::GetVerticalScrollBarWidth() + | |
101 1; | |
102 if (difference > 0) { | |
103 POINT exclude[4] = {0}; | |
104 exclude[0].x = max_x - difference; // Top left corner. | |
105 exclude[0].y = 0; | |
106 | |
107 exclude[1].x = max_x; // Top right corner. | |
108 exclude[1].y = 0; | |
109 | |
110 exclude[2].x = max_x; // Bottom right corner. | |
111 exclude[2].y = max_y; | |
112 | |
113 exclude[3].x = max_x - difference; // Bottom left corner. | |
114 exclude[3].y = max_y; | |
115 | |
116 // Subtract this region from the original region. | |
117 HRGN exclude_rgn = CreatePolygonRgn(exclude, arraysize(exclude), ALTERNATE); | |
118 int result = CombineRgn(region, region, exclude_rgn, RGN_DIFF); | |
119 DeleteObject(exclude_rgn); | |
120 } | |
121 | |
122 // The system now owns the region, so we do not delete it. | |
123 ::SetWindowRgn(host_->GetNativeView(), region, TRUE); // TRUE = Redraw. | |
124 } | |
125 | |
126 NativeWebKeyboardEvent FindBarHost::GetKeyboardEvent( | 15 NativeWebKeyboardEvent FindBarHost::GetKeyboardEvent( |
127 const TabContents* contents, | 16 const TabContents* contents, |
128 const views::Textfield::Keystroke& key_stroke) { | 17 const views::Textfield::Keystroke& key_stroke) { |
129 HWND hwnd = contents->GetContentNativeView(); | 18 HWND hwnd = contents->GetContentNativeView(); |
130 return NativeWebKeyboardEvent( | 19 return NativeWebKeyboardEvent( |
131 hwnd, key_stroke.message(), key_stroke.key(), 0); | 20 hwnd, key_stroke.message(), key_stroke.key(), 0); |
132 } | 21 } |
133 | 22 |
134 void FindBarHost::AudibleAlert() { | 23 void FindBarHost::AudibleAlert() { |
135 MessageBeep(MB_OK); | 24 MessageBeep(MB_OK); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 | 63 |
175 gfx::NativeView FindBarHost::GetNativeView(BrowserView* browser_view) { | 64 gfx::NativeView FindBarHost::GetNativeView(BrowserView* browser_view) { |
176 return browser_view->GetWidget()->GetNativeView(); | 65 return browser_view->GetWidget()->GetNativeView(); |
177 } | 66 } |
178 | 67 |
179 bool FindBarHost::ShouldForwardKeystrokeToWebpageNative( | 68 bool FindBarHost::ShouldForwardKeystrokeToWebpageNative( |
180 const views::Textfield::Keystroke& key_stroke) { | 69 const views::Textfield::Keystroke& key_stroke) { |
181 // We specifically ignore WM_CHAR. See http://crbug.com/10509. | 70 // We specifically ignore WM_CHAR. See http://crbug.com/10509. |
182 return key_stroke.message() == WM_KEYDOWN || key_stroke.message() == WM_KEYUP; | 71 return key_stroke.message() == WM_KEYDOWN || key_stroke.message() == WM_KEYUP; |
183 } | 72 } |
OLD | NEW |