search_result_view.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef ASH_APP_LIST_VIEWS_SEARCH_RESULT_VIEW_H_
  5. #define ASH_APP_LIST_VIEWS_SEARCH_RESULT_VIEW_H_
  6. #include <memory>
  7. #include <vector>
  8. #include "ash/app_list/model/search/search_result.h"
  9. #include "ash/app_list/views/search_result_actions_view_delegate.h"
  10. #include "ash/app_list/views/search_result_base_view.h"
  11. #include "ash/ash_export.h"
  12. #include "base/compiler_specific.h"
  13. #include "base/memory/weak_ptr.h"
  14. namespace views {
  15. class FlexLayoutView;
  16. class ImageView;
  17. class Label;
  18. } // namespace views
  19. namespace ash {
  20. namespace test {
  21. class SearchResultListViewTest;
  22. class SearchResultViewWidgetTest;
  23. } // namespace test
  24. class AppListViewDelegate;
  25. class MaskedImageView;
  26. class SearchResult;
  27. class SearchResultListView;
  28. class SearchResultPageDialogController;
  29. // Search result view uses `views::FlexLayout` to show results in different
  30. // configurations.
  31. // +---------------------------------------------------------------+
  32. // |`text_container_` |
  33. // | +----------------------+ +----------------------------------+ |
  34. // | |`big_title_container_'| |`body_text_container_` | |
  35. // | | | | +------------------------------+ | |
  36. // | | | | |`title_and_details_container_`| | |
  37. // | | | | +------------------------------+ | |
  38. // | | | | +------------------------------+ | |
  39. // | | | | |`keyboard_shortcut_container_`| | |
  40. // | | | | +------------------------------+ | |
  41. // | +----------------------+ +----------------------------------+ |
  42. // +---------------------------------------------------------------+
  43. //
  44. // +-------------------------------------------------------------------------+
  45. // |`big_title_container_` |
  46. // | +--------------------------------+ +----------------------------------+ |
  47. // | |'big_title_main_text_container_'| |`big_title_superscript_container_`| |
  48. // | +--------------------------------+ +----------------------------------+ |
  49. // +-------------------------------------------------------------------------+
  50. //
  51. // The `title_and_details_container_` has two possible layouts depending on
  52. // `view_type_` and whether `keyboard_shortcut_container_` has results
  53. //
  54. // Layout used when the view_type_ == SearchResultViewType::kDefault OR
  55. // `has_keyboard_shortcut_contents_` is set.
  56. //
  57. // +--------------------------------------------------------------------+
  58. // |`title_and_details_container_` |
  59. // | +------------------+ +------------------+ +--------------------+ |
  60. // | |'title_container_'| |`separator_label_`| |`details_container_`| |
  61. // | +------------------+ +------------------+ +--------------------+ |
  62. // +--------------------------------------------------------------------+
  63. //
  64. // layout used when view type is SearchResultViewType::kAnswerCard or
  65. // SearchResultViewType::kClassic.
  66. // +-------------------------------+
  67. // |`title_and_details_container_` |
  68. // | +------------------+ |
  69. // | |'title_container_'| |
  70. // | +------------------+ |
  71. // | +--------------------+ |
  72. // | |'details_container_'| |
  73. // | +--------------------+ |
  74. // +-------------------------------+
  75. class ASH_EXPORT SearchResultView : public SearchResultBaseView,
  76. public SearchResultActionsViewDelegate {
  77. public:
  78. class LabelAndTag {
  79. public:
  80. LabelAndTag(views::Label* label, SearchResult::Tags tags);
  81. LabelAndTag(const LabelAndTag& other);
  82. LabelAndTag& operator=(const LabelAndTag& other);
  83. ~LabelAndTag();
  84. views::Label* GetLabel() const { return label_; }
  85. SearchResult::Tags GetTags() const { return tags_; }
  86. private:
  87. views::Label* label_; // Owned by views hierarchy.
  88. SearchResult::Tags tags_;
  89. };
  90. enum class SearchResultViewType {
  91. // The default vew type used for the majority of search results.
  92. kDefault,
  93. // The classic view type continues support for pre-BubbleView launcher's
  94. // search UI.
  95. kClassic,
  96. // Inline Answer views are used to directly answer questions posed by the
  97. // search query.
  98. kAnswerCard,
  99. };
  100. enum class LabelType {
  101. kBigTitle,
  102. kBigTitleSuperscript,
  103. kTitle,
  104. kDetails,
  105. kKeyboardShortcut,
  106. };
  107. // Internal class name.
  108. static const char kViewClassName[];
  109. SearchResultView(SearchResultListView* list_view,
  110. AppListViewDelegate* view_delegate,
  111. SearchResultPageDialogController* dialog_controller,
  112. SearchResultViewType view_type);
  113. SearchResultView(const SearchResultView&) = delete;
  114. SearchResultView& operator=(const SearchResultView&) = delete;
  115. ~SearchResultView() override;
  116. // Sets/gets SearchResult displayed by this view.
  117. void OnResultChanged() override;
  118. void SetSearchResultViewType(SearchResultViewType type);
  119. void ClearBigTitleContainer();
  120. SearchResultViewType view_type() { return view_type_; }
  121. views::LayoutOrientation TitleAndDetailsOrientationForTest();
  122. // Calculates the width of the `title_container_` and 'details_container_'
  123. // for SearchResultView's custom eliding behavior.
  124. // total_width is the total width allocated to `title_and_details_container_`
  125. static int GetTargetTitleWidth(int total_width,
  126. int separator_width,
  127. int target_details_width);
  128. static int GetMinimumDetailsWidth(int total_width,
  129. int details_width,
  130. int details_no_elide_width);
  131. // Set flex layout weights for title and details containers to support custom
  132. // eliding behavior.
  133. static void SetFlexBehaviorForTextContents(
  134. int total_width,
  135. int separator_width,
  136. int non_elided_details_width,
  137. views::FlexLayoutView* title_container,
  138. views::FlexLayoutView* details_container);
  139. private:
  140. friend class test::SearchResultListViewTest;
  141. friend class SearchResultListView;
  142. friend class SearchResultViewWidgetTest;
  143. void set_multi_line_label_height_for_test(int height) {
  144. multi_line_label_height_ = height;
  145. }
  146. int PreferredHeight() const;
  147. int PrimaryTextHeight() const;
  148. int SecondaryTextHeight() const;
  149. int ActionButtonRightMargin() const;
  150. std::vector<LabelAndTag> SetupContainerViewForTextVector(
  151. views::FlexLayoutView* parent,
  152. const std::vector<SearchResult::TextItem>& text_vector,
  153. LabelType label_type,
  154. bool has_keyboard_shortcut_contents,
  155. bool is_multi_line);
  156. void UpdateBadgeIcon();
  157. void UpdateBigTitleContainer();
  158. void UpdateBigTitleSuperscriptContainer();
  159. void UpdateTitleContainer();
  160. void UpdateDetailsContainer();
  161. void UpdateKeyboardShortcutContainer();
  162. void UpdateRating();
  163. void StyleLabel(views::Label* label,
  164. bool is_title_label,
  165. const SearchResult::Tags& tags);
  166. void StyleBigTitleContainer();
  167. void StyleBigTitleSuperscriptContainer();
  168. void StyleTitleContainer();
  169. void StyleDetailsContainer();
  170. void StyleKeyboardShortcutContainer();
  171. // Callback for query suggstion removal confirmation.
  172. void OnQueryRemovalAccepted(bool accepted);
  173. // Called when the result selection controller selects a new result.
  174. void OnSelectedResultChanged();
  175. // views::View overrides:
  176. const char* GetClassName() const override;
  177. gfx::Size CalculatePreferredSize() const override;
  178. void Layout() override;
  179. bool OnKeyPressed(const ui::KeyEvent& event) override;
  180. void PaintButtonContents(gfx::Canvas* canvas) override;
  181. void OnMouseEntered(const ui::MouseEvent& event) override;
  182. void OnMouseExited(const ui::MouseEvent& event) override;
  183. void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
  184. void VisibilityChanged(View* starting_from, bool is_visible) override;
  185. void OnThemeChanged() override;
  186. // ui::EventHandler overrides:
  187. void OnGestureEvent(ui::GestureEvent* event) override;
  188. // SearchResultObserver overrides:
  189. void OnMetadataChanged() override;
  190. void OnButtonPressed(const ui::Event& event);
  191. void SetIconImage(const gfx::ImageSkia& source,
  192. views::ImageView* const icon,
  193. const gfx::Size& size);
  194. // SearchResultActionsViewDelegate overrides:
  195. void OnSearchResultActionActivated(size_t index) override;
  196. bool IsSearchResultHoveredOrSelected() override;
  197. // Parent list view. Owned by views hierarchy.
  198. SearchResultListView* const list_view_;
  199. AppListViewDelegate* const view_delegate_;
  200. SearchResultPageDialogController* const dialog_controller_;
  201. MaskedImageView* icon_ = nullptr; // Owned by views hierarchy.
  202. views::ImageView* badge_icon_ = nullptr; // Owned by views hierarchy.
  203. views::FlexLayoutView* text_container_ =
  204. nullptr; // Owned by views hierarchy.
  205. views::FlexLayoutView* big_title_container_ =
  206. nullptr; // Owned by views hierarchy.
  207. views::FlexLayoutView* big_title_main_text_container_ =
  208. nullptr; // Owned by views hierarchy.
  209. views::FlexLayoutView* big_title_superscript_container_ =
  210. nullptr; // Owned by views hierarchy.
  211. views::FlexLayoutView* body_text_container_ =
  212. nullptr; // Owned by views hierarchy.
  213. views::FlexLayoutView* title_and_details_container_ =
  214. nullptr; // Owned by views hierarchy.
  215. views::FlexLayoutView* title_container_ =
  216. nullptr; // Owned by views hierarchy.
  217. views::FlexLayoutView* details_container_ =
  218. nullptr; // Owned by views hierarchy.
  219. views::FlexLayoutView* keyboard_shortcut_container_ =
  220. nullptr; // Owned by views hierarchy.
  221. std::vector<LabelAndTag> big_title_label_tags_; // Owned by views hierarchy.
  222. std::vector<LabelAndTag>
  223. big_title_superscript_label_tags_; // Owned by views hierarchy.
  224. std::vector<LabelAndTag> title_label_tags_; // Owned by views hierarchy.
  225. std::vector<LabelAndTag> details_label_tags_; // Owned by views hierarchy.
  226. std::vector<LabelAndTag>
  227. keyboard_shortcut_container_tags_; // Owned by views hierarchy.
  228. views::Label* result_text_separator_label_ =
  229. nullptr; // Owned by views hierarchy.
  230. views::Label* rating_separator_label_ = nullptr; // Owned by views hierarchy.
  231. views::Label* rating_ = nullptr; // Owned by views hierarchy.
  232. views::ImageView* rating_star_ = nullptr; // Owned by views hierarchy.
  233. // Whether the removal confirmation dialog is invoked by long press touch.
  234. bool confirm_remove_by_long_press_ = false;
  235. // Separator label is shown for `kDefault` when details text is not empty,
  236. bool should_show_result_text_separator_label_ = false;
  237. // Used to override `title_and_details_container_` layout when
  238. // `keyboard_shortcut_container_` is populated.
  239. bool has_keyboard_shortcut_contents_ = false;
  240. SearchResultViewType view_type_;
  241. // Search result view can have one non-elided label. Cache the its for flex
  242. // layout weight calculations.
  243. int non_elided_details_label_width_ = 0;
  244. // Search result view can have one multi-line label. Cache its height for
  245. // calculating PreferredHeight() and SecondaryTextHeight().
  246. int multi_line_label_height_ = 0;
  247. base::WeakPtrFactory<SearchResultView> weak_ptr_factory_{this};
  248. };
  249. } // namespace ash
  250. #endif // ASH_APP_LIST_VIEWS_SEARCH_RESULT_VIEW_H_