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

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

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