omnibox_result_view.h revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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_RESULT_VIEW_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_UI_VIEWS_OMNIBOX_OMNIBOX_RESULT_VIEW_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/gtest_prod_util.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/autocomplete_match.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkColor.h"
13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/gfx/animation/animation_delegate.h"
14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/gfx/animation/slide_animation.h"
15a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "ui/gfx/font_list.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/image_view.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/view.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class LocationBarView;
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class OmniboxPopupContentsView;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Canvas;
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class RenderText;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OmniboxResultView : public views::View,
29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                          private gfx::AnimationDelegate {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Keep these ordered from least dominant (normal) to most dominant
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (selected).
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum ResultViewState {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NORMAL = 0,
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HOVERED,
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SELECTED,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NUM_STATES
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum ColorKind {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BACKGROUND = 0,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TEXT,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DIMMED_TEXT,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    URL,
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DIVIDER,
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NUM_KINDS
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  OmniboxResultView(OmniboxPopupContentsView* model,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    int model_index,
51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                    LocationBarView* location_bar_view,
52a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                    const gfx::FontList& font_list);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~OmniboxResultView();
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor GetColor(ResultViewState state, ColorKind kind) const;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Updates the match used to paint the contents of this result view. We copy
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the match so that we can continue to paint the last result even after the
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // model has changed.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetMatch(const AutocompleteMatch& match);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ShowKeyword(bool show_keyword);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Invalidate();
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // views::View:
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual gfx::Size GetPreferredSize() OVERRIDE;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResultViewState GetState() const;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Returns the height of the text portion of the result view. In the base
72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // class, this is the height of one line of text.
73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual int GetTextHeight() const;
74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Returns the display width required for the match contents.
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int GetMatchContentsWidth() const;
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void PaintMatch(gfx::Canvas* canvas, int x);
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Draws given |render_text| on |canvas| at given location (|x|, |y|).
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // |contents| determines any formatting difference between contents and
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // description parts of the omnibox result (see AutocompleteMatch). If
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // |max_width| is a non-negative number, the text will be elided to fit
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // within |max_width|. Returns the x position to the right of the string.
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int DrawRenderText(gfx::Canvas* canvas,
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     gfx::RenderText* render_text,
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     bool contents,
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     int x,
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     int y,
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     int max_width) const;
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Creates a RenderText with given |text| and rendering defaults.
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<gfx::RenderText> CreateRenderText(
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const base::string16& text) const;
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Applies styles specified by |classifications| and |force_dim| in the range
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // from |range_start| to |range_end| in the |render_text|.
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void ApplyClassifications(
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      gfx::RenderText* render_text,
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const ACMatchClassifications& classifications,
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      bool force_dim) const;
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Renders match contents at a suitable location in the bounds of this view.
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  gfx::RenderText* RenderMatchContents();
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const gfx::Rect& text_bounds() const { return text_bounds_; }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_edge_item_padding(int value) { edge_item_padding_ = value; }
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_item_padding(int value) { item_padding_ = value; }
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_minimum_text_vertical_padding(int value) {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    minimum_text_vertical_padding_ = value;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Returns the match to be rendered for this row.
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const AutocompleteMatch& display_match() const {
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return render_associated_keyword_match_ ?
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        *match_.associated_keyword.get() : match_;
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(OmniboxResultViewTest, CheckComputeMatchWidths);
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Computes the maximum width, in pixels, that can be allocated for the two
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // parts of an autocomplete result, i.e. the contents and the description.
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static void ComputeMatchMaxWidths(int contents_width,
127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                    int separator_width,
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                    int description_width,
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                    int available_width,
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                    bool allow_shrinking_contents,
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                    int* contents_max_width,
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                    int* description_max_width);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Common initialization code of the colors returned by GetColors().
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void CommonInitColors(const ui::NativeTheme* theme,
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               SkColor colors[][NUM_KINDS]);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::ImageSkia GetIcon() const;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const gfx::ImageSkia* GetKeywordIcon() const;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // views::View:
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Layout() OVERRIDE;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
146d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // gfx::AnimationDelegate:
147d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Returns the offset at which the suggestion should be displayed within the
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // text bounds. The directionality of UI and match contents is used to
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // determine the offset relative to the correct edge.
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int GetDisplayOffset(bool is_ui_rtl, bool is_match_contents_rtl) const;
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static int default_icon_size_;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static int ellipsis_width_;
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Default values cached here, may be overridden using the setters above.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int edge_item_padding_;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int item_padding_;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int minimum_text_vertical_padding_;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This row's model and model index.
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  OmniboxPopupContentsView* model_;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t model_index_;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  LocationBarView* location_bar_view_;
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
169a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  const gfx::FontList font_list_;
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int font_height_;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A context used for mirroring regions.
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class MirroringContext;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<MirroringContext> mirroring_context_;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AutocompleteMatch match_;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Whether the associated keyword match should be rendered instead of the
179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // original match.
180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool render_associated_keyword_match_;
181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect text_bounds_;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect icon_bounds_;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect keyword_text_bounds_;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<views::ImageView> keyword_icon_;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
188d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  scoped_ptr<gfx::SlideAnimation> animation_;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<gfx::RenderText> match_contents_render_text_;
191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OmniboxResultView);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_BROWSER_UI_VIEWS_OMNIBOX_OMNIBOX_RESULT_VIEW_H_
196