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 base::string16& main_text, 24 const base::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 SetAnchorRect(anchor_in_screen); 30 31 ui::ResourceBundle& bundle = ui::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( 39 main_text, bundle.GetFontList(ui::ResourceBundle::MediumFont)); 40 label->SetHorizontalAlignment(gfx::ALIGN_LEFT); 41 label->set_directionality_mode(gfx::DIRECTIONALITY_FROM_TEXT); 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(gfx::DIRECTIONALITY_FROM_TEXT); 54 label_width = std::max(label_width, sub_label->GetPreferredSize().width()); 55 sub_label->SetMultiLine(true); 56 AddChildView(sub_label); 57 } 58 59 if (label_width < min_available) 60 label_width = min_available; 61 else if (label_width > max_available) 62 label_width = max_available; 63 label->SetBounds(text_start_x, kPadding, 64 label_width, label->GetHeightForWidth(label_width)); 65 int content_bottom = kPadding + label->height(); 66 67 if (sub_label) { 68 sub_label->SetBounds(text_start_x, 69 content_bottom + kTextVerticalMargin, 70 label_width, 71 sub_label->GetHeightForWidth(label_width)); 72 content_bottom += kTextVerticalMargin + sub_label->height(); 73 } 74 75 width_ = text_start_x + label_width + kPadding; 76 height_ = content_bottom + kPadding; 77 } 78 79 ValidationMessageBubbleDelegate::~ValidationMessageBubbleDelegate() {} 80 81 void ValidationMessageBubbleDelegate::Close() { 82 GetWidget()->Close(); 83 observer_ = NULL; 84 } 85 86 void ValidationMessageBubbleDelegate::SetPositionRelativeToAnchor( 87 const gfx::Rect& anchor_in_screen) { 88 SetAnchorRect(anchor_in_screen); 89 } 90 91 gfx::Size ValidationMessageBubbleDelegate::GetPreferredSize() const { 92 return gfx::Size(width_, height_); 93 } 94 95 void ValidationMessageBubbleDelegate::DeleteDelegate() { 96 delete this; 97 } 98 99 void ValidationMessageBubbleDelegate::WindowClosing() { 100 if (observer_ != NULL) 101 observer_->WindowClosing(); 102 } 103