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

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: 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
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 = 250;
Matt Giuca 2015/02/20 05:49:26 Needs to be at least 350px wide (plus a bit of a b
calamity 2015/02/20 06:57:44 Done.
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 }
Matt Giuca 2015/02/20 05:49:26 nit: Blank line.
calamity 2015/02/20 06:57:44 Done.
86 bool selected() { return selected_; }
87
88 // Overridden from views::View:
89 void GetAccessibleState(ui::AXViewState* state) override {
90 state->role = ui::AX_ROLE_BUTTON;
91 state->name = base::UTF8ToUTF16(custom_launcher_page_name_);
92 }
93
94 private:
95 bool selected_;
96 std::string custom_launcher_page_name_;
97
98 DISALLOW_COPY_AND_ASSIGN(CustomLauncherPageBackgroundView);
99 };
100
67 // A container that holds the start page recommendation tiles and the all apps 101 // A container that holds the start page recommendation tiles and the all apps
68 // tile. 102 // tile.
69 class StartPageView::StartPageTilesContainer 103 class StartPageView::StartPageTilesContainer
70 : public SearchResultContainerView { 104 : public SearchResultContainerView {
71 public: 105 public:
72 StartPageTilesContainer(ContentsView* contents_view, 106 StartPageTilesContainer(ContentsView* contents_view,
73 AllAppsTileItemView* all_apps_button); 107 AllAppsTileItemView* all_apps_button);
74 ~StartPageTilesContainer() override; 108 ~StartPageTilesContainer() override;
75 109
76 TileItemView* GetTileItemView(int index); 110 TileItemView* GetTileItemView(int index);
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 214
181 //////////////////////////////////////////////////////////////////////////////// 215 ////////////////////////////////////////////////////////////////////////////////
182 // StartPageView implementation: 216 // StartPageView implementation:
183 StartPageView::StartPageView(AppListMainView* app_list_main_view, 217 StartPageView::StartPageView(AppListMainView* app_list_main_view,
184 AppListViewDelegate* view_delegate) 218 AppListViewDelegate* view_delegate)
185 : app_list_main_view_(app_list_main_view), 219 : app_list_main_view_(app_list_main_view),
186 view_delegate_(view_delegate), 220 view_delegate_(view_delegate),
187 search_box_spacer_view_(new SearchBoxSpacerView( 221 search_box_spacer_view_(new SearchBoxSpacerView(
188 app_list_main_view->search_box_view()->GetPreferredSize())), 222 app_list_main_view->search_box_view()->GetPreferredSize())),
189 instant_container_(new views::View), 223 instant_container_(new views::View),
224 custom_launcher_page_background_(new CustomLauncherPageBackgroundView(
225 view_delegate_->GetModel()->custom_launcher_page_name())),
190 tiles_container_(new StartPageTilesContainer( 226 tiles_container_(new StartPageTilesContainer(
191 app_list_main_view->contents_view(), 227 app_list_main_view->contents_view(),
192 new AllAppsTileItemView( 228 new AllAppsTileItemView(
193 app_list_main_view_->contents_view(), 229 app_list_main_view_->contents_view(),
194 view_delegate_->GetModel()->top_level_item_list()))) { 230 view_delegate_->GetModel()->top_level_item_list()))) {
195 // The view containing the start page WebContents and SearchBoxSpacerView. 231 // The view containing the start page WebContents and SearchBoxSpacerView.
196 InitInstantContainer(); 232 InitInstantContainer();
197 AddChildView(instant_container_); 233 AddChildView(instant_container_);
198 234
199 // The view containing the start page tiles. 235 // The view containing the start page tiles.
200 AddChildView(tiles_container_); 236 AddChildView(tiles_container_);
201 237
238 AddChildView(custom_launcher_page_background_);
239
202 tiles_container_->SetResults(view_delegate_->GetModel()->results()); 240 tiles_container_->SetResults(view_delegate_->GetModel()->results());
203 Reset(); 241 Reset();
204 } 242 }
205 243
206 StartPageView::~StartPageView() { 244 StartPageView::~StartPageView() {
207 } 245 }
208 246
209 void StartPageView::InitInstantContainer() { 247 void StartPageView::InitInstantContainer() {
210 views::BoxLayout* instant_layout_manager = new views::BoxLayout( 248 views::BoxLayout* instant_layout_manager = new views::BoxLayout(
211 views::BoxLayout::kVertical, 0, 0, kInstantContainerSpacing); 249 views::BoxLayout::kVertical, 0, 0, kInstantContainerSpacing);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 return tiles_container_->tile_views(); 289 return tiles_container_->tile_views();
252 } 290 }
253 291
254 TileItemView* StartPageView::all_apps_button() const { 292 TileItemView* StartPageView::all_apps_button() const {
255 return tiles_container_->all_apps_button(); 293 return tiles_container_->all_apps_button();
256 } 294 }
257 295
258 void StartPageView::OnShow() { 296 void StartPageView::OnShow() {
259 tiles_container_->Update(); 297 tiles_container_->Update();
260 tiles_container_->ClearSelectedIndex(); 298 tiles_container_->ClearSelectedIndex();
299 custom_launcher_page_background_->SetSelected(false);
261 } 300 }
262 301
263 void StartPageView::Layout() { 302 void StartPageView::Layout() {
264 gfx::Rect bounds(GetContentsBounds()); 303 gfx::Rect bounds(GetContentsBounds());
265 bounds.set_height(instant_container_->GetHeightForWidth(bounds.width())); 304 bounds.set_height(instant_container_->GetHeightForWidth(bounds.width()));
266 instant_container_->SetBoundsRect(bounds); 305 instant_container_->SetBoundsRect(bounds);
267 306
268 // Tiles begin where the instant container ends. 307 // Tiles begin where the instant container ends.
269 bounds.set_y(bounds.bottom()); 308 bounds.set_y(bounds.bottom());
270 bounds.set_height(tiles_container_->GetHeightForWidth(bounds.width())); 309 bounds.set_height(tiles_container_->GetHeightForWidth(bounds.width()));
271 tiles_container_->SetBoundsRect(bounds); 310 tiles_container_->SetBoundsRect(bounds);
311
312 bounds = app_list_main_view_->contents_view()->GetCustomPageCollapsedBounds();
313 bounds.Intersect(GetContentsBounds());
314 bounds.ClampToCenteredSize(
315 gfx::Size(kLauncherPageBackgroundWidth, bounds.height()));
316 custom_launcher_page_background_->SetBoundsRect(bounds);
272 } 317 }
273 318
274 bool StartPageView::OnKeyPressed(const ui::KeyEvent& event) { 319 bool StartPageView::OnKeyPressed(const ui::KeyEvent& event) {
320 const int forward_dir = base::i18n::IsRTL() ? -1 : 1;
275 int selected_index = tiles_container_->selected_index(); 321 int selected_index = tiles_container_->selected_index();
276 if (selected_index >= 0 && 322
277 tiles_container_->GetTileItemView(selected_index)->OnKeyPressed(event)) 323 if (custom_launcher_page_background_->selected()) {
324 selected_index = tiles_container_->num_results();
325 switch (event.key_code()) {
326 case ui::VKEY_RETURN:
327 MaybeOpenCustomLauncherPage();
328 return true;
329 default:
330 break;
331 }
332 } else if (selected_index >= 0 &&
333 tiles_container_->GetTileItemView(selected_index)
334 ->OnKeyPressed(event)) {
278 return true; 335 return true;
336 }
279 337
280 const int forward_dir = base::i18n::IsRTL() ? -1 : 1;
281 int dir = 0; 338 int dir = 0;
282 switch (event.key_code()) { 339 switch (event.key_code()) {
283 case ui::VKEY_LEFT: 340 case ui::VKEY_LEFT:
284 dir = -forward_dir; 341 dir = -forward_dir;
285 break; 342 break;
286 case ui::VKEY_RIGHT: 343 case ui::VKEY_RIGHT:
287 dir = forward_dir; 344 // Don't go to the custom launcher page from the All apps tile.
345 if (selected_index != tiles_container_->num_results() - 1)
346 dir = forward_dir;
347 break;
348 case ui::VKEY_UP:
349 // Up selects the first tile if the custom launcher is selected.
350 if (custom_launcher_page_background_->selected()) {
351 selected_index = -1;
352 dir = 1;
353 }
288 break; 354 break;
289 case ui::VKEY_DOWN: 355 case ui::VKEY_DOWN:
290 // Down selects the first tile if nothing is selected. 356 // Down selects the first tile if nothing is selected.
291 if (!tiles_container_->IsValidSelectionIndex(selected_index)) 357 dir = 1;
292 dir = 1; 358 // If something is selected, select the custom launcher page.
359 if (tiles_container_->IsValidSelectionIndex(selected_index))
360 selected_index = tiles_container_->num_results() - 1;
293 break; 361 break;
294 case ui::VKEY_TAB: 362 case ui::VKEY_TAB:
295 dir = event.IsShiftDown() ? -1 : 1; 363 dir = event.IsShiftDown() ? -1 : 1;
296 break; 364 break;
297 default: 365 default:
298 break; 366 break;
299 } 367 }
300 368
301 if (dir == 0) 369 if (dir == 0)
302 return false; 370 return false;
303 371
304 if (!tiles_container_->IsValidSelectionIndex(selected_index)) { 372 if (selected_index == -1) {
373 custom_launcher_page_background_->SetSelected(false);
305 tiles_container_->SetSelectedIndex( 374 tiles_container_->SetSelectedIndex(
306 dir == -1 ? tiles_container_->num_results() - 1 : 0); 375 dir == -1 ? tiles_container_->num_results() - 1 : 0);
307 return true; 376 return true;
308 } 377 }
309 378
310 int selection_index = selected_index + dir; 379 int selection_index = selected_index + dir;
311 if (tiles_container_->IsValidSelectionIndex(selection_index)) { 380 if (tiles_container_->IsValidSelectionIndex(selection_index)) {
381 custom_launcher_page_background_->SetSelected(false);
312 tiles_container_->SetSelectedIndex(selection_index); 382 tiles_container_->SetSelectedIndex(selection_index);
313 return true; 383 return true;
314 } 384 }
315 385
386 if (selection_index == tiles_container_->num_results() &&
387 app_list_main_view_->ShouldShowCustomLauncherPage()) {
388 custom_launcher_page_background_->SetSelected(true);
389 tiles_container_->ClearSelectedIndex();
390 return true;
391 }
392
316 if (event.key_code() == ui::VKEY_TAB && selection_index == -1) 393 if (event.key_code() == ui::VKEY_TAB && selection_index == -1)
317 tiles_container_->ClearSelectedIndex(); // ContentsView will handle focus. 394 tiles_container_->ClearSelectedIndex(); // ContentsView will handle focus.
318 395
319 return false; 396 return false;
320 } 397 }
321 398
322 bool StartPageView::OnMousePressed(const ui::MouseEvent& event) { 399 bool StartPageView::OnMousePressed(const ui::MouseEvent& event) {
323 ContentsView* contents_view = app_list_main_view_->contents_view(); 400 ContentsView* contents_view = app_list_main_view_->contents_view();
324 if (!contents_view->GetCustomPageCollapsedBounds().Contains(event.location())) 401 if (!contents_view->GetCustomPageCollapsedBounds().Contains(event.location()))
325 return false; 402 return false;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 435
359 gfx::Rect StartPageView::GetSearchBoxBounds() const { 436 gfx::Rect StartPageView::GetSearchBoxBounds() const {
360 return search_box_spacer_view_->bounds(); 437 return search_box_spacer_view_->bounds();
361 } 438 }
362 439
363 TileItemView* StartPageView::GetTileItemView(size_t index) { 440 TileItemView* StartPageView::GetTileItemView(size_t index) {
364 return tiles_container_->GetTileItemView(index); 441 return tiles_container_->GetTileItemView(index);
365 } 442 }
366 443
367 } // namespace app_list 444 } // namespace app_list
OLDNEW
« ui/app_list/app_list_model.h ('K') | « 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