OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 #import "ui/app_list/cocoa/apps_grid_controller.h" | 5 #import "ui/app_list/cocoa/apps_grid_controller.h" |
6 | 6 |
| 7 #include "base/command_line.h" |
7 #include "base/mac/foundation_util.h" | 8 #include "base/mac/foundation_util.h" |
8 #include "base/macros.h" | 9 #include "base/macros.h" |
9 #include "ui/app_list/app_list_item.h" | 10 #include "ui/app_list/app_list_item.h" |
10 #include "ui/app_list/app_list_model.h" | 11 #include "ui/app_list/app_list_model.h" |
11 #include "ui/app_list/app_list_model_observer.h" | 12 #include "ui/app_list/app_list_model_observer.h" |
12 #include "ui/app_list/app_list_view_delegate.h" | 13 #include "ui/app_list/app_list_view_delegate.h" |
13 #import "ui/app_list/cocoa/apps_collection_view_drag_manager.h" | 14 #import "ui/app_list/cocoa/apps_collection_view_drag_manager.h" |
14 #import "ui/app_list/cocoa/apps_grid_view_item.h" | 15 #import "ui/app_list/cocoa/apps_grid_view_item.h" |
15 #import "ui/app_list/cocoa/apps_pagination_model_observer.h" | 16 #import "ui/app_list/cocoa/apps_pagination_model_observer.h" |
16 #include "ui/base/models/list_model_observer.h" | 17 #include "ui/base/models/list_model_observer.h" |
17 | 18 |
18 namespace { | 19 namespace { |
19 | 20 |
20 // OSX app list has hardcoded rows and columns for now. | 21 // OSX app list has hardcoded columns for now. |
21 const int kFixedRows = 4; | |
22 const int kFixedColumns = 4; | 22 const int kFixedColumns = 4; |
23 const int kItemsPerPage = kFixedRows * kFixedColumns; | |
24 | 23 |
25 // Padding space in pixels for fixed layout. | 24 // Padding space in pixels for fixed layout. |
26 const CGFloat kGridTopPadding = 1; | 25 const CGFloat kGridTopPadding = 1; |
27 const CGFloat kLeftRightPadding = 21; | 26 const CGFloat kLeftRightPadding = 21; |
28 const CGFloat kScrollerPadding = 16; | 27 const CGFloat kScrollerPadding = 16; |
29 | 28 |
30 // Preferred tile size when showing in fixed layout. These should be even | 29 // Preferred tile size when showing in fixed layout. These should be even |
31 // numbers to ensure that if they are grown 50% they remain integers. | 30 // numbers to ensure that if they are grown 50% they remain integers. |
32 const CGFloat kPreferredTileWidth = 88; | 31 const CGFloat kPreferredTileWidth = 88; |
33 const CGFloat kPreferredTileHeight = 98; | 32 const CGFloat kPreferredTileHeight = 98; |
34 | 33 |
35 const CGFloat kViewWidth = | 34 const CGFloat kViewWidth = |
36 kFixedColumns * kPreferredTileWidth + 2 * kLeftRightPadding; | 35 kFixedColumns * kPreferredTileWidth + 2 * kLeftRightPadding; |
37 const CGFloat kViewHeight = kFixedRows * kPreferredTileHeight; | |
38 | 36 |
39 const NSTimeInterval kScrollWhileDraggingDelay = 1.0; | 37 const NSTimeInterval kScrollWhileDraggingDelay = 1.0; |
40 NSTimeInterval g_scroll_duration = 0.18; | 38 NSTimeInterval g_scroll_duration = 0.18; |
41 | 39 |
| 40 const char kTestType[] = "test-type"; |
| 41 |
| 42 int DetermineFixedRowCount() { |
| 43 // This needs to be called before a delegate exists, since it is needed to |
| 44 // determine the height of the view. |
| 45 return [AppsGridController hasFewerRows] ? 3 : 4; |
| 46 } |
| 47 |
| 48 int RowCount() { |
| 49 static const int row_count = DetermineFixedRowCount(); |
| 50 return row_count; |
| 51 } |
| 52 |
| 53 int ItemsPerPage() { |
| 54 return RowCount() * kFixedColumns; |
| 55 } |
| 56 |
| 57 CGFloat ViewHeight() { |
| 58 return RowCount() * kPreferredTileHeight; |
| 59 } |
| 60 |
42 } // namespace | 61 } // namespace |
43 | 62 |
44 @interface AppsGridController () | 63 @interface AppsGridController () |
45 | 64 |
46 - (void)scrollToPageWithTimer:(size_t)targetPage; | 65 - (void)scrollToPageWithTimer:(size_t)targetPage; |
47 - (void)onTimer:(NSTimer*)theTimer; | 66 - (void)onTimer:(NSTimer*)theTimer; |
48 | 67 |
49 // Cancel a currently running scroll animation. | 68 // Cancel a currently running scroll animation. |
50 - (void)cancelScrollAnimation; | 69 - (void)cancelScrollAnimation; |
51 | 70 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 [parent_ listItemMovedFromIndex:from_index | 131 [parent_ listItemMovedFromIndex:from_index |
113 toModelIndex:to_index]; | 132 toModelIndex:to_index]; |
114 } | 133 } |
115 void OnAppListItemHighlight(size_t index, bool highlight) override { | 134 void OnAppListItemHighlight(size_t index, bool highlight) override { |
116 // NSCollectionView (or -[AppsGridController scrollToPage]) ensures only one | 135 // NSCollectionView (or -[AppsGridController scrollToPage]) ensures only one |
117 // item is highlighted, so clearing a highlight isn't necessary. | 136 // item is highlighted, so clearing a highlight isn't necessary. |
118 if (!highlight) | 137 if (!highlight) |
119 return; | 138 return; |
120 | 139 |
121 [parent_ selectItemAtIndex:index]; | 140 [parent_ selectItemAtIndex:index]; |
122 [parent_ scrollToPage:index / kItemsPerPage]; | 141 [parent_ scrollToPage:index / ItemsPerPage()]; |
123 } | 142 } |
124 | 143 |
125 AppsGridController* parent_; // Weak, owns us. | 144 AppsGridController* parent_; // Weak, owns us. |
126 | 145 |
127 DISALLOW_COPY_AND_ASSIGN(AppsGridDelegateBridge); | 146 DISALLOW_COPY_AND_ASSIGN(AppsGridDelegateBridge); |
128 }; | 147 }; |
129 | 148 |
130 } // namespace app_list | 149 } // namespace app_list |
131 | 150 |
132 @interface PageContainerView : NSView; | 151 @interface PageContainerView : NSView; |
(...skipping 12 matching lines...) Expand all Loading... |
145 @implementation AppsGridController | 164 @implementation AppsGridController |
146 | 165 |
147 + (void)setScrollAnimationDuration:(NSTimeInterval)duration { | 166 + (void)setScrollAnimationDuration:(NSTimeInterval)duration { |
148 g_scroll_duration = duration; | 167 g_scroll_duration = duration; |
149 } | 168 } |
150 | 169 |
151 + (CGFloat)scrollerPadding { | 170 + (CGFloat)scrollerPadding { |
152 return kScrollerPadding; | 171 return kScrollerPadding; |
153 } | 172 } |
154 | 173 |
| 174 + (BOOL)hasFewerRows { |
| 175 return !base::CommandLine::ForCurrentProcess()->HasSwitch(kTestType); |
| 176 } |
| 177 |
155 @synthesize paginationObserver = paginationObserver_; | 178 @synthesize paginationObserver = paginationObserver_; |
156 | 179 |
157 - (id)init { | 180 - (id)init { |
158 if ((self = [super init])) { | 181 if ((self = [super init])) { |
159 bridge_.reset(new app_list::AppsGridDelegateBridge(self)); | 182 bridge_.reset(new app_list::AppsGridDelegateBridge(self)); |
160 NSSize cellSize = NSMakeSize(kPreferredTileWidth, kPreferredTileHeight); | 183 NSSize cellSize = NSMakeSize(kPreferredTileWidth, kPreferredTileHeight); |
161 dragManager_.reset( | 184 dragManager_.reset([[AppsCollectionViewDragManager alloc] |
162 [[AppsCollectionViewDragManager alloc] initWithCellSize:cellSize | 185 initWithCellSize:cellSize |
163 rows:kFixedRows | 186 rows:RowCount() |
164 columns:kFixedColumns | 187 columns:kFixedColumns |
165 gridController:self]); | 188 gridController:self]); |
166 pages_.reset([[NSMutableArray alloc] init]); | 189 pages_.reset([[NSMutableArray alloc] init]); |
167 items_.reset([[NSMutableArray alloc] init]); | 190 items_.reset([[NSMutableArray alloc] init]); |
168 [self loadAndSetView]; | 191 [self loadAndSetView]; |
169 [self updatePages:0]; | 192 [self updatePages:0]; |
170 } | 193 } |
171 return self; | 194 return self; |
172 } | 195 } |
173 | 196 |
174 - (void)dealloc { | 197 - (void)dealloc { |
175 [[NSNotificationCenter defaultCenter] removeObserver:self]; | 198 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 } else { | 373 } else { |
351 [self scrollToPage:[self nearestPageIndex]]; | 374 [self scrollToPage:[self nearestPageIndex]]; |
352 } | 375 } |
353 } | 376 } |
354 | 377 |
355 - (void)loadAndSetView { | 378 - (void)loadAndSetView { |
356 base::scoped_nsobject<PageContainerView> pagesContainer( | 379 base::scoped_nsobject<PageContainerView> pagesContainer( |
357 [[PageContainerView alloc] initWithFrame:NSZeroRect]); | 380 [[PageContainerView alloc] initWithFrame:NSZeroRect]); |
358 | 381 |
359 NSRect scrollFrame = NSMakeRect(0, kGridTopPadding, kViewWidth, | 382 NSRect scrollFrame = NSMakeRect(0, kGridTopPadding, kViewWidth, |
360 kViewHeight + kScrollerPadding); | 383 ViewHeight() + kScrollerPadding); |
361 base::scoped_nsobject<ScrollViewWithNoScrollbars> scrollView( | 384 base::scoped_nsobject<ScrollViewWithNoScrollbars> scrollView( |
362 [[ScrollViewWithNoScrollbars alloc] initWithFrame:scrollFrame]); | 385 [[ScrollViewWithNoScrollbars alloc] initWithFrame:scrollFrame]); |
363 [scrollView setBorderType:NSNoBorder]; | 386 [scrollView setBorderType:NSNoBorder]; |
364 [scrollView setLineScroll:kViewWidth]; | 387 [scrollView setLineScroll:kViewWidth]; |
365 [scrollView setPageScroll:kViewWidth]; | 388 [scrollView setPageScroll:kViewWidth]; |
366 [scrollView setDelegate:self]; | 389 [scrollView setDelegate:self]; |
367 [scrollView setDocumentView:pagesContainer]; | 390 [scrollView setDocumentView:pagesContainer]; |
368 [scrollView setDrawsBackground:NO]; | 391 [scrollView setDrawsBackground:NO]; |
369 | 392 |
370 [[NSNotificationCenter defaultCenter] | 393 [[NSNotificationCenter defaultCenter] |
(...skipping 25 matching lines...) Expand all Loading... |
396 } | 419 } |
397 } | 420 } |
398 | 421 |
399 - (AppsGridViewItem*)itemAtPageIndex:(size_t)pageIndex | 422 - (AppsGridViewItem*)itemAtPageIndex:(size_t)pageIndex |
400 indexInPage:(size_t)indexInPage { | 423 indexInPage:(size_t)indexInPage { |
401 return base::mac::ObjCCastStrict<AppsGridViewItem>( | 424 return base::mac::ObjCCastStrict<AppsGridViewItem>( |
402 [[self collectionViewAtPageIndex:pageIndex] itemAtIndex:indexInPage]); | 425 [[self collectionViewAtPageIndex:pageIndex] itemAtIndex:indexInPage]); |
403 } | 426 } |
404 | 427 |
405 - (AppsGridViewItem*)itemAtIndex:(size_t)itemIndex { | 428 - (AppsGridViewItem*)itemAtIndex:(size_t)itemIndex { |
406 const size_t pageIndex = itemIndex / kItemsPerPage; | 429 const size_t pageIndex = itemIndex / ItemsPerPage(); |
407 return [self itemAtPageIndex:pageIndex | 430 return [self itemAtPageIndex:pageIndex |
408 indexInPage:itemIndex - pageIndex * kItemsPerPage]; | 431 indexInPage:itemIndex - pageIndex * ItemsPerPage()]; |
409 } | 432 } |
410 | 433 |
411 - (NSUInteger)selectedItemIndex { | 434 - (NSUInteger)selectedItemIndex { |
412 NSCollectionView* page = [self collectionViewAtPageIndex:visiblePage_]; | 435 NSCollectionView* page = [self collectionViewAtPageIndex:visiblePage_]; |
413 NSUInteger indexOnPage = [[page selectionIndexes] firstIndex]; | 436 NSUInteger indexOnPage = [[page selectionIndexes] firstIndex]; |
414 if (indexOnPage == NSNotFound) | 437 if (indexOnPage == NSNotFound) |
415 return NSNotFound; | 438 return NSNotFound; |
416 | 439 |
417 return indexOnPage + visiblePage_ * kItemsPerPage; | 440 return indexOnPage + visiblePage_ * ItemsPerPage(); |
418 } | 441 } |
419 | 442 |
420 - (NSButton*)selectedButton { | 443 - (NSButton*)selectedButton { |
421 NSUInteger index = [self selectedItemIndex]; | 444 NSUInteger index = [self selectedItemIndex]; |
422 if (index == NSNotFound) | 445 if (index == NSNotFound) |
423 return nil; | 446 return nil; |
424 | 447 |
425 return [[self itemAtIndex:index] button]; | 448 return [[self itemAtIndex:index] button]; |
426 } | 449 } |
427 | 450 |
428 - (NSScrollView*)gridScrollView { | 451 - (NSScrollView*)gridScrollView { |
429 return base::mac::ObjCCastStrict<NSScrollView>([self view]); | 452 return base::mac::ObjCCastStrict<NSScrollView>([self view]); |
430 } | 453 } |
431 | 454 |
432 - (NSView*)pagesContainerView { | 455 - (NSView*)pagesContainerView { |
433 return [[self gridScrollView] documentView]; | 456 return [[self gridScrollView] documentView]; |
434 } | 457 } |
435 | 458 |
436 - (void)updatePages:(size_t)startItemIndex { | 459 - (void)updatePages:(size_t)startItemIndex { |
437 // Note there is always at least one page. | 460 // Note there is always at least one page. |
438 size_t targetPages = 1; | 461 size_t targetPages = 1; |
439 if ([items_ count] != 0) | 462 if ([items_ count] != 0) |
440 targetPages = ([items_ count] - 1) / kItemsPerPage + 1; | 463 targetPages = ([items_ count] - 1) / ItemsPerPage() + 1; |
441 | 464 |
442 const size_t currentPages = [self pageCount]; | 465 const size_t currentPages = [self pageCount]; |
443 // First see if the number of pages have changed. | 466 // First see if the number of pages have changed. |
444 if (targetPages != currentPages) { | 467 if (targetPages != currentPages) { |
445 if (targetPages < currentPages) { | 468 if (targetPages < currentPages) { |
446 // Pages need to be removed. | 469 // Pages need to be removed. |
447 [pages_ removeObjectsInRange:NSMakeRange(targetPages, | 470 [pages_ removeObjectsInRange:NSMakeRange(targetPages, |
448 currentPages - targetPages)]; | 471 currentPages - targetPages)]; |
449 } else { | 472 } else { |
450 // Pages need to be added. | 473 // Pages need to be added. |
451 for (size_t i = currentPages; i < targetPages; ++i) { | 474 for (size_t i = currentPages; i < targetPages; ++i) { |
452 NSRect pageFrame = NSMakeRect( | 475 NSRect pageFrame = NSMakeRect(kLeftRightPadding + kViewWidth * i, 0, |
453 kLeftRightPadding + kViewWidth * i, 0, | 476 kViewWidth, ViewHeight()); |
454 kViewWidth, kViewHeight); | |
455 [pages_ addObject:[dragManager_ makePageWithFrame:pageFrame]]; | 477 [pages_ addObject:[dragManager_ makePageWithFrame:pageFrame]]; |
456 } | 478 } |
457 } | 479 } |
458 | 480 |
459 [[self pagesContainerView] setSubviews:pages_]; | 481 [[self pagesContainerView] setSubviews:pages_]; |
460 NSSize pagesSize = NSMakeSize(kViewWidth * targetPages, kViewHeight); | 482 NSSize pagesSize = NSMakeSize(kViewWidth * targetPages, ViewHeight()); |
461 [[self pagesContainerView] setFrameSize:pagesSize]; | 483 [[self pagesContainerView] setFrameSize:pagesSize]; |
462 [paginationObserver_ totalPagesChanged]; | 484 [paginationObserver_ totalPagesChanged]; |
463 } | 485 } |
464 | 486 |
465 const size_t startPage = startItemIndex / kItemsPerPage; | 487 const size_t startPage = startItemIndex / ItemsPerPage(); |
466 // All pages on or after |startPage| may need items added or removed. | 488 // All pages on or after |startPage| may need items added or removed. |
467 for (size_t pageIndex = startPage; pageIndex < targetPages; ++pageIndex) { | 489 for (size_t pageIndex = startPage; pageIndex < targetPages; ++pageIndex) { |
468 [self updatePageContent:pageIndex | 490 [self updatePageContent:pageIndex |
469 resetModel:YES]; | 491 resetModel:YES]; |
470 } | 492 } |
471 } | 493 } |
472 | 494 |
473 - (void)updatePageContent:(size_t)pageIndex | 495 - (void)updatePageContent:(size_t)pageIndex |
474 resetModel:(BOOL)resetModel { | 496 resetModel:(BOOL)resetModel { |
475 NSCollectionView* pageView = [self collectionViewAtPageIndex:pageIndex]; | 497 NSCollectionView* pageView = [self collectionViewAtPageIndex:pageIndex]; |
476 if (resetModel) { | 498 if (resetModel) { |
477 // Clear the models first, otherwise removed items could be autoreleased at | 499 // Clear the models first, otherwise removed items could be autoreleased at |
478 // an unknown point in the future, when the model owner may have gone away. | 500 // an unknown point in the future, when the model owner may have gone away. |
479 for (size_t i = 0; i < [[pageView content] count]; ++i) { | 501 for (size_t i = 0; i < [[pageView content] count]; ++i) { |
480 AppsGridViewItem* gridItem = base::mac::ObjCCastStrict<AppsGridViewItem>( | 502 AppsGridViewItem* gridItem = base::mac::ObjCCastStrict<AppsGridViewItem>( |
481 [pageView itemAtIndex:i]); | 503 [pageView itemAtIndex:i]); |
482 [gridItem setModel:NULL]; | 504 [gridItem setModel:NULL]; |
483 } | 505 } |
484 } | 506 } |
485 | 507 |
486 NSRange inPageRange = NSIntersectionRange( | 508 NSRange inPageRange = NSIntersectionRange( |
487 NSMakeRange(pageIndex * kItemsPerPage, kItemsPerPage), | 509 NSMakeRange(pageIndex * ItemsPerPage(), ItemsPerPage()), |
488 NSMakeRange(0, [items_ count])); | 510 NSMakeRange(0, [items_ count])); |
489 NSArray* pageContent = [items_ subarrayWithRange:inPageRange]; | 511 NSArray* pageContent = [items_ subarrayWithRange:inPageRange]; |
490 [pageView setContent:pageContent]; | 512 [pageView setContent:pageContent]; |
491 if (!resetModel) | 513 if (!resetModel) |
492 return; | 514 return; |
493 | 515 |
494 for (size_t i = 0; i < [pageContent count]; ++i) { | 516 for (size_t i = 0; i < [pageContent count]; ++i) { |
495 AppsGridViewItem* gridItem = base::mac::ObjCCastStrict<AppsGridViewItem>( | 517 AppsGridViewItem* gridItem = base::mac::ObjCCastStrict<AppsGridViewItem>( |
496 [pageView itemAtIndex:i]); | 518 [pageView itemAtIndex:i]); |
497 [gridItem setModel:static_cast<app_list::AppListItem*>( | 519 [gridItem setModel:static_cast<app_list::AppListItem*>( |
498 [[pageContent objectAtIndex:i] pointerValue])]; | 520 [[pageContent objectAtIndex:i] pointerValue])]; |
499 } | 521 } |
500 } | 522 } |
501 | 523 |
502 - (void)moveItemInView:(size_t)fromIndex | 524 - (void)moveItemInView:(size_t)fromIndex |
503 toItemIndex:(size_t)toIndex { | 525 toItemIndex:(size_t)toIndex { |
504 base::scoped_nsobject<NSValue> item( | 526 base::scoped_nsobject<NSValue> item( |
505 [[items_ objectAtIndex:fromIndex] retain]); | 527 [[items_ objectAtIndex:fromIndex] retain]); |
506 [items_ removeObjectAtIndex:fromIndex]; | 528 [items_ removeObjectAtIndex:fromIndex]; |
507 [items_ insertObject:item | 529 [items_ insertObject:item |
508 atIndex:toIndex]; | 530 atIndex:toIndex]; |
509 | 531 |
510 size_t fromPageIndex = fromIndex / kItemsPerPage; | 532 size_t fromPageIndex = fromIndex / ItemsPerPage(); |
511 size_t toPageIndex = toIndex / kItemsPerPage; | 533 size_t toPageIndex = toIndex / ItemsPerPage(); |
512 if (fromPageIndex == toPageIndex) { | 534 if (fromPageIndex == toPageIndex) { |
513 [self updatePageContent:fromPageIndex | 535 [self updatePageContent:fromPageIndex |
514 resetModel:NO]; // Just reorder items. | 536 resetModel:NO]; // Just reorder items. |
515 return; | 537 return; |
516 } | 538 } |
517 | 539 |
518 if (fromPageIndex > toPageIndex) | 540 if (fromPageIndex > toPageIndex) |
519 std::swap(fromPageIndex, toPageIndex); | 541 std::swap(fromPageIndex, toPageIndex); |
520 | 542 |
521 for (size_t i = fromPageIndex; i <= toPageIndex; ++i) { | 543 for (size_t i = fromPageIndex; i <= toPageIndex; ++i) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
596 } | 618 } |
597 | 619 |
598 - (BOOL)moveSelectionByDelta:(int)indexDelta { | 620 - (BOOL)moveSelectionByDelta:(int)indexDelta { |
599 if (indexDelta == 0) | 621 if (indexDelta == 0) |
600 return NO; | 622 return NO; |
601 | 623 |
602 NSUInteger oldIndex = [self selectedItemIndex]; | 624 NSUInteger oldIndex = [self selectedItemIndex]; |
603 | 625 |
604 // If nothing is currently selected, select the first item on the page. | 626 // If nothing is currently selected, select the first item on the page. |
605 if (oldIndex == NSNotFound) { | 627 if (oldIndex == NSNotFound) { |
606 [self selectItemAtIndex:visiblePage_ * kItemsPerPage]; | 628 [self selectItemAtIndex:visiblePage_ * ItemsPerPage()]; |
607 return YES; | 629 return YES; |
608 } | 630 } |
609 | 631 |
610 // Can't select a negative index. | 632 // Can't select a negative index. |
611 if (indexDelta < 0 && static_cast<NSUInteger>(-indexDelta) > oldIndex) | 633 if (indexDelta < 0 && static_cast<NSUInteger>(-indexDelta) > oldIndex) |
612 return NO; | 634 return NO; |
613 | 635 |
614 // Can't select an index greater or equal to the number of items. | 636 // Can't select an index greater or equal to the number of items. |
615 if (oldIndex + indexDelta >= [items_ count]) { | 637 if (oldIndex + indexDelta >= [items_ count]) { |
616 if (visiblePage_ == [pages_ count] - 1) | 638 if (visiblePage_ == [pages_ count] - 1) |
617 return NO; | 639 return NO; |
618 | 640 |
619 // If we're not on the last page, then select the last item. | 641 // If we're not on the last page, then select the last item. |
620 [self selectItemAtIndex:[items_ count] - 1]; | 642 [self selectItemAtIndex:[items_ count] - 1]; |
621 return YES; | 643 return YES; |
622 } | 644 } |
623 | 645 |
624 [self selectItemAtIndex:oldIndex + indexDelta]; | 646 [self selectItemAtIndex:oldIndex + indexDelta]; |
625 return YES; | 647 return YES; |
626 } | 648 } |
627 | 649 |
628 - (void)selectItemAtIndex:(NSUInteger)index { | 650 - (void)selectItemAtIndex:(NSUInteger)index { |
629 if (index >= [items_ count]) | 651 if (index >= [items_ count]) |
630 return; | 652 return; |
631 | 653 |
632 if (index / kItemsPerPage != visiblePage_) | 654 if (index / ItemsPerPage() != visiblePage_) |
633 [self scrollToPage:index / kItemsPerPage]; | 655 [self scrollToPage:index / ItemsPerPage()]; |
634 | 656 |
635 [[self itemAtIndex:index] setSelected:YES]; | 657 [[self itemAtIndex:index] setSelected:YES]; |
636 } | 658 } |
637 | 659 |
638 - (BOOL)handleCommandBySelector:(SEL)command { | 660 - (BOOL)handleCommandBySelector:(SEL)command { |
639 if (command == @selector(insertNewline:) || | 661 if (command == @selector(insertNewline:) || |
640 command == @selector(insertLineBreak:)) { | 662 command == @selector(insertLineBreak:)) { |
641 [self activateSelection]; | 663 [self activateSelection]; |
642 return YES; | 664 return YES; |
643 } | 665 } |
644 | 666 |
645 NSUInteger oldIndex = [self selectedItemIndex]; | 667 NSUInteger oldIndex = [self selectedItemIndex]; |
646 // If nothing is currently selected, select the first item on the page. | 668 // If nothing is currently selected, select the first item on the page. |
647 if (oldIndex == NSNotFound) { | 669 if (oldIndex == NSNotFound) { |
648 [self selectItemAtIndex:visiblePage_ * kItemsPerPage]; | 670 [self selectItemAtIndex:visiblePage_ * ItemsPerPage()]; |
649 return YES; | 671 return YES; |
650 } | 672 } |
651 | 673 |
652 if (command == @selector(moveLeft:)) { | 674 if (command == @selector(moveLeft:)) { |
653 return oldIndex % kFixedColumns == 0 ? | 675 return oldIndex % kFixedColumns == 0 |
654 [self moveSelectionByDelta:-kItemsPerPage + kFixedColumns - 1] : | 676 ? [self moveSelectionByDelta:-ItemsPerPage() + kFixedColumns - 1] |
655 [self moveSelectionByDelta:-1]; | 677 : [self moveSelectionByDelta:-1]; |
656 } | 678 } |
657 | 679 |
658 if (command == @selector(moveRight:)) { | 680 if (command == @selector(moveRight:)) { |
659 return oldIndex % kFixedColumns == kFixedColumns - 1 ? | 681 return oldIndex % kFixedColumns == kFixedColumns - 1 |
660 [self moveSelectionByDelta:+kItemsPerPage - kFixedColumns + 1] : | 682 ? [self moveSelectionByDelta:+ItemsPerPage() - kFixedColumns + 1] |
661 [self moveSelectionByDelta:1]; | 683 : [self moveSelectionByDelta:1]; |
662 } | 684 } |
663 | 685 |
664 if (command == @selector(moveUp:)) { | 686 if (command == @selector(moveUp:)) { |
665 return oldIndex / kFixedColumns % kFixedRows == 0 ? | 687 return oldIndex / kFixedColumns % RowCount() == 0 |
666 NO : [self moveSelectionByDelta:-kFixedColumns]; | 688 ? NO |
| 689 : [self moveSelectionByDelta:-kFixedColumns]; |
667 } | 690 } |
668 | 691 |
669 if (command == @selector(moveDown:)) { | 692 if (command == @selector(moveDown:)) { |
670 return oldIndex / kFixedColumns % kFixedRows == kFixedRows - 1 ? | 693 return oldIndex / kFixedColumns % RowCount() == RowCount() - 1 |
671 NO : [self moveSelectionByDelta:kFixedColumns]; | 694 ? NO |
| 695 : [self moveSelectionByDelta:kFixedColumns]; |
672 } | 696 } |
673 | 697 |
674 if (command == @selector(pageUp:) || | 698 if (command == @selector(pageUp:) || |
675 command == @selector(scrollPageUp:)) | 699 command == @selector(scrollPageUp:)) |
676 return [self moveSelectionByDelta:-kItemsPerPage]; | 700 return [self moveSelectionByDelta:-ItemsPerPage()]; |
677 | 701 |
678 if (command == @selector(pageDown:) || | 702 if (command == @selector(pageDown:) || |
679 command == @selector(scrollPageDown:)) | 703 command == @selector(scrollPageDown:)) |
680 return [self moveSelectionByDelta:kItemsPerPage]; | 704 return [self moveSelectionByDelta:ItemsPerPage()]; |
681 | 705 |
682 return NO; | 706 return NO; |
683 } | 707 } |
684 | 708 |
685 @end | 709 @end |
OLD | NEW |