omnibox_result_view.h revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/autocomplete_match.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkColor.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/animation/animation_delegate.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/animation/slide_animation.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/font.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/image_view.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/view.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OmniboxResultViewModel;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Canvas;
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class RenderText;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OmniboxResultView : public views::View,
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          private ui::AnimationDelegate {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Keep these ordered from least dominant (normal) to most dominant
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (selected).
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum ResultViewState {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NORMAL = 0,
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HOVERED,
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SELECTED,
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NUM_STATES
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum ColorKind {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BACKGROUND = 0,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TEXT,
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DIMMED_TEXT,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    URL,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DIVIDER,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NUM_KINDS
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OmniboxResultView(OmniboxResultViewModel* model,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    int model_index,
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    const gfx::Font& font);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~OmniboxResultView();
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor GetColor(ResultViewState state, ColorKind kind) const;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Updates the match used to paint the contents of this result view. We copy
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the match so that we can continue to paint the last result even after the
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // model has changed.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetMatch(const AutocompleteMatch& match);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ShowKeyword(bool show_keyword);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Invalidate();
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // views::View:
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual gfx::Size GetPreferredSize() OVERRIDE;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResultViewState GetState() const;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void PaintMatch(gfx::Canvas* canvas,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const AutocompleteMatch& match,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          int x);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the height of the text portion of the result view. In the base
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // class, this is the height of one line of text.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int GetTextHeight() const;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Draws the specified |text| into the canvas, using highlighting provided by
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |classifications|. If |force_dim| is true, ACMatchClassification::DIM is
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to all of the classifications. Returns the x position to the right
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of the string.
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DrawString(gfx::Canvas* canvas,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const string16& text,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const ACMatchClassifications& classifications,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 bool force_dim,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 int x,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 int y);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const gfx::Rect& text_bounds() const { return text_bounds_; }
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_edge_item_padding(int value) { edge_item_padding_ = value; }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_item_padding(int value) { item_padding_ = value; }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_minimum_text_vertical_padding(int value) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    minimum_text_vertical_padding_ = value;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct RunData;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::vector<RunData> Runs;
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef std::vector<gfx::RenderText*> Classifications;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Common initialization code of the colors returned by GetColors().
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void CommonInitColors(const ui::NativeTheme* theme,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               SkColor colors[][NUM_KINDS]);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Predicate functions for use when sorting the runs.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool SortRunsLogically(const RunData& lhs, const RunData& rhs);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool SortRunsVisually(const RunData& lhs, const RunData& rhs);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::ImageSkia GetIcon() const;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const gfx::ImageSkia* GetKeywordIcon() const;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Elides |runs| to fit in |remaining_width|.  The runs in |runs| should be in
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // logical order.
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When we need to elide a run, the ellipsis will be placed at the end of that
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // run.  This means that if we elide a run whose visual direction is opposite
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that of the drawing context, the ellipsis will not be at the "end" of the
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // drawn string.  For example, if in an LTR context we have the LTR run
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "LTR_STRING" and the RTL run "RTL_STRING", the unelided text would be drawn
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // like:
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     LTR_STRING GNIRTS_LTR
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we need to elide the RTL run, then it will be drawn like:
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     LTR_STRING ...RTS_LTR
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Instead of:
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     LTR_STRING RTS_LTR...
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Elide(Runs* runs, int remaining_width) const;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // views::View:
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Layout() OVERRIDE;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ui::AnimationDelegate:
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static int default_icon_size_;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Default values cached here, may be overridden using the setters above.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int edge_item_padding_;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int item_padding_;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int minimum_text_vertical_padding_;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This row's model and model index.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OmniboxResultViewModel* model_;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t model_index_;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const gfx::Font font_;
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int font_height_;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Width of the ellipsis in the normal font.
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ellipsis_width_;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A context used for mirroring regions.
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class MirroringContext;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<MirroringContext> mirroring_context_;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AutocompleteMatch match_;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect text_bounds_;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect icon_bounds_;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect keyword_text_bounds_;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<views::ImageView> keyword_icon_;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ui::SlideAnimation> animation_;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OmniboxResultView);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_BROWSER_UI_VIEWS_OMNIBOX_OMNIBOX_RESULT_VIEW_H_
171