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