Chromium Code Reviews| 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/extensions/toolbar_actions_bar_bubble_mac.h" | 5 #import "chrome/browser/ui/cocoa/extensions/toolbar_actions_bar_bubble_mac.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/mac/foundation_util.h" | 9 #include "base/mac/foundation_util.h" |
| 10 #include "base/strings/sys_string_conversions.h" | 10 #include "base/strings/sys_string_conversions.h" |
| 11 #import "chrome/browser/ui/cocoa/info_bubble_view.h" | 11 #import "chrome/browser/ui/cocoa/info_bubble_view.h" |
| 12 #import "chrome/browser/ui/cocoa/info_bubble_window.h" | 12 #import "chrome/browser/ui/cocoa/info_bubble_window.h" |
| 13 #include "chrome/browser/ui/toolbar/toolbar_actions_bar_bubble_delegate.h" | 13 #include "chrome/browser/ui/toolbar/toolbar_actions_bar_bubble_delegate.h" |
| 14 #include "skia/ext/skia_utils_mac.h" | 14 #include "skia/ext/skia_utils_mac.h" |
| 15 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutTw eaker.h" | 15 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutTw eaker.h" |
| 16 #include "third_party/skia/include/core/SkColor.h" | 16 #include "third_party/skia/include/core/SkColor.h" |
| 17 #import "ui/base/cocoa/controls/hyperlink_button_cell.h" | 17 #import "ui/base/cocoa/controls/hyperlink_button_cell.h" |
| 18 #import "ui/base/cocoa/hover_button.h" | 18 #import "ui/base/cocoa/hover_button.h" |
| 19 #include "ui/base/resource/resource_bundle.h" | |
| 19 #import "ui/base/cocoa/window_size_constants.h" | 20 #import "ui/base/cocoa/window_size_constants.h" |
| 21 #include "ui/gfx/image/image_skia_util_mac.h" | |
| 20 #include "ui/native_theme/native_theme.h" | 22 #include "ui/native_theme/native_theme.h" |
| 21 #include "ui/native_theme/native_theme_mac.h" | 23 #include "ui/native_theme/native_theme_mac.h" |
| 22 | 24 |
| 23 namespace { | 25 namespace { |
| 24 BOOL g_animations_enabled = false; | 26 BOOL g_animations_enabled = false; |
| 25 CGFloat kMinWidth = 320.0; | 27 CGFloat kMinWidth = 320.0; |
| 26 } | 28 } |
| 27 | 29 |
| 28 @interface ToolbarActionsBarBubbleMac () | 30 @interface ToolbarActionsBarBubbleMac () |
| 29 | 31 |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 52 // Handles a button being clicked. | 54 // Handles a button being clicked. |
| 53 - (void)onButtonClicked:(id)sender; | 55 - (void)onButtonClicked:(id)sender; |
| 54 | 56 |
| 55 @end | 57 @end |
| 56 | 58 |
| 57 @implementation ToolbarActionsBarBubbleMac | 59 @implementation ToolbarActionsBarBubbleMac |
| 58 | 60 |
| 59 @synthesize actionButton = actionButton_; | 61 @synthesize actionButton = actionButton_; |
| 60 @synthesize itemList = itemList_; | 62 @synthesize itemList = itemList_; |
| 61 @synthesize dismissButton = dismissButton_; | 63 @synthesize dismissButton = dismissButton_; |
| 62 @synthesize learnMoreButton = learnMoreButton_; | 64 @synthesize link = link_; |
| 65 @synthesize label = label_; | |
| 66 @synthesize iconView = iconView_; | |
| 63 | 67 |
| 64 - (id)initWithParentWindow:(NSWindow*)parentWindow | 68 - (id)initWithParentWindow:(NSWindow*)parentWindow |
| 65 anchorPoint:(NSPoint)anchorPoint | 69 anchorPoint:(NSPoint)anchorPoint |
| 66 anchoredToAction:(BOOL)anchoredToAction | 70 anchoredToAction:(BOOL)anchoredToAction |
| 67 delegate: | 71 delegate: |
| 68 (std::unique_ptr<ToolbarActionsBarBubbleDelegate>) | 72 (std::unique_ptr<ToolbarActionsBarBubbleDelegate>) |
| 69 delegate { | 73 delegate { |
| 70 base::scoped_nsobject<InfoBubbleWindow> window( | 74 base::scoped_nsobject<InfoBubbleWindow> window( |
| 71 [[InfoBubbleWindow alloc] | 75 [[InfoBubbleWindow alloc] |
| 72 initWithContentRect:ui::kWindowSizeDeterminedLater | 76 initWithContentRect:ui::kWindowSizeDeterminedLater |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 170 [button setBezelStyle:NSRoundedBezelStyle]; | 174 [button setBezelStyle:NSRoundedBezelStyle]; |
| 171 [button setTarget:self]; | 175 [button setTarget:self]; |
| 172 [button setAction:@selector(onButtonClicked:)]; | 176 [button setAction:@selector(onButtonClicked:)]; |
| 173 [[[self window] contentView] addSubview:button]; | 177 [[[self window] contentView] addSubview:button]; |
| 174 [button sizeToFit]; | 178 [button sizeToFit]; |
| 175 return button; | 179 return button; |
| 176 } | 180 } |
| 177 | 181 |
| 178 - (void)layout { | 182 - (void)layout { |
| 179 // First, construct the pieces of the bubble that have a fixed width: the | 183 // First, construct the pieces of the bubble that have a fixed width: the |
| 180 // heading, and the button strip (the learn more link, the action button, and | 184 // heading, and the button strip (the extra view (icon and/or (linked) text), |
| 181 // the dismiss button). | 185 // the action button, and the dismiss button). |
| 182 NSTextField* heading = | 186 NSTextField* heading = |
| 183 [self addTextFieldWithString:delegate_->GetHeadingText() | 187 [self addTextFieldWithString:delegate_->GetHeadingText() |
| 184 fontSize:13.0 | 188 fontSize:13.0 |
| 185 alignment:NSLeftTextAlignment]; | 189 alignment:NSLeftTextAlignment]; |
| 186 NSSize headingSize = [heading frame].size; | 190 NSSize headingSize = [heading frame].size; |
| 187 | 191 |
| 188 base::string16 learnMore = delegate_->GetLearnMoreButtonText(); | 192 std::unique_ptr<ToolbarActionsBarBubbleDelegate::ExtraViewInfo> |
| 189 NSSize learnMoreSize = NSZeroSize; | 193 extra_view_info = delegate_->GetExtraViewInfo(); |
| 190 if (!learnMore.empty()) { // The "learn more" link is optional. | 194 |
| 191 NSAttributedString* learnMoreString = | 195 int resource_id = extra_view_info->resource_id; |
| 192 [self attributedStringWithString:learnMore | 196 |
| 193 fontSize:13.0 | 197 NSSize extraViewIconSize = NSZeroSize; |
| 194 alignment:NSLeftTextAlignment]; | 198 if (resource_id != -1) { // The extra view icon is optional. |
| 195 learnMoreButton_ = | 199 NSImage* i = gfx::NSImageFromImageSkia( |
|
Devlin
2016/10/12 20:16:54
I think this would be more efficient as ResourceBu
catmullings
2016/10/14 23:16:46
Done.
| |
| 196 [[HyperlinkButtonCell buttonWithString:learnMoreString.string] retain]; | 200 *(ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
| 197 [learnMoreButton_ setTarget:self]; | 201 resource_id))); |
| 198 [learnMoreButton_ setAction:@selector(onButtonClicked:)]; | 202 NSRect frame = NSMakeRect(0, 0, i.size.width, i.size.height); |
| 199 [[[self window] contentView] addSubview:learnMoreButton_]; | 203 iconView_ = [[NSImageView alloc] initWithFrame:frame]; |
|
Devlin
2016/10/12 20:16:53
maybe init it with the image instead? https://dev
catmullings
2016/10/14 23:16:46
As discussed, disregarding this suggestion because
| |
| 200 [learnMoreButton_ sizeToFit]; | 204 [iconView_ |
| 201 learnMoreSize = NSMakeSize(NSWidth([learnMoreButton_ frame]), | 205 setImage:gfx::NSImageFromImageSkia(*( |
|
Devlin
2016/10/12 20:16:53
We should be able to avoid re-fetching the image.
catmullings
2016/10/14 23:16:46
Done.
| |
| 202 NSHeight([learnMoreButton_ frame])); | 206 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
| 207 resource_id)))]; | |
| 208 extraViewIconSize = i.size; | |
| 209 | |
| 210 [[[self window] contentView] addSubview:iconView_]; | |
| 211 } | |
| 212 | |
| 213 NSSize extraViewTextSize = NSZeroSize; | |
| 214 const base::string16& text = extra_view_info->text; | |
| 215 if (!text.empty()) { // The extra view text is optional. | |
| 216 if (extra_view_info->is_text_linked) { | |
| 217 NSAttributedString* linkString = | |
| 218 [self attributedStringWithString:text | |
| 219 fontSize:13.0 | |
| 220 alignment:NSLeftTextAlignment]; | |
| 221 link_ = [[HyperlinkButtonCell buttonWithString:linkString.string] retain]; | |
| 222 [link_ setTarget:self]; | |
| 223 [link_ setAction:@selector(onButtonClicked:)]; | |
| 224 [[[self window] contentView] addSubview:link_]; | |
| 225 [link_ sizeToFit]; | |
| 226 } else { | |
| 227 label_ = [self addTextFieldWithString:text | |
| 228 fontSize:13.0 | |
| 229 alignment:NSLeftTextAlignment]; | |
| 230 } | |
| 231 extraViewTextSize = | |
| 232 (label_) ? [label_ frame].size | |
|
Devlin
2016/10/12 20:16:53
no need for parens
catmullings
2016/10/14 23:16:46
Done.
| |
| 233 : NSMakeSize(NSWidth([link_ frame]), NSHeight([link_ frame])); | |
|
Devlin
2016/10/12 20:16:53
Why not use the size property on frame?
catmullings
2016/10/14 23:16:46
I can. I was following the patterns below for sett
catmullings
2016/10/14 23:16:46
Done.
| |
| 203 } | 234 } |
| 204 | 235 |
| 205 base::string16 cancelStr = delegate_->GetDismissButtonText(); | 236 base::string16 cancelStr = delegate_->GetDismissButtonText(); |
| 206 NSSize dismissButtonSize = NSZeroSize; | 237 NSSize dismissButtonSize = NSZeroSize; |
| 207 if (!cancelStr.empty()) { // A cancel/dismiss button is optional. | 238 if (!cancelStr.empty()) { // A cancel/dismiss button is optional. |
| 208 dismissButton_ = [self addButtonWithString:cancelStr]; | 239 dismissButton_ = [self addButtonWithString:cancelStr]; |
| 209 dismissButtonSize = | 240 dismissButtonSize = |
| 210 NSMakeSize(NSWidth([dismissButton_ frame]), | 241 NSMakeSize(NSWidth([dismissButton_ frame]), |
| 211 NSHeight([dismissButton_ frame])); | 242 NSHeight([dismissButton_ frame])); |
| 212 } | 243 } |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 223 DCHECK(actionButton_ || dismissButton_); | 254 DCHECK(actionButton_ || dismissButton_); |
| 224 CGFloat buttonStripHeight = | 255 CGFloat buttonStripHeight = |
| 225 std::max(actionButtonSize.height, dismissButtonSize.height); | 256 std::max(actionButtonSize.height, dismissButtonSize.height); |
| 226 | 257 |
| 227 const CGFloat kButtonPadding = 5.0; | 258 const CGFloat kButtonPadding = 5.0; |
| 228 CGFloat buttonStripWidth = 0; | 259 CGFloat buttonStripWidth = 0; |
| 229 if (actionButton_) | 260 if (actionButton_) |
| 230 buttonStripWidth += actionButtonSize.width + kButtonPadding; | 261 buttonStripWidth += actionButtonSize.width + kButtonPadding; |
| 231 if (dismissButton_) | 262 if (dismissButton_) |
| 232 buttonStripWidth += dismissButtonSize.width + kButtonPadding; | 263 buttonStripWidth += dismissButtonSize.width + kButtonPadding; |
| 233 if (learnMoreButton_) | 264 if (iconView_) |
| 234 buttonStripWidth += learnMoreSize.width + kButtonPadding; | 265 buttonStripWidth += extraViewIconSize.width + kButtonPadding; |
| 266 if (link_ || label_) | |
| 267 buttonStripWidth += extraViewTextSize.width + kButtonPadding; | |
| 235 | 268 |
| 236 CGFloat headingWidth = headingSize.width; | 269 CGFloat headingWidth = headingSize.width; |
| 237 CGFloat windowWidth = | 270 CGFloat windowWidth = |
| 238 std::max(std::max(kMinWidth, buttonStripWidth), headingWidth); | 271 std::max(std::max(kMinWidth, buttonStripWidth), headingWidth); |
| 239 | 272 |
| 240 NSTextField* content = | 273 NSTextField* content = |
| 241 [self addTextFieldWithString:delegate_->GetBodyText(anchoredToAction_) | 274 [self addTextFieldWithString:delegate_->GetBodyText(anchoredToAction_) |
| 242 fontSize:12.0 | 275 fontSize:12.0 |
| 243 alignment:NSLeftTextAlignment]; | 276 alignment:NSLeftTextAlignment]; |
| 244 [content setFrame:NSMakeRect(0, 0, windowWidth, 0)]; | 277 [content setFrame:NSMakeRect(0, 0, windowWidth, 0)]; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 280 currentMaxWidth -= (actionButtonSize.width + kButtonPadding); | 313 currentMaxWidth -= (actionButtonSize.width + kButtonPadding); |
| 281 } | 314 } |
| 282 if (dismissButton_) { | 315 if (dismissButton_) { |
| 283 [dismissButton_ setFrame:NSMakeRect( | 316 [dismissButton_ setFrame:NSMakeRect( |
| 284 currentMaxWidth - dismissButtonSize.width, | 317 currentMaxWidth - dismissButtonSize.width, |
| 285 currentHeight, | 318 currentHeight, |
| 286 dismissButtonSize.width, | 319 dismissButtonSize.width, |
| 287 dismissButtonSize.height)]; | 320 dismissButtonSize.height)]; |
| 288 currentMaxWidth -= (dismissButtonSize.width + kButtonPadding); | 321 currentMaxWidth -= (dismissButtonSize.width + kButtonPadding); |
| 289 } | 322 } |
| 290 if (learnMoreButton_) { | 323 if (label_ || link_) { |
| 291 CGFloat learnMoreHeight = | 324 CGFloat extraViewTextHeight = |
| 292 currentHeight + (buttonStripHeight - learnMoreSize.height) / 2.0; | 325 currentHeight + (buttonStripHeight - extraViewTextSize.height) / 2.0; |
| 293 [learnMoreButton_ setFrame:NSMakeRect(kHorizontalPadding, | 326 if (link_) { |
| 294 learnMoreHeight, | 327 [link_ setFrame:NSMakeRect(currentMaxWidth - extraViewTextSize.width, |
|
Devlin
2016/10/12 20:16:53
this would be cleaner if we define the frame above
catmullings
2016/10/14 23:16:46
Yup, much better. I'll do that.
catmullings
2016/10/14 23:16:46
Done.
| |
| 295 learnMoreSize.width, | 328 extraViewTextHeight, extraViewTextSize.width, |
| 296 learnMoreSize.height)]; | 329 extraViewTextSize.height)]; |
| 330 } else { | |
| 331 [label_ setFrame:NSMakeRect(currentMaxWidth - extraViewTextSize.width, | |
| 332 extraViewTextHeight, extraViewTextSize.width, | |
| 333 extraViewTextSize.height)]; | |
| 334 } | |
| 335 currentMaxWidth -= extraViewTextSize.width + kButtonPadding; | |
| 336 } | |
| 337 if (iconView_) { | |
| 338 CGFloat extraViewIconHeight = | |
| 339 currentHeight + (buttonStripHeight - extraViewIconSize.height) / 2.0; | |
| 340 | |
| 341 [iconView_ | |
| 342 setFrame:NSMakeRect(kHorizontalPadding, extraViewIconHeight, | |
| 343 extraViewIconSize.width, extraViewIconSize.height)]; | |
| 344 currentMaxWidth -= extraViewIconSize.width + kButtonPadding; | |
| 297 } | 345 } |
| 298 // Buttons have some inherit padding of their own, so we don't need quite as | 346 // Buttons have some inherit padding of their own, so we don't need quite as |
| 299 // much space here. | 347 // much space here. |
| 300 currentHeight += buttonStripHeight + kVerticalPadding / 2; | 348 currentHeight += buttonStripHeight + kVerticalPadding / 2; |
| 301 | 349 |
| 302 if (itemList_) { | 350 if (itemList_) { |
| 303 [itemList_ setFrame:NSMakeRect(kHorizontalPadding + kItemListIndentation, | 351 [itemList_ setFrame:NSMakeRect(kHorizontalPadding + kItemListIndentation, |
| 304 currentHeight, | 352 currentHeight, |
| 305 itemListSize.width, | 353 itemListSize.width, |
| 306 itemListSize.height)]; | 354 itemListSize.height)]; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 329 windowSize = [heading convertSize:windowSize toView:nil]; | 377 windowSize = [heading convertSize:windowSize toView:nil]; |
| 330 windowFrame.size = windowSize; | 378 windowFrame.size = windowSize; |
| 331 [[self window] setFrame:windowFrame display:YES]; | 379 [[self window] setFrame:windowFrame display:YES]; |
| 332 } | 380 } |
| 333 | 381 |
| 334 - (void)onButtonClicked:(id)sender { | 382 - (void)onButtonClicked:(id)sender { |
| 335 if (acknowledged_) | 383 if (acknowledged_) |
| 336 return; | 384 return; |
| 337 ToolbarActionsBarBubbleDelegate::CloseAction action = | 385 ToolbarActionsBarBubbleDelegate::CloseAction action = |
| 338 ToolbarActionsBarBubbleDelegate::CLOSE_EXECUTE; | 386 ToolbarActionsBarBubbleDelegate::CLOSE_EXECUTE; |
| 339 if (learnMoreButton_ && sender == learnMoreButton_) { | 387 if (link_ && sender == link_) { |
| 340 action = ToolbarActionsBarBubbleDelegate::CLOSE_LEARN_MORE; | 388 action = ToolbarActionsBarBubbleDelegate::CLOSE_LINK; |
| 341 } else if (dismissButton_ && sender == dismissButton_) { | 389 } else if (dismissButton_ && sender == dismissButton_) { |
| 342 action = ToolbarActionsBarBubbleDelegate::CLOSE_DISMISS_USER_ACTION; | 390 action = ToolbarActionsBarBubbleDelegate::CLOSE_DISMISS_USER_ACTION; |
| 343 } else { | 391 } else { |
| 344 DCHECK_EQ(sender, actionButton_); | 392 DCHECK_EQ(sender, actionButton_); |
| 345 action = ToolbarActionsBarBubbleDelegate::CLOSE_EXECUTE; | 393 action = ToolbarActionsBarBubbleDelegate::CLOSE_EXECUTE; |
| 346 } | 394 } |
| 347 acknowledged_ = YES; | 395 acknowledged_ = YES; |
| 348 delegate_->OnBubbleClosed(action); | 396 delegate_->OnBubbleClosed(action); |
| 349 [self close]; | 397 [self close]; |
| 350 } | 398 } |
| 351 | 399 |
| 352 @end | 400 @end |
| OLD | NEW |