Chromium Code Reviews| 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 |