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/start_page_view.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "ui/app_list/app_list_constants.h"
9 #include "ui/app_list/app_list_item.h"
10 #include "ui/app_list/app_list_model.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/tile_item_view.h"
16 #include "ui/gfx/canvas.h"
17 #include "ui/views/background.h"
18 #include "ui/views/controls/image_view.h"
19 #include "ui/views/controls/label.h"
20 #include "ui/views/controls/textfield/textfield.h"
21 #include "ui/views/layout/box_layout.h"
28 const int kTopMargin
= 30;
29 const int kInstantContainerSpacing
= 20;
32 const int kWebViewWidth
= 200;
33 const int kWebViewHeight
= 105;
35 // DummySearchBoxView constants.
36 const int kDummySearchBoxWidth
= 490;
37 const int kDummySearchBoxHeight
= 40;
38 const int kDummySearchBoxBorderWidth
= 1;
39 const int kDummySearchBoxBorderBottomWidth
= 2;
40 const int kDummySearchBoxBorderCornerRadius
= 2;
42 // Tile container constants.
43 const size_t kNumStartPageTiles
= 5;
44 const int kTileSpacing
= 10;
46 // A background that paints a solid white rounded rect with a thin grey border.
47 class DummySearchBoxBackground
: public views::Background
{
49 DummySearchBoxBackground() {}
50 virtual ~DummySearchBoxBackground() {}
53 // views::Background overrides:
54 virtual void Paint(gfx::Canvas
* canvas
, views::View
* view
) const OVERRIDE
{
55 gfx::Rect bounds
= view
->GetContentsBounds();
58 paint
.setFlags(SkPaint::kAntiAlias_Flag
);
59 paint
.setColor(kStartPageBorderColor
);
60 canvas
->DrawRoundRect(bounds
, kDummySearchBoxBorderCornerRadius
, paint
);
61 bounds
.Inset(kDummySearchBoxBorderWidth
,
62 kDummySearchBoxBorderWidth
,
63 kDummySearchBoxBorderWidth
,
64 kDummySearchBoxBorderBottomWidth
);
65 paint
.setColor(SK_ColorWHITE
);
66 canvas
->DrawRoundRect(bounds
, kDummySearchBoxBorderCornerRadius
, paint
);
69 DISALLOW_COPY_AND_ASSIGN(DummySearchBoxBackground
);
72 // A placeholder search box which is sized to fit within the start page view.
73 class DummySearchBoxView
: public SearchBoxView
{
75 DummySearchBoxView(SearchBoxViewDelegate
* delegate
,
76 AppListViewDelegate
* view_delegate
)
77 : SearchBoxView(delegate
, view_delegate
) {
78 set_background(new DummySearchBoxBackground());
81 virtual ~DummySearchBoxView() {}
83 // Overridden from views::View:
84 virtual gfx::Size
GetPreferredSize() const OVERRIDE
{
85 return gfx::Size(kDummySearchBoxWidth
, kDummySearchBoxHeight
);
89 DISALLOW_COPY_AND_ASSIGN(DummySearchBoxView
);
94 StartPageView::StartPageView(AppListMainView
* app_list_main_view
,
95 AppListViewDelegate
* view_delegate
)
96 : app_list_main_view_(app_list_main_view
),
98 view_delegate_(view_delegate
),
99 search_box_view_(new DummySearchBoxView(this, view_delegate_
)),
101 new SearchResultListView(app_list_main_view
, view_delegate
)),
102 instant_container_(new views::View
),
103 tiles_container_(new views::View
),
104 show_state_(SHOW_START_PAGE
) {
105 // The view containing the start page WebContents and DummySearchBoxView.
106 InitInstantContainer();
107 AddChildView(instant_container_
);
109 // The view containing the search results.
110 AddChildView(results_view_
);
112 // The view containing the start page tiles.
113 InitTilesContainer();
114 AddChildView(tiles_container_
);
116 SetModel(view_delegate_
->GetModel());
117 view_delegate_
->AddObserver(this);
120 StartPageView::~StartPageView() {
121 view_delegate_
->RemoveObserver(this);
123 model_
->RemoveObserver(this);
126 void StartPageView::InitInstantContainer() {
127 views::BoxLayout
* instant_layout_manager
= new views::BoxLayout(
128 views::BoxLayout::kVertical
, 0, 0, kInstantContainerSpacing
);
129 instant_layout_manager
->set_inside_border_insets(
130 gfx::Insets(kTopMargin
, 0, kInstantContainerSpacing
, 0));
131 instant_layout_manager
->set_main_axis_alignment(
132 views::BoxLayout::MAIN_AXIS_ALIGNMENT_END
);
133 instant_container_
->SetLayoutManager(instant_layout_manager
);
135 views::View
* web_view
= view_delegate_
->CreateStartPageWebView(
136 gfx::Size(kWebViewWidth
, kWebViewHeight
));
138 instant_container_
->AddChildView(web_view
);
140 // TODO(calamity): This container is needed to horizontally center the search
141 // box view. Remove this container once BoxLayout supports CrossAxisAlignment.
142 views::View
* search_box_container
= new views::View();
143 views::BoxLayout
* layout_manager
=
144 new views::BoxLayout(views::BoxLayout::kHorizontal
, 0, 0, 0);
145 layout_manager
->set_main_axis_alignment(
146 views::BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER
);
147 search_box_container
->SetLayoutManager(layout_manager
);
148 search_box_container
->AddChildView(search_box_view_
);
150 instant_container_
->AddChildView(search_box_container
);
153 void StartPageView::InitTilesContainer() {
154 views::BoxLayout
* tiles_layout_manager
=
155 new views::BoxLayout(views::BoxLayout::kHorizontal
, 0, 0, kTileSpacing
);
156 tiles_layout_manager
->set_main_axis_alignment(
157 views::BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER
);
158 tiles_container_
->SetLayoutManager(tiles_layout_manager
);
159 for (size_t i
= 0; i
< kNumStartPageTiles
; ++i
) {
160 TileItemView
* tile_item
= new TileItemView();
161 tiles_container_
->AddChildView(tile_item
);
162 tile_views_
.push_back(tile_item
);
166 void StartPageView::SetModel(AppListModel
* model
) {
169 model_
->RemoveObserver(this);
171 model_
->AddObserver(this);
172 results_view_
->SetResults(model_
->results());
176 void StartPageView::Reset() {
177 SetShowState(SHOW_START_PAGE
);
178 if (!model_
|| !model_
->top_level_item_list())
181 for (size_t i
= 0; i
< kNumStartPageTiles
; ++i
) {
182 AppListItem
* item
= NULL
;
183 if (i
< model_
->top_level_item_list()->item_count())
184 item
= model_
->top_level_item_list()->item_at(i
);
185 tile_views_
[i
]->SetAppListItem(item
);
189 void StartPageView::ShowSearchResults() {
190 SetShowState(SHOW_SEARCH_RESULTS
);
193 void StartPageView::SetShowState(ShowState show_state
) {
194 instant_container_
->SetVisible(show_state
== SHOW_START_PAGE
);
195 results_view_
->SetVisible(show_state
== SHOW_SEARCH_RESULTS
);
197 if (show_state
== SHOW_START_PAGE
)
198 search_box_view_
->search_box()->RequestFocus();
200 if (show_state_
== show_state
)
203 show_state_
= show_state
;
205 results_view_
->UpdateAutoLaunchState();
206 if (show_state
== SHOW_SEARCH_RESULTS
)
207 results_view_
->SetSelectedIndex(0);
210 bool StartPageView::IsShowingSearchResults() const {
211 return show_state_
== SHOW_SEARCH_RESULTS
;
214 bool StartPageView::OnKeyPressed(const ui::KeyEvent
& event
) {
215 if (show_state_
== SHOW_SEARCH_RESULTS
)
216 return results_view_
->OnKeyPressed(event
);
221 void StartPageView::Layout() {
222 // Instant and search results take up the height of the instant container.
223 gfx::Rect
bounds(GetContentsBounds());
224 bounds
.set_height(instant_container_
->GetHeightForWidth(bounds
.width()));
225 instant_container_
->SetBoundsRect(bounds
);
226 results_view_
->SetBoundsRect(bounds
);
228 // Tiles begin where the instant container ends.
229 bounds
.set_y(bounds
.bottom());
230 bounds
.set_height(tiles_container_
->GetHeightForWidth(bounds
.width()));
231 tiles_container_
->SetBoundsRect(bounds
);
234 void StartPageView::QueryChanged(SearchBoxView
* sender
) {
235 // Forward the search terms on to the real search box and clear the dummy
237 app_list_main_view_
->OnStartPageSearchTextfieldChanged(
238 sender
->search_box()->text());
239 sender
->search_box()->SetText(base::string16());
242 void StartPageView::OnProfilesChanged() {
243 SetModel(view_delegate_
->GetModel());
246 void StartPageView::OnAppListModelStatusChanged() {
250 void StartPageView::OnAppListItemAdded(AppListItem
* item
) {
254 void StartPageView::OnAppListItemDeleted() {
258 void StartPageView::OnAppListItemUpdated(AppListItem
* item
) {
262 } // namespace app_list