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