confirm_infobar.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam// Use of this source code is governed by a BSD-style license that can be
3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam// found in the LICENSE file.
4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam#include "chrome/browser/ui/views/infobars/confirm_infobar.h"
6b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam#include "base/logging.h"
8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam#include "chrome/browser/infobars/confirm_infobar_delegate.h"
9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam#include "ui/base/window_open_disposition.h"
10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam#include "ui/views/controls/button/label_button.h"
11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam#include "ui/views/controls/label.h"
12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam#include "ui/views/controls/link.h"
13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam// ConfirmInfoBarDelegate -----------------------------------------------------
16c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam// static
18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamscoped_ptr<InfoBar> ConfirmInfoBarDelegate::CreateInfoBar(
19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    scoped_ptr<ConfirmInfoBarDelegate> delegate) {
20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam  return scoped_ptr<InfoBar>(new ConfirmInfoBar(delegate.Pass()));
21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam// ConfirmInfoBar -------------------------------------------------------------
25c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
26c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian CarlstromConfirmInfoBar::ConfirmInfoBar(scoped_ptr<ConfirmInfoBarDelegate> delegate)
27c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    : InfoBarView(delegate.PassAs<InfoBarDelegate>()),
28c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom      label_(NULL),
29c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom      ok_button_(NULL),
30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam      cancel_button_(NULL),
31      link_(NULL) {
32}
33
34ConfirmInfoBar::~ConfirmInfoBar() {
35}
36
37void ConfirmInfoBar::Layout() {
38  InfoBarView::Layout();
39
40  int x = StartX();
41  Labels labels;
42  labels.push_back(label_);
43  labels.push_back(link_);
44  AssignWidths(&labels, std::max(0, EndX() - x - NonLabelWidth()));
45
46  label_->SetPosition(gfx::Point(x, OffsetY(label_)));
47  if (!label_->text().empty())
48    x = label_->bounds().right() + kEndOfLabelSpacing;
49
50  if (ok_button_) {
51    ok_button_->SetPosition(gfx::Point(x, OffsetY(ok_button_)));
52    x = ok_button_->bounds().right() + kButtonButtonSpacing;
53  }
54
55  if (cancel_button_)
56    cancel_button_->SetPosition(gfx::Point(x, OffsetY(cancel_button_)));
57
58  link_->SetPosition(gfx::Point(EndX() - link_->width(), OffsetY(link_)));
59}
60
61void ConfirmInfoBar::ViewHierarchyChanged(
62    const ViewHierarchyChangedDetails& details) {
63  if (details.is_add && details.child == this && (label_ == NULL)) {
64    ConfirmInfoBarDelegate* delegate = GetDelegate();
65    label_ = CreateLabel(delegate->GetMessageText());
66    AddChildView(label_);
67
68    if (delegate->GetButtons() & ConfirmInfoBarDelegate::BUTTON_OK) {
69      ok_button_ = CreateLabelButton(this,
70          delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK),
71          delegate->NeedElevation(ConfirmInfoBarDelegate::BUTTON_OK));
72      AddChildView(ok_button_);
73    }
74
75    if (delegate->GetButtons() & ConfirmInfoBarDelegate::BUTTON_CANCEL) {
76      cancel_button_ = CreateLabelButton(this,
77          delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_CANCEL),
78          delegate->NeedElevation(ConfirmInfoBarDelegate::BUTTON_CANCEL));
79      AddChildView(cancel_button_);
80    }
81
82    base::string16 link_text(delegate->GetLinkText());
83    link_ = CreateLink(link_text, this);
84    AddChildView(link_);
85  }
86
87  // This must happen after adding all other children so InfoBarView can ensure
88  // the close button is the last child.
89  InfoBarView::ViewHierarchyChanged(details);
90}
91
92void ConfirmInfoBar::ButtonPressed(views::Button* sender,
93                                   const ui::Event& event) {
94  if (!owner())
95    return;  // We're closing; don't call anything, it might access the owner.
96  ConfirmInfoBarDelegate* delegate = GetDelegate();
97  if ((ok_button_ != NULL) && sender == ok_button_) {
98    if (delegate->Accept())
99      RemoveSelf();
100  } else if ((cancel_button_ != NULL) && (sender == cancel_button_)) {
101    if (delegate->Cancel())
102      RemoveSelf();
103  } else {
104    InfoBarView::ButtonPressed(sender, event);
105  }
106}
107
108int ConfirmInfoBar::ContentMinimumWidth() {
109  return label_->GetMinimumSize().width() + link_->GetMinimumSize().width() +
110      NonLabelWidth();
111}
112
113void ConfirmInfoBar::LinkClicked(views::Link* source, int event_flags) {
114  if (!owner())
115    return;  // We're closing; don't call anything, it might access the owner.
116  DCHECK_EQ(link_, source);
117  if (GetDelegate()->LinkClicked(ui::DispositionFromEventFlags(event_flags)))
118    RemoveSelf();
119}
120
121ConfirmInfoBarDelegate* ConfirmInfoBar::GetDelegate() {
122  return delegate()->AsConfirmInfoBarDelegate();
123}
124
125int ConfirmInfoBar::NonLabelWidth() const {
126  int width = (label_->text().empty() || (!ok_button_ && !cancel_button_)) ?
127      0 : kEndOfLabelSpacing;
128  if (ok_button_)
129    width += ok_button_->width() + (cancel_button_ ? kButtonButtonSpacing : 0);
130  width += (cancel_button_ ? cancel_button_->width() : 0);
131  return width + ((link_->text().empty() || !width) ? 0 : kEndOfLabelSpacing);
132}
133