| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/website_settings/chooser_bubble_ui_cocoa.h" | 5 #import "chrome/browser/ui/cocoa/website_settings/chooser_bubble_ui_cocoa.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <cmath> | 10 #include <cmath> |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 #import "chrome/browser/ui/cocoa/browser_window_utils.h" | 21 #import "chrome/browser/ui/cocoa/browser_window_utils.h" |
| 22 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_button.h" | 22 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_button.h" |
| 23 #import "chrome/browser/ui/cocoa/hover_close_button.h" | 23 #import "chrome/browser/ui/cocoa/hover_close_button.h" |
| 24 #import "chrome/browser/ui/cocoa/info_bubble_view.h" | 24 #import "chrome/browser/ui/cocoa/info_bubble_view.h" |
| 25 #import "chrome/browser/ui/cocoa/info_bubble_window.h" | 25 #import "chrome/browser/ui/cocoa/info_bubble_window.h" |
| 26 #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h" | 26 #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h" |
| 27 #include "chrome/grit/generated_resources.h" | 27 #include "chrome/grit/generated_resources.h" |
| 28 #include "content/public/browser/native_web_keyboard_event.h" | 28 #include "content/public/browser/native_web_keyboard_event.h" |
| 29 #include "skia/ext/skia_utils_mac.h" | 29 #include "skia/ext/skia_utils_mac.h" |
| 30 #include "ui/base/cocoa/cocoa_base_utils.h" | 30 #include "ui/base/cocoa/cocoa_base_utils.h" |
| 31 #include "ui/base/cocoa/controls/hyperlink_text_view.h" | 31 #import "ui/base/cocoa/controls/hyperlink_button_cell.h" |
| 32 #include "ui/base/cocoa/window_size_constants.h" | 32 #include "ui/base/cocoa/window_size_constants.h" |
| 33 #include "ui/base/l10n/l10n_util.h" | 33 #include "ui/base/l10n/l10n_util.h" |
| 34 #include "ui/base/l10n/l10n_util_mac.h" | 34 #include "ui/base/l10n/l10n_util_mac.h" |
| 35 #include "url/gurl.h" | 35 #include "url/gurl.h" |
| 36 | 36 |
| 37 namespace { | 37 namespace { |
| 38 | 38 |
| 39 // Chooser bubble width. | 39 // Chooser bubble width. |
| 40 const CGFloat kChooserBubbleWidth = 320.0f; | 40 const CGFloat kChooserBubbleWidth = 320.0f; |
| 41 | 41 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 62 @private | 62 @private |
| 63 // Bridge to the C++ class that created this object. | 63 // Bridge to the C++ class that created this object. |
| 64 ChooserBubbleUiCocoa* bridge_; | 64 ChooserBubbleUiCocoa* bridge_; |
| 65 | 65 |
| 66 base::scoped_nsobject<NSTextField> titleView_; | 66 base::scoped_nsobject<NSTextField> titleView_; |
| 67 base::scoped_nsobject<NSScrollView> scrollView_; | 67 base::scoped_nsobject<NSScrollView> scrollView_; |
| 68 base::scoped_nsobject<NSTableColumn> tableColumn_; | 68 base::scoped_nsobject<NSTableColumn> tableColumn_; |
| 69 base::scoped_nsobject<NSTableView> tableView_; | 69 base::scoped_nsobject<NSTableView> tableView_; |
| 70 base::scoped_nsobject<NSButton> connectButton_; | 70 base::scoped_nsobject<NSButton> connectButton_; |
| 71 base::scoped_nsobject<NSButton> cancelButton_; | 71 base::scoped_nsobject<NSButton> cancelButton_; |
| 72 base::scoped_nsobject<HyperlinkTextView> message_; | 72 base::scoped_nsobject<NSTextField> message_; |
| 73 base::scoped_nsobject<NSButton> getHelpButton_; |
| 73 bool buttonPressed_; | 74 bool buttonPressed_; |
| 74 | 75 |
| 75 Browser* browser_; // Weak. | 76 Browser* browser_; // Weak. |
| 76 ChooserBubbleController* chooserBubbleController_; // Weak. | 77 ChooserBubbleController* chooserBubbleController_; // Weak. |
| 77 } | 78 } |
| 78 | 79 |
| 79 // Designated initializer. |browser| and |bridge| must both be non-nil. | 80 // Designated initializer. |browser| and |bridge| must both be non-nil. |
| 80 - (id)initWithBrowser:(Browser*)browser | 81 - (id)initWithBrowser:(Browser*)browser |
| 81 initWithChooserBubbleController: | 82 initWithChooserBubbleController: |
| 82 (ChooserBubbleController*)chooserBubbleController | 83 (ChooserBubbleController*)chooserBubbleController |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 // Creates a button with |title| and |action|. | 121 // Creates a button with |title| and |action|. |
| 121 - (base::scoped_nsobject<NSButton>)buttonWithTitle:(NSString*)title | 122 - (base::scoped_nsobject<NSButton>)buttonWithTitle:(NSString*)title |
| 122 action:(SEL)action; | 123 action:(SEL)action; |
| 123 | 124 |
| 124 // Creates the "Connect" button. | 125 // Creates the "Connect" button. |
| 125 - (base::scoped_nsobject<NSButton>)connectButton; | 126 - (base::scoped_nsobject<NSButton>)connectButton; |
| 126 | 127 |
| 127 // Creates the "Cancel" button. | 128 // Creates the "Cancel" button. |
| 128 - (base::scoped_nsobject<NSButton>)cancelButton; | 129 - (base::scoped_nsobject<NSButton>)cancelButton; |
| 129 | 130 |
| 130 // Creates the help link. | 131 // Creates the message. |
| 131 - (base::scoped_nsobject<HyperlinkTextView>)message; | 132 - (base::scoped_nsobject<NSTextField>)message; |
| 133 |
| 134 // Creates the "Get help" button. |
| 135 - (base::scoped_nsobject<NSButton>)getHelpButton; |
| 132 | 136 |
| 133 // Called when the "Connect" button is pressed. | 137 // Called when the "Connect" button is pressed. |
| 134 - (void)onConnect:(id)sender; | 138 - (void)onConnect:(id)sender; |
| 135 | 139 |
| 136 // Called when the "Cancel" button is pressed. | 140 // Called when the "Cancel" button is pressed. |
| 137 - (void)onCancel:(id)sender; | 141 - (void)onCancel:(id)sender; |
| 138 | 142 |
| 143 // Called when the "Get help" button is pressed. |
| 144 - (void)onGetHelpPressed:(id)sender; |
| 145 |
| 139 @end | 146 @end |
| 140 | 147 |
| 141 @implementation ChooserBubbleUiController | 148 @implementation ChooserBubbleUiController |
| 142 | 149 |
| 143 - (id)initWithBrowser:(Browser*)browser | 150 - (id)initWithBrowser:(Browser*)browser |
| 144 initWithChooserBubbleController: | 151 initWithChooserBubbleController: |
| 145 (ChooserBubbleController*)chooserBubbleController | 152 (ChooserBubbleController*)chooserBubbleController |
| 146 bridge:(ChooserBubbleUiCocoa*)bridge { | 153 bridge:(ChooserBubbleUiCocoa*)bridge { |
| 147 DCHECK(browser); | 154 DCHECK(browser); |
| 148 DCHECK(chooserBubbleController); | 155 DCHECK(chooserBubbleController); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 connectButton_ = [self connectButton]; | 238 connectButton_ = [self connectButton]; |
| 232 CGFloat connectButtonWidth = NSWidth([connectButton_ frame]); | 239 CGFloat connectButtonWidth = NSWidth([connectButton_ frame]); |
| 233 CGFloat connectButtonHeight = NSHeight([connectButton_ frame]); | 240 CGFloat connectButtonHeight = NSHeight([connectButton_ frame]); |
| 234 | 241 |
| 235 // Cancel button. | 242 // Cancel button. |
| 236 cancelButton_ = [self cancelButton]; | 243 cancelButton_ = [self cancelButton]; |
| 237 CGFloat cancelButtonWidth = NSWidth([cancelButton_ frame]); | 244 CGFloat cancelButtonWidth = NSWidth([cancelButton_ frame]); |
| 238 | 245 |
| 239 // Message. | 246 // Message. |
| 240 message_ = [self message]; | 247 message_ = [self message]; |
| 248 CGFloat messageWidth = NSWidth([message_ frame]); |
| 241 CGFloat messageHeight = NSHeight([message_ frame]); | 249 CGFloat messageHeight = NSHeight([message_ frame]); |
| 242 | 250 |
| 251 // Get help button. |
| 252 getHelpButton_ = [self getHelpButton]; |
| 253 |
| 243 // Separator. | 254 // Separator. |
| 244 CGFloat separatorOriginX = 0.0f; | 255 CGFloat separatorOriginX = 0.0f; |
| 245 CGFloat separatorOriginY = kMarginY + messageHeight + kVerticalPadding; | 256 CGFloat separatorOriginY = kMarginY + messageHeight + kVerticalPadding; |
| 246 NSBox* separator = | 257 NSBox* separator = |
| 247 [self horizontalSeparatorWithFrame:NSMakeRect(separatorOriginX, | 258 [self horizontalSeparatorWithFrame:NSMakeRect(separatorOriginX, |
| 248 separatorOriginY, | 259 separatorOriginY, |
| 249 kChooserBubbleWidth, 0.0f)]; | 260 kChooserBubbleWidth, 0.0f)]; |
| 250 | 261 |
| 251 // ScollView embedding with TableView. | 262 // ScollView embedding with TableView. |
| 252 CGFloat scrollViewWidth = kChooserBubbleWidth - 2 * kMarginX; | 263 CGFloat scrollViewWidth = kChooserBubbleWidth - 2 * kMarginX; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 | 317 |
| 307 // Separator. | 318 // Separator. |
| 308 [view addSubview:separator]; | 319 [view addSubview:separator]; |
| 309 | 320 |
| 310 // Message. | 321 // Message. |
| 311 CGFloat messageOriginX = kMarginX; | 322 CGFloat messageOriginX = kMarginX; |
| 312 CGFloat messageOriginY = kMarginY; | 323 CGFloat messageOriginY = kMarginY; |
| 313 [message_ setFrameOrigin:NSMakePoint(messageOriginX, messageOriginY)]; | 324 [message_ setFrameOrigin:NSMakePoint(messageOriginX, messageOriginY)]; |
| 314 [view addSubview:message_]; | 325 [view addSubview:message_]; |
| 315 | 326 |
| 327 // Get help button. |
| 328 getHelpButton_ = [self getHelpButton]; |
| 329 CGFloat getHelpButtonOriginX = |
| 330 kMarginX + messageWidth - kHorizontalPadding / 2; |
| 331 CGFloat getHelpButtonOriginY = kMarginY; |
| 332 [getHelpButton_ |
| 333 setFrameOrigin:NSMakePoint(getHelpButtonOriginX, getHelpButtonOriginY)]; |
| 334 [view addSubview:getHelpButton_]; |
| 335 |
| 316 bubbleFrame = [[self window] frameRectForContentRect:bubbleFrame]; | 336 bubbleFrame = [[self window] frameRectForContentRect:bubbleFrame]; |
| 317 if ([[self window] isVisible]) { | 337 if ([[self window] isVisible]) { |
| 318 // Unfortunately, calling -setFrame followed by -setFrameOrigin (called | 338 // Unfortunately, calling -setFrame followed by -setFrameOrigin (called |
| 319 // within -setAnchorPoint) causes flickering. Avoid the flickering by | 339 // within -setAnchorPoint) causes flickering. Avoid the flickering by |
| 320 // manually adjusting the new frame's origin so that the top left stays the | 340 // manually adjusting the new frame's origin so that the top left stays the |
| 321 // same, and only calling -setFrame. | 341 // same, and only calling -setFrame. |
| 322 NSRect currentWindowFrame = [[self window] frame]; | 342 NSRect currentWindowFrame = [[self window] frame]; |
| 323 bubbleFrame.origin = currentWindowFrame.origin; | 343 bubbleFrame.origin = currentWindowFrame.origin; |
| 324 bubbleFrame.origin.y = bubbleFrame.origin.y + | 344 bubbleFrame.origin.y = bubbleFrame.origin.y + |
| 325 currentWindowFrame.size.height - | 345 currentWindowFrame.size.height - |
| 326 bubbleFrame.size.height; | 346 bubbleFrame.size.height; |
| 327 [[self window] setFrame:bubbleFrame display:YES]; | 347 [[self window] setFrame:bubbleFrame display:YES]; |
| 328 } else { | 348 } else { |
| 329 [[self window] setFrame:bubbleFrame display:NO]; | 349 [[self window] setFrame:bubbleFrame display:NO]; |
| 330 [self setAnchorPoint:[self getExpectedAnchorPoint]]; | 350 [self setAnchorPoint:[self getExpectedAnchorPoint]]; |
| 331 [self showWindow:nil]; | 351 [self showWindow:nil]; |
| 332 [[self window] makeFirstResponder:nil]; | 352 [[self window] makeFirstResponder:nil]; |
| 333 [[self window] setInitialFirstResponder:connectButton_.get()]; | 353 [[self window] setInitialFirstResponder:tableView_.get()]; |
| 334 } | 354 } |
| 335 } | 355 } |
| 336 | 356 |
| 337 - (NSInteger)numberOfRowsInTableView:(NSTableView*)tableView { | 357 - (NSInteger)numberOfRowsInTableView:(NSTableView*)tableView { |
| 338 // When there are no devices, the table contains a message saying there are | 358 // When there are no devices, the table contains a message saying there are |
| 339 // no devices, so the number of rows is always at least 1. | 359 // no devices, so the number of rows is always at least 1. |
| 340 return std::max( | 360 return std::max( |
| 341 static_cast<NSInteger>(chooserBubbleController_->NumOptions()), | 361 static_cast<NSInteger>(chooserBubbleController_->NumOptions()), |
| 342 static_cast<NSInteger>(1)); | 362 static_cast<NSInteger>(1)); |
| 343 } | 363 } |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 l10n_util::GetNSString(IDS_CHOOSER_BUBBLE_CONNECT_BUTTON_TEXT); | 475 l10n_util::GetNSString(IDS_CHOOSER_BUBBLE_CONNECT_BUTTON_TEXT); |
| 456 return [self buttonWithTitle:connectTitle action:@selector(onConnect:)]; | 476 return [self buttonWithTitle:connectTitle action:@selector(onConnect:)]; |
| 457 } | 477 } |
| 458 | 478 |
| 459 - (base::scoped_nsobject<NSButton>)cancelButton { | 479 - (base::scoped_nsobject<NSButton>)cancelButton { |
| 460 NSString* cancelTitle = | 480 NSString* cancelTitle = |
| 461 l10n_util::GetNSString(IDS_CHOOSER_BUBBLE_CANCEL_BUTTON_TEXT); | 481 l10n_util::GetNSString(IDS_CHOOSER_BUBBLE_CANCEL_BUTTON_TEXT); |
| 462 return [self buttonWithTitle:cancelTitle action:@selector(onCancel:)]; | 482 return [self buttonWithTitle:cancelTitle action:@selector(onCancel:)]; |
| 463 } | 483 } |
| 464 | 484 |
| 465 - (base::scoped_nsobject<HyperlinkTextView>)message { | 485 - (base::scoped_nsobject<NSTextField>)message { |
| 466 base::scoped_nsobject<HyperlinkTextView> textView( | 486 base::scoped_nsobject<NSTextField> messageView( |
| 467 [[HyperlinkTextView alloc] initWithFrame:NSZeroRect]); | 487 [[NSTextField alloc] initWithFrame:NSZeroRect]); |
| 488 [messageView setDrawsBackground:NO]; |
| 489 [messageView setBezeled:NO]; |
| 490 [messageView setEditable:NO]; |
| 491 [messageView setSelectable:NO]; |
| 492 [messageView |
| 493 setStringValue:l10n_util::GetNSStringF(IDS_CHOOSER_BUBBLE_FOOTNOTE_TEXT, |
| 494 base::string16())]; |
| 495 [messageView setFont:[NSFont systemFontOfSize:[NSFont systemFontSize]]]; |
| 496 [messageView sizeToFit]; |
| 497 return messageView; |
| 498 } |
| 468 | 499 |
| 469 base::string16 linkString = | 500 - (base::scoped_nsobject<NSButton>)getHelpButton { |
| 470 l10n_util::GetStringUTF16(IDS_CHOOSER_BUBBLE_GET_HELP_LINK_TEXT); | 501 base::scoped_nsobject<NSButton> button( |
| 471 | 502 [[NSButton alloc] initWithFrame:NSZeroRect]); |
| 472 NSString* text = | 503 base::scoped_nsobject<HyperlinkButtonCell> cell([[HyperlinkButtonCell alloc] |
| 473 l10n_util::GetNSStringF(IDS_CHOOSER_BUBBLE_FOOTNOTE_TEXT, linkString); | 504 initTextCell:l10n_util::GetNSString( |
| 474 [textView setMessage:text | 505 IDS_CHOOSER_BUBBLE_GET_HELP_LINK_TEXT)]); |
| 475 withFont:[NSFont systemFontOfSize:[NSFont systemFontSize]] | 506 [button setCell:cell.get()]; |
| 476 messageColor:[NSColor blackColor]]; | 507 [button sizeToFit]; |
| 477 | 508 [button setTarget:self]; |
| 478 NSColor* linkColor = | 509 [button setAction:@selector(onGetHelpPressed:)]; |
| 479 skia::SkColorToCalibratedNSColor(chrome_style::GetLinkColor()); | 510 return button; |
| 480 [textView | |
| 481 addLinkRange:NSMakeRange([text length] - linkString.size(), | |
| 482 linkString.size()) | |
| 483 withURL:base::SysUTF8ToNSString( | |
| 484 chooserBubbleController_->GetHelpCenterUrl().spec()) | |
| 485 linkColor:linkColor]; | |
| 486 | |
| 487 // Removes the underlining from the link. | |
| 488 NSTextStorage* textStorage = [textView textStorage]; | |
| 489 [textStorage addAttribute:NSUnderlineStyleAttributeName | |
| 490 value:@(NSUnderlineStyleNone) | |
| 491 range:NSMakeRange(0, [text length])]; | |
| 492 | |
| 493 [textView setVerticallyResizable:YES]; | |
| 494 [textView | |
| 495 setFrameSize:NSMakeSize(kChooserBubbleWidth - 2 * kMarginX, MAXFLOAT)]; | |
| 496 [textView sizeToFit]; | |
| 497 | |
| 498 return textView; | |
| 499 } | 511 } |
| 500 | 512 |
| 501 + (CGFloat)matchWidthsOf:(NSView*)viewA andOf:(NSView*)viewB { | 513 + (CGFloat)matchWidthsOf:(NSView*)viewA andOf:(NSView*)viewB { |
| 502 NSRect frameA = [viewA frame]; | 514 NSRect frameA = [viewA frame]; |
| 503 NSRect frameB = [viewB frame]; | 515 NSRect frameB = [viewB frame]; |
| 504 CGFloat width = std::max(NSWidth(frameA), NSWidth(frameB)); | 516 CGFloat width = std::max(NSWidth(frameA), NSWidth(frameB)); |
| 505 [viewA setFrameSize:NSMakeSize(width, NSHeight(frameA))]; | 517 [viewA setFrameSize:NSMakeSize(width, NSHeight(frameA))]; |
| 506 [viewB setFrameSize:NSMakeSize(width, NSHeight(frameB))]; | 518 [viewB setFrameSize:NSMakeSize(width, NSHeight(frameB))]; |
| 507 return width; | 519 return width; |
| 508 } | 520 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 521 chooserBubbleController_->Select(row); | 533 chooserBubbleController_->Select(row); |
| 522 [self close]; | 534 [self close]; |
| 523 } | 535 } |
| 524 | 536 |
| 525 - (void)onCancel:(id)sender { | 537 - (void)onCancel:(id)sender { |
| 526 buttonPressed_ = true; | 538 buttonPressed_ = true; |
| 527 chooserBubbleController_->Cancel(); | 539 chooserBubbleController_->Cancel(); |
| 528 [self close]; | 540 [self close]; |
| 529 } | 541 } |
| 530 | 542 |
| 543 - (void)onGetHelpPressed:(id)sender { |
| 544 chooserBubbleController_->OpenHelpCenterUrl(); |
| 545 } |
| 546 |
| 531 @end | 547 @end |
| 532 | 548 |
| 533 ChooserBubbleUiCocoa::ChooserBubbleUiCocoa( | 549 ChooserBubbleUiCocoa::ChooserBubbleUiCocoa( |
| 534 Browser* browser, | 550 Browser* browser, |
| 535 ChooserBubbleController* chooser_bubble_controller) | 551 ChooserBubbleController* chooser_bubble_controller) |
| 536 : browser_(browser), | 552 : browser_(browser), |
| 537 chooser_bubble_controller_(chooser_bubble_controller), | 553 chooser_bubble_controller_(chooser_bubble_controller), |
| 538 chooser_bubble_ui_controller_(nil) { | 554 chooser_bubble_ui_controller_(nil) { |
| 539 DCHECK(browser); | 555 DCHECK(browser); |
| 540 DCHECK(chooser_bubble_controller); | 556 DCHECK(chooser_bubble_controller); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 [chooser_bubble_ui_controller_ onOptionAdded:static_cast<NSInteger>(index)]; | 592 [chooser_bubble_ui_controller_ onOptionAdded:static_cast<NSInteger>(index)]; |
| 577 } | 593 } |
| 578 | 594 |
| 579 void ChooserBubbleUiCocoa::OnOptionRemoved(size_t index) { | 595 void ChooserBubbleUiCocoa::OnOptionRemoved(size_t index) { |
| 580 [chooser_bubble_ui_controller_ onOptionRemoved:static_cast<NSInteger>(index)]; | 596 [chooser_bubble_ui_controller_ onOptionRemoved:static_cast<NSInteger>(index)]; |
| 581 } | 597 } |
| 582 | 598 |
| 583 void ChooserBubbleUiCocoa::OnBubbleClosing() { | 599 void ChooserBubbleUiCocoa::OnBubbleClosing() { |
| 584 chooser_bubble_ui_controller_ = nil; | 600 chooser_bubble_ui_controller_ = nil; |
| 585 } | 601 } |
| OLD | NEW |