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> |
| 8 |
| 9 #include "base/macros.h" |
| 10 #include "base/strings/sys_string_conversions.h" |
7 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_button.h" | 11 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_button.h" |
8 #include "chrome/grit/generated_resources.h" | 12 #include "chrome/grit/generated_resources.h" |
| 13 #include "components/chooser_controller/chooser_controller.h" |
9 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutTw
eaker.h" | 14 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutTw
eaker.h" |
10 #import "ui/base/cocoa/controls/hyperlink_button_cell.h" | 15 #import "ui/base/cocoa/controls/hyperlink_button_cell.h" |
11 #include "ui/base/l10n/l10n_util.h" | |
12 #include "ui/base/l10n/l10n_util_mac.h" | 16 #include "ui/base/l10n/l10n_util_mac.h" |
13 | 17 |
14 namespace { | 18 namespace { |
15 | 19 |
16 // Chooser width. | 20 // Chooser width. |
17 const CGFloat kChooserWidth = 320.0f; | 21 const CGFloat kChooserWidth = 320.0f; |
18 | 22 |
19 // Chooser height. | 23 // Chooser height. |
20 const CGFloat kChooserHeight = 280.0f; | 24 const CGFloat kChooserHeight = 280.0f; |
21 | 25 |
22 // Distance between the chooser border and the view that is closest to the | 26 // Distance between the chooser border and the view that is closest to the |
23 // border. | 27 // border. |
24 const CGFloat kMarginX = 20.0f; | 28 const CGFloat kMarginX = 20.0f; |
25 const CGFloat kMarginY = 20.0f; | 29 const CGFloat kMarginY = 20.0f; |
26 | 30 |
27 // Distance between two views inside the chooser. | 31 // Distance between two views inside the chooser. |
28 const CGFloat kHorizontalPadding = 10.0f; | 32 const CGFloat kHorizontalPadding = 10.0f; |
29 const CGFloat kVerticalPadding = 10.0f; | 33 const CGFloat kVerticalPadding = 10.0f; |
30 | 34 |
31 // Separator alpha value. | 35 // Separator alpha value. |
32 const CGFloat kSeparatorAlphaValue = 0.6f; | 36 const CGFloat kSeparatorAlphaValue = 0.6f; |
33 | 37 |
34 // Separator height. | 38 // Separator height. |
35 const CGFloat kSeparatorHeight = 1.0f; | 39 const CGFloat kSeparatorHeight = 1.0f; |
36 | 40 |
37 } // namespace | 41 } // namespace |
38 | 42 |
| 43 class TableViewController : public ChooserController::Observer { |
| 44 public: |
| 45 TableViewController(ChooserController* chooser_controller, |
| 46 NSTableView* table_view); |
| 47 ~TableViewController() override; |
| 48 |
| 49 // ChooserController::Observer: |
| 50 void OnOptionsInitialized() override; |
| 51 void OnOptionAdded(size_t index) override; |
| 52 void OnOptionRemoved(size_t index) override; |
| 53 |
| 54 void UpdateTableView(); |
| 55 |
| 56 private: |
| 57 ChooserController* chooser_controller_; |
| 58 NSTableView* table_view_; |
| 59 |
| 60 DISALLOW_COPY_AND_ASSIGN(TableViewController); |
| 61 }; |
| 62 |
| 63 TableViewController::TableViewController(ChooserController* chooser_controller, |
| 64 NSTableView* table_view) |
| 65 : chooser_controller_(chooser_controller), table_view_(table_view) { |
| 66 DCHECK(chooser_controller_); |
| 67 DCHECK(table_view_); |
| 68 chooser_controller_->set_observer(this); |
| 69 } |
| 70 |
| 71 TableViewController::~TableViewController() { |
| 72 chooser_controller_->set_observer(nullptr); |
| 73 } |
| 74 |
| 75 void TableViewController::OnOptionsInitialized() { |
| 76 UpdateTableView(); |
| 77 } |
| 78 |
| 79 void TableViewController::OnOptionAdded(size_t index) { |
| 80 UpdateTableView(); |
| 81 } |
| 82 |
| 83 void TableViewController::OnOptionRemoved(size_t index) { |
| 84 // |table_view_| will automatically select the removed item's next item. |
| 85 // So here it tracks if the removed item is the item that was currently |
| 86 // selected, if so, deselect it. Also if the removed item is before the |
| 87 // currently selected item, the currently selected item's index needs to |
| 88 // be adjusted by one. |
| 89 NSInteger idx = static_cast<NSInteger>(index); |
| 90 NSInteger selected_row = [table_view_ selectedRow]; |
| 91 if (selected_row == idx) |
| 92 [table_view_ deselectRow:idx]; |
| 93 else if (selected_row > idx) |
| 94 [table_view_ |
| 95 selectRowIndexes:[NSIndexSet indexSetWithIndex:selected_row - 1] |
| 96 byExtendingSelection:NO]; |
| 97 |
| 98 UpdateTableView(); |
| 99 } |
| 100 |
| 101 void TableViewController::UpdateTableView() { |
| 102 [table_view_ setEnabled:chooser_controller_->NumOptions() > 0]; |
| 103 [table_view_ reloadData]; |
| 104 } |
| 105 |
39 @implementation ChooserContentViewCocoa | 106 @implementation ChooserContentViewCocoa |
40 | 107 |
41 - (instancetype)initWithChooserTitle:(NSString*)chooserTitle { | 108 - (instancetype)initWithChooserTitle:(NSString*)chooserTitle |
| 109 ChooserController: |
| 110 (std::unique_ptr<ChooserController>)chooserController { |
| 111 chooserController_ = std::move(chooserController); |
42 // ------------------------------------ | 112 // ------------------------------------ |
43 // | Chooser title | | 113 // | Chooser title | |
44 // | -------------------------------- | | 114 // | -------------------------------- | |
45 // | | option 0 | | | 115 // | | option 0 | | |
46 // | | option 1 | | | 116 // | | option 1 | | |
47 // | | option 2 | | | 117 // | | option 2 | | |
48 // | | | | | 118 // | | | | |
49 // | | | | | 119 // | | | | |
50 // | | | | | 120 // | | | | |
51 // | -------------------------------- | | 121 // | -------------------------------- | |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 CGFloat messageOriginY = kMarginY; | 219 CGFloat messageOriginY = kMarginY; |
150 [message_ setFrameOrigin:NSMakePoint(messageOriginX, messageOriginY)]; | 220 [message_ setFrameOrigin:NSMakePoint(messageOriginX, messageOriginY)]; |
151 [self addSubview:message_]; | 221 [self addSubview:message_]; |
152 | 222 |
153 // Help button. | 223 // Help button. |
154 CGFloat helpButtonOriginX = | 224 CGFloat helpButtonOriginX = |
155 kMarginX + messageWidth - kHorizontalPadding / 2; | 225 kMarginX + messageWidth - kHorizontalPadding / 2; |
156 CGFloat helpButtonOriginY = kMarginY; | 226 CGFloat helpButtonOriginY = kMarginY; |
157 [helpButton_ | 227 [helpButton_ |
158 setFrameOrigin:NSMakePoint(helpButtonOriginX, helpButtonOriginY)]; | 228 setFrameOrigin:NSMakePoint(helpButtonOriginX, helpButtonOriginY)]; |
| 229 [helpButton_ setTarget:self]; |
| 230 [helpButton_ setAction:@selector(onHelpPressed:)]; |
159 [self addSubview:helpButton_]; | 231 [self addSubview:helpButton_]; |
| 232 |
| 233 tableViewController_.reset( |
| 234 new TableViewController(chooserController_.get(), tableView_.get())); |
160 } | 235 } |
161 | 236 |
162 return self; | 237 return self; |
163 } | 238 } |
164 | 239 |
165 - (base::scoped_nsobject<NSTextField>)createChooserTitle:(NSString*)title { | 240 - (base::scoped_nsobject<NSTextField>)createChooserTitle:(NSString*)title { |
166 base::scoped_nsobject<NSTextField> titleView( | 241 base::scoped_nsobject<NSTextField> titleView( |
167 [[NSTextField alloc] initWithFrame:NSZeroRect]); | 242 [[NSTextField alloc] initWithFrame:NSZeroRect]); |
168 [titleView setDrawsBackground:NO]; | 243 [titleView setDrawsBackground:NO]; |
169 [titleView setBezeled:NO]; | 244 [titleView setBezeled:NO]; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 } | 317 } |
243 | 318 |
244 - (NSButton*)cancelButton { | 319 - (NSButton*)cancelButton { |
245 return cancelButton_.get(); | 320 return cancelButton_.get(); |
246 } | 321 } |
247 | 322 |
248 - (NSButton*)helpButton { | 323 - (NSButton*)helpButton { |
249 return helpButton_.get(); | 324 return helpButton_.get(); |
250 } | 325 } |
251 | 326 |
| 327 - (NSInteger)numOptions { |
| 328 // When there are no devices, the table contains a message saying there are |
| 329 // no devices, so the number of rows is always at least 1. |
| 330 return std::max(static_cast<NSInteger>(chooserController_->NumOptions()), |
| 331 static_cast<NSInteger>(1)); |
| 332 } |
| 333 |
| 334 - (NSString*)getOption:(NSInteger)index { |
| 335 NSInteger numOptions = |
| 336 static_cast<NSInteger>(chooserController_->NumOptions()); |
| 337 if (numOptions == 0) { |
| 338 DCHECK_EQ(0, index); |
| 339 return l10n_util::GetNSString(IDS_DEVICE_CHOOSER_NO_DEVICES_FOUND_PROMPT); |
| 340 } |
| 341 |
| 342 DCHECK_GE(index, 0); |
| 343 DCHECK_LT(index, numOptions); |
| 344 |
| 345 return base::SysUTF16ToNSString( |
| 346 chooserController_->GetOption(static_cast<size_t>(index))); |
| 347 } |
| 348 |
| 349 - (void)updateTableView { |
| 350 tableViewController_->UpdateTableView(); |
| 351 } |
| 352 |
| 353 - (void)Accept { |
| 354 chooserController_->Select([tableView_ selectedRow]); |
| 355 } |
| 356 |
| 357 - (void)Cancel { |
| 358 chooserController_->Cancel(); |
| 359 } |
| 360 |
| 361 - (void)Close { |
| 362 chooserController_->Close(); |
| 363 } |
| 364 |
| 365 - (void)onHelpPressed:(id)sender { |
| 366 chooserController_->OpenHelpCenterUrl(); |
| 367 } |
| 368 |
252 @end | 369 @end |
OLD | NEW |