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

Unified Diff: chrome/browser/ui/views/autofill/autofill_dialog_views.cc

Issue 18850006: retry r210334 with fix for android (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 5 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: chrome/browser/ui/views/autofill/autofill_dialog_views.cc
diff --git a/chrome/browser/ui/views/autofill/autofill_dialog_views.cc b/chrome/browser/ui/views/autofill/autofill_dialog_views.cc
index 0bd2fd0afdd05af8b95973252f17be913f97802d..6b895fd1b9402be875ff7a16d087becbf7e8e097 100644
--- a/chrome/browser/ui/views/autofill/autofill_dialog_views.cc
+++ b/chrome/browser/ui/views/autofill/autofill_dialog_views.cc
@@ -23,7 +23,6 @@
#include "grit/theme_resources.h"
#include "grit/ui_resources.h"
#include "third_party/skia/include/core/SkColor.h"
-#include "ui/base/animation/animation_delegate.h"
#include "ui/base/animation/multi_animation.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/models/combobox_model.h"
@@ -68,29 +67,29 @@ const int kMinimumContentsHeight = 100;
const int kAroundTextPadding = 4;
// Padding around icons inside DecoratedTextfields.
-const size_t kTextfieldIconPadding = 3;
+const int kTextfieldIconPadding = 3;
// Size of the triangular mark that indicates an invalid textfield (in pixels).
-const size_t kDogEarSize = 10;
+const int kDogEarSize = 10;
// The space between the edges of a notification bar and the text within (in
// pixels).
-const size_t kNotificationPadding = 14;
+const int kNotificationPadding = 14;
// Vertical padding above and below each detail section (in pixels).
-const size_t kDetailSectionInset = 10;
+const int kDetailSectionInset = 10;
-const size_t kAutocheckoutStepsAreaPadding = 28;
-const size_t kAutocheckoutStepInset = 20;
+const int kAutocheckoutStepsAreaPadding = 28;
+const int kAutocheckoutStepInset = 20;
-const size_t kAutocheckoutProgressBarWidth = 375;
-const size_t kAutocheckoutProgressBarHeight = 15;
+const int kAutocheckoutProgressBarWidth = 375;
+const int kAutocheckoutProgressBarHeight = 15;
-const size_t kArrowHeight = 7;
-const size_t kArrowWidth = 2 * kArrowHeight;
+const int kArrowHeight = 7;
+const int kArrowWidth = 2 * kArrowHeight;
// The padding around the edges of the legal documents text, in pixels.
-const size_t kLegalDocPadding = 20;
+const int kLegalDocPadding = 20;
// Slight shading for mouse hover and legal document background.
SkColor kShadingColor = SkColorSetARGB(7, 0, 0, 0);
@@ -99,13 +98,23 @@ SkColor kShadingColor = SkColorSetARGB(7, 0, 0, 0);
SkColor kSubtleBorderColor = SkColorSetARGB(10, 0, 0, 0);
// The top padding, in pixels, for the suggestions menu dropdown arrows.
-const size_t kMenuButtonTopOffset = 5;
+const int kMenuButtonTopOffset = 5;
// The side padding, in pixels, for the suggestions menu dropdown arrows.
-const size_t kMenuButtonHorizontalPadding = 20;
+const int kMenuButtonHorizontalPadding = 20;
+
+// The padding around text in the overlay view.
+const int kOverlayTextPadding = 20;
+
+// Spacing between lines of text in the overlay view.
+const int kOverlayTextInterlineSpacing = 10;
const char kDecoratedTextfieldClassName[] = "autofill/DecoratedTextfield";
const char kNotificationAreaClassName[] = "autofill/NotificationArea";
+const char kOverlayViewClassName[] = "autofill/OverlayView";
+
+typedef ui::MultiAnimation::Part Part;
+typedef ui::MultiAnimation::Parts Parts;
views::Border* CreateLabelAlignmentBorder() {
// TODO(estade): this should be made to match the native textfield top
@@ -125,99 +134,17 @@ views::Label* CreateDetailsSectionLabel(const string16& text) {
// Draws an arrow at the top of |canvas| pointing to |tip_x|.
void DrawArrow(gfx::Canvas* canvas, int tip_x, const SkColor& color) {
const int arrow_half_width = kArrowWidth / 2.0f;
- const int arrow_middle = tip_x - arrow_half_width;
SkPath arrow;
- arrow.moveTo(arrow_middle - arrow_half_width, kArrowHeight);
- arrow.lineTo(arrow_middle + arrow_half_width, kArrowHeight);
- arrow.lineTo(arrow_middle, 0);
+ arrow.moveTo(tip_x, 0);
+ arrow.rLineTo(arrow_half_width, kArrowHeight);
+ arrow.rLineTo(-kArrowWidth, 0);
arrow.close();
- canvas->ClipPath(arrow);
- canvas->DrawColor(color);
+ SkPaint paint;
+ paint.setColor(color);
+ canvas->DrawPath(arrow, paint);
}
-typedef ui::MultiAnimation::Part Part;
-typedef ui::MultiAnimation::Parts Parts;
-
-class OverlayView : public views::View,
- public ui::AnimationDelegate {
- public:
- OverlayView() {
- SetLayoutManager(new views::FillLayout());
-
- set_background(views::Background::CreateSolidBackground(GetNativeTheme()->
- GetSystemColor(ui::NativeTheme::kColorId_DialogBackground)));
-
- Parts parts;
- // For this part of the animation, simply show the splash image.
- parts.push_back(Part(kSplashDisplayDurationMs, ui::Tween::ZERO));
- // For this part of the animation, fade out the splash image.
- parts.push_back(Part(kSplashFadeOutDurationMs, ui::Tween::EASE_IN));
- // For this part of the animation, fade out |this| (fade in the dialog).
- parts.push_back(Part(kSplashFadeInDialogDurationMs, ui::Tween::EASE_OUT));
- fade_out_.reset(
- new ui::MultiAnimation(parts,
- ui::MultiAnimation::GetDefaultTimerInterval()));
- fade_out_->set_delegate(this);
- fade_out_->set_continuous(false);
- fade_out_->Start();
- }
-
- virtual ~OverlayView() {}
-
- // ui::AnimationDelegate implementation:
- virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE {
- DCHECK_EQ(animation, fade_out_.get());
- if (fade_out_->current_part_index() != 0)
- SchedulePaint();
- }
-
- virtual void AnimationEnded(const ui::Animation* animation) OVERRIDE {
- DCHECK_EQ(animation, fade_out_.get());
- SetVisible(false);
- }
-
- // views::View implementation:
- virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
- // BubbleFrameView doesn't mask the window, it just draws the border via
- // image assets. Match that rounding here.
- static const SkScalar kCornerRadius = SkIntToScalar(2);
- gfx::Rect rect =
- GetWidget()->non_client_view()->frame_view()->GetLocalBounds();
- rect.Inset(12, 12, 12, 12);
- gfx::Path window_mask;
- window_mask.addRoundRect(gfx::RectToSkRect(rect),
- kCornerRadius, kCornerRadius);
- canvas->ClipPath(window_mask);
-
- if (fade_out_->current_part_index() == 2) {
- canvas->SaveLayerAlpha((1 - fade_out_->GetCurrentValue()) * 255);
- views::View::OnPaint(canvas);
- canvas->Restore();
- } else {
- views::View::OnPaint(canvas);
- }
- }
-
- virtual void PaintChildren(gfx::Canvas* canvas) OVERRIDE {
- if (fade_out_->current_part_index() == 0) {
- views::View::PaintChildren(canvas);
- } else if (fade_out_->current_part_index() == 1) {
- canvas->SaveLayerAlpha((1 - fade_out_->GetCurrentValue()) * 255);
- views::View::PaintChildren(canvas);
- canvas->Restore();
- }
- }
-
- private:
- // This MultiAnimation is used to first fade out the contents of the overlay,
- // then fade out the background of the overlay (revealing the dialog behind
- // the overlay). This avoids cross-fade.
- scoped_ptr<ui::MultiAnimation> fade_out_;
-
- DISALLOW_COPY_AND_ASSIGN(OverlayView);
-};
-
// This class handles layout for the first row of a SuggestionView.
// It exists to circumvent shortcomings of GridLayout and BoxLayout (namely that
// the former doesn't fully respect child visibility, and that the latter won't
@@ -609,6 +536,184 @@ void AutofillDialogViews::AccountChooser::LinkClicked(views::Link* source,
controller_->SignInLinkClicked();
}
+// AutofillDialogViews::OverlayView --------------------------------------------
+
+AutofillDialogViews::OverlayView::OverlayView(views::ButtonListener* listener)
+ : image_view_(new views::ImageView()),
+ message_stack_(new views::View()),
+ button_(new views::LabelButton(listener, string16())) {
+ set_border(views::Border::CreateEmptyBorder(12, 12, 12, 12));
+ set_background(views::Background::CreateSolidBackground(GetNativeTheme()->
+ GetSystemColor(ui::NativeTheme::kColorId_DialogBackground)));
+
+ AddChildView(image_view_);
+
+ AddChildView(message_stack_);
+ message_stack_->SetLayoutManager(
+ new views::BoxLayout(views::BoxLayout::kVertical, 0, 0,
+ kOverlayTextInterlineSpacing));
+ message_stack_->set_border(views::Border::CreateEmptyBorder(
+ kOverlayTextPadding, kOverlayTextPadding, 0, kOverlayTextPadding));
+
+ AddChildView(button_);
+ button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
+ button_->set_focusable(true);
+}
+
+AutofillDialogViews::OverlayView::~OverlayView() {}
+
+void AutofillDialogViews::OverlayView::SetState(
+ const DialogOverlayState& state,
+ views::ButtonListener* listener) {
+ // Don't update anything if we're still fading out the old state.
+ if (fade_out_)
+ return;
+
+ if (state.image.IsEmpty()) {
+ SetVisible(false);
+ return;
+ }
+
+ image_view_->SetImage(state.image.ToImageSkia());
+
+ message_stack_->RemoveAllChildViews(true);
+ for (size_t i = 0; i < state.strings.size(); ++i) {
+ views::Label* label = new views::Label();
+ label->SetMultiLine(true);
+ label->SetText(state.strings[i].text);
+ label->SetFont(state.strings[i].font);
+ label->SetHorizontalAlignment(state.strings[i].alignment);
+ message_stack_->AddChildView(label);
+ }
+ message_stack_->SetVisible(message_stack_->child_count() > 0);
+
+ button_->SetVisible(!state.button_text.empty());
+ if (!state.button_text.empty())
+ button_->SetText(state.button_text);
+
+ SetVisible(true);
+ if (parent())
+ parent()->Layout();
+}
+
+void AutofillDialogViews::OverlayView::BeginFadeOut() {
+ Parts parts;
+ // For this part of the animation, simply show the splash image.
+ parts.push_back(Part(kSplashDisplayDurationMs, ui::Tween::ZERO));
+ // For this part of the animation, fade out the splash image.
+ parts.push_back(Part(kSplashFadeOutDurationMs, ui::Tween::EASE_IN));
+ // For this part of the animation, fade out |this| (fade in the dialog).
+ parts.push_back(Part(kSplashFadeInDialogDurationMs, ui::Tween::EASE_OUT));
+ fade_out_.reset(
+ new ui::MultiAnimation(parts,
+ ui::MultiAnimation::GetDefaultTimerInterval()));
+ fade_out_->set_delegate(this);
+ fade_out_->set_continuous(false);
+ fade_out_->Start();
+}
+
+void AutofillDialogViews::OverlayView::AnimationProgressed(
+ const ui::Animation* animation) {
+ DCHECK_EQ(animation, fade_out_.get());
+ if (fade_out_->current_part_index() != 0)
+ SchedulePaint();
+}
+
+void AutofillDialogViews::OverlayView::AnimationEnded(
+ const ui::Animation* animation) {
+ DCHECK_EQ(animation, fade_out_.get());
+ SetVisible(false);
+ fade_out_.reset();
+}
+
+void AutofillDialogViews::OverlayView::Layout() {
+ gfx::Rect bounds = GetContentsBounds();
+ if (!message_stack_->visible()) {
+ image_view_->SetBoundsRect(bounds);
+ return;
+ }
+
+ int y = bounds.bottom() - views::kButtonVEdgeMarginNew;
+ if (button_->visible()) {
+ button_->SizeToPreferredSize();
+ y -= button_->height();
+ button_->SetPosition(gfx::Point(
+ bounds.width() - button_->width() -
+ views::kButtonHEdgeMarginNew,
+ y));
+ y -= views::kButtonVEdgeMarginNew;
+ }
+
+ int message_height = message_stack_->GetHeightForWidth(bounds.width());
+ y -= message_height;
+ message_stack_->SetBounds(bounds.x(), y, bounds.width(), message_height);
+
+ gfx::Size image_size = image_view_->GetPreferredSize();
+ const int kImageBottomMargin = 40;
+ y -= image_size.height() + kImageBottomMargin;
+ image_view_->SetBounds(bounds.x(), y, bounds.width(), image_size.height());
+}
+
+const char* AutofillDialogViews::OverlayView::GetClassName() const {
+ return kOverlayViewClassName;
+}
+
+void AutofillDialogViews::OverlayView::OnPaint(gfx::Canvas* canvas) {
+ // BubbleFrameView doesn't mask the window, it just draws the border via
+ // image assets. Match that rounding here.
+ static const SkScalar kCornerRadius = SkIntToScalar(2);
+ gfx::Rect rect = GetContentsBounds();
+ gfx::Path window_mask;
+ window_mask.addRoundRect(gfx::RectToSkRect(rect),
+ kCornerRadius, kCornerRadius);
+ canvas->ClipPath(window_mask);
+
+ // Fade out background (i.e. fade in what's behind |this|).
+ if (fade_out_ && fade_out_->current_part_index() == 2)
+ canvas->SaveLayerAlpha((1 - fade_out_->GetCurrentValue()) * 255);
+
+ OnPaintBackground(canvas);
+
+ // Draw the arrow, border, and fill for the bottom area.
+ if (message_stack_->visible()) {
+ const int arrow_half_width = kArrowWidth / 2.0f;
+ SkPath arrow;
+ int y = message_stack_->y() - 1;
+ // Note that we purposely draw slightly outside of |rect| so that the
+ // stroke is hidden on the sides.
+ arrow.moveTo(rect.x() - 1, y);
+ arrow.rLineTo(rect.width() / 2 - arrow_half_width, 0);
+ arrow.rLineTo(arrow_half_width, -kArrowHeight);
+ arrow.rLineTo(arrow_half_width, kArrowHeight);
+ arrow.lineTo(rect.right() + 1, y);
+ arrow.lineTo(rect.right() + 1, rect.bottom() + 1);
+ arrow.lineTo(rect.x() - 1, rect.bottom() + 1);
+ arrow.close();
+
+ SkPaint paint;
+ paint.setColor(kShadingColor);
+ paint.setStyle(SkPaint::kFill_Style);
+ canvas->DrawPath(arrow, paint);
+ paint.setColor(kSubtleBorderColor);
+ paint.setStyle(SkPaint::kStroke_Style);
+ canvas->DrawPath(arrow, paint);
+ }
+
+ PaintChildren(canvas);
+}
+
+void AutofillDialogViews::OverlayView::PaintChildren(gfx::Canvas* canvas) {
+ // Don't draw children.
+ if (fade_out_ && fade_out_->current_part_index() == 2)
+ return;
+
+ // Fade out children.
+ if (fade_out_ && fade_out_->current_part_index() == 1)
+ canvas->SaveLayerAlpha((1 - fade_out_->GetCurrentValue()) * 255);
+
+ views::View::PaintChildren(canvas);
+}
+
// AutofillDialogViews::NotificationArea ---------------------------------------
AutofillDialogViews::NotificationArea::NotificationArea(
@@ -1018,6 +1123,14 @@ void AutofillDialogViews::Show() {
views::Widget::GetTopLevelWidgetForNativeView(
controller_->web_contents()->GetView()->GetNativeView());
observer_.Add(browser_widget);
+
+ gfx::Image splash_image = controller_->SplashPageImage();
+ if (!splash_image.IsEmpty()) {
+ DialogOverlayState state;
+ state.image = splash_image;
+ overlay_view_->SetState(state, NULL);
+ overlay_view_->BeginFadeOut();
+ }
}
void AutofillDialogViews::Hide() {
@@ -1069,6 +1182,9 @@ void AutofillDialogViews::UpdateButtonStrip() {
autocheckout_progress_bar_view_->SetVisible(
controller_->ShouldShowProgressBar());
GetDialogClientView()->UpdateDialogButtons();
+
+ overlay_view_->SetState(controller_->GetDialogOverlay(), this);
+
ContentsPreferredSizeChanged();
}
@@ -1401,15 +1517,6 @@ views::View* AutofillDialogViews::CreateFootnoteView() {
}
views::View* AutofillDialogViews::CreateOverlayView() {
- gfx::Image splash_image = controller_->SplashPageImage();
- if (splash_image.IsEmpty())
- return NULL;
-
- overlay_view_ = new OverlayView();
- views::ImageView* image = new views::ImageView();
- image->SetImage(splash_image.ToImageSkia());
- overlay_view_->AddChildView(image);
-
return overlay_view_;
}
@@ -1439,6 +1546,11 @@ views::NonClientFrameView* AutofillDialogViews::CreateNonClientFrameView(
void AutofillDialogViews::ButtonPressed(views::Button* sender,
const ui::Event& event) {
+ if (sender->GetAncestorWithClassName(kOverlayViewClassName)) {
+ controller_->OverlayButtonPressed();
+ return;
+ }
+
// TODO(estade): Should the menu be shown on mouse down?
DetailsGroup* group = NULL;
for (DetailGroupMap::iterator iter = detail_groups_.begin();
@@ -1581,6 +1693,9 @@ void AutofillDialogViews::InitChildViews() {
sign_in_delegate_.reset(
new AutofillDialogSignInDelegate(this,
sign_in_webview_->GetWebContents()));
+
+ overlay_view_ = new OverlayView(this);
+ overlay_view_->SetVisible(false);
}
views::View* AutofillDialogViews::CreateDetailsContainer() {

Powered by Google App Engine
This is Rietveld 408576698