Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_dialog_controller. h" | 5 #import "chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller. h" |
| 6 | 6 |
| 7 #include "base/mac/mac_util.h" | 7 #include "base/mac/mac_util.h" |
| 8 #include "base/memory/scoped_nsobject.h" | |
| 8 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 9 #include "base/sys_string_conversions.h" | 10 #include "base/sys_string_conversions.h" |
| 10 #include "base/utf_string_conversions.h" | 11 #include "base/utf_string_conversions.h" |
| 11 #include "chrome/browser/extensions/extension_install_dialog.h" | 12 #include "chrome/browser/extensions/extension_install_dialog.h" |
| 12 #include "chrome/browser/ui/browser.h" | 13 #include "chrome/browser/ui/browser.h" |
| 13 #include "chrome/browser/ui/browser_list.h" | 14 #include "chrome/browser/ui/browser_list.h" |
| 14 #include "chrome/browser/ui/browser_window.h" | 15 #include "chrome/browser/ui/browser_window.h" |
| 15 #include "chrome/common/extensions/extension.h" | 16 #include "chrome/common/extensions/extension.h" |
| 16 #include "grit/generated_resources.h" | 17 #include "grit/generated_resources.h" |
| 17 #include "skia/ext/skia_utils_mac.h" | 18 #include "skia/ext/skia_utils_mac.h" |
| 18 #include "ui/base/l10n/l10n_util.h" | 19 #include "ui/base/l10n/l10n_util.h" |
| 19 #include "ui/base/l10n/l10n_util_mac.h" | 20 #include "ui/base/l10n/l10n_util_mac.h" |
| 20 | 21 |
| 22 @interface ExtensionInstallDialogController () | |
| 23 - (bool)isInlineInstall; | |
| 24 - (void)appendRatingStar:(const SkBitmap*)skiaImage; | |
| 25 @end | |
| 26 | |
| 21 namespace { | 27 namespace { |
| 22 | 28 |
| 29 // Padding above the warnings separator, we must also subtract this when hiding | |
| 30 // it. | |
| 31 const CGFloat kWarningsSeparatorPadding = 14; | |
| 32 | |
| 23 // Maximum height we will adjust controls to when trying to accomodate their | 33 // Maximum height we will adjust controls to when trying to accomodate their |
| 24 // contents. | 34 // contents. |
| 25 const CGFloat kMaxControlHeight = 400; | 35 const CGFloat kMaxControlHeight = 400; |
| 26 | 36 |
| 27 // Adjust a control's height so that its content its not clipped. Returns the | 37 // Adjust a control's height so that its content its not clipped. Returns the |
| 28 // amount the control's height had to be adjusted. | 38 // amount the control's height had to be adjusted. |
| 29 CGFloat AdjustControlHeightToFitContent(NSControl* control) { | 39 CGFloat AdjustControlHeightToFitContent(NSControl* control) { |
| 30 NSRect currentRect = [control frame]; | 40 NSRect currentRect = [control frame]; |
| 31 NSRect fitRect = currentRect; | 41 NSRect fitRect = currentRect; |
| 32 fitRect.size.height = kMaxControlHeight; | 42 fitRect.size.height = kMaxControlHeight; |
| 33 CGFloat desiredHeight = [[control cell] cellSizeForBounds:fitRect].height; | 43 CGFloat desiredHeight = [[control cell] cellSizeForBounds:fitRect].height; |
| 34 CGFloat offset = desiredHeight - currentRect.size.height; | 44 CGFloat offset = desiredHeight - currentRect.size.height; |
| 35 | 45 |
| 36 [control setFrameSize:NSMakeSize(currentRect.size.width, | 46 [control setFrameSize:NSMakeSize(currentRect.size.width, |
| 37 currentRect.size.height + offset)]; | 47 currentRect.size.height + offset)]; |
| 38 return offset; | 48 return offset; |
| 39 } | 49 } |
| 40 | 50 |
| 41 // Moves the control vertically by the specified amount. | 51 // Moves the control vertically by the specified amount. |
| 42 void OffsetControlVertically(NSControl* control, CGFloat amount) { | 52 void OffsetControlVertically(NSControl* control, CGFloat amount) { |
| 43 NSPoint origin = [control frame].origin; | 53 NSPoint origin = [control frame].origin; |
| 44 origin.y += amount; | 54 origin.y += amount; |
| 45 [control setFrameOrigin:origin]; | 55 [control setFrameOrigin:origin]; |
| 46 } | 56 } |
| 47 | 57 |
| 58 void AppendRatingStarsShim(const SkBitmap* skiaImage, | |
| 59 ExtensionInstallDialogController* controller) { | |
| 60 [controller appendRatingStar:skiaImage]; | |
| 61 } | |
| 62 | |
| 48 } | 63 } |
| 49 | 64 |
| 50 @implementation ExtensionInstallDialogController | 65 @implementation ExtensionInstallDialogController |
| 51 | 66 |
| 52 @synthesize iconView = iconView_; | 67 @synthesize iconView = iconView_; |
| 53 @synthesize titleField = titleField_; | 68 @synthesize titleField = titleField_; |
| 54 @synthesize subtitleField = subtitleField_; | 69 @synthesize subtitleField = subtitleField_; |
| 55 @synthesize warningsField = warningsField_; | 70 @synthesize warningsField = warningsField_; |
| 56 @synthesize warningsBox= warningsBox_; | |
| 57 @synthesize cancelButton = cancelButton_; | 71 @synthesize cancelButton = cancelButton_; |
| 58 @synthesize okButton = okButton_; | 72 @synthesize okButton = okButton_; |
| 73 @synthesize warningsSeparator = warningsSeparator_; | |
| 74 @synthesize ratingStars = ratingStars_; | |
| 75 @synthesize ratingCountField = ratingCountField_; | |
| 76 @synthesize userCountField = userCountField_; | |
| 59 | 77 |
| 60 - (id)initWithParentWindow:(NSWindow*)window | 78 - (id)initWithParentWindow:(NSWindow*)window |
| 61 profile:(Profile*)profile | 79 profile:(Profile*)profile |
| 62 extension:(const Extension*)extension | 80 extension:(const Extension*)extension |
| 63 delegate:(ExtensionInstallUI::Delegate*)delegate | 81 delegate:(ExtensionInstallUI::Delegate*)delegate |
| 64 icon:(SkBitmap*)icon | 82 icon:(SkBitmap*)icon |
| 65 prompt:(const ExtensionInstallUI::Prompt&)prompt { | 83 prompt:(const ExtensionInstallUI::Prompt&)prompt { |
| 84 prompt_.reset(new ExtensionInstallUI::Prompt(prompt)); | |
|
Nico
2011/09/05 22:59:17
You shouldn't write member variables before "self
Mihai Parparita -not on Chrome
2011/09/06 00:54:11
Moved initialization of prompt_ to be after the [s
| |
| 66 NSString* nibpath = nil; | 85 NSString* nibpath = nil; |
| 67 | 86 |
| 68 // We use a different XIB in the case of no permission warnings, that is a | 87 // We use a different XIB in the case of inline installs or no permission |
| 69 // little bit more nicely laid out. | 88 // warnings, that respectively show webstore ratings data and are a more |
| 70 if (prompt.GetPermissionCount() == 0) { | 89 // nicely laid out. |
| 90 if ([self isInlineInstall]) { | |
| 91 nibpath = [base::mac::MainAppBundle() | |
| 92 pathForResource:@"ExtensionInstallPromptInline" | |
| 93 ofType:@"nib"]; | |
| 94 } else if (prompt.GetPermissionCount() == 0) { | |
| 71 nibpath = [base::mac::MainAppBundle() | 95 nibpath = [base::mac::MainAppBundle() |
| 72 pathForResource:@"ExtensionInstallPromptNoWarnings" | 96 pathForResource:@"ExtensionInstallPromptNoWarnings" |
| 73 ofType:@"nib"]; | 97 ofType:@"nib"]; |
| 74 } else { | 98 } else { |
| 75 nibpath = [base::mac::MainAppBundle() | 99 nibpath = [base::mac::MainAppBundle() |
| 76 pathForResource:@"ExtensionInstallPrompt" | 100 pathForResource:@"ExtensionInstallPrompt" |
| 77 ofType:@"nib"]; | 101 ofType:@"nib"]; |
| 78 } | 102 } |
| 79 | 103 |
| 80 if ((self = [super initWithWindowNibPath:nibpath owner:self])) { | 104 if ((self = [super initWithWindowNibPath:nibpath owner:self])) { |
| 81 parentWindow_ = window; | 105 parentWindow_ = window; |
| 82 profile_ = profile; | 106 profile_ = profile; |
| 83 icon_ = *icon; | 107 icon_ = *icon; |
| 84 delegate_ = delegate; | 108 delegate_ = delegate; |
| 85 | 109 extension_ = extension; |
| 86 title_.reset([base::SysUTF16ToNSString( | |
| 87 prompt.GetHeading(extension->name())) retain]); | |
| 88 subtitle_.reset([base::SysUTF16ToNSString( | |
| 89 prompt.GetPermissionsHeader()) retain]); | |
| 90 button_.reset([base::SysUTF16ToNSString( | |
| 91 prompt.GetAcceptButtonLabel()) retain]); | |
| 92 NSString* cancel_button_label = prompt.HasAbortButtonLabel() ? | |
| 93 base::SysUTF16ToNSString(prompt.GetAbortButtonLabel()) : | |
| 94 l10n_util::GetNSString(IDS_CANCEL); | |
| 95 cancel_button_.reset([cancel_button_label retain]); | |
| 96 | |
| 97 // We display the permission warnings as a simple text string, separated by | |
| 98 // newlines. | |
| 99 if (prompt.GetPermissionCount()) { | |
| 100 string16 joined_warnings; | |
| 101 for (size_t i = 0; i < prompt.GetPermissionCount(); ++i) { | |
| 102 if (i > 0) | |
| 103 joined_warnings += UTF8ToUTF16("\n\n"); | |
| 104 | |
| 105 joined_warnings += prompt.GetPermission(i); | |
| 106 } | |
| 107 | |
| 108 warnings_.reset( | |
| 109 [base::SysUTF16ToNSString(joined_warnings) retain]); | |
| 110 } | |
| 111 } | 110 } |
| 112 return self; | 111 return self; |
| 113 } | 112 } |
| 114 | 113 |
| 115 - (void)runAsModalSheet { | 114 - (void)runAsModalSheet { |
| 116 [NSApp beginSheet:[self window] | 115 [NSApp beginSheet:[self window] |
| 117 modalForWindow:parentWindow_ | 116 modalForWindow:parentWindow_ |
| 118 modalDelegate:self | 117 modalDelegate:self |
| 119 didEndSelector:@selector(didEndSheet:returnCode:contextInfo:) | 118 didEndSelector:@selector(didEndSheet:returnCode:contextInfo:) |
| 120 contextInfo:nil]; | 119 contextInfo:nil]; |
| 121 } | 120 } |
| 122 | 121 |
| 122 - (IBAction)storeLinkClicked:(id)sender { | |
| 123 GURL store_url( | |
| 124 extension_urls::GetWebstoreItemDetailURLPrefix() + extension_->id()); | |
| 125 BrowserList::GetLastActiveWithProfile(profile_)-> | |
| 126 OpenURL(store_url, GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK); | |
| 127 | |
| 128 delegate_->InstallUIAbort(true); | |
|
Nico
2011/09/05 22:59:17
nit: Make it more clear what "true" means here, ei
Mihai Parparita -not on Chrome
2011/09/06 00:54:11
Done.
| |
| 129 [NSApp endSheet:[self window]]; | |
|
Nico
2011/09/05 22:59:17
Window-modal sheets are not cool. Have you thought
Mihai Parparita -not on Chrome
2011/09/06 00:54:11
Tab-modal dialogs sound like a good idea for a fol
Nico
2011/09/06 01:04:00
Yes. Thanks. (Maybe file a bug and add the bug #
Mihai Parparita -not on Chrome
2011/09/06 01:25:59
Filed http://crbug.com/95455
| |
| 130 } | |
| 131 | |
| 123 - (IBAction)cancel:(id)sender { | 132 - (IBAction)cancel:(id)sender { |
| 124 delegate_->InstallUIAbort(true); | 133 delegate_->InstallUIAbort(true); |
| 125 [NSApp endSheet:[self window]]; | 134 [NSApp endSheet:[self window]]; |
| 126 } | 135 } |
| 127 | 136 |
| 128 - (IBAction)ok:(id)sender { | 137 - (IBAction)ok:(id)sender { |
| 129 delegate_->InstallUIProceed(); | 138 delegate_->InstallUIProceed(); |
| 130 [NSApp endSheet:[self window]]; | 139 [NSApp endSheet:[self window]]; |
| 131 } | 140 } |
| 132 | 141 |
| 133 - (void)awakeFromNib { | 142 - (void)awakeFromNib { |
| 134 [titleField_ setStringValue:title_.get()]; | 143 // Make sure we're the window's delegate as set in the nib. |
| 135 [subtitleField_ setStringValue:subtitle_.get()]; | 144 DCHECK_EQ(self, static_cast<ExtensionInstallDialogController*>( |
| 136 [okButton_ setTitle:button_.get()]; | 145 [[self window] delegate])); |
| 137 [cancelButton_ setTitle:cancel_button_.get()]; | 146 |
| 147 // Set control labels | |
|
Nico
2011/09/05 22:59:17
nit: trailing period.
Mihai Parparita -not on Chrome
2011/09/06 00:54:11
Done.
| |
| 148 [titleField_ setStringValue:base::SysUTF16ToNSString( | |
| 149 prompt_->GetHeading(extension_->name()))]; | |
| 150 [okButton_ setTitle:base::SysUTF16ToNSString( | |
| 151 prompt_->GetAcceptButtonLabel())]; | |
| 152 [cancelButton_ setTitle:prompt_->HasAbortButtonLabel() ? | |
| 153 base::SysUTF16ToNSString(prompt_->GetAbortButtonLabel()) : | |
| 154 l10n_util::GetNSString(IDS_CANCEL)]; | |
|
Nico
2011/09/05 22:59:17
Do you need to resize the controls to make them ad
Mihai Parparita -not on Chrome
2011/09/06 00:54:11
It looks like there's no autosizing going on (e.g.
Nico
2011/09/06 01:04:00
This is sometimes doable all in the xib file witho
Mihai Parparita -not on Chrome
2011/09/06 01:25:59
Yeah, I looked into that, but since I set the butt
| |
| 155 if ([self isInlineInstall]) { | |
| 156 prompt_->AppendRatingStars( | |
| 157 reinterpret_cast<ExtensionInstallUI::Prompt::StarAppender>( | |
| 158 AppendRatingStarsShim), | |
|
Nico
2011/09/05 22:59:17
You need this cast because AppendRatingStarsShim d
Mihai Parparita -not on Chrome
2011/09/06 00:54:11
Done.
| |
| 159 self); | |
| 160 [ratingCountField_ setStringValue:base::SysUTF16ToNSString( | |
| 161 prompt_->GetRatingCount())]; | |
| 162 [userCountField_ setStringValue:base::SysUTF16ToNSString( | |
| 163 prompt_->GetUserCount())]; | |
| 164 } | |
| 138 | 165 |
| 139 NSImage* image = gfx::SkBitmapToNSImage(icon_); | 166 NSImage* image = gfx::SkBitmapToNSImage(icon_); |
| 140 [iconView_ setImage:image]; | 167 [iconView_ setImage:image]; |
| 141 | 168 |
| 142 // Reisze |titleField_| to fit title | 169 // Resize |titleField_| to fit title |
| 143 CGFloat originalTitleWidth = [titleField_ frame].size.width; | 170 CGFloat originalTitleWidth = [titleField_ frame].size.width; |
| 144 [titleField_ sizeToFit]; | 171 [titleField_ sizeToFit]; |
| 145 CGFloat newTitleWidth = [titleField_ frame].size.width; | 172 CGFloat newTitleWidth = [titleField_ frame].size.width; |
| 146 if (newTitleWidth > originalTitleWidth) { | 173 if (newTitleWidth > originalTitleWidth) { |
| 147 NSRect frame = [[self window] frame]; | 174 NSRect frame = [[self window] frame]; |
| 148 frame.size.width += newTitleWidth - originalTitleWidth; | 175 frame.size.width += newTitleWidth - originalTitleWidth; |
| 149 [[self window] setFrame:frame display:NO]; | 176 [[self window] setFrame:frame display:NO]; |
| 150 } | 177 } |
| 151 | 178 |
| 152 // Make sure we're the window's delegate as set in the nib. | 179 CGFloat totalOffset = 0.0; |
| 153 DCHECK_EQ(self, static_cast<ExtensionInstallDialogController*>( | 180 // If there are any warnings, then we have to do some special layout. |
| 154 [[self window] delegate])); | 181 if (prompt_->GetPermissionCount() > 0) { |
| 182 [subtitleField_ setStringValue:base::SysUTF16ToNSString( | |
| 183 prompt_->GetPermissionsHeader())]; | |
| 155 | 184 |
| 156 // If there are any warnings, then we have to do some special layout. | 185 // We display the permission warnings as a simple text string, separated by |
| 157 if ([warnings_.get() length] > 0) { | 186 // newlines. |
| 158 [warningsField_ setStringValue:warnings_.get()]; | 187 string16 joined_warnings; |
|
Nico
2011/09/05 22:59:17
nit: variables objc methods have camelCaps names (
Mihai Parparita -not on Chrome
2011/09/06 00:54:11
Leftover from past version of the file, fixed.
| |
| 188 for (size_t i = 0; i < prompt_->GetPermissionCount(); ++i) { | |
| 189 if (i > 0) | |
| 190 joined_warnings += UTF8ToUTF16("\n"); | |
|
Nico
2011/09/05 22:59:17
nit: You could go from utf8 to nsstring directly (
Mihai Parparita -not on Chrome
2011/09/06 00:54:11
Done.
| |
| 191 | |
| 192 joined_warnings += prompt_->GetPermission(i); | |
| 193 } | |
| 194 [warningsField_ setStringValue:base::SysUTF16ToNSString(joined_warnings)]; | |
| 159 | 195 |
| 160 // The dialog is laid out in the NIB exactly how we want it assuming that | 196 // The dialog is laid out in the NIB exactly how we want it assuming that |
| 161 // each label fits on one line. However, for each label, we want to allow | 197 // each label fits on one line. However, for each label, we want to allow |
| 162 // wrapping onto multiple lines. So we accumulate an offset by measuring how | 198 // wrapping onto multiple lines. So we accumulate an offset by measuring how |
| 163 // big each label wants to be, and comparing it to how bit it actually is. | 199 // big each label wants to be, and comparing it to how big it actually is. |
| 164 // Then we shift each label down and resize by the appropriate amount, then | 200 // Then we shift each label down and resize by the appropriate amount, then |
| 165 // finally resize the window. | 201 // finally resize the window. |
| 166 CGFloat totalOffset = 0.0; | |
| 167 | 202 |
| 168 // Text fields. | 203 // Additionally, in the store version of the dialog the icon extends past |
| 169 totalOffset += AdjustControlHeightToFitContent(titleField_); | 204 // the one-line version of the permission field. Therefore when increasing |
| 170 OffsetControlVertically(titleField_, -totalOffset); | 205 // the window size for multi-line permissions we don't have to add the full |
| 206 // | |
|
Nico
2011/09/05 22:59:17
you accidentally the rest of the comment
Nico
2011/09/06 01:04:00
still missing
Mihai Parparita -not on Chrome
2011/09/06 01:25:59
Done.
| |
| 207 CGFloat warningsGrowthSlack = 0; | |
| 208 if ([warningsField_ frame].origin.y > [iconView_ frame].origin.y) { | |
| 209 warningsGrowthSlack = | |
| 210 [warningsField_ frame].origin.y - [iconView_ frame].origin.y; | |
| 211 } | |
| 171 | 212 |
| 172 totalOffset += AdjustControlHeightToFitContent(subtitleField_); | 213 totalOffset += AdjustControlHeightToFitContent(subtitleField_); |
| 173 OffsetControlVertically(subtitleField_, -totalOffset); | 214 OffsetControlVertically(subtitleField_, -totalOffset); |
| 174 | 215 |
| 175 CGFloat warningsOffset = AdjustControlHeightToFitContent(warningsField_); | 216 totalOffset += AdjustControlHeightToFitContent(warningsField_); |
| 176 OffsetControlVertically(warningsField_, -warningsOffset); | 217 OffsetControlVertically(warningsField_, -totalOffset); |
| 177 totalOffset += warningsOffset; | 218 totalOffset = MAX(totalOffset - warningsGrowthSlack, 0); |
| 219 } else if ([self isInlineInstall]) { | |
| 220 // Inline installs that don't have a permissions section need to hide | |
| 221 // controls related to that and shrink the window by the space they take | |
| 222 // up. | |
| 223 NSRect hiddenRect = NSUnionRect([warningsSeparator_ frame], | |
| 224 [subtitleField_ frame]); | |
| 225 hiddenRect = NSUnionRect(hiddenRect, [warningsField_ frame]); | |
| 226 [warningsSeparator_ setHidden:YES]; | |
| 227 [subtitleField_ setHidden:YES]; | |
| 228 [warningsField_ setHidden:YES]; | |
| 229 totalOffset -= hiddenRect.size.height + kWarningsSeparatorPadding; | |
| 230 } | |
| 178 | 231 |
| 179 NSRect warningsBoxRect = [warningsBox_ frame]; | 232 // If necessary, adjust the window size. |
| 180 warningsBoxRect.origin.y -= totalOffset; | 233 if (totalOffset) { |
| 181 warningsBoxRect.size.height += warningsOffset; | |
| 182 [warningsBox_ setFrame:warningsBoxRect]; | |
| 183 | |
| 184 // buttons are positioned automatically in the XIB. | |
| 185 | |
| 186 // Finally, adjust the window size. | |
| 187 NSRect currentRect = [[self window] frame]; | 234 NSRect currentRect = [[self window] frame]; |
| 188 [[self window] setFrame:NSMakeRect(currentRect.origin.x, | 235 [[self window] setFrame:NSMakeRect(currentRect.origin.x, |
| 189 currentRect.origin.y - totalOffset, | 236 currentRect.origin.y - totalOffset, |
| 190 currentRect.size.width, | 237 currentRect.size.width, |
| 191 currentRect.size.height + totalOffset) | 238 currentRect.size.height + totalOffset) |
| 192 display:NO]; | 239 display:NO]; |
| 193 } | 240 } |
| 241 | |
| 242 // Focus the cancel button, otherwise the store link gets the default focus | |
| 243 // for inline installs. | |
| 244 [[self window] makeFirstResponder:cancelButton_]; | |
|
Nico
2011/09/05 22:59:17
I think you can set the first responder in the nib
Mihai Parparita -not on Chrome
2011/09/06 00:54:11
I selected the window in Interface Builder and the
| |
| 194 } | 245 } |
| 195 | 246 |
| 196 - (void)didEndSheet:(NSWindow*)sheet | 247 - (void)didEndSheet:(NSWindow*)sheet |
| 197 returnCode:(int)returnCode | 248 returnCode:(int)returnCode |
| 198 contextInfo:(void*)contextInfo { | 249 contextInfo:(void*)contextInfo { |
| 199 [sheet close]; | 250 [sheet close]; |
| 200 } | 251 } |
| 201 | 252 |
| 202 - (void)windowWillClose:(NSNotification*)notification { | 253 - (void)windowWillClose:(NSNotification*)notification { |
| 203 [self autorelease]; | 254 [self autorelease]; |
| 204 } | 255 } |
| 205 | 256 |
| 257 - (bool)isInlineInstall { | |
| 258 return prompt_->type() == ExtensionInstallUI::INLINE_INSTALL_PROMPT; | |
| 259 } | |
| 260 | |
| 261 - (void)appendRatingStar:(const SkBitmap*)skiaImage { | |
| 262 NSImage* image = gfx::SkBitmapToNSImageWithColorSpace( | |
| 263 *skiaImage, base::mac::GetSystemColorSpace()); | |
| 264 NSRect frame = NSMakeRect(0, 0, skiaImage->width(), skiaImage->height()); | |
| 265 NSImageView* view = [[[NSImageView alloc] initWithFrame:frame] autorelease]; | |
|
Nico
2011/09/05 22:59:17
nit: I think we generally prefer scoped_nsobject o
Mihai Parparita -not on Chrome
2011/09/06 00:54:11
Done.
| |
| 266 [view setImage:image]; | |
| 267 | |
| 268 // Add this star after all the other ones | |
| 269 CGFloat maxStarRight = 0; | |
| 270 if ([[ratingStars_ subviews] count]) { | |
| 271 maxStarRight = NSMaxX([[[ratingStars_ subviews] lastObject] frame]); | |
| 272 } | |
| 273 NSRect starBounds = NSMakeRect(maxStarRight, 0, | |
| 274 skiaImage->width(), skiaImage->height()); | |
| 275 [view setFrame:starBounds]; | |
| 276 [ratingStars_ addSubview:view]; | |
| 277 } | |
| 278 | |
| 206 @end // ExtensionInstallDialogController | 279 @end // ExtensionInstallDialogController |
| 207 | 280 |
| 208 void ShowExtensionInstallDialog( | 281 void ShowExtensionInstallDialog( |
| 209 Profile* profile, | 282 Profile* profile, |
| 210 ExtensionInstallUI::Delegate* delegate, | 283 ExtensionInstallUI::Delegate* delegate, |
| 211 const Extension* extension, | 284 const Extension* extension, |
| 212 SkBitmap* icon, | 285 SkBitmap* icon, |
| 213 const ExtensionInstallUI::Prompt& prompt) { | 286 const ExtensionInstallUI::Prompt& prompt) { |
| 214 Browser* browser = BrowserList::GetLastActiveWithProfile(profile); | 287 Browser* browser = BrowserList::GetLastActiveWithProfile(profile); |
| 215 if (!browser) { | 288 if (!browser) { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 229 [[ExtensionInstallDialogController alloc] | 302 [[ExtensionInstallDialogController alloc] |
| 230 initWithParentWindow:native_window | 303 initWithParentWindow:native_window |
| 231 profile:profile | 304 profile:profile |
| 232 extension:extension | 305 extension:extension |
| 233 delegate:delegate | 306 delegate:delegate |
| 234 icon:icon | 307 icon:icon |
| 235 prompt:prompt]; | 308 prompt:prompt]; |
| 236 | 309 |
| 237 [controller runAsModalSheet]; | 310 [controller runAsModalSheet]; |
| 238 } | 311 } |
| OLD | NEW |