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

Side by Side Diff: chrome/browser/ui/cocoa/extensions/media_galleries_scan_result_dialog_cocoa.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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/cocoa/extensions/media_galleries_scan_result_dialog_ cocoa.h" 5 #include "chrome/browser/ui/cocoa/extensions/media_galleries_scan_result_dialog_ cocoa.h"
6 6
7 #include "base/mac/foundation_util.h" 7 #include "base/mac/foundation_util.h"
8 #include "base/mac/scoped_nsobject.h" 8 #include "base/mac/scoped_nsobject.h"
9 #include "base/strings/sys_string_conversions.h" 9 #include "base/strings/sys_string_conversions.h"
10 #include "chrome/browser/ui/chrome_style.h"
11 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_alert.h" 10 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_alert.h"
12 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_control_u tils.h" 11 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_control_u tils.h"
13 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sh eet.h" 12 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sh eet.h"
14 #import "chrome/browser/ui/cocoa/key_equivalent_constants.h" 13 #import "chrome/browser/ui/cocoa/key_equivalent_constants.h"
15 #include "content/public/browser/web_contents.h" 14 #include "content/public/browser/web_contents.h"
16 #include "grit/generated_resources.h" 15 #include "grit/generated_resources.h"
17 #include "grit/theme_resources.h"
18 #import "ui/base/cocoa/flipped_view.h" 16 #import "ui/base/cocoa/flipped_view.h"
19 #import "ui/base/cocoa/menu_controller.h"
20 #import "ui/base/models/menu_model.h" 17 #import "ui/base/models/menu_model.h"
21 #include "ui/base/l10n/l10n_util.h" 18 #include "ui/base/l10n/l10n_util.h"
22 19
23 const CGFloat kDetailGray = 0.625; 20 namespace {
groby-ooo-7-16 2014/04/23 21:57:58 const implies internal linkage - no need for anon
vandebo (ex-Chrome) 2014/04/25 20:10:56 Done.
21
22 const CGFloat kCheckboxLeading = 10;
23 const CGFloat kCheckboxWidth = 440;
24 const CGFloat kScrollAreaHeight = 220;
25
26 } // namespace
24 27
25 // Controller for UI events on items in the media galleries dialog. 28 // Controller for UI events on items in the media galleries dialog.
26 @interface MediaGalleriesScanResultCocoaController : NSObject { 29 @interface MediaGalleriesScanResultCocoaController : NSObject {
27 @private 30 @private
28 MediaGalleriesScanResultDialogCocoa* dialog_; 31 MediaGalleriesScanResultDialogCocoa* dialog_;
29 } 32 }
30 33
31 @property(assign, nonatomic) MediaGalleriesScanResultDialogCocoa* dialog; 34 @property(assign, nonatomic) MediaGalleriesScanResultDialogCocoa* dialog;
32 35
36 - (void)onAcceptButton:(id)sender;
37 - (void)onCancelButton:(id)sender;
38
33 @end 39 @end
34 40
35 @implementation MediaGalleriesScanResultCocoaController 41 @implementation MediaGalleriesScanResultCocoaController
36 42
37 @synthesize dialog = dialog_; 43 @synthesize dialog = dialog_;
38 44
39 - (void)onAcceptButton:(id)sender { 45 - (void)onAcceptButton:(id)sender {
40 dialog_->OnAcceptClicked(); 46 dialog_->OnAcceptClicked();
41 } 47 }
42 48
43 - (void)onCancelButton:(id)sender { 49 - (void)onCancelButton:(id)sender {
44 dialog_->OnCancelClicked(); 50 dialog_->OnCancelClicked();
45 } 51 }
46 52
47 - (void)onCheckboxToggled:(id)sender {
48 DCHECK(dialog_);
49 dialog_->OnCheckboxToggled(sender);
50 }
51
52 - (void)onFolderViewClicked:(id)sender {
53 DCHECK(dialog_);
54 dialog_->OnFolderViewClicked(sender);
55 }
56
57 @end 53 @end
58 54
59 55
60 @interface MediaGalleriesScanResultButton : NSButton {
61 @private
62 MediaGalleriesScanResultDialogCocoa* dialog_; // |dialog_| owns |this|.
63 MediaGalleryPrefId prefId_;
64 base::scoped_nsobject<MenuController> menuController_;
65 }
66
67 @property(readonly, nonatomic) MediaGalleryPrefId prefId;
68
69 - (id)initWithFrame:(NSRect)frameRect
70 dialog:(MediaGalleriesScanResultDialogCocoa*)dialog
71 prefId:(MediaGalleryPrefId)prefId;
72 - (NSMenu*)menuForEvent:(NSEvent*)theEvent;
73
74 @end
75
76 @implementation MediaGalleriesScanResultButton
77
78 @synthesize prefId = prefId_;
79
80 - (id)initWithFrame:(NSRect)frameRect
81 dialog:(MediaGalleriesScanResultDialogCocoa*)dialog
82 prefId:(MediaGalleryPrefId)prefId {
83 if ((self = [super initWithFrame:frameRect])) {
84 dialog_ = dialog;
85 prefId_ = prefId;
86 }
87 return self;
88 }
89
90 - (NSMenu*)menuForEvent:(NSEvent*)theEvent {
91 menuController_.reset(
92 [[MenuController alloc] initWithModel:dialog_->GetContextMenu(prefId_)
93 useWithPopUpButtonCell:NO]);
94 return [menuController_ menu];
95 }
96
97 @end
98
99 namespace {
100
101 const CGFloat kCheckboxMargin = 10;
102 const CGFloat kCheckboxMaxWidth = 440;
103 const CGFloat kScrollAreaHeight = 220;
104
105 } // namespace
106
107 MediaGalleriesScanResultDialogCocoa::MediaGalleriesScanResultDialogCocoa( 56 MediaGalleriesScanResultDialogCocoa::MediaGalleriesScanResultDialogCocoa(
108 MediaGalleriesScanResultDialogController* controller, 57 MediaGalleriesScanResultDialogController* controller,
109 MediaGalleriesScanResultCocoaController* cocoa_controller) 58 MediaGalleriesScanResultCocoaController* cocoa_controller)
110 : controller_(controller), 59 : controller_(controller),
111 accepted_(false), 60 accepted_(false),
112 cocoa_controller_([cocoa_controller retain]) { 61 cocoa_controller_([cocoa_controller retain]) {
113 [cocoa_controller_ setDialog:this]; 62 [cocoa_controller_ setDialog:this];
114 63
115 alert_.reset([[ConstrainedWindowAlert alloc] init]); 64 alert_.reset([[ConstrainedWindowAlert alloc] init]);
116 65
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 [main_container_ setCornerRadius:0]; 102 [main_container_ setCornerRadius:0];
154 [main_container_ setContentViewMargins:NSZeroSize]; 103 [main_container_ setContentViewMargins:NSZeroSize];
155 [main_container_ setTitlePosition:NSNoTitle]; 104 [main_container_ setTitlePosition:NSNoTitle];
156 [main_container_ setBorderColor:[NSColor colorWithCalibratedRed:kDetailGray 105 [main_container_ setBorderColor:[NSColor colorWithCalibratedRed:kDetailGray
157 green:kDetailGray 106 green:kDetailGray
158 blue:kDetailGray 107 blue:kDetailGray
159 alpha:1.0]]; 108 alpha:1.0]];
160 109
161 base::scoped_nsobject<NSScrollView> scroll_view( 110 base::scoped_nsobject<NSScrollView> scroll_view(
162 [[NSScrollView alloc] initWithFrame: 111 [[NSScrollView alloc] initWithFrame:
163 NSMakeRect(0, 0, kCheckboxMaxWidth, kScrollAreaHeight)]); 112 NSMakeRect(0, 0, kCheckboxWidth, kScrollAreaHeight)]);
164 [scroll_view setHasVerticalScroller:YES]; 113 [scroll_view setHasVerticalScroller:YES];
165 [scroll_view setHasHorizontalScroller:NO]; 114 [scroll_view setHasHorizontalScroller:NO];
166 [scroll_view setBorderType:NSNoBorder]; 115 [scroll_view setBorderType:NSNoBorder];
167 [scroll_view setAutohidesScrollers:YES]; 116 [scroll_view setAutohidesScrollers:YES];
168 [[main_container_ contentView] addSubview:scroll_view]; 117 [[main_container_ contentView] addSubview:scroll_view];
169 118
170 // Add scan results checkboxes inside the scrolling view. 119 // Add scan results checkboxes inside the scrolling view.
171 checkbox_container_.reset([[FlippedView alloc] initWithFrame:NSZeroRect]); 120 checkbox_container_.reset([[FlippedView alloc] initWithFrame:NSZeroRect]);
172 checkboxes_.reset([[NSMutableArray alloc] init]); 121 CGFloat height = CreateCheckboxes();
122 // Give the container a reasonable initial size so that the scroll_view can
123 // figure out the content size.
124 [checkbox_container_ setFrame:NSMakeRect(0, 0, kCheckboxWidth, height)];
173 [scroll_view setDocumentView:checkbox_container_]; 125 [scroll_view setDocumentView:checkbox_container_];
174 126
175 CGFloat y_pos = 0; 127 NSRect checkboxes_frame =
176 128 NSMakeRect(0, 0, [scroll_view contentSize].width, height);
177 y_pos = CreateCheckboxes(y_pos, controller_->GetGalleryList()); 129 [checkbox_container_ setFrame:checkboxes_frame];
178
179 [checkbox_container_ setFrame:NSMakeRect(0, 0, kCheckboxMaxWidth, y_pos + 2)];
180 130
181 // Resize to pack the scroll view if possible. 131 // Resize to pack the scroll view if possible.
182 NSRect scroll_frame = [scroll_view frame]; 132 NSRect scroll_frame = [scroll_view frame];
183 if (NSHeight(scroll_frame) > NSHeight([checkbox_container_ frame])) { 133 if (NSHeight(scroll_frame) > NSHeight(checkboxes_frame)) {
184 scroll_frame.size.height = NSHeight([checkbox_container_ frame]); 134 scroll_frame.size.height = NSHeight(checkboxes_frame);
185 [scroll_view setFrame:scroll_frame]; 135 [scroll_view setFrame:scroll_frame];
186 } 136 }
187 137
188 [main_container_ setFrameFromContentFrame:scroll_frame]; 138 [main_container_ setFrameFromContentFrame:scroll_frame];
139 NSRect main_frame = [main_container_ frame];
groby-ooo-7-16 2014/04/23 21:57:58 setFrameOrigin:
vandebo (ex-Chrome) 2014/04/25 20:10:56 Done.
140 main_frame.origin = NSZeroPoint;
141 [main_container_ setFrame:main_frame];
189 [alert_ setAccessoryView:main_container_]; 142 [alert_ setAccessoryView:main_container_];
190
191 [alert_ layout]; 143 [alert_ layout];
192 } 144 }
193 145
194 void MediaGalleriesScanResultDialogCocoa::AcceptDialogForTesting() { 146 void MediaGalleriesScanResultDialogCocoa::AcceptDialogForTesting() {
195 OnAcceptClicked(); 147 OnAcceptClicked();
196 } 148 }
197 149
198 CGFloat MediaGalleriesScanResultDialogCocoa::CreateCheckboxes( 150 CGFloat MediaGalleriesScanResultDialogCocoa::CreateCheckboxes() {
199 CGFloat y_pos, 151 CGFloat y_pos = 0;
200 const MediaGalleriesScanResultDialogController::OrderedScanResults& 152 MediaGalleriesScanResultDialogController::OrderedScanResults scan_results =
201 scan_results) { 153 controller_->GetGalleryList();
202 y_pos += kCheckboxMargin;
203
204 for (MediaGalleriesScanResultDialogController::OrderedScanResults:: 154 for (MediaGalleriesScanResultDialogController::OrderedScanResults::
205 const_iterator iter = scan_results.begin(); 155 const_iterator iter = scan_results.begin();
206 iter != scan_results.end(); iter++) { 156 iter != scan_results.end(); iter++) {
207 const MediaGalleriesScanResultDialogController::ScanResult& scan_result = 157 const MediaGalleriesScanResultDialogController::ScanResult& scan_result =
208 *iter; 158 *iter;
209 UpdateScanResultCheckbox(scan_result.pref_info, scan_result.selected, 159 base::scoped_nsobject<MediaGalleryListEntry> checkbox_entry(
210 y_pos); 160 [[MediaGalleryListEntry alloc]
211 y_pos = NSMaxY([[checkboxes_ lastObject] frame]) + kCheckboxMargin; 161 initWithFrame:NSZeroRect
162 controller:this
163 prefId:scan_result.pref_info.pref_id
164 galleryName:scan_result.pref_info.GetGalleryDisplayName()
165 subscript:scan_result.pref_info.GetGalleryAdditionalDetails()
166 tooltip:scan_result.pref_info.GetGalleryTooltip()
167 showFolderViewer:scan_result.pref_info.IsGalleryAvailable()]);
168
169 [checkbox_entry setState:scan_result.selected];
170
171 NSRect entry_rect = [checkbox_entry frame];
172 entry_rect.origin.y = y_pos;
173 [checkbox_entry setFrame:entry_rect];
174 [checkbox_container_ addSubview:checkbox_entry];
175 y_pos = NSMaxY(entry_rect) + kCheckboxLeading;
212 } 176 }
213 177
214 return y_pos; 178 return y_pos;
215 } 179 }
216 180
217 void MediaGalleriesScanResultDialogCocoa::OnAcceptClicked() { 181 void MediaGalleriesScanResultDialogCocoa::OnAcceptClicked() {
218 accepted_ = true; 182 accepted_ = true;
219 183
220 if (window_) 184 if (window_)
221 window_->CloseWebContentsModalDialog(); 185 window_->CloseWebContentsModalDialog();
222 } 186 }
223 187
224 void MediaGalleriesScanResultDialogCocoa::OnCancelClicked() { 188 void MediaGalleriesScanResultDialogCocoa::OnCancelClicked() {
225 if (window_) 189 if (window_)
226 window_->CloseWebContentsModalDialog(); 190 window_->CloseWebContentsModalDialog();
227 } 191 }
228 192
229 void MediaGalleriesScanResultDialogCocoa::OnCheckboxToggled(
230 NSButton* button) {
231 [[[alert_ buttons] objectAtIndex:0] setEnabled:YES];
232
233 MediaGalleriesScanResultButton* checkbox =
234 (MediaGalleriesScanResultButton*) button;
235 controller_->DidToggleGalleryId([checkbox prefId],
236 [checkbox state] == NSOnState);
237 }
238
239 void MediaGalleriesScanResultDialogCocoa::OnFolderViewClicked(
240 NSButton* button) {
241 MediaGalleriesScanResultButton* checkbox =
242 base::mac::ObjCCastStrict<MediaGalleriesScanResultButton>(button);
243 controller_->DidClickOpenFolderViewer([checkbox prefId]);
244 }
245
246 void MediaGalleriesScanResultDialogCocoa::UpdateScanResultCheckbox(
247 const MediaGalleryPrefInfo& gallery,
248 bool selected,
249 CGFloat y_pos) {
250 // Checkbox.
251 base::scoped_nsobject<MediaGalleriesScanResultButton> checkbox(
252 [[MediaGalleriesScanResultButton alloc] initWithFrame:NSZeroRect
253 dialog:this
254 prefId:gallery.pref_id]);
255 [[checkbox cell] setLineBreakMode:NSLineBreakByTruncatingMiddle];
256 [checkbox setButtonType:NSSwitchButton];
257 [checkbox setTarget:cocoa_controller_];
258 [checkbox setAction:@selector(onCheckboxToggled:)];
259 [checkboxes_ addObject:checkbox];
260
261 [checkbox setTitle:base::SysUTF16ToNSString(
262 gallery.GetGalleryDisplayName())];
263 [checkbox setToolTip:base::SysUTF16ToNSString(gallery.GetGalleryTooltip())];
264 [checkbox setState:selected ? NSOnState : NSOffState];
265 [checkbox sizeToFit];
266 NSRect checkbox_rect = [checkbox bounds];
267
268 // Folder viewer button.
269 NSRect folder_viewer_rect = NSZeroRect;
270 base::scoped_nsobject<MediaGalleriesScanResultButton> folder_viewer;
271 if (gallery.IsGalleryAvailable()) {
272 folder_viewer.reset(
273 [[MediaGalleriesScanResultButton alloc] initWithFrame:NSZeroRect
274 dialog:this
275 prefId:gallery.pref_id]);
276 [folder_viewer setButtonType:NSMomentaryChangeButton];
277 [folder_viewer setTarget:cocoa_controller_];
278 [folder_viewer setAction:@selector(onFolderViewClicked:)];
279
280 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
281 [folder_viewer setImage:rb.GetNativeImageNamed(
282 IDR_FILE_FOLDER).ToNSImage()];
283 [folder_viewer setTitle:nil];
284 [folder_viewer setBordered:false];
285 [folder_viewer setToolTip:
286 base::SysUTF16ToNSString(gallery.GetGalleryTooltip())];
287 [folder_viewer sizeToFit];
288 folder_viewer_rect = [folder_viewer bounds];
289 } else {
290 folder_viewer_rect.size.width = -kCheckboxMargin;
291 }
292
293 // Additional details text.
294 base::scoped_nsobject<NSTextField> details(
295 [[NSTextField alloc] initWithFrame:NSZeroRect]);
296 [[details cell] setLineBreakMode:NSLineBreakByTruncatingHead];
297 [details setEditable:NO];
298 [details setSelectable:NO];
299 [details setBezeled:NO];
300 [details setAttributedStringValue:
301 constrained_window::GetAttributedLabelString(
302 base::SysUTF16ToNSString(gallery.GetGalleryAdditionalDetails()),
303 chrome_style::kTextFontStyle,
304 NSNaturalTextAlignment,
305 NSLineBreakByClipping
306 )];
307 [details setTextColor:[NSColor colorWithCalibratedRed:kDetailGray
308 green:kDetailGray
309 blue:kDetailGray
310 alpha:1.0]];
311 [details sizeToFit];
312 NSRect details_rect = [details bounds];
313
314 // Size the views. If all the elements don't naturally fit, the checkbox
315 // should get squished and will elide in the middle. However, it shouldn't
316 // squish too much so it gets at least half of the max width and the details
317 // text should elide as well in that case.
318 int natural_width = NSWidth(checkbox_rect) + NSWidth(folder_viewer_rect) +
319 NSWidth(details_rect) + 5 * kCheckboxMargin;
320 if (natural_width > kCheckboxMaxWidth) {
321 int max_content = kCheckboxMaxWidth - 5 * kCheckboxMargin;
322 if (NSWidth(folder_viewer_rect) + NSWidth(details_rect) > max_content / 2) {
323 details_rect.size.width = std::max(
324 max_content / 2 - NSWidth(folder_viewer_rect),
325 max_content - NSWidth(checkbox_rect) - NSWidth(folder_viewer_rect));
326 }
327 checkbox_rect.size.width =
328 max_content - NSWidth(folder_viewer_rect) - NSWidth(details_rect);
329 }
330
331 checkbox_rect.origin = NSMakePoint(kCheckboxMargin, y_pos);
332 [checkbox setFrame:checkbox_rect];
333 [checkbox_container_ addSubview:checkbox];
334
335 folder_viewer_rect.origin =
336 NSMakePoint(NSMaxX(checkbox_rect) + kCheckboxMargin, y_pos);
337 if (gallery.IsGalleryAvailable()) {
338 [folder_viewer setFrame:folder_viewer_rect];
339 [checkbox_container_ addSubview:folder_viewer];
340 }
341
342 details_rect.origin =
343 NSMakePoint(NSMaxX(folder_viewer_rect) + kCheckboxMargin, y_pos - 1);
344 [details setFrame:details_rect];
345 [checkbox_container_ addSubview:details];
346 }
347
348 void MediaGalleriesScanResultDialogCocoa::UpdateResults() { 193 void MediaGalleriesScanResultDialogCocoa::UpdateResults() {
349 InitDialogControls(); 194 InitDialogControls();
350 } 195 }
351 196
352 void MediaGalleriesScanResultDialogCocoa::OnConstrainedWindowClosed( 197 void MediaGalleriesScanResultDialogCocoa::OnConstrainedWindowClosed(
353 ConstrainedWindowMac* window) { 198 ConstrainedWindowMac* window) {
354 controller_->DialogFinished(accepted_); 199 controller_->DialogFinished(accepted_);
355 } 200 }
356 201
202 void MediaGalleriesScanResultDialogCocoa::OnCheckboxToggled(
203 MediaGalleryPrefId prefId, bool checked) {
204 controller_->DidToggleGalleryId(prefId, checked);
205 }
206
207 void MediaGalleriesScanResultDialogCocoa::OnFolderViewerClicked(
208 MediaGalleryPrefId prefId) {
209 controller_->DidClickOpenFolderViewer(prefId);
210 }
211
357 ui::MenuModel* MediaGalleriesScanResultDialogCocoa::GetContextMenu( 212 ui::MenuModel* MediaGalleriesScanResultDialogCocoa::GetContextMenu(
358 MediaGalleryPrefId prefid) { 213 MediaGalleryPrefId pref_id) {
359 return controller_->GetContextMenu(prefid); 214 return controller_->GetContextMenu(pref_id);
360 } 215 }
361 216
362 // static 217 // static
363 MediaGalleriesScanResultDialog* MediaGalleriesScanResultDialog::Create( 218 MediaGalleriesScanResultDialog* MediaGalleriesScanResultDialog::Create(
364 MediaGalleriesScanResultDialogController* controller) { 219 MediaGalleriesScanResultDialogController* controller) {
365 base::scoped_nsobject<MediaGalleriesScanResultCocoaController> 220 base::scoped_nsobject<MediaGalleriesScanResultCocoaController>
366 cocoa_controller([[MediaGalleriesScanResultCocoaController alloc] init]); 221 cocoa_controller([[MediaGalleriesScanResultCocoaController alloc] init]);
367 return new MediaGalleriesScanResultDialogCocoa(controller, cocoa_controller); 222 return new MediaGalleriesScanResultDialogCocoa(controller, cocoa_controller);
368 } 223 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698