| 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> |
| 11 | 11 |
| 12 #include "base/mac/scoped_nsobject.h" | 12 #include "base/mac/scoped_nsobject.h" |
| 13 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
| 14 #include "base/strings/sys_string_conversions.h" | |
| 15 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
| 16 #include "chrome/browser/ui/browser.h" | 15 #include "chrome/browser/ui/browser.h" |
| 17 #include "chrome/browser/ui/browser_window.h" | 16 #include "chrome/browser/ui/browser_window.h" |
| 18 #import "chrome/browser/ui/cocoa/base_bubble_controller.h" | 17 #import "chrome/browser/ui/cocoa/base_bubble_controller.h" |
| 19 #import "chrome/browser/ui/cocoa/browser_window_controller.h" | 18 #import "chrome/browser/ui/cocoa/browser_window_controller.h" |
| 20 #import "chrome/browser/ui/cocoa/browser_window_utils.h" | 19 #import "chrome/browser/ui/cocoa/browser_window_utils.h" |
| 21 #import "chrome/browser/ui/cocoa/chooser_content_view_cocoa.h" | 20 #import "chrome/browser/ui/cocoa/chooser_content_view_cocoa.h" |
| 22 #import "chrome/browser/ui/cocoa/info_bubble_view.h" | 21 #import "chrome/browser/ui/cocoa/info_bubble_view.h" |
| 23 #import "chrome/browser/ui/cocoa/info_bubble_window.h" | 22 #import "chrome/browser/ui/cocoa/info_bubble_window.h" |
| 24 #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h" | 23 #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h" |
| 25 #include "chrome/browser/ui/website_settings/chooser_bubble_delegate.h" | 24 #include "chrome/browser/ui/website_settings/chooser_bubble_delegate.h" |
| 26 #include "chrome/grit/generated_resources.h" | 25 #include "chrome/grit/generated_resources.h" |
| 27 #include "components/bubble/bubble_controller.h" | 26 #include "components/bubble/bubble_controller.h" |
| 27 #include "components/chooser_controller/chooser_controller.h" |
| 28 #include "components/url_formatter/elide_url.h" | 28 #include "components/url_formatter/elide_url.h" |
| 29 #include "content/public/browser/native_web_keyboard_event.h" | 29 #include "content/public/browser/native_web_keyboard_event.h" |
| 30 #include "ui/base/cocoa/cocoa_base_utils.h" | 30 #include "ui/base/cocoa/cocoa_base_utils.h" |
| 31 #include "ui/base/cocoa/window_size_constants.h" | 31 #include "ui/base/cocoa/window_size_constants.h" |
| 32 #include "ui/base/l10n/l10n_util.h" | |
| 33 #include "ui/base/l10n/l10n_util_mac.h" | 32 #include "ui/base/l10n/l10n_util_mac.h" |
| 34 #include "url/gurl.h" | 33 #include "url/gurl.h" |
| 35 #include "url/origin.h" | 34 #include "url/origin.h" |
| 36 | 35 |
| 37 std::unique_ptr<BubbleUi> ChooserBubbleDelegate::BuildBubbleUi() { | 36 std::unique_ptr<BubbleUi> ChooserBubbleDelegate::BuildBubbleUi() { |
| 38 return base::WrapUnique( | 37 return base::WrapUnique( |
| 39 new ChooserBubbleUiCocoa(browser_, chooser_controller())); | 38 new ChooserBubbleUiCocoa(browser_, std::move(chooser_controller_))); |
| 40 } | 39 } |
| 41 | 40 |
| 42 @interface ChooserBubbleUiController | 41 @interface ChooserBubbleUiController |
| 43 : BaseBubbleController<NSTableViewDataSource, NSTableViewDelegate> { | 42 : BaseBubbleController<NSTableViewDataSource, NSTableViewDelegate> { |
| 44 @private | 43 @private |
| 45 // Bridge to the C++ class that created this object. | 44 // Bridge to the C++ class that created this object. |
| 46 ChooserBubbleUiCocoa* bridge_; // Weak. | 45 ChooserBubbleUiCocoa* bridge_; // Weak. |
| 47 bool buttonPressed_; | 46 bool buttonPressed_; |
| 48 | 47 |
| 49 base::scoped_nsobject<ChooserContentViewCocoa> chooserContentView_; | 48 base::scoped_nsobject<ChooserContentViewCocoa> chooserContentView_; |
| 50 NSTableView* tableView_; // Weak. | 49 NSTableView* tableView_; // Weak. |
| 51 NSButton* connectButton_; // Weak. | 50 NSButton* connectButton_; // Weak. |
| 52 NSButton* cancelButton_; // Weak. | 51 NSButton* cancelButton_; // Weak. |
| 53 NSButton* helpButton_; // Weak. | |
| 54 | 52 |
| 55 Browser* browser_; // Weak. | 53 Browser* browser_; // Weak. |
| 56 ChooserController* chooserController_; // Weak. | |
| 57 } | 54 } |
| 58 | 55 |
| 59 // Designated initializer. |browser| and |bridge| must both be non-nil. | 56 // Designated initializer. |browser| and |bridge| must both be non-nil. |
| 60 - (id)initWithBrowser:(Browser*)browser | 57 - (id)initWithBrowser:(Browser*)browser |
| 61 chooserController:(ChooserController*)chooserController | 58 chooserController:(std::unique_ptr<ChooserController>)chooserController |
| 62 bubbleReference:(BubbleReference)bubbleReference | |
| 63 bridge:(ChooserBubbleUiCocoa*)bridge; | 59 bridge:(ChooserBubbleUiCocoa*)bridge; |
| 64 | 60 |
| 65 // Makes the bubble visible. | 61 // Makes the bubble visible. |
| 66 - (void)show; | 62 - (void)show; |
| 67 | 63 |
| 68 // Will reposition the bubble based in case the anchor or parent should change. | 64 // Will reposition the bubble based in case the anchor or parent should change. |
| 69 - (void)updateAnchorPosition; | 65 - (void)updateAnchorPosition; |
| 70 | 66 |
| 71 // Will calculate the expected anchor point for this bubble. | 67 // Will calculate the expected anchor point for this bubble. |
| 72 // Should only be used outside this class for tests. | 68 // Should only be used outside this class for tests. |
| 73 - (NSPoint)getExpectedAnchorPoint; | 69 - (NSPoint)getExpectedAnchorPoint; |
| 74 | 70 |
| 75 // Returns true if the browser has support for the location bar. | 71 // Returns true if the browser has support for the location bar. |
| 76 // Should only be used outside this class for tests. | 72 // Should only be used outside this class for tests. |
| 77 - (bool)hasLocationBar; | 73 - (bool)hasLocationBar; |
| 78 | 74 |
| 79 // Update |tableView_| when chooser options were initialized. | |
| 80 - (void)onOptionsInitialized; | |
| 81 | |
| 82 // Update |tableView_| when chooser option was added. | |
| 83 - (void)onOptionAdded:(NSInteger)index; | |
| 84 | |
| 85 // Update |tableView_| when chooser option was removed. | |
| 86 - (void)onOptionRemoved:(NSInteger)index; | |
| 87 | |
| 88 // Update |tableView_| when chooser options changed. | 75 // Update |tableView_| when chooser options changed. |
| 89 - (void)updateTableView; | 76 - (void)updateTableView; |
| 90 | 77 |
| 91 // Determines if the bubble has an anchor in a corner or no anchor at all. | 78 // Determines if the bubble has an anchor in a corner or no anchor at all. |
| 92 - (info_bubble::BubbleArrowLocation)getExpectedArrowLocation; | 79 - (info_bubble::BubbleArrowLocation)getExpectedArrowLocation; |
| 93 | 80 |
| 94 // Returns the expected parent for this bubble. | 81 // Returns the expected parent for this bubble. |
| 95 - (NSWindow*)getExpectedParentWindow; | 82 - (NSWindow*)getExpectedParentWindow; |
| 96 | 83 |
| 97 // Called when the "Connect" button is pressed. | 84 // Called when the "Connect" button is pressed. |
| 98 - (void)onConnect:(id)sender; | 85 - (void)onConnect:(id)sender; |
| 99 | 86 |
| 100 // Called when the "Cancel" button is pressed. | 87 // Called when the "Cancel" button is pressed. |
| 101 - (void)onCancel:(id)sender; | 88 - (void)onCancel:(id)sender; |
| 102 | 89 |
| 103 // Called when the "Get help" button is pressed. | |
| 104 - (void)onHelpPressed:(id)sender; | |
| 105 | |
| 106 @end | 90 @end |
| 107 | 91 |
| 108 @implementation ChooserBubbleUiController | 92 @implementation ChooserBubbleUiController |
| 109 | 93 |
| 110 - (id)initWithBrowser:(Browser*)browser | 94 - (id)initWithBrowser:(Browser*)browser |
| 111 chooserController:(ChooserController*)chooserController | 95 chooserController:(std::unique_ptr<ChooserController>)chooserController |
| 112 bubbleReference:(BubbleReference)bubbleReference | |
| 113 bridge:(ChooserBubbleUiCocoa*)bridge { | 96 bridge:(ChooserBubbleUiCocoa*)bridge { |
| 114 DCHECK(browser); | 97 DCHECK(browser); |
| 115 DCHECK(chooserController); | 98 DCHECK(chooserController); |
| 116 DCHECK(bubbleReference); | |
| 117 DCHECK(bridge); | 99 DCHECK(bridge); |
| 118 | 100 |
| 119 browser_ = browser; | 101 browser_ = browser; |
| 120 chooserController_ = chooserController; | |
| 121 | 102 |
| 122 base::scoped_nsobject<InfoBubbleWindow> window([[InfoBubbleWindow alloc] | 103 base::scoped_nsobject<InfoBubbleWindow> window([[InfoBubbleWindow alloc] |
| 123 initWithContentRect:ui::kWindowSizeDeterminedLater | 104 initWithContentRect:ui::kWindowSizeDeterminedLater |
| 124 styleMask:NSBorderlessWindowMask | 105 styleMask:NSBorderlessWindowMask |
| 125 backing:NSBackingStoreBuffered | 106 backing:NSBackingStoreBuffered |
| 126 defer:NO]); | 107 defer:NO]); |
| 127 [window setAllowedAnimations:info_bubble::kAnimateNone]; | 108 [window setAllowedAnimations:info_bubble::kAnimateNone]; |
| 128 [window setReleasedWhenClosed:NO]; | 109 [window setReleasedWhenClosed:NO]; |
| 129 if ((self = [super initWithWindow:window | 110 if ((self = [super initWithWindow:window |
| 130 parentWindow:[self getExpectedParentWindow] | 111 parentWindow:[self getExpectedParentWindow] |
| 131 anchoredAt:NSZeroPoint])) { | 112 anchoredAt:NSZeroPoint])) { |
| 132 self.bubbleReference = bubbleReference; | |
| 133 [self setShouldCloseOnResignKey:NO]; | 113 [self setShouldCloseOnResignKey:NO]; |
| 134 [self setShouldOpenAsKeyWindow:YES]; | 114 [self setShouldOpenAsKeyWindow:YES]; |
| 135 [[self bubble] setArrowLocation:[self getExpectedArrowLocation]]; | 115 [[self bubble] setArrowLocation:[self getExpectedArrowLocation]]; |
| 136 bridge_ = bridge; | 116 bridge_ = bridge; |
| 137 NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; | 117 NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; |
| 138 [center addObserver:self | 118 [center addObserver:self |
| 139 selector:@selector(parentWindowDidMove:) | 119 selector:@selector(parentWindowDidMove:) |
| 140 name:NSWindowDidMoveNotification | 120 name:NSWindowDidMoveNotification |
| 141 object:[self getExpectedParentWindow]]; | 121 object:[self getExpectedParentWindow]]; |
| 122 |
| 123 url::Origin origin = chooserController->GetOrigin(); |
| 124 chooserContentView_.reset([[ChooserContentViewCocoa alloc] |
| 125 initWithChooserTitle: |
| 126 l10n_util::GetNSStringF( |
| 127 IDS_DEVICE_CHOOSER_PROMPT, |
| 128 url_formatter::FormatOriginForSecurityDisplay( |
| 129 origin, url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC)) |
| 130 chooserController:std::move(chooserController)]); |
| 131 |
| 132 tableView_ = [chooserContentView_ tableView]; |
| 133 connectButton_ = [chooserContentView_ connectButton]; |
| 134 cancelButton_ = [chooserContentView_ cancelButton]; |
| 135 |
| 136 [connectButton_ setTarget:self]; |
| 137 [connectButton_ setAction:@selector(onConnect:)]; |
| 138 [cancelButton_ setTarget:self]; |
| 139 [cancelButton_ setAction:@selector(onCancel:)]; |
| 140 [tableView_ setDelegate:self]; |
| 141 [tableView_ setDataSource:self]; |
| 142 |
| 143 [[[self window] contentView] addSubview:chooserContentView_.get()]; |
| 142 } | 144 } |
| 145 |
| 143 return self; | 146 return self; |
| 144 } | 147 } |
| 145 | 148 |
| 146 - (void)windowWillClose:(NSNotification*)notification { | 149 - (void)windowWillClose:(NSNotification*)notification { |
| 147 [[NSNotificationCenter defaultCenter] | 150 [[NSNotificationCenter defaultCenter] |
| 148 removeObserver:self | 151 removeObserver:self |
| 149 name:NSWindowDidMoveNotification | 152 name:NSWindowDidMoveNotification |
| 150 object:nil]; | 153 object:nil]; |
| 151 if (!buttonPressed_) | 154 if (!buttonPressed_) |
| 152 chooserController_->Close(); | 155 [chooserContentView_ close]; |
| 153 bridge_->OnBubbleClosing(); | 156 bridge_->OnBubbleClosing(); |
| 154 [super windowWillClose:notification]; | 157 [super windowWillClose:notification]; |
| 155 } | 158 } |
| 156 | 159 |
| 157 - (void)parentWindowWillToggleFullScreen:(NSNotification*)notification { | 160 - (void)parentWindowWillToggleFullScreen:(NSNotification*)notification { |
| 158 // Override the base class implementation, which would have closed the bubble. | 161 // Override the base class implementation, which would have closed the bubble. |
| 159 } | 162 } |
| 160 | 163 |
| 161 - (void)parentWindowDidResize:(NSNotification*)notification { | 164 - (void)parentWindowDidResize:(NSNotification*)notification { |
| 162 [self setAnchorPoint:[self getExpectedAnchorPoint]]; | 165 [self setAnchorPoint:[self getExpectedAnchorPoint]]; |
| 163 } | 166 } |
| 164 | 167 |
| 165 - (void)parentWindowDidMove:(NSNotification*)notification { | 168 - (void)parentWindowDidMove:(NSNotification*)notification { |
| 166 DCHECK(bridge_); | 169 DCHECK(bridge_); |
| 167 [self setAnchorPoint:[self getExpectedAnchorPoint]]; | 170 [self setAnchorPoint:[self getExpectedAnchorPoint]]; |
| 168 } | 171 } |
| 169 | 172 |
| 170 - (void)show { | 173 - (void)show { |
| 171 chooserContentView_.reset([[ChooserContentViewCocoa alloc] | |
| 172 initWithChooserTitle: | |
| 173 l10n_util::GetNSStringF( | |
| 174 IDS_DEVICE_CHOOSER_PROMPT, | |
| 175 url_formatter::FormatOriginForSecurityDisplay( | |
| 176 chooserController_->GetOrigin(), | |
| 177 url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC))]); | |
| 178 | |
| 179 tableView_ = [chooserContentView_ tableView]; | |
| 180 connectButton_ = [chooserContentView_ connectButton]; | |
| 181 cancelButton_ = [chooserContentView_ cancelButton]; | |
| 182 helpButton_ = [chooserContentView_ helpButton]; | |
| 183 | |
| 184 [connectButton_ setTarget:self]; | |
| 185 [connectButton_ setAction:@selector(onConnect:)]; | |
| 186 [cancelButton_ setTarget:self]; | |
| 187 [cancelButton_ setAction:@selector(onCancel:)]; | |
| 188 [tableView_ setDelegate:self]; | |
| 189 [tableView_ setDataSource:self]; | |
| 190 [helpButton_ setTarget:self]; | |
| 191 [helpButton_ setAction:@selector(onHelpPressed:)]; | |
| 192 | |
| 193 [[[self window] contentView] addSubview:chooserContentView_.get()]; | |
| 194 | |
| 195 NSRect bubbleFrame = | 174 NSRect bubbleFrame = |
| 196 [[self window] frameRectForContentRect:[chooserContentView_ frame]]; | 175 [[self window] frameRectForContentRect:[chooserContentView_ frame]]; |
| 197 if ([[self window] isVisible]) { | 176 if ([[self window] isVisible]) { |
| 198 // Unfortunately, calling -setFrame followed by -setFrameOrigin (called | 177 // Unfortunately, calling -setFrame followed by -setFrameOrigin (called |
| 199 // within -setAnchorPoint) causes flickering. Avoid the flickering by | 178 // within -setAnchorPoint) causes flickering. Avoid the flickering by |
| 200 // manually adjusting the new frame's origin so that the top left stays the | 179 // manually adjusting the new frame's origin so that the top left stays the |
| 201 // same, and only calling -setFrame. | 180 // same, and only calling -setFrame. |
| 202 NSRect currentWindowFrame = [[self window] frame]; | 181 NSRect currentWindowFrame = [[self window] frame]; |
| 203 bubbleFrame.origin = currentWindowFrame.origin; | 182 bubbleFrame.origin = currentWindowFrame.origin; |
| 204 bubbleFrame.origin.y = bubbleFrame.origin.y + | 183 bubbleFrame.origin.y = bubbleFrame.origin.y + |
| 205 currentWindowFrame.size.height - | 184 currentWindowFrame.size.height - |
| 206 bubbleFrame.size.height; | 185 bubbleFrame.size.height; |
| 207 [[self window] setFrame:bubbleFrame display:YES]; | 186 [[self window] setFrame:bubbleFrame display:YES]; |
| 208 } else { | 187 } else { |
| 209 [[self window] setFrame:bubbleFrame display:NO]; | 188 [[self window] setFrame:bubbleFrame display:NO]; |
| 210 [self setAnchorPoint:[self getExpectedAnchorPoint]]; | 189 [self setAnchorPoint:[self getExpectedAnchorPoint]]; |
| 211 [self showWindow:nil]; | 190 [self showWindow:nil]; |
| 212 [[self window] makeFirstResponder:nil]; | 191 [[self window] makeFirstResponder:nil]; |
| 213 [[self window] setInitialFirstResponder:tableView_]; | 192 [[self window] setInitialFirstResponder:tableView_]; |
| 214 } | 193 } |
| 215 } | 194 } |
| 216 | 195 |
| 217 - (NSInteger)numberOfRowsInTableView:(NSTableView*)tableView { | 196 - (NSInteger)numberOfRowsInTableView:(NSTableView*)tableView { |
| 218 // When there are no devices, the table contains a message saying there are | 197 return [chooserContentView_ numberOfOptions]; |
| 219 // no devices, so the number of rows is always at least 1. | |
| 220 return std::max(static_cast<NSInteger>(chooserController_->NumOptions()), | |
| 221 static_cast<NSInteger>(1)); | |
| 222 } | 198 } |
| 223 | 199 |
| 224 - (id)tableView:(NSTableView*)tableView | 200 - (id)tableView:(NSTableView*)tableView |
| 225 objectValueForTableColumn:(NSTableColumn*)tableColumn | 201 objectValueForTableColumn:(NSTableColumn*)tableColumn |
| 226 row:(NSInteger)rowIndex { | 202 row:(NSInteger)rowIndex { |
| 227 NSInteger num_options = | 203 return [chooserContentView_ optionAtIndex:rowIndex]; |
| 228 static_cast<NSInteger>(chooserController_->NumOptions()); | |
| 229 if (num_options == 0) { | |
| 230 DCHECK_EQ(0, rowIndex); | |
| 231 return l10n_util::GetNSString(IDS_DEVICE_CHOOSER_NO_DEVICES_FOUND_PROMPT); | |
| 232 } | |
| 233 | |
| 234 DCHECK_GE(rowIndex, 0); | |
| 235 DCHECK_LT(rowIndex, num_options); | |
| 236 return base::SysUTF16ToNSString( | |
| 237 chooserController_->GetOption(static_cast<size_t>(rowIndex))); | |
| 238 } | 204 } |
| 239 | 205 |
| 240 - (BOOL)tableView:(NSTableView*)aTableView | 206 - (BOOL)tableView:(NSTableView*)aTableView |
| 241 shouldEditTableColumn:(NSTableColumn*)aTableColumn | 207 shouldEditTableColumn:(NSTableColumn*)aTableColumn |
| 242 row:(NSInteger)rowIndex { | 208 row:(NSInteger)rowIndex { |
| 243 return NO; | 209 return NO; |
| 244 } | 210 } |
| 245 | 211 |
| 246 - (void)onOptionsInitialized { | |
| 247 [self updateTableView]; | |
| 248 } | |
| 249 | |
| 250 - (void)onOptionAdded:(NSInteger)index { | |
| 251 [self updateTableView]; | |
| 252 } | |
| 253 | |
| 254 - (void)onOptionRemoved:(NSInteger)index { | |
| 255 // |tableView_| will automatically select the removed item's next item. | |
| 256 // So here it tracks if the removed item is the item that was currently | |
| 257 // selected, if so, deselect it. Also if the removed item is before the | |
| 258 // currently selected item, the currently selected item's index needs to | |
| 259 // be adjusted by one. | |
| 260 NSInteger selectedRow = [tableView_ selectedRow]; | |
| 261 if (selectedRow == index) | |
| 262 [tableView_ deselectRow:index]; | |
| 263 else if (selectedRow > index) | |
| 264 [tableView_ selectRowIndexes:[NSIndexSet indexSetWithIndex:selectedRow - 1] | |
| 265 byExtendingSelection:NO]; | |
| 266 | |
| 267 [self updateTableView]; | |
| 268 } | |
| 269 | |
| 270 - (void)updateTableView { | 212 - (void)updateTableView { |
| 271 [tableView_ setEnabled:chooserController_->NumOptions() > 0]; | 213 [chooserContentView_ updateTableView]; |
| 272 [tableView_ reloadData]; | |
| 273 } | 214 } |
| 274 | 215 |
| 275 - (void)tableViewSelectionDidChange:(NSNotification*)aNotification { | 216 - (void)tableViewSelectionDidChange:(NSNotification*)aNotification { |
| 276 [connectButton_ setEnabled:[tableView_ numberOfSelectedRows] > 0]; | 217 [connectButton_ setEnabled:[tableView_ numberOfSelectedRows] > 0]; |
| 277 } | 218 } |
| 278 | 219 |
| 279 - (void)updateAnchorPosition { | 220 - (void)updateAnchorPosition { |
| 280 [self setParentWindow:[self getExpectedParentWindow]]; | 221 [self setParentWindow:[self getExpectedParentWindow]]; |
| 281 [self setAnchorPoint:[self getExpectedAnchorPoint]]; | 222 [self setAnchorPoint:[self getExpectedAnchorPoint]]; |
| 282 } | 223 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 322 + (void)alignCenterOf:(NSView*)viewA verticallyToCenterOf:(NSView*)viewB { | 263 + (void)alignCenterOf:(NSView*)viewA verticallyToCenterOf:(NSView*)viewB { |
| 323 NSRect frameA = [viewA frame]; | 264 NSRect frameA = [viewA frame]; |
| 324 NSRect frameB = [viewB frame]; | 265 NSRect frameB = [viewB frame]; |
| 325 frameA.origin.y = | 266 frameA.origin.y = |
| 326 NSMinY(frameB) + std::floor((NSHeight(frameB) - NSHeight(frameA)) / 2); | 267 NSMinY(frameB) + std::floor((NSHeight(frameB) - NSHeight(frameA)) / 2); |
| 327 [viewA setFrameOrigin:frameA.origin]; | 268 [viewA setFrameOrigin:frameA.origin]; |
| 328 } | 269 } |
| 329 | 270 |
| 330 - (void)onConnect:(id)sender { | 271 - (void)onConnect:(id)sender { |
| 331 buttonPressed_ = true; | 272 buttonPressed_ = true; |
| 332 NSInteger row = [tableView_ selectedRow]; | 273 [chooserContentView_ accept]; |
| 333 chooserController_->Select(row); | |
| 334 self.bubbleReference->CloseBubble(BUBBLE_CLOSE_ACCEPTED); | 274 self.bubbleReference->CloseBubble(BUBBLE_CLOSE_ACCEPTED); |
| 335 [self close]; | 275 [self close]; |
| 336 } | 276 } |
| 337 | 277 |
| 338 - (void)onCancel:(id)sender { | 278 - (void)onCancel:(id)sender { |
| 339 buttonPressed_ = true; | 279 buttonPressed_ = true; |
| 340 chooserController_->Cancel(); | 280 [chooserContentView_ cancel]; |
| 341 self.bubbleReference->CloseBubble(BUBBLE_CLOSE_CANCELED); | 281 self.bubbleReference->CloseBubble(BUBBLE_CLOSE_CANCELED); |
| 342 [self close]; | 282 [self close]; |
| 343 } | 283 } |
| 344 | 284 |
| 345 - (void)onHelpPressed:(id)sender { | |
| 346 chooserController_->OpenHelpCenterUrl(); | |
| 347 } | |
| 348 | |
| 349 @end | 285 @end |
| 350 | 286 |
| 351 ChooserBubbleUiCocoa::ChooserBubbleUiCocoa( | 287 ChooserBubbleUiCocoa::ChooserBubbleUiCocoa( |
| 352 Browser* browser, | 288 Browser* browser, |
| 353 ChooserController* chooser_controller) | 289 std::unique_ptr<ChooserController> chooser_controller) |
| 354 : browser_(browser), | 290 : browser_(browser), |
| 355 chooser_controller_(chooser_controller), | |
| 356 chooser_bubble_ui_controller_(nil) { | 291 chooser_bubble_ui_controller_(nil) { |
| 357 DCHECK(browser); | 292 DCHECK(browser_); |
| 358 DCHECK(chooser_controller); | 293 DCHECK(chooser_controller); |
| 359 chooser_controller_->set_observer(this); | 294 chooser_bubble_ui_controller_ = [[ChooserBubbleUiController alloc] |
| 295 initWithBrowser:browser_ |
| 296 chooserController:std::move(chooser_controller) |
| 297 bridge:this]; |
| 360 } | 298 } |
| 361 | 299 |
| 362 ChooserBubbleUiCocoa::~ChooserBubbleUiCocoa() { | 300 ChooserBubbleUiCocoa::~ChooserBubbleUiCocoa() { |
| 363 chooser_controller_->set_observer(nullptr); | 301 if (chooser_bubble_ui_controller_) { |
| 364 [chooser_bubble_ui_controller_ close]; | 302 [chooser_bubble_ui_controller_ close]; |
| 365 chooser_bubble_ui_controller_ = nil; | 303 chooser_bubble_ui_controller_ = nil; |
| 304 } |
| 366 } | 305 } |
| 367 | 306 |
| 368 void ChooserBubbleUiCocoa::Show(BubbleReference bubble_reference) { | 307 void ChooserBubbleUiCocoa::Show(BubbleReference bubble_reference) { |
| 369 if (!chooser_bubble_ui_controller_) { | 308 [chooser_bubble_ui_controller_ setBubbleReference:bubble_reference]; |
| 370 chooser_bubble_ui_controller_ = | |
| 371 [[ChooserBubbleUiController alloc] initWithBrowser:browser_ | |
| 372 chooserController:chooser_controller_ | |
| 373 bubbleReference:bubble_reference | |
| 374 bridge:this]; | |
| 375 } | |
| 376 | |
| 377 [chooser_bubble_ui_controller_ show]; | 309 [chooser_bubble_ui_controller_ show]; |
| 378 [chooser_bubble_ui_controller_ updateTableView]; | 310 [chooser_bubble_ui_controller_ updateTableView]; |
| 379 } | 311 } |
| 380 | 312 |
| 381 void ChooserBubbleUiCocoa::Close() { | 313 void ChooserBubbleUiCocoa::Close() { |
| 382 [chooser_bubble_ui_controller_ close]; | 314 if (chooser_bubble_ui_controller_) { |
| 383 chooser_bubble_ui_controller_ = nil; | 315 [chooser_bubble_ui_controller_ close]; |
| 316 chooser_bubble_ui_controller_ = nil; |
| 317 } |
| 384 } | 318 } |
| 385 | 319 |
| 386 void ChooserBubbleUiCocoa::UpdateAnchorPosition() { | 320 void ChooserBubbleUiCocoa::UpdateAnchorPosition() { |
| 387 [chooser_bubble_ui_controller_ updateAnchorPosition]; | 321 if (chooser_bubble_ui_controller_) |
| 388 } | 322 [chooser_bubble_ui_controller_ updateAnchorPosition]; |
| 389 | |
| 390 void ChooserBubbleUiCocoa::OnOptionsInitialized() { | |
| 391 [chooser_bubble_ui_controller_ onOptionsInitialized]; | |
| 392 } | |
| 393 | |
| 394 void ChooserBubbleUiCocoa::OnOptionAdded(size_t index) { | |
| 395 [chooser_bubble_ui_controller_ onOptionAdded:static_cast<NSInteger>(index)]; | |
| 396 } | |
| 397 | |
| 398 void ChooserBubbleUiCocoa::OnOptionRemoved(size_t index) { | |
| 399 [chooser_bubble_ui_controller_ onOptionRemoved:static_cast<NSInteger>(index)]; | |
| 400 } | 323 } |
| 401 | 324 |
| 402 void ChooserBubbleUiCocoa::OnBubbleClosing() { | 325 void ChooserBubbleUiCocoa::OnBubbleClosing() { |
| 403 chooser_bubble_ui_controller_ = nil; | 326 chooser_bubble_ui_controller_ = nil; |
| 404 } | 327 } |
| OLD | NEW |