OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |