alternate_nav_infobar_view.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
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/alternate_nav_infobar_view.h"
6
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/views/controls/label.h"
11#include "ui/views/controls/link.h"
12
13
14// AlternateNavInfoBarDelegate -------------------------------------------------
15
16// static
17scoped_ptr<InfoBar> AlternateNavInfoBarDelegate::CreateInfoBar(
18    scoped_ptr<AlternateNavInfoBarDelegate> delegate) {
19  return scoped_ptr<InfoBar>(new AlternateNavInfoBarView(delegate.Pass()));
20}
21
22
23// AlternateNavInfoBarView -----------------------------------------------------
24
25AlternateNavInfoBarView::AlternateNavInfoBarView(
26    scoped_ptr<AlternateNavInfoBarDelegate> delegate)
27    : InfoBarView(delegate.PassAs<InfoBarDelegate>()),
28      label_1_(NULL),
29      link_(NULL),
30      label_2_(NULL) {
31}
32
33AlternateNavInfoBarView::~AlternateNavInfoBarView() {
34}
35
36void AlternateNavInfoBarView::Layout() {
37  InfoBarView::Layout();
38
39  // TODO(pkasting): This isn't perfect; there are points when we should elide a
40  // view because its subsequent view will be too small to show an ellipsis.
41  gfx::Size label_1_size = label_1_->GetPreferredSize();
42  int available_width = EndX() - StartX();
43  label_1_->SetBounds(StartX(), OffsetY(label_1_size),
44      std::min(label_1_size.width(), available_width), label_1_size.height());
45  available_width = std::max(0, available_width - label_1_size.width());
46
47  gfx::Size link_size = link_->GetPreferredSize();
48  link_->SetBounds(label_1_->bounds().right(), OffsetY(link_size),
49      std::min(link_size.width(), available_width), link_size.height());
50  available_width = std::max(0, available_width - link_size.width());
51
52  gfx::Size label_2_size = label_2_->GetPreferredSize();
53  label_2_->SetBounds(link_->bounds().right(), OffsetY(label_2_size),
54      std::min(label_2_size.width(), available_width), label_2_size.height());
55}
56
57void AlternateNavInfoBarView::ViewHierarchyChanged(
58    const ViewHierarchyChangedDetails& details) {
59  if (details.is_add && (details.child == this) && (label_1_ == NULL)) {
60    AlternateNavInfoBarDelegate* delegate = GetDelegate();
61    size_t offset;
62    base::string16 message_text = delegate->GetMessageTextWithOffset(&offset);
63    DCHECK_NE(string16::npos, offset);
64    label_1_ = CreateLabel(message_text.substr(0, offset));
65    AddChildView(label_1_);
66
67    link_ = CreateLink(delegate->GetLinkText(), this);
68    AddChildView(link_);
69
70    label_2_ = CreateLabel(message_text.substr(offset));
71    AddChildView(label_2_);
72  }
73
74  // This must happen after adding all other children so InfoBarView can ensure
75  // the close button is the last child.
76  InfoBarView::ViewHierarchyChanged(details);
77}
78
79void AlternateNavInfoBarView::LinkClicked(views::Link* source,
80                                          int event_flags) {
81  if (!owner())
82    return;  // We're closing; don't call anything, it might access the owner.
83  DCHECK(link_ != NULL);
84  DCHECK_EQ(link_, source);
85  if (GetDelegate()->LinkClicked(ui::DispositionFromEventFlags(event_flags)))
86    RemoveSelf();
87}
88
89AlternateNavInfoBarDelegate* AlternateNavInfoBarView::GetDelegate() {
90  return static_cast<AlternateNavInfoBarDelegate*>(delegate());
91}
92