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

Side by Side Diff: ios/chrome/browser/translate/before_translate_infobar_controller.mm

Issue 809333003: Upstream //ios/chrome/browser/translate (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Review comments Created 5 years, 11 months 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "ios/chrome/browser/translate/before_translate_infobar_controller.h"
6
7 #import <UIKit/UIKit.h>
8
9 #include "base/logging.h"
10 #include "base/strings/sys_string_conversions.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "components/translate/core/browser/translate_infobar_delegate.h"
13 #include "grit/components_strings.h"
14 #include "ios/chrome/browser/translate/translate_infobar_tags.h"
15 #include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
16 #import "ios/public/provider/chrome/browser/ui/infobar_view_delegate.h"
17 #import "ios/public/provider/chrome/browser/ui/infobar_view_protocol.h"
18 #include "ui/base/l10n/l10n_util.h"
19 #include "ui/gfx/image/image.h"
20
21 namespace {
22
23 CGFloat kNavigationBarHeight = 44;
24 CGFloat kUIPickerHeight = 216;
25 CGFloat kUIPickerFontSize = 26;
26 NSTimeInterval kPickerAnimationDurationInSeconds = 0.2;
27
28 } // namespace
29
30 // The class is a data source and delegate to the UIPickerView that contains the
31 // language list.
32 @interface LanguagePickerController
33 : UIViewController<UIPickerViewDataSource, UIPickerViewDelegate> {
34 __weak translate::TranslateInfoBarDelegate* translateInfoBarDelegate_;
35 NSInteger initialRow_; // Displayed in bold font.
36 NSInteger disabledRow_; // Grayed out.
37 }
38 @end
39
40 @implementation LanguagePickerController
41
42 - (instancetype)initWithDelegate:(translate::TranslateInfoBarDelegate*)
43 translateInfoBarDelegate
44 initialRow:(NSInteger)initialRow
45 disabledRow:(NSInteger)disabledRow {
46 if ((self = [super init])) {
47 translateInfoBarDelegate_ = translateInfoBarDelegate;
48 initialRow_ = initialRow;
49 disabledRow_ = disabledRow;
50 }
51 return self;
52 }
53
54 #pragma mark -
55 #pragma mark UIPickerViewDataSource
56
57 - (NSInteger)pickerView:(UIPickerView*)pickerView
58 numberOfRowsInComponent:(NSInteger)component {
59 NSUInteger numRows = translateInfoBarDelegate_->num_languages();
60 return numRows;
61 }
62
63 - (NSInteger)numberOfComponentsInPickerView:(UIPickerView*)pickerView {
64 return 1;
65 }
66
67 #pragma mark -
68 #pragma mark UIPickerViewDelegate
69
70 - (UIView*)pickerView:(UIPickerView*)pickerView
71 viewForRow:(NSInteger)row
72 forComponent:(NSInteger)component
73 reusingView:(UIView*)view {
74 DCHECK_EQ(0, component);
75 UILabel* label = [view isKindOfClass:[UILabel class]]
76 ? (UILabel*)view
77 : [[[UILabel alloc] init] autorelease];
78 [label setText:base::SysUTF16ToNSString(
79 translateInfoBarDelegate_->language_name_at(row))];
80 [label setTextAlignment:NSTextAlignmentCenter];
81 UIFont* font = [UIFont systemFontOfSize:kUIPickerFontSize];
82 BOOL enabled = YES;
83 if (row == initialRow_)
84 font = [UIFont boldSystemFontOfSize:kUIPickerFontSize];
85 else if (row == disabledRow_)
86 enabled = NO;
87 [label setFont:font];
88 [label setEnabled:enabled];
89 return label;
90 }
91
92 @end
93
94 @interface BeforeTranslateInfoBarController ()
95
96 // Action for any of the user defined buttons.
97 - (void)infoBarButtonDidPress:(id)sender;
98 // Action for any of the user defined links.
99 - (void)infobarLinkDidPress:(NSNumber*)tag;
100 // Action for the language selection "Done" button.
101 - (void)languageSelectionDone;
102 // Dismisses the language selection view.
103 - (void)dismissLanguageSelectionView;
104
105 @end
106
107 @implementation BeforeTranslateInfoBarController {
108 __weak translate::TranslateInfoBarDelegate* translateInfoBarDelegate_;
109 // A fullscreen view that catches all touch events and contains a UIPickerView
110 // and a UINavigationBar.
111 base::scoped_nsobject<UIView> languageSelectionView_;
112 // Stores whether the user is currently choosing in the UIPickerView the
113 // original language, or the target language.
114 NSUInteger languageSelectionType_;
115 // The language picker.
116 base::scoped_nsobject<UIPickerView> languagePicker_;
117 // Navigation bar associated with the picker with "Done" and "Cancel" buttons.
118 base::scoped_nsobject<UINavigationBar> navigationBar_;
119 // The controller of the languagePicker. Needs to be an ivar because
120 // |languagePicker_| does not retain it.
121 base::scoped_nsobject<LanguagePickerController> languagePickerController_;
122 }
123
124 #pragma mark -
125 #pragma mark InfoBarControllerProtocol
126
127 - (void)layoutForDelegate:(infobars::InfoBarDelegate*)delegate
128 frame:(CGRect)frame {
129 translateInfoBarDelegate_ = delegate->AsTranslateInfoBarDelegate();
130 infobars::InfoBarDelegate* infoBarDelegate =
131 static_cast<infobars::InfoBarDelegate*>(translateInfoBarDelegate_);
132 DCHECK(!infoBarView_);
133 infoBarView_.reset([ios::GetChromeBrowserProvider()->CreateInfoBarView()
134 initWithFrame:frame
135 delegate:delegate_
136 isWarning:infoBarDelegate->GetInfoBarType() ==
137 infobars::InfoBarDelegate::WARNING_TYPE]);
138 // Icon
139 gfx::Image icon = translateInfoBarDelegate_->GetIcon();
140 if (!icon.IsEmpty())
141 [infoBarView_ addLeftIcon:icon.ToUIImage()];
142
143 // Main text.
144 [self updateInfobarLabel];
145
146 // Close button.
147 [infoBarView_ addCloseButtonWithTag:TranslateInfoBarIOSTag::BEFORE_DENY
148 target:self
149 action:@selector(infoBarButtonDidPress:)];
150 // Other buttons.
151 NSString* buttonAccept = l10n_util::GetNSString(IDS_TRANSLATE_INFOBAR_ACCEPT);
152 NSString* buttonDeny = l10n_util::GetNSString(IDS_TRANSLATE_INFOBAR_DENY);
153 [infoBarView_ addButton1:buttonAccept
154 tag1:TranslateInfoBarIOSTag::BEFORE_ACCEPT
155 button2:buttonDeny
156 tag2:TranslateInfoBarIOSTag::BEFORE_DENY
157 target:self
158 action:@selector(infoBarButtonDidPress:)];
159 }
160
161 - (void)updateInfobarLabel {
162 NSString* originalLanguage =
163 base::SysUTF16ToNSString(translateInfoBarDelegate_->language_name_at(
164 translateInfoBarDelegate_->original_language_index()));
165 NSString* targetLanguage =
166 base::SysUTF16ToNSString(translateInfoBarDelegate_->language_name_at(
167 translateInfoBarDelegate_->target_language_index()));
168 base::string16 originalLanguageWithLink =
169 base::SysNSStringToUTF16([[infoBarView_ class]
170 stringAsLink:originalLanguage
171 tag:TranslateInfoBarIOSTag::BEFORE_SOURCE_LANGUAGE]);
172 base::string16 targetLanguageWithLink =
173 base::SysNSStringToUTF16([[infoBarView_ class]
174 stringAsLink:targetLanguage
175 tag:TranslateInfoBarIOSTag::BEFORE_TARGET_LANGUAGE]);
176 NSString* label =
177 l10n_util::GetNSStringF(IDS_TRANSLATE_INFOBAR_BEFORE_MESSAGE_IOS,
178 originalLanguageWithLink, targetLanguageWithLink);
179 [infoBarView_ addLabel:label
180 target:self
181 action:@selector(infobarLinkDidPress:)];
182 }
183
184 - (void)languageSelectionDone {
185 size_t selectedRow = [languagePicker_ selectedRowInComponent:0];
186 if (languageSelectionType_ ==
187 TranslateInfoBarIOSTag::BEFORE_SOURCE_LANGUAGE &&
188 selectedRow != translateInfoBarDelegate_->target_language_index()) {
189 translateInfoBarDelegate_->UpdateOriginalLanguageIndex(selectedRow);
190 }
191 if (languageSelectionType_ ==
192 TranslateInfoBarIOSTag::BEFORE_TARGET_LANGUAGE &&
193 selectedRow != translateInfoBarDelegate_->original_language_index()) {
194 translateInfoBarDelegate_->UpdateTargetLanguageIndex(selectedRow);
195 }
196 [self updateInfobarLabel];
197 [self dismissLanguageSelectionView];
198 }
199
200 - (void)dismissLanguageSelectionView {
201 DCHECK_EQ(languagePicker_ == nil, navigationBar_ == nil);
202 if (languagePicker_ == nil)
203 return;
204 // Sets the picker's delegate and data source to nil, because the
205 // |languagePickerController_| may be destroyed before the picker is hidden,
206 // and even though the interactions with the picker are disabled, it might
207 // still be turning and requesting data from the data source or calling the
208 // delegate.
209 [languagePicker_ setDataSource:nil];
210 [languagePicker_ setDelegate:nil];
211 languagePickerController_.reset();
212 // Animate the picker away.
213 CGRect languagePickerFrame = [languagePicker_ frame];
214 CGRect navigationBarFrame = [navigationBar_ frame];
215 const CGFloat animationHeight =
216 languagePickerFrame.size.height + navigationBarFrame.size.height;
217 languagePickerFrame.origin.y += animationHeight;
218 navigationBarFrame.origin.y += animationHeight;
219 UIView* blockLanguagePicker = languagePicker_.get();
220 UIView* blockNavigationBar = navigationBar_.get();
221 void (^animations)(void) = ^{
222 blockLanguagePicker.frame = languagePickerFrame;
223 blockNavigationBar.frame = navigationBarFrame;
224 };
225 languagePicker_.reset();
226 navigationBar_.reset();
227 void (^completion)(BOOL finished) = ^(BOOL finished) {
228 [languageSelectionView_ removeFromSuperview];
229 languageSelectionView_.reset();
230 };
231 [UIView animateWithDuration:kPickerAnimationDurationInSeconds
232 animations:animations
233 completion:completion];
234 }
235
236 #pragma mark - Handling of User Events
237
238 - (void)infoBarButtonDidPress:(id)sender {
239 // This press might have occurred after the user has already pressed a button,
240 // in which case the view has been detached from the delegate and this press
241 // should be ignored.
242 if (!delegate_) {
243 return;
244 }
245 if ([sender isKindOfClass:[UIButton class]]) {
246 NSUInteger buttonId = static_cast<UIButton*>(sender).tag;
247 DCHECK(buttonId == TranslateInfoBarIOSTag::BEFORE_ACCEPT ||
248 buttonId == TranslateInfoBarIOSTag::BEFORE_DENY);
249 delegate_->InfoBarButtonDidPress(buttonId);
250 }
251 }
252
253 - (void)infobarLinkDidPress:(NSNumber*)tag {
254 DCHECK([tag isKindOfClass:[NSNumber class]]);
255 languageSelectionType_ = [tag unsignedIntegerValue];
256 DCHECK(languageSelectionType_ ==
257 TranslateInfoBarIOSTag::BEFORE_SOURCE_LANGUAGE ||
258 languageSelectionType_ ==
259 TranslateInfoBarIOSTag::BEFORE_TARGET_LANGUAGE);
260 if (languagePicker_ != nil)
261 return; // The UIPickerView is already up.
262
263 // Creates and adds the view containing the UIPickerView and the
264 // UINavigationBar.
265 UIView* parentView =
266 [[UIApplication sharedApplication] keyWindow].rootViewController.view;
267 // Convert the parent frame to handle device rotation.
268 CGRect parentFrame =
269 CGRectApplyAffineTransform([parentView frame], [parentView transform]);
270 const CGFloat totalPickerHeight = kUIPickerHeight + kNavigationBarHeight;
271 CGRect languageSelectionViewFrame =
272 CGRectMake(0, parentFrame.size.height - totalPickerHeight,
273 parentFrame.size.width, totalPickerHeight);
274 languageSelectionView_.reset(
275 [[UIView alloc] initWithFrame:languageSelectionViewFrame]);
276 [languageSelectionView_
277 setAutoresizingMask:UIViewAutoresizingFlexibleWidth |
278 UIViewAutoresizingFlexibleTopMargin];
279 [parentView addSubview:languageSelectionView_];
280
281 // Creates the navigation bar and its buttons.
282 CGRect finalPickerFrame = CGRectMake(
283 0, [languageSelectionView_ frame].size.height - kUIPickerHeight,
284 [languageSelectionView_ frame].size.width, kUIPickerHeight);
285 CGRect finalNavigationBarFrame = CGRectMake(
286 0, 0, [languageSelectionView_ frame].size.width, kNavigationBarHeight);
287 // The language picker animates from the bottom of the screen.
288 CGRect initialPickerFrame = finalPickerFrame;
289 initialPickerFrame.origin.y += totalPickerHeight;
290 CGRect initialNavigationBarFrame = finalNavigationBarFrame;
291 initialNavigationBarFrame.origin.y += totalPickerHeight;
292
293 navigationBar_.reset(
294 [[UINavigationBar alloc] initWithFrame:initialNavigationBarFrame]);
295 const UIViewAutoresizing resizingMask =
296 UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;
297 [navigationBar_ setAutoresizingMask:resizingMask];
298 base::scoped_nsobject<UIBarButtonItem> doneButton([[UIBarButtonItem alloc]
299 initWithBarButtonSystemItem:UIBarButtonSystemItemDone
300 target:self
301 action:@selector(languageSelectionDone)]);
302 base::scoped_nsobject<UIBarButtonItem> cancelButton([[UIBarButtonItem alloc]
303 initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
304 target:self
305 action:@selector(dismissLanguageSelectionView)]);
306 base::scoped_nsobject<UINavigationItem> item(
307 [[UINavigationItem alloc] initWithTitle:nil]);
308 [item setRightBarButtonItem:doneButton];
309 [item setLeftBarButtonItem:cancelButton];
310 [item setHidesBackButton:YES];
311 [navigationBar_ pushNavigationItem:item animated:NO];
312
313 // Creates the PickerView and its controller.
314 NSInteger selectedRow;
315 NSInteger disabledRow;
316 if (languageSelectionType_ ==
317 TranslateInfoBarIOSTag::BEFORE_SOURCE_LANGUAGE) {
318 selectedRow = translateInfoBarDelegate_->original_language_index();
319 disabledRow = translateInfoBarDelegate_->target_language_index();
320 } else {
321 selectedRow = translateInfoBarDelegate_->target_language_index();
322 disabledRow = translateInfoBarDelegate_->original_language_index();
323 }
324 languagePickerController_.reset([[LanguagePickerController alloc]
325 initWithDelegate:translateInfoBarDelegate_
326 initialRow:selectedRow
327 disabledRow:disabledRow]);
328 languagePicker_.reset(
329 [[UIPickerView alloc] initWithFrame:initialPickerFrame]);
330 [languagePicker_ setAutoresizingMask:resizingMask];
331 [languagePicker_ setShowsSelectionIndicator:YES];
332 [languagePicker_ setDataSource:languagePickerController_];
333 [languagePicker_ setDelegate:languagePickerController_];
334 [languagePicker_ setShowsSelectionIndicator:YES];
335 [languagePicker_ setBackgroundColor:[infoBarView_ backgroundColor]];
336 [languagePicker_ selectRow:selectedRow inComponent:0 animated:NO];
337
338 [UIView animateWithDuration:kPickerAnimationDurationInSeconds
339 animations:^{
340 languagePicker_.get().frame = finalPickerFrame;
341 navigationBar_.get().frame = finalNavigationBarFrame;
342 }];
343
344 // Add the subviews.
345 [languageSelectionView_ addSubview:languagePicker_];
346 [languageSelectionView_ addSubview:navigationBar_];
347 }
348
349 - (void)removeView {
350 [super removeView];
351 [self dismissLanguageSelectionView];
352 }
353
354 - (void)detachView {
355 [super detachView];
356 [self dismissLanguageSelectionView];
357 }
358
359 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698