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..d4712345b56deca63a113148467c6999e6402bc4 |
| --- /dev/null |
| +++ b/chrome/browser/ui/cocoa/extensions/media_gallery_list_entry_view.mm |
| @@ -0,0 +1,233 @@ |
| +// 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" |
| + |
| +const CGFloat kCheckboxMargin = 10; |
| + |
| +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. |
| + // 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 disabledControlTextColor]]; |
| + } |
| + |
| + [self addSubview:checkbox_]; |
| + if (showFolderViewer) |
|
groby-ooo-7-16
2014/04/28 22:17:12
Personal nit: You might want to roll this into the
vandebo (ex-Chrome)
2014/04/29 18:40:29
Done.
|
| + [self addSubview:folderViewer_]; |
| + if (!subscript.empty()) |
| + [self addSubview:details_]; |
| + |
| + [self layoutSubViews]; |
| + } |
| + return self; |
| +} |
| + |
| +- (void)setFrameSize:(NSSize)frameSize { |
| + [super setFrameSize:frameSize]; |
| + [self layoutSubViews]; |
| +} |
| + |
| +- (void)resizeWithOldSuperviewSize:(NSSize)oldBoundsSize { |
| + NSRect frame = [self frame]; |
| + frame.size.width = NSWidth([[self superview] frame]); |
| + [self setFrameSize:frame.size]; |
| +} |
| + |
| +- (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 bounds = [self bounds]; |
| + // If we have an empty frame, we should auto size, so start with really big |
| + // bounds and then set it to the real size of the contents later. |
| + if (NSIsEmptyRect([self frame])) |
| + bounds.size = NSMakeSize(10000, 10000); |
| + |
| + [checkbox_ sizeToFit]; |
| + if (folderViewer_.get()) |
|
groby-ooo-7-16
2014/04/28 22:17:12
Skip the if - it's fine to send messages to nil :)
vandebo (ex-Chrome)
2014/04/29 18:40:29
Done.
|
| + [folderViewer_ sizeToFit]; |
| + if (details_.get()) |
| + [details_ sizeToFit]; |
| + |
| + // Auto size everything and lay it out horizontally. |
| + CGFloat xPos = kCheckboxMargin; |
| + for (NSView* view in [self subviews]) { |
| + NSRect viewFrame = [view frame]; |
| + viewFrame.origin.x = xPos; |
| + if (NSHeight(bounds) < NSHeight(viewFrame)) |
|
groby-ooo-7-16
2014/04/28 22:17:12
viewFrame.size.height = std::min(NSHeight(bounds),
vandebo (ex-Chrome)
2014/04/29 18:40:29
Done.
|
| + viewFrame.size.height = NSHeight(bounds); |
| + [view setFrame:viewFrame]; |
| + xPos = NSMaxX([view frame]) + kCheckboxMargin; |
| + } |
| + |
| + NSRect folderViewerFrame = NSZeroRect; |
|
groby-ooo-7-16
2014/04/28 22:17:12
Just folderViewFrame = [folderView_ frame];
Messa
vandebo (ex-Chrome)
2014/04/29 18:40:29
Done.
|
| + if (folderViewer_.get()) |
| + folderViewerFrame = [folderViewer_ frame]; |
| + NSRect detailsFrame = NSZeroRect; |
| + if (details_.get()) |
| + detailsFrame = [details_ 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. |
| + if (xPos > NSWidth(bounds)) { |
| + CGFloat maxContent = NSWidth(bounds) - 4 * kCheckboxMargin; |
|
groby-ooo-7-16
2014/04/28 22:17:12
the 4* is probably not correct. ([[self subviews]
vandebo (ex-Chrome)
2014/04/29 18:40:29
Fixed up differently.
|
| + if (NSWidth(folderViewerFrame) + NSWidth(detailsFrame) > |
| + maxContent / 2) { |
| + detailsFrame.size.width = std::max( |
|
groby-ooo-7-16
2014/04/28 22:17:12
Caveat: Technically, you can have non-existing det
vandebo (ex-Chrome)
2014/04/29 18:40:29
I haven't coded for that contingency/not a concern
|
| + maxContent / 2 - NSWidth(folderViewerFrame), |
| + NSWidth(bounds) - kCheckboxMargin - NSMinX(detailsFrame)); |
| + [details_ setFrameSize:detailsFrame.size]; |
| + xPos = NSMaxX(detailsFrame) + kCheckboxMargin; |
| + } |
| + CGFloat overflow = xPos - NSWidth(bounds); |
| + if (overflow > 0) { |
| + NSRect checkboxFrame = [checkbox_ frame]; |
| + checkboxFrame.size.width -= overflow; |
| + [checkbox_ setFrameSize:checkboxFrame.size]; |
| + if (folderViewer_.get()) { |
|
groby-ooo-7-16
2014/04/28 22:17:12
You can probably save a lot of this logic if you j
vandebo (ex-Chrome)
2014/04/29 18:40:29
I did try that code here. It was the same number
|
| + folderViewerFrame.origin.x -= overflow; |
| + [folderViewer_ setFrameOrigin:folderViewerFrame.origin]; |
| + } |
| + if (details_.get()) { |
| + detailsFrame.origin.x -= overflow; |
| + [details_ setFrameOrigin:detailsFrame.origin]; |
| + } |
| + } |
| + } |
| + |
| + if (NSIsEmptyRect([self frame])) { |
| + NSRect frame = NSMakeRect(0, 0, 1, 1); |
| + for (NSView* view in [self subviews]) { |
| + frame = NSUnionRect(frame, [view frame]); |
| + } |
| + frame.size.width += kCheckboxMargin; |
| + [super setFrameSize:frame.size]; |
| + } |
| +} |
| + |
| +@end |