diff options
author | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-02 22:47:36 +0000 |
---|---|---|
committer | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-02 22:47:36 +0000 |
commit | 1c89c290fcfb818a7ee3b544bb2d534e002df8a6 (patch) | |
tree | 3cecc42eabe4fdd0a1119b00e4400a649d37666c /chrome/browser | |
parent | aa1026c6b91c006370b0c8dda03064c9b19f765e (diff) | |
download | chromium_src-1c89c290fcfb818a7ee3b544bb2d534e002df8a6.zip chromium_src-1c89c290fcfb818a7ee3b544bb2d534e002df8a6.tar.gz chromium_src-1c89c290fcfb818a7ee3b544bb2d534e002df8a6.tar.bz2 |
Fix DCHECK() in infobar animation.
The core of the problem here is that painting does not always happen synchronously with layout, and the old code was not always forcing re-layout to occur if the animation progressed in the meantime. This change forces re-layout to occur any time the animation progresses or the target height is changed, and makes that the one time when the tab and bar heights are recalculated -- all other places then use the calculated values.
This also tweaks which functions are in the cross-platform versus platform-specific code as well as making a few other small cleanups.
Finally, this re-enables a test on Mac that seems to be passing now.
BUG=60990, 75451
TEST=none
Review URL: http://codereview.chromium.org/6788014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@80272 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
16 files changed, 140 insertions, 124 deletions
diff --git a/chrome/browser/extensions/extension_crash_recovery_browsertest.cc b/chrome/browser/extensions/extension_crash_recovery_browsertest.cc index a71ec7f..3dd85a9 100644 --- a/chrome/browser/extensions/extension_crash_recovery_browsertest.cc +++ b/chrome/browser/extensions/extension_crash_recovery_browsertest.cc @@ -367,9 +367,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest, } } -// Occassional crashes. See http://crbug.com75450 -IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest, - DISABLED_TwoExtensionsOneByOne) { +IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest, TwoExtensionsOneByOne) { const size_t size_before = GetExtensionService()->extensions()->size(); LoadTestExtension(); CrashExtension(size_before); diff --git a/chrome/browser/extensions/extension_infobar_apitest.cc b/chrome/browser/extensions/extension_infobar_apitest.cc index 3803e2f..98299f9 100644 --- a/chrome/browser/extensions/extension_infobar_apitest.cc +++ b/chrome/browser/extensions/extension_infobar_apitest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -6,12 +6,10 @@ #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/common/chrome_switches.h" -#if defined(OS_WIN) -// Also marking this as disabled on Windows. See http://crbug.com/75451. -#define MAYBE_Infobars DISABLED_Infobars +#if defined(TOOLKIT_VIEWS) || defined(OS_MACOSX) +#define MAYBE_Infobars Infobars #else // Need to finish port to Linux. See http://crbug.com/39916 for details. -// Temporarily marked as DISABLED on OSX too. See http://crbug.com/60990 for details. #define MAYBE_Infobars DISABLED_Infobars #endif diff --git a/chrome/browser/external_tab_container_win.cc b/chrome/browser/external_tab_container_win.cc index 33d1fc1..b2f3ade 100644 --- a/chrome/browser/external_tab_container_win.cc +++ b/chrome/browser/external_tab_container_win.cc @@ -939,7 +939,7 @@ void ExternalTabContainer::SetEnableExtensionAutomation( } } -void ExternalTabContainer::InfoBarContainerSizeChanged(bool is_animating) { +void ExternalTabContainer::InfoBarContainerHeightChanged(bool is_animating) { if (external_tab_view_) external_tab_view_->Layout(); } diff --git a/chrome/browser/external_tab_container_win.h b/chrome/browser/external_tab_container_win.h index 39e4854..02f5884 100644 --- a/chrome/browser/external_tab_container_win.h +++ b/chrome/browser/external_tab_container_win.h @@ -212,7 +212,7 @@ class ExternalTabContainer : public TabContentsDelegate, } // InfoBarContainer::Delegate overrides - virtual void InfoBarContainerSizeChanged(bool is_animating); + virtual void InfoBarContainerHeightChanged(bool is_animating) OVERRIDE; virtual void TabContentsCreated(TabContents* new_contents); diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 6c8adbd..237b91a 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc @@ -1672,7 +1672,7 @@ void BrowserView::GetAccessibleState(ui::AccessibleViewState* state) { state->role = ui::AccessibilityTypes::ROLE_CLIENT; } -void BrowserView::InfoBarContainerSizeChanged(bool is_animating) { +void BrowserView::InfoBarContainerHeightChanged(bool is_animating) { SelectedTabToolbarSizeChanged(is_animating); } diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index d0be79c..6de107b 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h @@ -375,7 +375,7 @@ class BrowserView : public BrowserBubbleHost, virtual gfx::Size GetMinimumSize() OVERRIDE; // InfoBarContainer::Delegate overrides - virtual void InfoBarContainerSizeChanged(bool is_animating) OVERRIDE; + virtual void InfoBarContainerHeightChanged(bool is_animating) OVERRIDE; // views::SingleSplitView::Observer overrides: virtual bool SplitHandleMoved(views::SingleSplitView* view) OVERRIDE; diff --git a/chrome/browser/ui/views/frame/browser_view_layout.cc b/chrome/browser/ui/views/frame/browser_view_layout.cc index 2ae1780..2bacf2ba 100644 --- a/chrome/browser/ui/views/frame/browser_view_layout.cc +++ b/chrome/browser/ui/views/frame/browser_view_layout.cc @@ -367,8 +367,8 @@ int BrowserViewLayout::LayoutInfoBar(int top) { infobar_container_->SetVisible(visible); int height = infobar_container_->GetPreferredSize().height(); DCHECK(visible || !height) << "Invisible InfoBarContainer has height."; - int overlapped_top = top - - static_cast<InfoBarContainerView*>(infobar_container_)->VerticalOverlap(); + int overlapped_top = top - static_cast<InfoBarContainerView*>( + infobar_container_)->GetVerticalOverlap(); infobar_container_->SetBounds(vertical_layout_rect_.x(), overlapped_top, vertical_layout_rect_.width(), diff --git a/chrome/browser/ui/views/infobars/extension_infobar.cc b/chrome/browser/ui/views/infobars/extension_infobar.cc index 4b5a4ff..e123459 100644 --- a/chrome/browser/ui/views/infobars/extension_infobar.cc +++ b/chrome/browser/ui/views/infobars/extension_infobar.cc @@ -43,7 +43,7 @@ ExtensionInfoBar::ExtensionInfoBar(ExtensionInfoBarDelegate* delegate) ExtensionView* extension_view = delegate->extension_host()->view(); int height = extension_view->GetPreferredSize().height(); - set_target_height((height > 0) ? + SetTargetHeight((height > 0) ? (height + InfoBarBackground::kSeparatorLineHeight) : height); // Get notified of resize events for the ExtensionView. @@ -130,7 +130,7 @@ void ExtensionInfoBar::OnExtensionPreferredSizeChanged(ExtensionView* view) { animation()->Reset(0.0); // Clamp height to a min and a max size of between 1 and 2 InfoBars. - set_target_height(std::min(2 * kDefaultTargetHeight, + SetTargetHeight(std::min(2 * kDefaultTargetHeight, std::max(kDefaultTargetHeight, view->GetPreferredSize().height()))); animation()->Show(); diff --git a/chrome/browser/ui/views/infobars/infobar.cc b/chrome/browser/ui/views/infobars/infobar.cc index 7f37126..8641094 100644 --- a/chrome/browser/ui/views/infobars/infobar.cc +++ b/chrome/browser/ui/views/infobars/infobar.cc @@ -39,8 +39,7 @@ void InfoBar::Hide(bool animate) { } void InfoBar::AnimationProgressed(const ui::Animation* animation) { - if (container_) - container_->OnInfoBarAnimated(false); + RecalculateHeight(); } void InfoBar::RemoveInfoBar() { @@ -48,12 +47,14 @@ void InfoBar::RemoveInfoBar() { container_->RemoveDelegate(delegate_); } -void InfoBar::PlatformSpecificHide(bool animate) { +void InfoBar::RecalculateHeight() { + PlatformSpecificRecalculateHeight(); + if (container_) + container_->OnInfoBarHeightChanged(animation_->is_animating()); } void InfoBar::AnimationEnded(const ui::Animation* animation) { - if (container_) - container_->OnInfoBarAnimated(true); + RecalculateHeight(); MaybeDelete(); } diff --git a/chrome/browser/ui/views/infobars/infobar.h b/chrome/browser/ui/views/infobars/infobar.h index 651c368..7a50f27 100644 --- a/chrome/browser/ui/views/infobars/infobar.h +++ b/chrome/browser/ui/views/infobars/infobar.h @@ -45,8 +45,14 @@ class InfoBar : public ui::AnimationDelegate { ui::SlideAnimation* animation() { return animation_.get(); } const ui::SlideAnimation* animation() const { return animation_.get(); } - // Subclasses may optionally override this. - virtual void PlatformSpecificHide(bool animate); + // Calls PlatformSpecificRecalculateHeight(), then informs our container our + // height has changed. + void RecalculateHeight(); + + // Platforms may optionally override these if they need to do work during + // processing of the given calls. + virtual void PlatformSpecificHide(bool animate) {} + virtual void PlatformSpecificRecalculateHeight() {} private: // ui::AnimationDelegate: diff --git a/chrome/browser/ui/views/infobars/infobar_container.cc b/chrome/browser/ui/views/infobars/infobar_container.cc index 70612d3..1ec0159 100644 --- a/chrome/browser/ui/views/infobars/infobar_container.cc +++ b/chrome/browser/ui/views/infobars/infobar_container.cc @@ -20,9 +20,10 @@ InfoBarContainer::InfoBarContainer(Delegate* delegate) InfoBarContainer::~InfoBarContainer() { // Before we remove any children, we reset |delegate_|, so that no removals - // will result in us trying to call delegate_->InfoBarContainerSizeChanged(). - // This is important because at this point |delegate_| may be shutting down, - // and it's at best unimportant and at worst disastrous to call that. + // will result in us trying to call + // delegate_->InfoBarContainerHeightChanged(). This is important because at + // this point |delegate_| may be shutting down, and it's at best unimportant + // and at worst disastrous to call that. delegate_ = NULL; ChangeTabContents(NULL); } @@ -60,12 +61,12 @@ void InfoBarContainer::ChangeTabContents(TabContents* contents) { } // Now that everything is up to date, signal the delegate to re-layout. - OnInfoBarAnimated(true); + OnInfoBarHeightChanged(true); } -void InfoBarContainer::OnInfoBarAnimated(bool done) { +void InfoBarContainer::OnInfoBarHeightChanged(bool is_animating) { if (delegate_) - delegate_->InfoBarContainerSizeChanged(!done); + delegate_->InfoBarContainerHeightChanged(is_animating); } void InfoBarContainer::RemoveDelegate(InfoBarDelegate* delegate) { diff --git a/chrome/browser/ui/views/infobars/infobar_container.h b/chrome/browser/ui/views/infobars/infobar_container.h index a48b27d..c1dc3f3 100644 --- a/chrome/browser/ui/views/infobars/infobar_container.h +++ b/chrome/browser/ui/views/infobars/infobar_container.h @@ -25,11 +25,10 @@ class TabContents; // functions, which are pure virtual here. class InfoBarContainer : public NotificationObserver { public: - // The delegate is notified each time InfoBarContainer::OnInfoBarAnimated() is - // called. + // The delegate is notified each time the infobar container changes height. class Delegate { public: - virtual void InfoBarContainerSizeChanged(bool is_animating) = 0; + virtual void InfoBarContainerHeightChanged(bool is_animating) = 0; protected: virtual ~Delegate(); @@ -43,10 +42,10 @@ class InfoBarContainer : public NotificationObserver { // |contents|, and show them all. |contents| may be NULL. void ChangeTabContents(TabContents* contents); - // Called when a contained infobar has animated. The container is expected to - // do anything necessary to respond to the infobar's possible size change, + // Called when a contained infobar has animated or by some other means changed + // its height. The container is expected to do anything necessary to respond, // e.g. re-layout. - void OnInfoBarAnimated(bool done); + void OnInfoBarHeightChanged(bool is_animating); // Remove the specified InfoBarDelegate from the selected TabContents. This // will notify us back and cause us to close the InfoBar. This is called from @@ -58,6 +57,10 @@ class InfoBarContainer : public NotificationObserver { // hidden. void RemoveInfoBar(InfoBar* infobar); + // Return the amount by which to overlap the toolbar above, so that the + // InfoBars inside may draw anti-spoof arrows atop it. + virtual int GetVerticalOverlap() = 0; + protected: // These must be implemented on each platform to e.g. adjust the visible // object hierarchy. diff --git a/chrome/browser/ui/views/infobars/infobar_container_view.cc b/chrome/browser/ui/views/infobars/infobar_container_view.cc index 66be4eb..0a98454 100644 --- a/chrome/browser/ui/views/infobars/infobar_container_view.cc +++ b/chrome/browser/ui/views/infobars/infobar_container_view.cc @@ -18,7 +18,7 @@ InfoBarContainerView::InfoBarContainerView(Delegate* delegate) InfoBarContainerView::~InfoBarContainerView() { } -int InfoBarContainerView::VerticalOverlap() { +int InfoBarContainerView::GetVerticalOverlap() { return GetVerticalOverlap(NULL); } @@ -31,14 +31,14 @@ gfx::Size InfoBarContainerView::GetPreferredSize() { } void InfoBarContainerView::Layout() { - int top = GetVerticalOverlap(NULL); + int top = GetVerticalOverlap(); for (int i = 0; i < child_count(); ++i) { View* child = GetChildViewAt(i); - gfx::Size ps = child->GetPreferredSize(); - top -= static_cast<InfoBarView*>(child)->AnimatedTabHeight(); - child->SetBounds(0, top, width(), ps.height()); - top += ps.height(); + top -= static_cast<InfoBarView*>(child)->tab_height(); + int child_height = child->GetPreferredSize().height(); + child->SetBounds(0, top, width(), child_height); + top += child_height; } } @@ -63,8 +63,7 @@ int InfoBarContainerView::GetVerticalOverlap(int* total_height) { for (int i = 0; i < child_count(); ++i) { View* child = GetChildViewAt(i); - gfx::Size ps = child->GetPreferredSize(); - next_child_y -= static_cast<InfoBarView*>(child)->AnimatedTabHeight(); + next_child_y -= static_cast<InfoBarView*>(child)->tab_height(); vertical_overlap = std::max(vertical_overlap, -next_child_y); next_child_y += child->GetPreferredSize().height(); } diff --git a/chrome/browser/ui/views/infobars/infobar_container_view.h b/chrome/browser/ui/views/infobars/infobar_container_view.h index 1348bf7..ffd695b 100644 --- a/chrome/browser/ui/views/infobars/infobar_container_view.h +++ b/chrome/browser/ui/views/infobars/infobar_container_view.h @@ -16,10 +16,7 @@ class InfoBarContainerView : public AccessiblePaneView, explicit InfoBarContainerView(Delegate* delegate); virtual ~InfoBarContainerView(); - // Overlap the previous view by this amount, vertically, so that the - // first InfoBarView in this InfoBarContainer may draw its tab on - // top. - int VerticalOverlap(); + virtual int GetVerticalOverlap() OVERRIDE; private: // AccessiblePaneView: @@ -31,9 +28,9 @@ class InfoBarContainerView : public AccessiblePaneView, virtual void PlatformSpecificAddInfoBar(InfoBar* infobar) OVERRIDE; virtual void PlatformSpecificRemoveInfoBar(InfoBar* infobar) OVERRIDE; - // Return the maximum vertical overlap of the InfoBarContainer's children, - // and, when |total_height| is non-NULL, set the |*total_height| of the - // InfoBarContainer. + // Return the amount by which to overlap the toolbar above, and, when + // |total_height| is non-NULL, set it to the height of the InfoBarContainer + // (including overlap). int GetVerticalOverlap(int* total_height); DISALLOW_COPY_AND_ASSIGN(InfoBarContainerView); diff --git a/chrome/browser/ui/views/infobars/infobar_view.cc b/chrome/browser/ui/views/infobars/infobar_view.cc index 893dcc0..813d2ee 100644 --- a/chrome/browser/ui/views/infobars/infobar_view.cc +++ b/chrome/browser/ui/views/infobars/infobar_view.cc @@ -56,6 +56,8 @@ InfoBarView::InfoBarView(InfoBarDelegate* delegate) 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 @@ views::TextButton* InfoBarView::CreateTextButton( } 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 @@ void InfoBarView::PaintChildren(gfx::Canvas* canvas) { // // 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 @@ int InfoBarView::ContentMinimumWidth() const { 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::CenterY(const gfx::Size prefsize) const { } 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 @@ void InfoBarView::PlatformSpecificHide(bool animate) { 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,68 +382,8 @@ void InfoBarView::GetAccessibleState(ui::AccessibleViewState* state) { 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()); -} - -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())); - } + return gfx::Size(0, tab_height_ + bar_height_); } void InfoBarView::FocusWillChange(View* focused_before, View* focused_now) { diff --git a/chrome/browser/ui/views/infobars/infobar_view.h b/chrome/browser/ui/views/infobars/infobar_view.h index 3b5f924..09835c2 100644 --- a/chrome/browser/ui/views/infobars/infobar_view.h +++ b/chrome/browser/ui/views/infobars/infobar_view.h @@ -35,7 +35,7 @@ class InfoBarView : public InfoBar, SkPath* fill_path() const { return fill_path_.get(); } SkPath* stroke_path() const { return stroke_path_.get(); } - int AnimatedTabHeight() const; + int tab_height() const { return tab_height_; } protected: // The target height of the InfoBar, regardless of what its current height @@ -80,7 +80,8 @@ class InfoBarView : public InfoBar, // button from overlapping views that cannot be shrunk any further. virtual int ContentMinimumWidth() const; - void set_target_height(int height) { target_height_ = height; } + // Changes the target height of the main ("bar") portion of the infobar. + void SetTargetHeight(int height); // These return x coordinates delimiting the usable area for subclasses to lay // out their controls. @@ -102,11 +103,11 @@ class InfoBarView : public InfoBar, // InfoBar: virtual void PlatformSpecificHide(bool animate) OVERRIDE; + virtual void PlatformSpecificRecalculateHeight() OVERRIDE; // views::View: virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; virtual gfx::Size GetPreferredSize() OVERRIDE; - virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE; virtual void PaintChildren(gfx::Canvas* canvas) OVERRIDE; // views::FocusChangeListener: @@ -117,8 +118,6 @@ class InfoBarView : public InfoBar, // |prefsize| within the standard InfoBar height. Stable during an animation. int CenterY(const gfx::Size prefsize) const; - int AnimatedBarHeight() const; - // Destroys the external focus tracker, if present. If |restore_focus| is // true, restores focus to the view tracked by the focus tracker before doing // so. @@ -144,6 +143,12 @@ class InfoBarView : public InfoBar, // The target height for the bar portion of the InfoBarView. int target_height_; + // The current heights of the tab and bar portions. + int tab_height_; + int bar_height_; + + // The paths for the InfoBarBackground to draw, sized according to the heights + // above. scoped_ptr<SkPath> fill_path_; scoped_ptr<SkPath> stroke_path_; |