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)#ifndef CHROME_BROWSER_UI_VIEWS_OMNIBOX_OMNIBOX_POPUP_CONTENTS_VIEW_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_UI_VIEWS_OMNIBOX_OMNIBOX_POPUP_CONTENTS_VIEW_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/omnibox/omnibox_popup_model.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/omnibox/omnibox_popup_view.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/window_open_disposition.h"
12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/gfx/animation/animation_delegate.h"
13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/gfx/animation/slide_animation.h"
14a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "ui/gfx/font_list.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/view.h"
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/views/view_targeter_delegate.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct AutocompleteMatch;
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class LocationBarView;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OmniboxEditModel;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OmniboxResultView;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OmniboxView;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Profile;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A view representing the contents of the autocomplete popup.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OmniboxPopupContentsView : public views::View,
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 public OmniboxPopupView,
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 public views::ViewTargeterDelegate,
29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                 public gfx::AnimationDelegate {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Factory method for creating the AutocompletePopupView.
32a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  static OmniboxPopupView* Create(const gfx::FontList& font_list,
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  OmniboxView* omnibox_view,
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  OmniboxEditModel* edit_model,
35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  LocationBarView* location_bar_view);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the bounds the popup should be shown at. This is the display bounds
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and includes offsets for the dropshadow which this view's border renders.
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect GetPopupBounds() const;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void LayoutChildren();
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from OmniboxPopupView:
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool IsOpen() const OVERRIDE;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void InvalidateLine(size_t line) OVERRIDE;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void UpdatePopupAppearance() OVERRIDE;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual gfx::Rect GetTargetBounds() OVERRIDE;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void PaintUpdatesNow() OVERRIDE;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnDragCanceled() OVERRIDE;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Overridden from gfx::AnimationDelegate:
52d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from views::View:
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Layout() OVERRIDE;
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual views::View* GetTooltipHandlerForPoint(
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const gfx::Point& point) OVERRIDE;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnMouseCaptureLost() OVERRIDE;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnMouseMoved(const ui::MouseEvent& event) OVERRIDE;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from ui::EventHandler:
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool IsSelectedIndex(size_t index) const;
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool IsHoveredIndex(size_t index) const;
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  gfx::Image GetIconIfExtensionMatch(size_t index) const;
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool IsStarredMatch(const AutocompleteMatch& match) const;
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int max_match_contents_width() const {
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return max_match_contents_width_;
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  OmniboxPopupContentsView(const gfx::FontList& font_list,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           OmniboxView* omnibox_view,
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           OmniboxEditModel* edit_model,
82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           LocationBarView* location_bar_view);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~OmniboxPopupContentsView();
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  LocationBarView* location_bar_view() { return location_bar_view_; }
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void PaintResultViews(gfx::Canvas* canvas);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calculates the height needed to show all the results in the model.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int CalculatePopupHeight();
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual OmniboxResultView* CreateResultView(int model_index,
92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                              const gfx::FontList& font_list);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from views::View:
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This method should not be triggered directly as we paint our children
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in an un-conventional way inside OnPaint. We use a separate canvas to
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // paint the children. Hence we override this method to a no-op so that
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the view hierarchy does not "accidentally" trigger this.
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void PaintChildren(gfx::Canvas* canvas,
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             const views::CullSet& cull_set) OVERRIDE;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<OmniboxPopupModel> model_;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class AutocompletePopupWidget;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // views::ViewTargeterDelegate:
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual views::View* TargetForRect(views::View* root,
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     const gfx::Rect& rect) OVERRIDE;
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Call immediately after construction.
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Init();
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the model has a match at the specified index.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool HasMatchAt(size_t index) const;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the match at the specified index within the popup model.
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const AutocompleteMatch& GetMatchAtIndex(size_t index) const;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fill a path for the contents' roundrect. |bounding_rect| is the rect that
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bounds the path.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MakeContentsPath(gfx::Path* path, const gfx::Rect& bounding_rect);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Find the index of the match under the given |point|, specified in window
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // coordinates. Returns OmniboxPopupModel::kNoMatch if there isn't a match at
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the specified point.
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t GetIndexForPoint(const gfx::Point& point);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Processes a located event (e.g. mouse/gesture) and sets the selection/hover
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // state of a line in the list.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UpdateLineEvent(const ui::LocatedEvent& event,
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       bool should_set_selected_line);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Opens an entry from the list depending on the event and the selected
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // disposition.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OpenSelectedLine(const ui::LocatedEvent& event,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        WindowOpenDisposition disposition);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OmniboxResultView* result_view_at(size_t i);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The popup that contains this view.  We create this, but it deletes itself
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when its window is destroyed.  This is a WeakPtr because it's possible for
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the OS to destroy the window and thus delete this object before we're
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // deleted, or without our knowledge.
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtr<AutocompletePopupWidget> popup_;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The edit view that invokes us.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OmniboxView* omnibox_view_;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  LocationBarView* location_bar_view_;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
153a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // The font list used for result rows, based on the omnibox font list.
154a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  gfx::FontList font_list_;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the user cancels a dragging action (i.e. by pressing ESC), we don't have
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a convenient way to release mouse capture. Instead we use this flag to
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // simply ignore all remaining drag events, and the eventual mouse release
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // event. Since OnDragCanceled() can be called when we're not dragging, this
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // flag is reset to false on a mouse pressed event, to make sure we don't
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // erroneously ignore the next drag.
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ignore_mouse_drag_;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The popup sizes vertically using an animation when the popup is getting
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // shorter (not larger, that makes it look "slow").
166d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  gfx::SlideAnimation size_animation_;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect start_bounds_;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect target_bounds_;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int left_margin_;
171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int right_margin_;
172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const gfx::ImageSkia* bottom_shadow_;  // Ptr owned by resource bundle.
174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Amount of extra padding to add to the popup on the top and bottom.
176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int outside_vertical_padding_;
177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // When the dropdown is not wide enough while displaying postfix suggestions,
179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // we use the width of widest match contents to shift the suggestions so that
180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // the widest suggestion just reaches the end edge.
181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int max_match_contents_width_;
182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OmniboxPopupContentsView);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_BROWSER_UI_VIEWS_OMNIBOX_OMNIBOX_POPUP_CONTENTS_VIEW_H_
187