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

Side by Side Diff: chrome/browser/ui/views/infobars/infobar_view.cc

Issue 6788014: Fix DCHECK() in infobar animation. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 8 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/views/infobars/infobar_view.h" 5 #include "chrome/browser/ui/views/infobars/infobar_view.h"
6 6
7 #include "base/message_loop.h" 7 #include "base/message_loop.h"
8 #include "base/utf_string_conversions.h" 8 #include "base/utf_string_conversions.h"
9 #include "chrome/browser/tab_contents/infobar_delegate.h" 9 #include "chrome/browser/tab_contents/infobar_delegate.h"
10 #include "chrome/browser/ui/views/infobars/infobar_background.h" 10 #include "chrome/browser/ui/views/infobars/infobar_background.h"
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 49
50 const int InfoBarView::kTabWidth = (kCurveWidth + kTabIconPadding) * 2 + 50 const int InfoBarView::kTabWidth = (kCurveWidth + kTabIconPadding) * 2 +
51 kMaxIconWidth; 51 kMaxIconWidth;
52 52
53 InfoBarView::InfoBarView(InfoBarDelegate* delegate) 53 InfoBarView::InfoBarView(InfoBarDelegate* delegate)
54 : InfoBar(delegate), 54 : InfoBar(delegate),
55 icon_(NULL), 55 icon_(NULL),
56 close_button_(NULL), 56 close_button_(NULL),
57 ALLOW_THIS_IN_INITIALIZER_LIST(delete_factory_(this)), 57 ALLOW_THIS_IN_INITIALIZER_LIST(delete_factory_(this)),
58 target_height_(kDefaultTargetHeight), 58 target_height_(kDefaultTargetHeight),
59 tab_height_(0),
60 bar_height_(0),
59 fill_path_(new SkPath), 61 fill_path_(new SkPath),
60 stroke_path_(new SkPath) { 62 stroke_path_(new SkPath) {
61 set_parent_owned(false); // InfoBar deletes itself at the appropriate time. 63 set_parent_owned(false); // InfoBar deletes itself at the appropriate time.
62 64
63 InfoBarDelegate::Type infobar_type = delegate->GetInfoBarType(); 65 InfoBarDelegate::Type infobar_type = delegate->GetInfoBarType();
64 set_background(new InfoBarBackground(infobar_type)); 66 set_background(new InfoBarBackground(infobar_type));
65 } 67 }
66 68
67 InfoBarView::~InfoBarView() { 69 InfoBarView::~InfoBarView() {
68 } 70 }
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 240
239 void InfoBarView::PaintChildren(gfx::Canvas* canvas) { 241 void InfoBarView::PaintChildren(gfx::Canvas* canvas) {
240 canvas->Save(); 242 canvas->Save();
241 243
242 // TODO(scr): This really should be the |fill_path_|, but the clipPath seems 244 // TODO(scr): This really should be the |fill_path_|, but the clipPath seems
243 // broken on non-Windows platforms (crbug.com/75154). For now, just clip to 245 // broken on non-Windows platforms (crbug.com/75154). For now, just clip to
244 // the bar bounds. 246 // the bar bounds.
245 // 247 //
246 // gfx::CanvasSkia* canvas_skia = canvas->AsCanvasSkia(); 248 // gfx::CanvasSkia* canvas_skia = canvas->AsCanvasSkia();
247 // canvas_skia->clipPath(*fill_path_); 249 // canvas_skia->clipPath(*fill_path_);
248 int tab_height = AnimatedTabHeight(); 250 DCHECK_EQ(tab_height_ + bar_height_, height())
249 int bar_height = AnimatedBarHeight(); 251 << "Infobar piecewise heights do not match overall height";
250 DCHECK_EQ(tab_height + bar_height, height()) 252 canvas->ClipRectInt(0, tab_height_, width(), bar_height_);
251 << "Animation progressed between OnBoundsChanged & PaintChildren.";
252 canvas->ClipRectInt(0, tab_height, width(), bar_height);
253
254 views::View::PaintChildren(canvas); 253 views::View::PaintChildren(canvas);
255 canvas->Restore(); 254 canvas->Restore();
256 } 255 }
257 256
258 void InfoBarView::ButtonPressed(views::Button* sender, 257 void InfoBarView::ButtonPressed(views::Button* sender,
259 const views::Event& event) { 258 const views::Event& event) {
260 if (sender == close_button_) { 259 if (sender == close_button_) {
261 if (delegate()) 260 if (delegate())
262 delegate()->InfoBarDismissed(); 261 delegate()->InfoBarDismissed();
263 RemoveInfoBar(); 262 RemoveInfoBar();
264 } 263 }
265 } 264 }
266 265
267 int InfoBarView::ContentMinimumWidth() const { 266 int InfoBarView::ContentMinimumWidth() const {
268 return 0; 267 return 0;
269 } 268 }
270 269
270 void InfoBarView::SetTargetHeight(int height) {
271 if (target_height_ != height) {
272 target_height_ = height;
273 OnSizeChanged();
274 }
275 }
276
271 int InfoBarView::StartX() const { 277 int InfoBarView::StartX() const {
272 // Ensure we don't return a value greater than EndX(), so children can safely 278 // Ensure we don't return a value greater than EndX(), so children can safely
273 // set something's width to "EndX() - StartX()" without risking that being 279 // set something's width to "EndX() - StartX()" without risking that being
274 // negative. 280 // negative.
275 return std::min(EndX(), 281 return std::min(EndX(),
276 ((icon_ != NULL) ? icon_->bounds().right() : 0) + kHorizontalPadding); 282 ((icon_ != NULL) ? icon_->bounds().right() : 0) + kHorizontalPadding);
277 } 283 }
278 284
279 int InfoBarView::EndX() const { 285 int InfoBarView::EndX() const {
280 const int kCloseButtonSpacing = 12; 286 const int kCloseButtonSpacing = 12;
281 return close_button_->x() - kCloseButtonSpacing; 287 return close_button_->x() - kCloseButtonSpacing;
282 } 288 }
283 289
284 int InfoBarView::CenterY(const gfx::Size prefsize) const { 290 int InfoBarView::CenterY(const gfx::Size prefsize) const {
285 return std::max((target_height_ - prefsize.height()) / 2, 0); 291 return std::max((target_height_ - prefsize.height()) / 2, 0);
286 } 292 }
287 293
288 int InfoBarView::OffsetY(const gfx::Size prefsize) const { 294 int InfoBarView::OffsetY(const gfx::Size prefsize) const {
289 return CenterY(prefsize) + AnimatedTabHeight() - 295 return CenterY(prefsize) + tab_height_ - (target_height_ - bar_height_);
290 (target_height_ - AnimatedBarHeight());
291 } 296 }
292 297
293 void InfoBarView::PlatformSpecificHide(bool animate) { 298 void InfoBarView::PlatformSpecificHide(bool animate) {
294 if (!animate) 299 if (!animate)
295 return; 300 return;
296 301
297 bool restore_focus = true; 302 bool restore_focus = true;
298 #if defined(OS_WIN) 303 #if defined(OS_WIN)
299 // Do not restore focus (and active state with it) on Windows if some other 304 // Do not restore focus (and active state with it) on Windows if some other
300 // top-level window became active. 305 // top-level window became active.
301 if (GetWidget() && 306 if (GetWidget() &&
302 !ui::DoesWindowBelongToActiveWindow(GetWidget()->GetNativeView())) 307 !ui::DoesWindowBelongToActiveWindow(GetWidget()->GetNativeView()))
303 restore_focus = false; 308 restore_focus = false;
304 #endif // defined(OS_WIN) 309 #endif // defined(OS_WIN)
305 DestroyFocusTracker(restore_focus); 310 DestroyFocusTracker(restore_focus);
306 } 311 }
307 312
308 void InfoBarView::GetAccessibleState(ui::AccessibleViewState* state) { 313 void InfoBarView::PlatformSpecificOnSizeChanged() {
309 if (delegate()) { 314 int old_tab_height = tab_height_;
310 state->name = l10n_util::GetStringUTF16( 315 int old_bar_height = bar_height_;
311 (delegate()->GetInfoBarType() == InfoBarDelegate::WARNING_TYPE) ? 316 tab_height_ = static_cast<int>(kTabHeight * animation()->GetCurrentValue());
312 IDS_ACCNAME_INFOBAR_WARNING : IDS_ACCNAME_INFOBAR_PAGE_ACTION); 317 bar_height_ =
313 } 318 static_cast<int>(target_height_ * animation()->GetCurrentValue());
314 state->role = ui::AccessibilityTypes::ROLE_ALERT; 319 if ((old_tab_height == tab_height_) && (old_bar_height == bar_height_))
315 } 320 return;
316 321
317 int InfoBarView::AnimatedTabHeight() const {
318 return static_cast<int>(kTabHeight * animation()->GetCurrentValue());
319 }
320
321 int InfoBarView::AnimatedBarHeight() const {
322 return static_cast<int>(target_height_ * animation()->GetCurrentValue());
323 }
324
325 gfx::Size InfoBarView::GetPreferredSize() {
326 return gfx::Size(0, AnimatedTabHeight() + AnimatedBarHeight());
327 }
328
329 void InfoBarView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
330 int tab_height = AnimatedTabHeight();
331 int bar_height = AnimatedBarHeight();
332 int divider_y = tab_height - 1;
333 DCHECK_EQ(tab_height + bar_height, height())
334 << "Animation progressed between Layout & OnBoundsChanged.";
335
336 int mirrored_x = GetMirroredXWithWidthInView(0, kTabWidth);
337 stroke_path_->rewind(); 322 stroke_path_->rewind();
338 fill_path_->rewind(); 323 fill_path_->rewind();
339 324 if (tab_height_) {
340 if (tab_height) { 325 int divider_y = tab_height_ - 1;
341 stroke_path_->moveTo(SkIntToScalar(mirrored_x), 326 stroke_path_->moveTo(
342 SkIntToScalar(divider_y)); 327 SkIntToScalar(GetMirroredXWithWidthInView(0, kTabWidth)),
328 SkIntToScalar(divider_y));
343 stroke_path_->rCubicTo( 329 stroke_path_->rCubicTo(
344 SkScalarDiv(kCurveWidth, 2), 0.0, 330 SkScalarDiv(kCurveWidth, 2), 0.0,
345 SkScalarDiv(kCurveWidth, 2), 331 SkScalarDiv(kCurveWidth, 2),
346 SkIntToScalar(-divider_y), 332 SkIntToScalar(-divider_y),
347 SkIntToScalar(kCurveWidth), 333 SkIntToScalar(kCurveWidth),
348 SkIntToScalar(-divider_y)); 334 SkIntToScalar(-divider_y));
349 stroke_path_->rLineTo(SkScalarMulAdd(kTabIconPadding, 2, kMaxIconWidth), 335 stroke_path_->rLineTo(SkScalarMulAdd(kTabIconPadding, 2, kMaxIconWidth),
350 0.0); 336 0.0);
351 stroke_path_->rCubicTo( 337 stroke_path_->rCubicTo(
352 SkScalarDiv(kCurveWidth, 2), 0.0, 338 SkScalarDiv(kCurveWidth, 2), 0.0,
(...skipping 12 matching lines...) Expand all
365 351
366 // Fill and stroke have different opinions about how to treat paths. 352 // Fill and stroke have different opinions about how to treat paths.
367 // Because in Skia integral coordinates represent pixel boundaries, 353 // Because in Skia integral coordinates represent pixel boundaries,
368 // offsetting the path makes it go exactly through pixel centers; this 354 // offsetting the path makes it go exactly through pixel centers; this
369 // results in lines that are exactly where we expect, instead of having odd 355 // results in lines that are exactly where we expect, instead of having odd
370 // "off by one" issues. Were we to do this for |fill_path|, however, which 356 // "off by one" issues. Were we to do this for |fill_path|, however, which
371 // tries to fill "inside" the path (using some questionable math), we'd get 357 // tries to fill "inside" the path (using some questionable math), we'd get
372 // a fill at a very different place than we'd want. 358 // a fill at a very different place than we'd want.
373 stroke_path_->offset(SK_ScalarHalf, SK_ScalarHalf); 359 stroke_path_->offset(SK_ScalarHalf, SK_ScalarHalf);
374 } 360 }
375 if (bar_height) { 361 if (bar_height_) {
376 fill_path_->addRect(0.0, SkIntToScalar(tab_height), 362 fill_path_->addRect(0.0, SkIntToScalar(tab_height_),
377 SkIntToScalar(width()), SkIntToScalar(height())); 363 SkIntToScalar(width()), SkIntToScalar(height()));
378 } 364 }
365
366 // Ensure that notifying our container of our size change will result in a
367 // re-layout.
368 InvalidateLayout();
Sheridan Rawlins 2011/04/01 18:41:48 InvalidateLayout only needs_layout, but doesn't ca
Peter Kasting 2011/04/01 19:07:15 We will notify the container immediately upon retu
369 }
370
371 void InfoBarView::GetAccessibleState(ui::AccessibleViewState* state) {
372 if (delegate()) {
373 state->name = l10n_util::GetStringUTF16(
374 (delegate()->GetInfoBarType() == InfoBarDelegate::WARNING_TYPE) ?
375 IDS_ACCNAME_INFOBAR_WARNING : IDS_ACCNAME_INFOBAR_PAGE_ACTION);
376 }
377 state->role = ui::AccessibilityTypes::ROLE_ALERT;
378 }
379
380 gfx::Size InfoBarView::GetPreferredSize() {
381 return gfx::Size(0, tab_height_ + bar_height_);
379 } 382 }
380 383
381 void InfoBarView::FocusWillChange(View* focused_before, View* focused_now) { 384 void InfoBarView::FocusWillChange(View* focused_before, View* focused_now) {
382 // This will trigger some screen readers to read the entire contents of this 385 // This will trigger some screen readers to read the entire contents of this
383 // infobar. 386 // infobar.
384 if (focused_before && focused_now && !this->Contains(focused_before) && 387 if (focused_before && focused_now && !this->Contains(focused_before) &&
385 this->Contains(focused_now) && GetWidget()) { 388 this->Contains(focused_now) && GetWidget()) {
386 GetWidget()->NotifyAccessibilityEvent( 389 GetWidget()->NotifyAccessibilityEvent(
387 this, ui::AccessibilityTypes::EVENT_ALERT, true); 390 this, ui::AccessibilityTypes::EVENT_ALERT, true);
388 } 391 }
389 } 392 }
390 393
391 void InfoBarView::DestroyFocusTracker(bool restore_focus) { 394 void InfoBarView::DestroyFocusTracker(bool restore_focus) {
392 if (focus_tracker_ != NULL) { 395 if (focus_tracker_ != NULL) {
393 if (restore_focus) 396 if (restore_focus)
394 focus_tracker_->FocusLastFocusedExternalView(); 397 focus_tracker_->FocusLastFocusedExternalView();
395 focus_tracker_->SetFocusManager(NULL); 398 focus_tracker_->SetFocusManager(NULL);
396 focus_tracker_.reset(); 399 focus_tracker_.reset();
397 } 400 }
398 } 401 }
399 402
400 void InfoBarView::DeleteSelf() { 403 void InfoBarView::DeleteSelf() {
401 delete this; 404 delete this;
402 } 405 }
OLDNEW
« chrome/browser/ui/views/infobars/infobar.h ('K') | « chrome/browser/ui/views/infobars/infobar_view.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698