1 // Copyright 2014 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.
5 #include "ui/app_list/views/search_result_page_view.h"
9 #include "ui/app_list/app_list_constants.h"
10 #include "ui/app_list/app_list_switches.h"
11 #include "ui/app_list/app_list_view_delegate.h"
12 #include "ui/app_list/views/app_list_main_view.h"
13 #include "ui/app_list/views/search_box_view.h"
14 #include "ui/app_list/views/search_result_list_view.h"
15 #include "ui/app_list/views/search_result_tile_item_list_view.h"
16 #include "ui/gfx/shadow_value.h"
17 #include "ui/views/background.h"
18 #include "ui/views/layout/box_layout.h"
19 #include "ui/views/layout/fill_layout.h"
20 #include "ui/views/shadow_border.h"
26 const int kGroupSpacing
= 6;
27 const int kTopPadding
= 8;
29 // The z-height of the search box and cards in this view.
30 const int kSearchResultZHeight
= 1;
32 // A container view that ensures the card background and the shadow are painted
33 // in the correct order.
34 class SearchCardView
: public views::View
{
36 explicit SearchCardView(views::View
* content_view
) {
37 SetBorder(make_scoped_ptr(
38 new views::ShadowBorder(GetShadowForZHeight(kSearchResultZHeight
))));
39 SetLayoutManager(new views::FillLayout());
40 content_view
->set_background(
41 views::Background::CreateSolidBackground(kCardBackgroundColor
));
42 AddChildView(content_view
);
45 ~SearchCardView() override
{}
47 void ChildPreferredSizeChanged(views::View
* child
) override
{
49 PreferredSizeChanged();
55 SearchResultPageView::SearchResultPageView() : selected_index_(0) {
56 if (switches::IsExperimentalAppListEnabled()) {
57 gfx::ShadowValue shadow
= GetShadowForZHeight(kSearchResultZHeight
);
58 scoped_ptr
<views::Border
> border(new views::ShadowBorder(shadow
));
60 gfx::Insets insets
= gfx::Insets(kTopPadding
, kExperimentalSearchBoxPadding
,
61 0, kExperimentalSearchBoxPadding
);
62 insets
+= -border
->GetInsets();
64 views::BoxLayout
* layout
=
65 new views::BoxLayout(views::BoxLayout::kVertical
, 0, 0, kGroupSpacing
);
66 layout
->set_inside_border_insets(insets
);
68 SetLayoutManager(layout
);
70 SetLayoutManager(new views::FillLayout
);
74 SearchResultPageView::~SearchResultPageView() {
77 void SearchResultPageView::SetSelection(bool select
) {
79 SetSelectedIndex(0, false);
81 result_container_views_
[selected_index_
]->ClearSelectedIndex();
84 void SearchResultPageView::AddSearchResultContainerView(
85 AppListModel::SearchResults
* results_model
,
86 SearchResultContainerView
* result_container
) {
87 views::View
* view_to_add
= result_container
;
88 if (switches::IsExperimentalAppListEnabled())
89 view_to_add
= new SearchCardView(result_container
);
91 AddChildView(view_to_add
);
92 result_container_views_
.push_back(result_container
);
93 result_container
->SetResults(results_model
);
96 bool SearchResultPageView::OnKeyPressed(const ui::KeyEvent
& event
) {
97 if (result_container_views_
.at(selected_index_
)->OnKeyPressed(event
))
101 bool directional_movement
= false;
102 switch (event
.key_code()) {
104 dir
= event
.IsShiftDown() ? -1 : 1;
108 directional_movement
= true;
112 directional_movement
= true;
118 // Find the next result container with results.
119 int new_selected
= selected_index_
;
122 } while (IsValidSelectionIndex(new_selected
) &&
123 result_container_views_
[new_selected
]->num_results() == 0);
125 if (IsValidSelectionIndex(new_selected
)) {
126 SetSelectedIndex(new_selected
, directional_movement
);
133 void SearchResultPageView::SetSelectedIndex(int index
,
134 bool directional_movement
) {
135 bool from_bottom
= index
< selected_index_
;
137 // Reset the old selected view's selection.
138 result_container_views_
[selected_index_
]->ClearSelectedIndex();
139 selected_index_
= index
;
140 // Set the new selected view's selection to its first result.
141 result_container_views_
[selected_index_
]->OnContainerSelected(
142 from_bottom
, directional_movement
);
145 bool SearchResultPageView::IsValidSelectionIndex(int index
) {
146 return index
>= 0 && index
< static_cast<int>(result_container_views_
.size());
149 void SearchResultPageView::ChildPreferredSizeChanged(views::View
* child
) {
150 DCHECK(!result_container_views_
.empty());
152 if (switches::IsExperimentalAppListEnabled()) {
153 // Sort the result container views by their score.
154 std::sort(result_container_views_
.begin(), result_container_views_
.end(),
155 [](const SearchResultContainerView
* a
,
156 const SearchResultContainerView
* b
) -> bool {
157 return a
->container_score() > b
->container_score();
160 for (size_t i
= 0; i
< result_container_views_
.size(); ++i
) {
161 result_container_views_
[i
]->ClearSelectedIndex();
162 ReorderChildView(result_container_views_
[i
]->parent(), i
);
167 SetSelectedIndex(0, false);
170 gfx::Rect
SearchResultPageView::GetPageBoundsForState(
171 AppListModel::State state
) const {
172 gfx::Rect onscreen_bounds
= GetDefaultContentsBounds();
174 case AppListModel::STATE_SEARCH_RESULTS
:
175 return onscreen_bounds
;
177 return GetAboveContentsOffscreenBounds(onscreen_bounds
.size());
181 void SearchResultPageView::OnAnimationUpdated(double progress
,
182 AppListModel::State from_state
,
183 AppListModel::State to_state
) {
184 if (from_state
!= AppListModel::STATE_SEARCH_RESULTS
&&
185 to_state
!= AppListModel::STATE_SEARCH_RESULTS
) {
189 gfx::Rect
onscreen_bounds(
190 GetPageBoundsForState(AppListModel::STATE_SEARCH_RESULTS
));
191 set_clip_insets(bounds().InsetsFrom(onscreen_bounds
));
194 int SearchResultPageView::GetSearchBoxZHeight() const {
195 return switches::IsExperimentalAppListEnabled()
196 ? kSearchResultZHeight
197 : AppListPage::GetSearchBoxZHeight();
200 } // namespace app_list