1 // Copyright (c) 2013 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/ui/views/validation_message_bubble_delegate.h" 6 7 #include "grit/theme_resources.h" 8 #include "ui/base/resource/resource_bundle.h" 9 #include "ui/views/controls/image_view.h" 10 #include "ui/views/controls/label.h" 11 #include "ui/views/widget/widget.h" 12 13 // static 14 const int ValidationMessageBubbleDelegate::kWindowMinWidth = 64; 15 // static 16 const int ValidationMessageBubbleDelegate::kWindowMaxWidth = 256; 17 static const int kPadding = 0; 18 static const int kIconTextMargin = 8; 19 static const int kTextVerticalMargin = 4; 20 21 ValidationMessageBubbleDelegate::ValidationMessageBubbleDelegate( 22 const gfx::Rect& anchor_in_screen, 23 const string16& main_text, 24 const string16& sub_text, 25 Observer* observer) 26 : observer_(observer), width_(0), height_(0) { 27 set_use_focusless(true); 28 set_arrow(views::BubbleBorder::TOP_LEFT); 29 set_anchor_rect(anchor_in_screen); 30 31 ResourceBundle& bundle = ResourceBundle::GetSharedInstance(); 32 views::ImageView* icon = new views::ImageView(); 33 icon->SetImage(*bundle.GetImageSkiaNamed(IDR_INPUT_ALERT)); 34 gfx::Size size = icon->GetPreferredSize(); 35 icon->SetBounds(kPadding, kPadding, size.width(), size.height()); 36 AddChildView(icon); 37 38 views::Label* label = new views::Label(main_text); 39 label->SetHorizontalAlignment(gfx::ALIGN_LEFT); 40 label->SetFont(bundle.GetFont(ResourceBundle::MediumFont)); 41 label->set_directionality_mode(views::Label::AUTO_DETECT_DIRECTIONALITY); 42 int text_start_x = kPadding + size.width() + kIconTextMargin; 43 int min_available = kWindowMinWidth - text_start_x - kPadding; 44 int max_available = kWindowMaxWidth - text_start_x - kPadding; 45 int label_width = label->GetPreferredSize().width(); 46 label->SetMultiLine(true); 47 AddChildView(label); 48 49 views::Label* sub_label = NULL; 50 if (!sub_text.empty()) { 51 sub_label = new views::Label(sub_text); 52 sub_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); 53 sub_label->set_directionality_mode( 54 views::Label::AUTO_DETECT_DIRECTIONALITY); 55 label_width = std::max(label_width, sub_label->GetPreferredSize().width()); 56 sub_label->SetMultiLine(true); 57 AddChildView(sub_label); 58 } 59 60 if (label_width < min_available) 61 label_width = min_available; 62 else if (label_width > max_available) 63 label_width = max_available; 64 label->SetBounds(text_start_x, kPadding, 65 label_width, label->GetHeightForWidth(label_width)); 66 int content_bottom = kPadding + label->height(); 67 68 if (sub_label) { 69 sub_label->SetBounds(text_start_x, 70 content_bottom + kTextVerticalMargin, 71 label_width, 72 sub_label->GetHeightForWidth(label_width)); 73 content_bottom += kTextVerticalMargin + sub_label->height(); 74 } 75 76 width_ = text_start_x + label_width + kPadding; 77 height_ = content_bottom + kPadding; 78 } 79 80 ValidationMessageBubbleDelegate::~ValidationMessageBubbleDelegate() {} 81 82 void ValidationMessageBubbleDelegate::Close() { 83 GetWidget()->Close(); 84 observer_ = NULL; 85 } 86 87 void ValidationMessageBubbleDelegate::SetPositionRelativeToAnchor( 88 const gfx::Rect& anchor_in_screen) { 89 set_anchor_rect(anchor_in_screen); 90 SizeToContents(); 91 } 92 93 gfx::Size ValidationMessageBubbleDelegate::GetPreferredSize() { 94 return gfx::Size(width_, height_); 95 } 96 97 void ValidationMessageBubbleDelegate::DeleteDelegate() { 98 delete this; 99 } 100 101 void ValidationMessageBubbleDelegate::WindowClosing() { 102 if (observer_ != NULL) 103 observer_->WindowClosing(); 104 } 105