Home | History | Annotate | Download | only in infobars
      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/confirm_infobar.h"
      6 
      7 #include "base/logging.h"
      8 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
      9 #include "ui/base/window_open_disposition.h"
     10 #include "ui/views/controls/button/label_button.h"
     11 #include "ui/views/controls/label.h"
     12 #include "ui/views/controls/link.h"
     13 
     14 
     15 // ConfirmInfoBarDelegate -----------------------------------------------------
     16 
     17 // static
     18 scoped_ptr<InfoBar> ConfirmInfoBarDelegate::CreateInfoBar(
     19     scoped_ptr<ConfirmInfoBarDelegate> delegate) {
     20   return scoped_ptr<InfoBar>(new ConfirmInfoBar(delegate.Pass()));
     21 }
     22 
     23 
     24 // ConfirmInfoBar -------------------------------------------------------------
     25 
     26 ConfirmInfoBar::ConfirmInfoBar(scoped_ptr<ConfirmInfoBarDelegate> delegate)
     27     : InfoBarView(delegate.PassAs<InfoBarDelegate>()),
     28       label_(NULL),
     29       ok_button_(NULL),
     30       cancel_button_(NULL),
     31       link_(NULL) {
     32 }
     33 
     34 ConfirmInfoBar::~ConfirmInfoBar() {
     35 }
     36 
     37 void ConfirmInfoBar::Layout() {
     38   InfoBarView::Layout();
     39 
     40   int available_width = std::max(0, EndX() - StartX() - ContentMinimumWidth());
     41   gfx::Size label_size = label_->GetPreferredSize();
     42   label_->SetBounds(StartX(), OffsetY(label_size),
     43       std::min(label_size.width(), available_width), label_size.height());
     44   available_width = std::max(0, available_width - label_size.width());
     45 
     46   int button_x = label_->bounds().right() + kEndOfLabelSpacing;
     47   if (ok_button_ != NULL) {
     48     gfx::Size ok_size = ok_button_->GetPreferredSize();
     49     ok_button_->SetBounds(button_x, OffsetY(ok_size), ok_size.width(),
     50                           ok_size.height());
     51     button_x += ok_size.width() + kButtonButtonSpacing;
     52   }
     53 
     54   if (cancel_button_ != NULL) {
     55     gfx::Size cancel_size = cancel_button_->GetPreferredSize();
     56     cancel_button_->SetBounds(button_x, OffsetY(cancel_size),
     57                               cancel_size.width(), cancel_size.height());
     58   }
     59 
     60   if (link_ != NULL) {
     61     gfx::Size link_size = link_->GetPreferredSize();
     62     int link_width = std::min(link_size.width(), available_width);
     63     link_->SetBounds(EndX() - link_width, OffsetY(link_size), link_width,
     64                      link_size.height());
     65   }
     66 }
     67 
     68 void ConfirmInfoBar::ViewHierarchyChanged(
     69     const ViewHierarchyChangedDetails& details) {
     70   if (details.is_add && details.child == this && (label_ == NULL)) {
     71     ConfirmInfoBarDelegate* delegate = GetDelegate();
     72     label_ = CreateLabel(delegate->GetMessageText());
     73     AddChildView(label_);
     74 
     75     if (delegate->GetButtons() & ConfirmInfoBarDelegate::BUTTON_OK) {
     76       ok_button_ = CreateLabelButton(this,
     77           delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK),
     78           delegate->NeedElevation(ConfirmInfoBarDelegate::BUTTON_OK));
     79       AddChildView(ok_button_);
     80     }
     81 
     82     if (delegate->GetButtons() & ConfirmInfoBarDelegate::BUTTON_CANCEL) {
     83       cancel_button_ = CreateLabelButton(this,
     84           delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_CANCEL),
     85           delegate->NeedElevation(ConfirmInfoBarDelegate::BUTTON_CANCEL));
     86       AddChildView(cancel_button_);
     87     }
     88 
     89     base::string16 link_text(delegate->GetLinkText());
     90     if (!link_text.empty()) {
     91       link_ = CreateLink(link_text, this);
     92       AddChildView(link_);
     93     }
     94   }
     95 
     96   // This must happen after adding all other children so InfoBarView can ensure
     97   // the close button is the last child.
     98   InfoBarView::ViewHierarchyChanged(details);
     99 }
    100 
    101 void ConfirmInfoBar::ButtonPressed(views::Button* sender,
    102                                    const ui::Event& event) {
    103   if (!owner())
    104     return;  // We're closing; don't call anything, it might access the owner.
    105   ConfirmInfoBarDelegate* delegate = GetDelegate();
    106   if ((ok_button_ != NULL) && sender == ok_button_) {
    107     if (delegate->Accept())
    108       RemoveSelf();
    109   } else if ((cancel_button_ != NULL) && (sender == cancel_button_)) {
    110     if (delegate->Cancel())
    111       RemoveSelf();
    112   } else {
    113     InfoBarView::ButtonPressed(sender, event);
    114   }
    115 }
    116 
    117 int ConfirmInfoBar::ContentMinimumWidth() const {
    118   int width = (link_ == NULL) ? 0 : kEndOfLabelSpacing;  // Space before link
    119   int before_cancel_spacing = kEndOfLabelSpacing;
    120   if (ok_button_ != NULL) {
    121     width += kEndOfLabelSpacing + ok_button_->GetPreferredSize().width();
    122     before_cancel_spacing = kButtonButtonSpacing;
    123   }
    124   return width + ((cancel_button_ == NULL) ? 0 :
    125       (before_cancel_spacing + cancel_button_->GetPreferredSize().width()));
    126 }
    127 
    128 void ConfirmInfoBar::LinkClicked(views::Link* source, int event_flags) {
    129   if (!owner())
    130     return;  // We're closing; don't call anything, it might access the owner.
    131   DCHECK(link_ != NULL);
    132   DCHECK_EQ(link_, source);
    133   if (GetDelegate()->LinkClicked(ui::DispositionFromEventFlags(event_flags)))
    134     RemoveSelf();
    135 }
    136 
    137 ConfirmInfoBarDelegate* ConfirmInfoBar::GetDelegate() {
    138   return delegate()->AsConfirmInfoBarDelegate();
    139 }
    140