| 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/autocomplete/autocomplete_popup_contents_view.
h" | 5 #include "chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h" |
| 6 | 6 |
| 7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
| 8 #include <commctrl.h> | 8 #include <commctrl.h> |
| 9 #include <dwmapi.h> | 9 #include <dwmapi.h> |
| 10 #include <objidl.h> | 10 #include <objidl.h> |
| 11 #endif | 11 #endif |
| 12 | 12 |
| 13 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
| 14 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
| 15 #include "chrome/browser/autocomplete/autocomplete_popup_model.h" | 15 #include "chrome/browser/autocomplete/autocomplete_popup_model.h" |
| 16 #include "chrome/browser/profiles/profile.h" | 16 #include "chrome/browser/profiles/profile.h" |
| 17 #include "chrome/browser/themes/theme_service.h" | 17 #include "chrome/browser/themes/theme_service.h" |
| 18 #include "chrome/browser/ui/omnibox/omnibox_view.h" | 18 #include "chrome/browser/ui/omnibox/omnibox_view.h" |
| 19 #include "chrome/browser/ui/views/autocomplete/autocomplete_result_view.h" | |
| 20 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" | 19 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" |
| 21 #include "chrome/browser/ui/views/autocomplete/touch_autocomplete_popup_contents
_view.h" | 20 #include "chrome/browser/ui/views/omnibox/omnibox_result_view.h" |
| 21 #include "chrome/browser/ui/views/omnibox/touch_omnibox_popup_contents_view.h" |
| 22 #include "grit/chromium_strings.h" | 22 #include "grit/chromium_strings.h" |
| 23 #include "grit/generated_resources.h" | 23 #include "grit/generated_resources.h" |
| 24 #include "grit/theme_resources.h" | 24 #include "grit/theme_resources.h" |
| 25 #include "third_party/skia/include/core/SkShader.h" | 25 #include "third_party/skia/include/core/SkShader.h" |
| 26 #include "ui/base/l10n/l10n_util.h" | 26 #include "ui/base/l10n/l10n_util.h" |
| 27 #include "ui/base/layout.h" | 27 #include "ui/base/layout.h" |
| 28 #include "ui/base/resource/resource_bundle.h" | 28 #include "ui/base/resource/resource_bundle.h" |
| 29 #include "ui/base/theme_provider.h" | 29 #include "ui/base/theme_provider.h" |
| 30 #include "ui/gfx/canvas.h" | 30 #include "ui/gfx/canvas.h" |
| 31 #include "ui/gfx/insets.h" | 31 #include "ui/gfx/insets.h" |
| (...skipping 26 matching lines...) Expand all Loading... |
| 58 // to gfx::Font::DeriveFont. | 58 // to gfx::Font::DeriveFont. |
| 59 #if defined(OS_CHROMEOS) | 59 #if defined(OS_CHROMEOS) |
| 60 // Don't adjust the size on Chrome OS (http://crbug.com/61433). | 60 // Don't adjust the size on Chrome OS (http://crbug.com/61433). |
| 61 const int kEditFontAdjust = 0; | 61 const int kEditFontAdjust = 0; |
| 62 #else | 62 #else |
| 63 const int kEditFontAdjust = -1; | 63 const int kEditFontAdjust = -1; |
| 64 #endif | 64 #endif |
| 65 | 65 |
| 66 } // namespace | 66 } // namespace |
| 67 | 67 |
| 68 class AutocompletePopupContentsView::AutocompletePopupWidget | 68 class OmniboxPopupContentsView::AutocompletePopupWidget |
| 69 : public views::Widget, | 69 : public views::Widget, |
| 70 public base::SupportsWeakPtr<AutocompletePopupWidget> { | 70 public base::SupportsWeakPtr<AutocompletePopupWidget> { |
| 71 public: | 71 public: |
| 72 AutocompletePopupWidget() {} | 72 AutocompletePopupWidget() {} |
| 73 virtual ~AutocompletePopupWidget() {} | 73 virtual ~AutocompletePopupWidget() {} |
| 74 | 74 |
| 75 private: | 75 private: |
| 76 DISALLOW_COPY_AND_ASSIGN(AutocompletePopupWidget); | 76 DISALLOW_COPY_AND_ASSIGN(AutocompletePopupWidget); |
| 77 }; | 77 }; |
| 78 | 78 |
| 79 //////////////////////////////////////////////////////////////////////////////// | 79 //////////////////////////////////////////////////////////////////////////////// |
| 80 // AutocompletePopupContentsView, public: | 80 // OmniboxPopupContentsView, public: |
| 81 | 81 |
| 82 AutocompletePopupContentsView* | 82 OmniboxPopupContentsView* OmniboxPopupContentsView::CreateForEnvironment( |
| 83 AutocompletePopupContentsView::CreateForEnvironment( | 83 const gfx::Font& font, |
| 84 const gfx::Font& font, | 84 OmniboxView* omnibox_view, |
| 85 OmniboxView* omnibox_view, | 85 AutocompleteEditModel* edit_model, |
| 86 AutocompleteEditModel* edit_model, | 86 views::View* location_bar) { |
| 87 views::View* location_bar) { | 87 OmniboxPopupContentsView* view = NULL; |
| 88 AutocompletePopupContentsView* view = NULL; | |
| 89 if (ui::GetDisplayLayout() == ui::LAYOUT_TOUCH) { | 88 if (ui::GetDisplayLayout() == ui::LAYOUT_TOUCH) { |
| 90 view = new TouchAutocompletePopupContentsView( | 89 view = new TouchOmniboxPopupContentsView( |
| 91 font, omnibox_view, edit_model, location_bar); | 90 font, omnibox_view, edit_model, location_bar); |
| 92 } else { | 91 } else { |
| 93 view = new AutocompletePopupContentsView( | 92 view = new OmniboxPopupContentsView( |
| 94 font, omnibox_view, edit_model, location_bar); | 93 font, omnibox_view, edit_model, location_bar); |
| 95 } | 94 } |
| 96 | 95 |
| 97 view->Init(); | 96 view->Init(); |
| 98 return view; | 97 return view; |
| 99 } | 98 } |
| 100 | 99 |
| 101 AutocompletePopupContentsView::AutocompletePopupContentsView( | 100 OmniboxPopupContentsView::OmniboxPopupContentsView( |
| 102 const gfx::Font& font, | 101 const gfx::Font& font, |
| 103 OmniboxView* omnibox_view, | 102 OmniboxView* omnibox_view, |
| 104 AutocompleteEditModel* edit_model, | 103 AutocompleteEditModel* edit_model, |
| 105 views::View* location_bar) | 104 views::View* location_bar) |
| 106 : model_(new AutocompletePopupModel(this, edit_model)), | 105 : model_(new AutocompletePopupModel(this, edit_model)), |
| 107 omnibox_view_(omnibox_view), | 106 omnibox_view_(omnibox_view), |
| 108 profile_(edit_model->profile()), | 107 profile_(edit_model->profile()), |
| 109 location_bar_(location_bar), | 108 location_bar_(location_bar), |
| 110 result_font_(font.DeriveFont(kEditFontAdjust)), | 109 result_font_(font.DeriveFont(kEditFontAdjust)), |
| 111 result_bold_font_(result_font_.DeriveFont(0, gfx::Font::BOLD)), | 110 result_bold_font_(result_font_.DeriveFont(0, gfx::Font::BOLD)), |
| 112 ignore_mouse_drag_(false), | 111 ignore_mouse_drag_(false), |
| 113 ALLOW_THIS_IN_INITIALIZER_LIST(size_animation_(this)) { | 112 ALLOW_THIS_IN_INITIALIZER_LIST(size_animation_(this)) { |
| 114 // The following little dance is required because set_border() requires a | 113 // The following little dance is required because set_border() requires a |
| 115 // pointer to a non-const object. | 114 // pointer to a non-const object. |
| 116 views::BubbleBorder* bubble_border = | 115 views::BubbleBorder* bubble_border = |
| 117 new views::BubbleBorder(views::BubbleBorder::NONE, | 116 new views::BubbleBorder(views::BubbleBorder::NONE, |
| 118 views::BubbleBorder::NO_SHADOW); | 117 views::BubbleBorder::NO_SHADOW); |
| 119 bubble_border_ = bubble_border; | 118 bubble_border_ = bubble_border; |
| 120 set_border(bubble_border); | 119 set_border(bubble_border); |
| 121 // The contents is owned by the LocationBarView. | 120 // The contents is owned by the LocationBarView. |
| 122 set_owned_by_client(); | 121 set_owned_by_client(); |
| 123 } | 122 } |
| 124 | 123 |
| 125 void AutocompletePopupContentsView::Init() { | 124 void OmniboxPopupContentsView::Init() { |
| 126 // This can't be done in the constructor as at that point we aren't | 125 // This can't be done in the constructor as at that point we aren't |
| 127 // necessarily our final class yet, and we may have subclasses | 126 // necessarily our final class yet, and we may have subclasses |
| 128 // overriding CreateResultView. | 127 // overriding CreateResultView. |
| 129 for (size_t i = 0; i < AutocompleteResult::kMaxMatches; ++i) { | 128 for (size_t i = 0; i < AutocompleteResult::kMaxMatches; ++i) { |
| 130 AutocompleteResultView* result_view = | 129 OmniboxResultView* result_view = |
| 131 CreateResultView(this, i, result_font_, result_bold_font_); | 130 CreateResultView(this, i, result_font_, result_bold_font_); |
| 132 result_view->SetVisible(false); | 131 result_view->SetVisible(false); |
| 133 AddChildViewAt(result_view, static_cast<int>(i)); | 132 AddChildViewAt(result_view, static_cast<int>(i)); |
| 134 } | 133 } |
| 135 } | 134 } |
| 136 | 135 |
| 137 AutocompletePopupContentsView::~AutocompletePopupContentsView() { | 136 OmniboxPopupContentsView::~OmniboxPopupContentsView() { |
| 138 // We don't need to do anything with |popup_| here. The OS either has already | 137 // We don't need to do anything with |popup_| here. The OS either has already |
| 139 // closed the window, in which case it's been deleted, or it will soon, in | 138 // closed the window, in which case it's been deleted, or it will soon, in |
| 140 // which case there's nothing we need to do. | 139 // which case there's nothing we need to do. |
| 141 } | 140 } |
| 142 | 141 |
| 143 gfx::Rect AutocompletePopupContentsView::GetPopupBounds() const { | 142 gfx::Rect OmniboxPopupContentsView::GetPopupBounds() const { |
| 144 if (!size_animation_.is_animating()) | 143 if (!size_animation_.is_animating()) |
| 145 return target_bounds_; | 144 return target_bounds_; |
| 146 | 145 |
| 147 gfx::Rect current_frame_bounds = start_bounds_; | 146 gfx::Rect current_frame_bounds = start_bounds_; |
| 148 int total_height_delta = target_bounds_.height() - start_bounds_.height(); | 147 int total_height_delta = target_bounds_.height() - start_bounds_.height(); |
| 149 // Round |current_height_delta| instead of truncating so we won't leave single | 148 // Round |current_height_delta| instead of truncating so we won't leave single |
| 150 // white pixels at the bottom of the popup as long when animating very small | 149 // white pixels at the bottom of the popup as long when animating very small |
| 151 // height differences. | 150 // height differences. |
| 152 int current_height_delta = static_cast<int>( | 151 int current_height_delta = static_cast<int>( |
| 153 size_animation_.GetCurrentValue() * total_height_delta - 0.5); | 152 size_animation_.GetCurrentValue() * total_height_delta - 0.5); |
| 154 current_frame_bounds.set_height( | 153 current_frame_bounds.set_height( |
| 155 current_frame_bounds.height() + current_height_delta); | 154 current_frame_bounds.height() + current_height_delta); |
| 156 return current_frame_bounds; | 155 return current_frame_bounds; |
| 157 } | 156 } |
| 158 | 157 |
| 159 void AutocompletePopupContentsView::LayoutChildren() { | 158 void OmniboxPopupContentsView::LayoutChildren() { |
| 160 gfx::Rect contents_rect = GetContentsBounds(); | 159 gfx::Rect contents_rect = GetContentsBounds(); |
| 161 int top = contents_rect.y(); | 160 int top = contents_rect.y(); |
| 162 for (int i = 0; i < child_count(); ++i) { | 161 for (int i = 0; i < child_count(); ++i) { |
| 163 View* v = child_at(i); | 162 View* v = child_at(i); |
| 164 if (v->visible()) { | 163 if (v->visible()) { |
| 165 v->SetBounds(contents_rect.x(), top, contents_rect.width(), | 164 v->SetBounds(contents_rect.x(), top, contents_rect.width(), |
| 166 v->GetPreferredSize().height()); | 165 v->GetPreferredSize().height()); |
| 167 top = v->bounds().bottom(); | 166 top = v->bounds().bottom(); |
| 168 } | 167 } |
| 169 } | 168 } |
| 170 } | 169 } |
| 171 | 170 |
| 172 //////////////////////////////////////////////////////////////////////////////// | 171 //////////////////////////////////////////////////////////////////////////////// |
| 173 // AutocompletePopupContentsView, AutocompletePopupView overrides: | 172 // OmniboxPopupContentsView, AutocompletePopupView overrides: |
| 174 | 173 |
| 175 bool AutocompletePopupContentsView::IsOpen() const { | 174 bool OmniboxPopupContentsView::IsOpen() const { |
| 176 return (popup_ != NULL); | 175 return popup_ != NULL; |
| 177 } | 176 } |
| 178 | 177 |
| 179 void AutocompletePopupContentsView::InvalidateLine(size_t line) { | 178 void OmniboxPopupContentsView::InvalidateLine(size_t line) { |
| 180 AutocompleteResultView* result = static_cast<AutocompleteResultView*>( | 179 OmniboxResultView* result = static_cast<OmniboxResultView*>( |
| 181 child_at(static_cast<int>(line))); | 180 child_at(static_cast<int>(line))); |
| 182 result->Invalidate(); | 181 result->Invalidate(); |
| 183 | 182 |
| 184 if (HasMatchAt(line) && GetMatchAtIndex(line).associated_keyword.get()) { | 183 if (HasMatchAt(line) && GetMatchAtIndex(line).associated_keyword.get()) { |
| 185 result->ShowKeyword(IsSelectedIndex(line) && | 184 result->ShowKeyword(IsSelectedIndex(line) && |
| 186 model_->selected_line_state() == AutocompletePopupModel::KEYWORD); | 185 model_->selected_line_state() == AutocompletePopupModel::KEYWORD); |
| 187 } | 186 } |
| 188 } | 187 } |
| 189 | 188 |
| 190 void AutocompletePopupContentsView::UpdatePopupAppearance() { | 189 void OmniboxPopupContentsView::UpdatePopupAppearance() { |
| 191 if (model_->result().empty()) { | 190 if (model_->result().empty()) { |
| 192 // No matches, close any existing popup. | 191 // No matches, close any existing popup. |
| 193 if (popup_ != NULL) { | 192 if (popup_ != NULL) { |
| 194 size_animation_.Stop(); | 193 size_animation_.Stop(); |
| 195 | 194 |
| 196 // NOTE: Do NOT use CloseNow() here, as we may be deep in a callstack | 195 // NOTE: Do NOT use CloseNow() here, as we may be deep in a callstack |
| 197 // triggered by the popup receiving a message (e.g. LBUTTONUP), and | 196 // triggered by the popup receiving a message (e.g. LBUTTONUP), and |
| 198 // destroying the popup would cause us to read garbage when we unwind back | 197 // destroying the popup would cause us to read garbage when we unwind back |
| 199 // to that level. | 198 // to that level. |
| 200 popup_->Close(); // This will eventually delete the popup. | 199 popup_->Close(); // This will eventually delete the popup. |
| 201 popup_.reset(); | 200 popup_.reset(); |
| 202 } | 201 } |
| 203 return; | 202 return; |
| 204 } | 203 } |
| 205 | 204 |
| 206 // Update the match cached by each row, in the process of doing so make sure | 205 // Update the match cached by each row, in the process of doing so make sure |
| 207 // we have enough row views. | 206 // we have enough row views. |
| 208 size_t child_rv_count = child_count(); | 207 size_t child_rv_count = child_count(); |
| 209 const size_t result_size = model_->result().size(); | 208 const size_t result_size = model_->result().size(); |
| 210 for (size_t i = 0; i < result_size; ++i) { | 209 for (size_t i = 0; i < result_size; ++i) { |
| 211 AutocompleteResultView* view = static_cast<AutocompleteResultView*>( | 210 OmniboxResultView* view = static_cast<OmniboxResultView*>(child_at(i)); |
| 212 child_at(i)); | |
| 213 view->SetMatch(GetMatchAtIndex(i)); | 211 view->SetMatch(GetMatchAtIndex(i)); |
| 214 view->SetVisible(true); | 212 view->SetVisible(true); |
| 215 } | 213 } |
| 216 for (size_t i = result_size; i < child_rv_count; ++i) | 214 for (size_t i = result_size; i < child_rv_count; ++i) |
| 217 child_at(i)->SetVisible(false); | 215 child_at(i)->SetVisible(false); |
| 218 | 216 |
| 219 gfx::Rect new_target_bounds = CalculateTargetBounds(CalculatePopupHeight()); | 217 gfx::Rect new_target_bounds = CalculateTargetBounds(CalculatePopupHeight()); |
| 220 | 218 |
| 221 // If we're animating and our target height changes, reset the animation. | 219 // If we're animating and our target height changes, reset the animation. |
| 222 // NOTE: If we just reset blindly on _every_ update, then when the user types | 220 // NOTE: If we just reset blindly on _every_ update, then when the user types |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 if (target_bounds_.height() < start_bounds_.height()) | 258 if (target_bounds_.height() < start_bounds_.height()) |
| 261 size_animation_.Show(); | 259 size_animation_.Show(); |
| 262 else | 260 else |
| 263 start_bounds_ = target_bounds_; | 261 start_bounds_ = target_bounds_; |
| 264 popup_->SetBounds(GetPopupBounds()); | 262 popup_->SetBounds(GetPopupBounds()); |
| 265 } | 263 } |
| 266 | 264 |
| 267 SchedulePaint(); | 265 SchedulePaint(); |
| 268 } | 266 } |
| 269 | 267 |
| 270 gfx::Rect AutocompletePopupContentsView::GetTargetBounds() { | 268 gfx::Rect OmniboxPopupContentsView::GetTargetBounds() { |
| 271 return target_bounds_; | 269 return target_bounds_; |
| 272 } | 270 } |
| 273 | 271 |
| 274 void AutocompletePopupContentsView::PaintUpdatesNow() { | 272 void OmniboxPopupContentsView::PaintUpdatesNow() { |
| 275 // TODO(beng): remove this from the interface. | 273 // TODO(beng): remove this from the interface. |
| 276 } | 274 } |
| 277 | 275 |
| 278 void AutocompletePopupContentsView::OnDragCanceled() { | 276 void OmniboxPopupContentsView::OnDragCanceled() { |
| 279 ignore_mouse_drag_ = true; | 277 ignore_mouse_drag_ = true; |
| 280 } | 278 } |
| 281 | 279 |
| 282 //////////////////////////////////////////////////////////////////////////////// | 280 //////////////////////////////////////////////////////////////////////////////// |
| 283 // AutocompletePopupContentsView, AutocompleteResultViewModel implementation: | 281 // OmniboxPopupContentsView, OmniboxResultViewModel implementation: |
| 284 | 282 |
| 285 bool AutocompletePopupContentsView::IsSelectedIndex(size_t index) const { | 283 bool OmniboxPopupContentsView::IsSelectedIndex(size_t index) const { |
| 286 return index == model_->selected_line(); | 284 return index == model_->selected_line(); |
| 287 } | 285 } |
| 288 | 286 |
| 289 bool AutocompletePopupContentsView::IsHoveredIndex(size_t index) const { | 287 bool OmniboxPopupContentsView::IsHoveredIndex(size_t index) const { |
| 290 return index == model_->hovered_line(); | 288 return index == model_->hovered_line(); |
| 291 } | 289 } |
| 292 | 290 |
| 293 const SkBitmap* AutocompletePopupContentsView::GetIconIfExtensionMatch( | 291 const SkBitmap* OmniboxPopupContentsView::GetIconIfExtensionMatch( |
| 294 size_t index) const { | 292 size_t index) const { |
| 295 if (!HasMatchAt(index)) | 293 if (!HasMatchAt(index)) |
| 296 return NULL; | 294 return NULL; |
| 297 return model_->GetIconIfExtensionMatch(GetMatchAtIndex(index)); | 295 return model_->GetIconIfExtensionMatch(GetMatchAtIndex(index)); |
| 298 } | 296 } |
| 299 | 297 |
| 300 //////////////////////////////////////////////////////////////////////////////// | 298 //////////////////////////////////////////////////////////////////////////////// |
| 301 // AutocompletePopupContentsView, AnimationDelegate implementation: | 299 // OmniboxPopupContentsView, AnimationDelegate implementation: |
| 302 | 300 |
| 303 void AutocompletePopupContentsView::AnimationProgressed( | 301 void OmniboxPopupContentsView::AnimationProgressed( |
| 304 const ui::Animation* animation) { | 302 const ui::Animation* animation) { |
| 305 // We should only be running the animation when the popup is already visible. | 303 // We should only be running the animation when the popup is already visible. |
| 306 DCHECK(popup_ != NULL); | 304 DCHECK(popup_ != NULL); |
| 307 popup_->SetBounds(GetPopupBounds()); | 305 popup_->SetBounds(GetPopupBounds()); |
| 308 } | 306 } |
| 309 | 307 |
| 310 //////////////////////////////////////////////////////////////////////////////// | 308 //////////////////////////////////////////////////////////////////////////////// |
| 311 // AutocompletePopupContentsView, views::View overrides: | 309 // OmniboxPopupContentsView, views::View overrides: |
| 312 | 310 |
| 313 void AutocompletePopupContentsView::Layout() { | 311 void OmniboxPopupContentsView::Layout() { |
| 314 UpdateBlurRegion(); | 312 UpdateBlurRegion(); |
| 315 | 313 |
| 316 // Size our children to the available content area. | 314 // Size our children to the available content area. |
| 317 LayoutChildren(); | 315 LayoutChildren(); |
| 318 | 316 |
| 319 // We need to manually schedule a paint here since we are a layered window and | 317 // We need to manually schedule a paint here since we are a layered window and |
| 320 // won't implicitly require painting until we ask for one. | 318 // won't implicitly require painting until we ask for one. |
| 321 SchedulePaint(); | 319 SchedulePaint(); |
| 322 } | 320 } |
| 323 | 321 |
| 324 views::View* AutocompletePopupContentsView::GetEventHandlerForPoint( | 322 views::View* OmniboxPopupContentsView::GetEventHandlerForPoint( |
| 325 const gfx::Point& point) { | 323 const gfx::Point& point) { |
| 326 return this; | 324 return this; |
| 327 } | 325 } |
| 328 | 326 |
| 329 bool AutocompletePopupContentsView::OnMousePressed( | 327 bool OmniboxPopupContentsView::OnMousePressed( |
| 330 const views::MouseEvent& event) { | 328 const views::MouseEvent& event) { |
| 331 ignore_mouse_drag_ = false; // See comment on |ignore_mouse_drag_| in header. | 329 ignore_mouse_drag_ = false; // See comment on |ignore_mouse_drag_| in header. |
| 332 if (event.IsLeftMouseButton() || event.IsMiddleMouseButton()) | 330 if (event.IsLeftMouseButton() || event.IsMiddleMouseButton()) |
| 333 UpdateLineEvent(event, event.IsLeftMouseButton()); | 331 UpdateLineEvent(event, event.IsLeftMouseButton()); |
| 334 return true; | 332 return true; |
| 335 } | 333 } |
| 336 | 334 |
| 337 bool AutocompletePopupContentsView::OnMouseDragged( | 335 bool OmniboxPopupContentsView::OnMouseDragged( |
| 338 const views::MouseEvent& event) { | 336 const views::MouseEvent& event) { |
| 339 if (event.IsLeftMouseButton() || event.IsMiddleMouseButton()) | 337 if (event.IsLeftMouseButton() || event.IsMiddleMouseButton()) |
| 340 UpdateLineEvent(event, !ignore_mouse_drag_ && event.IsLeftMouseButton()); | 338 UpdateLineEvent(event, !ignore_mouse_drag_ && event.IsLeftMouseButton()); |
| 341 return true; | 339 return true; |
| 342 } | 340 } |
| 343 | 341 |
| 344 void AutocompletePopupContentsView::OnMouseReleased( | 342 void OmniboxPopupContentsView::OnMouseReleased( |
| 345 const views::MouseEvent& event) { | 343 const views::MouseEvent& event) { |
| 346 if (ignore_mouse_drag_) { | 344 if (ignore_mouse_drag_) { |
| 347 OnMouseCaptureLost(); | 345 OnMouseCaptureLost(); |
| 348 return; | 346 return; |
| 349 } | 347 } |
| 350 | 348 |
| 351 if (event.IsOnlyMiddleMouseButton() || event.IsOnlyLeftMouseButton()) { | 349 if (event.IsOnlyMiddleMouseButton() || event.IsOnlyLeftMouseButton()) { |
| 352 OpenSelectedLine(event, event.IsOnlyLeftMouseButton() ? CURRENT_TAB : | 350 OpenSelectedLine(event, event.IsOnlyLeftMouseButton() ? CURRENT_TAB : |
| 353 NEW_BACKGROUND_TAB); | 351 NEW_BACKGROUND_TAB); |
| 354 } | 352 } |
| 355 } | 353 } |
| 356 | 354 |
| 357 void AutocompletePopupContentsView::OnMouseCaptureLost() { | 355 void OmniboxPopupContentsView::OnMouseCaptureLost() { |
| 358 ignore_mouse_drag_ = false; | 356 ignore_mouse_drag_ = false; |
| 359 } | 357 } |
| 360 | 358 |
| 361 void AutocompletePopupContentsView::OnMouseMoved( | 359 void OmniboxPopupContentsView::OnMouseMoved( |
| 362 const views::MouseEvent& event) { | 360 const views::MouseEvent& event) { |
| 363 model_->SetHoveredLine(GetIndexForPoint(event.location())); | 361 model_->SetHoveredLine(GetIndexForPoint(event.location())); |
| 364 } | 362 } |
| 365 | 363 |
| 366 void AutocompletePopupContentsView::OnMouseEntered( | 364 void OmniboxPopupContentsView::OnMouseEntered( |
| 367 const views::MouseEvent& event) { | 365 const views::MouseEvent& event) { |
| 368 model_->SetHoveredLine(GetIndexForPoint(event.location())); | 366 model_->SetHoveredLine(GetIndexForPoint(event.location())); |
| 369 } | 367 } |
| 370 | 368 |
| 371 void AutocompletePopupContentsView::OnMouseExited( | 369 void OmniboxPopupContentsView::OnMouseExited( |
| 372 const views::MouseEvent& event) { | 370 const views::MouseEvent& event) { |
| 373 model_->SetHoveredLine(AutocompletePopupModel::kNoMatch); | 371 model_->SetHoveredLine(AutocompletePopupModel::kNoMatch); |
| 374 } | 372 } |
| 375 | 373 |
| 376 ui::GestureStatus AutocompletePopupContentsView::OnGestureEvent( | 374 ui::GestureStatus OmniboxPopupContentsView::OnGestureEvent( |
| 377 const views::GestureEvent& event) { | 375 const views::GestureEvent& event) { |
| 378 switch (event.type()) { | 376 switch (event.type()) { |
| 379 case ui::ET_GESTURE_TAP_DOWN: | 377 case ui::ET_GESTURE_TAP_DOWN: |
| 380 case ui::ET_GESTURE_SCROLL_BEGIN: | 378 case ui::ET_GESTURE_SCROLL_BEGIN: |
| 381 case ui::ET_GESTURE_SCROLL_UPDATE: | 379 case ui::ET_GESTURE_SCROLL_UPDATE: |
| 382 UpdateLineEvent(event, true); | 380 UpdateLineEvent(event, true); |
| 383 break; | 381 break; |
| 384 case ui::ET_GESTURE_TAP: | 382 case ui::ET_GESTURE_TAP: |
| 385 case ui::ET_GESTURE_SCROLL_END: | 383 case ui::ET_GESTURE_SCROLL_END: |
| 386 OpenSelectedLine(event, CURRENT_TAB); | 384 OpenSelectedLine(event, CURRENT_TAB); |
| 387 break; | 385 break; |
| 388 default: | 386 default: |
| 389 return ui::GESTURE_STATUS_UNKNOWN; | 387 return ui::GESTURE_STATUS_UNKNOWN; |
| 390 } | 388 } |
| 391 return ui::GESTURE_STATUS_CONSUMED; | 389 return ui::GESTURE_STATUS_CONSUMED; |
| 392 } | 390 } |
| 393 | 391 |
| 394 //////////////////////////////////////////////////////////////////////////////// | 392 //////////////////////////////////////////////////////////////////////////////// |
| 395 // AutocompletePopupContentsView, protected: | 393 // OmniboxPopupContentsView, protected: |
| 396 | 394 |
| 397 void AutocompletePopupContentsView::PaintResultViews(gfx::Canvas* canvas) { | 395 void OmniboxPopupContentsView::PaintResultViews(gfx::Canvas* canvas) { |
| 398 canvas->DrawColor(AutocompleteResultView::GetColor( | 396 canvas->DrawColor(OmniboxResultView::GetColor( |
| 399 AutocompleteResultView::NORMAL, AutocompleteResultView::BACKGROUND)); | 397 OmniboxResultView::NORMAL, OmniboxResultView::BACKGROUND)); |
| 400 View::PaintChildren(canvas); | 398 View::PaintChildren(canvas); |
| 401 } | 399 } |
| 402 | 400 |
| 403 int AutocompletePopupContentsView::CalculatePopupHeight() { | 401 int OmniboxPopupContentsView::CalculatePopupHeight() { |
| 404 DCHECK_GE(static_cast<size_t>(child_count()), model_->result().size()); | 402 DCHECK_GE(static_cast<size_t>(child_count()), model_->result().size()); |
| 405 int popup_height = 0; | 403 int popup_height = 0; |
| 406 for (size_t i = 0; i < model_->result().size(); ++i) | 404 for (size_t i = 0; i < model_->result().size(); ++i) |
| 407 popup_height += child_at(i)->GetPreferredSize().height(); | 405 popup_height += child_at(i)->GetPreferredSize().height(); |
| 408 return popup_height; | 406 return popup_height; |
| 409 } | 407 } |
| 410 | 408 |
| 411 AutocompleteResultView* AutocompletePopupContentsView::CreateResultView( | 409 OmniboxResultView* OmniboxPopupContentsView::CreateResultView( |
| 412 AutocompleteResultViewModel* model, | 410 OmniboxResultViewModel* model, |
| 413 int model_index, | 411 int model_index, |
| 414 const gfx::Font& font, | 412 const gfx::Font& font, |
| 415 const gfx::Font& bold_font) { | 413 const gfx::Font& bold_font) { |
| 416 return new AutocompleteResultView(model, model_index, font, bold_font); | 414 return new OmniboxResultView(model, model_index, font, bold_font); |
| 417 } | 415 } |
| 418 | 416 |
| 419 //////////////////////////////////////////////////////////////////////////////// | 417 //////////////////////////////////////////////////////////////////////////////// |
| 420 // AutocompletePopupContentsView, views::View overrides, protected: | 418 // OmniboxPopupContentsView, views::View overrides, protected: |
| 421 | 419 |
| 422 void AutocompletePopupContentsView::OnPaint(gfx::Canvas* canvas) { | 420 void OmniboxPopupContentsView::OnPaint(gfx::Canvas* canvas) { |
| 423 gfx::Path path; | 421 gfx::Path path; |
| 424 MakeContentsPath(&path, GetContentsBounds()); | 422 MakeContentsPath(&path, GetContentsBounds()); |
| 425 canvas->Save(); | 423 canvas->Save(); |
| 426 canvas->sk_canvas()->clipPath(path, | 424 canvas->sk_canvas()->clipPath(path, |
| 427 SkRegion::kIntersect_Op, | 425 SkRegion::kIntersect_Op, |
| 428 true /* doAntialias */); | 426 true /* doAntialias */); |
| 429 PaintResultViews(canvas); | 427 PaintResultViews(canvas); |
| 430 | 428 |
| 431 // We want the contents background to be slightly transparent so we can see | 429 // We want the contents background to be slightly transparent so we can see |
| 432 // the blurry glass effect on DWM systems behind. We do this _after_ we paint | 430 // the blurry glass effect on DWM systems behind. We do this _after_ we paint |
| 433 // the children since they paint text, and GDI will reset this alpha data if | 431 // the children since they paint text, and GDI will reset this alpha data if |
| 434 // we paint text after this call. | 432 // we paint text after this call. |
| 435 MakeCanvasTransparent(canvas); | 433 MakeCanvasTransparent(canvas); |
| 436 canvas->Restore(); | 434 canvas->Restore(); |
| 437 | 435 |
| 438 // Now we paint the border, so it will be alpha-blended atop the contents. | 436 // Now we paint the border, so it will be alpha-blended atop the contents. |
| 439 // This looks slightly better in the corners than drawing the contents atop | 437 // This looks slightly better in the corners than drawing the contents atop |
| 440 // the border. | 438 // the border. |
| 441 OnPaintBorder(canvas); | 439 OnPaintBorder(canvas); |
| 442 } | 440 } |
| 443 | 441 |
| 444 void AutocompletePopupContentsView::PaintChildren(gfx::Canvas* canvas) { | 442 void OmniboxPopupContentsView::PaintChildren(gfx::Canvas* canvas) { |
| 445 // We paint our children inside OnPaint(). | 443 // We paint our children inside OnPaint(). |
| 446 } | 444 } |
| 447 | 445 |
| 448 //////////////////////////////////////////////////////////////////////////////// | 446 //////////////////////////////////////////////////////////////////////////////// |
| 449 // AutocompletePopupContentsView, private: | 447 // OmniboxPopupContentsView, private: |
| 450 | 448 |
| 451 bool AutocompletePopupContentsView::HasMatchAt(size_t index) const { | 449 bool OmniboxPopupContentsView::HasMatchAt(size_t index) const { |
| 452 return index < model_->result().size(); | 450 return index < model_->result().size(); |
| 453 } | 451 } |
| 454 | 452 |
| 455 const AutocompleteMatch& AutocompletePopupContentsView::GetMatchAtIndex( | 453 const AutocompleteMatch& OmniboxPopupContentsView::GetMatchAtIndex( |
| 456 size_t index) const { | 454 size_t index) const { |
| 457 return model_->result().match_at(index); | 455 return model_->result().match_at(index); |
| 458 } | 456 } |
| 459 | 457 |
| 460 void AutocompletePopupContentsView::MakeContentsPath( | 458 void OmniboxPopupContentsView::MakeContentsPath( |
| 461 gfx::Path* path, | 459 gfx::Path* path, |
| 462 const gfx::Rect& bounding_rect) { | 460 const gfx::Rect& bounding_rect) { |
| 463 SkRect rect; | 461 SkRect rect; |
| 464 rect.set(SkIntToScalar(bounding_rect.x()), | 462 rect.set(SkIntToScalar(bounding_rect.x()), |
| 465 SkIntToScalar(bounding_rect.y()), | 463 SkIntToScalar(bounding_rect.y()), |
| 466 SkIntToScalar(bounding_rect.right()), | 464 SkIntToScalar(bounding_rect.right()), |
| 467 SkIntToScalar(bounding_rect.bottom())); | 465 SkIntToScalar(bounding_rect.bottom())); |
| 468 | 466 |
| 469 SkScalar radius = SkIntToScalar(views::BubbleBorder::GetCornerRadius()); | 467 SkScalar radius = SkIntToScalar(views::BubbleBorder::GetCornerRadius()); |
| 470 path->addRoundRect(rect, radius, radius); | 468 path->addRoundRect(rect, radius, radius); |
| 471 } | 469 } |
| 472 | 470 |
| 473 void AutocompletePopupContentsView::UpdateBlurRegion() { | 471 void OmniboxPopupContentsView::UpdateBlurRegion() { |
| 474 #if defined(OS_WIN) && !defined(USE_AURA) | 472 #if defined(OS_WIN) && !defined(USE_AURA) |
| 475 // We only support background blurring on Vista with Aero-Glass enabled. | 473 // We only support background blurring on Vista with Aero-Glass enabled. |
| 476 if (!views::NativeWidgetWin::IsAeroGlassEnabled() || !GetWidget()) | 474 if (!views::NativeWidgetWin::IsAeroGlassEnabled() || !GetWidget()) |
| 477 return; | 475 return; |
| 478 | 476 |
| 479 // Provide a blurred background effect within the contents region of the | 477 // Provide a blurred background effect within the contents region of the |
| 480 // popup. | 478 // popup. |
| 481 DWM_BLURBEHIND bb = {0}; | 479 DWM_BLURBEHIND bb = {0}; |
| 482 bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION; | 480 bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION; |
| 483 bb.fEnable = true; | 481 bb.fEnable = true; |
| 484 | 482 |
| 485 // Translate the contents rect into widget coordinates, since that's what | 483 // Translate the contents rect into widget coordinates, since that's what |
| 486 // DwmEnableBlurBehindWindow expects a region in. | 484 // DwmEnableBlurBehindWindow expects a region in. |
| 487 gfx::Rect contents_rect = ConvertRectToWidget(GetContentsBounds()); | 485 gfx::Rect contents_rect = ConvertRectToWidget(GetContentsBounds()); |
| 488 gfx::Path contents_path; | 486 gfx::Path contents_path; |
| 489 MakeContentsPath(&contents_path, contents_rect); | 487 MakeContentsPath(&contents_path, contents_rect); |
| 490 base::win::ScopedGDIObject<HRGN> popup_region; | 488 base::win::ScopedGDIObject<HRGN> popup_region; |
| 491 popup_region.Set(contents_path.CreateNativeRegion()); | 489 popup_region.Set(contents_path.CreateNativeRegion()); |
| 492 bb.hRgnBlur = popup_region.Get(); | 490 bb.hRgnBlur = popup_region.Get(); |
| 493 DwmEnableBlurBehindWindow(GetWidget()->GetNativeView(), &bb); | 491 DwmEnableBlurBehindWindow(GetWidget()->GetNativeView(), &bb); |
| 494 #endif | 492 #endif |
| 495 } | 493 } |
| 496 | 494 |
| 497 void AutocompletePopupContentsView::MakeCanvasTransparent( | 495 void OmniboxPopupContentsView::MakeCanvasTransparent(gfx::Canvas* canvas) { |
| 498 gfx::Canvas* canvas) { | |
| 499 // Allow the window blur effect to show through the popup background. | 496 // Allow the window blur effect to show through the popup background. |
| 500 SkAlpha alpha = GetThemeProvider()->ShouldUseNativeFrame() ? | 497 SkAlpha alpha = GetThemeProvider()->ShouldUseNativeFrame() ? |
| 501 kGlassPopupAlpha : kOpaquePopupAlpha; | 498 kGlassPopupAlpha : kOpaquePopupAlpha; |
| 502 canvas->DrawColor(SkColorSetA( | 499 canvas->DrawColor(SkColorSetA( |
| 503 AutocompleteResultView::GetColor(AutocompleteResultView::NORMAL, | 500 OmniboxResultView::GetColor(OmniboxResultView::NORMAL, |
| 504 AutocompleteResultView::BACKGROUND), alpha), SkXfermode::kDstIn_Mode); | 501 OmniboxResultView::BACKGROUND), alpha), SkXfermode::kDstIn_Mode); |
| 505 } | 502 } |
| 506 | 503 |
| 507 void AutocompletePopupContentsView::OpenIndex( | 504 void OmniboxPopupContentsView::OpenIndex(size_t index, |
| 508 size_t index, | 505 WindowOpenDisposition disposition) { |
| 509 WindowOpenDisposition disposition) { | |
| 510 if (!HasMatchAt(index)) | 506 if (!HasMatchAt(index)) |
| 511 return; | 507 return; |
| 512 | 508 |
| 513 // OpenMatch() may close the popup, which will clear the result set and, by | 509 // OpenMatch() may close the popup, which will clear the result set and, by |
| 514 // extension, |match| and its contents. So copy the relevant match out to | 510 // extension, |match| and its contents. So copy the relevant match out to |
| 515 // make sure it stays alive until the call completes. | 511 // make sure it stays alive until the call completes. |
| 516 AutocompleteMatch match = model_->result().match_at(index); | 512 AutocompleteMatch match = model_->result().match_at(index); |
| 517 omnibox_view_->OpenMatch(match, disposition, GURL(), index); | 513 omnibox_view_->OpenMatch(match, disposition, GURL(), index); |
| 518 } | 514 } |
| 519 | 515 |
| 520 size_t AutocompletePopupContentsView::GetIndexForPoint( | 516 size_t OmniboxPopupContentsView::GetIndexForPoint( |
| 521 const gfx::Point& point) { | 517 const gfx::Point& point) { |
| 522 if (!HitTest(point)) | 518 if (!HitTest(point)) |
| 523 return AutocompletePopupModel::kNoMatch; | 519 return AutocompletePopupModel::kNoMatch; |
| 524 | 520 |
| 525 int nb_match = model_->result().size(); | 521 int nb_match = model_->result().size(); |
| 526 DCHECK(nb_match <= child_count()); | 522 DCHECK(nb_match <= child_count()); |
| 527 for (int i = 0; i < nb_match; ++i) { | 523 for (int i = 0; i < nb_match; ++i) { |
| 528 views::View* child = child_at(i); | 524 views::View* child = child_at(i); |
| 529 gfx::Point point_in_child_coords(point); | 525 gfx::Point point_in_child_coords(point); |
| 530 View::ConvertPointToView(this, child, &point_in_child_coords); | 526 View::ConvertPointToView(this, child, &point_in_child_coords); |
| 531 if (child->HitTest(point_in_child_coords)) | 527 if (child->HitTest(point_in_child_coords)) |
| 532 return i; | 528 return i; |
| 533 } | 529 } |
| 534 return AutocompletePopupModel::kNoMatch; | 530 return AutocompletePopupModel::kNoMatch; |
| 535 } | 531 } |
| 536 | 532 |
| 537 gfx::Rect AutocompletePopupContentsView::CalculateTargetBounds(int h) { | 533 gfx::Rect OmniboxPopupContentsView::CalculateTargetBounds(int h) { |
| 538 gfx::Rect location_bar_bounds(location_bar_->GetContentsBounds()); | 534 gfx::Rect location_bar_bounds(location_bar_->GetContentsBounds()); |
| 539 const views::Border* border = location_bar_->border(); | 535 const views::Border* border = location_bar_->border(); |
| 540 if (border) { | 536 if (border) { |
| 541 // Adjust for the border so that the bubble and location bar borders are | 537 // Adjust for the border so that the bubble and location bar borders are |
| 542 // aligned. | 538 // aligned. |
| 543 gfx::Insets insets; | 539 gfx::Insets insets; |
| 544 border->GetInsets(&insets); | 540 border->GetInsets(&insets); |
| 545 location_bar_bounds.Inset(insets.left(), 0, insets.right(), 0); | 541 location_bar_bounds.Inset(insets.left(), 0, insets.right(), 0); |
| 546 } else { | 542 } else { |
| 547 // The normal location bar is drawn using a background graphic that includes | 543 // The normal location bar is drawn using a background graphic that includes |
| 548 // the border, so we inset by enough to make the edges line up, and the | 544 // the border, so we inset by enough to make the edges line up, and the |
| 549 // bubble appear at the same height as the Star bubble. | 545 // bubble appear at the same height as the Star bubble. |
| 550 location_bar_bounds.Inset(LocationBarView::kNormalHorizontalEdgeThickness, | 546 location_bar_bounds.Inset(LocationBarView::kNormalHorizontalEdgeThickness, |
| 551 0); | 547 0); |
| 552 } | 548 } |
| 553 gfx::Point location_bar_origin(location_bar_bounds.origin()); | 549 gfx::Point location_bar_origin(location_bar_bounds.origin()); |
| 554 views::View::ConvertPointToScreen(location_bar_, &location_bar_origin); | 550 views::View::ConvertPointToScreen(location_bar_, &location_bar_origin); |
| 555 location_bar_bounds.set_origin(location_bar_origin); | 551 location_bar_bounds.set_origin(location_bar_origin); |
| 556 return bubble_border_->GetBounds( | 552 return bubble_border_->GetBounds( |
| 557 location_bar_bounds, gfx::Size(location_bar_bounds.width(), h)); | 553 location_bar_bounds, gfx::Size(location_bar_bounds.width(), h)); |
| 558 } | 554 } |
| 559 | 555 |
| 560 void AutocompletePopupContentsView::UpdateLineEvent( | 556 void OmniboxPopupContentsView::UpdateLineEvent( |
| 561 const views::LocatedEvent& event, | 557 const views::LocatedEvent& event, |
| 562 bool should_set_selected_line) { | 558 bool should_set_selected_line) { |
| 563 size_t index = GetIndexForPoint(event.location()); | 559 size_t index = GetIndexForPoint(event.location()); |
| 564 model_->SetHoveredLine(index); | 560 model_->SetHoveredLine(index); |
| 565 if (HasMatchAt(index) && should_set_selected_line) | 561 if (HasMatchAt(index) && should_set_selected_line) |
| 566 model_->SetSelectedLine(index, false, false); | 562 model_->SetSelectedLine(index, false, false); |
| 567 } | 563 } |
| 568 | 564 |
| 569 void AutocompletePopupContentsView::OpenSelectedLine( | 565 void OmniboxPopupContentsView::OpenSelectedLine( |
| 570 const views::LocatedEvent& event, | 566 const views::LocatedEvent& event, |
| 571 WindowOpenDisposition disposition) { | 567 WindowOpenDisposition disposition) { |
| 572 size_t index = GetIndexForPoint(event.location()); | 568 size_t index = GetIndexForPoint(event.location()); |
| 573 OpenIndex(index, disposition); | 569 OpenIndex(index, disposition); |
| 574 } | 570 } |
| OLD | NEW |