confirm_infobar.cc revision ca12bfac764ba476d6cd062bf1dde12cc64c3f40
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
17InfoBar* ConfirmInfoBarDelegate::CreateInfoBar(InfoBarService* owner) {
18  return new ConfirmInfoBar(owner, this);
19}
20
21
22// ConfirmInfoBar -------------------------------------------------------------
23
24ConfirmInfoBar::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
33ConfirmInfoBar::~ConfirmInfoBar() {
34}
35
36void 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
67void 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
100void 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
116int 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
127void 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
136ConfirmInfoBarDelegate* ConfirmInfoBar::GetDelegate() {
137  return delegate()->AsConfirmInfoBarDelegate();
138}
139