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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: ios/chrome/browser/translate/before_translate_infobar_controller.mm
diff --git a/ios/chrome/browser/translate/before_translate_infobar_controller.mm b/ios/chrome/browser/translate/before_translate_infobar_controller.mm
new file mode 100644
index 0000000000000000000000000000000000000000..635ce0e382d3f33e8dea8cef67ba6f75dfe35590
--- /dev/null
+++ b/ios/chrome/browser/translate/before_translate_infobar_controller.mm
@@ -0,0 +1,359 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ios/chrome/browser/translate/before_translate_infobar_controller.h"
+
+#import <UIKit/UIKit.h>
+
+#include "base/logging.h"
+#include "base/strings/sys_string_conversions.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/translate/core/browser/translate_infobar_delegate.h"
+#include "grit/components_strings.h"
+#include "ios/chrome/browser/translate/translate_infobar_tags.h"
+#include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
+#import "ios/public/provider/chrome/browser/ui/infobar_view_delegate.h"
+#import "ios/public/provider/chrome/browser/ui/infobar_view_protocol.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/gfx/image/image.h"
+
+namespace {
+
+CGFloat kNavigationBarHeight = 44;
+CGFloat kUIPickerHeight = 216;
+CGFloat kUIPickerFontSize = 26;
+NSTimeInterval kPickerAnimationDurationInSeconds = 0.2;
+
+} // namespace
+
+// The class is a data source and delegate to the UIPickerView that contains the
+// language list.
+@interface LanguagePickerController
+ : UIViewController<UIPickerViewDataSource, UIPickerViewDelegate> {
+ __weak translate::TranslateInfoBarDelegate* translateInfoBarDelegate_;
+ NSInteger initialRow_; // Displayed in bold font.
+ NSInteger disabledRow_; // Grayed out.
+}
+@end
+
+@implementation LanguagePickerController
+
+- (instancetype)initWithDelegate:(translate::TranslateInfoBarDelegate*)
+ translateInfoBarDelegate
+ initialRow:(NSInteger)initialRow
+ disabledRow:(NSInteger)disabledRow {
+ if ((self = [super init])) {
+ translateInfoBarDelegate_ = translateInfoBarDelegate;
+ initialRow_ = initialRow;
+ disabledRow_ = disabledRow;
+ }
+ return self;
+}
+
+#pragma mark -
+#pragma mark UIPickerViewDataSource
+
+- (NSInteger)pickerView:(UIPickerView*)pickerView
+ numberOfRowsInComponent:(NSInteger)component {
+ NSUInteger numRows = translateInfoBarDelegate_->num_languages();
+ return numRows;
+}
+
+- (NSInteger)numberOfComponentsInPickerView:(UIPickerView*)pickerView {
+ return 1;
+}
+
+#pragma mark -
+#pragma mark UIPickerViewDelegate
+
+- (UIView*)pickerView:(UIPickerView*)pickerView
+ viewForRow:(NSInteger)row
+ forComponent:(NSInteger)component
+ reusingView:(UIView*)view {
+ DCHECK_EQ(0, component);
+ UILabel* label = [view isKindOfClass:[UILabel class]]
+ ? (UILabel*)view
+ : [[[UILabel alloc] init] autorelease];
+ [label setText:base::SysUTF16ToNSString(
+ translateInfoBarDelegate_->language_name_at(row))];
+ [label setTextAlignment:NSTextAlignmentCenter];
+ UIFont* font = [UIFont systemFontOfSize:kUIPickerFontSize];
+ BOOL enabled = YES;
+ if (row == initialRow_)
+ font = [UIFont boldSystemFontOfSize:kUIPickerFontSize];
+ else if (row == disabledRow_)
+ enabled = NO;
+ [label setFont:font];
+ [label setEnabled:enabled];
+ return label;
+}
+
+@end
+
+@interface BeforeTranslateInfoBarController ()
+
+// Action for any of the user defined buttons.
+- (void)infoBarButtonDidPress:(id)sender;
+// Action for any of the user defined links.
+- (void)infobarLinkDidPress:(NSNumber*)tag;
+// Action for the language selection "Done" button.
+- (void)languageSelectionDone;
+// Dismisses the language selection view.
+- (void)dismissLanguageSelectionView;
+
+@end
+
+@implementation BeforeTranslateInfoBarController {
+ __weak translate::TranslateInfoBarDelegate* translateInfoBarDelegate_;
+ // A fullscreen view that catches all touch events and contains a UIPickerView
+ // and a UINavigationBar.
+ base::scoped_nsobject<UIView> languageSelectionView_;
+ // Stores whether the user is currently choosing in the UIPickerView the
+ // original language, or the target language.
+ NSUInteger languageSelectionType_;
+ // The language picker.
+ base::scoped_nsobject<UIPickerView> languagePicker_;
+ // Navigation bar associated with the picker with "Done" and "Cancel" buttons.
+ base::scoped_nsobject<UINavigationBar> navigationBar_;
+ // The controller of the languagePicker. Needs to be an ivar because
+ // |languagePicker_| does not retain it.
+ base::scoped_nsobject<LanguagePickerController> languagePickerController_;
+}
+
+#pragma mark -
+#pragma mark InfoBarControllerProtocol
+
+- (void)layoutForDelegate:(infobars::InfoBarDelegate*)delegate
+ frame:(CGRect)frame {
+ translateInfoBarDelegate_ = delegate->AsTranslateInfoBarDelegate();
+ infobars::InfoBarDelegate* infoBarDelegate =
+ static_cast<infobars::InfoBarDelegate*>(translateInfoBarDelegate_);
+ DCHECK(!infoBarView_);
+ infoBarView_.reset([ios::GetChromeBrowserProvider()->CreateInfoBarView()
+ initWithFrame:frame
+ delegate:delegate_
+ isWarning:infoBarDelegate->GetInfoBarType() ==
+ infobars::InfoBarDelegate::WARNING_TYPE]);
+ // Icon
+ gfx::Image icon = translateInfoBarDelegate_->GetIcon();
+ if (!icon.IsEmpty())
+ [infoBarView_ addLeftIcon:icon.ToUIImage()];
+
+ // Main text.
+ [self updateInfobarLabel];
+
+ // Close button.
+ [infoBarView_ addCloseButtonWithTag:TranslateInfoBarIOSTag::BEFORE_DENY
+ target:self
+ action:@selector(infoBarButtonDidPress:)];
+ // Other buttons.
+ NSString* buttonAccept = l10n_util::GetNSString(IDS_TRANSLATE_INFOBAR_ACCEPT);
+ NSString* buttonDeny = l10n_util::GetNSString(IDS_TRANSLATE_INFOBAR_DENY);
+ [infoBarView_ addButton1:buttonAccept
+ tag1:TranslateInfoBarIOSTag::BEFORE_ACCEPT
+ button2:buttonDeny
+ tag2:TranslateInfoBarIOSTag::BEFORE_DENY
+ target:self
+ action:@selector(infoBarButtonDidPress:)];
+}
+
+- (void)updateInfobarLabel {
+ NSString* originalLanguage =
+ base::SysUTF16ToNSString(translateInfoBarDelegate_->language_name_at(
+ translateInfoBarDelegate_->original_language_index()));
+ NSString* targetLanguage =
+ base::SysUTF16ToNSString(translateInfoBarDelegate_->language_name_at(
+ translateInfoBarDelegate_->target_language_index()));
+ base::string16 originalLanguageWithLink =
+ base::SysNSStringToUTF16([[infoBarView_ class]
+ stringAsLink:originalLanguage
+ tag:TranslateInfoBarIOSTag::BEFORE_SOURCE_LANGUAGE]);
+ base::string16 targetLanguageWithLink =
+ base::SysNSStringToUTF16([[infoBarView_ class]
+ stringAsLink:targetLanguage
+ tag:TranslateInfoBarIOSTag::BEFORE_TARGET_LANGUAGE]);
+ NSString* label =
+ l10n_util::GetNSStringF(IDS_TRANSLATE_INFOBAR_BEFORE_MESSAGE_IOS,
+ originalLanguageWithLink, targetLanguageWithLink);
+ [infoBarView_ addLabel:label
+ target:self
+ action:@selector(infobarLinkDidPress:)];
+}
+
+- (void)languageSelectionDone {
+ size_t selectedRow = [languagePicker_ selectedRowInComponent:0];
+ if (languageSelectionType_ ==
+ TranslateInfoBarIOSTag::BEFORE_SOURCE_LANGUAGE &&
+ selectedRow != translateInfoBarDelegate_->target_language_index()) {
+ translateInfoBarDelegate_->UpdateOriginalLanguageIndex(selectedRow);
+ }
+ if (languageSelectionType_ ==
+ TranslateInfoBarIOSTag::BEFORE_TARGET_LANGUAGE &&
+ selectedRow != translateInfoBarDelegate_->original_language_index()) {
+ translateInfoBarDelegate_->UpdateTargetLanguageIndex(selectedRow);
+ }
+ [self updateInfobarLabel];
+ [self dismissLanguageSelectionView];
+}
+
+- (void)dismissLanguageSelectionView {
+ DCHECK_EQ(languagePicker_ == nil, navigationBar_ == nil);
+ if (languagePicker_ == nil)
+ return;
+ // Sets the picker's delegate and data source to nil, because the
+ // |languagePickerController_| may be destroyed before the picker is hidden,
+ // and even though the interactions with the picker are disabled, it might
+ // still be turning and requesting data from the data source or calling the
+ // delegate.
+ [languagePicker_ setDataSource:nil];
+ [languagePicker_ setDelegate:nil];
+ languagePickerController_.reset();
+ // Animate the picker away.
+ CGRect languagePickerFrame = [languagePicker_ frame];
+ CGRect navigationBarFrame = [navigationBar_ frame];
+ const CGFloat animationHeight =
+ languagePickerFrame.size.height + navigationBarFrame.size.height;
+ languagePickerFrame.origin.y += animationHeight;
+ navigationBarFrame.origin.y += animationHeight;
+ UIView* blockLanguagePicker = languagePicker_.get();
+ UIView* blockNavigationBar = navigationBar_.get();
+ void (^animations)(void) = ^{
+ blockLanguagePicker.frame = languagePickerFrame;
+ blockNavigationBar.frame = navigationBarFrame;
+ };
+ languagePicker_.reset();
+ navigationBar_.reset();
+ void (^completion)(BOOL finished) = ^(BOOL finished) {
+ [languageSelectionView_ removeFromSuperview];
+ languageSelectionView_.reset();
+ };
+ [UIView animateWithDuration:kPickerAnimationDurationInSeconds
+ animations:animations
+ completion:completion];
+}
+
+#pragma mark - Handling of User Events
+
+- (void)infoBarButtonDidPress:(id)sender {
+ // This press might have occurred after the user has already pressed a button,
+ // in which case the view has been detached from the delegate and this press
+ // should be ignored.
+ if (!delegate_) {
+ return;
+ }
+ if ([sender isKindOfClass:[UIButton class]]) {
+ NSUInteger buttonId = static_cast<UIButton*>(sender).tag;
+ DCHECK(buttonId == TranslateInfoBarIOSTag::BEFORE_ACCEPT ||
+ buttonId == TranslateInfoBarIOSTag::BEFORE_DENY);
+ delegate_->InfoBarButtonDidPress(buttonId);
+ }
+}
+
+- (void)infobarLinkDidPress:(NSNumber*)tag {
+ DCHECK([tag isKindOfClass:[NSNumber class]]);
+ languageSelectionType_ = [tag unsignedIntegerValue];
+ DCHECK(languageSelectionType_ ==
+ TranslateInfoBarIOSTag::BEFORE_SOURCE_LANGUAGE ||
+ languageSelectionType_ ==
+ TranslateInfoBarIOSTag::BEFORE_TARGET_LANGUAGE);
+ if (languagePicker_ != nil)
+ return; // The UIPickerView is already up.
+
+ // Creates and adds the view containing the UIPickerView and the
+ // UINavigationBar.
+ UIView* parentView =
+ [[UIApplication sharedApplication] keyWindow].rootViewController.view;
+ // Convert the parent frame to handle device rotation.
+ CGRect parentFrame =
+ CGRectApplyAffineTransform([parentView frame], [parentView transform]);
+ const CGFloat totalPickerHeight = kUIPickerHeight + kNavigationBarHeight;
+ CGRect languageSelectionViewFrame =
+ CGRectMake(0, parentFrame.size.height - totalPickerHeight,
+ parentFrame.size.width, totalPickerHeight);
+ languageSelectionView_.reset(
+ [[UIView alloc] initWithFrame:languageSelectionViewFrame]);
+ [languageSelectionView_
+ setAutoresizingMask:UIViewAutoresizingFlexibleWidth |
+ UIViewAutoresizingFlexibleTopMargin];
+ [parentView addSubview:languageSelectionView_];
+
+ // Creates the navigation bar and its buttons.
+ CGRect finalPickerFrame = CGRectMake(
+ 0, [languageSelectionView_ frame].size.height - kUIPickerHeight,
+ [languageSelectionView_ frame].size.width, kUIPickerHeight);
+ CGRect finalNavigationBarFrame = CGRectMake(
+ 0, 0, [languageSelectionView_ frame].size.width, kNavigationBarHeight);
+ // The language picker animates from the bottom of the screen.
+ CGRect initialPickerFrame = finalPickerFrame;
+ initialPickerFrame.origin.y += totalPickerHeight;
+ CGRect initialNavigationBarFrame = finalNavigationBarFrame;
+ initialNavigationBarFrame.origin.y += totalPickerHeight;
+
+ navigationBar_.reset(
+ [[UINavigationBar alloc] initWithFrame:initialNavigationBarFrame]);
+ const UIViewAutoresizing resizingMask =
+ UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;
+ [navigationBar_ setAutoresizingMask:resizingMask];
+ base::scoped_nsobject<UIBarButtonItem> doneButton([[UIBarButtonItem alloc]
+ initWithBarButtonSystemItem:UIBarButtonSystemItemDone
+ target:self
+ action:@selector(languageSelectionDone)]);
+ base::scoped_nsobject<UIBarButtonItem> cancelButton([[UIBarButtonItem alloc]
+ initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
+ target:self
+ action:@selector(dismissLanguageSelectionView)]);
+ base::scoped_nsobject<UINavigationItem> item(
+ [[UINavigationItem alloc] initWithTitle:nil]);
+ [item setRightBarButtonItem:doneButton];
+ [item setLeftBarButtonItem:cancelButton];
+ [item setHidesBackButton:YES];
+ [navigationBar_ pushNavigationItem:item animated:NO];
+
+ // Creates the PickerView and its controller.
+ NSInteger selectedRow;
+ NSInteger disabledRow;
+ if (languageSelectionType_ ==
+ TranslateInfoBarIOSTag::BEFORE_SOURCE_LANGUAGE) {
+ selectedRow = translateInfoBarDelegate_->original_language_index();
+ disabledRow = translateInfoBarDelegate_->target_language_index();
+ } else {
+ selectedRow = translateInfoBarDelegate_->target_language_index();
+ disabledRow = translateInfoBarDelegate_->original_language_index();
+ }
+ languagePickerController_.reset([[LanguagePickerController alloc]
+ initWithDelegate:translateInfoBarDelegate_
+ initialRow:selectedRow
+ disabledRow:disabledRow]);
+ languagePicker_.reset(
+ [[UIPickerView alloc] initWithFrame:initialPickerFrame]);
+ [languagePicker_ setAutoresizingMask:resizingMask];
+ [languagePicker_ setShowsSelectionIndicator:YES];
+ [languagePicker_ setDataSource:languagePickerController_];
+ [languagePicker_ setDelegate:languagePickerController_];
+ [languagePicker_ setShowsSelectionIndicator:YES];
+ [languagePicker_ setBackgroundColor:[infoBarView_ backgroundColor]];
+ [languagePicker_ selectRow:selectedRow inComponent:0 animated:NO];
+
+ [UIView animateWithDuration:kPickerAnimationDurationInSeconds
+ animations:^{
+ languagePicker_.get().frame = finalPickerFrame;
+ navigationBar_.get().frame = finalNavigationBarFrame;
+ }];
+
+ // Add the subviews.
+ [languageSelectionView_ addSubview:languagePicker_];
+ [languageSelectionView_ addSubview:navigationBar_];
+}
+
+- (void)removeView {
+ [super removeView];
+ [self dismissLanguageSelectionView];
+}
+
+- (void)detachView {
+ [super detachView];
+ [self dismissLanguageSelectionView];
+}
+
+@end

Powered by Google App Engine
This is Rietveld 408576698