omnibox_result_view.h revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_UI_VIEWS_OMNIBOX_OMNIBOX_RESULT_VIEW_H_
6#define CHROME_BROWSER_UI_VIEWS_OMNIBOX_OMNIBOX_RESULT_VIEW_H_
7
8#include <vector>
9
10#include "chrome/browser/autocomplete/autocomplete_match.h"
11#include "third_party/skia/include/core/SkColor.h"
12#include "ui/gfx/animation/animation_delegate.h"
13#include "ui/gfx/animation/slide_animation.h"
14#include "ui/gfx/font_list.h"
15#include "ui/gfx/rect.h"
16#include "ui/views/controls/image_view.h"
17#include "ui/views/view.h"
18
19class LocationBarView;
20class OmniboxResultViewModel;
21
22namespace gfx {
23class Canvas;
24class RenderText;
25}
26
27class OmniboxResultView : public views::View,
28                          private gfx::AnimationDelegate {
29 public:
30  // Keep these ordered from least dominant (normal) to most dominant
31  // (selected).
32  enum ResultViewState {
33    NORMAL = 0,
34    HOVERED,
35    SELECTED,
36    NUM_STATES
37  };
38
39  enum ColorKind {
40    BACKGROUND = 0,
41    TEXT,
42    DIMMED_TEXT,
43    URL,
44    DIVIDER,
45    NUM_KINDS
46  };
47
48  OmniboxResultView(OmniboxResultViewModel* model,
49                    int model_index,
50                    LocationBarView* location_bar_view,
51                    const gfx::FontList& font_list);
52  virtual ~OmniboxResultView();
53
54  SkColor GetColor(ResultViewState state, ColorKind kind) const;
55
56  // Updates the match used to paint the contents of this result view. We copy
57  // the match so that we can continue to paint the last result even after the
58  // model has changed.
59  void SetMatch(const AutocompleteMatch& match);
60
61  void ShowKeyword(bool show_keyword);
62
63  void Invalidate();
64
65  // views::View:
66  virtual gfx::Size GetPreferredSize() OVERRIDE;
67
68  ResultViewState GetState() const;
69
70  // Returns the height of the text portion of the result view. In the base
71  // class, this is the height of one line of text.
72  virtual int GetTextHeight() const;
73
74 protected:
75  virtual void PaintMatch(gfx::Canvas* canvas,
76                          const AutocompleteMatch& match,
77                          int x);
78
79  // Draws the specified |text| into the canvas, using highlighting provided by
80  // |classifications|. If |force_dim| is true, ACMatchClassification::DIM is
81  // added to all of the classifications. Returns the x position to the right
82  // of the string.
83  int DrawString(gfx::Canvas* canvas,
84                 const string16& text,
85                 const ACMatchClassifications& classifications,
86                 bool force_dim,
87                 int x,
88                 int y);
89
90  const gfx::Rect& text_bounds() const { return text_bounds_; }
91
92  void set_edge_item_padding(int value) { edge_item_padding_ = value; }
93  void set_item_padding(int value) { item_padding_ = value; }
94  void set_minimum_text_vertical_padding(int value) {
95    minimum_text_vertical_padding_ = value;
96  }
97
98 private:
99  struct RunData;
100  typedef std::vector<RunData> Runs;
101  typedef std::vector<gfx::RenderText*> Classifications;
102
103  // Common initialization code of the colors returned by GetColors().
104  static void CommonInitColors(const ui::NativeTheme* theme,
105                               SkColor colors[][NUM_KINDS]);
106
107  // Predicate functions for use when sorting the runs.
108  static bool SortRunsLogically(const RunData& lhs, const RunData& rhs);
109  static bool SortRunsVisually(const RunData& lhs, const RunData& rhs);
110
111  gfx::ImageSkia GetIcon() const;
112  const gfx::ImageSkia* GetKeywordIcon() const;
113
114  // Elides |runs| to fit in |remaining_width|.  The runs in |runs| should be in
115  // logical order.
116  //
117  // When we need to elide a run, the ellipsis will be placed at the end of that
118  // run.  This means that if we elide a run whose visual direction is opposite
119  // that of the drawing context, the ellipsis will not be at the "end" of the
120  // drawn string.  For example, if in an LTR context we have the LTR run
121  // "LTR_STRING" and the RTL run "RTL_STRING", the unelided text would be drawn
122  // like:
123  //     LTR_STRING GNIRTS_LTR
124  // If we need to elide the RTL run, then it will be drawn like:
125  //     LTR_STRING ...RTS_LTR
126  // Instead of:
127  //     LTR_STRING RTS_LTR...
128  void Elide(Runs* runs, int remaining_width) const;
129
130  // views::View:
131  virtual void Layout() OVERRIDE;
132  virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
133  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
134
135  // gfx::AnimationDelegate:
136  virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE;
137
138  static int default_icon_size_;
139
140  // Default values cached here, may be overridden using the setters above.
141  int edge_item_padding_;
142  int item_padding_;
143  int minimum_text_vertical_padding_;
144
145  // This row's model and model index.
146  OmniboxResultViewModel* model_;
147  size_t model_index_;
148
149  LocationBarView* location_bar_view_;
150
151  const gfx::FontList font_list_;
152  int font_height_;
153
154  // Width of the ellipsis in the normal font.
155  int ellipsis_width_;
156
157  // A context used for mirroring regions.
158  class MirroringContext;
159  scoped_ptr<MirroringContext> mirroring_context_;
160
161  AutocompleteMatch match_;
162
163  gfx::Rect text_bounds_;
164  gfx::Rect icon_bounds_;
165
166  gfx::Rect keyword_text_bounds_;
167  scoped_ptr<views::ImageView> keyword_icon_;
168
169  scoped_ptr<gfx::SlideAnimation> animation_;
170
171  DISALLOW_COPY_AND_ASSIGN(OmniboxResultView);
172};
173
174#endif  // CHROME_BROWSER_UI_VIEWS_OMNIBOX_OMNIBOX_RESULT_VIEW_H_
175