Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |