message_bubble.cc revision 72a454cd3513ac24fbdd0e0cb9ad70b86a99b801
1// Copyright (c) 2010 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
18namespace chromeos {
19
20static const int kBorderSize = 4;
21static const int kMaxLabelWidth = 250;
22
23MessageBubble::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    : InfoBubble(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
88void 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
97void 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
107MessageBubble* 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->Init(parent, position_relative_to, arrow_location,
118               bubble->text_->parent(), delegate);
119  return bubble;
120}
121
122// static
123MessageBubble* 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->Init(parent, position_relative_to, arrow_location,
135               bubble->text_->parent(), delegate);
136  return bubble;
137}
138
139void 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
148void MessageBubble::DoGrab() {
149  if (grab_enabled_)
150    WidgetGtk::DoGrab();
151}
152
153void MessageBubble::Close() {
154  parent_ = NULL;
155  InfoBubble::Close();
156}
157
158}  // namespace chromeos
159