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

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: Rebase and remove unused member variable 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 } 83 }
89 return fieldEditor_.get(); 84 return fieldEditor_.get();
90 } 85 }
91 86
92 @end 87 @end
93 88
94 89
95 @implementation AutofillDialogWindowController 90 @implementation AutofillDialogWindowController
96 91
97 - (id)initWithWebContents:(content::WebContents*)webContents 92 - (id)initWithWebContents:(content::WebContents*)webContents
98 autofillDialog:(autofill::AutofillDialogCocoa*)autofillDialog { 93 dialog:(autofill::AutofillDialogCocoa*)dialog {
99 DCHECK(webContents); 94 DCHECK(webContents);
100 95
101 base::scoped_nsobject<ConstrainedWindowCustomWindow> window( 96 base::scoped_nsobject<ConstrainedWindowCustomWindow> window(
102 [[ConstrainedWindowCustomWindow alloc] 97 [[ConstrainedWindowCustomWindow alloc]
103 initWithContentRect:ui::kWindowSizeDeterminedLater]); 98 initWithContentRect:ui::kWindowSizeDeterminedLater]);
104 99
105 if ((self = [super initWithWindow:window])) { 100 if ((self = [super initWithWindow:window])) {
106 [window setDelegate:self]; 101 [window setDelegate:self];
107 webContents_ = webContents; 102 webContents_ = webContents;
108 autofillDialog_ = autofillDialog; 103 dialog_ = dialog;
104
105 header_.reset([[AutofillHeader alloc] initWithDelegate:dialog->delegate()]);
109 106
110 mainContainer_.reset([[AutofillMainContainer alloc] 107 mainContainer_.reset([[AutofillMainContainer alloc]
111 initWithDelegate:autofillDialog->delegate()]); 108 initWithDelegate:dialog->delegate()]);
112 [mainContainer_ setTarget:self]; 109 [mainContainer_ setTarget:self];
113 110
114 signInContainer_.reset( 111 signInContainer_.reset(
115 [[AutofillSignInContainer alloc] initWithDialog:autofillDialog]); 112 [[AutofillSignInContainer alloc] initWithDialog:dialog]);
116 [[signInContainer_ view] setHidden:YES]; 113 [[signInContainer_ view] setHidden:YES];
117 114
118 // Set dialog title.
119 titleTextField_.reset([[NSTextField alloc] initWithFrame:NSZeroRect]);
120 [titleTextField_ setEditable:NO];
121 [titleTextField_ setBordered:NO];
122 [titleTextField_ setDrawsBackground:NO];
123 [titleTextField_ setFont:[NSFont systemFontOfSize:15.0]];
124 [titleTextField_ setStringValue:
125 base::SysUTF16ToNSString(autofillDialog->delegate()->DialogTitle())];
126 [titleTextField_ sizeToFit];
127
128 accountChooser_.reset([[AutofillAccountChooser alloc]
129 initWithFrame:NSZeroRect
130 delegate:autofillDialog->delegate()]);
131
132 loadingShieldController_.reset( 115 loadingShieldController_.reset(
133 [[AutofillLoadingShieldController alloc] 116 [[AutofillLoadingShieldController alloc] initWithDelegate:
134 initWithDelegate:autofillDialog->delegate()]); 117 dialog->delegate()]);
135 [[loadingShieldController_ view] setHidden:YES]; 118 [[loadingShieldController_ view] setHidden:YES];
136 119
137 overlayController_.reset( 120 overlayController_.reset(
138 [[AutofillOverlayController alloc] initWithDelegate: 121 [[AutofillOverlayController alloc] initWithDelegate:
139 autofillDialog->delegate()]); 122 dialog->delegate()]);
140 [[overlayController_ view] setHidden:YES]; 123 [[overlayController_ view] setHidden:YES];
141 124
142 // This needs a flipped content view because otherwise the size 125 // This needs a flipped content view because otherwise the size
143 // animation looks odd. However, replacing the contentView for constrained 126 // animation looks odd. However, replacing the contentView for constrained
144 // windows does not work - it does custom rendering. 127 // windows does not work - it does custom rendering.
145 base::scoped_nsobject<NSView> flippedContentView( 128 base::scoped_nsobject<NSView> flippedContentView(
146 [[FlippedView alloc] initWithFrame: 129 [[FlippedView alloc] initWithFrame:
147 [[[self window] contentView] frame]]); 130 [[[self window] contentView] frame]]);
148 [flippedContentView setSubviews: 131 [flippedContentView setSubviews:
149 @[accountChooser_, 132 @[header_,
150 titleTextField_,
151 [mainContainer_ view], 133 [mainContainer_ view],
152 [signInContainer_ view], 134 [signInContainer_ view],
153 [loadingShieldController_ view], 135 [loadingShieldController_ view],
154 [overlayController_ view]]]; 136 [overlayController_ view]]];
155 [flippedContentView setAutoresizingMask: 137 [flippedContentView setAutoresizingMask:
156 (NSViewWidthSizable | NSViewHeightSizable)]; 138 (NSViewWidthSizable | NSViewHeightSizable)];
157 [[[self window] contentView] addSubview:flippedContentView]; 139 [[[self window] contentView] addSubview:flippedContentView];
158 [mainContainer_ setAnchorView:[[accountChooser_ subviews] objectAtIndex:1]]; 140 [mainContainer_ setAnchorView:[header_ anchorView]];
159 } 141 }
160 return self; 142 return self;
161 } 143 }
162 144
163 - (void)dealloc { 145 - (void)dealloc {
164 [[NSNotificationCenter defaultCenter] removeObserver:self]; 146 [[NSNotificationCenter defaultCenter] removeObserver:self];
165 [super dealloc]; 147 [super dealloc];
166 } 148 }
167 149
168 - (CGFloat)maxHeight { 150 - (CGFloat)maxHeight {
169 NSRect dialogFrameRect = [[self window] frame]; 151 NSRect dialogFrameRect = [[self window] frame];
170 NSRect browserFrameRect = 152 NSRect browserFrameRect =
171 [webContents_->GetView()->GetTopLevelNativeWindow() frame]; 153 [webContents_->GetView()->GetTopLevelNativeWindow() frame];
172 dialogFrameRect.size.height = 154 dialogFrameRect.size.height =
173 NSMaxY(dialogFrameRect) - NSMinY(browserFrameRect); 155 NSMaxY(dialogFrameRect) - NSMinY(browserFrameRect);
174 dialogFrameRect = [[self window] contentRectForFrameRect:dialogFrameRect]; 156 dialogFrameRect = [[self window] contentRectForFrameRect:dialogFrameRect];
175 return NSHeight(dialogFrameRect); 157 return NSHeight(dialogFrameRect);
176 } 158 }
177 159
178 - (void)updateSignInSizeConstraints { 160 - (void)updateSignInSizeConstraints {
179 // Adjust for the size of all decorations and paddings outside main content. 161 // Adjust for the size of all decorations and paddings outside main content.
180 CGFloat minHeight = kMinimumContentsHeight - kDecorationHeight; 162 CGFloat decorationHeight =
181 CGFloat maxHeight = std::max([self maxHeight] - kDecorationHeight, minHeight); 163 [header_ frame].size.height + chrome_style::kClientBottomPadding;
164 CGFloat minHeight = kMinimumContentsHeight - decorationHeight;
165 CGFloat maxHeight = std::max([self maxHeight] - decorationHeight, minHeight);
182 CGFloat width = NSWidth([[[self window] contentView] frame]); 166 CGFloat width = NSWidth([[[self window] contentView] frame]);
183 167
184 [signInContainer_ constrainSizeToMinimum:NSMakeSize(width, minHeight) 168 [signInContainer_ constrainSizeToMinimum:NSMakeSize(width, minHeight)
185 maximum:NSMakeSize(width, maxHeight)]; 169 maximum:NSMakeSize(width, maxHeight)];
186 } 170 }
187 171
188 - (void)onContentViewFrameDidChange:(NSNotification*)notification { 172 - (void)onContentViewFrameDidChange:(NSNotification*)notification {
189 [self updateSignInSizeConstraints]; 173 [self updateSignInSizeConstraints];
190 if ([[signInContainer_ view] isHidden]) 174 if ([[signInContainer_ view] isHidden])
191 [self requestRelayout]; 175 [self requestRelayout];
(...skipping 12 matching lines...) Expand all
204 188
205 - (NSSize)preferredSize { 189 - (NSSize)preferredSize {
206 NSSize size; 190 NSSize size;
207 191
208 // Overall size is determined by either main container or sign in view. 192 // Overall size is determined by either main container or sign in view.
209 if ([[signInContainer_ view] isHidden]) 193 if ([[signInContainer_ view] isHidden])
210 size = [mainContainer_ preferredSize]; 194 size = [mainContainer_ preferredSize];
211 else 195 else
212 size = [signInContainer_ preferredSize]; 196 size = [signInContainer_ preferredSize];
213 197
214 // Always make room for the header. 198 // Always make room for the header.
groby-ooo-7-16 2013/11/22 14:51:38 This comment is confusing if combined with the bot
Ilya Sherman 2013/11/23 00:23:54 Done.
215 size.height += kDecorationHeight; 199 size.height +=
200 [header_ frame].size.height + chrome_style::kClientBottomPadding;
groby-ooo-7-16 2013/11/22 14:51:38 You might want to use heightForWidth here. (Since
Ilya Sherman 2013/11/23 00:23:54 Done.
216 201
217 if (![[overlayController_ view] isHidden]) { 202 if (![[overlayController_ view] isHidden]) {
218 CGFloat height = [overlayController_ heightForWidth:size.width]; 203 CGFloat height = [overlayController_ heightForWidth:size.width];
219 if (height != 0.0) 204 if (height != 0.0)
220 size.height = height; 205 size.height = height;
221 } 206 }
222 207
223 // Show as much of the main view as is possible without going past the 208 // Show as much of the main view as is possible without going past the
224 // bottom of the browser window. 209 // bottom of the browser window.
225 size.height = std::min(size.height, [self maxHeight]); 210 size.height = std::min(size.height, [self maxHeight]);
226 211
227 return size; 212 return size;
228 } 213 }
229 214
230 - (void)performLayout { 215 - (void)performLayout {
231 NSRect contentRect = NSZeroRect; 216 NSRect contentRect = NSZeroRect;
232 contentRect.size = [self preferredSize]; 217 contentRect.size = [self preferredSize];
233 NSRect clientRect = contentRect; 218 NSRect clientRect = contentRect;
234 clientRect.origin.y = chrome_style::kTitleTopPadding; 219 clientRect.size.height -= chrome_style::kClientBottomPadding;
235 clientRect.size.height -= chrome_style::kTitleTopPadding +
236 chrome_style::kClientBottomPadding;
237 220
238 [titleTextField_ setStringValue: 221 CGFloat headerHeight = [header_ heightForWidth:NSWidth(clientRect)];
239 base::SysUTF16ToNSString(autofillDialog_->delegate()->DialogTitle())]; 222 NSRect headerRect, mainRect;
240 [titleTextField_ sizeToFit]; 223 NSDivideRect(clientRect, &headerRect, &mainRect, headerHeight, NSMinYEdge);
241 224
242 NSRect headerRect, mainRect, titleRect, dummyRect; 225 [header_ setFrame:headerRect];
243 NSDivideRect(clientRect, &headerRect, &mainRect, 226 [header_ performLayout];
244 kAccountChooserHeight, NSMinYEdge);
245 NSDivideRect(mainRect, &dummyRect, &mainRect,
246 autofill::kDetailVerticalPadding, NSMinYEdge);
247 headerRect = NSInsetRect(headerRect, chrome_style::kHorizontalPadding, 0);
248 NSDivideRect(headerRect, &titleRect, &headerRect,
249 NSWidth([titleTextField_ frame]), NSMinXEdge);
250 227
251 // Align baseline of title with bottom of accountChooser.
252 base::scoped_nsobject<NSLayoutManager> layout_manager(
253 [[NSLayoutManager alloc] init]);
254 NSFont* titleFont = [titleTextField_ font];
255 titleRect.origin.y += NSHeight(titleRect) -
256 [layout_manager defaultBaselineOffsetForFont:titleFont];
257 [titleTextField_ setFrame:titleRect];
258
259 [accountChooser_ setFrame:headerRect];
260 [accountChooser_ performLayout];
261 if ([[signInContainer_ view] isHidden]) { 228 if ([[signInContainer_ view] isHidden]) {
262 [[mainContainer_ view] setFrame:mainRect]; 229 [[mainContainer_ view] setFrame:mainRect];
263 [mainContainer_ performLayout]; 230 [mainContainer_ performLayout];
264 } else { 231 } else {
265 [[signInContainer_ view] setFrame:mainRect]; 232 [[signInContainer_ view] setFrame:mainRect];
266 } 233 }
267 234
268 [[loadingShieldController_ view] setFrame:contentRect]; 235 [[loadingShieldController_ view] setFrame:contentRect];
269 [loadingShieldController_ performLayout]; 236 [loadingShieldController_ performLayout];
270 237
271 [[overlayController_ view] setFrame:contentRect]; 238 [[overlayController_ view] setFrame:contentRect];
272 [overlayController_ performLayout]; 239 [overlayController_ performLayout];
273 240
274 NSRect frameRect = [[self window] frameRectForContentRect:contentRect]; 241 NSRect frameRect = [[self window] frameRectForContentRect:contentRect];
275 [[self window] setFrame:frameRect display:YES]; 242 [[self window] setFrame:frameRect display:YES];
276 [[self window] recalculateKeyViewLoop]; 243 [[self window] recalculateKeyViewLoop];
277 } 244 }
278 245
279 - (IBAction)accept:(id)sender { 246 - (IBAction)accept:(id)sender {
280 if ([mainContainer_ validate]) 247 if ([mainContainer_ validate])
281 autofillDialog_->delegate()->OnAccept(); 248 dialog_->delegate()->OnAccept();
282 else 249 else
283 [mainContainer_ makeFirstInvalidInputFirstResponder]; 250 [mainContainer_ makeFirstInvalidInputFirstResponder];
284 } 251 }
285 252
286 - (IBAction)cancel:(id)sender { 253 - (IBAction)cancel:(id)sender {
287 autofillDialog_->delegate()->OnCancel(); 254 dialog_->delegate()->OnCancel();
288 autofillDialog_->PerformClose(); 255 dialog_->PerformClose();
289 } 256 }
290 257
291 - (void)show { 258 - (void)show {
292 // Resizing the browser causes the ConstrainedWindow to move. 259 // Resizing the browser causes the ConstrainedWindow to move.
293 // Observe that to allow resizes based on browser size. 260 // Observe that to allow resizes based on browser size.
294 // NOTE: This MUST come last after all initial setup is done, because there 261 // NOTE: This MUST come last after all initial setup is done, because there
295 // is an immediate notification post registration. 262 // is an immediate notification post registration.
296 DCHECK([self window]); 263 DCHECK([self window]);
297 [[NSNotificationCenter defaultCenter] 264 [[NSNotificationCenter defaultCenter]
298 addObserver:self 265 addObserver:self
299 selector:@selector(onContentViewFrameDidChange:) 266 selector:@selector(onContentViewFrameDidChange:)
300 name:NSWindowDidMoveNotification 267 name:NSWindowDidMoveNotification
301 object:[self window]]; 268 object:[self window]];
302 269
303 [self updateAccountChooser]; 270 [self updateAccountChooser];
304 [self updateNotificationArea]; 271 [self updateNotificationArea];
305 [self requestRelayout]; 272 [self requestRelayout];
306 } 273 }
307 274
308 - (void)hide { 275 - (void)hide {
309 autofillDialog_->delegate()->OnCancel(); 276 dialog_->delegate()->OnCancel();
310 autofillDialog_->PerformClose(); 277 dialog_->PerformClose();
311 } 278 }
312 279
313 - (void)updateNotificationArea { 280 - (void)updateNotificationArea {
314 [mainContainer_ updateNotificationArea]; 281 [mainContainer_ updateNotificationArea];
315 } 282 }
316 283
317 - (void)updateAccountChooser { 284 - (void)updateAccountChooser {
318 [accountChooser_ update]; 285 [header_ update];
319 [mainContainer_ updateLegalDocuments]; 286 [mainContainer_ updateLegalDocuments];
320 287
321 // For the duration of the loading shield, hide the main contents. 288 // For the duration of the loading shield, hide the main contents.
322 // This prevents the currently focused text field "shining through". 289 // This prevents the currently focused text field "shining through".
323 // No need to remember previous state, because the loading shield 290 // No need to remember previous state, because the loading shield
324 // always flows through to the main container. 291 // always flows through to the main container.
325 [loadingShieldController_ update]; 292 [loadingShieldController_ update];
326 [[mainContainer_ view] setHidden:![[loadingShieldController_ view] isHidden]]; 293 [[mainContainer_ view] setHidden:![[loadingShieldController_ view] isHidden]];
327 } 294 }
328 295
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 384
418 - (content::WebContents*)getSignInWebContents { 385 - (content::WebContents*)getSignInWebContents {
419 return [signInContainer_ webContents]; 386 return [signInContainer_ webContents];
420 } 387 }
421 388
422 - (BOOL)isShowingOverlay { 389 - (BOOL)isShowingOverlay {
423 return ![[overlayController_ view] isHidden]; 390 return ![[overlayController_ view] isHidden];
424 } 391 }
425 392
426 @end 393 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698