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
|
// 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_TEXT_VIEW_H_
#define CHROME_BROWSER_UI_VIEWS_OMNIBOX_OMNIBOX_TEXT_VIEW_H_
#include <stddef.h>
#include <memory>
#include <string_view>
#include "base/memory/raw_ptr.h"
#include "chrome/browser/ui/views/omnibox/omnibox_result_view.h"
#include "components/omnibox/browser/autocomplete_match.h"
#include "components/omnibox/browser/suggestion_answer.h"
#include "third_party/omnibox_proto/answer_data.pb.h"
#include "third_party/omnibox_proto/answer_type.pb.h"
#include "third_party/omnibox_proto/rich_answer_template.pb.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/gfx/font_list.h"
#include "ui/views/view.h"
namespace gfx {
class Canvas;
class RenderText;
} // namespace gfx
// A view containing a render text styled via search results. This differs from
// the general purpose views::Label class by having less general features (such
// as selection) and more specific features (such as suggestion answer styling).
class OmniboxTextView : public views::View {
METADATA_HEADER(OmniboxTextView, views::View)
public:
explicit OmniboxTextView(OmniboxResultView* result_view);
OmniboxTextView(const OmniboxTextView&) = delete;
OmniboxTextView& operator=(const OmniboxTextView&) = delete;
~OmniboxTextView() override;
// views::View:
gfx::Size CalculatePreferredSize(
const views::SizeBounds& available_size) const override;
void OnPaint(gfx::Canvas* canvas) override;
// Applies given theme color to underlying render text. This is called Apply*
// instead of Set* because the only state kept is in render_text, so call this
// after setting text with methods below.
void ApplyTextColor(ui::ColorId id);
// Returns the render text, or an empty string if there is none.
std::u16string_view GetText() const;
// Used for content/description separator & tail suggest ellipses.
void SetText(std::u16string_view new_text);
// Used for standard suggestions.
void SetTextWithStyling(std::u16string_view new_text,
const ACMatchClassifications& classifications);
// Used for search answers using `RichAnswerTemplate`.
// Sets the styling for `FormattedString`'s `FormattedStringFragment`s.
// `fragment_index` specifies where to start appending and styling text from.
// Headlines should be styled differently than subheads.
void AppendAndStyleAnswerText(
const omnibox::FormattedString& formatted_string,
size_t fragment_index,
const omnibox::AnswerType& answer_type,
bool is_headline);
// Used for suggestions using `RichAnswerTemplate`.
void SetMultilineAnswerText(const omnibox::FormattedString& formatted_string,
const omnibox::AnswerType& answer_type);
// Used for history embedding answers.
void SetMultilineText(const std::u16string& text);
// Get the height of one line of text. This is handy if the view might have
// multiple lines.
int GetLineHeight() const;
// Reapplies text styling to the results text, based on the types of the match
// parts.
void ReapplyStyling();
// Creates a platform-approriate RenderText, sets its format to that of
// a suggestion and inserts (renders) the provided |text|.
std::unique_ptr<gfx::RenderText> CreateRenderText(
std::u16string_view text) const;
private:
// Updates the cached maximum line height and recomputes the preferred size.
void OnStyleChanged();
// To get color values.
raw_ptr<OmniboxResultView> result_view_;
// Font settings for this view.
int font_height_ = 0;
// Whether to wrap lines if the width is too narrow for the whole string.
// TODO(crbug.com/370088101): Ensure `wrap_text_lines_` is set correctly in
// the `SetTextWithStyling()` and related methods above. Can we use
// `render_text_->multiline()` instead? Ideally, all the text setting
// methods should detect if nothing has changed (i.e. text, style, and other
// options like wrapping / multiline, etc are all unchanged). If nothing has
// changed, then they should early exit because those methods are called
// 1000's of times per keystroke and cause noticeable lag when not
// early-exiting. Otherwise, if something has changed, the methods should
// explicitly set all these states and not assume they still hold their
// default values from initialization since `OmniboxTextView`s are reused.
bool wrap_text_lines_ = false;
// The primary data for this class.
std::unique_ptr<gfx::RenderText> render_text_;
// The classifications most recently passed to SetText. Used to exit
// early instead of setting text when the text and classifications
// match the current state of the view.
std::unique_ptr<ACMatchClassifications> cached_classifications_;
// Caches the param and return value of `CalculatePreferredSize()` for
// multiline texts. `CalculatePreferredSize()` is called 100's of times per
// keystroke. For 1-line texts, it's cached via `View::SetPreferredSize()`.
// But the size of multiline texts depends on `available_size`. Caching for
// the most recent `available_size` reduces the need to recompute preferred
// size from 300 to 4 times per keystroke. Increasing the cache size to 2
// would reduce it further to 0 times per keystroke, but that seems
// unnecessary. Unused for 1-line texts.
// The most recent `available_size` param passed to
// `CalculatePreferredSize()`.
mutable views::SizeBounds cached_available_size_;
// The most recent return value from `CalculatePreferredSize()`.
mutable gfx::Size cached_calculate_preferred_size_;
};
#endif // CHROME_BROWSER_UI_VIEWS_OMNIBOX_OMNIBOX_TEXT_VIEW_H_
|