Chromium Code Reviews| Index: chrome/browser/ui/views/validation_message_bubble_view.cc |
| diff --git a/chrome/browser/ui/views/validation_message_bubble_view.cc b/chrome/browser/ui/views/validation_message_bubble_view.cc |
| index 076cba008f02e996523b872a0b40cf973bffc46c..ddeb223f1e2d40d7dd73f1d2dfe8103210c18654 100644 |
| --- a/chrome/browser/ui/views/validation_message_bubble_view.cc |
| +++ b/chrome/browser/ui/views/validation_message_bubble_view.cc |
| @@ -3,16 +3,129 @@ |
| // found in the LICENSE file. |
| #include "chrome/browser/ui/validation_message_bubble.h" |
|
sky
2013/04/30 13:53:21
newline between 5/6.
tkent
2013/05/01 03:15:02
Done.
|
| +#include "chrome/browser/ui/views/validation_message_bubble_delegate.h" |
| +#include "grit/theme_resources.h" |
| +#include "ui/base/resource/resource_bundle.h" |
| +#include "ui/views/controls/image_view.h" |
| +#include "ui/views/controls/label.h" |
| +#include "ui/views/widget/widget.h" |
| + |
| +const int kWindowMinWidth = 64; |
|
sky
2013/04/30 13:53:21
These belong in a namespace or static.
tkent
2013/05/01 03:15:02
Made them static.
BTW, why is it necessary? "const
|
| +const int kWindowMaxWidth = 256; |
| +const int kPadding = 0; |
| +const int kIconTextMargin = 8; |
| +const int kTextVerticalMargin = 4; |
| + |
| +ValidationMessageBubbleDelegate::ValidationMessageBubbleDelegate( |
|
sky
2013/04/30 13:53:21
Why is the ValidateMessageBubbleDelegate implement
tkent
2013/05/01 03:15:02
Moved ValidationMessageBubbleDelegate functions to
|
| + const gfx::Rect& anchor_in_screen, |
| + const string16& main_text, |
| + const string16& sub_text) { |
| + set_use_focusless(true); |
| + set_arrow(views::BubbleBorder::TOP_LEFT); |
| + set_anchor_rect(anchor_in_screen); |
| + |
| + ResourceBundle& bundle = ResourceBundle::GetSharedInstance(); |
| + views::ImageView* icon = new views::ImageView(); |
| + icon->SetImage(*bundle.GetImageSkiaNamed(IDR_INPUT_ALERT)); |
| + gfx::Size size = icon->GetPreferredSize(); |
| + icon->SetBounds(kPadding, kPadding, size.width(), size.height()); |
| + AddChildView(icon); |
| + |
| + views::Label* label = new views::Label(main_text); |
| + label->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| + label->SetFont(bundle.GetFont(ResourceBundle::MediumFont)); |
| + label->set_directionality_mode(views::Label::AUTO_DETECT_DIRECTIONALITY); |
| + int text_start_x = kPadding + size.width() + kIconTextMargin; |
| + int min_available = kWindowMinWidth - text_start_x - kPadding; |
| + int max_available = kWindowMaxWidth - text_start_x - kPadding; |
| + int label_width = label->GetPreferredSize().width(); |
| + label->SetMultiLine(true); |
| + AddChildView(label); |
| + |
| + views::Label* sub_label = NULL; |
| + if (!sub_text.empty()) { |
| + sub_label = new views::Label(sub_text); |
| + sub_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| + sub_label->set_directionality_mode( |
| + views::Label::AUTO_DETECT_DIRECTIONALITY); |
| + label_width = std::max(label_width, sub_label->GetPreferredSize().width()); |
| + sub_label->SetMultiLine(true); |
| + AddChildView(sub_label); |
| + } |
| + |
| + if (label_width < min_available) |
| + label_width = min_available; |
| + else if (label_width > max_available) |
| + label_width = max_available; |
| + label->SetBounds(text_start_x, kPadding, |
| + label_width, label->GetHeightForWidth(label_width)); |
| + int content_bottom = kPadding + label->height(); |
| + |
| + if (sub_label) { |
| + sub_label->SetBounds(text_start_x, |
| + content_bottom + kTextVerticalMargin, |
| + label_width, |
| + sub_label->GetHeightForWidth(label_width)); |
| + content_bottom += kTextVerticalMargin + sub_label->height(); |
| + } |
| + |
| + width_ = text_start_x + label_width + kPadding; |
| + height_ = content_bottom + kPadding; |
| +} |
| + |
| +gfx::Size ValidationMessageBubbleDelegate::GetPreferredSize() { |
| + return gfx::Size(width_, height_); |
| +} |
| + |
| +void ValidationMessageBubbleDelegate::DeleteDelegate() { |
| + delete this; |
| +} |
| + |
| +ValidationMessageBubbleDelegate::~ValidationMessageBubbleDelegate() {} |
| + |
| +namespace { |
| + |
| +class ValidationMessageBubbleImpl : public chrome::ValidationMessageBubble { |
| + public: |
| + ValidationMessageBubbleImpl(const gfx::Rect& anchor_in_screen, |
| + const string16& main_text, |
| + const string16& sub_text); |
| + |
| + virtual ~ValidationMessageBubbleImpl() { |
| + delegate_->GetWidget()->Hide(); |
| + } |
| + |
| + private: |
| + ValidationMessageBubbleDelegate* delegate_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ValidationMessageBubbleImpl); |
| +}; |
| + |
| +// A ValidationMessageBubble implementation for Views. |
| +ValidationMessageBubbleImpl::ValidationMessageBubbleImpl( |
| + const gfx::Rect& anchor_in_screen, |
| + const string16& main_text, |
| + const string16& sub_text) { |
| + // The delegate_ will kill itself in ValidationMessageBubbleDelegate:: |
| + // DeleteDelegate. |
| + delegate_ = new ValidationMessageBubbleDelegate( |
| + anchor_in_screen, main_text, sub_text); |
| + views::BubbleDelegateView::CreateBubble(delegate_); |
| + delegate_->GetWidget()->Show(); |
| +} |
| + |
| +} // namespace |
| namespace chrome { |
| scoped_ptr<ValidationMessageBubble> ValidationMessageBubble::CreateAndShow( |
| - content::RenderWidgetHost* widget_host, |
| + content::RenderWidgetHost*, |
| const gfx::Rect& anchor_in_screen, |
| const string16& main_text, |
| const string16& sub_text) { |
| - // TODO(tkent): Implement this and enable it. crbug.com/235719. |
| - return scoped_ptr<ValidationMessageBubble>().Pass(); |
| + scoped_ptr<ValidationMessageBubble> bubble( |
| + new ValidationMessageBubbleImpl(anchor_in_screen, main_text, sub_text)); |
| + return bubble.Pass(); |
| } |
| -} |
| +} // namespace chrome |