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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/ui/views/infobars/confirm_infobar.h" 6 7 #include "chrome/browser/tab_contents/confirm_infobar_delegate.h" 8 #include "chrome/browser/ui/views/event_utils.h" 9 #include "views/controls/button/text_button.h" 10 #include "views/controls/label.h" 11 12 // ConfirmInfoBarDelegate ----------------------------------------------------- 13 14 InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() { 15 return new ConfirmInfoBar(this); 16 } 17 18 // ConfirmInfoBar ------------------------------------------------------------- 19 20 ConfirmInfoBar::ConfirmInfoBar(ConfirmInfoBarDelegate* delegate) 21 : InfoBarView(delegate), 22 label_(NULL), 23 ok_button_(NULL), 24 cancel_button_(NULL), 25 link_(NULL) { 26 } 27 28 ConfirmInfoBar::~ConfirmInfoBar() { 29 } 30 31 void ConfirmInfoBar::Layout() { 32 InfoBarView::Layout(); 33 34 int available_width = std::max(0, EndX() - StartX() - ContentMinimumWidth()); 35 gfx::Size label_size = label_->GetPreferredSize(); 36 label_->SetBounds(StartX(), OffsetY(label_size), 37 std::min(label_size.width(), available_width), label_size.height()); 38 available_width = std::max(0, available_width - label_size.width()); 39 40 int button_x = label_->bounds().right() + kEndOfLabelSpacing; 41 if (ok_button_ != NULL) { 42 gfx::Size ok_size = ok_button_->GetPreferredSize(); 43 ok_button_->SetBounds(button_x, OffsetY(ok_size), ok_size.width(), 44 ok_size.height()); 45 button_x += ok_size.width() + kButtonButtonSpacing; 46 } 47 48 if (cancel_button_ != NULL) { 49 gfx::Size cancel_size = cancel_button_->GetPreferredSize(); 50 cancel_button_->SetBounds(button_x, OffsetY(cancel_size), 51 cancel_size.width(), cancel_size.height()); 52 } 53 54 if (link_ != NULL) { 55 gfx::Size link_size = link_->GetPreferredSize(); 56 int link_width = std::min(link_size.width(), available_width); 57 link_->SetBounds(EndX() - link_width, OffsetY(link_size), link_width, 58 link_size.height()); 59 } 60 } 61 62 void ConfirmInfoBar::ViewHierarchyChanged(bool is_add, 63 View* parent, 64 View* child) { 65 if (is_add && child == this && (label_ == NULL)) { 66 ConfirmInfoBarDelegate* delegate = GetDelegate(); 67 label_ = CreateLabel(delegate->GetMessageText()); 68 AddChildView(label_); 69 70 if (delegate->GetButtons() & ConfirmInfoBarDelegate::BUTTON_OK) { 71 ok_button_ = CreateTextButton(this, 72 delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK), 73 delegate->NeedElevation(ConfirmInfoBarDelegate::BUTTON_OK)); 74 AddChildView(ok_button_); 75 } 76 77 if (delegate->GetButtons() & ConfirmInfoBarDelegate::BUTTON_CANCEL) { 78 cancel_button_ = CreateTextButton(this, 79 delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_CANCEL), 80 delegate->NeedElevation(ConfirmInfoBarDelegate::BUTTON_CANCEL)); 81 AddChildView(cancel_button_); 82 } 83 84 string16 link_text(delegate->GetLinkText()); 85 if (!link_text.empty()) { 86 link_ = CreateLink(link_text, this, background()->get_color()); 87 AddChildView(link_); 88 } 89 } 90 91 // This must happen after adding all other children so InfoBarView can ensure 92 // the close button is the last child. 93 InfoBarView::ViewHierarchyChanged(is_add, parent, child); 94 } 95 96 void ConfirmInfoBar::ButtonPressed(views::Button* sender, 97 const views::Event& event) { 98 ConfirmInfoBarDelegate* delegate = GetDelegate(); 99 if ((ok_button_ != NULL) && sender == ok_button_) { 100 if (delegate->Accept()) 101 RemoveInfoBar(); 102 } else if ((cancel_button_ != NULL) && (sender == cancel_button_)) { 103 if (delegate->Cancel()) 104 RemoveInfoBar(); 105 } else { 106 InfoBarView::ButtonPressed(sender, event); 107 } 108 } 109 110 int ConfirmInfoBar::ContentMinimumWidth() const { 111 int width = (link_ == NULL) ? 0 : kEndOfLabelSpacing; // Space before link 112 int before_cancel_spacing = kEndOfLabelSpacing; 113 if (ok_button_ != NULL) { 114 width += kEndOfLabelSpacing + ok_button_->GetPreferredSize().width(); 115 before_cancel_spacing = kButtonButtonSpacing; 116 } 117 return width + ((cancel_button_ == NULL) ? 0 : 118 (before_cancel_spacing + cancel_button_->GetPreferredSize().width())); 119 } 120 121 void ConfirmInfoBar::LinkActivated(views::Link* source, int event_flags) { 122 DCHECK(link_ != NULL); 123 DCHECK_EQ(link_, source); 124 if (GetDelegate()->LinkClicked( 125 event_utils::DispositionFromEventFlags(event_flags))) 126 RemoveInfoBar(); 127 } 128 129 ConfirmInfoBarDelegate* ConfirmInfoBar::GetDelegate() { 130 return delegate()->AsConfirmInfoBarDelegate(); 131 } 132