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

Unified Diff: chrome/browser/ui/views/infobars/infobar_view.cc

Issue 6609047: [linux_views][Win] spoof proof redesign infobar extension with tab. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 10 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/infobars/infobar_view.cc
diff --git a/chrome/browser/ui/views/infobars/infobar_view.cc b/chrome/browser/ui/views/infobars/infobar_view.cc
index 97689bf769219a48fac8b86da42eafa025294c8b..6e1e3376a662a78344147d3e492339136d77efcf 100644
--- a/chrome/browser/ui/views/infobars/infobar_view.cc
+++ b/chrome/browser/ui/views/infobars/infobar_view.cc
@@ -42,28 +42,42 @@ const int InfoBarView::kButtonButtonSpacing = 10;
const int InfoBarView::kEndOfLabelSpacing = 16;
const int InfoBarView::kHorizontalPadding = 6;
+const int InfoBarView::kCurveDistance = 13;
+const int InfoBarView::kIconWidth = 29;
+const int InfoBarView::kTabHeight = 9;
+const int InfoBarView::kTabPadding = 4;
+
+const int InfoBarView::kTabWidth = kCurveDistance * 2 + kIconWidth +
+ kTabPadding;
+
InfoBarView::InfoBarView(InfoBarDelegate* delegate)
: InfoBar(delegate),
container_(NULL),
delegate_(delegate),
icon_(NULL),
close_button_(NULL),
- ALLOW_THIS_IN_INITIALIZER_LIST(animation_(new ui::SlideAnimation(this))),
+ ALLOW_THIS_IN_INITIALIZER_LIST(tab_animation_(new ui::SlideAnimation(this))),
Peter Kasting 2011/03/04 22:23:42 Nit: 80 columns (but this should go away when you
Sheridan Rawlins 2011/03/05 18:06:54 Done.
+ ALLOW_THIS_IN_INITIALIZER_LIST(bar_animation_(new ui::SlideAnimation(this))),
ALLOW_THIS_IN_INITIALIZER_LIST(delete_factory_(this)),
- target_height_(kDefaultTargetHeight) {
+ target_height_(kDefaultTargetHeight),
+ stroke_path_(new SkPath),
+ fill_path_(new SkPath),
+ clip_path_(new SkPath) {
set_parent_owned(false); // InfoBar deletes itself at the appropriate time.
InfoBarDelegate::Type infobar_type = delegate->GetInfoBarType();
set_background(new InfoBarBackground(infobar_type));
- animation_->SetTweenType(ui::Tween::LINEAR);
+ tab_animation_->SetTweenType(ui::Tween::LINEAR);
+ bar_animation_->SetTweenType(ui::Tween::LINEAR);
}
void InfoBarView::Show(bool animate) {
if (animate) {
- animation_->Show();
+ AnimationShow();
} else {
- animation_->Reset(1.0);
+ AnimationReset(1.0);
+ InvalidateLayout();
if (container_)
container_->OnInfoBarAnimated(true);
}
@@ -80,9 +94,9 @@ void InfoBarView::Hide(bool animate) {
restore_focus = false;
#endif // defined(OS_WIN)
DestroyFocusTracker(restore_focus);
- animation_->Hide();
+ AnimationHide();
} else {
- animation_->Reset(0.0);
+ AnimationReset(0.0);
Close();
}
}
@@ -100,61 +114,6 @@ void InfoBarView::Close() {
}
}
-void InfoBarView::PaintArrow(gfx::Canvas* canvas,
- View* outer_view,
- int arrow_center_x) {
- gfx::Point infobar_top(0, y());
- ConvertPointToView(parent(), outer_view, &infobar_top);
- int infobar_top_y = infobar_top.y();
- SkPoint gradient_points[2] = {
- {SkIntToScalar(0), SkIntToScalar(infobar_top_y)},
- {SkIntToScalar(0), SkIntToScalar(infobar_top_y + target_height_)}
- };
- InfoBarDelegate::Type infobar_type = delegate_->GetInfoBarType();
- SkColor gradient_colors[2] = {
- InfoBarBackground::GetTopColor(infobar_type),
- InfoBarBackground::GetBottomColor(infobar_type),
- };
- SkShader* gradient_shader = SkGradientShader::CreateLinear(gradient_points,
- gradient_colors, NULL, 2, SkShader::kMirror_TileMode);
- SkPaint paint;
- paint.setStrokeWidth(1);
- paint.setStyle(SkPaint::kFill_Style);
- paint.setShader(gradient_shader);
- gradient_shader->unref();
-
- // The size of the arrow (its height; also half its width). The
- // arrow area is |arrow_size| ^ 2. By taking the square root of the
- // animation value, we cause a linear animation of the area, which
- // matches the perception of the animation of the InfoBar.
- const int kArrowSize = 10;
- int arrow_size = static_cast<int>(kArrowSize *
- sqrt(animation_->GetCurrentValue()));
- SkPath fill_path;
- fill_path.moveTo(SkPoint::Make(SkIntToScalar(arrow_center_x - arrow_size),
- SkIntToScalar(infobar_top_y)));
- fill_path.rLineTo(SkIntToScalar(arrow_size), SkIntToScalar(-arrow_size));
- fill_path.rLineTo(SkIntToScalar(arrow_size), SkIntToScalar(arrow_size));
- SkPath border_path(fill_path);
- fill_path.close();
- gfx::CanvasSkia* canvas_skia = canvas->AsCanvasSkia();
- canvas_skia->drawPath(fill_path, paint);
-
- // Fill and stroke have different opinions about how to treat paths. Because
- // in Skia integral coordinates represent pixel boundaries, offsetting the
- // path makes it go exactly through pixel centers; this results in lines that
- // are exactly where we expect, instead of having odd "off by one" issues.
- // Were we to do this for |fill_path|, however, which tries to fill "inside"
- // the path (using some questionable math), we'd get a fill at a very
- // different place than we'd want.
- border_path.offset(SK_ScalarHalf, SK_ScalarHalf);
- paint.setShader(NULL);
- paint.setColor(SkColorSetA(ResourceBundle::toolbar_separator_color,
- SkColorGetA(gradient_colors[0])));
- paint.setStyle(SkPaint::kStroke_Style);
- canvas_skia->drawPath(border_path, paint);
-}
-
InfoBarView::~InfoBarView() {
}
@@ -241,10 +200,17 @@ views::TextButton* InfoBarView::CreateTextButton(
void InfoBarView::Layout() {
int start_x = kHorizontalPadding;
+
Peter Kasting 2011/03/04 22:23:42 Nit: No blank line
Sheridan Rawlins 2011/03/05 18:06:54 Done.
if (icon_ != NULL) {
+ // Center the icon vertically and horizontally within the tab.
gfx::Size icon_size = icon_->GetPreferredSize();
- icon_->SetBounds(start_x, OffsetY(icon_size), icon_size.width(),
- icon_size.height());
+ int center_x = std::max((kTabWidth - icon_size.width()) / 2, 0);
+ int full_height = target_height_ + kTabHeight;
+ int preferred_height = preferred_tab_height() + preferred_bar_height();
+ int center_y =
+ std::max((full_height - icon_size.height()) / 2, 0) -
+ (full_height - preferred_height);
+ icon_->SetBounds(center_x, center_y, icon_size.width(), icon_size.height());
start_x += icon_->bounds().right();
}
@@ -300,7 +266,7 @@ void InfoBarView::ViewHierarchyChanged(bool is_add, View* parent, View* child) {
// NULL our container_ pointer so that if Animation::Stop results in
// AnimationEnded being called, we do not try and delete ourselves twice.
container_ = NULL;
- animation_->Stop();
+ AnimationStop();
// Finally, clean ourselves up when we're removed from the view hierarchy
// since no-one refers to us now.
MessageLoop::current()->PostTask(FROM_HERE,
@@ -319,6 +285,24 @@ void InfoBarView::ViewHierarchyChanged(bool is_add, View* parent, View* child) {
}
}
+void InfoBarView::PaintChildren(gfx::Canvas* canvas) {
+ canvas->Save();
+
+ // TODO(scr): This really should be the |clip_path_|, but the
+ // clipPath seems broken. Try to get a reduction and file a bug
+ // with skia. For now, just clip to the bar bounds.
Peter Kasting 2011/03/04 22:23:42 Did you contact Mike Reed? He may be able to just
Sheridan Rawlins 2011/03/05 18:06:54 I definitely want to file a bug for this, but it s
+ //
+ // gfx::CanvasSkia* canvas_skia = canvas->AsCanvasSkia();
+ // canvas_skia->clipPath(*clip_path_);
+ int tab_height = preferred_tab_height();
+ int bar_height = preferred_bar_height();
+ DCHECK_EQ(tab_height + bar_height, height());
+ canvas->ClipRectInt(0, tab_height, width(), bar_height);
+
+ views::View::PaintChildren(canvas);
+ canvas->Restore();
+}
+
void InfoBarView::ButtonPressed(views::Button* sender,
const views::Event& event) {
if (sender == close_button_) {
@@ -329,6 +313,9 @@ void InfoBarView::ButtonPressed(views::Button* sender,
}
void InfoBarView::AnimationProgressed(const ui::Animation* animation) {
+ // If multiple infobars, the InfoBarContainer's bounds won't change
+ // when only the bottom tab is animating.
+ InvalidateLayout();
if (container_)
container_->OnInfoBarAnimated(false);
}
@@ -360,7 +347,17 @@ int InfoBarView::CenterY(const gfx::Size prefsize) const {
}
int InfoBarView::OffsetY(const gfx::Size prefsize) const {
- return CenterY(prefsize) - (target_height_ - height());
+ return CenterY(prefsize) + preferred_tab_height() - (target_height_ -
+ preferred_bar_height());
+}
+
+int InfoBarView::preferred_tab_height() const {
+ // TODO(scr): hookup tab_animation_
+ return static_cast<int>(kTabHeight * tab_animation_->GetCurrentValue());
+}
+
+int InfoBarView::preferred_bar_height() const {
+ return static_cast<int>(target_height_ * bar_animation_->GetCurrentValue());
}
void InfoBarView::GetAccessibleState(ui::AccessibleViewState* state) {
@@ -371,8 +368,60 @@ void InfoBarView::GetAccessibleState(ui::AccessibleViewState* state) {
}
gfx::Size InfoBarView::GetPreferredSize() {
- return gfx::Size(0,
- static_cast<int>(target_height_ * animation_->GetCurrentValue()));
+ return gfx::Size(0, preferred_tab_height() + preferred_bar_height());
+}
+
+void InfoBarView::OnBoundsChanged() {
+ views::View::OnBoundsChanged();
+ int tab_height = preferred_tab_height();
+ int bar_height = preferred_bar_height();
+ DCHECK_EQ(tab_height + bar_height, height());
+
+ // Fill and stroke have different opinions about how to treat paths. Because
+ // in Skia integral coordinates represent pixel boundaries, offsetting the
+ // path makes it go exactly through pixel centers; this results in lines that
+ // are exactly where we expect, instead of having odd "off by one" issues.
+ // Were we to do this for |fill_path|, however, which tries to fill "inside"
+ // the path (using some questionable math), we'd get a fill at a very
+ // different place than we'd want.
+ int mirrored_x = GetMirroredXWithWidthInView(0, kTabWidth);
+ stroke_path_->rewind();
+ if (tab_height) {
+ stroke_path_->moveTo(SkIntToScalar(mirrored_x) + SK_ScalarHalf,
Peter Kasting 2011/03/04 22:23:42 These offsets all seem wrong to me. It seems like
Sheridan Rawlins 2011/03/05 18:06:54 Ok. Instead of the SK_Scalar1, I added a kTabStro
+ SkIntToScalar(tab_height) - SK_ScalarHalf);
+ stroke_path_->rCubicTo(
+ SkScalarDiv(kCurveDistance, 2), 0.0,
+ SkScalarDiv(kCurveDistance, 2), SK_Scalar1 - SkIntToScalar(tab_height),
+ SkIntToScalar(kCurveDistance), SK_Scalar1 - SkIntToScalar(tab_height));
+ stroke_path_->rLineTo(SkIntToScalar(kTabPadding + kIconWidth), 0.0);
+ stroke_path_->rCubicTo(
+ SkScalarDiv(kCurveDistance, 2), 0.0,
+ SkScalarDiv(kCurveDistance, 2), SkIntToScalar(tab_height) - SK_Scalar1,
+ SkIntToScalar(kCurveDistance), SkIntToScalar(tab_height) - SK_Scalar1);
+ }
+
+ fill_path_->rewind();
+ if (tab_height + bar_height) {
+ fill_path_->moveTo(SkIntToScalar(mirrored_x), SkIntToScalar(tab_height));
+ fill_path_->rCubicTo(
+ SkScalarDiv(kCurveDistance, 2), 0.0,
+ SkScalarDiv(kCurveDistance, 2), -SkIntToScalar(tab_height),
+ SkIntToScalar(kCurveDistance), -SkIntToScalar(tab_height));
+ fill_path_->rLineTo(SkIntToScalar(kTabPadding + kIconWidth), 0.0);
+ fill_path_->rCubicTo(
+ SkScalarDiv(kCurveDistance, 2), 0.0,
+ SkScalarDiv(kCurveDistance, 2), SkIntToScalar(tab_height),
+ SkIntToScalar(kCurveDistance), SkIntToScalar(tab_height));
+ fill_path_->lineTo(SkIntToScalar(width()), SkIntToScalar(tab_height));
+ fill_path_->lineTo(SkIntToScalar(width()),
+ SkIntToScalar(height()));
+ fill_path_->lineTo(SkIntToScalar(0), SkIntToScalar(height()));
+ fill_path_->lineTo(SkIntToScalar(0), SkIntToScalar(tab_height));
+ fill_path_->close();
+ }
+
+ // Use the same clip path as the fill path.
Peter Kasting 2011/03/04 22:23:42 Nit: We shouldn't even have |clip_path_|, then.
Sheridan Rawlins 2011/03/05 18:06:54 Done.
+ *clip_path_ = *fill_path_;
}
void InfoBarView::FocusWillChange(View* focused_before, View* focused_now) {
@@ -386,8 +435,37 @@ void InfoBarView::FocusWillChange(View* focused_before, View* focused_now) {
}
void InfoBarView::AnimationEnded(const ui::Animation* animation) {
- if (container_ && !animation_->IsShowing())
- Close();
+ if (animation == bar_animation_.get()) {
+ if (bar_animation_->IsShowing())
+ tab_animation_->Show();
+ else if (container_)
+ Close();
+ }
+ if (animation == tab_animation_.get()) {
+ if (!tab_animation_->IsShowing())
+ bar_animation_->Hide();
+ }
+}
+
+void InfoBarView::AnimationReset(double value) {
+ // Since we animate the bar first and then the tab, distribute the
+ // value across the two animation objects.
+ double double_value = value * 2.0;
+ bar_animation_->Reset(std::min(double_value, 1.0));
+ tab_animation_->Reset(std::max(double_value - 1.0, 0.0));
+}
+
+void InfoBarView::AnimationShow() {
+ bar_animation_->Show();
+}
+
+void InfoBarView::AnimationHide() {
+ tab_animation_->Hide();
+}
+
+void InfoBarView::AnimationStop() {
+ tab_animation_->Stop();
+ bar_animation_->Stop();
}
void InfoBarView::DestroyFocusTracker(bool restore_focus) {

Powered by Google App Engine
This is Rietveld 408576698