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 |