OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/app_list/views/start_page_view.h" | 5 #include "ui/app_list/views/start_page_view.h" |
6 | 6 |
7 #include "base/i18n/rtl.h" | 7 #include "base/i18n/rtl.h" |
8 #include "base/metrics/histogram_macros.h" | 8 #include "base/metrics/histogram_macros.h" |
9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
| 10 #include "ui/accessibility/ax_view_state.h" |
10 #include "ui/app_list/app_list_constants.h" | 11 #include "ui/app_list/app_list_constants.h" |
11 #include "ui/app_list/app_list_item.h" | 12 #include "ui/app_list/app_list_item.h" |
12 #include "ui/app_list/app_list_model.h" | 13 #include "ui/app_list/app_list_model.h" |
13 #include "ui/app_list/app_list_view_delegate.h" | 14 #include "ui/app_list/app_list_view_delegate.h" |
14 #include "ui/app_list/search_result.h" | 15 #include "ui/app_list/search_result.h" |
15 #include "ui/app_list/views/all_apps_tile_item_view.h" | 16 #include "ui/app_list/views/all_apps_tile_item_view.h" |
16 #include "ui/app_list/views/app_list_main_view.h" | 17 #include "ui/app_list/views/app_list_main_view.h" |
17 #include "ui/app_list/views/contents_view.h" | 18 #include "ui/app_list/views/contents_view.h" |
18 #include "ui/app_list/views/search_box_view.h" | 19 #include "ui/app_list/views/search_box_view.h" |
19 #include "ui/app_list/views/search_result_container_view.h" | 20 #include "ui/app_list/views/search_result_container_view.h" |
(...skipping 17 matching lines...) Expand all Loading... |
37 const int kStartPageSearchBoxWidth = 480; | 38 const int kStartPageSearchBoxWidth = 480; |
38 | 39 |
39 // WebView constants. | 40 // WebView constants. |
40 const int kWebViewWidth = 700; | 41 const int kWebViewWidth = 700; |
41 const int kWebViewHeight = 244; | 42 const int kWebViewHeight = 244; |
42 | 43 |
43 // Tile container constants. | 44 // Tile container constants. |
44 const size_t kNumStartPageTiles = 4; | 45 const size_t kNumStartPageTiles = 4; |
45 const int kTileSpacing = 7; | 46 const int kTileSpacing = 7; |
46 | 47 |
| 48 const int kLauncherPageBackgroundWidth = 400; |
| 49 |
47 // An invisible placeholder view which fills the space for the search box view | 50 // An invisible placeholder view which fills the space for the search box view |
48 // in a box layout. The search box view itself is a child of the AppListView | 51 // in a box layout. The search box view itself is a child of the AppListView |
49 // (because it is visible on many different pages). | 52 // (because it is visible on many different pages). |
50 class SearchBoxSpacerView : public views::View { | 53 class SearchBoxSpacerView : public views::View { |
51 public: | 54 public: |
52 explicit SearchBoxSpacerView(const gfx::Size& search_box_size) | 55 explicit SearchBoxSpacerView(const gfx::Size& search_box_size) |
53 : size_(kStartPageSearchBoxWidth, search_box_size.height()) {} | 56 : size_(kStartPageSearchBoxWidth, search_box_size.height()) {} |
54 | 57 |
55 ~SearchBoxSpacerView() override {} | 58 ~SearchBoxSpacerView() override {} |
56 | 59 |
57 // Overridden from views::View: | 60 // Overridden from views::View: |
58 gfx::Size GetPreferredSize() const override { return size_; } | 61 gfx::Size GetPreferredSize() const override { return size_; } |
59 | 62 |
60 private: | 63 private: |
61 gfx::Size size_; | 64 gfx::Size size_; |
62 | 65 |
63 DISALLOW_COPY_AND_ASSIGN(SearchBoxSpacerView); | 66 DISALLOW_COPY_AND_ASSIGN(SearchBoxSpacerView); |
64 }; | 67 }; |
65 | 68 |
66 } // namespace | 69 } // namespace |
67 | 70 |
| 71 class CustomLauncherPageBackgroundView : public views::View { |
| 72 public: |
| 73 explicit CustomLauncherPageBackgroundView( |
| 74 const std::string& custom_launcher_page_name) |
| 75 : selected_(false), |
| 76 custom_launcher_page_name_(custom_launcher_page_name) { |
| 77 set_background(views::Background::CreateSolidBackground(kSelectedColor)); |
| 78 } |
| 79 ~CustomLauncherPageBackgroundView() override {} |
| 80 |
| 81 void SetSelected(bool selected) { |
| 82 selected_ = selected; |
| 83 SetVisible(selected); |
| 84 if (selected) |
| 85 NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, true); |
| 86 } |
| 87 |
| 88 bool selected() { return selected_; } |
| 89 |
| 90 // Overridden from views::View: |
| 91 void GetAccessibleState(ui::AXViewState* state) override { |
| 92 state->role = ui::AX_ROLE_BUTTON; |
| 93 state->name = base::UTF8ToUTF16(custom_launcher_page_name_); |
| 94 } |
| 95 |
| 96 private: |
| 97 bool selected_; |
| 98 std::string custom_launcher_page_name_; |
| 99 |
| 100 DISALLOW_COPY_AND_ASSIGN(CustomLauncherPageBackgroundView); |
| 101 }; |
| 102 |
68 // A container that holds the start page recommendation tiles and the all apps | 103 // A container that holds the start page recommendation tiles and the all apps |
69 // tile. | 104 // tile. |
70 class StartPageView::StartPageTilesContainer | 105 class StartPageView::StartPageTilesContainer |
71 : public SearchResultContainerView { | 106 : public SearchResultContainerView { |
72 public: | 107 public: |
73 StartPageTilesContainer(ContentsView* contents_view, | 108 StartPageTilesContainer(ContentsView* contents_view, |
74 AllAppsTileItemView* all_apps_button); | 109 AllAppsTileItemView* all_apps_button); |
75 ~StartPageTilesContainer() override; | 110 ~StartPageTilesContainer() override; |
76 | 111 |
77 TileItemView* GetTileItemView(int index); | 112 TileItemView* GetTileItemView(int index); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 | 216 |
182 //////////////////////////////////////////////////////////////////////////////// | 217 //////////////////////////////////////////////////////////////////////////////// |
183 // StartPageView implementation: | 218 // StartPageView implementation: |
184 StartPageView::StartPageView(AppListMainView* app_list_main_view, | 219 StartPageView::StartPageView(AppListMainView* app_list_main_view, |
185 AppListViewDelegate* view_delegate) | 220 AppListViewDelegate* view_delegate) |
186 : app_list_main_view_(app_list_main_view), | 221 : app_list_main_view_(app_list_main_view), |
187 view_delegate_(view_delegate), | 222 view_delegate_(view_delegate), |
188 search_box_spacer_view_(new SearchBoxSpacerView( | 223 search_box_spacer_view_(new SearchBoxSpacerView( |
189 app_list_main_view->search_box_view()->GetPreferredSize())), | 224 app_list_main_view->search_box_view()->GetPreferredSize())), |
190 instant_container_(new views::View), | 225 instant_container_(new views::View), |
| 226 custom_launcher_page_background_(new CustomLauncherPageBackgroundView( |
| 227 view_delegate_->GetModel()->custom_launcher_page_name())), |
191 tiles_container_(new StartPageTilesContainer( | 228 tiles_container_(new StartPageTilesContainer( |
192 app_list_main_view->contents_view(), | 229 app_list_main_view->contents_view(), |
193 new AllAppsTileItemView( | 230 new AllAppsTileItemView( |
194 app_list_main_view_->contents_view(), | 231 app_list_main_view_->contents_view(), |
195 view_delegate_->GetModel()->top_level_item_list()))) { | 232 view_delegate_->GetModel()->top_level_item_list()))) { |
196 // The view containing the start page WebContents and SearchBoxSpacerView. | 233 // The view containing the start page WebContents and SearchBoxSpacerView. |
197 InitInstantContainer(); | 234 InitInstantContainer(); |
198 AddChildView(instant_container_); | 235 AddChildView(instant_container_); |
199 | 236 |
200 // The view containing the start page tiles. | 237 // The view containing the start page tiles. |
201 AddChildView(tiles_container_); | 238 AddChildView(tiles_container_); |
202 | 239 |
| 240 AddChildView(custom_launcher_page_background_); |
| 241 |
203 tiles_container_->SetResults(view_delegate_->GetModel()->results()); | 242 tiles_container_->SetResults(view_delegate_->GetModel()->results()); |
204 Reset(); | 243 Reset(); |
205 } | 244 } |
206 | 245 |
207 StartPageView::~StartPageView() { | 246 StartPageView::~StartPageView() { |
208 } | 247 } |
209 | 248 |
210 void StartPageView::InitInstantContainer() { | 249 void StartPageView::InitInstantContainer() { |
211 views::BoxLayout* instant_layout_manager = new views::BoxLayout( | 250 views::BoxLayout* instant_layout_manager = new views::BoxLayout( |
212 views::BoxLayout::kVertical, 0, 0, kInstantContainerSpacing); | 251 views::BoxLayout::kVertical, 0, 0, kInstantContainerSpacing); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 return tiles_container_->tile_views(); | 295 return tiles_container_->tile_views(); |
257 } | 296 } |
258 | 297 |
259 TileItemView* StartPageView::all_apps_button() const { | 298 TileItemView* StartPageView::all_apps_button() const { |
260 return tiles_container_->all_apps_button(); | 299 return tiles_container_->all_apps_button(); |
261 } | 300 } |
262 | 301 |
263 void StartPageView::OnShow() { | 302 void StartPageView::OnShow() { |
264 tiles_container_->Update(); | 303 tiles_container_->Update(); |
265 tiles_container_->ClearSelectedIndex(); | 304 tiles_container_->ClearSelectedIndex(); |
| 305 custom_launcher_page_background_->SetSelected(false); |
266 } | 306 } |
267 | 307 |
268 void StartPageView::Layout() { | 308 void StartPageView::Layout() { |
269 gfx::Rect bounds(GetContentsBounds()); | 309 gfx::Rect bounds(GetContentsBounds()); |
270 bounds.set_height(instant_container_->GetHeightForWidth(bounds.width())); | 310 bounds.set_height(instant_container_->GetHeightForWidth(bounds.width())); |
271 instant_container_->SetBoundsRect(bounds); | 311 instant_container_->SetBoundsRect(bounds); |
272 | 312 |
273 // Tiles begin where the instant container ends. | 313 // Tiles begin where the instant container ends. |
274 bounds.set_y(bounds.bottom()); | 314 bounds.set_y(bounds.bottom()); |
275 bounds.set_height(tiles_container_->GetHeightForWidth(bounds.width())); | 315 bounds.set_height(tiles_container_->GetHeightForWidth(bounds.width())); |
276 tiles_container_->SetBoundsRect(bounds); | 316 tiles_container_->SetBoundsRect(bounds); |
| 317 |
| 318 bounds = app_list_main_view_->contents_view()->GetCustomPageCollapsedBounds(); |
| 319 bounds.Intersect(GetContentsBounds()); |
| 320 bounds.ClampToCenteredSize( |
| 321 gfx::Size(kLauncherPageBackgroundWidth, bounds.height())); |
| 322 custom_launcher_page_background_->SetBoundsRect(bounds); |
277 } | 323 } |
278 | 324 |
279 bool StartPageView::OnKeyPressed(const ui::KeyEvent& event) { | 325 bool StartPageView::OnKeyPressed(const ui::KeyEvent& event) { |
| 326 const int forward_dir = base::i18n::IsRTL() ? -1 : 1; |
280 int selected_index = tiles_container_->selected_index(); | 327 int selected_index = tiles_container_->selected_index(); |
281 if (selected_index >= 0 && | 328 |
282 tiles_container_->GetTileItemView(selected_index)->OnKeyPressed(event)) | 329 if (custom_launcher_page_background_->selected()) { |
| 330 selected_index = tiles_container_->num_results(); |
| 331 switch (event.key_code()) { |
| 332 case ui::VKEY_RETURN: |
| 333 MaybeOpenCustomLauncherPage(); |
| 334 return true; |
| 335 default: |
| 336 break; |
| 337 } |
| 338 } else if (selected_index >= 0 && |
| 339 tiles_container_->GetTileItemView(selected_index) |
| 340 ->OnKeyPressed(event)) { |
283 return true; | 341 return true; |
| 342 } |
284 | 343 |
285 const int forward_dir = base::i18n::IsRTL() ? -1 : 1; | |
286 int dir = 0; | 344 int dir = 0; |
287 switch (event.key_code()) { | 345 switch (event.key_code()) { |
288 case ui::VKEY_LEFT: | 346 case ui::VKEY_LEFT: |
289 dir = -forward_dir; | 347 dir = -forward_dir; |
290 break; | 348 break; |
291 case ui::VKEY_RIGHT: | 349 case ui::VKEY_RIGHT: |
292 dir = forward_dir; | 350 // Don't go to the custom launcher page from the All apps tile. |
| 351 if (selected_index != tiles_container_->num_results() - 1) |
| 352 dir = forward_dir; |
| 353 break; |
| 354 case ui::VKEY_UP: |
| 355 // Up selects the first tile if the custom launcher is selected. |
| 356 if (custom_launcher_page_background_->selected()) { |
| 357 selected_index = -1; |
| 358 dir = 1; |
| 359 } |
293 break; | 360 break; |
294 case ui::VKEY_DOWN: | 361 case ui::VKEY_DOWN: |
295 // Down selects the first tile if nothing is selected. | 362 // Down selects the first tile if nothing is selected. |
296 if (!tiles_container_->IsValidSelectionIndex(selected_index)) | 363 dir = 1; |
297 dir = 1; | 364 // If something is selected, select the custom launcher page. |
| 365 if (tiles_container_->IsValidSelectionIndex(selected_index)) |
| 366 selected_index = tiles_container_->num_results() - 1; |
298 break; | 367 break; |
299 case ui::VKEY_TAB: | 368 case ui::VKEY_TAB: |
300 dir = event.IsShiftDown() ? -1 : 1; | 369 dir = event.IsShiftDown() ? -1 : 1; |
301 break; | 370 break; |
302 default: | 371 default: |
303 break; | 372 break; |
304 } | 373 } |
305 | 374 |
306 if (dir == 0) | 375 if (dir == 0) |
307 return false; | 376 return false; |
308 | 377 |
309 if (!tiles_container_->IsValidSelectionIndex(selected_index)) { | 378 if (selected_index == -1) { |
| 379 custom_launcher_page_background_->SetSelected(false); |
310 tiles_container_->SetSelectedIndex( | 380 tiles_container_->SetSelectedIndex( |
311 dir == -1 ? tiles_container_->num_results() - 1 : 0); | 381 dir == -1 ? tiles_container_->num_results() - 1 : 0); |
312 return true; | 382 return true; |
313 } | 383 } |
314 | 384 |
315 int selection_index = selected_index + dir; | 385 int selection_index = selected_index + dir; |
316 if (tiles_container_->IsValidSelectionIndex(selection_index)) { | 386 if (tiles_container_->IsValidSelectionIndex(selection_index)) { |
| 387 custom_launcher_page_background_->SetSelected(false); |
317 tiles_container_->SetSelectedIndex(selection_index); | 388 tiles_container_->SetSelectedIndex(selection_index); |
318 return true; | 389 return true; |
319 } | 390 } |
320 | 391 |
| 392 if (selection_index == tiles_container_->num_results() && |
| 393 app_list_main_view_->ShouldShowCustomLauncherPage()) { |
| 394 custom_launcher_page_background_->SetSelected(true); |
| 395 tiles_container_->ClearSelectedIndex(); |
| 396 return true; |
| 397 } |
| 398 |
321 if (event.key_code() == ui::VKEY_TAB && selection_index == -1) | 399 if (event.key_code() == ui::VKEY_TAB && selection_index == -1) |
322 tiles_container_->ClearSelectedIndex(); // ContentsView will handle focus. | 400 tiles_container_->ClearSelectedIndex(); // ContentsView will handle focus. |
323 | 401 |
324 return false; | 402 return false; |
325 } | 403 } |
326 | 404 |
327 bool StartPageView::OnMousePressed(const ui::MouseEvent& event) { | 405 bool StartPageView::OnMousePressed(const ui::MouseEvent& event) { |
328 ContentsView* contents_view = app_list_main_view_->contents_view(); | 406 ContentsView* contents_view = app_list_main_view_->contents_view(); |
329 if (!contents_view->GetCustomPageCollapsedBounds().Contains(event.location())) | 407 if (!contents_view->GetCustomPageCollapsedBounds().Contains(event.location())) |
330 return false; | 408 return false; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 | 441 |
364 gfx::Rect StartPageView::GetSearchBoxBounds() const { | 442 gfx::Rect StartPageView::GetSearchBoxBounds() const { |
365 return search_box_spacer_view_->bounds(); | 443 return search_box_spacer_view_->bounds(); |
366 } | 444 } |
367 | 445 |
368 TileItemView* StartPageView::GetTileItemView(size_t index) { | 446 TileItemView* StartPageView::GetTileItemView(size_t index) { |
369 return tiles_container_->GetTileItemView(index); | 447 return tiles_container_->GetTileItemView(index); |
370 } | 448 } |
371 | 449 |
372 } // namespace app_list | 450 } // namespace app_list |
OLD | NEW |