Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 1 | // Copyright (c) 2013 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 | #include "chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.h" |
| 6 | |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 7 | #include "base/bind.h" |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 8 | #include "base/mac/bundle_locations.h" |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 9 | #include "base/mac/scoped_nsobject.h" |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 10 | #include "base/message_loop/message_loop.h" |
Ben Murdoch | fb25065 | 2013-07-31 11:42:55 +0100 | [diff] [blame] | 11 | #include "base/strings/sys_string_conversions.h" |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 12 | #include "chrome/browser/ui/autofill/autofill_dialog_view_delegate.h" |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 13 | #include "chrome/browser/ui/chrome_style.h" |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 14 | #include "chrome/browser/ui/chrome_style.h" |
| 15 | #include "chrome/browser/ui/chrome_style.h" |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 16 | #import "chrome/browser/ui/cocoa/autofill/autofill_account_chooser.h" |
| 17 | #import "chrome/browser/ui/cocoa/autofill/autofill_details_container.h" |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 18 | #include "chrome/browser/ui/cocoa/autofill/autofill_dialog_constants.h" |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 19 | #import "chrome/browser/ui/cocoa/autofill/autofill_main_container.h" |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 20 | #import "chrome/browser/ui/cocoa/autofill/autofill_section_container.h" |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 21 | #import "chrome/browser/ui/cocoa/autofill/autofill_sign_in_container.h" |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 22 | #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_button.h" |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 23 | #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.h" |
| 24 | #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_window.h" |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 25 | #include "content/public/browser/web_contents.h" |
| 26 | #include "content/public/browser/web_contents_view.h" |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 27 | #import "ui/base/cocoa/flipped_view.h" |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 28 | #include "ui/base/cocoa/window_size_constants.h" |
| 29 | |
| 30 | namespace { |
| 31 | |
| 32 | const CGFloat kAccountChooserHeight = 20.0; |
| 33 | const CGFloat kRelatedControlVerticalSpacing = 8.0; |
| 34 | |
| 35 | } // namespace; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 36 | |
| 37 | namespace autofill { |
| 38 | |
| 39 | // static |
| 40 | AutofillDialogView* AutofillDialogView::Create( |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 41 | AutofillDialogViewDelegate* delegate) { |
| 42 | return new AutofillDialogCocoa(delegate); |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 43 | } |
| 44 | |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 45 | AutofillDialogCocoa::AutofillDialogCocoa(AutofillDialogViewDelegate* delegate) |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 46 | : close_weak_ptr_factory_(this), |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 47 | delegate_(delegate) { |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 48 | } |
| 49 | |
| 50 | AutofillDialogCocoa::~AutofillDialogCocoa() { |
| 51 | } |
| 52 | |
| 53 | void AutofillDialogCocoa::Show() { |
| 54 | // This should only be called once. |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 55 | DCHECK(!sheet_delegate_.get()); |
| 56 | sheet_delegate_.reset([[AutofillDialogWindowController alloc] |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 57 | initWithWebContents:delegate_->GetWebContents() |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 58 | autofillDialog:this]); |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 59 | base::scoped_nsobject<CustomConstrainedWindowSheet> sheet( |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 60 | [[CustomConstrainedWindowSheet alloc] |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 61 | initWithCustomWindow:[sheet_delegate_ window]]); |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 62 | constrained_window_.reset( |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 63 | new ConstrainedWindowMac(this, delegate_->GetWebContents(), sheet)); |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 64 | } |
| 65 | |
| 66 | void AutofillDialogCocoa::Hide() { |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 67 | [sheet_delegate_ hide]; |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 68 | } |
| 69 | |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 70 | void AutofillDialogCocoa::PerformClose() { |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 71 | if (!close_weak_ptr_factory_.HasWeakPtrs()) { |
| 72 | base::MessageLoop::current()->PostTask( |
| 73 | FROM_HERE, |
| 74 | base::Bind(&AutofillDialogCocoa::CloseNow, |
| 75 | close_weak_ptr_factory_.GetWeakPtr())); |
| 76 | } |
| 77 | } |
| 78 | |
| 79 | void AutofillDialogCocoa::CloseNow() { |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 80 | constrained_window_->CloseWebContentsModalDialog(); |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 81 | } |
| 82 | |
| 83 | void AutofillDialogCocoa::UpdateAccountChooser() { |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 84 | [sheet_delegate_ updateAccountChooser]; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 85 | } |
| 86 | |
| 87 | void AutofillDialogCocoa::UpdateButtonStrip() { |
| 88 | } |
| 89 | |
Torne (Richard Coles) | b2df76e | 2013-05-13 16:52:09 +0100 | [diff] [blame] | 90 | void AutofillDialogCocoa::UpdateDetailArea() { |
| 91 | } |
| 92 | |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 93 | void AutofillDialogCocoa::UpdateForErrors() { |
| 94 | } |
| 95 | |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 96 | void AutofillDialogCocoa::UpdateNotificationArea() { |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 97 | [sheet_delegate_ updateNotificationArea]; |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 98 | } |
| 99 | |
| 100 | void AutofillDialogCocoa::UpdateAutocheckoutStepsArea() { |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 101 | } |
| 102 | |
| 103 | void AutofillDialogCocoa::UpdateSection(DialogSection section) { |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 104 | [sheet_delegate_ updateSection:section]; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 105 | } |
| 106 | |
| 107 | void AutofillDialogCocoa::FillSection(DialogSection section, |
| 108 | const DetailInput& originating_input) { |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 109 | [sheet_delegate_ fillSection:section forInput:originating_input]; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 110 | } |
| 111 | |
| 112 | void AutofillDialogCocoa::GetUserInput(DialogSection section, |
| 113 | DetailOutputMap* output) { |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 114 | [sheet_delegate_ getInputs:output forSection:section]; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 115 | } |
| 116 | |
| 117 | string16 AutofillDialogCocoa::GetCvc() { |
| 118 | return string16(); |
| 119 | } |
| 120 | |
| 121 | bool AutofillDialogCocoa::SaveDetailsLocally() { |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 122 | return [sheet_delegate_ saveDetailsLocally]; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 123 | } |
| 124 | |
| 125 | const content::NavigationController* AutofillDialogCocoa::ShowSignIn() { |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 126 | return [sheet_delegate_ showSignIn]; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 127 | } |
| 128 | |
| 129 | void AutofillDialogCocoa::HideSignIn() { |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 130 | [sheet_delegate_ hideSignIn]; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 131 | } |
| 132 | |
| 133 | void AutofillDialogCocoa::UpdateProgressBar(double value) {} |
| 134 | |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 135 | void AutofillDialogCocoa::ModelChanged() { |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 136 | [sheet_delegate_ modelChanged]; |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 137 | } |
| 138 | |
| 139 | void AutofillDialogCocoa::OnSignInResize(const gfx::Size& pref_size) { |
| 140 | // TODO(groby): Implement Mac support for this. |
| 141 | } |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 142 | |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 143 | TestableAutofillDialogView* AutofillDialogCocoa::GetTestableView() { |
| 144 | return this; |
| 145 | } |
| 146 | |
| 147 | void AutofillDialogCocoa::SubmitForTesting() { |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 148 | [sheet_delegate_ accept:nil]; |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 149 | } |
| 150 | |
| 151 | void AutofillDialogCocoa::CancelForTesting() { |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 152 | [sheet_delegate_ cancel:nil]; |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 153 | } |
| 154 | |
| 155 | string16 AutofillDialogCocoa::GetTextContentsOfInput(const DetailInput& input) { |
| 156 | for (size_t i = SECTION_MIN; i <= SECTION_MAX; ++i) { |
| 157 | DialogSection section = static_cast<DialogSection>(i); |
| 158 | DetailOutputMap contents; |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 159 | [sheet_delegate_ getInputs:&contents forSection:section]; |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 160 | DetailOutputMap::const_iterator it = contents.find(&input); |
| 161 | if (it != contents.end()) |
| 162 | return it->second; |
| 163 | } |
| 164 | |
| 165 | NOTREACHED(); |
| 166 | return string16(); |
| 167 | } |
| 168 | |
| 169 | void AutofillDialogCocoa::SetTextContentsOfInput(const DetailInput& input, |
| 170 | const string16& contents) { |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 171 | [sheet_delegate_ setTextContents:base::SysUTF16ToNSString(contents) |
Ben Murdoch | fb25065 | 2013-07-31 11:42:55 +0100 | [diff] [blame] | 172 | forInput:input]; |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 173 | } |
| 174 | |
| 175 | void AutofillDialogCocoa::SetTextContentsOfSuggestionInput( |
| 176 | DialogSection section, |
| 177 | const base::string16& text) { |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 178 | [sheet_delegate_ setTextContents:base::SysUTF16ToNSString(text) |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 179 | ofSuggestionForSection:section]; |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 180 | } |
| 181 | |
| 182 | void AutofillDialogCocoa::ActivateInput(const DetailInput& input) { |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 183 | [sheet_delegate_ activateFieldForInput:input]; |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 184 | } |
| 185 | |
| 186 | gfx::Size AutofillDialogCocoa::GetSize() const { |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 187 | return gfx::Size(NSSizeToCGSize([[sheet_delegate_ window] frame].size)); |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 188 | } |
| 189 | |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 190 | void AutofillDialogCocoa::OnConstrainedWindowClosed( |
| 191 | ConstrainedWindowMac* window) { |
| 192 | constrained_window_.reset(); |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 193 | // |this| belongs to |delegate_|, so no self-destruction here. |
| 194 | delegate_->ViewClosed(); |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 195 | } |
| 196 | |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 197 | } // autofill |
| 198 | |
| 199 | #pragma mark Window Controller |
| 200 | |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 201 | @interface AutofillDialogWindowController () |
| 202 | |
| 203 | // Notification that the WebContent's view frame has changed. |
| 204 | - (void)onContentViewFrameDidChange:(NSNotification*)notification; |
| 205 | |
| 206 | @end |
| 207 | |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 208 | @implementation AutofillDialogWindowController |
| 209 | |
| 210 | - (id)initWithWebContents:(content::WebContents*)webContents |
| 211 | autofillDialog:(autofill::AutofillDialogCocoa*)autofillDialog { |
| 212 | DCHECK(webContents); |
| 213 | |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 214 | base::scoped_nsobject<ConstrainedWindowCustomWindow> window( |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 215 | [[ConstrainedWindowCustomWindow alloc] |
| 216 | initWithContentRect:ui::kWindowSizeDeterminedLater]); |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 217 | |
| 218 | if ((self = [super initWithWindow:window])) { |
| 219 | webContents_ = webContents; |
| 220 | autofillDialog_ = autofillDialog; |
| 221 | |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 222 | mainContainer_.reset([[AutofillMainContainer alloc] |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 223 | initWithDelegate:autofillDialog->delegate()]); |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 224 | [mainContainer_ setTarget:self]; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 225 | |
| 226 | signInContainer_.reset( |
| 227 | [[AutofillSignInContainer alloc] |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 228 | initWithDelegate:autofillDialog->delegate()]); |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 229 | [[signInContainer_ view] setHidden:YES]; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 230 | |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 231 | NSRect clientRect = [[mainContainer_ view] frame]; |
| 232 | clientRect.origin = NSMakePoint(chrome_style::kClientBottomPadding, |
| 233 | chrome_style::kHorizontalPadding); |
| 234 | [[mainContainer_ view] setFrame:clientRect]; |
| 235 | [[signInContainer_ view] setFrame:clientRect]; |
| 236 | |
| 237 | NSRect headerRect = clientRect; |
| 238 | headerRect.size.height = kAccountChooserHeight; |
| 239 | headerRect.origin.y = NSMaxY(clientRect); |
| 240 | accountChooser_.reset([[AutofillAccountChooser alloc] |
| 241 | initWithFrame:headerRect |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 242 | delegate:autofillDialog->delegate()]); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 243 | |
| 244 | // This needs a flipped content view because otherwise the size |
| 245 | // animation looks odd. However, replacing the contentView for constrained |
| 246 | // windows does not work - it does custom rendering. |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 247 | base::scoped_nsobject<NSView> flippedContentView( |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 248 | [[FlippedView alloc] initWithFrame:NSZeroRect]); |
| 249 | [flippedContentView setSubviews: |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 250 | @[accountChooser_, [mainContainer_ view], [signInContainer_ view]]]; |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 251 | [flippedContentView setAutoresizingMask: |
| 252 | (NSViewWidthSizable | NSViewHeightSizable)]; |
| 253 | [[[self window] contentView] addSubview:flippedContentView]; |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 254 | [mainContainer_ setAnchorView:[[accountChooser_ subviews] objectAtIndex:1]]; |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 255 | |
| 256 | NSRect contentRect = clientRect; |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 257 | contentRect.origin = NSZeroPoint; |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 258 | contentRect.size.width += 2 * chrome_style::kHorizontalPadding; |
| 259 | contentRect.size.height += NSHeight(headerRect) + |
| 260 | chrome_style::kClientBottomPadding + |
| 261 | chrome_style::kTitleTopPadding; |
| 262 | [self performLayout]; |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 263 | |
| 264 | // Resizing the browser causes the ConstrainedWindow to move. |
| 265 | // Observe that to allow resizes based on browser size. |
| 266 | NSView* contentView = [[self window] contentView]; |
| 267 | [contentView setPostsFrameChangedNotifications:YES]; |
| 268 | [[NSNotificationCenter defaultCenter] |
| 269 | addObserver:self |
| 270 | selector:@selector(onContentViewFrameDidChange:) |
| 271 | name:NSWindowDidMoveNotification |
| 272 | object:[self window]]; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 273 | } |
| 274 | return self; |
| 275 | } |
| 276 | |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 277 | - (void)dealloc { |
| 278 | [[NSNotificationCenter defaultCenter] removeObserver:self]; |
| 279 | [super dealloc]; |
| 280 | } |
| 281 | |
| 282 | - (void)onContentViewFrameDidChange:(NSNotification*)notification { |
| 283 | [self performLayout]; |
| 284 | } |
| 285 | |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 286 | - (void)requestRelayout { |
| 287 | [self performLayout]; |
| 288 | } |
| 289 | |
| 290 | - (NSSize)preferredSize { |
| 291 | NSSize contentSize; |
| 292 | // TODO(groby): Currently, keep size identical to main container. |
| 293 | // Change to allow autoresize of web contents. |
| 294 | contentSize = [mainContainer_ preferredSize]; |
| 295 | |
| 296 | NSSize headerSize = NSMakeSize(contentSize.width, kAccountChooserHeight); |
| 297 | NSSize size = NSMakeSize( |
| 298 | std::max(contentSize.width, headerSize.width), |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 299 | contentSize.height + headerSize.height + kDetailTopPadding); |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 300 | size.width += 2 * chrome_style::kHorizontalPadding; |
| 301 | size.height += chrome_style::kClientBottomPadding + |
| 302 | chrome_style::kTitleTopPadding; |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 303 | |
| 304 | // Show as much of the main view as is possible without going past the |
| 305 | // bottom of the browser window. |
| 306 | NSRect dialogFrameRect = [[self window] frame]; |
| 307 | NSRect browserFrameRect = |
| 308 | [webContents_->GetView()->GetTopLevelNativeWindow() frame]; |
| 309 | dialogFrameRect.size.height = |
| 310 | NSMaxY(dialogFrameRect) - NSMinY(browserFrameRect); |
| 311 | dialogFrameRect = [[self window] contentRectForFrameRect:dialogFrameRect]; |
| 312 | size.height = std::min(NSHeight(dialogFrameRect), size.height); |
| 313 | |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 314 | return size; |
| 315 | } |
| 316 | |
| 317 | - (void)performLayout { |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 318 | NSRect contentRect = NSZeroRect; |
| 319 | contentRect.size = [self preferredSize]; |
| 320 | NSRect clientRect = NSInsetRect( |
| 321 | contentRect, chrome_style::kHorizontalPadding, 0); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 322 | clientRect.origin.y = chrome_style::kClientBottomPadding; |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 323 | clientRect.size.height -= chrome_style::kTitleTopPadding + |
| 324 | chrome_style::kClientBottomPadding; |
| 325 | |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 326 | NSRect headerRect, mainRect, dummyRect; |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 327 | NSDivideRect(clientRect, &headerRect, &mainRect, |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 328 | kAccountChooserHeight, NSMinYEdge); |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 329 | NSDivideRect(mainRect, &dummyRect, &mainRect, |
| 330 | kDetailTopPadding, NSMinYEdge); |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 331 | |
| 332 | [accountChooser_ setFrame:headerRect]; |
| 333 | if ([[signInContainer_ view] isHidden]) { |
| 334 | [[mainContainer_ view] setFrame:mainRect]; |
| 335 | [mainContainer_ performLayout]; |
| 336 | } else { |
| 337 | [[signInContainer_ view] setFrame:mainRect]; |
| 338 | } |
| 339 | |
| 340 | NSRect frameRect = [[self window] frameRectForContentRect:contentRect]; |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 341 | [[self window] setFrame:frameRect display:YES]; |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 342 | } |
| 343 | |
| 344 | - (IBAction)accept:(id)sender { |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 345 | if ([mainContainer_ validate]) |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 346 | autofillDialog_->delegate()->OnAccept(); |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 347 | } |
| 348 | |
| 349 | - (IBAction)cancel:(id)sender { |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 350 | autofillDialog_->delegate()->OnCancel(); |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 351 | autofillDialog_->PerformClose(); |
| 352 | } |
| 353 | |
| 354 | - (void)hide { |
Ben Murdoch | 3240926 | 2013-08-07 11:04:47 +0100 | [diff] [blame] | 355 | autofillDialog_->delegate()->OnCancel(); |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 356 | autofillDialog_->PerformClose(); |
| 357 | } |
| 358 | |
| 359 | - (void)updateNotificationArea { |
| 360 | [mainContainer_ updateNotificationArea]; |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 361 | } |
| 362 | |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 363 | - (void)updateAccountChooser { |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 364 | [accountChooser_ update]; |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 365 | [mainContainer_ updateLegalDocuments]; |
| 366 | } |
| 367 | |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 368 | - (void)updateSection:(autofill::DialogSection)section { |
| 369 | [[mainContainer_ sectionForId:section] update]; |
| 370 | } |
| 371 | |
Ben Murdoch | fb25065 | 2013-07-31 11:42:55 +0100 | [diff] [blame] | 372 | - (void)fillSection:(autofill::DialogSection)section |
| 373 | forInput:(const autofill::DetailInput&)input { |
| 374 | [[mainContainer_ sectionForId:section] fillForInput:input]; |
| 375 | } |
| 376 | |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 377 | - (content::NavigationController*)showSignIn { |
| 378 | [signInContainer_ loadSignInPage]; |
| 379 | [[mainContainer_ view] setHidden:YES]; |
| 380 | [[signInContainer_ view] setHidden:NO]; |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 381 | [self performLayout]; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 382 | |
| 383 | return [signInContainer_ navigationController]; |
| 384 | } |
| 385 | |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 386 | - (void)getInputs:(autofill::DetailOutputMap*)output |
| 387 | forSection:(autofill::DialogSection)section { |
| 388 | [[mainContainer_ sectionForId:section] getInputs:output]; |
| 389 | } |
| 390 | |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 391 | - (BOOL)saveDetailsLocally { |
| 392 | return [mainContainer_ saveDetailsLocally]; |
| 393 | } |
| 394 | |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 395 | - (void)hideSignIn { |
| 396 | [[signInContainer_ view] setHidden:YES]; |
| 397 | [[mainContainer_ view] setHidden:NO]; |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 398 | [self performLayout]; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 399 | } |
| 400 | |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 401 | - (void)modelChanged { |
| 402 | [mainContainer_ modelChanged]; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 403 | } |
| 404 | |
| 405 | @end |
Ben Murdoch | fb25065 | 2013-07-31 11:42:55 +0100 | [diff] [blame] | 406 | |
| 407 | |
| 408 | @implementation AutofillDialogWindowController (TestableAutofillDialogView) |
| 409 | |
| 410 | - (void)setTextContents:(NSString*)text |
| 411 | forInput:(const autofill::DetailInput&)input { |
| 412 | for (size_t i = autofill::SECTION_MIN; i <= autofill::SECTION_MAX; ++i) { |
| 413 | autofill::DialogSection section = static_cast<autofill::DialogSection>(i); |
| 414 | // TODO(groby): Need to find the section for an input directly - wasteful. |
| 415 | [[mainContainer_ sectionForId:section] setFieldValue:text forInput:input]; |
| 416 | } |
| 417 | } |
| 418 | |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 419 | - (void)setTextContents:(NSString*)text |
| 420 | ofSuggestionForSection:(autofill::DialogSection)section { |
| 421 | [[mainContainer_ sectionForId:section] setSuggestionFieldValue:text]; |
| 422 | } |
| 423 | |
Ben Murdoch | fb25065 | 2013-07-31 11:42:55 +0100 | [diff] [blame] | 424 | - (void)activateFieldForInput:(const autofill::DetailInput&)input { |
| 425 | for (size_t i = autofill::SECTION_MIN; i <= autofill::SECTION_MAX; ++i) { |
| 426 | autofill::DialogSection section = static_cast<autofill::DialogSection>(i); |
| 427 | [[mainContainer_ sectionForId:section] activateFieldForInput:input]; |
| 428 | } |
| 429 | } |
| 430 | |
| 431 | @end |