Roll leveldb from r73 to r75.
[chromium-blink-merge.git] / ash / popup_message.cc
blobbd519387f4d870a9c0032477971600433b20074d
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.
5 #include "ash/popup_message.h"
7 #include "ash/wm/window_animations.h"
8 #include "grit/ash_resources.h"
9 #include "ui/base/resource/resource_bundle.h"
10 #include "ui/gfx/insets.h"
11 #include "ui/views/bubble/bubble_delegate.h"
12 #include "ui/views/bubble/bubble_frame_view.h"
13 #include "ui/views/controls/image_view.h"
14 #include "ui/views/controls/label.h"
15 #include "ui/views/layout/box_layout.h"
16 #include "ui/views/widget/widget.h"
18 namespace ash {
19 namespace {
20 const int kMessageTopBottomMargin = 10;
21 const int kMessageLeftRightMargin = 10;
22 const int kMessageAppearanceDelayMs = 200;
23 const int kMessageMinHeight = 29 - 2 * kMessageTopBottomMargin;
24 const SkColor kMessageTextColor = SkColorSetRGB(0x22, 0x22, 0x22);
26 // The maximum width of the Message bubble. Borrowed the value from
27 // ash/message/message_controller.cc
28 const int kMessageMaxWidth = 250;
30 // The offset for the Message bubble - making sure that the bubble is flush
31 // with the shelf. The offset includes the arrow size in pixels as well as
32 // the activation bar and other spacing elements.
33 const int kArrowOffsetLeftRight = 11;
34 const int kArrowOffsetTopBottom = 7;
36 // The number of pixels between the icon and the text.
37 const int kHorizontalPopupPaddingBetweenItems = 10;
39 // The number of pixels between the text items.
40 const int kVerticalPopupPaddingBetweenItems = 10;
41 } // namespace
43 // The implementation of Message of the launcher.
44 class PopupMessage::MessageBubble : public views::BubbleDelegateView {
45 public:
46 MessageBubble(const base::string16& caption,
47 const base::string16& message,
48 IconType message_type,
49 views::View* anchor,
50 views::BubbleBorder::Arrow arrow_orientation,
51 const gfx::Size& size_override,
52 int arrow_offset);
54 void Close();
56 private:
57 // views::View overrides:
58 virtual gfx::Size GetPreferredSize() OVERRIDE;
60 // Each component (width/height) can force a size override for that component
61 // if not 0.
62 gfx::Size size_override_;
64 DISALLOW_COPY_AND_ASSIGN(MessageBubble);
67 PopupMessage::MessageBubble::MessageBubble(const base::string16& caption,
68 const base::string16& message,
69 IconType message_type,
70 views::View* anchor,
71 views::BubbleBorder::Arrow arrow,
72 const gfx::Size& size_override,
73 int arrow_offset)
74 : views::BubbleDelegateView(anchor, arrow),
75 size_override_(size_override) {
76 gfx::Insets insets = gfx::Insets(kArrowOffsetTopBottom,
77 kArrowOffsetLeftRight,
78 kArrowOffsetTopBottom,
79 kArrowOffsetLeftRight);
80 // An anchor can have an asymmetrical border for spacing reasons. Adjust the
81 // anchor location for this.
82 if (anchor->border())
83 insets += anchor->border()->GetInsets();
85 set_anchor_view_insets(insets);
86 set_close_on_esc(false);
87 set_close_on_deactivate(false);
88 set_use_focusless(true);
89 set_accept_events(false);
91 set_margins(gfx::Insets(kMessageTopBottomMargin, kMessageLeftRightMargin,
92 kMessageTopBottomMargin, kMessageLeftRightMargin));
93 set_shadow(views::BubbleBorder::SMALL_SHADOW);
95 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
96 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0,
97 kHorizontalPopupPaddingBetweenItems));
99 // Here is the layout:
100 // arrow_offset (if not 0)
101 // |-------------|
102 // | ^
103 // +-------------------------------------------------+
104 // -| |-
105 // icon | [!] Caption in bold which can be multi line | caption_label
106 // -| |-
107 // | Message text which can be multi line | message_label
108 // | as well. |
109 // | |-
110 // +-------------------------------------------------+
111 // |------------details container--------------|
112 // Note that the icon, caption and massage are optional.
114 // Add the icon to the first column (if there is one).
115 if (message_type != ICON_NONE) {
116 views::ImageView* icon = new views::ImageView();
117 icon->SetImage(
118 bundle.GetImageNamed(IDR_AURA_WARNING_ICON).ToImageSkia());
119 icon->SetVerticalAlignment(views::ImageView::LEADING);
120 AddChildView(icon);
123 // Create a container for the text items and use it as second column.
124 views::View* details = new views::View();
125 AddChildView(details);
126 details->SetLayoutManager(new views::BoxLayout(
127 views::BoxLayout::kVertical, 0, 0, kVerticalPopupPaddingBetweenItems));
129 // The caption label.
130 if (!caption.empty()) {
131 views::Label* caption_label = new views::Label(caption);
132 caption_label->SetMultiLine(true);
133 caption_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
134 caption_label->SetFont(bundle.GetFont(ui::ResourceBundle::BoldFont));
135 caption_label->SetEnabledColor(kMessageTextColor);
136 details->AddChildView(caption_label);
139 // The message label.
140 if (!message.empty()) {
141 views::Label* message_label = new views::Label(message);
142 message_label->SetMultiLine(true);
143 message_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
144 message_label->SetEnabledColor(kMessageTextColor);
145 details->AddChildView(message_label);
147 views::BubbleDelegateView::CreateBubble(this);
149 // Change the arrow offset if needed.
150 if (arrow_offset) {
151 // With the creation of the bubble, the bubble got already placed (and
152 // possibly re-oriented to fit on the screen). Since it is not possible to
153 // set the arrow offset before the creation, we need to set the offset,
154 // and the orientation variables again and force a re-placement.
155 GetBubbleFrameView()->bubble_border()->set_arrow_offset(arrow_offset);
156 GetBubbleFrameView()->bubble_border()->set_arrow(arrow);
157 SetAlignment(views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR);
161 void PopupMessage::MessageBubble::Close() {
162 if (GetWidget())
163 GetWidget()->Close();
166 gfx::Size PopupMessage::MessageBubble::GetPreferredSize() {
167 gfx::Size pref_size = views::BubbleDelegateView::GetPreferredSize();
168 // Override the size with either the provided size or adjust it to not
169 // violate our minimum / maximum sizes.
170 if (size_override_.height())
171 pref_size.set_height(size_override_.height());
172 else if (pref_size.height() < kMessageMinHeight)
173 pref_size.set_height(kMessageMinHeight);
175 if (size_override_.width())
176 pref_size.set_width(size_override_.width());
177 else if (pref_size.width() > kMessageMaxWidth)
178 pref_size.set_width(kMessageMaxWidth);
180 return pref_size;
183 PopupMessage::PopupMessage(const base::string16& caption,
184 const base::string16& message,
185 IconType message_type,
186 views::View* anchor,
187 views::BubbleBorder::Arrow arrow,
188 const gfx::Size& size_override,
189 int arrow_offset)
190 : view_(NULL) {
191 view_ = new MessageBubble(
192 caption, message, message_type, anchor, arrow, size_override,
193 arrow_offset);
194 widget_ = view_->GetWidget();
196 gfx::NativeView native_view = widget_->GetNativeView();
197 views::corewm::SetWindowVisibilityAnimationType(
198 native_view, views::corewm::WINDOW_VISIBILITY_ANIMATION_TYPE_VERTICAL);
199 views::corewm::SetWindowVisibilityAnimationTransition(
200 native_view, views::corewm::ANIMATE_HIDE);
201 view_->GetWidget()->Show();
204 PopupMessage::~PopupMessage() {
205 CancelHidingAnimation();
206 Close();
209 void PopupMessage::Close() {
210 if (view_) {
211 view_->Close();
212 view_ = NULL;
213 widget_ = NULL;
217 void PopupMessage::CancelHidingAnimation() {
218 if (!widget_ || !widget_->GetNativeView())
219 return;
221 gfx::NativeView native_view = widget_->GetNativeView();
222 views::corewm::SetWindowVisibilityAnimationTransition(
223 native_view, views::corewm::ANIMATE_NONE);
226 } // namespace ash