OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/system/tray/tray_bubble_view.h" | 5 #include "ash/system/tray/tray_bubble_view.h" |
6 | 6 |
7 #include "ash/shell.h" | 7 #include "ash/shell.h" |
8 #include "ash/shell_window_ids.h" | 8 #include "ash/shell_window_ids.h" |
9 #include "ash/system/tray/tray_constants.h" | 9 #include "ash/system/tray/tray_constants.h" |
10 #include "ash/wm/shelf_layout_manager.h" | 10 #include "ash/wm/shelf_layout_manager.h" |
11 #include "ash/wm/window_animations.h" | |
11 #include "grit/ash_strings.h" | 12 #include "grit/ash_strings.h" |
12 #include "third_party/skia/include/core/SkCanvas.h" | 13 #include "third_party/skia/include/core/SkCanvas.h" |
13 #include "third_party/skia/include/core/SkColor.h" | 14 #include "third_party/skia/include/core/SkColor.h" |
14 #include "third_party/skia/include/core/SkPaint.h" | 15 #include "third_party/skia/include/core/SkPaint.h" |
15 #include "third_party/skia/include/core/SkPath.h" | 16 #include "third_party/skia/include/core/SkPath.h" |
16 #include "third_party/skia/include/effects/SkBlurImageFilter.h" | 17 #include "third_party/skia/include/effects/SkBlurImageFilter.h" |
17 #include "ui/aura/event.h" | 18 #include "ui/aura/event.h" |
18 #include "ui/aura/window.h" | 19 #include "ui/aura/window.h" |
19 #include "ui/base/accessibility/accessible_view_state.h" | 20 #include "ui/base/accessibility/accessible_view_state.h" |
20 #include "ui/base/l10n/l10n_util.h" | 21 #include "ui/base/l10n/l10n_util.h" |
21 #include "ui/gfx/canvas.h" | 22 #include "ui/gfx/canvas.h" |
22 #include "ui/gfx/insets.h" | 23 #include "ui/gfx/insets.h" |
23 #include "ui/gfx/screen.h" | 24 #include "ui/gfx/screen.h" |
24 #include "ui/views/bubble/bubble_frame_view.h" | 25 #include "ui/views/bubble/bubble_frame_view.h" |
25 #include "ui/views/layout/box_layout.h" | 26 #include "ui/views/layout/box_layout.h" |
26 | 27 |
27 namespace ash { | 28 namespace ash { |
28 | 29 |
29 namespace { | 30 namespace { |
30 | 31 |
31 const int kShadowThickness = 4; | 32 const int kShadowThickness = 4; |
32 const int kBottomLineHeight = 1; | 33 const int kBottomLineHeight = 1; |
33 const int kSystemTrayBubbleHorizontalInset = 1; | 34 const int kSystemTrayBubbleHorizontalInset = 1; |
34 const int kSystemTrayBubbleVerticalInset = 1; | 35 const int kSystemTrayBubbleVerticalInset = 1; |
35 | 36 |
36 const int kArrowHeight = 10; | 37 const int kArrowHeight = 10; |
37 const int kArrowWidth = 20; | 38 const int kArrowWidth = 20; |
38 | 39 |
39 // Inset the arrow a bit from the edge. | 40 // Inset the arrow a bit from the edge. |
40 const int kArrowMinOffset = kArrowWidth / 2 + 4; | 41 const int kArrowEdgeMargin = 12; |
42 const int kArrowMinOffset = kArrowWidth / 2 + kArrowEdgeMargin; | |
41 | 43 |
42 const SkColor kShadowColor = SkColorSetARGB(0xff, 0, 0, 0); | 44 const SkColor kShadowColor = SkColorSetARGB(0xff, 0, 0, 0); |
43 | 45 |
46 const int kAnimationDurationForPopupMS = 200; | |
47 | |
44 void DrawBlurredShadowAroundView(gfx::Canvas* canvas, | 48 void DrawBlurredShadowAroundView(gfx::Canvas* canvas, |
45 int top, | 49 int top, |
46 int bottom, | 50 int bottom, |
47 int width, | 51 int width, |
48 const gfx::Insets& inset) { | 52 const gfx::Insets& inset) { |
49 SkPath path; | 53 SkPath path; |
50 path.incReserve(4); | 54 path.incReserve(4); |
51 path.moveTo(SkIntToScalar(inset.left() + kShadowThickness), | 55 path.moveTo(SkIntToScalar(inset.left() + kShadowThickness), |
52 SkIntToScalar(top + kShadowThickness + 1)); | 56 SkIntToScalar(top + kShadowThickness + 1)); |
53 path.lineTo(SkIntToScalar(inset.left() + kShadowThickness), | 57 path.lineTo(SkIntToScalar(inset.left() + kShadowThickness), |
(...skipping 18 matching lines...) Expand all Loading... | |
72 TrayBubbleBorder(views::View* owner, | 76 TrayBubbleBorder(views::View* owner, |
73 views::View* anchor, | 77 views::View* anchor, |
74 views::BubbleBorder::ArrowLocation arrow_location, | 78 views::BubbleBorder::ArrowLocation arrow_location, |
75 int arrow_offset) | 79 int arrow_offset) |
76 : views::BubbleBorder(arrow_location, | 80 : views::BubbleBorder(arrow_location, |
77 views::BubbleBorder::NO_SHADOW), | 81 views::BubbleBorder::NO_SHADOW), |
78 owner_(owner), | 82 owner_(owner), |
79 anchor_(anchor), | 83 anchor_(anchor), |
80 tray_arrow_offset_(arrow_offset) { | 84 tray_arrow_offset_(arrow_offset) { |
81 set_alignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE); | 85 set_alignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE); |
86 // Normally all rendering is mirrored for RTL. This doesn't work correctly | |
87 // with status area bubbles, and would make Paint much more complex. | |
88 // Instead, set rtl_mirrored_ to false so that GetInsets() returns | |
89 // the unmirrored insets. | |
90 set_rtl_mirrored(false); | |
82 } | 91 } |
83 | 92 |
84 virtual ~TrayBubbleBorder() {} | 93 virtual ~TrayBubbleBorder() {} |
85 | 94 |
86 private: | |
87 views::Background* FindAppropriateBackground(views::View* view, | |
88 const gfx::Point& point) const { | |
89 views::Background* background = NULL; | |
90 views::View* target = view->GetEventHandlerForPoint(point); | |
91 for (; target && !background; target = target->parent()) | |
92 background = target->background(); | |
93 return background; | |
94 } | |
95 | |
96 // Overridden from views::BubbleBorder. | 95 // Overridden from views::BubbleBorder. |
97 // Override views::BubbleBorder to set the bubble on top of the anchor when | 96 // Override views::BubbleBorder to set the bubble on top of the anchor when |
98 // it has no arrow. | 97 // it has no arrow. |
99 virtual gfx::Rect GetBounds(const gfx::Rect& position_relative_to, | 98 virtual gfx::Rect GetBounds(const gfx::Rect& position_relative_to, |
100 const gfx::Size& contents_size) const OVERRIDE { | 99 const gfx::Size& contents_size) const OVERRIDE { |
101 if (arrow_location() != NONE) { | 100 if (arrow_location() != NONE) { |
102 return views::BubbleBorder::GetBounds(position_relative_to, | 101 return views::BubbleBorder::GetBounds(position_relative_to, |
103 contents_size); | 102 contents_size); |
104 } | 103 } |
105 | 104 |
106 gfx::Size border_size(contents_size); | 105 gfx::Size border_size(contents_size); |
107 gfx::Insets insets; | 106 gfx::Insets insets; |
108 GetInsets(&insets); | 107 GetInsets(&insets); |
109 border_size.Enlarge(insets.width(), insets.height()); | 108 border_size.Enlarge(insets.width(), insets.height()); |
110 | 109 |
111 const int kArrowOverlap = 3; | 110 const int kArrowOverlap = 3; |
112 int x = position_relative_to.x() + | 111 int x = position_relative_to.x() + |
113 position_relative_to.width() / 2 - border_size.width() / 2; | 112 position_relative_to.width() / 2 - border_size.width() / 2; |
114 // Position the bubble on top of the anchor. | 113 // Position the bubble on top of the anchor. |
115 int y = position_relative_to.y() + | 114 int y = position_relative_to.y() + |
116 kArrowOverlap - border_size.height(); | 115 kArrowOverlap - border_size.height(); |
117 return gfx::Rect(x, y, border_size.width(), border_size.height()); | 116 return gfx::Rect(x, y, border_size.width(), border_size.height()); |
118 } | 117 } |
119 | 118 |
120 // Overridden from views::Border. | 119 // Overridden from views::Border. |
121 virtual void Paint(const views::View& view, | 120 virtual void Paint(const views::View& view, |
122 gfx::Canvas* canvas) const OVERRIDE { | 121 gfx::Canvas* canvas) const OVERRIDE { |
123 gfx::Insets inset; | 122 gfx::Insets inset; |
124 GetInsets(&inset); | 123 // Get the unmirrored insets for the arrow location. |
124 GetInsetsForArrowLocation(&inset, arrow_location()); | |
125 DrawBlurredShadowAroundView( | 125 DrawBlurredShadowAroundView( |
126 canvas, 0, owner_->height(), owner_->width(), inset); | 126 canvas, 0, owner_->height(), owner_->width(), inset); |
127 | 127 |
128 // Draw the bottom line. | 128 // Draw the bottom line. |
129 int y = owner_->height() + inset.top(); | 129 int y = owner_->height() + inset.top(); |
130 canvas->FillRect(gfx::Rect(inset.left(), y, owner_->width(), | 130 canvas->FillRect(gfx::Rect(inset.left(), y, owner_->width(), |
131 kBottomLineHeight), kBorderDarkColor); | 131 kBottomLineHeight), kBorderDarkColor); |
132 | 132 |
133 if (!Shell::GetInstance()->shelf()->IsVisible() || | 133 if (!Shell::GetInstance()->shelf()->IsVisible() || |
134 arrow_location() == views::BubbleBorder::NONE) | 134 arrow_location() == views::BubbleBorder::NONE) |
135 return; | 135 return; |
136 | 136 |
137 gfx::Point arrow_reference; | 137 gfx::Point arrow_reference; |
138 | 138 |
139 // Draw the arrow after drawing child borders, so that the arrow can cover | 139 // Draw the arrow after drawing child borders, so that the arrow can cover |
msw
2012/07/24 00:32:43
This should be calling the default implementation
| |
140 // the its overlap section with child border. | 140 // the its overlap section with child border. |
msw
2012/07/24 00:32:44
grammar nit: "the its"
stevenjb
2012/07/26 23:48:30
Done.
| |
141 SkPath path; | 141 SkPath path; |
142 path.incReserve(4); | 142 path.incReserve(4); |
143 if (arrow_location() == views::BubbleBorder::BOTTOM_RIGHT || | 143 if (arrow_location() == views::BubbleBorder::BOTTOM_RIGHT || |
144 arrow_location() == views::BubbleBorder::BOTTOM_LEFT) { | 144 arrow_location() == views::BubbleBorder::BOTTOM_LEFT) { |
145 // Do not let the arrow too close to the edge of the bubble and | 145 // Note: tray_arrow_offset_ is relative to the anchor widget. |
146 // and the edge of the anchor. | 146 int tip_x; |
147 int tip_x = base::i18n::IsRTL() ? | 147 if (tray_arrow_offset_ == |
148 std::min(std::max(tray_arrow_offset_, kArrowMinOffset), | 148 internal::TrayBubbleView::InitParams::kArrowDefaultOffset) { |
149 std::min(owner_->width(), anchor_->width()) | 149 if (arrow_location() == views::BubbleBorder::BOTTOM_LEFT) |
150 - kArrowMinOffset) : | 150 tip_x = kArrowMinOffset; |
151 std::min(std::max(owner_->width() - tray_arrow_offset_, | 151 else |
152 owner_->width() - | 152 tip_x = owner_->width() - kArrowMinOffset; |
153 std::min(owner_->width(), anchor_->width()) + | 153 } else { |
154 kArrowMinOffset), | 154 gfx::Point pt(tray_arrow_offset_, 0); |
155 owner_->width() - kArrowMinOffset); | 155 views::View::ConvertPointToScreen( |
156 anchor_->GetWidget()->GetRootView(), &pt); | |
157 views::View::ConvertPointFromScreen( | |
158 owner_->GetWidget()->GetRootView(), &pt); | |
159 tip_x = std::min(pt.x(), owner_->width() - kArrowMinOffset); | |
160 tip_x = std::max(tip_x, kArrowMinOffset); | |
161 } | |
156 int left_base_x = tip_x - kArrowWidth / 2; | 162 int left_base_x = tip_x - kArrowWidth / 2; |
157 int left_base_y = y; | 163 int left_base_y = y; |
158 int tip_y = left_base_y + kArrowHeight; | 164 int tip_y = left_base_y + kArrowHeight; |
159 path.moveTo(SkIntToScalar(left_base_x), SkIntToScalar(left_base_y)); | 165 path.moveTo(SkIntToScalar(left_base_x), SkIntToScalar(left_base_y)); |
160 path.lineTo(SkIntToScalar(tip_x), SkIntToScalar(tip_y)); | 166 path.lineTo(SkIntToScalar(tip_x), SkIntToScalar(tip_y)); |
161 path.lineTo(SkIntToScalar(left_base_x + kArrowWidth), | 167 path.lineTo(SkIntToScalar(left_base_x + kArrowWidth), |
162 SkIntToScalar(left_base_y)); | 168 SkIntToScalar(left_base_y)); |
163 arrow_reference.SetPoint(tip_x, left_base_y - kArrowHeight); | 169 arrow_reference.SetPoint(tip_x, left_base_y - kArrowHeight); |
164 } else { | 170 } else { |
165 int tip_y = y - tray_arrow_offset_; | 171 int tip_y; |
166 tip_y = std::min(std::max(kArrowMinOffset, tip_y), | 172 if (tray_arrow_offset_ == |
167 owner_->height() - kArrowMinOffset); | 173 internal::TrayBubbleView::InitParams::kArrowDefaultOffset) { |
174 tip_y = owner_->height() - kArrowMinOffset; | |
175 } else { | |
176 int pty = y - tray_arrow_offset_; | |
177 gfx::Point pt(0, pty); | |
178 views::View::ConvertPointToScreen( | |
179 anchor_->GetWidget()->GetRootView(), &pt); | |
180 views::View::ConvertPointFromScreen( | |
181 owner_->GetWidget()->GetRootView(), &pt); | |
182 tip_y = std::min(pt.y(), owner_->height() - kArrowMinOffset); | |
183 tip_y = std::max(tip_y, kArrowMinOffset); | |
184 } | |
168 int top_base_y = tip_y - kArrowWidth / 2; | 185 int top_base_y = tip_y - kArrowWidth / 2; |
169 int top_base_x, tip_x; | 186 int top_base_x, tip_x; |
170 if (arrow_location() == views::BubbleBorder::LEFT_BOTTOM) { | 187 if (arrow_location() == views::BubbleBorder::LEFT_BOTTOM) { |
171 top_base_x = inset.left() + kSystemTrayBubbleHorizontalInset; | 188 top_base_x = inset.left() + kSystemTrayBubbleHorizontalInset; |
172 tip_x = top_base_x - kArrowHeight; | 189 tip_x = top_base_x - kArrowHeight; |
173 arrow_reference.SetPoint(top_base_x + kArrowHeight, tip_y); | 190 arrow_reference.SetPoint(top_base_x + kArrowHeight, tip_y); |
174 } else { | 191 } else { |
175 DCHECK(arrow_location() == views::BubbleBorder::RIGHT_BOTTOM); | 192 DCHECK(arrow_location() == views::BubbleBorder::RIGHT_BOTTOM); |
176 top_base_x = inset.left() + owner_->width() - | 193 top_base_x = inset.left() + owner_->width() - |
177 kSystemTrayBubbleHorizontalInset; | 194 kSystemTrayBubbleHorizontalInset; |
(...skipping 14 matching lines...) Expand all Loading... | |
192 paint.setColor(background ? background->get_color() : kBackgroundColor); | 209 paint.setColor(background ? background->get_color() : kBackgroundColor); |
193 canvas->DrawPath(path, paint); | 210 canvas->DrawPath(path, paint); |
194 | 211 |
195 // Now draw the arrow border. | 212 // Now draw the arrow border. |
196 paint.setStyle(SkPaint::kStroke_Style); | 213 paint.setStyle(SkPaint::kStroke_Style); |
197 paint.setColor(kBorderDarkColor); | 214 paint.setColor(kBorderDarkColor); |
198 canvas->DrawPath(path, paint); | 215 canvas->DrawPath(path, paint); |
199 | 216 |
200 } | 217 } |
201 | 218 |
219 private: | |
220 views::Background* FindAppropriateBackground(views::View* view, | |
221 const gfx::Point& point) const { | |
222 views::Background* background = NULL; | |
223 views::View* target = view->GetEventHandlerForPoint(point); | |
224 for (; target && !background; target = target->parent()) | |
225 background = target->background(); | |
226 return background; | |
227 } | |
228 | |
202 views::View* owner_; | 229 views::View* owner_; |
203 views::View* anchor_; | 230 views::View* anchor_; |
204 const int tray_arrow_offset_; | 231 const int tray_arrow_offset_; |
205 | 232 |
206 DISALLOW_COPY_AND_ASSIGN(TrayBubbleBorder); | 233 DISALLOW_COPY_AND_ASSIGN(TrayBubbleBorder); |
207 }; | 234 }; |
208 | 235 |
209 } // namespace | 236 } // namespace |
210 | 237 |
211 namespace internal { | 238 namespace internal { |
212 | 239 |
240 // static | |
241 const int TrayBubbleView::InitParams::kArrowDefaultOffset = -1; | |
242 | |
243 TrayBubbleView::InitParams::InitParams(AnchorType anchor_type, | |
244 ShelfAlignment shelf_alignment) | |
245 : anchor_type(anchor_type), | |
246 shelf_alignment(shelf_alignment), | |
247 bubble_width(kTrayPopupWidth), | |
248 max_height(0), | |
249 can_activate(false), | |
250 arrow_offset(kArrowDefaultOffset) { | |
251 } | |
252 | |
253 TrayBubbleView* TrayBubbleView::Create(views::View* anchor, | |
254 Host* host, | |
255 const InitParams& init_params) { | |
256 // Set arrow_location here so that it can be passed correctly to the | |
257 // BubbleView constructor. | |
258 views::BubbleBorder::ArrowLocation arrow_location; | |
259 if (init_params.anchor_type == ANCHOR_TYPE_TRAY) { | |
260 if (init_params.shelf_alignment == SHELF_ALIGNMENT_BOTTOM) { | |
261 arrow_location = base::i18n::IsRTL() ? | |
262 views::BubbleBorder::BOTTOM_LEFT : views::BubbleBorder::BOTTOM_RIGHT; | |
263 } else if (init_params.shelf_alignment == SHELF_ALIGNMENT_LEFT) { | |
264 arrow_location = views::BubbleBorder::LEFT_BOTTOM; | |
265 } else { | |
266 arrow_location = views::BubbleBorder::RIGHT_BOTTOM; | |
267 } | |
268 } else { | |
269 arrow_location = views::BubbleBorder::NONE; | |
270 } | |
271 | |
272 return new TrayBubbleView(init_params, arrow_location, anchor, host); | |
273 } | |
274 | |
213 TrayBubbleView::TrayBubbleView( | 275 TrayBubbleView::TrayBubbleView( |
276 const InitParams& init_params, | |
277 views::BubbleBorder::ArrowLocation arrow_location, | |
214 views::View* anchor, | 278 views::View* anchor, |
215 views::BubbleBorder::ArrowLocation arrow_location, | 279 Host* host) |
216 Host* host, | |
217 bool can_activate, | |
218 int bubble_width) | |
219 : views::BubbleDelegateView(anchor, arrow_location), | 280 : views::BubbleDelegateView(anchor, arrow_location), |
220 host_(host), | 281 params_(init_params), |
221 can_activate_(can_activate), | 282 host_(host) { |
222 max_height_(0), | |
223 bubble_width_(bubble_width) { | |
224 set_margins(gfx::Insets()); | 283 set_margins(gfx::Insets()); |
225 set_parent_window(Shell::GetContainer( | 284 set_parent_window(Shell::GetContainer( |
226 anchor->GetWidget()->GetNativeWindow()->GetRootWindow(), | 285 anchor->GetWidget()->GetNativeWindow()->GetRootWindow(), |
227 internal::kShellWindowId_SettingBubbleContainer)); | 286 internal::kShellWindowId_SettingBubbleContainer)); |
228 set_notify_enter_exit_on_child(true); | 287 set_notify_enter_exit_on_child(true); |
229 SetPaintToLayer(true); | 288 SetPaintToLayer(true); |
230 SetFillsBoundsOpaquely(true); | 289 SetFillsBoundsOpaquely(true); |
231 } | 290 } |
232 | 291 |
233 TrayBubbleView::~TrayBubbleView() { | 292 TrayBubbleView::~TrayBubbleView() { |
234 // Inform host items (models) that their views are being destroyed. | 293 // Inform host items (models) that their views are being destroyed. |
235 if (host_) | 294 if (host_) |
236 host_->BubbleViewDestroyed(); | 295 host_->BubbleViewDestroyed(); |
237 } | 296 } |
238 | 297 |
239 void TrayBubbleView::SetBubbleBorder(int arrow_offset) { | |
240 DCHECK(GetWidget()); | |
241 TrayBubbleBorder* bubble_border = new TrayBubbleBorder( | |
242 this, anchor_view(), arrow_location(), arrow_offset); | |
243 GetBubbleFrameView()->SetBubbleBorder(bubble_border); | |
244 // Recalculate size with new border. | |
245 SizeToContents(); | |
246 } | |
247 | |
248 void TrayBubbleView::UpdateAnchor() { | 298 void TrayBubbleView::UpdateAnchor() { |
249 SizeToContents(); | 299 SizeToContents(); |
250 GetWidget()->GetRootView()->SchedulePaint(); | 300 GetWidget()->GetRootView()->SchedulePaint(); |
251 } | 301 } |
252 | 302 |
253 void TrayBubbleView::SetMaxHeight(int height) { | 303 void TrayBubbleView::SetMaxHeight(int height) { |
254 max_height_ = height; | 304 params_.max_height = height; |
255 if (GetWidget()) | 305 if (GetWidget()) |
256 SizeToContents(); | 306 SizeToContents(); |
257 } | 307 } |
258 | 308 |
259 void TrayBubbleView::Init() { | 309 void TrayBubbleView::Init() { |
260 views::BoxLayout* layout = | 310 views::BoxLayout* layout = |
261 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0); | 311 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0); |
262 layout->set_spread_blank_space(true); | 312 layout->set_spread_blank_space(true); |
263 SetLayoutManager(layout); | 313 SetLayoutManager(layout); |
264 set_background(NULL); | 314 set_background(NULL); |
265 } | 315 } |
266 | 316 |
267 gfx::Rect TrayBubbleView::GetAnchorRect() { | 317 gfx::Rect TrayBubbleView::GetAnchorRect() { |
268 gfx::Rect rect; | 318 gfx::Rect rect; |
269 if (host_) | 319 |
270 rect = host_->GetAnchorRect(); | 320 if (anchor_widget()->IsVisible()) { |
321 rect = anchor_widget()->GetWindowBoundsInScreen(); | |
322 if (params_.anchor_type == ANCHOR_TYPE_TRAY) { | |
323 if (params_.shelf_alignment == SHELF_ALIGNMENT_BOTTOM) { | |
324 bool rtl = base::i18n::IsRTL(); | |
325 rect.Inset( | |
326 rtl ? kPaddingFromRightEdgeOfScreenBottomAlignment : 0, | |
327 0, | |
328 rtl ? 0 : kPaddingFromRightEdgeOfScreenBottomAlignment, | |
329 kPaddingFromBottomOfScreenBottomAlignment); | |
330 } else if (params_.shelf_alignment == SHELF_ALIGNMENT_LEFT) { | |
331 rect.Inset(0, 0, kPaddingFromInnerEdgeOfLauncherVerticalAlignment, | |
332 kPaddingFromBottomOfScreenVerticalAlignment); | |
333 } else { | |
334 rect.Inset(kPaddingFromInnerEdgeOfLauncherVerticalAlignment, | |
335 0, 0, kPaddingFromBottomOfScreenVerticalAlignment); | |
336 } | |
337 } else if (params_.anchor_type == ANCHOR_TYPE_BUBBLE) { | |
338 // Invert the offsets to align with the bubble below. | |
339 if (params_.shelf_alignment == SHELF_ALIGNMENT_LEFT) { | |
340 rect.Inset(kPaddingFromInnerEdgeOfLauncherVerticalAlignment, | |
341 0, 0, kPaddingFromBottomOfScreenVerticalAlignment); | |
342 } else if (params_.shelf_alignment == SHELF_ALIGNMENT_RIGHT) { | |
343 rect.Inset(0, 0, kPaddingFromInnerEdgeOfLauncherVerticalAlignment, | |
344 kPaddingFromBottomOfScreenVerticalAlignment); | |
345 } | |
346 } | |
347 } | |
348 | |
271 // TODO(jennyz): May need to add left/right alignment in the following code. | 349 // TODO(jennyz): May need to add left/right alignment in the following code. |
272 if (rect.IsEmpty()) { | 350 if (rect.IsEmpty()) { |
273 rect = gfx::Screen::GetPrimaryDisplay().bounds(); | 351 rect = gfx::Screen::GetPrimaryDisplay().bounds(); |
274 rect = gfx::Rect( | 352 rect = gfx::Rect( |
275 base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreenBottomAlignment : | 353 base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreenBottomAlignment : |
276 rect.width() - kPaddingFromRightEdgeOfScreenBottomAlignment, | 354 rect.width() - kPaddingFromRightEdgeOfScreenBottomAlignment, |
277 rect.height() - kPaddingFromBottomOfScreenBottomAlignment, | 355 rect.height() - kPaddingFromBottomOfScreenBottomAlignment, |
278 0, 0); | 356 0, 0); |
279 } | 357 } |
280 return rect; | 358 return rect; |
281 } | 359 } |
282 | 360 |
283 gfx::Rect TrayBubbleView::GetBubbleBounds() { | 361 gfx::Rect TrayBubbleView::GetBubbleBounds() { |
284 // Same as BubbleDelegateView implementation, but don't try mirroring. | 362 // Same as BubbleDelegateView implementation, but don't try mirroring. |
285 return GetBubbleFrameView()->GetUpdatedWindowBounds( | 363 return GetBubbleFrameView()->GetUpdatedWindowBounds( |
286 GetAnchorRect(), GetPreferredSize(), false /*try_mirroring_arrow*/); | 364 GetAnchorRect(), GetPreferredSize(), false /*try_mirroring_arrow*/); |
287 } | 365 } |
288 | 366 |
289 bool TrayBubbleView::CanActivate() const { | 367 bool TrayBubbleView::CanActivate() const { |
290 return can_activate_; | 368 return params_.can_activate; |
369 } | |
370 | |
371 // Overridden to create BubbleFrameView and set the border to TrayBubbleBorder | |
372 // (instead of creating a default BubbleBorder and replacing it). | |
373 views::NonClientFrameView* TrayBubbleView::CreateNonClientFrameView( | |
374 views::Widget* widget) { | |
375 views::BubbleFrameView* bubble_frame_view = | |
msw
2012/07/23 22:20:49
Instead of changing the BubbleFrameView constructi
stevenjb
2012/07/23 23:32:06
The problem was that first a BubbleBorder() was ge
msw
2012/07/24 00:32:44
Ah, that's fair. Consider passing a BubbleBorder i
stevenjb
2012/07/26 23:48:30
Done.
| |
376 new views::BubbleFrameView(margins()); | |
377 TrayBubbleBorder* bubble_border = new TrayBubbleBorder( | |
378 this, anchor_view(), arrow_location(), params_.arrow_offset); | |
379 bubble_frame_view->SetBubbleBorder(bubble_border); | |
380 return bubble_frame_view; | |
291 } | 381 } |
292 | 382 |
293 gfx::Size TrayBubbleView::GetPreferredSize() { | 383 gfx::Size TrayBubbleView::GetPreferredSize() { |
294 gfx::Size size = views::BubbleDelegateView::GetPreferredSize(); | 384 gfx::Size size = views::BubbleDelegateView::GetPreferredSize(); |
295 int height = size.height(); | 385 int height = size.height(); |
296 if (max_height_ != 0 && height > max_height_) | 386 if (params_.max_height != 0 && height > params_.max_height) |
297 height = max_height_; | 387 height = params_.max_height; |
298 return gfx::Size(bubble_width_, height); | 388 return gfx::Size(params_.bubble_width, height); |
299 } | 389 } |
300 | 390 |
301 void TrayBubbleView::OnMouseEntered(const views::MouseEvent& event) { | 391 void TrayBubbleView::OnMouseEntered(const views::MouseEvent& event) { |
302 if (host_) | 392 if (host_) |
303 host_->OnMouseEnteredView(); | 393 host_->OnMouseEnteredView(); |
304 } | 394 } |
305 | 395 |
306 void TrayBubbleView::OnMouseExited(const views::MouseEvent& event) { | 396 void TrayBubbleView::OnMouseExited(const views::MouseEvent& event) { |
307 if (host_) | 397 if (host_) |
308 host_->OnMouseExitedView(); | 398 host_->OnMouseExitedView(); |
309 } | 399 } |
310 | 400 |
311 void TrayBubbleView::GetAccessibleState(ui::AccessibleViewState* state) { | 401 void TrayBubbleView::GetAccessibleState(ui::AccessibleViewState* state) { |
312 if (can_activate_) { | 402 if (params_.can_activate) { |
313 state->role = ui::AccessibilityTypes::ROLE_WINDOW; | 403 state->role = ui::AccessibilityTypes::ROLE_WINDOW; |
314 state->name = l10n_util::GetStringUTF16( | 404 state->name = l10n_util::GetStringUTF16( |
315 IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME); | 405 IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME); |
316 } | 406 } |
317 } | 407 } |
318 | 408 |
319 void TrayBubbleView::ChildPreferredSizeChanged(View* child) { | 409 void TrayBubbleView::ChildPreferredSizeChanged(View* child) { |
320 SizeToContents(); | 410 SizeToContents(); |
321 } | 411 } |
322 | 412 |
(...skipping 10 matching lines...) Expand all Loading... | |
333 TrayBubbleView::Host::Host() | 423 TrayBubbleView::Host::Host() |
334 : widget_(NULL), | 424 : widget_(NULL), |
335 tray_view_(NULL) { | 425 tray_view_(NULL) { |
336 Shell::GetInstance()->AddEnvEventFilter(this); | 426 Shell::GetInstance()->AddEnvEventFilter(this); |
337 } | 427 } |
338 | 428 |
339 TrayBubbleView::Host::~Host() { | 429 TrayBubbleView::Host::~Host() { |
340 Shell::GetInstance()->RemoveEnvEventFilter(this); | 430 Shell::GetInstance()->RemoveEnvEventFilter(this); |
341 } | 431 } |
342 | 432 |
343 void TrayBubbleView::Host::InitializeHost(views::Widget* widget, | 433 void TrayBubbleView::Host::PostCreateBubble(views::Widget* widget, |
344 views::View* tray_view) { | 434 TrayBubbleView* bubble_view, |
435 views::View* tray_view) { | |
345 widget_ = widget; | 436 widget_ = widget; |
346 tray_view_ = tray_view; | 437 tray_view_ = tray_view; |
438 | |
439 // Must occur after call to BubbleDelegateView::CreateBubble(). | |
440 bubble_view->SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE); | |
441 | |
442 // Setup animation. | |
443 ash::SetWindowVisibilityAnimationType( | |
444 widget->GetNativeWindow(), | |
445 ash::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); | |
446 ash::SetWindowVisibilityAnimationTransition( | |
447 widget->GetNativeWindow(), | |
448 ash::ANIMATE_BOTH); | |
449 ash::SetWindowVisibilityAnimationDuration( | |
450 widget->GetNativeWindow(), | |
451 base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMS)); | |
347 } | 452 } |
348 | 453 |
349 bool TrayBubbleView::Host::PreHandleKeyEvent(aura::Window* target, | 454 bool TrayBubbleView::Host::PreHandleKeyEvent(aura::Window* target, |
350 aura::KeyEvent* event) { | 455 aura::KeyEvent* event) { |
351 return false; | 456 return false; |
352 } | 457 } |
353 | 458 |
354 bool TrayBubbleView::Host::PreHandleMouseEvent(aura::Window* target, | 459 bool TrayBubbleView::Host::PreHandleMouseEvent(aura::Window* target, |
355 aura::MouseEvent* event) { | 460 aura::MouseEvent* event) { |
356 if (event->type() == ui::ET_MOUSE_PRESSED) | 461 if (event->type() == ui::ET_MOUSE_PRESSED) |
(...skipping 30 matching lines...) Expand all Loading... | |
387 return; | 492 return; |
388 } | 493 } |
389 // Handle clicking outside the bubble and tray. We don't block the event, so | 494 // Handle clicking outside the bubble and tray. We don't block the event, so |
390 // it will also be handled by whatever widget was clicked on. | 495 // it will also be handled by whatever widget was clicked on. |
391 OnClickedOutsideView(); | 496 OnClickedOutsideView(); |
392 } | 497 } |
393 | 498 |
394 | 499 |
395 } // namespace internal | 500 } // namespace internal |
396 } // namespace ash | 501 } // namespace ash |
OLD | NEW |