OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "chrome/browser/ui/cocoa/chooser_content_view_cocoa.h" | 5 #import "chrome/browser/ui/cocoa/chooser_content_view_cocoa.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "base/strings/sys_string_conversions.h" | 10 #include "base/strings/sys_string_conversions.h" |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 [table_view_ setHidden:NO]; | 308 [table_view_ setHidden:NO]; |
309 [spinner_ setHidden:YES]; | 309 [spinner_ setHidden:YES]; |
310 } | 310 } |
311 | 311 |
312 void ChooserContentViewController::OnOptionRemoved(size_t index) { | 312 void ChooserContentViewController::OnOptionRemoved(size_t index) { |
313 // |table_view_| will automatically select the removed item's next item. | 313 // |table_view_| will automatically select the removed item's next item. |
314 // So here it tracks if the removed item is the item that was currently | 314 // So here it tracks if the removed item is the item that was currently |
315 // selected, if so, deselect it. Also if the removed item is before the | 315 // selected, if so, deselect it. Also if the removed item is before the |
316 // currently selected item, the currently selected item's index needs to | 316 // currently selected item, the currently selected item's index needs to |
317 // be adjusted by one. | 317 // be adjusted by one. |
318 NSInteger idx = static_cast<NSInteger>(index); | 318 NSIndexSet* selected_rows = [table_view_ selectedRowIndexes]; |
319 NSInteger selected_row = [table_view_ selectedRow]; | 319 NSMutableIndexSet* updated_selected_rows = [NSMutableIndexSet indexSet]; |
320 if (selected_row == idx) { | 320 NSUInteger row = [selected_rows firstIndex]; |
321 [table_view_ deselectRow:idx]; | 321 while (row != NSNotFound) { |
322 } else if (selected_row > idx) { | 322 if (row < index) |
323 [table_view_ | 323 [updated_selected_rows addIndex:row]; |
324 selectRowIndexes:[NSIndexSet indexSetWithIndex:selected_row - 1] | 324 else if (row > index) |
325 byExtendingSelection:NO]; | 325 [updated_selected_rows addIndex:row - 1]; |
| 326 row = [selected_rows indexGreaterThanIndex:row]; |
326 } | 327 } |
327 | 328 |
| 329 [table_view_ selectRowIndexes:updated_selected_rows byExtendingSelection:NO]; |
| 330 |
328 UpdateTableView(); | 331 UpdateTableView(); |
329 } | 332 } |
330 | 333 |
331 void ChooserContentViewController::OnOptionUpdated(size_t index) { | 334 void ChooserContentViewController::OnOptionUpdated(size_t index) { |
332 UpdateTableView(); | 335 UpdateTableView(); |
333 } | 336 } |
334 | 337 |
335 void ChooserContentViewController::OnAdapterEnabledChanged(bool enabled) { | 338 void ChooserContentViewController::OnAdapterEnabledChanged(bool enabled) { |
336 // No row is selected since the adapter status has changed. | 339 // No row is selected since the adapter status has changed. |
337 // This will also disable the OK button if it was enabled because | 340 // This will also disable the OK button if it was enabled because |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 // When complete, show |word_connector_| and |rescan_button_| and hide | 375 // When complete, show |word_connector_| and |rescan_button_| and hide |
373 // |scanning_message_|. | 376 // |scanning_message_|. |
374 [scanning_message_ setHidden:refreshing ? NO : YES]; | 377 [scanning_message_ setHidden:refreshing ? NO : YES]; |
375 [word_connector_ setHidden:refreshing ? YES : NO]; | 378 [word_connector_ setHidden:refreshing ? YES : NO]; |
376 [rescan_button_ setHidden:refreshing ? YES : NO]; | 379 [rescan_button_ setHidden:refreshing ? YES : NO]; |
377 } | 380 } |
378 | 381 |
379 void ChooserContentViewController::UpdateTableView() { | 382 void ChooserContentViewController::UpdateTableView() { |
380 [table_view_ setEnabled:chooser_controller_->NumOptions() > 0]; | 383 [table_view_ setEnabled:chooser_controller_->NumOptions() > 0]; |
381 // For NSView-based table views, calling reloadData will deselect the | 384 // For NSView-based table views, calling reloadData will deselect the |
382 // currently selected row, so |selected_row| stores the currently selected | 385 // currently selected row, so |selected_rows| stores the currently selected |
383 // row in order to select it again. | 386 // rows in order to select them again. |
384 NSInteger selected_row = [table_view_ selectedRow]; | 387 NSIndexSet* selected_rows = [table_view_ selectedRowIndexes]; |
385 [table_view_ reloadData]; | 388 [table_view_ reloadData]; |
386 if (selected_row != -1) { | 389 [table_view_ selectRowIndexes:selected_rows byExtendingSelection:NO]; |
387 [table_view_ selectRowIndexes:[NSIndexSet indexSetWithIndex:selected_row] | |
388 byExtendingSelection:NO]; | |
389 } | |
390 } | 390 } |
391 | 391 |
392 @implementation ChooserContentViewCocoa | 392 @implementation ChooserContentViewCocoa |
393 | 393 |
394 // TODO(juncai): restructure this function to be some smaller methods to | 394 // TODO(juncai): restructure this function to be some smaller methods to |
395 // create the pieces for the view. By doing so, the methods that calculate | 395 // create the pieces for the view. By doing so, the methods that calculate |
396 // the frame and origins can be moved into those methods, rather than as | 396 // the frame and origins can be moved into those methods, rather than as |
397 // helper functions. | 397 // helper functions. |
398 - (instancetype)initWithChooserTitle:(NSString*)chooserTitle | 398 - (instancetype)initWithChooserTitle:(NSString*)chooserTitle |
399 chooserController: | 399 chooserController: |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 [scrollView_ setDrawsBackground:NO]; | 493 [scrollView_ setDrawsBackground:NO]; |
494 | 494 |
495 // TableView. | 495 // TableView. |
496 tableView_.reset([[NSTableView alloc] initWithFrame:NSZeroRect]); | 496 tableView_.reset([[NSTableView alloc] initWithFrame:NSZeroRect]); |
497 tableColumn_.reset([[NSTableColumn alloc] initWithIdentifier:@""]); | 497 tableColumn_.reset([[NSTableColumn alloc] initWithIdentifier:@""]); |
498 [tableColumn_ setWidth:(scrollViewWidth - kMarginX)]; | 498 [tableColumn_ setWidth:(scrollViewWidth - kMarginX)]; |
499 [tableView_ addTableColumn:tableColumn_]; | 499 [tableView_ addTableColumn:tableColumn_]; |
500 // Make the column title invisible. | 500 // Make the column title invisible. |
501 [tableView_ setHeaderView:nil]; | 501 [tableView_ setHeaderView:nil]; |
502 [tableView_ setFocusRingType:NSFocusRingTypeNone]; | 502 [tableView_ setFocusRingType:NSFocusRingTypeNone]; |
| 503 [tableView_ |
| 504 setAllowsMultipleSelection:chooserController_->AllowMultipleSelection() |
| 505 ? YES |
| 506 : NO]; |
503 | 507 |
504 // Spinner. | 508 // Spinner. |
505 // Set the spinner in the center of the scroll view. | 509 // Set the spinner in the center of the scroll view. |
506 CGFloat spinnerOriginX = | 510 CGFloat spinnerOriginX = |
507 scrollViewOriginX + (scrollViewWidth - kSpinnerSize) / 2; | 511 scrollViewOriginX + (scrollViewWidth - kSpinnerSize) / 2; |
508 CGFloat spinnerOriginY = | 512 CGFloat spinnerOriginY = |
509 scrollViewOriginY + (scrollViewHeight - kSpinnerSize) / 2; | 513 scrollViewOriginY + (scrollViewHeight - kSpinnerSize) / 2; |
510 spinner_.reset([[SpinnerView alloc] | 514 spinner_.reset([[SpinnerView alloc] |
511 initWithFrame:NSMakeRect(spinnerOriginX, spinnerOriginY, kSpinnerSize, | 515 initWithFrame:NSMakeRect(spinnerOriginX, spinnerOriginY, kSpinnerSize, |
512 kSpinnerSize)]); | 516 kSpinnerSize)]); |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
787 | 791 |
788 return base::SysUTF16ToNSString( | 792 return base::SysUTF16ToNSString( |
789 chooserController_->GetOption(static_cast<size_t>(index))); | 793 chooserController_->GetOption(static_cast<size_t>(index))); |
790 } | 794 } |
791 | 795 |
792 - (void)updateTableView { | 796 - (void)updateTableView { |
793 chooserContentViewController_->UpdateTableView(); | 797 chooserContentViewController_->UpdateTableView(); |
794 } | 798 } |
795 | 799 |
796 - (void)accept { | 800 - (void)accept { |
797 chooserController_->Select([tableView_ selectedRow]); | 801 NSIndexSet* selectedRows = [tableView_ selectedRowIndexes]; |
| 802 NSUInteger index = [selectedRows firstIndex]; |
| 803 std::vector<size_t> indices; |
| 804 while (index != NSNotFound) { |
| 805 indices.push_back(index); |
| 806 index = [selectedRows indexGreaterThanIndex:index]; |
| 807 } |
| 808 chooserController_->Select(indices); |
798 } | 809 } |
799 | 810 |
800 - (void)cancel { | 811 - (void)cancel { |
801 chooserController_->Cancel(); | 812 chooserController_->Cancel(); |
802 } | 813 } |
803 | 814 |
804 - (void)close { | 815 - (void)close { |
805 chooserController_->Close(); | 816 chooserController_->Close(); |
806 } | 817 } |
807 | 818 |
808 - (void)onAdapterOffHelp:(id)sender { | 819 - (void)onAdapterOffHelp:(id)sender { |
809 chooserController_->OpenAdapterOffHelpUrl(); | 820 chooserController_->OpenAdapterOffHelpUrl(); |
810 } | 821 } |
811 | 822 |
812 - (void)onRescan:(id)sender { | 823 - (void)onRescan:(id)sender { |
813 chooserController_->RefreshOptions(); | 824 chooserController_->RefreshOptions(); |
814 } | 825 } |
815 | 826 |
816 - (void)onHelpPressed:(id)sender { | 827 - (void)onHelpPressed:(id)sender { |
817 chooserController_->OpenHelpCenterUrl(); | 828 chooserController_->OpenHelpCenterUrl(); |
818 } | 829 } |
819 | 830 |
820 - (void)updateContentRowColor { | 831 - (void)updateContentRowColor { |
821 NSInteger selectedRow = [tableView_ selectedRow]; | 832 NSIndexSet* selectedRows = [tableView_ selectedRowIndexes]; |
822 NSInteger numOptions = | 833 NSInteger numOptions = |
823 base::checked_cast<NSInteger>(chooserController_->NumOptions()); | 834 base::checked_cast<NSInteger>(chooserController_->NumOptions()); |
824 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 835 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
825 for (NSInteger rowIndex = 0; rowIndex < numOptions; ++rowIndex) { | 836 for (NSInteger rowIndex = 0; rowIndex < numOptions; ++rowIndex) { |
| 837 BOOL isSelected = [selectedRows containsIndex:rowIndex]; |
826 // Update the color of the text. | 838 // Update the color of the text. |
827 [[self tableRowViewText:rowIndex] | 839 [[self tableRowViewText:rowIndex] |
828 setTextColor:(rowIndex == selectedRow ? [NSColor whiteColor] | 840 setTextColor:(isSelected ? [NSColor whiteColor] |
829 : [NSColor blackColor])]; | 841 : [NSColor blackColor])]; |
830 | 842 |
831 // Update the color of the image. | 843 // Update the color of the image. |
832 if (chooserController_->ShouldShowIconBeforeText()) { | 844 if (chooserController_->ShouldShowIconBeforeText()) { |
833 if (chooserController_->IsConnected(rowIndex)) { | 845 if (chooserController_->IsConnected(rowIndex)) { |
834 [[self tableRowViewImage:rowIndex] | 846 [[self tableRowViewImage:rowIndex] |
835 setImage:gfx::NSImageFromImageSkia(gfx::CreateVectorIcon( | 847 setImage:gfx::NSImageFromImageSkia(gfx::CreateVectorIcon( |
836 gfx::VectorIconId::BLUETOOTH_CONNECTED, | 848 gfx::VectorIconId::BLUETOOTH_CONNECTED, |
837 rowIndex == selectedRow ? SK_ColorWHITE | 849 isSelected ? SK_ColorWHITE : gfx::kChromeIconGrey))]; |
838 : gfx::kChromeIconGrey))]; | |
839 } else { | 850 } else { |
840 int signalStrengthLevel = | 851 int signalStrengthLevel = |
841 chooserController_->GetSignalStrengthLevel(rowIndex); | 852 chooserController_->GetSignalStrengthLevel(rowIndex); |
842 if (signalStrengthLevel != -1) { | 853 if (signalStrengthLevel != -1) { |
843 int imageId = | 854 int imageId = |
844 rowIndex == selectedRow | 855 isSelected |
845 ? kSignalStrengthLevelImageSelectedIds[signalStrengthLevel] | 856 ? kSignalStrengthLevelImageSelectedIds[signalStrengthLevel] |
846 : kSignalStrengthLevelImageIds[signalStrengthLevel]; | 857 : kSignalStrengthLevelImageIds[signalStrengthLevel]; |
847 [[self tableRowViewImage:rowIndex] | 858 [[self tableRowViewImage:rowIndex] |
848 setImage:rb.GetNativeImageNamed(imageId).ToNSImage()]; | 859 setImage:rb.GetNativeImageNamed(imageId).ToNSImage()]; |
849 } | 860 } |
850 } | 861 } |
851 } | 862 } |
852 | 863 |
853 // Update the color of paired status. | 864 // Update the color of paired status. |
854 NSTextField* pairedStatusText = [self tableRowViewPairedStatus:rowIndex]; | 865 NSTextField* pairedStatusText = [self tableRowViewPairedStatus:rowIndex]; |
855 if (pairedStatusText) { | 866 if (pairedStatusText) { |
856 [pairedStatusText | 867 [pairedStatusText setTextColor:(skia::SkColorToCalibratedNSColor( |
857 setTextColor:(skia::SkColorToCalibratedNSColor( | 868 isSelected ? gfx::kGoogleGreen300 |
858 rowIndex == selectedRow ? gfx::kGoogleGreen300 | 869 : gfx::kGoogleGreen700))]; |
859 : gfx::kGoogleGreen700))]; | |
860 } | 870 } |
861 } | 871 } |
862 } | 872 } |
863 | 873 |
864 - (NSImageView*)tableRowViewImage:(NSInteger)row { | 874 - (NSImageView*)tableRowViewImage:(NSInteger)row { |
865 ChooserContentTableRowView* tableRowView = | 875 ChooserContentTableRowView* tableRowView = |
866 [tableView_ viewAtColumn:0 row:row makeIfNecessary:YES]; | 876 [tableView_ viewAtColumn:0 row:row makeIfNecessary:YES]; |
867 return [tableRowView image]; | 877 return [tableRowView image]; |
868 } | 878 } |
869 | 879 |
(...skipping 11 matching lines...) Expand all Loading... |
881 | 891 |
882 - (void)drawRect:(NSRect)rect { | 892 - (void)drawRect:(NSRect)rect { |
883 [[NSColor colorWithCalibratedWhite:245.0f / 255.0f alpha:1.0f] setFill]; | 893 [[NSColor colorWithCalibratedWhite:245.0f / 255.0f alpha:1.0f] setFill]; |
884 NSRect footnoteFrame = | 894 NSRect footnoteFrame = |
885 NSMakeRect(0.0f, 0.0f, kChooserWidth, separatorOriginY_); | 895 NSMakeRect(0.0f, 0.0f, kChooserWidth, separatorOriginY_); |
886 NSRectFill(footnoteFrame); | 896 NSRectFill(footnoteFrame); |
887 [super drawRect:footnoteFrame]; | 897 [super drawRect:footnoteFrame]; |
888 } | 898 } |
889 | 899 |
890 @end | 900 @end |
OLD | NEW |