OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #import "chrome/browser/ui/cocoa/extensions/media_gallery_list_entry_view.h" | |
6 | |
7 #include "base/strings/sys_string_conversions.h" | |
8 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_control_u tils.h" | |
9 #include "chrome/browser/ui/chrome_style.h" | |
10 #include "grit/theme_resources.h" | |
11 #import "ui/base/cocoa/menu_controller.h" | |
12 #include "ui/base/resource/resource_bundle.h" | |
13 | |
14 namespace { | |
15 | |
16 const CGFloat kCheckboxMargin = 10; | |
17 | |
18 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
| |
19 if (a == 0) | |
20 return b; | |
21 if (b == 0) | |
22 return a; | |
23 return std::min(a, b); | |
24 } | |
25 | |
26 } // namespace | |
27 | |
28 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.
| |
29 | |
30 ui::MenuModel* MediaGalleryListEntryController::GetContextMenu( | |
31 MediaGalleryPrefId pref_id) { | |
32 return NULL; | |
33 } | |
34 | |
35 @interface MediaGalleryListEntry () | |
36 - (void)onCheckboxToggled:(id)sender; | |
37 - (void)onFolderViewerClicked:(id)sender; | |
38 - (ui::MenuModel*)getContextMenu; | |
39 - (void)layoutSubViews; | |
40 @end | |
41 | |
42 | |
43 @interface MediaGalleryButton : NSButton { | |
44 @private | |
45 MediaGalleryListEntry* controller_; // |controller_| owns |self|. | |
46 base::scoped_nsobject<MenuController> menuController_; | |
47 } | |
48 | |
49 - (id)initWithFrame:(NSRect)frameRect | |
50 controller:(MediaGalleryListEntry*)controller; | |
51 - (NSMenu*)menuForEvent:(NSEvent*)theEvent; | |
52 | |
53 @end | |
54 | |
55 @implementation MediaGalleryButton | |
56 | |
57 - (id)initWithFrame:(NSRect)frameRect | |
58 controller:(MediaGalleryListEntry*)controller { | |
59 if ((self = [super initWithFrame:frameRect])) { | |
60 controller_ = controller; | |
61 } | |
62 return self; | |
63 } | |
64 | |
65 - (NSMenu*)menuForEvent:(NSEvent*)theEvent { | |
66 menuController_.reset( | |
67 [[MenuController alloc] initWithModel:[controller_ getContextMenu] | |
68 useWithPopUpButtonCell:NO]); | |
69 return [menuController_ menu]; | |
70 } | |
71 | |
72 @end | |
73 | |
74 | |
75 @implementation MediaGalleryListEntry | |
76 | |
77 - (id)initWithFrame:(NSRect)frameRect | |
78 controller:(MediaGalleryListEntryController*)controller | |
79 prefId:(MediaGalleryPrefId)prefId | |
80 galleryName:(base::string16)galleryName | |
81 subscript:(base::string16)subscript | |
82 tooltip:(base::string16)tooltip | |
83 showFolderViewer:(bool)showFolderViewer { | |
84 if ((self = [super initWithFrame:frameRect])) { | |
85 controller_ = controller; | |
86 prefId_ = prefId; | |
87 | |
88 NSString* nsTooltip = base::SysUTF16ToNSString(tooltip); | |
89 | |
90 // 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.
| |
91 // It is overridden so the particular mask doesn't matter. | |
92 [self setAutoresizingMask:NSViewWidthSizable]; | |
93 checkbox_.reset( | |
94 [[MediaGalleryButton alloc] initWithFrame:NSZeroRect | |
95 controller:self]); | |
96 [[checkbox_ cell] setLineBreakMode:NSLineBreakByTruncatingMiddle]; | |
97 [checkbox_ setButtonType:NSSwitchButton]; | |
98 [checkbox_ setTarget:self]; | |
99 [checkbox_ setAction:@selector(onCheckboxToggled:)]; | |
100 | |
101 [checkbox_ setTitle:base::SysUTF16ToNSString(galleryName)]; | |
102 [checkbox_ setToolTip:nsTooltip]; | |
103 | |
104 // Folder viewer button. | |
105 if (showFolderViewer) { | |
106 folderViewer_.reset( | |
107 [[MediaGalleryButton alloc] initWithFrame:NSZeroRect | |
108 controller:self]); | |
109 [folderViewer_ setButtonType:NSMomentaryChangeButton]; | |
110 [folderViewer_ setTarget:self]; | |
111 [folderViewer_ setAction:@selector(onFolderViewerClicked:)]; | |
112 | |
113 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | |
114 [folderViewer_ setImage:rb.GetNativeImageNamed( | |
115 IDR_FILE_FOLDER).ToNSImage()]; | |
116 [folderViewer_ setTitle:nil]; | |
117 [folderViewer_ setBordered:false]; | |
118 [folderViewer_ setToolTip:nsTooltip]; | |
119 } | |
120 | |
121 // Additional details text. | |
122 if (!subscript.empty()) { | |
123 details_.reset([[NSTextField alloc] initWithFrame:NSZeroRect]); | |
124 [[details_ cell] setLineBreakMode:NSLineBreakByTruncatingHead]; | |
125 [details_ setEditable:NO]; | |
126 [details_ setSelectable:NO]; | |
127 [details_ setBezeled:NO]; | |
128 [details_ setAttributedStringValue: | |
129 constrained_window::GetAttributedLabelString( | |
130 base::SysUTF16ToNSString(subscript), | |
131 chrome_style::kTextFontStyle, | |
132 NSNaturalTextAlignment, | |
133 NSLineBreakByClipping | |
134 )]; | |
135 [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.
| |
136 green:kDetailGray | |
137 blue:kDetailGray | |
138 alpha:1.0]]; | |
139 } | |
140 | |
141 [self layoutSubViews]; | |
142 | |
143 [self addSubview:checkbox_]; | |
144 if (showFolderViewer) | |
145 [self addSubview:folderViewer_]; | |
146 if (!subscript.empty()) | |
147 [self addSubview:details_]; | |
148 } | |
149 return self; | |
150 } | |
151 | |
152 - (void)setFrame:(NSRect)frameRect { | |
153 [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 :
| |
154 [self layoutSubViews]; | |
155 } | |
156 | |
157 - (void)setFrameSize:(NSSize)frameSize { | |
158 [super setFrameSize:frameSize]; | |
159 [self layoutSubViews]; | |
160 } | |
161 | |
162 - (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
| |
163 NSRect superviewFrame = [[self superview] frame]; | |
164 NSRect frame = [self frame]; | |
165 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.
| |
166 frame.size.width = NSWidth(superviewFrame); | |
167 [self setFrame:frame]; | |
168 } | |
169 } | |
170 | |
171 - (void)setState:(bool)selected { | |
172 [checkbox_ setState:selected ? NSOnState : NSOffState]; | |
173 } | |
174 | |
175 - (void)onCheckboxToggled:(id)sender { | |
176 controller_->OnCheckboxToggled(prefId_, [sender state] == NSOnState); | |
177 } | |
178 | |
179 - (void)onFolderViewerClicked:(id)sender { | |
180 controller_->OnFolderViewerClicked(prefId_); | |
181 } | |
182 | |
183 - (ui::MenuModel*)getContextMenu { | |
184 return controller_->GetContextMenu(prefId_); | |
185 } | |
186 | |
187 - (void)layoutSubViews { | |
188 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.
| |
189 [checkbox_ sizeToFit]; | |
190 NSRect checkboxRect = [checkbox_ frame]; | |
191 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.
| |
192 MinIfNotZero(NSHeight(checkboxRect), NSHeight(frame)); | |
193 NSRect folderViewerRect = NSZeroRect; | |
194 if (folderViewer_.get()) { | |
195 [folderViewer_ sizeToFit]; | |
196 folderViewerRect = [folderViewer_ frame]; | |
197 } else { | |
198 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
| |
199 } | |
200 folderViewerRect.size.height = | |
groby-ooo-7-16
2014/04/23 21:57:58
Same here
| |
201 MinIfNotZero(NSHeight(folderViewerRect), NSHeight(frame)); | |
202 NSRect detailsRect = NSZeroRect; | |
203 if (details_.get()) { | |
204 [details_ sizeToFit]; | |
205 detailsRect = [details_ frame]; | |
206 } else { | |
207 detailsRect.size.width = -kCheckboxMargin; | |
208 } | |
209 detailsRect.size.height = | |
210 MinIfNotZero(NSHeight(detailsRect), NSHeight(frame)); | |
211 | |
212 // Size the views. If all the elements don't naturally fit, the checkbox | |
213 // should get squished and will elide in the middle. However, it shouldn't | |
214 // squish too much so it gets at least half of the max width and the details | |
215 // text should elide as well in that case. | |
216 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.
| |
217 NSWidth(detailsRect) + 4 * kCheckboxMargin; | |
218 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
| |
219 int maxContent = NSWidth(frame) - 4 * kCheckboxMargin; | |
220 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
| |
221 detailsRect.size.width = std::max( | |
222 maxContent / 2 - NSWidth(folderViewerRect), | |
223 maxContent - NSWidth(checkboxRect) - NSWidth(folderViewerRect)); | |
224 } | |
225 checkboxRect.size.width = | |
226 maxContent - NSWidth(folderViewerRect) - NSWidth(detailsRect); | |
227 } | |
228 | |
229 checkboxRect.origin = NSMakePoint(kCheckboxMargin, 0); | |
230 [checkbox_ setFrame:checkboxRect]; | |
231 | |
232 folderViewerRect.origin = | |
233 NSMakePoint(NSMaxX(checkboxRect) + kCheckboxMargin, 0); | |
234 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...
| |
235 [folderViewer_ setFrame:folderViewerRect]; | |
236 detailsRect.origin = | |
237 NSMakePoint(NSMaxX(folderViewerRect) + kCheckboxMargin, 0); | |
238 } else { | |
239 detailsRect.origin = folderViewerRect.origin; | |
240 } | |
241 | |
242 if (details_.get()) { | |
243 [details_ setFrame:detailsRect]; | |
244 } | |
245 | |
246 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.
| |
247 frame.size.width = | |
248 std::max(NSWidth(checkboxRect), | |
249 std::max(NSWidth(folderViewerRect), NSWidth(detailsRect))); | |
250 frame.size.height = | |
251 std::max(NSHeight(checkboxRect), | |
252 std::max(NSHeight(folderViewerRect), NSHeight(detailsRect))); | |
253 [super setFrame:frame]; | |
254 } | |
255 } | |
256 | |
257 @end | |
OLD | NEW |