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