Chromium Code Reviews| Index: chrome/browser/ui/cocoa/extensions/media_gallery_list_entry_view.mm |
| diff --git a/chrome/browser/ui/cocoa/extensions/media_gallery_list_entry_view.mm b/chrome/browser/ui/cocoa/extensions/media_gallery_list_entry_view.mm |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..950a14b9657a70e491d6fc72007a6c4947c39801 |
| --- /dev/null |
| +++ b/chrome/browser/ui/cocoa/extensions/media_gallery_list_entry_view.mm |
| @@ -0,0 +1,257 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#import "chrome/browser/ui/cocoa/extensions/media_gallery_list_entry_view.h" |
| + |
| +#include "base/strings/sys_string_conversions.h" |
| +#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_control_utils.h" |
| +#include "chrome/browser/ui/chrome_style.h" |
| +#include "grit/theme_resources.h" |
| +#import "ui/base/cocoa/menu_controller.h" |
| +#include "ui/base/resource/resource_bundle.h" |
| + |
| +namespace { |
| + |
| +const CGFloat kCheckboxMargin = 10; |
| + |
| +CGFloat MinIfNotZero(CGFloat a, CGFloat b) { |
|
groby-ooo-7-16
2014/04/23 21:57:58
std::min(std::max(a, 0.0), std::max(b, 0.0)))
Equ
vandebo (ex-Chrome)
2014/04/25 20:10:56
a & b are both >= 0, so that reduces to std::min(a
|
| + if (a == 0) |
| + return b; |
| + if (b == 0) |
| + return a; |
| + return std::min(a, b); |
| +} |
| + |
| +} // namespace |
| + |
| +const CGFloat kDetailGray = 0.625; |
|
groby-ooo-7-16
2014/04/23 21:57:58
Please keep consts together (and outside anon ns)
vandebo (ex-Chrome)
2014/04/25 20:10:56
Done.
|
| + |
| +ui::MenuModel* MediaGalleryListEntryController::GetContextMenu( |
| + MediaGalleryPrefId pref_id) { |
| + return NULL; |
| +} |
| + |
| +@interface MediaGalleryListEntry () |
| +- (void)onCheckboxToggled:(id)sender; |
| +- (void)onFolderViewerClicked:(id)sender; |
| +- (ui::MenuModel*)getContextMenu; |
| +- (void)layoutSubViews; |
| +@end |
| + |
| + |
| +@interface MediaGalleryButton : NSButton { |
| + @private |
| + MediaGalleryListEntry* controller_; // |controller_| owns |self|. |
| + base::scoped_nsobject<MenuController> menuController_; |
| +} |
| + |
| +- (id)initWithFrame:(NSRect)frameRect |
| + controller:(MediaGalleryListEntry*)controller; |
| +- (NSMenu*)menuForEvent:(NSEvent*)theEvent; |
| + |
| +@end |
| + |
| +@implementation MediaGalleryButton |
| + |
| +- (id)initWithFrame:(NSRect)frameRect |
| + controller:(MediaGalleryListEntry*)controller { |
| + if ((self = [super initWithFrame:frameRect])) { |
| + controller_ = controller; |
| + } |
| + return self; |
| +} |
| + |
| +- (NSMenu*)menuForEvent:(NSEvent*)theEvent { |
| + menuController_.reset( |
| + [[MenuController alloc] initWithModel:[controller_ getContextMenu] |
| + useWithPopUpButtonCell:NO]); |
| + return [menuController_ menu]; |
| +} |
| + |
| +@end |
| + |
| + |
| +@implementation MediaGalleryListEntry |
| + |
| +- (id)initWithFrame:(NSRect)frameRect |
| + controller:(MediaGalleryListEntryController*)controller |
| + prefId:(MediaGalleryPrefId)prefId |
| + galleryName:(base::string16)galleryName |
| + subscript:(base::string16)subscript |
| + tooltip:(base::string16)tooltip |
| + showFolderViewer:(bool)showFolderViewer { |
| + if ((self = [super initWithFrame:frameRect])) { |
| + controller_ = controller; |
| + prefId_ = prefId; |
| + |
| + NSString* nsTooltip = base::SysUTF16ToNSString(tooltip); |
| + |
| + // Set a auto resize mask so that resizeWithOldSuperviewSize() is called. |
|
groby-ooo-7-16
2014/04/23 21:57:58
nit: -resizeWithOldSuperviewSize:
vandebo (ex-Chrome)
2014/04/25 20:10:56
Done.
|
| + // It is overridden so the particular mask doesn't matter. |
| + [self setAutoresizingMask:NSViewWidthSizable]; |
| + checkbox_.reset( |
| + [[MediaGalleryButton alloc] initWithFrame:NSZeroRect |
| + controller:self]); |
| + [[checkbox_ cell] setLineBreakMode:NSLineBreakByTruncatingMiddle]; |
| + [checkbox_ setButtonType:NSSwitchButton]; |
| + [checkbox_ setTarget:self]; |
| + [checkbox_ setAction:@selector(onCheckboxToggled:)]; |
| + |
| + [checkbox_ setTitle:base::SysUTF16ToNSString(galleryName)]; |
| + [checkbox_ setToolTip:nsTooltip]; |
| + |
| + // Folder viewer button. |
| + if (showFolderViewer) { |
| + folderViewer_.reset( |
| + [[MediaGalleryButton alloc] initWithFrame:NSZeroRect |
| + controller:self]); |
| + [folderViewer_ setButtonType:NSMomentaryChangeButton]; |
| + [folderViewer_ setTarget:self]; |
| + [folderViewer_ setAction:@selector(onFolderViewerClicked:)]; |
| + |
| + ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| + [folderViewer_ setImage:rb.GetNativeImageNamed( |
| + IDR_FILE_FOLDER).ToNSImage()]; |
| + [folderViewer_ setTitle:nil]; |
| + [folderViewer_ setBordered:false]; |
| + [folderViewer_ setToolTip:nsTooltip]; |
| + } |
| + |
| + // Additional details text. |
| + if (!subscript.empty()) { |
| + details_.reset([[NSTextField alloc] initWithFrame:NSZeroRect]); |
| + [[details_ cell] setLineBreakMode:NSLineBreakByTruncatingHead]; |
| + [details_ setEditable:NO]; |
| + [details_ setSelectable:NO]; |
| + [details_ setBezeled:NO]; |
| + [details_ setAttributedStringValue: |
| + constrained_window::GetAttributedLabelString( |
| + base::SysUTF16ToNSString(subscript), |
| + chrome_style::kTextFontStyle, |
| + NSNaturalTextAlignment, |
| + NSLineBreakByClipping |
| + )]; |
| + [details_ setTextColor:[NSColor colorWithCalibratedRed:kDetailGray |
|
groby-ooo-7-16
2014/04/23 21:57:58
+colorWithCalibratedWhite:alpha: if you must speci
vandebo (ex-Chrome)
2014/04/25 20:10:56
Done.
|
| + green:kDetailGray |
| + blue:kDetailGray |
| + alpha:1.0]]; |
| + } |
| + |
| + [self layoutSubViews]; |
| + |
| + [self addSubview:checkbox_]; |
| + if (showFolderViewer) |
| + [self addSubview:folderViewer_]; |
| + if (!subscript.empty()) |
| + [self addSubview:details_]; |
| + } |
| + return self; |
| +} |
| + |
| +- (void)setFrame:(NSRect)frameRect { |
| + [super setFrame:frameRect]; |
|
groby-ooo-7-16
2014/04/23 21:57:58
Does this actually work? It seems that [super setF
vandebo (ex-Chrome)
2014/04/25 20:10:56
Adding some printf suggests that resize is not cal
groby-ooo-7-16
2014/04/25 20:29:54
Sigh. No idea why I confused super and superview :
|
| + [self layoutSubViews]; |
| +} |
| + |
| +- (void)setFrameSize:(NSSize)frameSize { |
| + [super setFrameSize:frameSize]; |
| + [self layoutSubViews]; |
| +} |
| + |
| +- (void)resizeWithOldSuperviewSize:(NSSize)oldBoundsSize { |
|
groby-ooo-7-16
2014/04/23 21:57:58
why not just set the autoresizingMask to NSViewWid
vandebo (ex-Chrome)
2014/04/25 20:10:56
I first tried setting the resize mask to NSViewWid
groby-ooo-7-16
2014/04/25 20:29:54
Yes, see NSView's -setPostsFrameChangedNotificatio
vandebo (ex-Chrome)
2014/04/28 19:04:51
I tried registered for this notification, it does
groby-ooo-7-16
2014/04/28 22:17:12
That's correct. -resizeWithOldSuperviewSize: trigg
vandebo (ex-Chrome)
2014/04/29 18:40:29
I've uploaded a full CL that adds the Notification
|
| + NSRect superviewFrame = [[self superview] frame]; |
| + NSRect frame = [self frame]; |
| + if (NSWidth(frame) != NSWidth(superviewFrame)) { |
|
groby-ooo-7-16
2014/04/23 21:57:58
If you *must* implement this for a reason I'm miss
vandebo (ex-Chrome)
2014/04/25 20:10:56
Done.
|
| + frame.size.width = NSWidth(superviewFrame); |
| + [self setFrame:frame]; |
| + } |
| +} |
| + |
| +- (void)setState:(bool)selected { |
| + [checkbox_ setState:selected ? NSOnState : NSOffState]; |
| +} |
| + |
| +- (void)onCheckboxToggled:(id)sender { |
| + controller_->OnCheckboxToggled(prefId_, [sender state] == NSOnState); |
| +} |
| + |
| +- (void)onFolderViewerClicked:(id)sender { |
| + controller_->OnFolderViewerClicked(prefId_); |
| +} |
| + |
| +- (ui::MenuModel*)getContextMenu { |
| + return controller_->GetContextMenu(prefId_); |
| +} |
| + |
| +- (void)layoutSubViews { |
| + NSRect frame = [self frame]; |
|
groby-ooo-7-16
2014/04/23 21:57:58
Technically, layout for subviews needs to happen i
vandebo (ex-Chrome)
2014/04/25 20:10:56
Done.
|
| + [checkbox_ sizeToFit]; |
| + NSRect checkboxRect = [checkbox_ frame]; |
| + checkboxRect.size.height = |
|
groby-ooo-7-16
2014/04/23 21:57:58
Why exactly the MinIfNotZero dance? checkboxRect c
vandebo (ex-Chrome)
2014/04/25 20:10:56
Right, the case where this matter is self having a
groby-ooo-7-16
2014/04/25 20:29:54
Does what we discussed not work? (empty frame just
vandebo (ex-Chrome)
2014/04/28 19:04:51
The windows of the scrollview is fixed, but the wi
groby-ooo-7-16
2014/04/28 22:17:12
Ah. Still, that should work without MinIfZero, unl
vandebo (ex-Chrome)
2014/04/29 18:40:29
Yup, MinIfNotZero is gone.
|
| + MinIfNotZero(NSHeight(checkboxRect), NSHeight(frame)); |
| + NSRect folderViewerRect = NSZeroRect; |
| + if (folderViewer_.get()) { |
| + [folderViewer_ sizeToFit]; |
| + folderViewerRect = [folderViewer_ frame]; |
| + } else { |
| + folderViewerRect.size.width = -kCheckboxMargin; |
|
groby-ooo-7-16
2014/04/23 21:57:58
Having a negative size for non-existent elements _
vandebo (ex-Chrome)
2014/04/25 20:10:56
So layout all the elements at their natural size,
groby-ooo-7-16
2014/04/25 20:29:54
Will look there, but yes, I'd suggest just updatin
vandebo (ex-Chrome)
2014/04/28 19:04:51
I've updated the code to lay everything out and th
|
| + } |
| + folderViewerRect.size.height = |
|
groby-ooo-7-16
2014/04/23 21:57:58
Same here
|
| + MinIfNotZero(NSHeight(folderViewerRect), NSHeight(frame)); |
| + NSRect detailsRect = NSZeroRect; |
| + if (details_.get()) { |
| + [details_ sizeToFit]; |
| + detailsRect = [details_ frame]; |
| + } else { |
| + detailsRect.size.width = -kCheckboxMargin; |
| + } |
| + detailsRect.size.height = |
| + MinIfNotZero(NSHeight(detailsRect), NSHeight(frame)); |
| + |
| + // Size the views. If all the elements don't naturally fit, the checkbox |
| + // should get squished and will elide in the middle. However, it shouldn't |
| + // squish too much so it gets at least half of the max width and the details |
| + // text should elide as well in that case. |
| + int naturalWidth = NSWidth(checkboxRect) + NSWidth(folderViewerRect) + |
|
groby-ooo-7-16
2014/04/23 21:57:58
If you computed all rects, this would simply be NS
vandebo (ex-Chrome)
2014/04/25 20:10:56
Done.
|
| + NSWidth(detailsRect) + 4 * kCheckboxMargin; |
| + if (NSWidth(frame) && naturalWidth > NSWidth(frame)) { |
|
groby-ooo-7-16
2014/04/23 21:57:58
Again, I think. Can you just early out if NSIsEmpt
vandebo (ex-Chrome)
2014/04/25 20:10:56
Only if I compute size and position for each eleme
|
| + int maxContent = NSWidth(frame) - 4 * kCheckboxMargin; |
| + if (NSWidth(folderViewerRect) + NSWidth(detailsRect) > maxContent / 2) { |
|
groby-ooo-7-16
2014/04/23 21:57:58
This is not quite what the comment above says. Or
vandebo (ex-Chrome)
2014/04/25 20:10:56
I think you're missing the case where the checkbox
|
| + detailsRect.size.width = std::max( |
| + maxContent / 2 - NSWidth(folderViewerRect), |
| + maxContent - NSWidth(checkboxRect) - NSWidth(folderViewerRect)); |
| + } |
| + checkboxRect.size.width = |
| + maxContent - NSWidth(folderViewerRect) - NSWidth(detailsRect); |
| + } |
| + |
| + checkboxRect.origin = NSMakePoint(kCheckboxMargin, 0); |
| + [checkbox_ setFrame:checkboxRect]; |
| + |
| + folderViewerRect.origin = |
| + NSMakePoint(NSMaxX(checkboxRect) + kCheckboxMargin, 0); |
| + if (folderViewer_.get()) { |
|
groby-ooo-7-16
2014/04/23 21:57:58
What if you just reflowed the subviews? Set the fr
vandebo (ex-Chrome)
2014/04/25 20:10:56
If the folder viewer is not present, that will add
groby-ooo-7-16
2014/04/25 20:29:54
How so? If the folderView is not present, it won't
vandebo (ex-Chrome)
2014/04/28 19:04:51
Oops, you're right...
|
| + [folderViewer_ setFrame:folderViewerRect]; |
| + detailsRect.origin = |
| + NSMakePoint(NSMaxX(folderViewerRect) + kCheckboxMargin, 0); |
| + } else { |
| + detailsRect.origin = folderViewerRect.origin; |
| + } |
| + |
| + if (details_.get()) { |
| + [details_ setFrame:detailsRect]; |
| + } |
| + |
| + if (NSIsEmptyRect(frame)) { |
|
groby-ooo-7-16
2014/04/23 21:57:58
Oh. I see. Empty rect is essentially -sizeToFit?
vandebo (ex-Chrome)
2014/04/25 20:10:56
Yes.
|
| + frame.size.width = |
| + std::max(NSWidth(checkboxRect), |
| + std::max(NSWidth(folderViewerRect), NSWidth(detailsRect))); |
| + frame.size.height = |
| + std::max(NSHeight(checkboxRect), |
| + std::max(NSHeight(folderViewerRect), NSHeight(detailsRect))); |
| + [super setFrame:frame]; |
| + } |
| +} |
| + |
| +@end |