OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/extension_install_view_controller.h" | 5 #import "chrome/browser/ui/cocoa/extensions/extension_install_view_controller.h" |
6 | 6 |
7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
8 #include "base/i18n/rtl.h" | 8 #include "base/i18n/rtl.h" |
9 #include "base/mac/bundle_locations.h" | 9 #include "base/mac/bundle_locations.h" |
10 #include "base/mac/mac_util.h" | 10 #include "base/mac/mac_util.h" |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
85 | 85 |
86 namespace { | 86 namespace { |
87 | 87 |
88 // Padding above the warnings separator, we must also subtract this when hiding | 88 // Padding above the warnings separator, we must also subtract this when hiding |
89 // it. | 89 // it. |
90 const CGFloat kWarningsSeparatorPadding = 14; | 90 const CGFloat kWarningsSeparatorPadding = 14; |
91 | 91 |
92 // The left padding for the link cell. | 92 // The left padding for the link cell. |
93 const CGFloat kLinkCellPaddingLeft = 3; | 93 const CGFloat kLinkCellPaddingLeft = 3; |
94 | 94 |
95 // Size of individual extension icons for bundle installs. | |
96 const CGFloat kExtensionIconSize = 32; | |
97 | |
95 // Maximum height we will adjust controls to when trying to accomodate their | 98 // Maximum height we will adjust controls to when trying to accomodate their |
96 // contents. | 99 // contents. |
97 const CGFloat kMaxControlHeight = 250; | 100 const CGFloat kMaxControlHeight = 250; |
98 | 101 |
99 NSString* const kTitleKey = @"title"; | 102 NSString* const kTitleKey = @"title"; |
100 NSString* const kChildrenKey = @"children"; | 103 NSString* const kChildrenKey = @"children"; |
101 NSString* const kCellAttributesKey = @"cellAttributes"; | 104 NSString* const kCellAttributesKey = @"cellAttributes"; |
102 NSString* const kPermissionsDetailIndex = @"permissionsDetailIndex"; | 105 NSString* const kPermissionsDetailIndex = @"permissionsDetailIndex"; |
103 NSString* const kPermissionsDetailType = @"permissionsDetailType"; | 106 NSString* const kPermissionsDetailType = @"permissionsDetailType"; |
104 | 107 |
108 CGFloat ComputeDesiredControlHeight(NSControl* control) { | |
Alexei Svitkine (slow)
2015/04/21 16:40:52
Add a comment above.
Marc Treib
2015/04/22 08:09:16
Done.
| |
109 NSRect rect = [control frame]; | |
110 rect.size.height = kMaxControlHeight; | |
111 return [[control cell] cellSizeForBounds:rect].height; | |
112 } | |
113 | |
105 // Adjust the |control|'s height so that its content is not clipped. | 114 // Adjust the |control|'s height so that its content is not clipped. |
106 // This also adds the change in height to the |totalOffset| and shifts the | 115 // This also adds the change in height to the |totalOffset| and shifts the |
107 // control down by that amount. | 116 // control down by that amount. |
108 void OffsetControlVerticallyToFitContent(NSControl* control, | 117 void OffsetControlVerticallyToFitContent(NSControl* control, |
109 CGFloat* totalOffset) { | 118 CGFloat* totalOffset) { |
110 // Adjust the control's height so that its content is not clipped. | 119 // Adjust the control's height so that its content is not clipped. |
111 NSRect currentRect = [control frame]; | 120 NSRect currentRect = [control frame]; |
112 NSRect fitRect = currentRect; | 121 CGFloat desiredHeight = ComputeDesiredControlHeight(control); |
113 fitRect.size.height = kMaxControlHeight; | |
114 CGFloat desiredHeight = [[control cell] cellSizeForBounds:fitRect].height; | |
115 CGFloat offset = desiredHeight - NSHeight(currentRect); | 122 CGFloat offset = desiredHeight - NSHeight(currentRect); |
116 | 123 |
117 [control setFrameSize:NSMakeSize(NSWidth(currentRect), | 124 [control setFrameSize:NSMakeSize(NSWidth(currentRect), |
118 NSHeight(currentRect) + offset)]; | 125 NSHeight(currentRect) + offset)]; |
119 | 126 |
120 *totalOffset += offset; | 127 *totalOffset += offset; |
121 | 128 |
122 // Move the control vertically by the new total offset. | 129 // Move the control vertically by the new total offset. |
123 NSPoint origin = [control frame].origin; | 130 NSPoint origin = [control frame].origin; |
124 origin.y -= *totalOffset; | 131 origin.y -= *totalOffset; |
125 [control setFrameOrigin:origin]; | 132 [control setFrameOrigin:origin]; |
126 } | 133 } |
127 | 134 |
135 // Adjust the |view|'s height so that its subviews are not clipped. | |
136 // This also adds the change in height to the |totalOffset| and shifts the | |
137 // control down by that amount. | |
138 void OffsetViewVerticallyToFitContent(NSView* view, CGFloat* totalOffset) { | |
139 // Adjust the view's height so that its subviews are not clipped. | |
140 CGFloat desiredHeight = 0; | |
141 for (NSView* subview in [view subviews]) { | |
142 int requiredHeight = NSMaxY([subview frame]); | |
143 if (requiredHeight > desiredHeight) { | |
Alexei Svitkine (slow)
2015/04/21 16:40:52
Nit: No {}'s
Marc Treib
2015/04/22 08:09:16
Done.
| |
144 desiredHeight = requiredHeight; | |
145 } | |
146 } | |
147 NSRect currentRect = [view frame]; | |
148 CGFloat offset = desiredHeight - NSHeight(currentRect); | |
149 | |
150 [view setFrameSize:NSMakeSize(NSWidth(currentRect), | |
151 NSHeight(currentRect) + offset)]; | |
152 | |
153 *totalOffset += offset; | |
154 | |
155 // Move the view vertically by the new total offset. | |
156 NSPoint origin = [view frame].origin; | |
157 origin.y -= *totalOffset; | |
158 [view setFrameOrigin:origin]; | |
159 } | |
160 | |
128 // Gets the desired height of |outlineView|. Simply using the view's frame | 161 // Gets the desired height of |outlineView|. Simply using the view's frame |
129 // doesn't work if an animation is pending. | 162 // doesn't work if an animation is pending. |
130 CGFloat GetDesiredOutlineViewHeight(NSOutlineView* outlineView) { | 163 CGFloat GetDesiredOutlineViewHeight(NSOutlineView* outlineView) { |
131 CGFloat height = 0; | 164 CGFloat height = 0; |
132 for (NSInteger i = 0; i < [outlineView numberOfRows]; ++i) | 165 for (NSInteger i = 0; i < [outlineView numberOfRows]; ++i) |
133 height += NSHeight([outlineView rectOfRow:i]); | 166 height += NSHeight([outlineView rectOfRow:i]); |
134 return height; | 167 return height; |
135 } | 168 } |
136 | 169 |
137 void OffsetOutlineViewVerticallyToFitContent(NSOutlineView* outlineView, | 170 void OffsetOutlineViewVerticallyToFitContent(NSOutlineView* outlineView, |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
263 prompt_->AppendRatingStars(AppendRatingStarsShim, self); | 296 prompt_->AppendRatingStars(AppendRatingStarsShim, self); |
264 [ratingCountField_ setStringValue:base::SysUTF16ToNSString( | 297 [ratingCountField_ setStringValue:base::SysUTF16ToNSString( |
265 prompt_->GetRatingCount())]; | 298 prompt_->GetRatingCount())]; |
266 [userCountField_ setStringValue:base::SysUTF16ToNSString( | 299 [userCountField_ setStringValue:base::SysUTF16ToNSString( |
267 prompt_->GetUserCount())]; | 300 prompt_->GetUserCount())]; |
268 [[storeLinkButton_ cell] setUnderlineOnHover:YES]; | 301 [[storeLinkButton_ cell] setUnderlineOnHover:YES]; |
269 [[storeLinkButton_ cell] setTextColor: | 302 [[storeLinkButton_ cell] setTextColor: |
270 gfx::SkColorToCalibratedNSColor(chrome_style::GetLinkColor())]; | 303 gfx::SkColorToCalibratedNSColor(chrome_style::GetLinkColor())]; |
271 } | 304 } |
272 | 305 |
273 // The bundle install dialog has no icon. | 306 [iconView_ setImage:prompt_->icon().ToNSImage()]; |
274 if (![self isBundleInstall]) | |
275 [iconView_ setImage:prompt_->icon().ToNSImage()]; | |
276 | 307 |
277 // The dialog is laid out in the NIB exactly how we want it assuming that | 308 // The dialog is laid out in the NIB exactly how we want it assuming that |
278 // each label fits on one line. However, for each label, we want to allow | 309 // each label fits on one line. However, for each label, we want to allow |
279 // wrapping onto multiple lines. So we accumulate an offset by measuring how | 310 // wrapping onto multiple lines. So we accumulate an offset by measuring how |
280 // big each label wants to be, and comparing it to how big it actually is. | 311 // big each label wants to be, and comparing it to how big it actually is. |
281 // Then we shift each label down and resize by the appropriate amount, then | 312 // Then we shift each label down and resize by the appropriate amount, then |
282 // finally resize the window. | 313 // finally resize the window. |
283 CGFloat totalOffset = 0.0; | 314 CGFloat totalOffset = 0.0; |
284 | 315 |
285 OffsetControlVerticallyToFitContent(titleField_, &totalOffset); | 316 OffsetControlVerticallyToFitContent(titleField_, &totalOffset); |
(...skipping 16 matching lines...) Expand all Loading... | |
302 NSMaxX(okButtonRect) - NSWidth(cancelButtonRect); | 333 NSMaxX(okButtonRect) - NSWidth(cancelButtonRect); |
303 [cancelButton_ setFrame:cancelButtonRect]; | 334 [cancelButton_ setFrame:cancelButtonRect]; |
304 } | 335 } |
305 buttonDelta = [GTMUILocalizerAndLayoutTweaker sizeToFitView:cancelButton_]; | 336 buttonDelta = [GTMUILocalizerAndLayoutTweaker sizeToFitView:cancelButton_]; |
306 if (buttonDelta.width) { | 337 if (buttonDelta.width) { |
307 [cancelButton_ setFrame:NSOffsetRect([cancelButton_ frame], | 338 [cancelButton_ setFrame:NSOffsetRect([cancelButton_ frame], |
308 -buttonDelta.width, 0)]; | 339 -buttonDelta.width, 0)]; |
309 } | 340 } |
310 | 341 |
311 if ([self isBundleInstall]) { | 342 if ([self isBundleInstall]) { |
312 // We display the list of extension names as a simple text string, seperated | |
313 // by newlines. | |
314 BundleInstaller::ItemList items = prompt_->bundle()->GetItemsWithState( | 343 BundleInstaller::ItemList items = prompt_->bundle()->GetItemsWithState( |
315 BundleInstaller::Item::STATE_PENDING); | 344 BundleInstaller::Item::STATE_PENDING); |
316 | 345 |
317 NSMutableString* joinedItems = [NSMutableString string]; | 346 const CGFloat titleWidth = |
318 for (size_t i = 0; i < items.size(); ++i) { | 347 [itemsField_ frame].size.width - kExtensionIconSize; |
319 if (i > 0) | 348 CGFloat offset = 0; |
320 [joinedItems appendString:@"\n"]; | 349 // Go over the items backwards, since Cocoa coords go from the bottom up. |
321 [joinedItems appendString:base::SysUTF16ToNSString( | 350 for (size_t i = items.size(); i > 0; --i) { |
322 items[i].GetNameForDisplay())]; | 351 const BundleInstaller::Item& item = items[i - 1]; |
352 | |
353 NSString* title = base::SysUTF16ToNSString(item.GetNameForDisplay()); | |
354 NSRect titleFrame = NSMakeRect(kExtensionIconSize, offset, titleWidth, 0); | |
355 base::scoped_nsobject<NSTextField> titleView( | |
356 [[NSTextField alloc] initWithFrame:titleFrame]); | |
357 [titleView setBordered:NO]; | |
358 [titleView setEditable:NO]; | |
359 [titleView setStringValue:title]; | |
360 | |
361 titleFrame.size.height = ComputeDesiredControlHeight(titleView); | |
362 | |
363 NSRect iconFrame = | |
364 NSMakeRect(0, offset, kExtensionIconSize, kExtensionIconSize); | |
365 | |
366 // Vertically center-align icon and title. | |
367 CGFloat align = (iconFrame.size.height - titleFrame.size.height) / 2; | |
368 if (align > 0) | |
369 titleFrame.origin.y += align; | |
370 else | |
371 iconFrame.origin.y -= align; | |
372 | |
373 [titleView setFrame:titleFrame]; | |
374 | |
375 gfx::ImageSkia skiaImage = gfx::ImageSkia::CreateFrom1xBitmap(item.icon); | |
376 NSImage* image = gfx::NSImageFromImageSkiaWithColorSpace( | |
377 skiaImage, base::mac::GetSystemColorSpace()); | |
378 base::scoped_nsobject<NSImageView> iconView( | |
379 [[NSImageView alloc] initWithFrame:iconFrame]); | |
380 [iconView setImage:image]; | |
381 | |
382 [itemsField_ addSubview:iconView]; | |
383 [itemsField_ addSubview:titleView]; | |
384 | |
385 offset = NSMaxY(NSUnionRect(titleFrame, iconFrame)); | |
323 } | 386 } |
324 [itemsField_ setStringValue:joinedItems]; | |
325 | 387 |
326 // Adjust the controls to fit the list of extensions. | 388 // Adjust the view to fit the list of extensions. |
327 OffsetControlVerticallyToFitContent(itemsField_, &totalOffset); | 389 OffsetViewVerticallyToFitContent(itemsField_, &totalOffset); |
328 } | 390 } |
329 | 391 |
330 // If there are any warnings, retained devices or retained files, then we | 392 // If there are any warnings, retained devices or retained files, then we |
331 // have to do some special layout. | 393 // have to do some special layout. |
332 if (prompt_->ShouldShowPermissions() || prompt_->GetRetainedFileCount() > 0) { | 394 if (prompt_->ShouldShowPermissions() || prompt_->GetRetainedFileCount() > 0) { |
333 NSSize spacing = [outlineView_ intercellSpacing]; | 395 NSSize spacing = [outlineView_ intercellSpacing]; |
334 spacing.width += 2; | 396 spacing.width += 2; |
335 spacing.height += 2; | 397 spacing.height += 2; |
336 [outlineView_ setIntercellSpacing:spacing]; | 398 [outlineView_ setIntercellSpacing:spacing]; |
337 [[[[outlineView_ tableColumns] objectAtIndex:0] dataCell] setWraps:YES]; | 399 [[[[outlineView_ tableColumns] objectAtIndex:0] dataCell] setWraps:YES]; |
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
814 } | 876 } |
815 | 877 |
816 - (void)accessibilityPerformAction:(NSString*)action { | 878 - (void)accessibilityPerformAction:(NSString*)action { |
817 if ([action isEqualToString:NSAccessibilityPressAction]) | 879 if ([action isEqualToString:NSAccessibilityPressAction]) |
818 [self handleLinkClicked]; | 880 [self handleLinkClicked]; |
819 else | 881 else |
820 [super accessibilityPerformAction:action]; | 882 [super accessibilityPerformAction:action]; |
821 } | 883 } |
822 | 884 |
823 @end | 885 @end |
OLD | NEW |