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 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
|
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_APP_LIST_VIEWS_APP_LIST_SEARCH_VIEW_H_
#define ASH_APP_LIST_VIEWS_APP_LIST_SEARCH_VIEW_H_
#include <memory>
#include <string>
#include <vector>
#include "ash/app_list/app_list_model_provider.h"
#include "ash/app_list/views/search_result_container_view.h"
#include "ash/ash_export.h"
#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/views/view.h"
namespace views {
class AXVirtualView;
} // namespace views
namespace ash {
class AppListToastView;
class AppListViewDelegate;
class ResultSelectionController;
class SearchBoxView;
class SearchNotifierController;
class SearchResultPageDialogController;
class SearchResultImageListView;
// The search results view for productivity launcher. Contains a scrolling list
// of search results. Does not include the search box, which is owned by a
// parent view.
class ASH_EXPORT AppListSearchView : public views::View,
public SearchResultContainerView::Delegate,
public AppListModelProvider::Observer {
public:
METADATA_HEADER(AppListSearchView);
AppListSearchView(AppListViewDelegate* view_delegate,
SearchResultPageDialogController* dialog_controller,
SearchBoxView* search_box_view);
AppListSearchView(const AppListSearchView&) = delete;
AppListSearchView& operator=(const AppListSearchView&) = delete;
~AppListSearchView() override;
// SearchResultContainerView::Delegate:
void OnSearchResultContainerResultsChanging() override;
void OnSearchResultContainerResultsChanged() override;
// views::View:
void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
void VisibilityChanged(View* starting_from, bool is_visible) override;
void OnKeyEvent(ui::KeyEvent* event) override;
// AppListModelProvider::Observer:
void OnActiveAppListModelsChanged(AppListModel* model,
SearchModel* search_model) override;
// Handles the `key_event` when the focus is moving above the search results,
// and returns true if the event is handled. Note that the caller of this
// function is responsible to set the event state to handled.
bool OverrideKeyNavigationAboveSearchResults(const ui::KeyEvent& key_event);
// Called when the app list search query changes and new search is about to
// start or cleared.
// `search_active` - whether search update will result in a new search. This
// will be false when the search is about to be cleared using an empty query.
void UpdateForNewSearch(bool search_active);
// Returns true if there are search results that can be keyboard selected.
bool CanSelectSearchResults();
// Sums the heights of all search_result_list_views_ owned by this view.
int TabletModePreferredHeight();
// Returns a layer that can be used for launcher page animations. Which layer
// is an implementation detail.
ui::Layer* GetPageAnimationLayer() const;
// Removes `search_notifer_` from the view hierarchy. This is called when
// `search_notifier_` is either accepted or timeout.
void RemoveSearchNotifierView();
std::vector<SearchResultContainerView*> result_container_views_for_test() {
return result_container_views_;
}
ResultSelectionController* result_selection_controller_for_test() {
return result_selection_controller_.get();
}
SearchBoxView* search_box_view() { return search_box_view_.get(); }
SearchResultImageListView* image_search_container() {
return image_search_container_;
}
AppListToastView* search_notifier_view() { return search_notifier_; }
SearchNotifierController* search_notifier_controller() const {
return search_notifier_controller_.get();
}
private:
// views::View:
void OnBoundsChanged(const gfx::Rect& previous_bounds) override;
// Passed to |result_selection_controller_| as a callback that gets called
// when the currently selected result changes.
// Scrolls the list view to the newly selected result.
void OnSelectedResultChanged();
// Sets whether changes in search result containers should be hidden from the
// accessibility framework.
// This is set while search results are being updated to reduce noisy updates
// sent to the accessibility framework while the search result containers are
// being rebuilt.
// The |ignore| value is reset in NotifyA11yResultsChanged(), at which time
// accessibility framework is notified that the view value/selected children
// have changed.
void SetIgnoreResultChangesForA11y(bool ignore);
// Schedules a call to |NotifyA11yResultsChanged|. Called from
// OnSearchResultContainerResultsChanged() when all result containers have
// finished changing. The goal of the delay is to silence bursts of A11Y
// events caused by from rapidly changing user queries and consecutive search
// result updates.
void ScheduleResultsChangedA11yNotification();
// Notifies the accessibility framework that the set of search results has
// changed.
// Note: This ensures that results changes are not being hidden from a11y
// framework.
void NotifyA11yResultsChanged();
// Send a kSelection a11y notification for the currently selected search
// result view unless overridden by |ignore_result_changes_for_a11y_|.
void MaybeNotifySelectedResultChanged();
// A callback that is triggered when the toast button of the search notifier
// is pressed.
void OnSearchNotifierButtonPressed();
const raw_ptr<SearchResultPageDialogController,
DanglingUntriaged | ExperimentalAsh>
dialog_controller_;
const raw_ptr<SearchBoxView, DanglingUntriaged | ExperimentalAsh>
search_box_view_;
// The scroll view that contains all the result_container_views_.
raw_ptr<views::ScrollView, ExperimentalAsh> scroll_view_ = nullptr;
// Whether changes in search result containers are hidden from the
// accessibility framework.
bool ignore_result_changes_for_a11y_ = false;
// Containers for search result views. The contained views are owned by the
// views hierarchy. Used by result_selection_controller_.
std::vector<SearchResultContainerView*> result_container_views_;
// The notifier that shows the search privacy notice or educational nudge.
raw_ptr<AppListToastView, ExperimentalAsh> search_notifier_ = nullptr;
// The container of the image search results. This is owned by the views
// hierarchy and is an element in result_container_views_;
raw_ptr<SearchResultImageListView, ExperimentalAsh> image_search_container_ =
nullptr;
// Cache of the last shown search results' animation metadata.
std::vector<SearchResultContainerView::SearchResultAimationMetadata>
last_result_metadata_;
// Handles search result selection.
std::unique_ptr<ResultSelectionController> result_selection_controller_;
// Handles the search notifiers in launcher search.
std::unique_ptr<SearchNotifierController> search_notifier_controller_;
// Timer used to delay calls to NotifyA11yResultsChanged().
base::OneShotTimer notify_a11y_results_changed_timer_;
// The virtual view that announces the guidance to the search notifier. The
// ownership belongs to the view accessibility.
raw_ptr<views::AXVirtualView> search_notifier_guide_ = nullptr;
// Stores the last time fast search result update animations were used.
absl::optional<base::TimeTicks> search_result_fast_update_time_;
// The last reported number of search results shown by all containers.
int last_search_result_count_ = 0;
base::WeakPtrFactory<AppListSearchView> weak_ptr_factory_{this};
};
} // namespace ash
#endif // ASH_APP_LIST_VIEWS_APP_LIST_SEARCH_VIEW_H_
|