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