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/layout/grid_layout.h" | 14 #include "ui/views/layout/grid_layout.h" |
16 #include "views/controls/button/image_button.h" | 15 #include "views/controls/button/image_button.h" |
17 #include "views/controls/image_view.h" | 16 #include "views/controls/image_view.h" |
18 #include "views/controls/label.h" | 17 #include "views/controls/label.h" |
19 #include "views/controls/link.h" | 18 #include "views/controls/link.h" |
20 #include "views/widget/widget.h" | 19 #include "views/widget/widget.h" |
21 | 20 |
21 namespace { | |
22 | |
23 // TODO(msw): Get color from theme/window color. | |
24 const SkColor kColor = SK_ColorWHITE; | |
25 | |
26 const int kBorderSize = 4; | |
27 const int kMaxLabelWidth = 250; | |
28 | |
29 } // namespace | |
30 | |
22 namespace chromeos { | 31 namespace chromeos { |
23 | 32 |
24 static const int kBorderSize = 4; | 33 MessageBubble::MessageBubble(views::View* anchor_view, |
25 static const int kMaxLabelWidth = 250; | 34 views::BubbleBorder::ArrowLocation arrow_location, |
35 SkBitmap* image, | |
36 const string16& text, | |
37 const string16& link) | |
38 : BubbleDelegateView(anchor_view, arrow_location, kColor), | |
39 image_(image), | |
40 text_(text), | |
41 close_button_(NULL), | |
42 link_listener_(NULL) { | |
43 help_links_.push_back(new views::Link(link)); | |
44 } | |
26 | 45 |
27 MessageBubble::MessageBubble(views::Widget::InitParams::Type type, | 46 MessageBubble::MessageBubble(views::View* anchor_view, |
28 views::Widget* parent, | 47 views::BubbleBorder::ArrowLocation arrow_location, |
29 SkBitmap* image, | 48 SkBitmap* image, |
30 const std::wstring& text, | 49 const string16& text, |
31 const std::vector<std::wstring>& links, | 50 const std::vector<string16>& links) |
32 bool grab_enabled, | 51 : BubbleDelegateView(anchor_view, arrow_location, kColor), |
33 MessageBubbleDelegate* delegate) | 52 image_(image), |
34 : Bubble(type, false), // don't show while screen is locked | 53 text_(text), |
35 parent_(parent), | 54 close_button_(NULL), |
36 message_delegate_(delegate), | 55 link_listener_(NULL) { |
37 grab_enabled_(grab_enabled) { | 56 for (size_t i = 0; i < links.size(); ++i) |
57 help_links_.push_back(new views::Link(links[i])); | |
58 } | |
59 | |
60 // static | |
61 void MessageBubble::ShowBubble(MessageBubble* bubble) { | |
62 // TODO(msw): views::Widget::InitParams::TYPE_POPUP??? | |
63 views::BubbleDelegateView::CreateBubble(bubble); | |
alicet1
2011/11/20 01:46:22
I think this bubble wants to be "focusless", check
msw
2011/11/21 20:34:43
Done.
I also added some temp code for chromeos::W
| |
64 bubble->Show(); | |
65 } | |
66 | |
67 MessageBubble::~MessageBubble() { | |
68 } | |
69 | |
70 void MessageBubble::Init() { | |
38 using views::GridLayout; | 71 using views::GridLayout; |
39 | 72 |
40 views::View* control_view = new views::View(); | 73 views::View* control_view = new views::View(); |
41 GridLayout* layout = new GridLayout(control_view); | 74 GridLayout* layout = new GridLayout(control_view); |
42 control_view->SetLayoutManager(layout); | 75 control_view->SetLayoutManager(layout); |
43 views::ColumnSet* column_set = layout->AddColumnSet(0); | 76 views::ColumnSet* column_set = layout->AddColumnSet(0); |
44 column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 0, | 77 column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 0, |
45 GridLayout::USE_PREF, 0, 0); | 78 GridLayout::USE_PREF, 0, 0); |
46 column_set->AddPaddingColumn(0, kBorderSize); | 79 column_set->AddPaddingColumn(0, kBorderSize); |
47 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, | 80 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, |
48 GridLayout::USE_PREF, 0, 0); | 81 GridLayout::USE_PREF, 0, 0); |
49 column_set->AddPaddingColumn(0, kBorderSize); | 82 column_set->AddPaddingColumn(0, kBorderSize); |
50 column_set->AddColumn(GridLayout::TRAILING, GridLayout::LEADING, 0, | 83 column_set->AddColumn(GridLayout::TRAILING, GridLayout::LEADING, 0, |
51 GridLayout::USE_PREF, 0, 0); | 84 GridLayout::USE_PREF, 0, 0); |
52 if (!links.empty()) { | 85 if (!help_links_.empty()) { |
53 column_set = layout->AddColumnSet(1); | 86 column_set = layout->AddColumnSet(1); |
54 column_set->AddPaddingColumn(0, kBorderSize + image->width()); | 87 column_set->AddPaddingColumn(0, kBorderSize + image_->width()); |
55 column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 1, | 88 column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 1, |
56 GridLayout::USE_PREF, 0, 0); | 89 GridLayout::USE_PREF, 0, 0); |
57 } | 90 } |
58 | 91 |
59 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 92 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
60 | 93 |
61 layout->StartRow(0, 0); | 94 layout->StartRow(0, 0); |
62 icon_ = new views::ImageView(); | 95 views::ImageView* icon = new views::ImageView(); |
63 icon_->SetImage(*image); | 96 icon->SetImage(*image_); |
64 layout->AddView(icon_); | 97 layout->AddView(icon); |
65 | 98 |
66 text_ = new views::Label(WideToUTF16Hack(text)); | 99 views::Label* label = new views::Label(text_); |
67 text_->SetMultiLine(true); | 100 label->SetMultiLine(true); |
68 text_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | 101 label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
69 text_->SetBackgroundColor(Bubble::kBackgroundColor); | 102 label->SizeToFit(kMaxLabelWidth); |
70 text_->SizeToFit(kMaxLabelWidth); | 103 layout->AddView(label); |
71 layout->AddView(text_); | |
72 | 104 |
73 close_button_ = new views::ImageButton(this); | 105 close_button_ = new views::ImageButton(this); |
74 close_button_->SetImage(views::CustomButton::BS_NORMAL, | 106 close_button_->SetImage(views::CustomButton::BS_NORMAL, |
75 rb.GetBitmapNamed(IDR_CLOSE_BAR)); | 107 rb.GetBitmapNamed(IDR_CLOSE_BAR)); |
76 close_button_->SetImage(views::CustomButton::BS_HOT, | 108 close_button_->SetImage(views::CustomButton::BS_HOT, |
77 rb.GetBitmapNamed(IDR_CLOSE_BAR_H)); | 109 rb.GetBitmapNamed(IDR_CLOSE_BAR_H)); |
78 close_button_->SetImage(views::CustomButton::BS_PUSHED, | 110 close_button_->SetImage(views::CustomButton::BS_PUSHED, |
79 rb.GetBitmapNamed(IDR_CLOSE_BAR_P)); | 111 rb.GetBitmapNamed(IDR_CLOSE_BAR_P)); |
80 layout->AddView(close_button_); | 112 layout->AddView(close_button_); |
81 | 113 |
82 for (size_t i = 0; i < links.size(); ++i) { | 114 for (size_t i = 0; i < help_links_.size(); ++i) { |
83 layout->StartRowWithPadding(0, 1, 0, kBorderSize); | 115 layout->StartRowWithPadding(0, 1, 0, kBorderSize); |
84 views::Link* help_link_ = new views::Link(WideToUTF16Hack(links[i])); | 116 views::Link* help_link = help_links_[i]; |
85 help_links_.push_back(help_link_); | 117 help_link->set_listener(this); |
86 help_link_->set_listener(this); | 118 help_link->SetEnabledColor(login::kLinkColor); |
87 help_link_->SetBackgroundColor(Bubble::kBackgroundColor); | 119 help_link->SetPressedColor(login::kLinkColor); |
88 help_link_->SetEnabledColor(login::kLinkColor); | 120 layout->AddView(help_link); |
89 help_link_->SetPressedColor(login::kLinkColor); | |
90 layout->AddView(help_link_); | |
91 } | 121 } |
92 } | 122 } |
93 | 123 |
94 MessageBubble::~MessageBubble() { | |
95 } | |
96 | |
97 void MessageBubble::ButtonPressed(views::Button* sender, | 124 void MessageBubble::ButtonPressed(views::Button* sender, |
98 const views::Event& event) { | 125 const views::Event& event) { |
99 if (sender == close_button_) { | 126 if (sender == close_button_) { |
100 Close(); | 127 GetWidget()->Close(); |
101 } else { | 128 } else { |
102 NOTREACHED() << "Unknown view"; | 129 NOTREACHED() << "Unknown view"; |
103 } | 130 } |
104 } | 131 } |
105 | 132 |
106 void MessageBubble::LinkClicked(views::Link* source, int event_flags) { | 133 void MessageBubble::LinkClicked(views::Link* source, int event_flags) { |
107 if (!message_delegate_) | 134 if (!link_listener_) |
108 return; | 135 return; |
109 for (size_t i = 0; i < help_links_.size(); ++i) { | 136 for (size_t i = 0; i < help_links_.size(); ++i) { |
110 if (source == help_links_[i]) { | 137 if (source == help_links_[i]) { |
111 message_delegate_->OnLinkActivated(i); | 138 link_listener_->OnLinkActivated(i); |
112 return; | 139 return; |
113 } | 140 } |
114 } | 141 } |
115 NOTREACHED() << "Unknown view"; | 142 NOTREACHED() << "Unknown view"; |
116 } | 143 } |
117 | 144 |
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(TOUCH_UI) && 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(TOUCH_UI) && defined(TOOLKIT_USES_GTK) | |
alicet1
2011/11/20 01:46:22
is there anything on touch that you need to exclud
msw
2011/11/21 20:34:43
I'm not sure the new bubble needs this mouse butto
| |
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 | 145 } // namespace chromeos |
OLD | NEW |