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

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: Layout in place Created 6 years, 7 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 const CGFloat kCheckboxLeading = 10;
21 const CGFloat kCheckboxWidth = 440;
22 const CGFloat kScrollAreaHeight = 220;
24 23
25 // Controller for UI events on items in the media galleries dialog. 24 // Controller for UI events on items in the media galleries dialog.
26 @interface MediaGalleriesScanResultCocoaController : NSObject { 25 @interface MediaGalleriesScanResultCocoaController : NSObject {
27 @private 26 @private
28 MediaGalleriesScanResultDialogCocoa* dialog_; 27 MediaGalleriesScanResultDialogCocoa* dialog_;
29 } 28 }
30 29
31 @property(assign, nonatomic) MediaGalleriesScanResultDialogCocoa* dialog; 30 @property(assign, nonatomic) MediaGalleriesScanResultDialogCocoa* dialog;
32 31
32 - (void)onAcceptButton:(id)sender;
33 - (void)onCancelButton:(id)sender;
34
33 @end 35 @end
34 36
35 @implementation MediaGalleriesScanResultCocoaController 37 @implementation MediaGalleriesScanResultCocoaController
36 38
37 @synthesize dialog = dialog_; 39 @synthesize dialog = dialog_;
38 40
39 - (void)onAcceptButton:(id)sender { 41 - (void)onAcceptButton:(id)sender {
40 dialog_->OnAcceptClicked(); 42 dialog_->OnAcceptClicked();
41 } 43 }
42 44
43 - (void)onCancelButton:(id)sender { 45 - (void)onCancelButton:(id)sender {
44 dialog_->OnCancelClicked(); 46 dialog_->OnCancelClicked();
45 } 47 }
46 48
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 49 @end
58 50
59 51
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( 52 MediaGalleriesScanResultDialogCocoa::MediaGalleriesScanResultDialogCocoa(
108 MediaGalleriesScanResultDialogController* controller, 53 MediaGalleriesScanResultDialogController* controller,
109 MediaGalleriesScanResultCocoaController* cocoa_controller) 54 MediaGalleriesScanResultCocoaController* cocoa_controller)
110 : controller_(controller), 55 : controller_(controller),
111 accepted_(false), 56 accepted_(false),
112 cocoa_controller_([cocoa_controller retain]) { 57 cocoa_controller_([cocoa_controller retain]) {
113 [cocoa_controller_ setDialog:this]; 58 [cocoa_controller_ setDialog:this];
114 59
115 alert_.reset([[ConstrainedWindowAlert alloc] init]); 60 alert_.reset([[ConstrainedWindowAlert alloc] init]);
116 61
(...skipping 29 matching lines...) Expand all
146 } 91 }
147 92
148 void MediaGalleriesScanResultDialogCocoa::InitDialogControls() { 93 void MediaGalleriesScanResultDialogCocoa::InitDialogControls() {
149 main_container_.reset([[NSBox alloc] init]); 94 main_container_.reset([[NSBox alloc] init]);
150 [main_container_ setBoxType:NSBoxCustom]; 95 [main_container_ setBoxType:NSBoxCustom];
151 [main_container_ setBorderType:NSLineBorder]; 96 [main_container_ setBorderType:NSLineBorder];
152 [main_container_ setBorderWidth:1]; 97 [main_container_ setBorderWidth:1];
153 [main_container_ setCornerRadius:0]; 98 [main_container_ setCornerRadius:0];
154 [main_container_ setContentViewMargins:NSZeroSize]; 99 [main_container_ setContentViewMargins:NSZeroSize];
155 [main_container_ setTitlePosition:NSNoTitle]; 100 [main_container_ setTitlePosition:NSNoTitle];
156 [main_container_ setBorderColor:[NSColor colorWithCalibratedRed:kDetailGray 101 [main_container_ setBorderColor:[NSColor disabledControlTextColor]];
157 green:kDetailGray
158 blue:kDetailGray
159 alpha:1.0]];
160 102
161 base::scoped_nsobject<NSScrollView> scroll_view( 103 base::scoped_nsobject<NSScrollView> scroll_view(
162 [[NSScrollView alloc] initWithFrame: 104 [[NSScrollView alloc] initWithFrame:
163 NSMakeRect(0, 0, kCheckboxMaxWidth, kScrollAreaHeight)]); 105 NSMakeRect(0, 0, kCheckboxWidth, kScrollAreaHeight)]);
164 [scroll_view setHasVerticalScroller:YES]; 106 [scroll_view setHasVerticalScroller:YES];
165 [scroll_view setHasHorizontalScroller:NO]; 107 [scroll_view setHasHorizontalScroller:NO];
166 [scroll_view setBorderType:NSNoBorder]; 108 [scroll_view setBorderType:NSNoBorder];
167 [scroll_view setAutohidesScrollers:YES]; 109 [scroll_view setAutohidesScrollers:YES];
168 [[main_container_ contentView] addSubview:scroll_view]; 110 [[main_container_ contentView] addSubview:scroll_view];
169 111
170 // Add scan results checkboxes inside the scrolling view. 112 // Add scan results checkboxes inside the scrolling view.
171 checkbox_container_.reset([[FlippedView alloc] initWithFrame:NSZeroRect]); 113 checkbox_container_.reset([[FlippedView alloc] initWithFrame:NSZeroRect]);
172 checkboxes_.reset([[NSMutableArray alloc] init]); 114 CGFloat height = CreateCheckboxes();
groby-ooo-7-16 2014/04/28 22:17:12 Not suggesting you change this, just as an FYI: In
115 // Give the container a reasonable initial size so that the scroll_view can
116 // figure out the content size.
117 [checkbox_container_ setFrameSize:NSMakeSize(kCheckboxWidth, height)];
173 [scroll_view setDocumentView:checkbox_container_]; 118 [scroll_view setDocumentView:checkbox_container_];
174 119 [checkbox_container_ setFrameSize:NSMakeSize([scroll_view contentSize].width,
175 CGFloat y_pos = 0; 120 height)];
176
177 y_pos = CreateCheckboxes(y_pos, controller_->GetGalleryList());
178
179 [checkbox_container_ setFrame:NSMakeRect(0, 0, kCheckboxMaxWidth, y_pos + 2)];
180 121
181 // Resize to pack the scroll view if possible. 122 // Resize to pack the scroll view if possible.
182 NSRect scroll_frame = [scroll_view frame]; 123 NSRect scroll_frame = [scroll_view frame];
183 if (NSHeight(scroll_frame) > NSHeight([checkbox_container_ frame])) { 124 if (NSHeight(scroll_frame) > NSHeight([checkbox_container_ frame])) {
184 scroll_frame.size.height = NSHeight([checkbox_container_ frame]); 125 scroll_frame.size.height = NSHeight([checkbox_container_ frame]);
185 [scroll_view setFrame:scroll_frame]; 126 [scroll_view setFrameSize:scroll_frame.size];
186 } 127 }
187 128
188 [main_container_ setFrameFromContentFrame:scroll_frame]; 129 [main_container_ setFrameFromContentFrame:scroll_frame];
130 [main_container_ setFrameOrigin:NSZeroPoint];
189 [alert_ setAccessoryView:main_container_]; 131 [alert_ setAccessoryView:main_container_];
190
191 [alert_ layout]; 132 [alert_ layout];
192 } 133 }
193 134
194 void MediaGalleriesScanResultDialogCocoa::AcceptDialogForTesting() { 135 void MediaGalleriesScanResultDialogCocoa::AcceptDialogForTesting() {
195 OnAcceptClicked(); 136 OnAcceptClicked();
196 } 137 }
197 138
198 CGFloat MediaGalleriesScanResultDialogCocoa::CreateCheckboxes( 139 CGFloat MediaGalleriesScanResultDialogCocoa::CreateCheckboxes() {
199 CGFloat y_pos, 140 CGFloat y_pos = 0;
200 const MediaGalleriesScanResultDialogController::OrderedScanResults& 141 MediaGalleriesScanResultDialogController::OrderedScanResults scan_results =
201 scan_results) { 142 controller_->GetGalleryList();
202 y_pos += kCheckboxMargin;
203
204 for (MediaGalleriesScanResultDialogController::OrderedScanResults:: 143 for (MediaGalleriesScanResultDialogController::OrderedScanResults::
205 const_iterator iter = scan_results.begin(); 144 const_iterator iter = scan_results.begin();
206 iter != scan_results.end(); iter++) { 145 iter != scan_results.end(); iter++) {
207 const MediaGalleriesScanResultDialogController::ScanResult& scan_result = 146 const MediaGalleriesScanResultDialogController::ScanResult& scan_result =
208 *iter; 147 *iter;
209 UpdateScanResultCheckbox(scan_result.pref_info, scan_result.selected, 148 base::scoped_nsobject<MediaGalleryListEntry> checkbox_entry(
210 y_pos); 149 [[MediaGalleryListEntry alloc]
211 y_pos = NSMaxY([[checkboxes_ lastObject] frame]) + kCheckboxMargin; 150 initWithFrame:NSZeroRect
151 controller:this
152 prefId:scan_result.pref_info.pref_id
153 galleryName:scan_result.pref_info.GetGalleryDisplayName()
154 subscript:scan_result.pref_info.GetGalleryAdditionalDetails()
155 tooltip:scan_result.pref_info.GetGalleryTooltip()
156 showFolderViewer:scan_result.pref_info.IsGalleryAvailable()]);
157
158 [checkbox_entry setState:scan_result.selected];
159
160 [checkbox_entry setFrameOrigin:NSMakePoint(0, y_pos)];
161 y_pos = NSMaxY([checkbox_entry frame]) + kCheckboxLeading;
162
163 [checkbox_container_ addSubview:checkbox_entry];
212 } 164 }
213 165
214 return y_pos; 166 return y_pos;
215 } 167 }
216 168
217 void MediaGalleriesScanResultDialogCocoa::OnAcceptClicked() { 169 void MediaGalleriesScanResultDialogCocoa::OnAcceptClicked() {
218 accepted_ = true; 170 accepted_ = true;
219 171
220 if (window_) 172 if (window_)
221 window_->CloseWebContentsModalDialog(); 173 window_->CloseWebContentsModalDialog();
222 } 174 }
223 175
224 void MediaGalleriesScanResultDialogCocoa::OnCancelClicked() { 176 void MediaGalleriesScanResultDialogCocoa::OnCancelClicked() {
225 if (window_) 177 if (window_)
226 window_->CloseWebContentsModalDialog(); 178 window_->CloseWebContentsModalDialog();
227 } 179 }
228 180
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() { 181 void MediaGalleriesScanResultDialogCocoa::UpdateResults() {
349 InitDialogControls(); 182 InitDialogControls();
350 } 183 }
351 184
352 void MediaGalleriesScanResultDialogCocoa::OnConstrainedWindowClosed( 185 void MediaGalleriesScanResultDialogCocoa::OnConstrainedWindowClosed(
353 ConstrainedWindowMac* window) { 186 ConstrainedWindowMac* window) {
354 controller_->DialogFinished(accepted_); 187 controller_->DialogFinished(accepted_);
355 } 188 }
356 189
190 void MediaGalleriesScanResultDialogCocoa::OnCheckboxToggled(
191 MediaGalleryPrefId prefId, bool checked) {
192 controller_->DidToggleGalleryId(prefId, checked);
193 }
194
195 void MediaGalleriesScanResultDialogCocoa::OnFolderViewerClicked(
196 MediaGalleryPrefId prefId) {
197 controller_->DidClickOpenFolderViewer(prefId);
198 }
199
357 ui::MenuModel* MediaGalleriesScanResultDialogCocoa::GetContextMenu( 200 ui::MenuModel* MediaGalleriesScanResultDialogCocoa::GetContextMenu(
358 MediaGalleryPrefId prefid) { 201 MediaGalleryPrefId pref_id) {
359 return controller_->GetContextMenu(prefid); 202 return controller_->GetContextMenu(pref_id);
360 } 203 }
361 204
362 // static 205 // static
363 MediaGalleriesScanResultDialog* MediaGalleriesScanResultDialog::Create( 206 MediaGalleriesScanResultDialog* MediaGalleriesScanResultDialog::Create(
364 MediaGalleriesScanResultDialogController* controller) { 207 MediaGalleriesScanResultDialogController* controller) {
365 base::scoped_nsobject<MediaGalleriesScanResultCocoaController> 208 base::scoped_nsobject<MediaGalleriesScanResultCocoaController>
366 cocoa_controller([[MediaGalleriesScanResultCocoaController alloc] init]); 209 cocoa_controller([[MediaGalleriesScanResultCocoaController alloc] init]);
367 return new MediaGalleriesScanResultDialogCocoa(controller, cocoa_controller); 210 return new MediaGalleriesScanResultDialogCocoa(controller, cocoa_controller);
368 } 211 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698