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