172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/autocomplete/autocomplete_popup_contents_view.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/compiler_specific.h" 8731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/utf_string_conversions.h" 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/autocomplete/autocomplete_edit_view.h" 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/autocomplete/autocomplete_popup_model.h" 114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/instant/instant_confirm_dialog.h" 124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/instant/promo_counter.h" 1321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h" 14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/views/autocomplete/autocomplete_result_view.h" 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/views/bubble/bubble_border.h" 1672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/location_bar/location_bar_view.h" 17731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "grit/chromium_strings.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/theme_resources.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "third_party/skia/include/core/SkShader.h" 2172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h" 2272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/resource/resource_bundle.h" 2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/theme_provider.h" 2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/canvas_skia.h" 2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/insets.h" 2672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/path.h" 27731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "unicode/ubidi.h" 28731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "views/controls/button/text_button.h" 29731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "views/controls/label.h" 3072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "views/layout/grid_layout.h" 3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "views/layout/layout_constants.h" 32731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "views/painter.h" 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/widget/widget.h" 34731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "views/window/window.h" 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN) 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <commctrl.h> 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <dwmapi.h> 3972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include <objidl.h> 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/win/scoped_gdi_object.h" 4272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "views/widget/widget_win.h" 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#if defined(OS_LINUX) 4672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/skia_utils_gtk.h" 473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#endif 483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst SkAlpha kGlassPopupAlpha = 240; 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst SkAlpha kOpaquePopupAlpha = 255; 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The size delta between the font used for the edit and the result rows. Passed 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// to gfx::Font::DeriveFont. 5572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#if defined(OS_CHROMEOS) 5672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Don't adjust the size on Chrome OS (http://crbug.com/61433). 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kEditFontAdjust = 0; 58201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#else 59201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst int kEditFontAdjust = -1; 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 62731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Horizontal padding between the buttons on the opt in promo. 63731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst int kOptInButtonPadding = 2; 64731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 65731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Padding around the opt in view. 66731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst int kOptInLeftPadding = 12; 674a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochconst int kOptInRightPadding = 10; 68731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst int kOptInTopPadding = 6; 694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochconst int kOptInBottomPadding = 5; 70731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 714a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// Horizontal/Vertical inset of the promo background. 724a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochconst int kOptInBackgroundHInset = 6; 734a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochconst int kOptInBackgroundVInset = 2; 74731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 75731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Border for instant opt-in buttons. Consists of two 9 patch painters: one for 76731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// the normal state, the other for the pressed state. 77731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickclass OptInButtonBorder : public views::Border { 78731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick public: 79731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick OptInButtonBorder() { 80731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick border_painter_.reset(CreatePainter(IDR_OPT_IN_BUTTON)); 81731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick border_pushed_painter_.reset(CreatePainter(IDR_OPT_IN_BUTTON_P)); 82731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 83731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 84731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick virtual void Paint(const views::View& view, gfx::Canvas* canvas) const { 85731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick views::Painter* painter; 86731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (static_cast<const views::CustomButton&>(view).state() == 87731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick views::CustomButton::BS_PUSHED) { 88731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick painter = border_pushed_painter_.get(); 89731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 90731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick painter = border_painter_.get(); 91731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 92731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick painter->Paint(view.width(), view.height(), canvas); 93731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 94731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 95731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick virtual void GetInsets(gfx::Insets* insets) const { 96731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick insets->Set(3, 8, 3, 8); 97731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 98731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 99731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick private: 100731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Creates 9 patch painter from the image with the id |image_id|. 101731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick views::Painter* CreatePainter(int image_id) { 102731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SkBitmap* image = 103731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ResourceBundle::GetSharedInstance().GetBitmapNamed(image_id); 104731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick int w = image->width() / 2; 105731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (image->width() % 2 == 0) 106731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick w--; 107731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick int h = image->height() / 2; 108731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (image->height() % 2 == 0) 109731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick h--; 110731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick gfx::Insets insets(h, w, h, w); 111731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return views::Painter::CreateImagePainter(*image, insets, true); 112731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 113731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 114731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<views::Painter> border_painter_; 115731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<views::Painter> border_pushed_painter_; 116731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 117731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DISALLOW_COPY_AND_ASSIGN(OptInButtonBorder); 118731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}; 119731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 120731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} // namespace 121731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 122731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickclass AutocompletePopupContentsView::InstantOptInView 123731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick : public views::View, 124731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick public views::ButtonListener { 125731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick public: 126731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick InstantOptInView(AutocompletePopupContentsView* contents_view, 127731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const gfx::Font& label_font, 128731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const gfx::Font& button_font) 1294a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch : contents_view_(contents_view), 1304a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch bg_painter_(views::Painter::CreateVerticalGradient( 1314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch SkColorSetRGB(255, 242, 183), 1324a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch SkColorSetRGB(250, 230, 145))) { 1333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen views::Label* label = new views::Label( 1343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen UTF16ToWide(l10n_util::GetStringUTF16(IDS_INSTANT_OPT_IN_LABEL))); 135731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick label->SetFont(label_font); 136731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 137731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick views::GridLayout* layout = new views::GridLayout(this); 138731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick layout->SetInsets(kOptInTopPadding, kOptInLeftPadding, 139731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick kOptInBottomPadding, kOptInRightPadding); 140731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SetLayoutManager(layout); 141731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 142731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const int first_column_set = 1; 143731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick views::GridLayout::Alignment v_align = views::GridLayout::CENTER; 144731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick views::ColumnSet* column_set = layout->AddColumnSet(first_column_set); 145731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick column_set->AddColumn(views::GridLayout::TRAILING, v_align, 1, 146731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick views::GridLayout::USE_PREF, 0, 0); 14772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); 148731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick column_set->AddColumn(views::GridLayout::CENTER, v_align, 0, 149731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick views::GridLayout::USE_PREF, 0, 0); 150731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick column_set->AddPaddingColumn(0, kOptInButtonPadding); 151731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick column_set->AddColumn(views::GridLayout::CENTER, v_align, 0, 152731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick views::GridLayout::USE_PREF, 0, 0); 153731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick column_set->LinkColumnSizes(2, 4, -1); 154731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick layout->StartRow(0, first_column_set); 155731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick layout->AddView(label); 156731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick layout->AddView(CreateButton(IDS_INSTANT_OPT_IN_ENABLE, button_font)); 157731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick layout->AddView(CreateButton(IDS_INSTANT_OPT_IN_NO_THANKS, button_font)); 158731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 159731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 160731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick virtual void ButtonPressed(views::Button* sender, const views::Event& event) { 161731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick contents_view_->UserPressedOptIn( 162731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick sender->tag() == IDS_INSTANT_OPT_IN_ENABLE); 163731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // WARNING: we've been deleted. 164731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 165731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 166dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen virtual void OnPaint(gfx::Canvas* canvas) { 1674a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch canvas->Save(); 1684a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch canvas->TranslateInt(kOptInBackgroundHInset, kOptInBackgroundVInset); 1694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch bg_painter_->Paint(width() - kOptInBackgroundHInset * 2, 1704a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch height() - kOptInBackgroundVInset * 2, canvas); 1714a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch canvas->DrawRectInt(ResourceBundle::toolbar_separator_color, 0, 0, 1724a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch width() - kOptInBackgroundHInset * 2, 1734a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch height() - kOptInBackgroundVInset * 2); 1744a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch canvas->Restore(); 175731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 176731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 177731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick private: 178731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Creates and returns a button configured for the opt-in promo. 179731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick views::View* CreateButton(int id, const gfx::Font& font) { 180731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // NOTE: we can't use NativeButton as the popup is a layered window and 181731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // native buttons don't draw in layered windows. 182731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // TODO: these buttons look crap. Figure out the right border/background to 183731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // use. 184731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick views::TextButton* button = 1853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen new views::TextButton(this, UTF16ToWide(l10n_util::GetStringUTF16(id))); 186731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick button->set_border(new OptInButtonBorder()); 187731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick button->SetNormalHasBorder(true); 188731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick button->set_tag(id); 189731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick button->SetFont(font); 190731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick button->set_animate_on_state_change(false); 191731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return button; 192731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 193731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 194731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick AutocompletePopupContentsView* contents_view_; 1954a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch scoped_ptr<views::Painter> bg_painter_; 196731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 197731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DISALLOW_COPY_AND_ASSIGN(InstantOptInView); 198731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}; 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//////////////////////////////////////////////////////////////////////////////// 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// AutocompletePopupContentsView, public: 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochAutocompletePopupContentsView::AutocompletePopupContentsView( 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const gfx::Font& font, 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AutocompleteEditView* edit_view, 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AutocompleteEditModel* edit_model, 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile, 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const views::View* location_bar) 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : model_(new AutocompletePopupModel(this, edit_model, profile)), 210dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen opt_in_view_(NULL), 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch edit_view_(edit_view), 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch location_bar_(location_bar), 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result_font_(font.DeriveFont(kEditFontAdjust)), 2143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick result_bold_font_(result_font_.DeriveFont(0, gfx::Font::BOLD)), 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ignore_mouse_drag_(false), 216dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ALLOW_THIS_IN_INITIALIZER_LIST(size_animation_(this)) { 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The following little dance is required because set_border() requires a 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // pointer to a non-const object. 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BubbleBorder* bubble_border = new BubbleBorder(BubbleBorder::NONE); 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bubble_border_ = bubble_border; 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch set_border(bubble_border); 222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // The contents is owned by the LocationBarView. 223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen set_parent_owned(false); 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochAutocompletePopupContentsView::~AutocompletePopupContentsView() { 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We don't need to do anything with |popup_| here. The OS either has already 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // closed the window, in which case it's been deleted, or it will soon, in 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // which case there's nothing we need to do. 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Rect AutocompletePopupContentsView::GetPopupBounds() const { 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!size_animation_.is_animating()) 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return target_bounds_; 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Rect current_frame_bounds = start_bounds_; 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int total_height_delta = target_bounds_.height() - start_bounds_.height(); 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Round |current_height_delta| instead of truncating so we won't leave single 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // white pixels at the bottom of the popup as long when animating very small 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // height differences. 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int current_height_delta = static_cast<int>( 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_animation_.GetCurrentValue() * total_height_delta - 0.5); 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch current_frame_bounds.set_height( 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch current_frame_bounds.height() + current_height_delta); 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return current_frame_bounds; 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid AutocompletePopupContentsView::LayoutChildren() { 249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gfx::Rect contents_rect = GetContentsBounds(); 250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int top = contents_rect.y(); 251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (int i = 0; i < child_count(); ++i) { 252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen View* v = GetChildViewAt(i); 253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (v->IsVisible()) { 254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen v->SetBounds(contents_rect.x(), top, contents_rect.width(), 255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen v->GetPreferredSize().height()); 256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen top = v->bounds().bottom(); 257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//////////////////////////////////////////////////////////////////////////////// 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// AutocompletePopupContentsView, AutocompletePopupView overrides: 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool AutocompletePopupContentsView::IsOpen() const { 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return (popup_ != NULL); 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutocompletePopupContentsView::InvalidateLine(size_t line) { 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GetChildViewAt(static_cast<int>(line))->SchedulePaint(); 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutocompletePopupContentsView::UpdatePopupAppearance() { 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (model_->result().empty()) { 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // No matches, close any existing popup. 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (popup_ != NULL) { 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_animation_.Stop(); 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // NOTE: Do NOT use CloseNow() here, as we may be deep in a callstack 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // triggered by the popup receiving a message (e.g. LBUTTONUP), and 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // destroying the popup would cause us to read garbage when we unwind back 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to that level. 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch popup_->Close(); // This will eventually delete the popup. 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch popup_.reset(); 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Update the match cached by each row, in the process of doing so make sure 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // we have enough row views. 28972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen size_t child_rv_count = child_count(); 290731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (opt_in_view_) { 291731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(child_rv_count > 0); 292731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick child_rv_count--; 293731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < model_->result().size(); ++i) { 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AutocompleteResultView* result_view; 296731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (i >= child_rv_count) { 2973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick result_view = 298dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CreateResultView(this, i, result_font_, result_bold_font_); 29972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen AddChildViewAt(result_view, static_cast<int>(i)); 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result_view = static_cast<AutocompleteResultView*>(GetChildViewAt(i)); 302731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick result_view->SetVisible(true); 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen result_view->SetMatch(GetMatchAtIndex(i)); 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 306731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (size_t i = model_->result().size(); i < child_rv_count; ++i) 307731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick GetChildViewAt(i)->SetVisible(false); 308731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 3094a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch PromoCounter* counter = model_->profile()->GetInstantPromoCounter(); 3104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (!opt_in_view_ && counter && counter->ShouldShow(base::Time::Now())) { 311731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick opt_in_view_ = new InstantOptInView(this, result_bold_font_, result_font_); 312731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick AddChildView(opt_in_view_); 3134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } else if (opt_in_view_ && (!counter || 3144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch !counter->ShouldShow(base::Time::Now()))) { 3154a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch delete opt_in_view_; 3164a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch opt_in_view_ = NULL; 317731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 318731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 319dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen gfx::Rect new_target_bounds = CalculateTargetBounds(CalculatePopupHeight()); 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If we're animating and our target height changes, reset the animation. 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // NOTE: If we just reset blindly on _every_ update, then when the user types 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // rapidly we could get "stuck" trying repeatedly to animate shrinking by the 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // last few pixels to get to one visible result. 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (new_target_bounds.height() != target_bounds_.height()) 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_animation_.Reset(); 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch target_bounds_ = new_target_bounds; 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (popup_ == NULL) { 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If the popup is currently closed, we need to create it. 331ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen popup_ = (new AutocompletePopupClass)->AsWeakPtr(); 332ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen views::Widget::CreateParams params(views::Widget::CreateParams::TYPE_POPUP); 333ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen params.can_activate = false; 334ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen params.transparent = true; 335ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen popup_->SetCreateParams(params); 336ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen popup_->Init(location_bar_->GetWidget()->GetNativeView(), GetPopupBounds()); 337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen popup_->SetContentsView(this); 338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen popup_->MoveAbove(popup_->GetRelativeWindowForPopup( 339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen edit_view_->GetNativeView())); 340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen popup_->Show(); 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Animate the popup shrinking, but don't animate growing larger since that 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // would make the popup feel less responsive. 344dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen start_bounds_ = GetWidget()->GetWindowScreenBounds(); 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (target_bounds_.height() < start_bounds_.height()) 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_animation_.Show(); 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch start_bounds_ = target_bounds_; 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch popup_->SetBounds(GetPopupBounds()); 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SchedulePaint(); 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickgfx::Rect AutocompletePopupContentsView::GetTargetBounds() { 3563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return target_bounds_; 3573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 3583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutocompletePopupContentsView::PaintUpdatesNow() { 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(beng): remove this from the interface. 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutocompletePopupContentsView::OnDragCanceled() { 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ignore_mouse_drag_ = true; 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//////////////////////////////////////////////////////////////////////////////// 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// AutocompletePopupContentsView, AutocompleteResultViewModel implementation: 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool AutocompletePopupContentsView::IsSelectedIndex(size_t index) const { 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return HasMatchAt(index) ? index == model_->selected_line() : false; 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool AutocompletePopupContentsView::IsHoveredIndex(size_t index) const { 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return HasMatchAt(index) ? index == model_->hovered_line() : false; 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 378ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst SkBitmap* AutocompletePopupContentsView::GetIconIfExtensionMatch( 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t index) const { 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!HasMatchAt(index)) 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return model_->GetIconIfExtensionMatch(GetMatchAtIndex(index)); 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//////////////////////////////////////////////////////////////////////////////// 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// AutocompletePopupContentsView, AnimationDelegate implementation: 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutocompletePopupContentsView::AnimationProgressed( 3893f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const ui::Animation* animation) { 390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We should only be running the animation when the popup is already visible. 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(popup_ != NULL); 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch popup_->SetBounds(GetPopupBounds()); 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//////////////////////////////////////////////////////////////////////////////// 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// AutocompletePopupContentsView, views::View overrides: 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutocompletePopupContentsView::Layout() { 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UpdateBlurRegion(); 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Size our children to the available content area. 402dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LayoutChildren(); 403dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 404dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // We need to manually schedule a paint here since we are a layered window and 405dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // won't implicitly require painting until we ask for one. 406dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SchedulePaint(); 407dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 408dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 409ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenviews::View* AutocompletePopupContentsView::GetEventHandlerForPoint( 410ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const gfx::Point& point) { 411ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If there is no opt in view, then we want all mouse events. Otherwise let 412ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // any descendants of the opt-in view get mouse events. 413ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!opt_in_view_) 414ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return this; 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 416ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen views::View* child = views::View::GetEventHandlerForPoint(point); 417ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen views::View* ancestor = child; 418ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen while (ancestor && ancestor != opt_in_view_) 419ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ancestor = ancestor->parent(); 420ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return ancestor ? child : this; 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool AutocompletePopupContentsView::OnMousePressed( 424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const views::MouseEvent& event) { 425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ignore_mouse_drag_ = false; // See comment on |ignore_mouse_drag_| in header. 426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (event.IsLeftMouseButton() || event.IsMiddleMouseButton()) { 427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t index = GetIndexForPoint(event.location()); 428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model_->SetHoveredLine(index); 429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (HasMatchAt(index) && event.IsLeftMouseButton()) 43072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen model_->SetSelectedLine(index, false, false); 431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 435ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool AutocompletePopupContentsView::OnMouseDragged( 436ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const views::MouseEvent& event) { 437ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (event.IsLeftMouseButton() || event.IsMiddleMouseButton()) { 438ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t index = GetIndexForPoint(event.location()); 439ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen model_->SetHoveredLine(index); 440ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!ignore_mouse_drag_ && HasMatchAt(index) && event.IsLeftMouseButton()) 441ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen model_->SetSelectedLine(index, false, false); 442ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 443ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 444ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 445ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutocompletePopupContentsView::OnMouseReleased( 447ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const views::MouseEvent& event) { 448ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (ignore_mouse_drag_) { 449ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen OnMouseCaptureLost(); 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t index = GetIndexForPoint(event.location()); 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (event.IsOnlyMiddleMouseButton()) 455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OpenIndex(index, NEW_BACKGROUND_TAB); 456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else if (event.IsOnlyLeftMouseButton()) 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OpenIndex(index, CURRENT_TAB); 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 460ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid AutocompletePopupContentsView::OnMouseCaptureLost() { 461ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ignore_mouse_drag_ = false; 462ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 463ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 464ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid AutocompletePopupContentsView::OnMouseMoved( 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const views::MouseEvent& event) { 466ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen model_->SetHoveredLine(GetIndexForPoint(event.location())); 467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 469ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid AutocompletePopupContentsView::OnMouseEntered( 470ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const views::MouseEvent& event) { 471ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen model_->SetHoveredLine(GetIndexForPoint(event.location())); 472ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 473731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 474ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid AutocompletePopupContentsView::OnMouseExited( 475ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const views::MouseEvent& event) { 476ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen model_->SetHoveredLine(AutocompletePopupModel::kNoMatch); 477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 479dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen//////////////////////////////////////////////////////////////////////////////// 480dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// AutocompletePopupContentsView, protected: 481dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 482dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid AutocompletePopupContentsView::PaintResultViews(gfx::CanvasSkia* canvas) { 483dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen canvas->drawColor(AutocompleteResultView::GetColor( 484dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen AutocompleteResultView::NORMAL, AutocompleteResultView::BACKGROUND)); 485dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen View::PaintChildren(canvas); 486dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 487dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 488dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenint AutocompletePopupContentsView::CalculatePopupHeight() { 489dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK_GE(static_cast<size_t>(child_count()), model_->result().size()); 490dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int popup_height = 0; 491dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen for (size_t i = 0; i < model_->result().size(); ++i) 492dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen popup_height += GetChildViewAt(i)->GetPreferredSize().height(); 493dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return popup_height + 494dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen (opt_in_view_ ? opt_in_view_->GetPreferredSize().height() : 0); 495dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 496dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 497dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenAutocompleteResultView* AutocompletePopupContentsView::CreateResultView( 498dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen AutocompleteResultViewModel* model, 499dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int model_index, 500dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const gfx::Font& font, 501dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const gfx::Font& bold_font) { 502dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return new AutocompleteResultView(model, model_index, font, bold_font); 503dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//////////////////////////////////////////////////////////////////////////////// 506ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// AutocompletePopupContentsView, views::View overrides, protected: 507ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 508ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid AutocompletePopupContentsView::OnPaint(gfx::Canvas* canvas) { 509ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // We paint our children in an unconventional way. 510ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // 511ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Because the border of this view creates an anti-aliased round-rect region 512ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // for the contents, we need to render our rectangular result child views into 513ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // this round rect region. We can't use a simple clip because clipping is 514ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // 1-bit and we get nasty jagged edges. 515ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // 516ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Instead, we paint all our children into a second canvas and use that as a 517ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // shader to fill a path representing the round-rect clipping region. This 518ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // yields a nice anti-aliased edge. 519ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gfx::CanvasSkia contents_canvas(width(), height(), true); 520ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PaintResultViews(&contents_canvas); 521ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 522ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // We want the contents background to be slightly transparent so we can see 523ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // the blurry glass effect on DWM systems behind. We do this _after_ we paint 524ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // the children since they paint text, and GDI will reset this alpha data if 525ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // we paint text after this call. 526ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MakeCanvasTransparent(&contents_canvas); 527ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 528ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Now paint the contents of the contents canvas into the actual canvas. 529ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SkPaint paint; 530ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen paint.setAntiAlias(true); 531ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 532ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SkShader* shader = SkShader::CreateBitmapShader( 533ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen contents_canvas.getDevice()->accessBitmap(false), 534ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SkShader::kClamp_TileMode, 535ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SkShader::kClamp_TileMode); 536ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen paint.setShader(shader); 537ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen shader->unref(); 538ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 539ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gfx::Path path; 540ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MakeContentsPath(&path, GetContentsBounds()); 541ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen canvas->AsCanvasSkia()->drawPath(path, paint); 542ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 543ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Now we paint the border, so it will be alpha-blended atop the contents. 544ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // This looks slightly better in the corners than drawing the contents atop 545ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // the border. 546ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen OnPaintBorder(canvas); 547ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 548ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 549ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid AutocompletePopupContentsView::PaintChildren(gfx::Canvas* canvas) { 550ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // We paint our children inside OnPaint(). 551ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 552ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 553ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen//////////////////////////////////////////////////////////////////////////////// 554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// AutocompletePopupContentsView, private: 555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool AutocompletePopupContentsView::HasMatchAt(size_t index) const { 557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return index < model_->result().size(); 558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst AutocompleteMatch& AutocompletePopupContentsView::GetMatchAtIndex( 561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t index) const { 562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return model_->result().match_at(index); 563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutocompletePopupContentsView::MakeContentsPath( 566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Path* path, 567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const gfx::Rect& bounding_rect) { 568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SkRect rect; 569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rect.set(SkIntToScalar(bounding_rect.x()), 570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SkIntToScalar(bounding_rect.y()), 571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SkIntToScalar(bounding_rect.right()), 572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SkIntToScalar(bounding_rect.bottom())); 573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SkScalar radius = SkIntToScalar(BubbleBorder::GetCornerRadius()); 575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch path->addRoundRect(rect, radius, radius); 576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutocompletePopupContentsView::UpdateBlurRegion() { 579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN) 580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We only support background blurring on Vista with Aero-Glass enabled. 58172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!views::WidgetWin::IsAeroGlassEnabled() || !GetWidget()) 582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Provide a blurred background effect within the contents region of the 585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // popup. 586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DWM_BLURBEHIND bb = {0}; 587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION; 588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bb.fEnable = true; 589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Translate the contents rect into widget coordinates, since that's what 591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // DwmEnableBlurBehindWindow expects a region in. 59272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen gfx::Rect contents_rect = GetContentsBounds(); 593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Point origin(contents_rect.origin()); 594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch views::View::ConvertPointToWidget(this, &origin); 595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch contents_rect.set_origin(origin); 596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Path contents_path; 598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MakeContentsPath(&contents_path, contents_rect); 59921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen base::win::ScopedGDIObject<HRGN> popup_region; 600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch popup_region.Set(contents_path.CreateNativeRegion()); 601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bb.hRgnBlur = popup_region.Get(); 602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DwmEnableBlurBehindWindow(GetWidget()->GetNativeView(), &bb); 603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutocompletePopupContentsView::MakeCanvasTransparent( 607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Canvas* canvas) { 608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Allow the window blur effect to show through the popup background. 609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SkAlpha alpha = GetThemeProvider()->ShouldUseNativeFrame() ? 610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kGlassPopupAlpha : kOpaquePopupAlpha; 611dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen canvas->AsCanvasSkia()->drawColor(SkColorSetA( 612dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen AutocompleteResultView::GetColor(AutocompleteResultView::NORMAL, 613dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen AutocompleteResultView::BACKGROUND), alpha), SkXfermode::kDstIn_Mode); 614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutocompletePopupContentsView::OpenIndex( 617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t index, 618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WindowOpenDisposition disposition) { 619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!HasMatchAt(index)) 620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const AutocompleteMatch& match = model_->result().match_at(index); 623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // OpenURL() may close the popup, which will clear the result set and, by 624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // extension, |match| and its contents. So copy the relevant strings out to 625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // make sure they stay alive until the call completes. 626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL url(match.destination_url); 62772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen string16 keyword; 628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const bool is_keyword_hint = model_->GetKeywordForMatch(match, &keyword); 629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch edit_view_->OpenURL(url, disposition, match.transition, GURL(), index, 63072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen is_keyword_hint ? string16() : keyword); 631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochsize_t AutocompletePopupContentsView::GetIndexForPoint( 634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const gfx::Point& point) { 635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!HitTest(point)) 636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return AutocompletePopupModel::kNoMatch; 637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int nb_match = model_->result().size(); 63972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(nb_match <= child_count()); 640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < nb_match; ++i) { 641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch views::View* child = GetChildViewAt(i); 642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Point point_in_child_coords(point); 643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch View::ConvertPointToView(this, child, &point_in_child_coords); 644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (child->HitTest(point_in_child_coords)) 645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return i; 646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return AutocompletePopupModel::kNoMatch; 648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 6493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickgfx::Rect AutocompletePopupContentsView::CalculateTargetBounds(int h) { 65172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen gfx::Rect location_bar_bounds(location_bar_->GetContentsBounds()); 6523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const views::Border* border = location_bar_->border(); 6533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (border) { 6543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Adjust for the border so that the bubble and location bar borders are 6553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // aligned. 6563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick gfx::Insets insets; 6573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick border->GetInsets(&insets); 6583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick location_bar_bounds.Inset(insets.left(), 0, insets.right(), 0); 6593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else { 6603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // The normal location bar is drawn using a background graphic that includes 6613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // the border, so we inset by enough to make the edges line up, and the 6623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // bubble appear at the same height as the Star bubble. 6633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick location_bar_bounds.Inset(LocationBarView::kNormalHorizontalEdgeThickness, 6643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 0); 6653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 6663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick gfx::Point location_bar_origin(location_bar_bounds.origin()); 6673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick views::View::ConvertPointToScreen(location_bar_, &location_bar_origin); 6683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick location_bar_bounds.set_origin(location_bar_origin); 6693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return bubble_border_->GetBounds( 6703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick location_bar_bounds, gfx::Size(location_bar_bounds.width(), h)); 6713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 672731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 673731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid AutocompletePopupContentsView::UserPressedOptIn(bool opt_in) { 674731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick delete opt_in_view_; 675731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick opt_in_view_ = NULL; 6764a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch PromoCounter* counter = model_->profile()->GetInstantPromoCounter(); 6774a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch DCHECK(counter); 6784a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch counter->Hide(); 6794a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (opt_in) { 6804a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch browser::ShowInstantConfirmDialogIfNecessary( 6814a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch location_bar_->GetWindow()->GetNativeWindow(), model_->profile()); 6824a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 683731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick UpdatePopupAppearance(); 684731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 685