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 |