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