| 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 |