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.
5 #include "chrome/browser/ui/views/infobars/confirm_infobar.h"
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"
15 // ConfirmInfoBarDelegate -----------------------------------------------------
17 InfoBar* ConfirmInfoBarDelegate::CreateInfoBar(InfoBarService* owner) {
18 return new ConfirmInfoBar(owner, this);
22 // ConfirmInfoBar -------------------------------------------------------------
24 ConfirmInfoBar::ConfirmInfoBar(InfoBarService* owner,
25 ConfirmInfoBarDelegate* delegate)
26 : InfoBarView(owner, delegate),
33 ConfirmInfoBar::~ConfirmInfoBar() {
36 void ConfirmInfoBar::Layout() {
37 InfoBarView::Layout();
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());
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(),
50 button_x += ok_size.width() + kButtonButtonSpacing;
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());
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,
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());
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_);
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_);
88 string16 link_text(delegate->GetLinkText());
89 if (!link_text.empty()) {
90 link_ = CreateLink(link_text, this);
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);
100 void ConfirmInfoBar::ButtonPressed(views::Button* sender,
101 const ui::Event& event) {
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())
108 } else if ((cancel_button_ != NULL) && (sender == cancel_button_)) {
109 if (delegate->Cancel())
112 InfoBarView::ButtonPressed(sender, event);
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;
123 return width + ((cancel_button_ == NULL) ? 0 :
124 (before_cancel_spacing + cancel_button_->GetPreferredSize().width()));
127 void ConfirmInfoBar::LinkClicked(views::Link* source, int event_flags) {
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)))
136 ConfirmInfoBarDelegate* ConfirmInfoBar::GetDelegate() {
137 return delegate()->AsConfirmInfoBarDelegate();