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