| 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 <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 | 61 |
| 62 InfoBarView::InfoBarView(TabContentsWrapper* owner, InfoBarDelegate* delegate) | 62 InfoBarView::InfoBarView(TabContentsWrapper* owner, InfoBarDelegate* delegate) |
| 63 : InfoBar(owner, delegate), | 63 : InfoBar(owner, delegate), |
| 64 icon_(NULL), | 64 icon_(NULL), |
| 65 close_button_(NULL) { | 65 close_button_(NULL) { |
| 66 set_parent_owned(false); // InfoBar deletes itself at the appropriate time. | 66 set_parent_owned(false); // InfoBar deletes itself at the appropriate time. |
| 67 set_background(new InfoBarBackground(delegate->GetInfoBarType())); | 67 set_background(new InfoBarBackground(delegate->GetInfoBarType())); |
| 68 } | 68 } |
| 69 | 69 |
| 70 InfoBarView::~InfoBarView() { | 70 InfoBarView::~InfoBarView() { |
| 71 // We should have closed any open menus in PlatformSpecificHide(), then |
| 72 // subclasses' RunMenu() functions should have prevented opening any new ones |
| 73 // once we became unowned. |
| 74 DCHECK(!menu_runner_.get()); |
| 71 } | 75 } |
| 72 | 76 |
| 73 // static | 77 // static |
| 74 views::Label* InfoBarView::CreateLabel(const string16& text) { | 78 views::Label* InfoBarView::CreateLabel(const string16& text) { |
| 75 views::Label* label = new views::Label(UTF16ToWideHack(text), | 79 views::Label* label = new views::Label(UTF16ToWideHack(text), |
| 76 ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::MediumFont)); | 80 ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::MediumFont)); |
| 77 label->SetColor(SK_ColorBLACK); | 81 label->SetColor(SK_ColorBLACK); |
| 78 label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | 82 label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
| 79 return label; | 83 return label; |
| 80 } | 84 } |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 // canvas_skia->clipPath(fill_path_); | 256 // canvas_skia->clipPath(fill_path_); |
| 253 DCHECK_EQ(total_height(), height()) | 257 DCHECK_EQ(total_height(), height()) |
| 254 << "Infobar piecewise heights do not match overall height"; | 258 << "Infobar piecewise heights do not match overall height"; |
| 255 canvas->ClipRectInt(0, arrow_height(), width(), bar_height()); | 259 canvas->ClipRectInt(0, arrow_height(), width(), bar_height()); |
| 256 views::View::PaintChildren(canvas); | 260 views::View::PaintChildren(canvas); |
| 257 canvas->Restore(); | 261 canvas->Restore(); |
| 258 } | 262 } |
| 259 | 263 |
| 260 void InfoBarView::ButtonPressed(views::Button* sender, | 264 void InfoBarView::ButtonPressed(views::Button* sender, |
| 261 const views::Event& event) { | 265 const views::Event& event) { |
| 266 DCHECK(owned()); // Subclasses should never call us while we're closing. |
| 262 if (sender == close_button_) { | 267 if (sender == close_button_) { |
| 263 // If we're not owned, we're already closing, so don't call | 268 delegate()->InfoBarDismissed(); |
| 264 // InfoBarDismissed(), since this can lead to us double-recording | |
| 265 // dismissals. | |
| 266 if (delegate() && owned()) | |
| 267 delegate()->InfoBarDismissed(); | |
| 268 RemoveSelf(); | 269 RemoveSelf(); |
| 269 } | 270 } |
| 270 } | 271 } |
| 271 | 272 |
| 272 int InfoBarView::ContentMinimumWidth() const { | 273 int InfoBarView::ContentMinimumWidth() const { |
| 273 return 0; | 274 return 0; |
| 274 } | 275 } |
| 275 | 276 |
| 276 int InfoBarView::StartX() const { | 277 int InfoBarView::StartX() const { |
| 277 // 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 |
| 278 // set something's width to "EndX() - StartX()" without risking that being | 279 // set something's width to "EndX() - StartX()" without risking that being |
| 279 // negative. | 280 // negative. |
| 280 return std::min(EndX(), | 281 return std::min(EndX(), |
| 281 ((icon_ != NULL) ? icon_->bounds().right() : 0) + kHorizontalPadding); | 282 ((icon_ != NULL) ? icon_->bounds().right() : 0) + kHorizontalPadding); |
| 282 } | 283 } |
| 283 | 284 |
| 284 int InfoBarView::EndX() const { | 285 int InfoBarView::EndX() const { |
| 285 const int kCloseButtonSpacing = 12; | 286 const int kCloseButtonSpacing = 12; |
| 286 return close_button_->x() - kCloseButtonSpacing; | 287 return close_button_->x() - kCloseButtonSpacing; |
| 287 } | 288 } |
| 288 | 289 |
| 289 const InfoBarContainer::Delegate* InfoBarView::container_delegate() const { | 290 const InfoBarContainer::Delegate* InfoBarView::container_delegate() const { |
| 290 const InfoBarContainer* infobar_container = container(); | 291 const InfoBarContainer* infobar_container = container(); |
| 291 return infobar_container ? infobar_container->delegate() : NULL; | 292 return infobar_container ? infobar_container->delegate() : NULL; |
| 292 } | 293 } |
| 293 | 294 |
| 294 void InfoBarView::RunMenuAt(ui::MenuModel* menu_model, | 295 void InfoBarView::RunMenuAt(ui::MenuModel* menu_model, |
| 295 views::MenuButton* button, | 296 views::MenuButton* button, |
| 296 views::MenuItemView::AnchorPosition anchor) { | 297 views::MenuItemView::AnchorPosition anchor) { |
| 298 DCHECK(owned()); // We'd better not open any menus while we're closing. |
| 297 views::MenuModelAdapter adapter(menu_model); | 299 views::MenuModelAdapter adapter(menu_model); |
| 298 gfx::Point screen_point; | 300 gfx::Point screen_point; |
| 299 views::View::ConvertPointToScreen(button, &screen_point); | 301 views::View::ConvertPointToScreen(button, &screen_point); |
| 300 menu_runner_.reset(new views::MenuRunner(adapter.CreateMenu())); | 302 menu_runner_.reset(new views::MenuRunner(adapter.CreateMenu())); |
| 301 // Ignore the result as we know we can only get here after the menu has | 303 // Ignore the result since we don't need to handle a deleted menu specially. |
| 302 // closed. | |
| 303 ignore_result(menu_runner_->RunMenuAt( | 304 ignore_result(menu_runner_->RunMenuAt( |
| 304 GetWidget(), button, gfx::Rect(screen_point, button->size()), anchor, | 305 GetWidget(), button, gfx::Rect(screen_point, button->size()), anchor, |
| 305 views::MenuRunner::HAS_MNEMONICS)); | 306 views::MenuRunner::HAS_MNEMONICS)); |
| 306 // TODO(pkasting): this may be deleted after rewrite. | |
| 307 } | 307 } |
| 308 | 308 |
| 309 void InfoBarView::PlatformSpecificShow(bool animate) { | 309 void InfoBarView::PlatformSpecificShow(bool animate) { |
| 310 views::Widget* widget = GetWidget(); | 310 views::Widget* widget = GetWidget(); |
| 311 views::FocusManager* focus_manager = GetFocusManager(); | 311 views::FocusManager* focus_manager = GetFocusManager(); |
| 312 #if defined(OS_WIN) | 312 #if defined(OS_WIN) |
| 313 // If we gain focus, we want to restore it to the previously-focused element | 313 // If we gain focus, we want to restore it to the previously-focused element |
| 314 // when we're hidden. So when we're in a Widget, create a focus tracker so | 314 // when we're hidden. So when we're in a Widget, create a focus tracker so |
| 315 // that if we gain focus we'll know what the previously-focused element was. | 315 // that if we gain focus we'll know what the previously-focused element was. |
| 316 if (widget) { | 316 if (widget) { |
| 317 focus_tracker_.reset( | 317 focus_tracker_.reset( |
| 318 new views::ExternalFocusTracker(this, focus_manager)); | 318 new views::ExternalFocusTracker(this, focus_manager)); |
| 319 } | 319 } |
| 320 #endif | 320 #endif |
| 321 if (focus_manager) | 321 if (focus_manager) |
| 322 focus_manager->AddFocusChangeListener(this); | 322 focus_manager->AddFocusChangeListener(this); |
| 323 if (widget) { | 323 if (widget) { |
| 324 widget->NotifyAccessibilityEvent( | 324 widget->NotifyAccessibilityEvent( |
| 325 this, ui::AccessibilityTypes::EVENT_ALERT, true); | 325 this, ui::AccessibilityTypes::EVENT_ALERT, true); |
| 326 } | 326 } |
| 327 } | 327 } |
| 328 | 328 |
| 329 void InfoBarView::PlatformSpecificHide(bool animate) { | 329 void InfoBarView::PlatformSpecificHide(bool animate) { |
| 330 // We're being removed. Cancel any menus we may have open. Because we are | 330 // Cancel any menus we may have open. It doesn't make sense to leave them |
| 331 // deleted after a delay and after our delegate is deleted we have to | 331 // open while we're hidden, and if we're going to become unowned, we can't |
| 332 // explicitly cancel the menu rather than relying on the destructor to cancel | 332 // allow the user to choose any options and potentially call functions that |
| 333 // the menu. | 333 // try to access the owner. |
| 334 menu_runner_.reset(); | 334 menu_runner_.reset(); |
| 335 | 335 |
| 336 // It's possible to be called twice (once with |animate| true and once with it | 336 // It's possible to be called twice (once with |animate| true and once with it |
| 337 // false); in this case the second RemoveFocusChangeListener() call will | 337 // false); in this case the second RemoveFocusChangeListener() call will |
| 338 // silently no-op. | 338 // silently no-op. |
| 339 views::FocusManager* focus_manager = GetFocusManager(); | 339 views::FocusManager* focus_manager = GetFocusManager(); |
| 340 if (focus_manager) | 340 if (focus_manager) |
| 341 focus_manager->RemoveFocusChangeListener(this); | 341 focus_manager->RemoveFocusChangeListener(this); |
| 342 | 342 |
| 343 #if defined(OS_WIN) && !defined(USE_AURA) | 343 #if defined(OS_WIN) && !defined(USE_AURA) |
| (...skipping 30 matching lines...) Expand all Loading... |
| 374 | 374 |
| 375 void InfoBarView::FocusWillChange(View* focused_before, View* focused_now) { | 375 void InfoBarView::FocusWillChange(View* focused_before, View* focused_now) { |
| 376 // This will trigger some screen readers to read the entire contents of this | 376 // This will trigger some screen readers to read the entire contents of this |
| 377 // infobar. | 377 // infobar. |
| 378 if (focused_before && focused_now && !Contains(focused_before) && | 378 if (focused_before && focused_now && !Contains(focused_before) && |
| 379 Contains(focused_now) && GetWidget()) { | 379 Contains(focused_now) && GetWidget()) { |
| 380 GetWidget()->NotifyAccessibilityEvent( | 380 GetWidget()->NotifyAccessibilityEvent( |
| 381 this, ui::AccessibilityTypes::EVENT_ALERT, true); | 381 this, ui::AccessibilityTypes::EVENT_ALERT, true); |
| 382 } | 382 } |
| 383 } | 383 } |
| OLD | NEW |