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