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/infobar_service.h"
9 #include "chrome/browser/ui/views/elevation_icon_setter.h"
10 #include "components/infobars/core/confirm_infobar_delegate.h"
11 #include "ui/base/resource/material_design/material_design_controller.h"
12 #include "ui/base/window_open_disposition.h"
13 #include "ui/views/controls/button/label_button.h"
14 #include "ui/views/controls/label.h"
15 #include "ui/views/controls/link.h"
17 // InfoBarService -------------------------------------------------------------
19 scoped_ptr
<infobars::InfoBar
> InfoBarService::CreateConfirmInfoBar(
20 scoped_ptr
<ConfirmInfoBarDelegate
> delegate
) {
21 return make_scoped_ptr(new ConfirmInfoBar(delegate
.Pass()));
25 // ConfirmInfoBar -------------------------------------------------------------
27 ConfirmInfoBar::ConfirmInfoBar(scoped_ptr
<ConfirmInfoBarDelegate
> delegate
)
28 : InfoBarView(delegate
.Pass()),
35 ConfirmInfoBar::~ConfirmInfoBar() {
36 // Ensure |elevation_icon_setter_| is destroyed before |ok_button_|.
37 elevation_icon_setter_
.reset();
40 void ConfirmInfoBar::Layout() {
41 InfoBarView::Layout();
45 labels
.push_back(label_
);
46 labels
.push_back(link_
);
47 AssignWidths(&labels
, std::max(0, EndX() - x
- NonLabelWidth()));
49 label_
->SetPosition(gfx::Point(x
, OffsetY(label_
)));
50 if (!label_
->text().empty())
51 x
= label_
->bounds().right() + kEndOfLabelSpacing
;
54 ok_button_
->SetPosition(gfx::Point(x
, OffsetY(ok_button_
)));
55 x
= ok_button_
->bounds().right() + kButtonButtonSpacing
;
59 cancel_button_
->SetPosition(gfx::Point(x
, OffsetY(cancel_button_
)));
61 link_
->SetPosition(gfx::Point(EndX() - link_
->width(), OffsetY(link_
)));
64 void ConfirmInfoBar::ViewHierarchyChanged(
65 const ViewHierarchyChangedDetails
& details
) {
66 if (details
.is_add
&& details
.child
== this && (label_
== NULL
)) {
67 ConfirmInfoBarDelegate
* delegate
= GetDelegate();
68 label_
= CreateLabel(delegate
->GetMessageText());
71 if (delegate
->GetButtons() & ConfirmInfoBarDelegate::BUTTON_OK
) {
72 ok_button_
= CreateLabelButton(
73 this, delegate
->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK
));
74 if (delegate
->OKButtonTriggersUACPrompt())
75 elevation_icon_setter_
.reset(new ElevationIconSetter(
77 base::Bind(&ConfirmInfoBar::Layout
, base::Unretained(this))));
78 AddChildView(ok_button_
);
79 ok_button_
->SizeToPreferredSize();
82 if (delegate
->GetButtons() & ConfirmInfoBarDelegate::BUTTON_CANCEL
) {
83 cancel_button_
= CreateLabelButton(
85 delegate
->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_CANCEL
));
86 AddChildView(cancel_button_
);
87 cancel_button_
->SizeToPreferredSize();
90 base::string16
link_text(delegate
->GetLinkText());
91 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 (sender
== ok_button_
) {
106 if (delegate
->Accept())
108 } else if (sender
== cancel_button_
) {
109 if (delegate
->Cancel())
112 InfoBarView::ButtonPressed(sender
, event
);
116 int ConfirmInfoBar::ContentMinimumWidth() const {
117 return label_
->GetMinimumSize().width() + link_
->GetMinimumSize().width() +
121 void ConfirmInfoBar::LinkClicked(views::Link
* source
, int event_flags
) {
123 return; // We're closing; don't call anything, it might access the owner.
124 DCHECK_EQ(link_
, source
);
125 if (GetDelegate()->LinkClicked(ui::DispositionFromEventFlags(event_flags
)))
129 ConfirmInfoBarDelegate
* ConfirmInfoBar::GetDelegate() {
130 return delegate()->AsConfirmInfoBarDelegate();
133 int ConfirmInfoBar::NonLabelWidth() const {
134 int width
= (label_
->text().empty() || (!ok_button_
&& !cancel_button_
)) ?
135 0 : kEndOfLabelSpacing
;
137 width
+= ok_button_
->width() + (cancel_button_
? kButtonButtonSpacing
: 0);
138 width
+= cancel_button_
? cancel_button_
->width() : 0;
139 return width
+ ((link_
->text().empty() || !width
) ? 0 : kEndOfLabelSpacing
);