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

Side by Side Diff: chrome/browser/ui/cocoa/autofill/autofill_dialog_window_controller.mm

Issue 77283002: [rAc OSX] Factor out AutofillHeader class to contain dialog header elements. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix compile after rebase Created 7 years, 1 month 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 #import "chrome/browser/ui/cocoa/autofill/autofill_dialog_window_controller.h" 5 #import "chrome/browser/ui/cocoa/autofill/autofill_dialog_window_controller.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/autofill/autofill_dialog_view_delegate.h" 10 #include "chrome/browser/ui/autofill/autofill_dialog_view_delegate.h"
11 #include "chrome/browser/ui/chrome_style.h" 11 #include "chrome/browser/ui/chrome_style.h"
12 #import "chrome/browser/ui/cocoa/autofill/autofill_account_chooser.h"
13 #include "chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.h" 12 #include "chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.h"
14 #include "chrome/browser/ui/cocoa/autofill/autofill_dialog_constants.h" 13 #include "chrome/browser/ui/cocoa/autofill/autofill_dialog_constants.h"
14 #import "chrome/browser/ui/cocoa/autofill/autofill_header.h"
15 #import "chrome/browser/ui/cocoa/autofill/autofill_input_field.h" 15 #import "chrome/browser/ui/cocoa/autofill/autofill_input_field.h"
16 #import "chrome/browser/ui/cocoa/autofill/autofill_loading_shield_controller.h" 16 #import "chrome/browser/ui/cocoa/autofill/autofill_loading_shield_controller.h"
17 #import "chrome/browser/ui/cocoa/autofill/autofill_main_container.h" 17 #import "chrome/browser/ui/cocoa/autofill/autofill_main_container.h"
18 #import "chrome/browser/ui/cocoa/autofill/autofill_overlay_controller.h" 18 #import "chrome/browser/ui/cocoa/autofill/autofill_overlay_controller.h"
19 #import "chrome/browser/ui/cocoa/autofill/autofill_section_container.h" 19 #import "chrome/browser/ui/cocoa/autofill/autofill_section_container.h"
20 #import "chrome/browser/ui/cocoa/autofill/autofill_sign_in_container.h" 20 #import "chrome/browser/ui/cocoa/autofill/autofill_sign_in_container.h"
21 #import "chrome/browser/ui/cocoa/autofill/autofill_textfield.h" 21 #import "chrome/browser/ui/cocoa/autofill/autofill_textfield.h"
22 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_wi ndow.h" 22 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_wi ndow.h"
23 #include "content/public/browser/web_contents.h" 23 #include "content/public/browser/web_contents.h"
24 #include "content/public/browser/web_contents_view.h" 24 #include "content/public/browser/web_contents_view.h"
25 #include "grit/generated_resources.h" 25 #include "grit/generated_resources.h"
26 #import "ui/base/cocoa/flipped_view.h" 26 #import "ui/base/cocoa/flipped_view.h"
27 #include "ui/base/cocoa/window_size_constants.h" 27 #include "ui/base/cocoa/window_size_constants.h"
28 #include "ui/base/l10n/l10n_util.h" 28 #include "ui/base/l10n/l10n_util.h"
29 29
30 namespace { 30 namespace {
31 const CGFloat kAccountChooserHeight = 20.0; 31
32 const CGFloat kMinimumContentsHeight = 101; 32 const CGFloat kMinimumContentsHeight = 101;
33 33
34 // Height of all decorations & paddings on main dialog together.
35 const CGFloat kDecorationHeight = kAccountChooserHeight +
36 autofill::kDetailVerticalPadding +
37 chrome_style::kClientBottomPadding +
38 chrome_style::kTitleTopPadding;
39 } // namespace 34 } // namespace
40 35
41 #pragma mark Field Editor 36 #pragma mark Field Editor
42 37
43 @interface AutofillDialogFieldEditor : NSTextView 38 @interface AutofillDialogFieldEditor : NSTextView
44 @end 39 @end
45 40
46 41
47 @implementation AutofillDialogFieldEditor 42 @implementation AutofillDialogFieldEditor
48 43
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 } 95 }
101 return fieldEditor_.get(); 96 return fieldEditor_.get();
102 } 97 }
103 98
104 @end 99 @end
105 100
106 101
107 @implementation AutofillDialogWindowController 102 @implementation AutofillDialogWindowController
108 103
109 - (id)initWithWebContents:(content::WebContents*)webContents 104 - (id)initWithWebContents:(content::WebContents*)webContents
110 autofillDialog:(autofill::AutofillDialogCocoa*)autofillDialog { 105 dialog:(autofill::AutofillDialogCocoa*)dialog {
111 DCHECK(webContents); 106 DCHECK(webContents);
112 107
113 base::scoped_nsobject<ConstrainedWindowCustomWindow> window( 108 base::scoped_nsobject<ConstrainedWindowCustomWindow> window(
114 [[ConstrainedWindowCustomWindow alloc] 109 [[ConstrainedWindowCustomWindow alloc]
115 initWithContentRect:ui::kWindowSizeDeterminedLater]); 110 initWithContentRect:ui::kWindowSizeDeterminedLater]);
116 111
117 if ((self = [super initWithWindow:window])) { 112 if ((self = [super initWithWindow:window])) {
118 [window setDelegate:self]; 113 [window setDelegate:self];
119 webContents_ = webContents; 114 webContents_ = webContents;
120 autofillDialog_ = autofillDialog; 115 dialog_ = dialog;
116
117 header_.reset([[AutofillHeader alloc] initWithDelegate:dialog->delegate()]);
121 118
122 mainContainer_.reset([[AutofillMainContainer alloc] 119 mainContainer_.reset([[AutofillMainContainer alloc]
123 initWithDelegate:autofillDialog->delegate()]); 120 initWithDelegate:dialog->delegate()]);
124 [mainContainer_ setTarget:self]; 121 [mainContainer_ setTarget:self];
125 122
126 signInContainer_.reset( 123 signInContainer_.reset(
127 [[AutofillSignInContainer alloc] initWithDialog:autofillDialog]); 124 [[AutofillSignInContainer alloc] initWithDialog:dialog]);
128 [[signInContainer_ view] setHidden:YES]; 125 [[signInContainer_ view] setHidden:YES];
129 126
130 // Set dialog title.
131 titleTextField_.reset([[NSTextField alloc] initWithFrame:NSZeroRect]);
132 [titleTextField_ setEditable:NO];
133 [titleTextField_ setBordered:NO];
134 [titleTextField_ setDrawsBackground:NO];
135 [titleTextField_ setFont:[NSFont systemFontOfSize:15.0]];
136 [titleTextField_ setStringValue:
137 base::SysUTF16ToNSString(autofillDialog->delegate()->DialogTitle())];
138 [titleTextField_ sizeToFit];
139
140 accountChooser_.reset([[AutofillAccountChooser alloc]
141 initWithFrame:NSZeroRect
142 delegate:autofillDialog->delegate()]);
143
144 loadingShieldController_.reset( 127 loadingShieldController_.reset(
145 [[AutofillLoadingShieldController alloc] 128 [[AutofillLoadingShieldController alloc] initWithDelegate:
146 initWithDelegate:autofillDialog->delegate()]); 129 dialog->delegate()]);
147 [[loadingShieldController_ view] setHidden:YES]; 130 [[loadingShieldController_ view] setHidden:YES];
148 131
149 overlayController_.reset( 132 overlayController_.reset(
150 [[AutofillOverlayController alloc] initWithDelegate: 133 [[AutofillOverlayController alloc] initWithDelegate:
151 autofillDialog->delegate()]); 134 dialog->delegate()]);
152 [[overlayController_ view] setHidden:YES]; 135 [[overlayController_ view] setHidden:YES];
153 136
154 // This needs a flipped content view because otherwise the size 137 // This needs a flipped content view because otherwise the size
155 // animation looks odd. However, replacing the contentView for constrained 138 // animation looks odd. However, replacing the contentView for constrained
156 // windows does not work - it does custom rendering. 139 // windows does not work - it does custom rendering.
157 base::scoped_nsobject<NSView> flippedContentView( 140 base::scoped_nsobject<NSView> flippedContentView(
158 [[FlippedView alloc] initWithFrame: 141 [[FlippedView alloc] initWithFrame:
159 [[[self window] contentView] frame]]); 142 [[[self window] contentView] frame]]);
160 [flippedContentView setSubviews: 143 [flippedContentView setSubviews:
161 @[accountChooser_, 144 @[[header_ view],
162 titleTextField_,
163 [mainContainer_ view], 145 [mainContainer_ view],
164 [signInContainer_ view], 146 [signInContainer_ view],
165 [loadingShieldController_ view], 147 [loadingShieldController_ view],
166 [overlayController_ view]]]; 148 [overlayController_ view]]];
167 [flippedContentView setAutoresizingMask: 149 [flippedContentView setAutoresizingMask:
168 (NSViewWidthSizable | NSViewHeightSizable)]; 150 (NSViewWidthSizable | NSViewHeightSizable)];
169 [[[self window] contentView] addSubview:flippedContentView]; 151 [[[self window] contentView] addSubview:flippedContentView];
170 [mainContainer_ setAnchorView:[[accountChooser_ subviews] objectAtIndex:1]]; 152 [mainContainer_ setAnchorView:[header_ anchorView]];
171 } 153 }
172 return self; 154 return self;
173 } 155 }
174 156
175 - (void)dealloc { 157 - (void)dealloc {
176 [[NSNotificationCenter defaultCenter] removeObserver:self]; 158 [[NSNotificationCenter defaultCenter] removeObserver:self];
177 [super dealloc]; 159 [super dealloc];
178 } 160 }
179 161
180 - (CGFloat)maxHeight { 162 - (CGFloat)maxHeight {
181 NSRect dialogFrameRect = [[self window] frame]; 163 NSRect dialogFrameRect = [[self window] frame];
182 NSRect browserFrameRect = 164 NSRect browserFrameRect =
183 [webContents_->GetView()->GetTopLevelNativeWindow() frame]; 165 [webContents_->GetView()->GetTopLevelNativeWindow() frame];
184 dialogFrameRect.size.height = 166 dialogFrameRect.size.height =
185 NSMaxY(dialogFrameRect) - NSMinY(browserFrameRect); 167 NSMaxY(dialogFrameRect) - NSMinY(browserFrameRect);
186 dialogFrameRect = [[self window] contentRectForFrameRect:dialogFrameRect]; 168 dialogFrameRect = [[self window] contentRectForFrameRect:dialogFrameRect];
187 return NSHeight(dialogFrameRect); 169 return NSHeight(dialogFrameRect);
188 } 170 }
189 171
190 - (void)updateSignInSizeConstraints { 172 - (void)updateSignInSizeConstraints {
191 // Adjust for the size of all decorations and paddings outside main content. 173 // Adjust for the size of all decorations and paddings outside main content.
192 CGFloat minHeight = kMinimumContentsHeight - kDecorationHeight; 174 CGFloat decorationHeight =
193 CGFloat maxHeight = std::max([self maxHeight] - kDecorationHeight, minHeight); 175 [[header_ view] frame].size.height + chrome_style::kClientBottomPadding;
176 CGFloat minHeight = kMinimumContentsHeight - decorationHeight;
177 CGFloat maxHeight = std::max([self maxHeight] - decorationHeight, minHeight);
194 CGFloat width = NSWidth([[[self window] contentView] frame]); 178 CGFloat width = NSWidth([[[self window] contentView] frame]);
195 179
196 [signInContainer_ constrainSizeToMinimum:NSMakeSize(width, minHeight) 180 [signInContainer_ constrainSizeToMinimum:NSMakeSize(width, minHeight)
197 maximum:NSMakeSize(width, maxHeight)]; 181 maximum:NSMakeSize(width, maxHeight)];
198 } 182 }
199 183
200 - (void)onContentViewFrameDidChange:(NSNotification*)notification { 184 - (void)onContentViewFrameDidChange:(NSNotification*)notification {
201 [self updateSignInSizeConstraints]; 185 [self updateSignInSizeConstraints];
202 if ([[signInContainer_ view] isHidden]) 186 if ([[signInContainer_ view] isHidden])
203 [self requestRelayout]; 187 [self requestRelayout];
(...skipping 15 matching lines...) Expand all
219 203
220 if (![[overlayController_ view] isHidden]) { 204 if (![[overlayController_ view] isHidden]) {
221 size.height = [overlayController_ heightForWidth:size.width]; 205 size.height = [overlayController_ heightForWidth:size.width];
222 } else { 206 } else {
223 // Overall size is determined by either main container or sign in view. 207 // Overall size is determined by either main container or sign in view.
224 if ([[signInContainer_ view] isHidden]) 208 if ([[signInContainer_ view] isHidden])
225 size = [mainContainer_ preferredSize]; 209 size = [mainContainer_ preferredSize];
226 else 210 else
227 size = [signInContainer_ preferredSize]; 211 size = [signInContainer_ preferredSize];
228 212
229 // Always make room for the header. 213 // Always make room for the header and bottom padding.
230 size.height += kDecorationHeight; 214 size.height +=
215 [header_ heightForWidth:size.width] +
216 chrome_style::kClientBottomPadding;
231 } 217 }
232 218
233 // Show as much of the main view as is possible without going past the 219 // Show as much of the main view as is possible without going past the
234 // bottom of the browser window. 220 // bottom of the browser window.
235 size.height = std::min(size.height, [self maxHeight]); 221 size.height = std::min(size.height, [self maxHeight]);
236 222
237 return size; 223 return size;
238 } 224 }
239 225
240 - (void)performLayout { 226 - (void)performLayout {
241 NSRect contentRect = NSZeroRect; 227 NSRect contentRect = NSZeroRect;
242 contentRect.size = [self preferredSize]; 228 contentRect.size = [self preferredSize];
243 NSRect clientRect = contentRect; 229 NSRect clientRect = contentRect;
244 clientRect.origin.y = chrome_style::kTitleTopPadding; 230 clientRect.size.height -= chrome_style::kClientBottomPadding;
245 clientRect.size.height -= chrome_style::kTitleTopPadding +
246 chrome_style::kClientBottomPadding;
247 231
248 [titleTextField_ setStringValue: 232 CGFloat headerHeight = [header_ heightForWidth:NSWidth(clientRect)];
249 base::SysUTF16ToNSString(autofillDialog_->delegate()->DialogTitle())]; 233 NSRect headerRect, mainRect;
250 [titleTextField_ sizeToFit]; 234 NSDivideRect(clientRect, &headerRect, &mainRect, headerHeight, NSMinYEdge);
251 235
252 NSRect headerRect, mainRect, titleRect, dummyRect; 236 [[header_ view] setFrame:headerRect];
253 NSDivideRect(clientRect, &headerRect, &mainRect, 237 [header_ performLayout];
254 kAccountChooserHeight, NSMinYEdge);
255 NSDivideRect(mainRect, &dummyRect, &mainRect,
256 autofill::kDetailVerticalPadding, NSMinYEdge);
257 headerRect = NSInsetRect(headerRect, chrome_style::kHorizontalPadding, 0);
258 NSDivideRect(headerRect, &titleRect, &headerRect,
259 NSWidth([titleTextField_ frame]), NSMinXEdge);
260 238
261 // Align baseline of title with bottom of accountChooser.
262 base::scoped_nsobject<NSLayoutManager> layout_manager(
263 [[NSLayoutManager alloc] init]);
264 NSFont* titleFont = [titleTextField_ font];
265 titleRect.origin.y += NSHeight(titleRect) -
266 [layout_manager defaultBaselineOffsetForFont:titleFont];
267 [titleTextField_ setFrame:titleRect];
268
269 [accountChooser_ setFrame:headerRect];
270 [accountChooser_ performLayout];
271 if ([[signInContainer_ view] isHidden]) { 239 if ([[signInContainer_ view] isHidden]) {
272 [[mainContainer_ view] setFrame:mainRect]; 240 [[mainContainer_ view] setFrame:mainRect];
273 [mainContainer_ performLayout]; 241 [mainContainer_ performLayout];
274 } else { 242 } else {
275 [[signInContainer_ view] setFrame:mainRect]; 243 [[signInContainer_ view] setFrame:mainRect];
276 } 244 }
277 245
278 [[loadingShieldController_ view] setFrame:contentRect]; 246 [[loadingShieldController_ view] setFrame:contentRect];
279 [loadingShieldController_ performLayout]; 247 [loadingShieldController_ performLayout];
280 248
281 [[overlayController_ view] setFrame:contentRect]; 249 [[overlayController_ view] setFrame:contentRect];
282 [overlayController_ performLayout]; 250 [overlayController_ performLayout];
283 251
284 NSRect frameRect = [[self window] frameRectForContentRect:contentRect]; 252 NSRect frameRect = [[self window] frameRectForContentRect:contentRect];
285 [[self window] setFrame:frameRect display:YES]; 253 [[self window] setFrame:frameRect display:YES];
286 [[self window] recalculateKeyViewLoop]; 254 [[self window] recalculateKeyViewLoop];
287 } 255 }
288 256
289 - (IBAction)accept:(id)sender { 257 - (IBAction)accept:(id)sender {
290 if ([mainContainer_ validate]) 258 if ([mainContainer_ validate])
291 autofillDialog_->delegate()->OnAccept(); 259 dialog_->delegate()->OnAccept();
292 else 260 else
293 [mainContainer_ makeFirstInvalidInputFirstResponder]; 261 [mainContainer_ makeFirstInvalidInputFirstResponder];
294 } 262 }
295 263
296 - (IBAction)cancel:(id)sender { 264 - (IBAction)cancel:(id)sender {
297 autofillDialog_->delegate()->OnCancel(); 265 dialog_->delegate()->OnCancel();
298 autofillDialog_->PerformClose(); 266 dialog_->PerformClose();
299 } 267 }
300 268
301 - (void)show { 269 - (void)show {
302 // Resizing the browser causes the ConstrainedWindow to move. 270 // Resizing the browser causes the ConstrainedWindow to move.
303 // Observe that to allow resizes based on browser size. 271 // Observe that to allow resizes based on browser size.
304 // NOTE: This MUST come last after all initial setup is done, because there 272 // NOTE: This MUST come last after all initial setup is done, because there
305 // is an immediate notification post registration. 273 // is an immediate notification post registration.
306 DCHECK([self window]); 274 DCHECK([self window]);
307 [[NSNotificationCenter defaultCenter] 275 [[NSNotificationCenter defaultCenter]
308 addObserver:self 276 addObserver:self
309 selector:@selector(onContentViewFrameDidChange:) 277 selector:@selector(onContentViewFrameDidChange:)
310 name:NSWindowDidMoveNotification 278 name:NSWindowDidMoveNotification
311 object:[self window]]; 279 object:[self window]];
312 280
313 [self updateAccountChooser]; 281 [self updateAccountChooser];
314 [self updateNotificationArea]; 282 [self updateNotificationArea];
315 [self requestRelayout]; 283 [self requestRelayout];
316 } 284 }
317 285
318 - (void)hide { 286 - (void)hide {
319 autofillDialog_->delegate()->OnCancel(); 287 dialog_->delegate()->OnCancel();
320 autofillDialog_->PerformClose(); 288 dialog_->PerformClose();
321 } 289 }
322 290
323 - (void)updateNotificationArea { 291 - (void)updateNotificationArea {
324 [mainContainer_ updateNotificationArea]; 292 [mainContainer_ updateNotificationArea];
325 } 293 }
326 294
327 - (void)updateAccountChooser { 295 - (void)updateAccountChooser {
328 [accountChooser_ update]; 296 [header_ update];
329 [mainContainer_ updateLegalDocuments]; 297 [mainContainer_ updateLegalDocuments];
330 298
331 // For the duration of the loading shield, hide the main contents. 299 // For the duration of the loading shield, hide the main contents.
332 // This prevents the currently focused text field "shining through". 300 // This prevents the currently focused text field "shining through".
333 // No need to remember previous state, because the loading shield 301 // No need to remember previous state, because the loading shield
334 // always flows through to the main container. 302 // always flows through to the main container.
335 [loadingShieldController_ update]; 303 [loadingShieldController_ update];
336 [[mainContainer_ view] setHidden:![[loadingShieldController_ view] isHidden]]; 304 [[mainContainer_ view] setHidden:![[loadingShieldController_ view] isHidden]];
337 } 305 }
338 306
339 - (void)updateButtonStrip { 307 - (void)updateButtonStrip {
340 // For the duration of the overlay, hide the main contents and the header. 308 // For the duration of the overlay, hide the main contents and the header.
341 // This prevents the currently focused text field "shining through". No need 309 // This prevents the currently focused text field "shining through". No need
342 // to remember previous state, because the overlay view is always the last 310 // to remember previous state, because the overlay view is always the last
343 // state of the dialog. 311 // state of the dialog.
344 [overlayController_ updateState]; 312 [overlayController_ updateState];
345 [accountChooser_ setHidden:![[overlayController_ view] isHidden]]; 313 [[header_ view] setHidden:![[overlayController_ view] isHidden]];
346 [[mainContainer_ view] setHidden:![[overlayController_ view] isHidden]]; 314 [[mainContainer_ view] setHidden:![[overlayController_ view] isHidden]];
347 } 315 }
348 316
349 - (void)updateSection:(autofill::DialogSection)section { 317 - (void)updateSection:(autofill::DialogSection)section {
350 [[mainContainer_ sectionForId:section] update]; 318 [[mainContainer_ sectionForId:section] update];
351 [mainContainer_ updateSaveInChrome]; 319 [mainContainer_ updateSaveInChrome];
352 } 320 }
353 321
354 - (void)fillSection:(autofill::DialogSection)section 322 - (void)fillSection:(autofill::DialogSection)section
355 forInput:(const autofill::DetailInput&)input { 323 forInput:(const autofill::DetailInput&)input {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 401
434 - (content::WebContents*)getSignInWebContents { 402 - (content::WebContents*)getSignInWebContents {
435 return [signInContainer_ webContents]; 403 return [signInContainer_ webContents];
436 } 404 }
437 405
438 - (BOOL)isShowingOverlay { 406 - (BOOL)isShowingOverlay {
439 return ![[overlayController_ view] isHidden]; 407 return ![[overlayController_ view] isHidden];
440 } 408 }
441 409
442 @end 410 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698