Home | History | Annotate | Download | only in login
      1 // Copyright (c) 2011 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/chromeos/login/message_bubble.h"
      6 
      7 #include "base/logging.h"
      8 #include "chrome/browser/chromeos/login/helper.h"
      9 #include "grit/generated_resources.h"
     10 #include "grit/theme_resources.h"
     11 #include "ui/base/resource/resource_bundle.h"
     12 #include "views/controls/button/image_button.h"
     13 #include "views/controls/image_view.h"
     14 #include "views/controls/label.h"
     15 #include "views/layout/grid_layout.h"
     16 #include "views/widget/widget.h"
     17 
     18 namespace chromeos {
     19 
     20 static const int kBorderSize = 4;
     21 static const int kMaxLabelWidth = 250;
     22 
     23 MessageBubble::MessageBubble(views::WidgetGtk::Type type,
     24                              views::Widget* parent,
     25                              SkBitmap* image,
     26                              const std::wstring& text,
     27                              const std::wstring& help,
     28                              bool grab_enabled,
     29                              MessageBubbleDelegate* delegate)
     30     : Bubble(type, false),  // don't show while screen is locked
     31       parent_(parent),
     32       help_link_(NULL),
     33       message_delegate_(delegate),
     34       grab_enabled_(grab_enabled) {
     35   using views::GridLayout;
     36 
     37   views::View* control_view = new views::View();
     38   GridLayout* layout = new GridLayout(control_view);
     39   control_view->SetLayoutManager(layout);
     40   views::ColumnSet* column_set = layout->AddColumnSet(0);
     41   column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 0,
     42                         GridLayout::USE_PREF, 0, 0);
     43   column_set->AddPaddingColumn(0, kBorderSize);
     44   column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
     45                         GridLayout::USE_PREF, 0, 0);
     46   column_set->AddPaddingColumn(0, kBorderSize);
     47   column_set->AddColumn(GridLayout::TRAILING, GridLayout::LEADING, 0,
     48                         GridLayout::USE_PREF, 0, 0);
     49   if (!help.empty()) {
     50     column_set = layout->AddColumnSet(1);
     51     column_set->AddPaddingColumn(0, kBorderSize + image->width());
     52     column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 1,
     53                           GridLayout::USE_PREF, 0, 0);
     54   }
     55 
     56   ResourceBundle& rb = ResourceBundle::GetSharedInstance();
     57 
     58   layout->StartRow(0, 0);
     59   icon_ = new views::ImageView();
     60   icon_->SetImage(*image);
     61   layout->AddView(icon_);
     62 
     63   text_ = new views::Label(text);
     64   text_->SetMultiLine(true);
     65   text_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
     66   text_->SizeToFit(kMaxLabelWidth);
     67   layout->AddView(text_);
     68 
     69   close_button_ = new views::ImageButton(this);
     70   close_button_->SetImage(views::CustomButton::BS_NORMAL,
     71       rb.GetBitmapNamed(IDR_CLOSE_BAR));
     72   close_button_->SetImage(views::CustomButton::BS_HOT,
     73       rb.GetBitmapNamed(IDR_CLOSE_BAR_H));
     74   close_button_->SetImage(views::CustomButton::BS_PUSHED,
     75       rb.GetBitmapNamed(IDR_CLOSE_BAR_P));
     76   layout->AddView(close_button_);
     77 
     78   if (!help.empty()) {
     79     layout->StartRowWithPadding(0, 1, 0, kBorderSize);
     80     help_link_ = new views::Link(help);
     81     help_link_->SetController(this);
     82     help_link_->SetNormalColor(login::kLinkColor);
     83     help_link_->SetHighlightedColor(login::kLinkColor);
     84     layout->AddView(help_link_);
     85   }
     86 }
     87 
     88 void MessageBubble::ButtonPressed(views::Button* sender,
     89                                   const views::Event& event) {
     90   if (sender == close_button_) {
     91     Close();
     92   } else {
     93     NOTREACHED() << "Unknown view";
     94   }
     95 }
     96 
     97 void MessageBubble::LinkActivated(views::Link* source, int event_flags) {
     98   if (source == help_link_) {
     99     if (message_delegate_)
    100       message_delegate_->OnHelpLinkActivated();
    101   } else {
    102     NOTREACHED() << "Unknown view";
    103   }
    104 }
    105 
    106 // static
    107 MessageBubble* MessageBubble::Show(views::Widget* parent,
    108                                    const gfx::Rect& position_relative_to,
    109                                    BubbleBorder::ArrowLocation arrow_location,
    110                                    SkBitmap* image,
    111                                    const std::wstring& text,
    112                                    const std::wstring& help,
    113                                    MessageBubbleDelegate* delegate) {
    114   // The bubble will be destroyed when it is closed.
    115   MessageBubble* bubble = new MessageBubble(
    116       views::WidgetGtk::TYPE_WINDOW, parent, image, text, help, true, delegate);
    117   bubble->InitBubble(parent, position_relative_to, arrow_location,
    118                      bubble->text_->parent(), delegate);
    119   return bubble;
    120 }
    121 
    122 // static
    123 MessageBubble* MessageBubble::ShowNoGrab(
    124     views::Widget* parent,
    125     const gfx::Rect& position_relative_to,
    126     BubbleBorder::ArrowLocation arrow_location,
    127     SkBitmap* image,
    128     const std::wstring& text,
    129     const std::wstring& help,
    130     MessageBubbleDelegate* delegate) {
    131   // The bubble will be destroyed when it is closed.
    132   MessageBubble* bubble = new MessageBubble(
    133       views::WidgetGtk::TYPE_CHILD, parent, image, text, help, false, delegate);
    134   bubble->InitBubble(parent, position_relative_to, arrow_location,
    135                      bubble->text_->parent(), delegate);
    136   return bubble;
    137 }
    138 
    139 void MessageBubble::IsActiveChanged() {
    140   // Active parent instead.
    141   if (parent_ && IsActive()) {
    142     gtk_window_present_with_time(
    143         GTK_WINDOW(static_cast<WidgetGtk*>(parent_)->GetNativeView()),
    144                    gtk_get_current_event_time());
    145   }
    146 }
    147 
    148 void MessageBubble::SetMouseCapture() {
    149   if (grab_enabled_)
    150     WidgetGtk::SetMouseCapture();
    151 }
    152 
    153 void MessageBubble::Close() {
    154   parent_ = NULL;
    155   Bubble::Close();
    156 }
    157 
    158 }  // namespace chromeos
    159