blob: bff44c1dd7523f9f0b95f4cdb38b4b4d1d5ac102 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/views/infobars/alternate_nav_infobar_view.h"
#include "base/logging.h"
#include "chrome/browser/ui/omnibox/alternate_nav_infobar_delegate.h"
#include "ui/base/window_open_disposition.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/link.h"
// AlternateNavInfoBarDelegate -------------------------------------------------
// static
scoped_ptr<InfoBar> AlternateNavInfoBarDelegate::CreateInfoBar(
scoped_ptr<AlternateNavInfoBarDelegate> delegate) {
return scoped_ptr<InfoBar>(new AlternateNavInfoBarView(delegate.Pass()));
}
// AlternateNavInfoBarView -----------------------------------------------------
AlternateNavInfoBarView::AlternateNavInfoBarView(
scoped_ptr<AlternateNavInfoBarDelegate> delegate)
: InfoBarView(delegate.PassAs<InfoBarDelegate>()),
label_1_(NULL),
link_(NULL),
label_2_(NULL) {
}
AlternateNavInfoBarView::~AlternateNavInfoBarView() {
}
void AlternateNavInfoBarView::Layout() {
InfoBarView::Layout();
// TODO(pkasting): This isn't perfect; there are points when we should elide a
// view because its subsequent view will be too small to show an ellipsis.
gfx::Size label_1_size = label_1_->GetPreferredSize();
int available_width = EndX() - StartX();
label_1_->SetBounds(StartX(), OffsetY(label_1_size),
std::min(label_1_size.width(), available_width), label_1_size.height());
available_width = std::max(0, available_width - label_1_size.width());
gfx::Size link_size = link_->GetPreferredSize();
link_->SetBounds(label_1_->bounds().right(), OffsetY(link_size),
std::min(link_size.width(), available_width), link_size.height());
available_width = std::max(0, available_width - link_size.width());
gfx::Size label_2_size = label_2_->GetPreferredSize();
label_2_->SetBounds(link_->bounds().right(), OffsetY(label_2_size),
std::min(label_2_size.width(), available_width), label_2_size.height());
}
void AlternateNavInfoBarView::ViewHierarchyChanged(
const ViewHierarchyChangedDetails& details) {
if (details.is_add && (details.child == this) && (label_1_ == NULL)) {
AlternateNavInfoBarDelegate* delegate = GetDelegate();
size_t offset;
base::string16 message_text = delegate->GetMessageTextWithOffset(&offset);
DCHECK_NE(base::string16::npos, offset);
label_1_ = CreateLabel(message_text.substr(0, offset));
AddChildView(label_1_);
link_ = CreateLink(delegate->GetLinkText(), this);
AddChildView(link_);
label_2_ = CreateLabel(message_text.substr(offset));
AddChildView(label_2_);
}
// This must happen after adding all other children so InfoBarView can ensure
// the close button is the last child.
InfoBarView::ViewHierarchyChanged(details);
}
void AlternateNavInfoBarView::LinkClicked(views::Link* source,
int event_flags) {
if (!owner())
return; // We're closing; don't call anything, it might access the owner.
DCHECK(link_ != NULL);
DCHECK_EQ(link_, source);
if (GetDelegate()->LinkClicked(ui::DispositionFromEventFlags(event_flags)))
RemoveSelf();
}
AlternateNavInfoBarDelegate* AlternateNavInfoBarView::GetDelegate() {
return static_cast<AlternateNavInfoBarDelegate*>(delegate());
}