Chromium Code Reviews| 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" |
| 11 #include "chrome/browser/chooser_controller/chooser_controller.h" | 11 #include "chrome/browser/chooser_controller/chooser_controller.h" |
| 12 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_button.h" | 12 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_button.h" |
| 13 #include "chrome/browser/ui/cocoa/spinner_view.h" | 13 #include "chrome/browser/ui/cocoa/spinner_view.h" |
| 14 #include "chrome/grit/generated_resources.h" | 14 #include "chrome/grit/generated_resources.h" |
| 15 #include "grit/ui_resources.h" | |
| 15 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutTw eaker.h" | 16 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutTw eaker.h" |
| 16 #import "ui/base/cocoa/controls/hyperlink_button_cell.h" | 17 #import "ui/base/cocoa/controls/hyperlink_button_cell.h" |
| 17 #include "ui/base/l10n/l10n_util_mac.h" | 18 #include "ui/base/l10n/l10n_util_mac.h" |
| 19 #include "ui/base/resource/resource_bundle.h" | |
| 18 | 20 |
| 19 namespace { | 21 namespace { |
| 20 | 22 |
| 21 // Chooser width. | 23 // Chooser width. |
| 22 const CGFloat kChooserWidth = 350.0f; | 24 const CGFloat kChooserWidth = 350.0f; |
| 23 | 25 |
| 24 // Chooser height. | 26 // Chooser height. |
| 25 const CGFloat kChooserHeight = 300.0f; | 27 const CGFloat kChooserHeight = 300.0f; |
| 26 | 28 |
| 29 // Signal strength level image size. | |
| 30 const CGFloat kSignalStrengthLevelImageSize = 20.0f; | |
| 31 | |
| 32 // Table row view height. | |
| 33 const CGFloat kTableRowViewHeight = 23.0f; | |
| 34 | |
| 27 // Spinner size. | 35 // Spinner size. |
| 28 const CGFloat kSpinnerSize = 24.0f; | 36 const CGFloat kSpinnerSize = 24.0f; |
| 29 | 37 |
| 30 // Distance between the chooser border and the view that is closest to the | 38 // Distance between the chooser border and the view that is closest to the |
| 31 // border. | 39 // border. |
| 32 const CGFloat kMarginX = 20.0f; | 40 const CGFloat kMarginX = 20.0f; |
| 33 const CGFloat kMarginY = 20.0f; | 41 const CGFloat kMarginY = 20.0f; |
| 34 | 42 |
| 35 // Distance between two views inside the chooser. | 43 // Distance between two views inside the chooser. |
| 36 const CGFloat kHorizontalPadding = 10.0f; | 44 const CGFloat kHorizontalPadding = 10.0f; |
| 37 const CGFloat kVerticalPadding = 10.0f; | 45 const CGFloat kVerticalPadding = 10.0f; |
| 38 | 46 |
| 39 // Separator alpha value. | 47 // Separator alpha value. |
| 40 const CGFloat kSeparatorAlphaValue = 0.6f; | 48 const CGFloat kSeparatorAlphaValue = 0.6f; |
| 41 | 49 |
| 42 // Separator height. | 50 // Separator height. |
| 43 const CGFloat kSeparatorHeight = 1.0f; | 51 const CGFloat kSeparatorHeight = 1.0f; |
| 44 | 52 |
| 53 // The lookup table for signal strength level image. | |
| 54 const int kSignalStrengthLevelImageIds[5] = {IDR_SIGNAL_0_BAR, IDR_SIGNAL_1_BAR, | |
| 55 IDR_SIGNAL_2_BAR, IDR_SIGNAL_3_BAR, | |
| 56 IDR_SIGNAL_4_BAR}; | |
| 57 | |
| 45 } // namespace | 58 } // namespace |
| 46 | 59 |
| 60 // A table row view that contains one line of text, and optionally contains an | |
| 61 // image in front of the text. | |
| 62 @interface TableRowView : NSView { | |
|
Robert Sesek
2016/08/24 18:47:37
Since ObjC is a flat, global namespace, I'd make t
juncai
2016/08/25 00:59:17
Done.
| |
| 63 @private | |
| 64 base::scoped_nsobject<NSImageView> image_; | |
| 65 base::scoped_nsobject<NSTextField> text_; | |
| 66 } | |
| 67 | |
| 68 // Designated initializer. | |
| 69 - (instancetype)initWithText:(NSString*)text | |
| 70 signalStrengthLevel:(NSInteger)level; | |
| 71 | |
| 72 // Gets the image in front of the text. | |
| 73 - (NSImageView*)image; | |
| 74 | |
| 75 // Gets the text. | |
| 76 - (NSTextField*)text; | |
| 77 | |
| 78 @end | |
| 79 | |
| 80 @implementation TableRowView | |
| 81 | |
| 82 - (instancetype)initWithText:(NSString*)text | |
| 83 signalStrengthLevel:(NSInteger)level { | |
| 84 if ((self = [super initWithFrame:NSZeroRect])) { | |
| 85 if (level != -1) { | |
| 86 DCHECK_GE(level, 0); | |
| 87 DCHECK_LT(level, base::checked_cast<NSInteger>( | |
| 88 arraysize(kSignalStrengthLevelImageIds))); | |
| 89 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | |
| 90 NSImage* signalStrengthLevelImage = | |
| 91 rb.GetNativeImageNamed(kSignalStrengthLevelImageIds[level]) | |
| 92 .ToNSImage(); | |
| 93 | |
| 94 image_.reset([[NSImageView alloc] | |
| 95 initWithFrame:NSMakeRect(0, (kTableRowViewHeight - | |
| 96 kSignalStrengthLevelImageSize) / | |
| 97 2, | |
| 98 kSignalStrengthLevelImageSize, | |
| 99 kSignalStrengthLevelImageSize)]); | |
| 100 [image_ setImage:signalStrengthLevelImage]; | |
| 101 [self addSubview:image_]; | |
| 102 } | |
| 103 | |
| 104 text_.reset([[NSTextField alloc] initWithFrame:NSZeroRect]); | |
| 105 [text_ setDrawsBackground:NO]; | |
| 106 [text_ setBezeled:NO]; | |
| 107 [text_ setEditable:NO]; | |
| 108 [text_ setSelectable:NO]; | |
| 109 [text_ setStringValue:text]; | |
| 110 [text_ setFont:[NSFont systemFontOfSize:[NSFont systemFontSize]]]; | |
| 111 [text_ sizeToFit]; | |
| 112 CGFloat textHeight = NSHeight([text_ frame]); | |
| 113 [text_ setFrameOrigin:NSMakePoint( | |
| 114 level == -1 ? 0 : kSignalStrengthLevelImageSize + | |
| 115 kHorizontalPadding, | |
| 116 (kTableRowViewHeight - textHeight) / 2)]; | |
| 117 [self addSubview:text_]; | |
| 118 } | |
| 119 | |
| 120 return self; | |
| 121 } | |
| 122 | |
| 123 - (NSImageView*)image { | |
| 124 return image_.get(); | |
| 125 } | |
| 126 | |
| 127 - (NSTextField*)text { | |
| 128 return text_.get(); | |
| 129 } | |
| 130 | |
| 131 @end | |
| 132 | |
| 47 class ChooserContentViewController : public ChooserController::View { | 133 class ChooserContentViewController : public ChooserController::View { |
| 48 public: | 134 public: |
| 49 ChooserContentViewController(ChooserContentViewCocoa* chooser_content_view, | 135 ChooserContentViewController(ChooserContentViewCocoa* chooser_content_view, |
| 50 ChooserController* chooser_controller, | 136 ChooserController* chooser_controller, |
| 51 NSTableView* table_view, | 137 NSTableView* table_view, |
| 52 SpinnerView* spinner, | 138 SpinnerView* spinner, |
| 53 NSTextField* status, | 139 NSTextField* status, |
| 54 NSButton* rescan_button); | 140 NSButton* rescan_button); |
| 55 ~ChooserContentViewController() override; | 141 ~ChooserContentViewController() override; |
| 56 | 142 |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 168 // When refreshing, show |status_| and hide |rescan_button_|. | 254 // When refreshing, show |status_| and hide |rescan_button_|. |
| 169 // When complete, show |rescan_button_| and hide |status_|. | 255 // When complete, show |rescan_button_| and hide |status_|. |
| 170 [status_ setHidden:refreshing ? NO : YES]; | 256 [status_ setHidden:refreshing ? NO : YES]; |
| 171 [rescan_button_ setHidden:refreshing ? YES : NO]; | 257 [rescan_button_ setHidden:refreshing ? YES : NO]; |
| 172 | 258 |
| 173 [chooser_content_view_ updateView]; | 259 [chooser_content_view_ updateView]; |
| 174 } | 260 } |
| 175 | 261 |
| 176 void ChooserContentViewController::UpdateTableView() { | 262 void ChooserContentViewController::UpdateTableView() { |
| 177 [table_view_ setEnabled:chooser_controller_->NumOptions() > 0]; | 263 [table_view_ setEnabled:chooser_controller_->NumOptions() > 0]; |
| 264 // For NSView-based table views, calling reloadData will deselect the | |
| 265 // currently selected row, so |selected_row| stores the currently selected | |
| 266 // row in order to select it again. | |
| 267 NSInteger selected_row = [table_view_ selectedRow]; | |
| 178 [table_view_ reloadData]; | 268 [table_view_ reloadData]; |
| 269 if (selected_row != -1) { | |
| 270 [table_view_ selectRowIndexes:[NSIndexSet indexSetWithIndex:selected_row] | |
| 271 byExtendingSelection:NO]; | |
| 272 } | |
| 179 } | 273 } |
| 180 | 274 |
| 181 @implementation ChooserContentViewCocoa | 275 @implementation ChooserContentViewCocoa |
| 182 | 276 |
| 183 // TODO(juncai): restructure this function to be some smaller methods to | 277 // TODO(juncai): restructure this function to be some smaller methods to |
| 184 // create the pieces for the view. By doing so, the methods that calculate | 278 // create the pieces for the view. By doing so, the methods that calculate |
| 185 // the frame and origins can be moved into those methods, rather than as | 279 // the frame and origins can be moved into those methods, rather than as |
| 186 // helper functions. | 280 // helper functions. |
| 187 - (instancetype)initWithChooserTitle:(NSString*)chooserTitle | 281 - (instancetype)initWithChooserTitle:(NSString*)chooserTitle |
| 188 chooserController: | 282 chooserController: |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 388 [titleView setEditable:NO]; | 482 [titleView setEditable:NO]; |
| 389 [titleView setSelectable:NO]; | 483 [titleView setSelectable:NO]; |
| 390 [titleView setStringValue:title]; | 484 [titleView setStringValue:title]; |
| 391 [titleView setFont:[NSFont systemFontOfSize:[NSFont systemFontSize]]]; | 485 [titleView setFont:[NSFont systemFontOfSize:[NSFont systemFontSize]]]; |
| 392 // The height is arbitrary as it will be adjusted later. | 486 // The height is arbitrary as it will be adjusted later. |
| 393 [titleView setFrameSize:NSMakeSize(kChooserWidth - 2 * kMarginX, 0.0f)]; | 487 [titleView setFrameSize:NSMakeSize(kChooserWidth - 2 * kMarginX, 0.0f)]; |
| 394 [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:titleView]; | 488 [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:titleView]; |
| 395 return titleView; | 489 return titleView; |
| 396 } | 490 } |
| 397 | 491 |
| 492 - (NSView*)createTableRowView:(NSInteger)rowIndex { | |
| 493 NSInteger level = -1; | |
| 494 size_t numOptions = chooserController_->NumOptions(); | |
| 495 if (chooserController_->ShouldShowIconBeforeText() && numOptions > 0) { | |
| 496 DCHECK_GE(rowIndex, 0); | |
| 497 DCHECK_LT(rowIndex, base::checked_cast<NSInteger>(numOptions)); | |
| 498 level = base::checked_cast<NSInteger>( | |
| 499 chooserController_->GetSignalStrengthLevel( | |
| 500 base::checked_cast<size_t>(rowIndex))); | |
| 501 } | |
| 502 | |
| 503 base::scoped_nsobject<TableRowView> tableRowView([[TableRowView alloc] | |
| 504 initWithText:[self optionAtIndex:rowIndex] | |
| 505 signalStrengthLevel:level]); | |
| 506 return tableRowView.autorelease(); | |
| 507 } | |
| 508 | |
| 509 - (CGFloat)tableRowViewHeight:(NSInteger)row { | |
| 510 return kTableRowViewHeight; | |
| 511 } | |
| 512 | |
| 398 - (base::scoped_nsobject<NSButton>)createButtonWithTitle:(NSString*)title { | 513 - (base::scoped_nsobject<NSButton>)createButtonWithTitle:(NSString*)title { |
| 399 base::scoped_nsobject<NSButton> button( | 514 base::scoped_nsobject<NSButton> button( |
| 400 [[ConstrainedWindowButton alloc] initWithFrame:NSZeroRect]); | 515 [[ConstrainedWindowButton alloc] initWithFrame:NSZeroRect]); |
| 401 [button setButtonType:NSMomentaryPushInButton]; | 516 [button setButtonType:NSMomentaryPushInButton]; |
| 402 [button setTitle:title]; | 517 [button setTitle:title]; |
| 403 [button sizeToFit]; | 518 [button sizeToFit]; |
| 404 return button; | 519 return button; |
| 405 } | 520 } |
| 406 | 521 |
| 407 - (base::scoped_nsobject<NSButton>)createConnectButton { | 522 - (base::scoped_nsobject<NSButton>)createConnectButton { |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 529 return helpButton_.get(); | 644 return helpButton_.get(); |
| 530 } | 645 } |
| 531 | 646 |
| 532 - (NSInteger)numberOfOptions { | 647 - (NSInteger)numberOfOptions { |
| 533 // When there are no devices, the table contains a message saying there are | 648 // When there are no devices, the table contains a message saying there are |
| 534 // no devices, so the number of rows is always at least 1. | 649 // no devices, so the number of rows is always at least 1. |
| 535 return std::max(static_cast<NSInteger>(chooserController_->NumOptions()), | 650 return std::max(static_cast<NSInteger>(chooserController_->NumOptions()), |
| 536 static_cast<NSInteger>(1)); | 651 static_cast<NSInteger>(1)); |
| 537 } | 652 } |
| 538 | 653 |
| 654 // When this function is called with numOptions == 0, it is to show the | |
| 655 // message saying there are no devices. | |
| 539 - (NSString*)optionAtIndex:(NSInteger)index { | 656 - (NSString*)optionAtIndex:(NSInteger)index { |
| 540 NSInteger numOptions = | 657 NSInteger numOptions = |
| 541 static_cast<NSInteger>(chooserController_->NumOptions()); | 658 static_cast<NSInteger>(chooserController_->NumOptions()); |
| 542 if (numOptions == 0) { | 659 if (numOptions == 0) { |
| 543 DCHECK_EQ(0, index); | 660 DCHECK_EQ(0, index); |
| 544 return base::SysUTF16ToNSString(chooserController_->GetNoOptionsText()); | 661 return base::SysUTF16ToNSString(chooserController_->GetNoOptionsText()); |
| 545 } | 662 } |
| 546 | 663 |
| 547 DCHECK_GE(index, 0); | 664 DCHECK_GE(index, 0); |
| 548 DCHECK_LT(index, numOptions); | 665 DCHECK_LT(index, numOptions); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 568 } | 685 } |
| 569 | 686 |
| 570 - (void)onRescan:(id)sender { | 687 - (void)onRescan:(id)sender { |
| 571 chooserController_->RefreshOptions(); | 688 chooserController_->RefreshOptions(); |
| 572 } | 689 } |
| 573 | 690 |
| 574 - (void)onHelpPressed:(id)sender { | 691 - (void)onHelpPressed:(id)sender { |
| 575 chooserController_->OpenHelpCenterUrl(); | 692 chooserController_->OpenHelpCenterUrl(); |
| 576 } | 693 } |
| 577 | 694 |
| 695 - (NSImageView*)tableRowViewImage:(NSInteger)row { | |
| 696 TableRowView* tableRowView = | |
| 697 [tableView_ viewAtColumn:0 row:row makeIfNecessary:YES]; | |
| 698 return [tableRowView image]; | |
| 699 } | |
| 700 | |
| 701 - (NSTextField*)tableRowViewText:(NSInteger)row { | |
| 702 TableRowView* tableRowView = | |
| 703 [tableView_ viewAtColumn:0 row:row makeIfNecessary:YES]; | |
| 704 return [tableRowView text]; | |
| 705 } | |
| 706 | |
| 578 @end | 707 @end |
| OLD | NEW |