OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/ui/views/omnibox/omnibox_popup_contents_view.h" | 5 #include "chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h" |
6 | 6 |
7 #include "chrome/browser/search/search.h" | 7 #include "chrome/browser/search/search.h" |
8 #include "chrome/browser/ui/omnibox/omnibox_popup_non_view.h" | 8 #include "chrome/browser/ui/omnibox/omnibox_popup_non_view.h" |
9 #include "chrome/browser/ui/omnibox/omnibox_view.h" | 9 #include "chrome/browser/ui/omnibox/omnibox_view.h" |
10 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" | |
11 #include "chrome/browser/ui/views/omnibox/omnibox_result_view.h" | 10 #include "chrome/browser/ui/views/omnibox/omnibox_result_view.h" |
11 #include "chrome/browser/ui/views/omnibox/omnibox_view_delegate.h" | |
12 #include "chrome/browser/ui/views/omnibox/touch_omnibox_popup_contents_view.h" | 12 #include "chrome/browser/ui/views/omnibox/touch_omnibox_popup_contents_view.h" |
13 #include "grit/theme_resources.h" | |
14 #include "grit/ui_resources.h" | |
13 #include "ui/base/theme_provider.h" | 15 #include "ui/base/theme_provider.h" |
14 #include "ui/gfx/canvas.h" | 16 #include "ui/gfx/canvas.h" |
15 #include "ui/gfx/image/image.h" | 17 #include "ui/gfx/image/image.h" |
16 #include "ui/gfx/path.h" | 18 #include "ui/gfx/path.h" |
19 #include "ui/views/controls/image_view.h" | |
17 #include "ui/views/widget/widget.h" | 20 #include "ui/views/widget/widget.h" |
18 | 21 |
19 #if defined(USE_AURA) | 22 #if defined(USE_AURA) |
20 #include "ui/views/corewm/window_animations.h" | 23 #include "ui/views/corewm/window_animations.h" |
21 #endif | 24 #endif |
22 | 25 |
23 #if defined(OS_WIN) | |
24 #include <dwmapi.h> | |
25 | |
26 #include "base/win/scoped_gdi_object.h" | |
27 #if !defined(USE_AURA) | |
28 #include "ui/base/win/shell.h" | |
29 #endif | |
30 #endif | |
31 | |
32 namespace { | 26 namespace { |
33 | 27 |
34 const SkAlpha kGlassPopupAlpha = 240; | 28 const SkAlpha kGlassPopupAlpha = 240; |
35 const SkAlpha kOpaquePopupAlpha = 255; | 29 const SkAlpha kOpaquePopupAlpha = 255; |
36 | 30 |
37 // The size delta between the font used for the edit and the result rows. Passed | 31 // The size delta between the font used for the edit and the result rows. Passed |
38 // to gfx::Font::DeriveFont. | 32 // to gfx::Font::DeriveFont. |
39 #if defined(OS_CHROMEOS) | 33 #if defined(OS_CHROMEOS) |
40 // Don't adjust the size on Chrome OS (http://crbug.com/61433). | 34 // Don't adjust the size on Chrome OS (http://crbug.com/61433). |
41 const int kEditFontAdjust = 0; | 35 const int kEditFontAdjust = 0; |
42 #else | 36 #else |
43 const int kEditFontAdjust = -1; | 37 const int kEditFontAdjust = -1; |
44 #endif | 38 #endif |
45 | 39 |
40 // This is the number of pixels in the border image interior to the actual | |
41 // border. | |
42 const int kBorderInterior = 6; | |
43 | |
46 } // namespace | 44 } // namespace |
47 | 45 |
48 class OmniboxPopupContentsView::AutocompletePopupWidget | 46 class OmniboxPopupContentsView::AutocompletePopupWidget |
49 : public views::Widget, | 47 : public views::Widget, |
50 public base::SupportsWeakPtr<AutocompletePopupWidget> { | 48 public base::SupportsWeakPtr<AutocompletePopupWidget> { |
51 public: | 49 public: |
52 AutocompletePopupWidget() {} | 50 AutocompletePopupWidget() {} |
53 virtual ~AutocompletePopupWidget() {} | 51 virtual ~AutocompletePopupWidget() {} |
54 | 52 |
55 private: | 53 private: |
56 DISALLOW_COPY_AND_ASSIGN(AutocompletePopupWidget); | 54 DISALLOW_COPY_AND_ASSIGN(AutocompletePopupWidget); |
57 }; | 55 }; |
58 | 56 |
59 //////////////////////////////////////////////////////////////////////////////// | 57 //////////////////////////////////////////////////////////////////////////////// |
60 // OmniboxPopupContentsView, public: | 58 // OmniboxPopupContentsView, public: |
61 | 59 |
62 OmniboxPopupView* OmniboxPopupContentsView::Create( | 60 OmniboxPopupView* OmniboxPopupContentsView::Create( |
63 const gfx::Font& font, | 61 const gfx::Font& font, |
64 OmniboxView* omnibox_view, | 62 OmniboxView* omnibox_view, |
65 OmniboxEditModel* edit_model, | 63 OmniboxEditModel* edit_model, |
66 views::View* location_bar) { | 64 OmniboxViewDelegate* view_delegate) { |
67 if (chrome::IsInstantExtendedAPIEnabled()) | 65 if (chrome::IsInstantExtendedAPIEnabled()) |
68 return new OmniboxPopupNonView(edit_model); | 66 return new OmniboxPopupNonView(edit_model); |
69 | 67 |
70 OmniboxPopupContentsView* view = NULL; | 68 OmniboxPopupContentsView* view = NULL; |
71 if (ui::GetDisplayLayout() == ui::LAYOUT_TOUCH) { | 69 if (ui::GetDisplayLayout() == ui::LAYOUT_TOUCH) { |
72 view = new TouchOmniboxPopupContentsView( | 70 view = new TouchOmniboxPopupContentsView( |
73 font, omnibox_view, edit_model, location_bar); | 71 font, omnibox_view, edit_model, view_delegate); |
74 } else { | 72 } else { |
75 view = new OmniboxPopupContentsView( | 73 view = new OmniboxPopupContentsView( |
76 font, omnibox_view, edit_model, location_bar); | 74 font, omnibox_view, edit_model, view_delegate); |
77 } | 75 } |
78 | 76 |
79 view->Init(); | 77 view->Init(); |
80 return view; | 78 return view; |
81 } | 79 } |
82 | 80 |
83 OmniboxPopupContentsView::OmniboxPopupContentsView( | 81 OmniboxPopupContentsView::OmniboxPopupContentsView( |
84 const gfx::Font& font, | 82 const gfx::Font& font, |
85 OmniboxView* omnibox_view, | 83 OmniboxView* omnibox_view, |
86 OmniboxEditModel* edit_model, | 84 OmniboxEditModel* edit_model, |
87 views::View* location_bar) | 85 OmniboxViewDelegate* view_delegate) |
88 : model_(new OmniboxPopupModel(this, edit_model)), | 86 : model_(new OmniboxPopupModel(this, edit_model)), |
89 omnibox_view_(omnibox_view), | 87 omnibox_view_(omnibox_view), |
90 location_bar_(location_bar), | 88 view_delegate_(view_delegate), |
91 font_(font.DeriveFont(kEditFontAdjust)), | 89 font_(font.DeriveFont(kEditFontAdjust)), |
92 ignore_mouse_drag_(false), | 90 ignore_mouse_drag_(false), |
93 size_animation_(this) { | 91 size_animation_(this), |
94 bubble_border_ = new views::BubbleBorder(views::BubbleBorder::NONE, | 92 provider_logo_(new views::ImageView), |
95 views::BubbleBorder::NO_SHADOW, SK_ColorWHITE); | 93 left_margin_(0), |
96 set_border(const_cast<views::BubbleBorder*>(bubble_border_)); | 94 right_margin_(0), |
95 outside_vertical_padding_(0) { | |
97 // The contents is owned by the LocationBarView. | 96 // The contents is owned by the LocationBarView. |
98 set_owned_by_client(); | 97 set_owned_by_client(); |
98 | |
99 ui::ThemeProvider* theme = view_delegate_->GetThemeProviderForPopup(); | |
100 provider_logo_->set_owned_by_client(); | |
Peter Kasting
2013/06/06 18:52:16
Why use set_owned_by_client() and a scoped_ptr ins
| |
101 provider_logo_->SetImage(theme->GetImageSkiaNamed(IDR_OMNIBOX_GOOGLE_LOGO)); | |
102 provider_logo_->SizeToPreferredSize(); | |
103 | |
104 bottom_shadow_ = theme->GetImageSkiaNamed(IDR_BUBBLE_B); | |
99 } | 105 } |
100 | 106 |
101 void OmniboxPopupContentsView::Init() { | 107 void OmniboxPopupContentsView::Init() { |
102 // This can't be done in the constructor as at that point we aren't | 108 // This can't be done in the constructor as at that point we aren't |
103 // necessarily our final class yet, and we may have subclasses | 109 // necessarily our final class yet, and we may have subclasses |
104 // overriding CreateResultView. | 110 // overriding CreateResultView. |
105 for (size_t i = 0; i < AutocompleteResult::kMaxMatches; ++i) { | 111 for (size_t i = 0; i < AutocompleteResult::kMaxMatches; ++i) { |
106 OmniboxResultView* result_view = CreateResultView(this, i, font_); | 112 OmniboxResultView* result_view = CreateResultView(this, i, font_); |
107 result_view->SetVisible(false); | 113 result_view->SetVisible(false); |
108 AddChildViewAt(result_view, static_cast<int>(i)); | 114 AddChildViewAt(result_view, static_cast<int>(i)); |
109 } | 115 } |
116 AddChildView(provider_logo_.get()); | |
110 } | 117 } |
111 | 118 |
112 OmniboxPopupContentsView::~OmniboxPopupContentsView() { | 119 OmniboxPopupContentsView::~OmniboxPopupContentsView() { |
113 // We don't need to do anything with |popup_| here. The OS either has already | 120 // We don't need to do anything with |popup_| here. The OS either has already |
114 // closed the window, in which case it's been deleted, or it will soon, in | 121 // closed the window, in which case it's been deleted, or it will soon, in |
115 // which case there's nothing we need to do. | 122 // which case there's nothing we need to do. |
116 } | 123 } |
117 | 124 |
118 gfx::Rect OmniboxPopupContentsView::GetPopupBounds() const { | 125 gfx::Rect OmniboxPopupContentsView::GetPopupBounds() const { |
119 if (!size_animation_.is_animating()) | 126 if (!size_animation_.is_animating()) |
120 return target_bounds_; | 127 return target_bounds_; |
121 | 128 |
122 gfx::Rect current_frame_bounds = start_bounds_; | 129 gfx::Rect current_frame_bounds = start_bounds_; |
123 int total_height_delta = target_bounds_.height() - start_bounds_.height(); | 130 int total_height_delta = target_bounds_.height() - start_bounds_.height(); |
124 // Round |current_height_delta| instead of truncating so we won't leave single | 131 // Round |current_height_delta| instead of truncating so we won't leave single |
125 // white pixels at the bottom of the popup as long when animating very small | 132 // white pixels at the bottom of the popup as long when animating very small |
126 // height differences. | 133 // height differences. |
127 int current_height_delta = static_cast<int>( | 134 int current_height_delta = static_cast<int>( |
128 size_animation_.GetCurrentValue() * total_height_delta - 0.5); | 135 size_animation_.GetCurrentValue() * total_height_delta - 0.5); |
129 current_frame_bounds.set_height( | 136 current_frame_bounds.set_height( |
130 current_frame_bounds.height() + current_height_delta); | 137 current_frame_bounds.height() + current_height_delta); |
131 return current_frame_bounds; | 138 return current_frame_bounds; |
132 } | 139 } |
133 | 140 |
134 void OmniboxPopupContentsView::LayoutChildren() { | 141 void OmniboxPopupContentsView::LayoutChildren() { |
135 gfx::Rect contents_rect = GetContentsBounds(); | 142 gfx::Rect contents_rect = GetContentsBounds(); |
136 int top = contents_rect.y(); | 143 |
137 for (int i = 0; i < child_count(); ++i) { | 144 provider_logo_->SetPosition(gfx::Point(5, 5)); |
Peter Kasting
2013/06/06 18:52:16
These numbers are pretty magic
| |
145 | |
146 int top = contents_rect.y() + outside_vertical_padding_; | |
147 int left = contents_rect.x() + left_margin_; | |
148 int width = contents_rect.width() - left_margin_ - right_margin_; | |
Peter Kasting
2013/06/06 18:52:16
Or just:
contents_rect.Inset(left_margin_, outs
| |
149 for (size_t i = 0; i < AutocompleteResult::kMaxMatches; ++i) { | |
138 View* v = child_at(i); | 150 View* v = child_at(i); |
139 if (v->visible()) { | 151 if (v->visible()) { |
140 v->SetBounds(contents_rect.x(), top, contents_rect.width(), | 152 v->SetBounds(left, top, width, v->GetPreferredSize().height()); |
141 v->GetPreferredSize().height()); | |
142 top = v->bounds().bottom(); | 153 top = v->bounds().bottom(); |
143 } | 154 } |
144 } | 155 } |
145 } | 156 } |
146 | 157 |
147 //////////////////////////////////////////////////////////////////////////////// | 158 //////////////////////////////////////////////////////////////////////////////// |
148 // OmniboxPopupContentsView, OmniboxPopupView overrides: | 159 // OmniboxPopupContentsView, OmniboxPopupView overrides: |
149 | 160 |
150 bool OmniboxPopupContentsView::IsOpen() const { | 161 bool OmniboxPopupContentsView::IsOpen() const { |
151 return popup_ != NULL; | 162 return popup_ != NULL; |
(...skipping 27 matching lines...) Expand all Loading... | |
179 | 190 |
180 // Update the match cached by each row, in the process of doing so make sure | 191 // Update the match cached by each row, in the process of doing so make sure |
181 // we have enough row views. | 192 // we have enough row views. |
182 size_t child_rv_count = child_count(); | 193 size_t child_rv_count = child_count(); |
183 const size_t result_size = model_->result().size(); | 194 const size_t result_size = model_->result().size(); |
184 for (size_t i = 0; i < result_size; ++i) { | 195 for (size_t i = 0; i < result_size; ++i) { |
185 OmniboxResultView* view = result_view_at(i); | 196 OmniboxResultView* view = result_view_at(i); |
186 view->SetMatch(GetMatchAtIndex(i)); | 197 view->SetMatch(GetMatchAtIndex(i)); |
187 view->SetVisible(true); | 198 view->SetVisible(true); |
188 } | 199 } |
189 for (size_t i = result_size; i < child_rv_count; ++i) | 200 for (size_t i = result_size; i < AutocompleteResult::kMaxMatches; ++i) |
190 child_at(i)->SetVisible(false); | 201 child_at(i)->SetVisible(false); |
191 | 202 |
192 gfx::Rect new_target_bounds = CalculateTargetBounds(CalculatePopupHeight()); | 203 gfx::Rect new_target_bounds = CalculateTargetBounds(CalculatePopupHeight()); |
193 | 204 |
194 // If we're animating and our target height changes, reset the animation. | 205 // If we're animating and our target height changes, reset the animation. |
195 // NOTE: If we just reset blindly on _every_ update, then when the user types | 206 // NOTE: If we just reset blindly on _every_ update, then when the user types |
196 // rapidly we could get "stuck" trying repeatedly to animate shrinking by the | 207 // rapidly we could get "stuck" trying repeatedly to animate shrinking by the |
197 // last few pixels to get to one visible result. | 208 // last few pixels to get to one visible result. |
198 if (new_target_bounds.height() != target_bounds_.height()) | 209 if (new_target_bounds.height() != target_bounds_.height()) |
199 size_animation_.Reset(); | 210 size_animation_.Reset(); |
200 target_bounds_ = new_target_bounds; | 211 target_bounds_ = new_target_bounds; |
201 | 212 |
202 if (popup_ == NULL) { | 213 if (popup_ == NULL) { |
203 // If the popup is currently closed, we need to create it. | 214 // If the popup is currently closed, we need to create it. |
204 popup_ = (new AutocompletePopupWidget)->AsWeakPtr(); | 215 popup_ = (new AutocompletePopupWidget)->AsWeakPtr(); |
205 views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); | 216 views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); |
206 params.can_activate = false; | 217 params.can_activate = false; |
207 params.transparent = true; | 218 params.transparent = true; |
208 params.parent = location_bar_->GetWidget()->GetNativeView(); | 219 params.parent = view_delegate_->GetPopupParent(); |
209 params.bounds = GetPopupBounds(); | 220 params.bounds = GetPopupBounds(); |
210 params.context = location_bar_->GetWidget()->GetNativeView(); | 221 params.context = view_delegate_->GetPopupParent(); |
211 popup_->Init(params); | 222 popup_->Init(params); |
212 #if defined(USE_AURA) | 223 #if defined(USE_AURA) |
213 views::corewm::SetWindowVisibilityAnimationType( | 224 views::corewm::SetWindowVisibilityAnimationType( |
214 popup_->GetNativeView(), | 225 popup_->GetNativeView(), |
215 views::corewm::WINDOW_VISIBILITY_ANIMATION_TYPE_VERTICAL); | 226 views::corewm::WINDOW_VISIBILITY_ANIMATION_TYPE_VERTICAL); |
216 #if defined(OS_CHROMEOS) | 227 #if defined(OS_CHROMEOS) |
217 // No animation for autocomplete popup appearance. | 228 // No animation for autocomplete popup appearance. |
218 views::corewm::SetWindowVisibilityAnimationTransition( | 229 views::corewm::SetWindowVisibilityAnimationTransition( |
219 popup_->GetNativeView(), views::corewm::ANIMATE_HIDE); | 230 popup_->GetNativeView(), views::corewm::ANIMATE_HIDE); |
220 #endif | 231 #endif |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
280 const ui::Animation* animation) { | 291 const ui::Animation* animation) { |
281 // We should only be running the animation when the popup is already visible. | 292 // We should only be running the animation when the popup is already visible. |
282 DCHECK(popup_ != NULL); | 293 DCHECK(popup_ != NULL); |
283 popup_->SetBounds(GetPopupBounds()); | 294 popup_->SetBounds(GetPopupBounds()); |
284 } | 295 } |
285 | 296 |
286 //////////////////////////////////////////////////////////////////////////////// | 297 //////////////////////////////////////////////////////////////////////////////// |
287 // OmniboxPopupContentsView, views::View overrides: | 298 // OmniboxPopupContentsView, views::View overrides: |
288 | 299 |
289 void OmniboxPopupContentsView::Layout() { | 300 void OmniboxPopupContentsView::Layout() { |
290 UpdateBlurRegion(); | |
291 | |
292 // Size our children to the available content area. | 301 // Size our children to the available content area. |
293 LayoutChildren(); | 302 LayoutChildren(); |
294 | 303 |
295 // We need to manually schedule a paint here since we are a layered window and | 304 // We need to manually schedule a paint here since we are a layered window and |
296 // won't implicitly require painting until we ask for one. | 305 // won't implicitly require painting until we ask for one. |
297 SchedulePaint(); | 306 SchedulePaint(); |
298 } | 307 } |
299 | 308 |
300 views::View* OmniboxPopupContentsView::GetEventHandlerForPoint( | 309 views::View* OmniboxPopupContentsView::GetEventHandlerForPoint( |
301 const gfx::Point& point) { | 310 const gfx::Point& point) { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
378 canvas->DrawColor(result_view_at(0)->GetColor( | 387 canvas->DrawColor(result_view_at(0)->GetColor( |
379 OmniboxResultView::NORMAL, OmniboxResultView::BACKGROUND)); | 388 OmniboxResultView::NORMAL, OmniboxResultView::BACKGROUND)); |
380 View::PaintChildren(canvas); | 389 View::PaintChildren(canvas); |
381 } | 390 } |
382 | 391 |
383 int OmniboxPopupContentsView::CalculatePopupHeight() { | 392 int OmniboxPopupContentsView::CalculatePopupHeight() { |
384 DCHECK_GE(static_cast<size_t>(child_count()), model_->result().size()); | 393 DCHECK_GE(static_cast<size_t>(child_count()), model_->result().size()); |
385 int popup_height = 0; | 394 int popup_height = 0; |
386 for (size_t i = 0; i < model_->result().size(); ++i) | 395 for (size_t i = 0; i < model_->result().size(); ++i) |
387 popup_height += child_at(i)->GetPreferredSize().height(); | 396 popup_height += child_at(i)->GetPreferredSize().height(); |
388 return popup_height; | 397 |
398 // Add enough space on the top and bottom so it looks like there is the same | |
399 // amount of space between the text and the popup border as there is in the | |
400 // interior between each row of text. | |
401 // | |
402 // Discovering the exact amount of leading and padding around the font is | |
403 // a bit tricky and platform-specific, but this computation seems to work in | |
404 // practice. | |
405 OmniboxResultView* result_view = result_view_at(0); | |
406 outside_vertical_padding_ = | |
407 (result_view->GetPreferredSize().height() - | |
408 result_view->GetTextHeight()); | |
409 | |
410 return popup_height + outside_vertical_padding_ * 2 + | |
411 bottom_shadow_->height() - kBorderInterior; | |
389 } | 412 } |
390 | 413 |
391 OmniboxResultView* OmniboxPopupContentsView::CreateResultView( | 414 OmniboxResultView* OmniboxPopupContentsView::CreateResultView( |
392 OmniboxResultViewModel* model, | 415 OmniboxResultViewModel* model, |
393 int model_index, | 416 int model_index, |
394 const gfx::Font& font) { | 417 const gfx::Font& font) { |
395 return new OmniboxResultView(model, model_index, location_bar_, font); | 418 return new OmniboxResultView(model, model_index, view_delegate_, font); |
396 } | 419 } |
397 | 420 |
398 //////////////////////////////////////////////////////////////////////////////// | 421 //////////////////////////////////////////////////////////////////////////////// |
399 // OmniboxPopupContentsView, views::View overrides, protected: | 422 // OmniboxPopupContentsView, views::View overrides, protected: |
400 | 423 |
401 void OmniboxPopupContentsView::OnPaint(gfx::Canvas* canvas) { | 424 void OmniboxPopupContentsView::OnPaint(gfx::Canvas* canvas) { |
425 gfx::Rect contents_bounds = GetContentsBounds(); | |
426 contents_bounds.set_height( | |
427 contents_bounds.height() - bottom_shadow_->height() + kBorderInterior); | |
428 | |
402 gfx::Path path; | 429 gfx::Path path; |
403 MakeContentsPath(&path, GetContentsBounds()); | 430 MakeContentsPath(&path, contents_bounds); |
404 canvas->Save(); | 431 canvas->Save(); |
405 canvas->sk_canvas()->clipPath(path, | 432 canvas->sk_canvas()->clipPath(path, |
406 SkRegion::kIntersect_Op, | 433 SkRegion::kIntersect_Op, |
407 true /* doAntialias */); | 434 true /* doAntialias */); |
408 PaintResultViews(canvas); | 435 PaintResultViews(canvas); |
409 | |
410 // We want the contents background to be slightly transparent so we can see | |
411 // the blurry glass effect on DWM systems behind. We do this _after_ we paint | |
412 // the children since they paint text, and GDI will reset this alpha data if | |
413 // we paint text after this call. | |
414 MakeCanvasTransparent(canvas); | |
415 canvas->Restore(); | 436 canvas->Restore(); |
416 | 437 |
417 // Now we paint the border, so it will be alpha-blended atop the contents. | 438 // Now we paint the border, so it will be alpha-blended atop the contents. |
418 // This looks slightly better in the corners than drawing the contents atop | 439 // This looks slightly better in the corners than drawing the contents atop |
419 // the border. | 440 // the border. |
420 OnPaintBorder(canvas); | 441 //OnPaintBorder(canvas); |
Peter Kasting
2013/06/06 18:52:16
Remove this
| |
442 | |
443 canvas->TileImageInt(*bottom_shadow_, 0, height() - bottom_shadow_->height(), | |
444 width(), bottom_shadow_->height()); | |
421 } | 445 } |
422 | 446 |
423 void OmniboxPopupContentsView::PaintChildren(gfx::Canvas* canvas) { | 447 void OmniboxPopupContentsView::PaintChildren(gfx::Canvas* canvas) { |
424 // We paint our children inside OnPaint(). | 448 // We paint our children inside OnPaint(). |
425 } | 449 } |
426 | 450 |
427 //////////////////////////////////////////////////////////////////////////////// | 451 //////////////////////////////////////////////////////////////////////////////// |
428 // OmniboxPopupContentsView, private: | 452 // OmniboxPopupContentsView, private: |
429 | 453 |
430 bool OmniboxPopupContentsView::HasMatchAt(size_t index) const { | 454 bool OmniboxPopupContentsView::HasMatchAt(size_t index) const { |
431 return index < model_->result().size(); | 455 return index < model_->result().size(); |
432 } | 456 } |
433 | 457 |
434 const AutocompleteMatch& OmniboxPopupContentsView::GetMatchAtIndex( | 458 const AutocompleteMatch& OmniboxPopupContentsView::GetMatchAtIndex( |
435 size_t index) const { | 459 size_t index) const { |
436 return model_->result().match_at(index); | 460 return model_->result().match_at(index); |
437 } | 461 } |
438 | 462 |
439 void OmniboxPopupContentsView::MakeContentsPath( | 463 void OmniboxPopupContentsView::MakeContentsPath( |
Peter Kasting
2013/06/06 18:52:16
This function can just be inlined into its lone ca
| |
440 gfx::Path* path, | 464 gfx::Path* path, |
441 const gfx::Rect& bounding_rect) { | 465 const gfx::Rect& bounding_rect) { |
442 SkRect rect; | 466 SkRect rect; |
Peter Kasting
2013/06/06 18:52:16
Can avoid this temp by using the 4-arg version of
| |
443 rect.set(SkIntToScalar(bounding_rect.x()), | 467 rect.set(SkIntToScalar(bounding_rect.x()), |
444 SkIntToScalar(bounding_rect.y()), | 468 SkIntToScalar(bounding_rect.y()), |
445 SkIntToScalar(bounding_rect.right()), | 469 SkIntToScalar(bounding_rect.right()), |
446 SkIntToScalar(bounding_rect.bottom())); | 470 SkIntToScalar(bounding_rect.bottom())); |
447 | 471 path->addRect(rect); |
448 SkScalar radius = SkIntToScalar(views::BubbleBorder::GetCornerRadius()); | |
449 path->addRoundRect(rect, radius, radius); | |
450 } | |
451 | |
452 void OmniboxPopupContentsView::UpdateBlurRegion() { | |
453 #if defined(OS_WIN) && !defined(USE_AURA) | |
454 // We only support background blurring on Vista with Aero-Glass enabled. | |
455 if (!ui::win::IsAeroGlassEnabled() || !GetWidget()) | |
456 return; | |
457 | |
458 // Provide a blurred background effect within the contents region of the | |
459 // popup. | |
460 DWM_BLURBEHIND bb = {0}; | |
461 bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION; | |
462 bb.fEnable = true; | |
463 | |
464 // Translate the contents rect into widget coordinates, since that's what | |
465 // DwmEnableBlurBehindWindow expects a region in. | |
466 gfx::Rect contents_rect = ConvertRectToWidget(GetContentsBounds()); | |
467 gfx::Path contents_path; | |
468 MakeContentsPath(&contents_path, contents_rect); | |
469 base::win::ScopedGDIObject<HRGN> popup_region; | |
470 popup_region.Set(contents_path.CreateNativeRegion()); | |
471 bb.hRgnBlur = popup_region.Get(); | |
472 DwmEnableBlurBehindWindow(GetWidget()->GetNativeView(), &bb); | |
473 #endif | |
474 } | |
475 | |
476 void OmniboxPopupContentsView::MakeCanvasTransparent(gfx::Canvas* canvas) { | |
477 // Allow the window blur effect to show through the popup background. | |
478 SkAlpha alpha = GetThemeProvider()->ShouldUseNativeFrame() ? | |
479 kGlassPopupAlpha : kOpaquePopupAlpha; | |
480 canvas->DrawColor(SkColorSetA( | |
481 result_view_at(0)->GetColor(OmniboxResultView::NORMAL, | |
482 OmniboxResultView::BACKGROUND), alpha), SkXfermode::kDstIn_Mode); | |
483 } | 472 } |
484 | 473 |
485 void OmniboxPopupContentsView::OpenIndex(size_t index, | 474 void OmniboxPopupContentsView::OpenIndex(size_t index, |
486 WindowOpenDisposition disposition) { | 475 WindowOpenDisposition disposition) { |
487 if (!HasMatchAt(index)) | 476 if (!HasMatchAt(index)) |
488 return; | 477 return; |
489 | 478 |
490 // OpenMatch() may close the popup, which will clear the result set and, by | 479 // OpenMatch() may close the popup, which will clear the result set and, by |
491 // extension, |match| and its contents. So copy the relevant match out to | 480 // extension, |match| and its contents. So copy the relevant match out to |
492 // make sure it stays alive until the call completes. | 481 // make sure it stays alive until the call completes. |
(...skipping 11 matching lines...) Expand all Loading... | |
504 for (int i = 0; i < nb_match; ++i) { | 493 for (int i = 0; i < nb_match; ++i) { |
505 views::View* child = child_at(i); | 494 views::View* child = child_at(i); |
506 gfx::Point point_in_child_coords(point); | 495 gfx::Point point_in_child_coords(point); |
507 View::ConvertPointToTarget(this, child, &point_in_child_coords); | 496 View::ConvertPointToTarget(this, child, &point_in_child_coords); |
508 if (child->HitTestPoint(point_in_child_coords)) | 497 if (child->HitTestPoint(point_in_child_coords)) |
509 return i; | 498 return i; |
510 } | 499 } |
511 return OmniboxPopupModel::kNoMatch; | 500 return OmniboxPopupModel::kNoMatch; |
512 } | 501 } |
513 | 502 |
514 gfx::Rect OmniboxPopupContentsView::CalculateTargetBounds(int h) { | 503 gfx::Rect OmniboxPopupContentsView::CalculateTargetBounds(int h) { |
Peter Kasting
2013/06/06 18:52:16
This can be inlined into its caller too
| |
515 gfx::Rect location_bar_bounds(location_bar_->GetContentsBounds()); | 504 gfx::Point top_left_screen_coord; |
516 const views::Border* border = location_bar_->border(); | 505 int width; |
517 if (border) { | 506 view_delegate_->GetPopupPositioningInfo( |
518 // Adjust for the border so that the bubble and location bar borders are | 507 &top_left_screen_coord, &width, &left_margin_, &right_margin_); |
519 // aligned. | 508 |
520 gfx::Insets insets = border->GetInsets(); | 509 return gfx::Rect(top_left_screen_coord, gfx::Size(width, h)); |
521 location_bar_bounds.Inset(insets.left(), 0, insets.right(), 0); | |
522 } else { | |
523 // The normal location bar is drawn using a background graphic that includes | |
524 // the border, so we inset by enough to make the edges line up, and the | |
525 // bubble appear at the same height as the Star bubble. | |
526 location_bar_bounds.Inset(LocationBarView::kNormalHorizontalEdgeThickness, | |
527 0); | |
528 } | |
529 gfx::Point location_bar_origin(location_bar_bounds.origin()); | |
530 views::View::ConvertPointToScreen(location_bar_, &location_bar_origin); | |
531 location_bar_bounds.set_origin(location_bar_origin); | |
532 return bubble_border_->GetBounds( | |
533 location_bar_bounds, gfx::Size(location_bar_bounds.width(), h)); | |
534 } | 510 } |
535 | 511 |
536 void OmniboxPopupContentsView::UpdateLineEvent( | 512 void OmniboxPopupContentsView::UpdateLineEvent( |
537 const ui::LocatedEvent& event, | 513 const ui::LocatedEvent& event, |
538 bool should_set_selected_line) { | 514 bool should_set_selected_line) { |
539 size_t index = GetIndexForPoint(event.location()); | 515 size_t index = GetIndexForPoint(event.location()); |
540 model_->SetHoveredLine(index); | 516 model_->SetHoveredLine(index); |
541 if (HasMatchAt(index) && should_set_selected_line) | 517 if (HasMatchAt(index) && should_set_selected_line) |
542 model_->SetSelectedLine(index, false, false); | 518 model_->SetSelectedLine(index, false, false); |
543 } | 519 } |
544 | 520 |
545 void OmniboxPopupContentsView::OpenSelectedLine( | 521 void OmniboxPopupContentsView::OpenSelectedLine( |
546 const ui::LocatedEvent& event, | 522 const ui::LocatedEvent& event, |
547 WindowOpenDisposition disposition) { | 523 WindowOpenDisposition disposition) { |
548 size_t index = GetIndexForPoint(event.location()); | 524 size_t index = GetIndexForPoint(event.location()); |
549 OpenIndex(index, disposition); | 525 OpenIndex(index, disposition); |
550 } | 526 } |
551 | 527 |
552 OmniboxResultView* OmniboxPopupContentsView::result_view_at(size_t i) { | 528 OmniboxResultView* OmniboxPopupContentsView::result_view_at(size_t i) { |
553 return static_cast<OmniboxResultView*>(child_at(static_cast<int>(i))); | 529 return static_cast<OmniboxResultView*>(child_at(static_cast<int>(i))); |
554 } | 530 } |
OLD | NEW |