OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 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_details_container.h" | 5 #import "chrome/browser/ui/cocoa/autofill/autofill_details_container.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/mac/foundation_util.h" | 9 #include "base/mac/foundation_util.h" |
10 #include "chrome/browser/ui/autofill/autofill_dialog_view_delegate.h" | 10 #include "chrome/browser/ui/autofill/autofill_dialog_view_delegate.h" |
11 #import "chrome/browser/ui/cocoa/autofill/autofill_bubble_controller.h" | 11 #import "chrome/browser/ui/cocoa/autofill/autofill_bubble_controller.h" |
12 #import "chrome/browser/ui/cocoa/autofill/autofill_section_container.h" | 12 #import "chrome/browser/ui/cocoa/autofill/autofill_section_container.h" |
| 13 #import "chrome/browser/ui/cocoa/info_bubble_view.h" |
13 | 14 |
14 @implementation AutofillDetailsContainer | 15 @implementation AutofillDetailsContainer |
15 | 16 |
16 - (id)initWithDelegate:(autofill::AutofillDialogViewDelegate*)delegate { | 17 - (id)initWithDelegate:(autofill::AutofillDialogViewDelegate*)delegate { |
17 if (self = [super init]) { | 18 if (self = [super init]) { |
18 delegate_ = delegate; | 19 delegate_ = delegate; |
19 } | 20 } |
20 return self; | 21 return self; |
21 } | 22 } |
22 | 23 |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 [scrollView_ reflectScrolledClipView:clipView]; | 151 [scrollView_ reflectScrolledClipView:clipView]; |
151 [self updateErrorBubble]; | 152 [self updateErrorBubble]; |
152 } | 153 } |
153 | 154 |
154 - (void)updateErrorBubble { | 155 - (void)updateErrorBubble { |
155 if (!delegate_->ShouldShowErrorBubble()) { | 156 if (!delegate_->ShouldShowErrorBubble()) { |
156 [errorBubbleController_ close]; | 157 [errorBubbleController_ close]; |
157 } | 158 } |
158 } | 159 } |
159 | 160 |
160 - (NSPoint)anchorPointFromView:(NSView*)view { | |
161 // All math done in window coordinates, since views might be flipped. | |
162 NSRect viewRect = [view convertRect:[view bounds] toView:nil]; | |
163 NSPoint anchorPoint = | |
164 NSMakePoint(NSMidX(viewRect), NSMinY(viewRect)); | |
165 return [[view window] convertBaseToScreen:anchorPoint]; | |
166 } | |
167 | |
168 - (void)errorBubbleWindowWillClose:(NSNotification*)notification { | 161 - (void)errorBubbleWindowWillClose:(NSNotification*)notification { |
169 DCHECK_EQ([notification object], [errorBubbleController_ window]); | 162 DCHECK_EQ([notification object], [errorBubbleController_ window]); |
170 | 163 |
171 NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; | 164 NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; |
172 [center removeObserver:self | 165 [center removeObserver:self |
173 name:NSWindowWillCloseNotification | 166 name:NSWindowWillCloseNotification |
174 object:[errorBubbleController_ window]]; | 167 object:[errorBubbleController_ window]]; |
175 errorBubbleController_ = nil; | 168 errorBubbleController_ = nil; |
176 } | 169 } |
177 | 170 |
(...skipping 10 matching lines...) Expand all Loading... |
188 | 181 |
189 // Handle bubble self-deleting. | 182 // Handle bubble self-deleting. |
190 NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; | 183 NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; |
191 [center addObserver:self | 184 [center addObserver:self |
192 selector:@selector(errorBubbleWindowWillClose:) | 185 selector:@selector(errorBubbleWindowWillClose:) |
193 name:NSWindowWillCloseNotification | 186 name:NSWindowWillCloseNotification |
194 object:[errorBubbleController_ window]]; | 187 object:[errorBubbleController_ window]]; |
195 | 188 |
196 // Compute anchor point (in window coords - views might be flipped). | 189 // Compute anchor point (in window coords - views might be flipped). |
197 NSRect viewRect = [field convertRect:[field bounds] toView:nil]; | 190 NSRect viewRect = [field convertRect:[field bounds] toView:nil]; |
198 NSPoint anchorPoint = NSMakePoint(NSMidX(viewRect), NSMinY(viewRect)); | 191 |
| 192 // If a bubble at maximum size with a left-aligned edge would exceed the |
| 193 // window width, align the right edge of bubble and view. In all other |
| 194 // cases, align the left edge of the bubble and the view. |
| 195 // Alignment is based on maximum width to avoid the arrow changing positions |
| 196 // if the validation bubble stays on the same field but gets a message of |
| 197 // differing length. (E.g. "Field is required"/"Invalid Zip Code. Please |
| 198 // check and try again" if an empty zip field gets changed to a bad zip). |
| 199 NSPoint anchorPoint; |
| 200 if ((NSMinX(viewRect) + [errorBubbleController_ maxWidth]) > |
| 201 NSWidth([parentWindow frame])) { |
| 202 anchorPoint = NSMakePoint(NSMaxX(viewRect), NSMinY(viewRect)); |
| 203 [[errorBubbleController_ bubble] setArrowLocation:info_bubble::kTopRight]; |
| 204 [[errorBubbleController_ bubble] setAlignment: |
| 205 info_bubble::kAlignRightEdgeToAnchorEdge]; |
| 206 |
| 207 } else { |
| 208 anchorPoint = NSMakePoint(NSMinX(viewRect), NSMinY(viewRect)); |
| 209 [[errorBubbleController_ bubble] setArrowLocation:info_bubble::kTopLeft]; |
| 210 [[errorBubbleController_ bubble] setAlignment: |
| 211 info_bubble::kAlignLeftEdgeToAnchorEdge]; |
| 212 } |
199 [errorBubbleController_ setAnchorPoint: | 213 [errorBubbleController_ setAnchorPoint: |
200 [parentWindow convertBaseToScreen:anchorPoint]]; | 214 [parentWindow convertBaseToScreen:anchorPoint]]; |
201 | 215 |
202 [errorBubbleController_ showWindow:self]; | 216 [errorBubbleController_ showWindow:self]; |
203 } | 217 } |
204 | 218 |
205 - (void)hideErrorBubble { | 219 - (void)hideErrorBubble { |
206 [errorBubble_ setHidden:YES]; | 220 [errorBubble_ setHidden:YES]; |
207 } | 221 } |
208 | 222 |
(...skipping 11 matching lines...) Expand all Loading... |
220 } | 234 } |
221 | 235 |
222 if ([field invalid]) { | 236 if ([field invalid]) { |
223 [self showErrorBubbleForField:field]; | 237 [self showErrorBubbleForField:field]; |
224 } else { | 238 } else { |
225 [errorBubbleController_ close]; | 239 [errorBubbleController_ close]; |
226 } | 240 } |
227 } | 241 } |
228 | 242 |
229 @end | 243 @end |
OLD | NEW |