confirm_infobar.cc revision 0529e5d033099cbfc42635f6f6183833b09dff6e
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// static
18scoped_ptr<infobars::InfoBar> ConfirmInfoBarDelegate::CreateInfoBar(
19    scoped_ptr<ConfirmInfoBarDelegate> delegate) {
20  return scoped_ptr<infobars::InfoBar>(new ConfirmInfoBar(delegate.Pass()));
21}
22
23
24// ConfirmInfoBar -------------------------------------------------------------
25
26ConfirmInfoBar::ConfirmInfoBar(scoped_ptr<ConfirmInfoBarDelegate> delegate)
27    : InfoBarView(delegate.PassAs<infobars::InfoBarDelegate>()),
28      label_(NULL),
29      ok_button_(NULL),
30      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