Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(108)

Unified Diff: chrome/browser/ui/cocoa/extensions/media_gallery_list_entry_view.mm

Issue 231873003: Refactor media galleries dialogs on cocoa to extract common code (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: nit Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698