| Index: chrome/browser/ui/views/infobars/infobar_view.cc
|
| ===================================================================
|
| --- chrome/browser/ui/views/infobars/infobar_view.cc (revision 80169)
|
| +++ chrome/browser/ui/views/infobars/infobar_view.cc (working copy)
|
| @@ -56,6 +56,8 @@
|
| close_button_(NULL),
|
| ALLOW_THIS_IN_INITIALIZER_LIST(delete_factory_(this)),
|
| target_height_(kDefaultTargetHeight),
|
| + tab_height_(0),
|
| + bar_height_(0),
|
| fill_path_(new SkPath),
|
| stroke_path_(new SkPath) {
|
| set_parent_owned(false); // InfoBar deletes itself at the appropriate time.
|
| @@ -149,6 +151,53 @@
|
| }
|
|
|
| void InfoBarView::Layout() {
|
| + // Calculate the fill and stroke paths. We do this here, rather than in
|
| + // PlatformSpecificRecalculateHeight(), because this is also reached when our
|
| + // width is changed, which affects both paths.
|
| + stroke_path_->rewind();
|
| + fill_path_->rewind();
|
| + if (tab_height_) {
|
| + int divider_y = tab_height_ - 1;
|
| + stroke_path_->moveTo(
|
| + SkIntToScalar(GetMirroredXWithWidthInView(0, kTabWidth)),
|
| + SkIntToScalar(divider_y));
|
| + stroke_path_->rCubicTo(
|
| + SkScalarDiv(kCurveWidth, 2), 0.0,
|
| + SkScalarDiv(kCurveWidth, 2),
|
| + SkIntToScalar(-divider_y),
|
| + SkIntToScalar(kCurveWidth),
|
| + SkIntToScalar(-divider_y));
|
| + stroke_path_->rLineTo(SkScalarMulAdd(kTabIconPadding, 2, kMaxIconWidth),
|
| + 0.0);
|
| + stroke_path_->rCubicTo(
|
| + SkScalarDiv(kCurveWidth, 2), 0.0,
|
| + SkScalarDiv(kCurveWidth, 2),
|
| + SkIntToScalar(divider_y),
|
| + SkIntToScalar(kCurveWidth),
|
| + SkIntToScalar(divider_y));
|
| +
|
| + // Create the fill portion of the tab. Because the fill is inside the
|
| + // bounds and will not cover the separator, we need to extend downward by a
|
| + // pixel before closing.
|
| + *fill_path_ = *stroke_path_;
|
| + fill_path_->rLineTo(0.0, 1.0);
|
| + fill_path_->rLineTo(-SkIntToScalar(kTabWidth), 0.0);
|
| + fill_path_->close();
|
| +
|
| + // 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.
|
| + stroke_path_->offset(SK_ScalarHalf, SK_ScalarHalf);
|
| + }
|
| + if (bar_height_) {
|
| + fill_path_->addRect(0.0, SkIntToScalar(tab_height_), SkIntToScalar(width()),
|
| + SkIntToScalar(height()));
|
| + }
|
| +
|
| int start_x = kHorizontalPadding;
|
| if (icon_ != NULL) {
|
| // Center the icon horizontally within the tab, and vertically between the
|
| @@ -245,12 +294,9 @@
|
| //
|
| // gfx::CanvasSkia* canvas_skia = canvas->AsCanvasSkia();
|
| // canvas_skia->clipPath(*fill_path_);
|
| - int tab_height = AnimatedTabHeight();
|
| - int bar_height = AnimatedBarHeight();
|
| - DCHECK_EQ(tab_height + bar_height, height())
|
| - << "Animation progressed between OnBoundsChanged & PaintChildren.";
|
| - canvas->ClipRectInt(0, tab_height, width(), bar_height);
|
| -
|
| + DCHECK_EQ(tab_height_ + bar_height_, height())
|
| + << "Infobar piecewise heights do not match overall height";
|
| + canvas->ClipRectInt(0, tab_height_, width(), bar_height_);
|
| views::View::PaintChildren(canvas);
|
| canvas->Restore();
|
| }
|
| @@ -268,6 +314,13 @@
|
| return 0;
|
| }
|
|
|
| +void InfoBarView::SetTargetHeight(int height) {
|
| + if (target_height_ != height) {
|
| + target_height_ = height;
|
| + RecalculateHeight();
|
| + }
|
| +}
|
| +
|
| int InfoBarView::StartX() const {
|
| // Ensure we don't return a value greater than EndX(), so children can safely
|
| // set something's width to "EndX() - StartX()" without risking that being
|
| @@ -286,8 +339,7 @@
|
| }
|
|
|
| int InfoBarView::OffsetY(const gfx::Size prefsize) const {
|
| - return CenterY(prefsize) + AnimatedTabHeight() -
|
| - (target_height_ - AnimatedBarHeight());
|
| + return CenterY(prefsize) + tab_height_ - (target_height_ - bar_height_);
|
| }
|
|
|
| void InfoBarView::PlatformSpecificHide(bool animate) {
|
| @@ -305,6 +357,22 @@
|
| DestroyFocusTracker(restore_focus);
|
| }
|
|
|
| +void InfoBarView::PlatformSpecificRecalculateHeight() {
|
| + int old_tab_height = tab_height_;
|
| + int old_bar_height = bar_height_;
|
| + tab_height_ = static_cast<int>(kTabHeight * animation()->GetCurrentValue());
|
| + bar_height_ =
|
| + static_cast<int>(target_height_ * animation()->GetCurrentValue());
|
| +
|
| + // Don't re-layout if nothing has changed, e.g. because the animation step was
|
| + // not large enough to actually change the heights by at least a pixel.
|
| + if ((old_tab_height != tab_height_) || (old_bar_height != bar_height_)) {
|
| + // Ensure that notifying our container of our size change will result in a
|
| + // re-layout.
|
| + InvalidateLayout();
|
| + }
|
| +}
|
| +
|
| void InfoBarView::GetAccessibleState(ui::AccessibleViewState* state) {
|
| if (delegate()) {
|
| state->name = l10n_util::GetStringUTF16(
|
| @@ -314,70 +382,10 @@
|
| state->role = ui::AccessibilityTypes::ROLE_ALERT;
|
| }
|
|
|
| -int InfoBarView::AnimatedTabHeight() const {
|
| - return static_cast<int>(kTabHeight * animation()->GetCurrentValue());
|
| -}
|
| -
|
| -int InfoBarView::AnimatedBarHeight() const {
|
| - return static_cast<int>(target_height_ * animation()->GetCurrentValue());
|
| -}
|
| -
|
| gfx::Size InfoBarView::GetPreferredSize() {
|
| - return gfx::Size(0, AnimatedTabHeight() + AnimatedBarHeight());
|
| + return gfx::Size(0, tab_height_ + bar_height_);
|
| }
|
|
|
| -void InfoBarView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
|
| - int tab_height = AnimatedTabHeight();
|
| - int bar_height = AnimatedBarHeight();
|
| - int divider_y = tab_height - 1;
|
| - DCHECK_EQ(tab_height + bar_height, height())
|
| - << "Animation progressed between Layout & OnBoundsChanged.";
|
| -
|
| - int mirrored_x = GetMirroredXWithWidthInView(0, kTabWidth);
|
| - stroke_path_->rewind();
|
| - fill_path_->rewind();
|
| -
|
| - if (tab_height) {
|
| - stroke_path_->moveTo(SkIntToScalar(mirrored_x),
|
| - SkIntToScalar(divider_y));
|
| - stroke_path_->rCubicTo(
|
| - SkScalarDiv(kCurveWidth, 2), 0.0,
|
| - SkScalarDiv(kCurveWidth, 2),
|
| - SkIntToScalar(-divider_y),
|
| - SkIntToScalar(kCurveWidth),
|
| - SkIntToScalar(-divider_y));
|
| - stroke_path_->rLineTo(SkScalarMulAdd(kTabIconPadding, 2, kMaxIconWidth),
|
| - 0.0);
|
| - stroke_path_->rCubicTo(
|
| - SkScalarDiv(kCurveWidth, 2), 0.0,
|
| - SkScalarDiv(kCurveWidth, 2),
|
| - SkIntToScalar(divider_y),
|
| - SkIntToScalar(kCurveWidth),
|
| - SkIntToScalar(divider_y));
|
| -
|
| - // Create the fill portion of the tab. Because the fill is inside the
|
| - // bounds and will not cover the separator, we need to extend downward by a
|
| - // pixel before closing.
|
| - *fill_path_ = *stroke_path_;
|
| - fill_path_->rLineTo(0.0, 1.0);
|
| - fill_path_->rLineTo(-SkIntToScalar(kTabWidth), 0.0);
|
| - fill_path_->close();
|
| -
|
| - // 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.
|
| - stroke_path_->offset(SK_ScalarHalf, SK_ScalarHalf);
|
| - }
|
| - if (bar_height) {
|
| - fill_path_->addRect(0.0, SkIntToScalar(tab_height),
|
| - SkIntToScalar(width()), SkIntToScalar(height()));
|
| - }
|
| -}
|
| -
|
| void InfoBarView::FocusWillChange(View* focused_before, View* focused_now) {
|
| // This will trigger some screen readers to read the entire contents of this
|
| // infobar.
|
|
|