| 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 | 
|---|