- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / infobars / alternate_nav_infobar_view.cc
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 InfoBar* AlternateNavInfoBarDelegate::CreateInfoBar(InfoBarService* owner) {
17   return new AlternateNavInfoBarView(owner, this);
18 }
19
20
21 // AlternateNavInfoBarView -----------------------------------------------------
22
23 AlternateNavInfoBarView::AlternateNavInfoBarView(
24     InfoBarService* owner,
25     AlternateNavInfoBarDelegate* delegate)
26     : InfoBarView(owner, delegate),
27       label_1_(NULL),
28       link_(NULL),
29       label_2_(NULL) {
30 }
31
32 AlternateNavInfoBarView::~AlternateNavInfoBarView() {
33 }
34
35 void 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
56 void 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
78 void 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
88 AlternateNavInfoBarDelegate* AlternateNavInfoBarView::GetDelegate() {
89   return static_cast<AlternateNavInfoBarDelegate*>(delegate());
90 }