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/alternate_nav_infobar_view.h"
7 #include "base/logging.h"
8 #include "chrome/browser/ui/omnibox/alternate_nav_infobar_delegate.h"
9 #include "ui/base/window_open_disposition.h"
10 #include "ui/gfx/text_elider.h"
11 #include "ui/views/controls/label.h"
12 #include "ui/views/controls/link.h"
15 // AlternateNavInfoBarDelegate -------------------------------------------------
18 scoped_ptr
<infobars::InfoBar
> AlternateNavInfoBarDelegate::CreateInfoBar(
19 scoped_ptr
<AlternateNavInfoBarDelegate
> delegate
) {
20 return make_scoped_ptr(new AlternateNavInfoBarView(delegate
.Pass()));
24 // AlternateNavInfoBarView -----------------------------------------------------
26 AlternateNavInfoBarView::AlternateNavInfoBarView(
27 scoped_ptr
<AlternateNavInfoBarDelegate
> delegate
)
28 : InfoBarView(delegate
.Pass()),
34 AlternateNavInfoBarView::~AlternateNavInfoBarView() {
38 void AlternateNavInfoBarView::ElideLabels(Labels
* labels
, int available_width
) {
39 views::Label
* last_label
= labels
->back();
42 for (Labels::iterator
i(labels
->begin()); i
!= labels
->end(); ++i
)
43 used_width
+= (*i
)->GetPreferredSize().width();
44 int last_label_width
= std::min(last_label
->GetPreferredSize().width(),
45 available_width
- used_width
);
46 if (last_label_width
< last_label
->GetMinimumSize().width()) {
49 labels
->back()->SetText(labels
->back()->text() + gfx::kEllipsisUTF16
);
51 last_label
->SetSize(gfx::Size(last_label_width
, last_label
->height()));
53 ElideLabels(labels
, available_width
- last_label_width
);
56 void AlternateNavInfoBarView::Layout() {
57 InfoBarView::Layout();
59 label_1_
->SetText(label_1_text_
);
60 link_
->SetText(link_text_
);
61 label_2_
->SetText(label_2_text_
);
63 labels
.push_back(label_1_
);
64 labels
.push_back(link_
);
65 labels
.push_back(label_2_
);
66 ElideLabels(&labels
, EndX() - StartX());
68 label_1_
->SetPosition(gfx::Point(StartX(), OffsetY(label_1_
)));
69 link_
->SetPosition(gfx::Point(label_1_
->bounds().right(), OffsetY(link_
)));
70 label_2_
->SetPosition(gfx::Point(link_
->bounds().right(), OffsetY(label_2_
)));
73 void AlternateNavInfoBarView::ViewHierarchyChanged(
74 const ViewHierarchyChangedDetails
& details
) {
75 if (details
.is_add
&& (details
.child
== this) && (label_1_
== NULL
)) {
76 AlternateNavInfoBarDelegate
* delegate
= GetDelegate();
78 base::string16 message_text
= delegate
->GetMessageTextWithOffset(&offset
);
79 DCHECK_NE(base::string16::npos
, offset
);
80 label_1_text_
= message_text
.substr(0, offset
);
81 label_1_
= CreateLabel(label_1_text_
);
82 AddChildView(label_1_
);
84 link_text_
= delegate
->GetLinkText();
85 link_
= CreateLink(link_text_
, this);
88 label_2_text_
= message_text
.substr(offset
);
89 label_2_
= CreateLabel(label_2_text_
);
90 AddChildView(label_2_
);
93 // This must happen after adding all other children so InfoBarView can ensure
94 // the close button is the last child.
95 InfoBarView::ViewHierarchyChanged(details
);
98 int AlternateNavInfoBarView::ContentMinimumWidth() const {
99 int label_1_width
= label_1_
->GetMinimumSize().width();
100 return label_1_width
? label_1_width
: link_
->GetMinimumSize().width();
103 void AlternateNavInfoBarView::LinkClicked(views::Link
* source
,
106 return; // We're closing; don't call anything, it might access the owner.
107 DCHECK(link_
!= NULL
);
108 DCHECK_EQ(link_
, source
);
109 if (GetDelegate()->LinkClicked(ui::DispositionFromEventFlags(event_flags
)))
113 AlternateNavInfoBarDelegate
* AlternateNavInfoBarView::GetDelegate() {
114 return static_cast<AlternateNavInfoBarDelegate
*>(delegate());