1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_VIEWS_OMNIBOX_OMNIBOX_MATCH_CELL_VIEW_H_
#define CHROME_BROWSER_UI_VIEWS_OMNIBOX_OMNIBOX_MATCH_CELL_VIEW_H_
#include "base/memory/raw_ptr.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/views/view.h"
namespace views {
class ImageView;
class Link;
} // namespace views
struct AutocompleteMatch;
class OmniboxResultView;
class OmniboxTextView;
class OmniboxMatchCellView : public views::View {
METADATA_HEADER(OmniboxMatchCellView, views::View)
public:
// Constants used in layout. Exposed so other views can coordinate margins.
// The gap between the popup's left edge (not the focus indicator's edge) and
// `OmniboxMatchCellView`.
static constexpr int kMarginLeft = 4;
// Probably intended to be the gap between the popup's right edge (assuming no
// buttons) and the text cut off. But this isn't used by
// `OmniboxMatchCellView`. `OmniboxMatchCellView::GetInsets()` hardcodes 7; so
// 8 here is probably wrong.
static constexpr int kMarginRight = 8;
// The height of the standard 1-line match row. Multiline & IPH matches have
// larger heights.
static constexpr int kRowHeight = 40;
// The width of icon, answer, and entity image bounds. These images are
// smaller than this bounds; they'll be centered within the bounds.
static constexpr int kImageBoundsWidth = 40;
// For IPH matches, `OmniboxMatchCellView` is inset from the left & right by
// `kIphOffset`.
static constexpr int kIphOffset = 16;
// Computes the maximum width, in pixels, that can be allocated for the two
// parts of an autocomplete result, i.e. the contents and the description.
//
// When |allow_shrinking_contents| is true, and the contents and description
// are together on a line without enough space for both, the code tries to
// divide the available space equally between the two, unless this would make
// one or both too narrow. Otherwise, the contents is given as much space as
// it wants and the description gets the remainder.
static void ComputeMatchMaxWidths(int contents_width,
int separator_width,
int description_width,
int iph_link_width,
int available_width,
bool allow_shrinking_contents,
int* contents_max_width,
int* description_max_width,
int* iph_link_max_width);
explicit OmniboxMatchCellView(OmniboxResultView* result_view);
OmniboxMatchCellView(const OmniboxMatchCellView&) = delete;
OmniboxMatchCellView& operator=(const OmniboxMatchCellView&) = delete;
~OmniboxMatchCellView() override;
views::ImageView* icon() { return icon_view_; }
OmniboxTextView* content() { return content_view_; }
OmniboxTextView* description() { return description_view_; }
OmniboxTextView* separator() { return separator_view_; }
views::Link* iph_link_view() { return iph_link_view_; }
// Determines if `match` should display an answer, calculator, or entity
// image.
static bool ShouldDisplayImage(const AutocompleteMatch& match);
void OnMatchUpdate(const OmniboxResultView* result_view,
const AutocompleteMatch& match);
// Set's the `icon_view_` image, possibly with a rounded square background.
void SetIcon(const gfx::ImageSkia& image, const AutocompleteMatch& match);
// Clears the `icon_view_` image. Useful for suggestions that don't need icons
// e.g., tail suggestions. Can't simply set the icon to an empty icon,
// because doing so would still draw a background behind the icon.
void ClearIcon();
// Sets the answer image and, if the image is not square, sets the answer size
// proportional to the image size to preserve its aspect ratio. `match`
// correspond to the match for this view and is used to detect if this is a
// weather answer (weather answers handle images differently).
void SetImage(const gfx::ImageSkia& image, const AutocompleteMatch& match);
// views::View:
gfx::Insets GetInsets() const override;
void Layout(PassKey) override;
gfx::Size CalculatePreferredSize(
const views::SizeBounds& available_size) const override;
private:
enum class LayoutStyle {
DEFAULT_NON_SEARCH_SUGGESTION,
SEARCH_SUGGESTION,
SEARCH_SUGGESTION_WITH_IMAGE,
IPH_SUGGESTION,
HISTORY_EMBEDDING_ANSWER,
};
// How far to indent the icon, entity, or answer image from the left side of
// this view. Images are positioned ignoring `GetInsets()`; i.e., this
// measures from the visual left edge of the popup.
int GetImageIndent() const;
// How far to indent the text from the left side of this view. Texts are
// positioned considering `GetInsets()` but ignoring the width and positioning
// of images; i.e., this measures from the visual left edge of the popup +
// `kMarginLeft`. IPH matches are externally inset as well, so this will
// measure from the left edge of the IPH background + `kMarginLeft`.
int GetTextIndent() const;
void SetTailSuggestCommonPrefixWidth(const std::u16string& common_prefix);
LayoutStyle layout_style_ = LayoutStyle::DEFAULT_NON_SEARCH_SUGGESTION;
// Weak pointers for easy reference.
// An icon representing the type or content.
raw_ptr<views::ImageView> icon_view_;
// The image for answers in suggest and rich entity suggestions.
raw_ptr<views::ImageView> answer_image_view_;
raw_ptr<OmniboxTextView> tail_suggest_ellipse_view_;
raw_ptr<OmniboxTextView> content_view_;
raw_ptr<OmniboxTextView> description_view_;
raw_ptr<OmniboxTextView> separator_view_;
// Some IPH matches have a link users can click to learn more or take action.
raw_ptr<views::Link> iph_link_view_;
// This holds the rendered width of the common prefix of a set of tail
// suggestions so that it doesn't have to be re-calculated if the prefix
// doesn't change.
int tail_suggest_common_prefix_width_ = 0;
};
#endif // CHROME_BROWSER_UI_VIEWS_OMNIBOX_OMNIBOX_MATCH_CELL_VIEW_H_
|