OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/login/message_bubble.h" | 5 #include "chrome/browser/chromeos/login/message_bubble.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/utf_string_conversions.h" | |
11 #include "chrome/browser/chromeos/login/helper.h" | 10 #include "chrome/browser/chromeos/login/helper.h" |
12 #include "grit/generated_resources.h" | 11 #include "grit/generated_resources.h" |
13 #include "grit/theme_resources_standard.h" | 12 #include "grit/theme_resources_standard.h" |
14 #include "ui/base/resource/resource_bundle.h" | 13 #include "ui/base/resource/resource_bundle.h" |
15 #include "ui/views/controls/button/image_button.h" | 14 #include "ui/views/controls/button/image_button.h" |
16 #include "ui/views/controls/image_view.h" | 15 #include "ui/views/controls/image_view.h" |
17 #include "ui/views/controls/label.h" | 16 #include "ui/views/controls/label.h" |
18 #include "ui/views/controls/link.h" | 17 #include "ui/views/controls/link.h" |
19 #include "ui/views/layout/grid_layout.h" | 18 #include "ui/views/layout/grid_layout.h" |
20 #include "ui/views/widget/widget.h" | 19 #include "ui/views/widget/widget.h" |
21 | 20 |
| 21 namespace { |
| 22 |
| 23 const int kBorderSize = 4; |
| 24 const int kMaxLabelWidth = 250; |
| 25 |
| 26 } // namespace |
| 27 |
22 namespace chromeos { | 28 namespace chromeos { |
23 | 29 |
24 static const int kBorderSize = 4; | 30 MessageBubble::MessageBubble(views::View* anchor_view, |
25 static const int kMaxLabelWidth = 250; | 31 views::BubbleBorder::ArrowLocation arrow_location, |
| 32 SkBitmap* image, |
| 33 const string16& text, |
| 34 const std::vector<string16>& links) |
| 35 : BubbleDelegateView(anchor_view, arrow_location, kBackgroundColor), |
| 36 image_(image), |
| 37 text_(text), |
| 38 close_button_(NULL), |
| 39 link_listener_(NULL) { |
| 40 set_use_focusless(true); |
| 41 for (size_t i = 0; i < links.size(); ++i) |
| 42 help_links_.push_back(new views::Link(links[i])); |
| 43 } |
26 | 44 |
27 MessageBubble::MessageBubble(views::Widget::InitParams::Type type, | 45 MessageBubble::~MessageBubble() { |
28 views::Widget* parent, | 46 } |
29 SkBitmap* image, | 47 |
30 const std::wstring& text, | 48 void MessageBubble::Init() { |
31 const std::vector<std::wstring>& links, | |
32 bool grab_enabled, | |
33 MessageBubbleDelegate* delegate) | |
34 : Bubble(type, false), // don't show while screen is locked | |
35 parent_(parent), | |
36 message_delegate_(delegate), | |
37 grab_enabled_(grab_enabled) { | |
38 using views::GridLayout; | 49 using views::GridLayout; |
39 | 50 |
40 views::View* control_view = new views::View(); | 51 views::View* control_view = new views::View(); |
41 GridLayout* layout = new GridLayout(control_view); | 52 GridLayout* layout = new GridLayout(control_view); |
42 control_view->SetLayoutManager(layout); | 53 control_view->SetLayoutManager(layout); |
43 views::ColumnSet* column_set = layout->AddColumnSet(0); | 54 views::ColumnSet* column_set = layout->AddColumnSet(0); |
44 column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 0, | 55 column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 0, |
45 GridLayout::USE_PREF, 0, 0); | 56 GridLayout::USE_PREF, 0, 0); |
46 column_set->AddPaddingColumn(0, kBorderSize); | 57 column_set->AddPaddingColumn(0, kBorderSize); |
47 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, | 58 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, |
48 GridLayout::USE_PREF, 0, 0); | 59 GridLayout::USE_PREF, 0, 0); |
49 column_set->AddPaddingColumn(0, kBorderSize); | 60 column_set->AddPaddingColumn(0, kBorderSize); |
50 column_set->AddColumn(GridLayout::TRAILING, GridLayout::LEADING, 0, | 61 column_set->AddColumn(GridLayout::TRAILING, GridLayout::LEADING, 0, |
51 GridLayout::USE_PREF, 0, 0); | 62 GridLayout::USE_PREF, 0, 0); |
52 if (!links.empty()) { | 63 if (!help_links_.empty()) { |
53 column_set = layout->AddColumnSet(1); | 64 column_set = layout->AddColumnSet(1); |
54 column_set->AddPaddingColumn(0, kBorderSize + image->width()); | 65 column_set->AddPaddingColumn(0, kBorderSize + image_->width()); |
55 column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 1, | 66 column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 1, |
56 GridLayout::USE_PREF, 0, 0); | 67 GridLayout::USE_PREF, 0, 0); |
57 } | 68 } |
58 | 69 |
59 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 70 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
60 | 71 |
61 layout->StartRow(0, 0); | 72 layout->StartRow(0, 0); |
62 icon_ = new views::ImageView(); | 73 views::ImageView* icon = new views::ImageView(); |
63 icon_->SetImage(*image); | 74 icon->SetImage(*image_); |
64 layout->AddView(icon_); | 75 layout->AddView(icon); |
65 | 76 |
66 text_ = new views::Label(WideToUTF16Hack(text)); | 77 views::Label* label = new views::Label(text_); |
67 text_->SetMultiLine(true); | 78 label->SetMultiLine(true); |
68 text_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | 79 label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
69 text_->SetBackgroundColor(Bubble::kBackgroundColor); | 80 label->SizeToFit(kMaxLabelWidth); |
70 text_->SizeToFit(kMaxLabelWidth); | 81 layout->AddView(label); |
71 layout->AddView(text_); | |
72 | 82 |
73 close_button_ = new views::ImageButton(this); | 83 close_button_ = new views::ImageButton(this); |
74 close_button_->SetImage(views::CustomButton::BS_NORMAL, | 84 close_button_->SetImage(views::CustomButton::BS_NORMAL, |
75 rb.GetBitmapNamed(IDR_CLOSE_BAR)); | 85 rb.GetBitmapNamed(IDR_CLOSE_BAR)); |
76 close_button_->SetImage(views::CustomButton::BS_HOT, | 86 close_button_->SetImage(views::CustomButton::BS_HOT, |
77 rb.GetBitmapNamed(IDR_CLOSE_BAR_H)); | 87 rb.GetBitmapNamed(IDR_CLOSE_BAR_H)); |
78 close_button_->SetImage(views::CustomButton::BS_PUSHED, | 88 close_button_->SetImage(views::CustomButton::BS_PUSHED, |
79 rb.GetBitmapNamed(IDR_CLOSE_BAR_P)); | 89 rb.GetBitmapNamed(IDR_CLOSE_BAR_P)); |
80 layout->AddView(close_button_); | 90 layout->AddView(close_button_); |
81 | 91 |
82 for (size_t i = 0; i < links.size(); ++i) { | 92 for (size_t i = 0; i < help_links_.size(); ++i) { |
83 layout->StartRowWithPadding(0, 1, 0, kBorderSize); | 93 layout->StartRowWithPadding(0, 1, 0, kBorderSize); |
84 views::Link* help_link_ = new views::Link(WideToUTF16Hack(links[i])); | 94 views::Link* help_link = help_links_[i]; |
85 help_links_.push_back(help_link_); | 95 help_link->set_listener(this); |
86 help_link_->set_listener(this); | 96 help_link->SetEnabledColor(login::kLinkColor); |
87 help_link_->SetBackgroundColor(Bubble::kBackgroundColor); | 97 help_link->SetPressedColor(login::kLinkColor); |
88 help_link_->SetEnabledColor(login::kLinkColor); | 98 layout->AddView(help_link); |
89 help_link_->SetPressedColor(login::kLinkColor); | |
90 layout->AddView(help_link_); | |
91 } | 99 } |
92 } | 100 } |
93 | 101 |
94 MessageBubble::~MessageBubble() { | |
95 } | |
96 | |
97 void MessageBubble::ButtonPressed(views::Button* sender, | 102 void MessageBubble::ButtonPressed(views::Button* sender, |
98 const views::Event& event) { | 103 const views::Event& event) { |
99 if (sender == close_button_) { | 104 if (sender == close_button_) { |
100 Close(); | 105 GetWidget()->Close(); |
101 } else { | 106 } else { |
102 NOTREACHED() << "Unknown view"; | 107 NOTREACHED() << "Unknown view"; |
103 } | 108 } |
104 } | 109 } |
105 | 110 |
106 void MessageBubble::LinkClicked(views::Link* source, int event_flags) { | 111 void MessageBubble::LinkClicked(views::Link* source, int event_flags) { |
107 if (!message_delegate_) | 112 if (!link_listener_) |
108 return; | 113 return; |
109 for (size_t i = 0; i < help_links_.size(); ++i) { | 114 for (size_t i = 0; i < help_links_.size(); ++i) { |
110 if (source == help_links_[i]) { | 115 if (source == help_links_[i]) { |
111 message_delegate_->OnLinkActivated(i); | 116 link_listener_->OnLinkActivated(i); |
112 return; | 117 return; |
113 } | 118 } |
114 } | 119 } |
115 NOTREACHED() << "Unknown view"; | 120 NOTREACHED() << "Unknown view"; |
116 } | 121 } |
117 | 122 |
118 // static | |
119 MessageBubble* MessageBubble::Show( | |
120 views::Widget* parent, | |
121 const gfx::Rect& position_relative_to, | |
122 views::BubbleBorder::ArrowLocation arrow_location, | |
123 SkBitmap* image, | |
124 const std::wstring& text, | |
125 const std::wstring& help, | |
126 MessageBubbleDelegate* delegate) { | |
127 std::vector<std::wstring> links; | |
128 if (!help.empty()) | |
129 links.push_back(help); | |
130 return MessageBubble::ShowWithLinks(parent, | |
131 position_relative_to, | |
132 arrow_location, | |
133 image, | |
134 text, | |
135 links, | |
136 delegate); | |
137 } | |
138 | |
139 // static | |
140 MessageBubble* MessageBubble::ShowWithLinks( | |
141 views::Widget* parent, | |
142 const gfx::Rect& position_relative_to, | |
143 views::BubbleBorder::ArrowLocation arrow_location, | |
144 SkBitmap* image, | |
145 const std::wstring& text, | |
146 const std::vector<std::wstring>& links, | |
147 MessageBubbleDelegate* delegate) { | |
148 // The bubble will be destroyed when it is closed. | |
149 MessageBubble* bubble = new MessageBubble( | |
150 views::Widget::InitParams::TYPE_POPUP, parent, image, text, links, | |
151 true, delegate); | |
152 bubble->InitBubble(parent, position_relative_to, arrow_location, | |
153 views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR, | |
154 bubble->text_->parent(), delegate); | |
155 return bubble; | |
156 } | |
157 | |
158 // static | |
159 MessageBubble* MessageBubble::ShowNoGrab( | |
160 views::Widget* parent, | |
161 const gfx::Rect& position_relative_to, | |
162 views::BubbleBorder::ArrowLocation arrow_location, | |
163 SkBitmap* image, | |
164 const std::wstring& text, | |
165 const std::wstring& help, | |
166 MessageBubbleDelegate* delegate) { | |
167 std::vector<std::wstring> links; | |
168 if (!help.empty()) | |
169 links.push_back(help); | |
170 // The bubble will be destroyed when it is closed. | |
171 MessageBubble* bubble = new MessageBubble( | |
172 views::Widget::InitParams::TYPE_CONTROL, parent, image, text, links, | |
173 false, delegate); | |
174 bubble->InitBubble(parent, position_relative_to, arrow_location, | |
175 views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR, | |
176 bubble->text_->parent(), delegate); | |
177 return bubble; | |
178 } | |
179 | |
180 #if defined(TOOLKIT_USES_GTK) | |
181 // TODO(saintlou): Unclear if we need this for the !gtk case. | |
182 void MessageBubble::OnActiveChanged() { | |
183 if (parent_ && IsActive()) { | |
184 // Show the parent. | |
185 gtk_window_present_with_time(parent_->GetNativeWindow(), | |
186 gtk_get_current_event_time()); | |
187 } | |
188 } | |
189 | |
190 void MessageBubble::SetMouseCapture() { | |
191 if (grab_enabled_) | |
192 NativeWidgetGtk::SetMouseCapture(); | |
193 } | |
194 #endif | |
195 | |
196 void MessageBubble::Close() { | |
197 parent_ = NULL; | |
198 Bubble::Close(); | |
199 } | |
200 | |
201 #if defined(TOOLKIT_USES_GTK) | |
202 gboolean MessageBubble::OnButtonPress(GtkWidget* widget, | |
203 GdkEventButton* event) { | |
204 NativeWidgetGtk::OnButtonPress(widget, event); | |
205 // Never propagate event to parent. | |
206 return true; | |
207 } | |
208 #endif | |
209 | |
210 } // namespace chromeos | 123 } // namespace chromeos |
OLD | NEW |