15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <algorithm> 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/search/search.h" 107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/themes/theme_properties.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/omnibox/omnibox_view.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/location_bar/location_bar_view.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/omnibox/omnibox_result_view.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/theme_provider.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/path.h" 1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "ui/resources/grit/ui_resources.h" 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/views/controls/image_view.h" 205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/views/view_targeter.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h" 227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/views/window/non_client_view.h" 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/window_animations.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// This is the number of pixels in the border image interior to the actual 26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// border. 27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const int kBorderInterior = 6; 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OmniboxPopupContentsView::AutocompletePopupWidget 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public views::Widget, 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public base::SupportsWeakPtr<AutocompletePopupWidget> { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) AutocompletePopupWidget() {} 3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) virtual ~AutocompletePopupWidget() {} 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AutocompletePopupWidget); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OmniboxPopupContentsView, public: 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OmniboxPopupView* OmniboxPopupContentsView::Create( 44a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const gfx::FontList& font_list, 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OmniboxView* omnibox_view, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OmniboxEditModel* edit_model, 47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LocationBarView* location_bar_view) { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OmniboxPopupContentsView* view = NULL; 495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu view = new OmniboxPopupContentsView( 505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu font_list, omnibox_view, edit_model, location_bar_view); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view->Init(); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return view; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OmniboxPopupContentsView::OmniboxPopupContentsView( 56a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const gfx::FontList& font_list, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OmniboxView* omnibox_view, 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OmniboxEditModel* edit_model, 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LocationBarView* location_bar_view) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : model_(new OmniboxPopupModel(this, edit_model)), 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) omnibox_view_(omnibox_view), 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) location_bar_view_(location_bar_view), 63a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) font_list_(font_list), 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ignore_mouse_drag_(false), 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) size_animation_(this), 66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) left_margin_(0), 67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) right_margin_(0), 6868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) outside_vertical_padding_(0) { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The contents is owned by the LocationBarView. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_owned_by_client(); 71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ui::ThemeProvider* theme = location_bar_view_->GetThemeProvider(); 73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bottom_shadow_ = theme->GetImageSkiaNamed(IDR_BUBBLE_B); 745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SetEventTargeter( 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<views::ViewTargeter>(new views::ViewTargeter(this))); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OmniboxPopupContentsView::Init() { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This can't be done in the constructor as at that point we aren't 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // necessarily our final class yet, and we may have subclasses 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // overriding CreateResultView. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < AutocompleteResult::kMaxMatches; ++i) { 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OmniboxResultView* result_view = CreateResultView(i, font_list_); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_view->SetVisible(false); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildViewAt(result_view, static_cast<int>(i)); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OmniboxPopupContentsView::~OmniboxPopupContentsView() { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't need to do anything with |popup_| here. The OS either has already 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // closed the window, in which case it's been deleted, or it will soon, in 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which case there's nothing we need to do. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect OmniboxPopupContentsView::GetPopupBounds() const { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!size_animation_.is_animating()) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return target_bounds_; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect current_frame_bounds = start_bounds_; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int total_height_delta = target_bounds_.height() - start_bounds_.height(); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Round |current_height_delta| instead of truncating so we won't leave single 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // white pixels at the bottom of the popup as long when animating very small 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // height differences. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int current_height_delta = static_cast<int>( 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_animation_.GetCurrentValue() * total_height_delta - 0.5); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_frame_bounds.set_height( 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_frame_bounds.height() + current_height_delta); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return current_frame_bounds; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OmniboxPopupContentsView::LayoutChildren() { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect contents_rect = GetContentsBounds(); 114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) contents_rect.Inset(left_margin_, 1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) views::NonClientFrameView::kClientEdgeThickness + 1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) outside_vertical_padding_, 1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) right_margin_, outside_vertical_padding_); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int top = contents_rect.y(); 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (size_t i = 0; i < AutocompleteResult::kMaxMatches; ++i) { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) View* v = child_at(i); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (v->visible()) { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v->SetBounds(contents_rect.x(), top, contents_rect.width(), 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v->GetPreferredSize().height()); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) top = v->bounds().bottom(); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OmniboxPopupContentsView, OmniboxPopupView overrides: 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool OmniboxPopupContentsView::IsOpen() const { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return popup_ != NULL; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OmniboxPopupContentsView::InvalidateLine(size_t line) { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OmniboxResultView* result = result_view_at(line); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->Invalidate(); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasMatchAt(line) && GetMatchAtIndex(line).associated_keyword.get()) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->ShowKeyword(IsSelectedIndex(line) && 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->selected_line_state() == OmniboxPopupModel::KEYWORD); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OmniboxPopupContentsView::UpdatePopupAppearance() { 148ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const size_t hidden_matches = model_->result().ShouldHideTopMatch() ? 1 : 0; 149ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (model_->result().size() <= hidden_matches || 150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) omnibox_view_->IsImeShowingPopup()) { 151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // No matches or the IME is showing a popup window which may overlap 152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // the omnibox popup window. Close any existing popup. 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (popup_ != NULL) { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_animation_.Stop(); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: Do NOT use CloseNow() here, as we may be deep in a callstack 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // triggered by the popup receiving a message (e.g. LBUTTONUP), and 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // destroying the popup would cause us to read garbage when we unwind back 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to that level. 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) popup_->Close(); // This will eventually delete the popup. 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) popup_.reset(); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the match cached by each row, in the process of doing so make sure 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we have enough row views. 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t result_size = model_->result().size(); 169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) max_match_contents_width_ = 0; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < result_size; ++i) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OmniboxResultView* view = result_view_at(i); 172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const AutocompleteMatch& match = GetMatchAtIndex(i); 173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) view->SetMatch(match); 174ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch view->SetVisible(i >= hidden_matches); 175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (match.type == AutocompleteMatchType::SEARCH_SUGGEST_INFINITE) { 176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) max_match_contents_width_ = std::max( 177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) max_match_contents_width_, view->GetMatchContentsWidth()); 178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (size_t i = result_size; i < AutocompleteResult::kMaxMatches; ++i) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child_at(i)->SetVisible(false); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) gfx::Point top_left_screen_coord; 185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int width; 186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) location_bar_view_->GetOmniboxPopupPositioningInfo( 187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &top_left_screen_coord, &width, &left_margin_, &right_margin_); 188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) gfx::Rect new_target_bounds(top_left_screen_coord, 189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) gfx::Size(width, CalculatePopupHeight())); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we're animating and our target height changes, reset the animation. 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: If we just reset blindly on _every_ update, then when the user types 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // rapidly we could get "stuck" trying repeatedly to animate shrinking by the 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // last few pixels to get to one visible result. 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (new_target_bounds.height() != target_bounds_.height()) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_animation_.Reset(); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_bounds_ = new_target_bounds; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (popup_ == NULL) { 200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch views::Widget* popup_parent = location_bar_view_->GetWidget(); 201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the popup is currently closed, we need to create it. 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) popup_ = (new AutocompletePopupWidget)->AsWeakPtr(); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); 205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; 206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch params.parent = popup_parent->GetNativeView(); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.bounds = GetPopupBounds(); 208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch params.context = popup_parent->GetNativeWindow(); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) popup_->Init(params); 21068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Third-party software such as DigitalPersona identity verification can 21168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // hook the underlying window creation methods and use SendMessage to 21268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // synchronously change focus/activation, resulting in the popup being 21368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // destroyed by the time control returns here. Bail out in this case to 21468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // avoid a NULL dereference. 21568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!popup_.get()) 21668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) wm::SetWindowVisibilityAnimationTransition( 218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) popup_->GetNativeView(), wm::ANIMATE_NONE); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) popup_->SetContentsView(this); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) popup_->StackAbove(omnibox_view_->GetRelativeWindowForPopup()); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!popup_.get()) { 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For some IMEs GetRelativeWindowForPopup triggers the omnibox to lose 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // focus, thereby closing (and destroying) the popup. 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(sky): this won't be needed once we close the omnibox on input 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // window showing. 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) popup_->ShowInactive(); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Animate the popup shrinking, but don't animate growing larger since that 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // would make the popup feel less responsive. 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_bounds_ = GetWidget()->GetWindowBoundsInScreen(); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target_bounds_.height() < start_bounds_.height()) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_animation_.Show(); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_bounds_ = target_bounds_; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) popup_->SetBounds(GetPopupBounds()); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 240424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) Layout(); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect OmniboxPopupContentsView::GetTargetBounds() { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return target_bounds_; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OmniboxPopupContentsView::PaintUpdatesNow() { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(beng): remove this from the interface. 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OmniboxPopupContentsView::OnDragCanceled() { 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ignore_mouse_drag_ = true; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OmniboxPopupContentsView, OmniboxResultViewModel implementation: 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool OmniboxPopupContentsView::IsSelectedIndex(size_t index) const { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return index == model_->selected_line(); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool OmniboxPopupContentsView::IsHoveredIndex(size_t index) const { 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return index == model_->hovered_line(); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Image OmniboxPopupContentsView::GetIconIfExtensionMatch( 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t index) const { 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!HasMatchAt(index)) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gfx::Image(); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return model_->GetIconIfExtensionMatch(GetMatchAtIndex(index)); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool OmniboxPopupContentsView::IsStarredMatch( 2745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const AutocompleteMatch& match) const { 2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return model_->IsStarredMatch(match); 2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OmniboxPopupContentsView, AnimationDelegate implementation: 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OmniboxPopupContentsView::AnimationProgressed( 282d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const gfx::Animation* animation) { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should only be running the animation when the popup is already visible. 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(popup_ != NULL); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) popup_->SetBounds(GetPopupBounds()); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OmniboxPopupContentsView, views::View overrides: 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OmniboxPopupContentsView::Layout() { 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Size our children to the available content area. 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LayoutChildren(); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need to manually schedule a paint here since we are a layered window and 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // won't implicitly require painting until we ask for one. 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)views::View* OmniboxPopupContentsView::GetTooltipHandlerForPoint( 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const gfx::Point& point) { 302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return NULL; 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool OmniboxPopupContentsView::OnMousePressed( 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ui::MouseEvent& event) { 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ignore_mouse_drag_ = false; // See comment on |ignore_mouse_drag_| in header. 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event.IsLeftMouseButton() || event.IsMiddleMouseButton()) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateLineEvent(event, event.IsLeftMouseButton()); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool OmniboxPopupContentsView::OnMouseDragged( 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ui::MouseEvent& event) { 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event.IsLeftMouseButton() || event.IsMiddleMouseButton()) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateLineEvent(event, !ignore_mouse_drag_ && event.IsLeftMouseButton()); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OmniboxPopupContentsView::OnMouseReleased( 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ui::MouseEvent& event) { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ignore_mouse_drag_) { 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnMouseCaptureLost(); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event.IsOnlyMiddleMouseButton() || event.IsOnlyLeftMouseButton()) { 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OpenSelectedLine(event, event.IsOnlyLeftMouseButton() ? CURRENT_TAB : 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEW_BACKGROUND_TAB); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OmniboxPopupContentsView::OnMouseCaptureLost() { 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ignore_mouse_drag_ = false; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OmniboxPopupContentsView::OnMouseMoved( 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ui::MouseEvent& event) { 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->SetHoveredLine(GetIndexForPoint(event.location())); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OmniboxPopupContentsView::OnMouseEntered( 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ui::MouseEvent& event) { 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->SetHoveredLine(GetIndexForPoint(event.location())); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OmniboxPopupContentsView::OnMouseExited( 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ui::MouseEvent& event) { 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->SetHoveredLine(OmniboxPopupModel::kNoMatch); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void OmniboxPopupContentsView::OnGestureEvent(ui::GestureEvent* event) { 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (event->type()) { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::ET_GESTURE_TAP_DOWN: 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::ET_GESTURE_SCROLL_BEGIN: 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::ET_GESTURE_SCROLL_UPDATE: 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateLineEvent(*event, true); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::ET_GESTURE_TAP: 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::ET_GESTURE_SCROLL_END: 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OpenSelectedLine(*event, CURRENT_TAB); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event->SetHandled(); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OmniboxPopupContentsView, protected: 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OmniboxPopupContentsView::PaintResultViews(gfx::Canvas* canvas) { 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas->DrawColor(result_view_at(0)->GetColor( 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OmniboxResultView::NORMAL, OmniboxResultView::BACKGROUND)); 375cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) View::PaintChildren(canvas, views::CullSet()); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int OmniboxPopupContentsView::CalculatePopupHeight() { 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(static_cast<size_t>(child_count()), model_->result().size()); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int popup_height = 0; 381ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (size_t i = model_->result().ShouldHideTopMatch() ? 1 : 0; 382ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch i < model_->result().size(); ++i) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) popup_height += child_at(i)->GetPreferredSize().height(); 384868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 385868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Add enough space on the top and bottom so it looks like there is the same 386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // amount of space between the text and the popup border as there is in the 387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // interior between each row of text. 388868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // 389868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Discovering the exact amount of leading and padding around the font is 390868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // a bit tricky and platform-specific, but this computation seems to work in 391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // practice. 392868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) OmniboxResultView* result_view = result_view_at(0); 393868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) outside_vertical_padding_ = 394868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) (result_view->GetPreferredSize().height() - 395868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) result_view->GetTextHeight()); 396868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return popup_height + 3987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) views::NonClientFrameView::kClientEdgeThickness + // Top border. 3997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) outside_vertical_padding_ * 2 + // Padding. 4007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bottom_shadow_->height() - kBorderInterior; // Bottom border. 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OmniboxResultView* OmniboxPopupContentsView::CreateResultView( 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int model_index, 405a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const gfx::FontList& font_list) { 406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return new OmniboxResultView(this, model_index, location_bar_view_, 407a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) font_list); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OmniboxPopupContentsView, views::View overrides, protected: 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OmniboxPopupContentsView::OnPaint(gfx::Canvas* canvas) { 414868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) gfx::Rect contents_bounds = GetContentsBounds(); 415868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) contents_bounds.set_height( 416868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) contents_bounds.height() - bottom_shadow_->height() + kBorderInterior); 417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Path path; 419868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) MakeContentsPath(&path, contents_bounds); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas->Save(); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas->sk_canvas()->clipPath(path, 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkRegion::kIntersect_Op, 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true /* doAntialias */); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PaintResultViews(canvas); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas->Restore(); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Top border. 4287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) canvas->FillRect( 4297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) gfx::Rect(0, 0, width(), views::NonClientFrameView::kClientEdgeThickness), 4307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ThemeProperties::GetDefaultColor( 4317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ThemeProperties::COLOR_TOOLBAR_SEPARATOR)); 4327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Bottom border. 434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) canvas->TileImageInt(*bottom_shadow_, 0, height() - bottom_shadow_->height(), 435868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) width(), bottom_shadow_->height()); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 438cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void OmniboxPopupContentsView::PaintChildren(gfx::Canvas* canvas, 439cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const views::CullSet& cull_set) { 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We paint our children inside OnPaint(). 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OmniboxPopupContentsView, private: 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)views::View* OmniboxPopupContentsView::TargetForRect(views::View* root, 4475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const gfx::Rect& rect) { 4485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CHECK_EQ(root, this); 4495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return this; 4505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 4515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool OmniboxPopupContentsView::HasMatchAt(size_t index) const { 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return index < model_->result().size(); 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const AutocompleteMatch& OmniboxPopupContentsView::GetMatchAtIndex( 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t index) const { 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return model_->result().match_at(index); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OmniboxPopupContentsView::MakeContentsPath( 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Path* path, 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& bounding_rect) { 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkRect rect; 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rect.set(SkIntToScalar(bounding_rect.x()), 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkIntToScalar(bounding_rect.y()), 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkIntToScalar(bounding_rect.right()), 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkIntToScalar(bounding_rect.bottom())); 469868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) path->addRect(rect); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t OmniboxPopupContentsView::GetIndexForPoint( 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Point& point) { 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!HitTestPoint(point)) 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OmniboxPopupModel::kNoMatch; 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nb_match = model_->result().size(); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(nb_match <= child_count()); 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < nb_match; ++i) { 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* child = child_at(i); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Point point_in_child_coords(point); 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) View::ConvertPointToTarget(this, child, &point_in_child_coords); 483ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (child->visible() && child->HitTestPoint(point_in_child_coords)) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i; 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OmniboxPopupModel::kNoMatch; 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OmniboxPopupContentsView::UpdateLineEvent( 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ui::LocatedEvent& event, 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool should_set_selected_line) { 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t index = GetIndexForPoint(event.location()); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->SetHoveredLine(index); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasMatchAt(index) && should_set_selected_line) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->SetSelectedLine(index, false, false); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OmniboxPopupContentsView::OpenSelectedLine( 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ui::LocatedEvent& event, 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WindowOpenDisposition disposition) { 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t index = GetIndexForPoint(event.location()); 502868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!HasMatchAt(index)) 503868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 504f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) omnibox_view_->OpenMatch(model_->result().match_at(index), disposition, 5055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL(), base::string16(), index); 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OmniboxResultView* OmniboxPopupContentsView::result_view_at(size_t i) { 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<OmniboxResultView*>(child_at(static_cast<int>(i))); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 511