OLD | NEW |
---|---|
(Empty) | |
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 "ash/popup_message.h" | |
6 | |
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" | |
17 | |
18 namespace ash { | |
19 namespace { | |
20 const int kMessageTopBottomMargin = 10; | |
21 const int kMessageLeftRightMargin = 10; | |
22 const int kMessageAppearanceDelay = 200; // msec | |
James Cook
2013/05/22 12:29:07
nit: Consider kMessageAppearanceDelayMs, then you
Mr4D (OOO till 08-26)
2013/05/22 14:57:34
Done.
| |
23 const int kMessageMinHeight = 29 - 2 * kMessageTopBottomMargin; | |
24 const SkColor kMessageTextColor = SkColorSetRGB(0x22, 0x22, 0x22); | |
25 | |
26 // The maximum width of the Message bubble. Borrowed the value from | |
27 // ash/Message/Message_controller.cc | |
James Cook
2013/05/22 12:29:07
Message/Message -> message/message
Mr4D (OOO till 08-26)
2013/05/22 14:57:34
Done.
| |
28 const int kMessageMaxWidth = 250; | |
29 | |
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; | |
35 | |
36 // The number of pixels between the icon and the text. | |
37 const int kHorizontalPopupPaddingBetweenItems = 10; | |
38 | |
39 // The number of pixels between the text items. | |
40 const int kVerticalPopupPaddingBetweenItems = 10; | |
41 } // namespace | |
42 | |
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); | |
53 | |
54 void Close(); | |
55 | |
56 private: | |
57 // views::View overrides: | |
58 virtual gfx::Size GetPreferredSize() OVERRIDE; | |
59 | |
60 // Each component (width/height) can force a size override for that component | |
61 // if not 0. | |
James Cook
2013/05/22 12:29:07
two space indent
Mr4D (OOO till 08-26)
2013/05/22 14:57:34
Done.
| |
62 gfx::Size size_override_; | |
63 | |
64 DISALLOW_COPY_AND_ASSIGN(MessageBubble); | |
65 }; | |
66 | |
67 PopupMessage::MessageBubble::MessageBubble( | |
68 const base::string16& caption, | |
James Cook
2013/05/22 12:29:07
indent
Mr4D (OOO till 08-26)
2013/05/22 14:57:34
Done.
| |
69 const base::string16& message, | |
70 IconType message_type, | |
71 views::View* anchor, | |
72 views::BubbleBorder::Arrow arrow, | |
73 const gfx::Size& size_override, | |
74 int arrow_offset) | |
75 : views::BubbleDelegateView(anchor, arrow), | |
76 size_override_(size_override) { | |
77 gfx::Insets insets = gfx::Insets(kArrowOffsetTopBottom, | |
78 kArrowOffsetLeftRight, | |
79 kArrowOffsetTopBottom, | |
80 kArrowOffsetLeftRight); | |
81 // An anchor can have an asymmetrical border for spacing reasons. Adjust the | |
82 // anchor location for this. | |
83 if (anchor->border()) | |
84 insets += anchor->border()->GetInsets(); | |
85 | |
86 set_anchor_view_insets(insets); | |
87 set_close_on_esc(false); | |
88 set_close_on_deactivate(false); | |
89 set_use_focusless(true); | |
90 set_accept_events(false); | |
91 | |
92 set_margins(gfx::Insets(kMessageTopBottomMargin, kMessageLeftRightMargin, | |
93 kMessageTopBottomMargin, kMessageLeftRightMargin)); | |
94 set_shadow(views::BubbleBorder::SMALL_SHADOW); | |
95 | |
96 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); | |
97 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, | |
98 kHorizontalPopupPaddingBetweenItems)); | |
99 | |
100 // Add the icon to the first column (if there is one). | |
James Cook
2013/05/22 12:29:07
optional nit: This class could use a little ASCII-
Mr4D (OOO till 08-26)
2013/05/22 14:57:34
Done.
| |
101 if (message_type != ICON_NONE) { | |
102 views::ImageView* icon = new views::ImageView(); | |
103 icon->SetImage( | |
104 bundle.GetImageNamed(IDR_AURA_WARNING_ICON).ToImageSkia()); | |
105 icon->SetVerticalAlignment(views::ImageView::LEADING); | |
106 AddChildView(icon); | |
107 } | |
108 | |
109 // Create a container for the text items and use it as second column. | |
110 views::View* details = new views::View(); | |
111 AddChildView(details); | |
112 details->SetLayoutManager(new views::BoxLayout( | |
113 views::BoxLayout::kVertical, 0, 0, kVerticalPopupPaddingBetweenItems)); | |
114 | |
115 // The caption label. | |
116 if (!caption.empty()) { | |
117 views::Label* caption_label = new views::Label(caption); | |
118 caption_label->SetMultiLine(true); | |
119 caption_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
120 caption_label->SetFont(bundle.GetFont(ui::ResourceBundle::BoldFont)); | |
121 caption_label->SetEnabledColor(kMessageTextColor); | |
122 details->AddChildView(caption_label); | |
123 } | |
124 | |
125 // The message label. | |
126 if (!message.empty()) { | |
127 views::Label* message_label = new views::Label(message); | |
128 message_label->SetMultiLine(true); | |
129 message_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
130 message_label->SetEnabledColor(kMessageTextColor); | |
131 details->AddChildView(message_label); | |
132 } | |
133 views::BubbleDelegateView::CreateBubble(this); | |
134 | |
135 // Change the arrow offset if needed. | |
136 if (arrow_offset) { | |
137 // With the creation of the bubble, the bubble got already placed (and | |
138 // possibly re-oriented to fit on the screen). Since it is not possible to | |
139 // set the arrow offset before the creation, we need to set the offset, | |
140 // and the orientation variables again and force a re-placement. | |
141 GetBubbleFrameView()->bubble_border()->set_arrow_offset(arrow_offset); | |
142 GetBubbleFrameView()->bubble_border()->set_arrow(arrow); | |
143 SetAlignment(views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR); | |
144 } | |
145 } | |
146 | |
147 void PopupMessage::MessageBubble::Close() { | |
148 if (GetWidget()) | |
149 GetWidget()->Close(); | |
150 } | |
151 | |
152 gfx::Size PopupMessage::MessageBubble::GetPreferredSize() { | |
153 gfx::Size pref_size = views::BubbleDelegateView::GetPreferredSize(); | |
154 // Override the size with either the provided size or adjust it to not | |
155 // violate our minimum / maximum sizes. | |
156 if (size_override_.height()) | |
157 pref_size.set_height(size_override_.height()); | |
158 else if (pref_size.height() < kMessageMinHeight) | |
159 pref_size.set_height(kMessageMinHeight); | |
160 | |
161 if (size_override_.width()) | |
162 pref_size.set_width(size_override_.width()); | |
163 else if (pref_size.width() > kMessageMaxWidth) | |
164 pref_size.set_width(kMessageMaxWidth); | |
165 | |
166 return pref_size; | |
167 } | |
168 | |
169 PopupMessage::PopupMessage(const base::string16& caption, | |
170 const base::string16& message, | |
171 IconType message_type, | |
172 views::View* anchor, | |
173 views::BubbleBorder::Arrow arrow, | |
174 const gfx::Size& size_override, | |
175 int arrow_offset) | |
176 : view_(NULL) { | |
177 view_ = new MessageBubble( | |
178 caption, message, message_type, anchor, arrow, size_override, | |
179 arrow_offset); | |
180 widget_ = view_->GetWidget(); | |
181 | |
182 gfx::NativeView native_view = widget_->GetNativeView(); | |
183 views::corewm::SetWindowVisibilityAnimationType( | |
184 native_view, views::corewm::WINDOW_VISIBILITY_ANIMATION_TYPE_VERTICAL); | |
185 views::corewm::SetWindowVisibilityAnimationTransition( | |
186 native_view, views::corewm::ANIMATE_HIDE); | |
187 view_->GetWidget()->Show(); | |
188 } | |
189 | |
190 PopupMessage::~PopupMessage() { | |
191 CancelHidingAnimation(); | |
192 Close(); | |
193 } | |
194 | |
195 void PopupMessage::Close() { | |
196 if (view_) { | |
197 view_->Close(); | |
198 view_ = NULL; | |
199 widget_ = NULL; | |
200 } | |
201 } | |
202 | |
203 void PopupMessage::CancelHidingAnimation() { | |
James Cook
2013/05/22 12:29:07
Do you think this would be more clear with a singl
Mr4D (OOO till 08-26)
2013/05/22 14:57:34
Well...
a. I have found this somewhere else and t
| |
204 if (!widget_ || !widget_->GetNativeView()) | |
205 return; | |
206 | |
207 gfx::NativeView native_view = widget_->GetNativeView(); | |
208 views::corewm::SetWindowVisibilityAnimationTransition( | |
209 native_view, views::corewm::ANIMATE_NONE); | |
210 } | |
211 | |
212 } // namespace ash | |
OLD | NEW |