Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: ui/app_list/views/start_page_view.cc

Issue 924193005: Add keyboard navigation to the custom launcher page on app list start page. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/app_list/views/start_page_view.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « ui/app_list/views/start_page_view.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698