Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(136)

Side by Side Diff: ash/system/tray/tray_bubble_view.cc

Issue 10808066: Fix position of web notification bubble and arrow (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Rebase Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ash/system/tray/tray_bubble_view.h ('k') | ash/system/tray_accessibility.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 = 9; 37 const int kArrowHeight = 9;
37 const int kArrowWidth = 19; 38 const int kArrowWidth = 19;
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 11 matching lines...) Expand all
65 paint.setImageFilter(new SkBlurImageFilter( 69 paint.setImageFilter(new SkBlurImageFilter(
66 SkIntToScalar(3), SkIntToScalar(3)))->unref(); 70 SkIntToScalar(3), SkIntToScalar(3)))->unref();
67 canvas->sk_canvas()->drawPath(path, paint); 71 canvas->sk_canvas()->drawPath(path, paint);
68 } 72 }
69 73
70 class TrayBubbleBorder : public views::BubbleBorder { 74 class TrayBubbleBorder : public views::BubbleBorder {
71 public: 75 public:
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 const SkColor& arrow_color)
77 views::BubbleBorder::NO_SHADOW), 81 : views::BubbleBorder(arrow_location, 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 set_background_color(arrow_color);
82 } 87 }
83 88
84 virtual ~TrayBubbleBorder() {} 89 virtual ~TrayBubbleBorder() {}
85 90
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. 91 // Overridden from views::BubbleBorder.
97 // Override views::BubbleBorder to set the bubble on top of the anchor when 92 // Override views::BubbleBorder to set the bubble on top of the anchor when
98 // it has no arrow. 93 // it has no arrow.
99 virtual gfx::Rect GetBounds(const gfx::Rect& position_relative_to, 94 virtual gfx::Rect GetBounds(const gfx::Rect& position_relative_to,
100 const gfx::Size& contents_size) const OVERRIDE { 95 const gfx::Size& contents_size) const OVERRIDE {
101 if (arrow_location() != NONE) { 96 if (arrow_location() != NONE) {
102 return views::BubbleBorder::GetBounds(position_relative_to, 97 return views::BubbleBorder::GetBounds(position_relative_to,
103 contents_size); 98 contents_size);
104 } 99 }
105 100
106 gfx::Size border_size(contents_size); 101 gfx::Size border_size(contents_size);
107 gfx::Insets insets; 102 gfx::Insets insets;
108 GetInsets(&insets); 103 GetInsets(&insets);
109 border_size.Enlarge(insets.width(), insets.height()); 104 border_size.Enlarge(insets.width(), insets.height());
110 105
111 const int kArrowOverlap = 3; 106 const int kArrowOverlap = 3;
112 int x = position_relative_to.x() + 107 int x = position_relative_to.x() +
113 position_relative_to.width() / 2 - border_size.width() / 2; 108 position_relative_to.width() / 2 - border_size.width() / 2;
114 // Position the bubble on top of the anchor. 109 // Position the bubble on top of the anchor.
115 int y = position_relative_to.y() + 110 int y = position_relative_to.y() +
116 kArrowOverlap - border_size.height(); 111 kArrowOverlap - border_size.height();
117 return gfx::Rect(x, y, border_size.width(), border_size.height()); 112 return gfx::Rect(x, y, border_size.width(), border_size.height());
118 } 113 }
119 114
115 // TrayBubbleView supports dynamically updated bubbles. This does not
116 // behave well with BubbleFrameView which expects arrow_location to be
117 // unmirrored during initial layout (when ClientView is constructed),
118 // then mirrored after SizeToContents() gets called.
119 // So, instead of mirroring the arrow in CreateNonClientFrameView,
120 // mirror it here instead.
121 // TODO(stevenjb): Fix this in ui/views/bubble: crbug.com/139813
122 virtual void GetInsets(gfx::Insets* insets) const OVERRIDE {
123 ArrowLocation arrow_loc = arrow_location();
124 if (base::i18n::IsRTL())
125 arrow_loc = horizontal_mirror(arrow_loc);
126 return GetInsetsForArrowLocation(insets, arrow_loc);
127 }
128
120 // Overridden from views::Border. 129 // Overridden from views::Border.
121 virtual void Paint(const views::View& view, 130 virtual void Paint(const views::View& view,
122 gfx::Canvas* canvas) const OVERRIDE { 131 gfx::Canvas* canvas) const OVERRIDE {
123 gfx::Insets inset; 132 gfx::Insets inset;
124 GetInsets(&inset); 133 // Get the unmirrored insets for the arrow location; the tray bubbles are
134 // never mirrored for RTL (since that would put them off screen).
135 GetInsetsForArrowLocation(&inset, arrow_location());
125 DrawBlurredShadowAroundView( 136 DrawBlurredShadowAroundView(
126 canvas, 0, owner_->height(), owner_->width(), inset); 137 canvas, 0, owner_->height(), owner_->width(), inset);
127 138
128 // Draw the bottom line. 139 // Draw the bottom line.
129 int y = owner_->height() + inset.top(); 140 int y = owner_->height() + inset.top();
130 canvas->FillRect(gfx::Rect(inset.left(), y, owner_->width(), 141 canvas->FillRect(gfx::Rect(inset.left(), y, owner_->width(),
131 kBottomLineHeight), kBorderDarkColor); 142 kBottomLineHeight), kBorderDarkColor);
132 143
133 if (!Shell::GetInstance()->shelf()->IsVisible() || 144 if (!Shell::GetInstance()->shelf()->IsVisible() ||
134 arrow_location() == views::BubbleBorder::NONE) 145 arrow_location() == views::BubbleBorder::NONE)
135 return; 146 return;
136 147
137 gfx::Point arrow_reference; 148 gfx::Point arrow_reference;
138 149
139 // Draw the arrow after drawing child borders, so that the arrow can cover 150 // Draw the arrow after drawing child borders, so that the arrow can cover
140 // the its overlap section with child border. 151 // its overlap section with child border.
141 SkPath path; 152 SkPath path;
142 path.incReserve(4); 153 path.incReserve(4);
143 if (arrow_location() == views::BubbleBorder::BOTTOM_RIGHT || 154 if (arrow_location() == views::BubbleBorder::BOTTOM_RIGHT ||
144 arrow_location() == views::BubbleBorder::BOTTOM_LEFT) { 155 arrow_location() == views::BubbleBorder::BOTTOM_LEFT) {
145 // Do not let the arrow too close to the edge of the bubble and 156 // Note: tray_arrow_offset_ is relative to the anchor widget.
146 // and the edge of the anchor. 157 int tip_x;
147 int tip_x = base::i18n::IsRTL() ? 158 if (tray_arrow_offset_ ==
148 std::min(std::max(tray_arrow_offset_, kArrowMinOffset), 159 internal::TrayBubbleView::InitParams::kArrowDefaultOffset) {
149 std::min(owner_->width(), anchor_->width()) 160 if (arrow_location() == views::BubbleBorder::BOTTOM_LEFT)
150 - kArrowMinOffset) : 161 tip_x = kArrowMinOffset;
151 std::min(std::max(owner_->width() - tray_arrow_offset_, 162 else
152 owner_->width() - 163 tip_x = owner_->width() - kArrowMinOffset;
153 std::min(owner_->width(), anchor_->width()) + 164 } else {
154 kArrowMinOffset), 165 gfx::Point pt(tray_arrow_offset_, 0);
155 owner_->width() - kArrowMinOffset); 166 views::View::ConvertPointToScreen(
167 anchor_->GetWidget()->GetRootView(), &pt);
168 views::View::ConvertPointFromScreen(
169 owner_->GetWidget()->GetRootView(), &pt);
170 tip_x = std::min(pt.x(), owner_->width() - kArrowMinOffset);
171 tip_x = std::max(tip_x, kArrowMinOffset);
172 }
156 int left_base_x = tip_x - kArrowWidth / 2; 173 int left_base_x = tip_x - kArrowWidth / 2;
157 int left_base_y = y; 174 int left_base_y = y;
158 int tip_y = left_base_y + kArrowHeight; 175 int tip_y = left_base_y + kArrowHeight;
159 path.moveTo(SkIntToScalar(left_base_x), SkIntToScalar(left_base_y)); 176 path.moveTo(SkIntToScalar(left_base_x), SkIntToScalar(left_base_y));
160 path.lineTo(SkIntToScalar(tip_x), SkIntToScalar(tip_y)); 177 path.lineTo(SkIntToScalar(tip_x), SkIntToScalar(tip_y));
161 path.lineTo(SkIntToScalar(left_base_x + kArrowWidth), 178 path.lineTo(SkIntToScalar(left_base_x + kArrowWidth),
162 SkIntToScalar(left_base_y)); 179 SkIntToScalar(left_base_y));
163 arrow_reference.SetPoint(tip_x, left_base_y - kArrowHeight); 180 arrow_reference.SetPoint(tip_x, left_base_y - kArrowHeight);
164 } else { 181 } else {
165 int tip_y = y - tray_arrow_offset_; 182 int tip_y;
166 tip_y = std::min(std::max(kArrowMinOffset, tip_y), 183 if (tray_arrow_offset_ ==
167 owner_->height() - kArrowMinOffset); 184 internal::TrayBubbleView::InitParams::kArrowDefaultOffset) {
185 tip_y = owner_->height() - kArrowMinOffset;
186 } else {
187 int pty = y - tray_arrow_offset_;
188 gfx::Point pt(0, pty);
189 views::View::ConvertPointToScreen(
190 anchor_->GetWidget()->GetRootView(), &pt);
191 views::View::ConvertPointFromScreen(
192 owner_->GetWidget()->GetRootView(), &pt);
193 tip_y = std::min(pt.y(), owner_->height() - kArrowMinOffset);
194 tip_y = std::max(tip_y, kArrowMinOffset);
195 }
168 int top_base_y = tip_y - kArrowWidth / 2; 196 int top_base_y = tip_y - kArrowWidth / 2;
169 int top_base_x, tip_x; 197 int top_base_x, tip_x;
170 if (arrow_location() == views::BubbleBorder::LEFT_BOTTOM) { 198 if (arrow_location() == views::BubbleBorder::LEFT_BOTTOM) {
171 top_base_x = inset.left() + kSystemTrayBubbleHorizontalInset; 199 top_base_x = inset.left() + kSystemTrayBubbleHorizontalInset;
172 tip_x = top_base_x - kArrowHeight; 200 tip_x = top_base_x - kArrowHeight;
173 arrow_reference.SetPoint(top_base_x + kArrowHeight, tip_y); 201 arrow_reference.SetPoint(top_base_x + kArrowHeight, tip_y);
174 } else { 202 } else {
175 DCHECK(arrow_location() == views::BubbleBorder::RIGHT_BOTTOM); 203 DCHECK(arrow_location() == views::BubbleBorder::RIGHT_BOTTOM);
176 top_base_x = inset.left() + owner_->width() - 204 top_base_x = inset.left() + owner_->width() -
177 kSystemTrayBubbleHorizontalInset; 205 kSystemTrayBubbleHorizontalInset;
178 tip_x = top_base_x + kArrowHeight; 206 tip_x = top_base_x + kArrowHeight;
179 arrow_reference.SetPoint(top_base_x - kArrowHeight, tip_y); 207 arrow_reference.SetPoint(top_base_x - kArrowHeight, tip_y);
180 } 208 }
181 path.moveTo(SkIntToScalar(top_base_x), SkIntToScalar(top_base_y)); 209 path.moveTo(SkIntToScalar(top_base_x), SkIntToScalar(top_base_y));
182 path.lineTo(SkIntToScalar(tip_x), SkIntToScalar(tip_y)); 210 path.lineTo(SkIntToScalar(tip_x), SkIntToScalar(tip_y));
183 path.lineTo(SkIntToScalar(top_base_x), 211 path.lineTo(SkIntToScalar(top_base_x),
184 SkIntToScalar(top_base_y + kArrowWidth)); 212 SkIntToScalar(top_base_y + kArrowWidth));
185 } 213 }
186 214
187 views::Background* background = FindAppropriateBackground(owner_,
188 arrow_reference);
189
190 SkPaint paint; 215 SkPaint paint;
191 paint.setAntiAlias(true); 216 paint.setAntiAlias(true);
192 paint.setStyle(SkPaint::kFill_Style); 217 paint.setStyle(SkPaint::kFill_Style);
193 paint.setColor(background ? background->get_color() : kBackgroundColor); 218 paint.setColor(background_color());
194 canvas->DrawPath(path, paint); 219 canvas->DrawPath(path, paint);
195 220
196 // Now draw the arrow border. 221 // Now draw the arrow border.
197 paint.setStyle(SkPaint::kStroke_Style); 222 paint.setStyle(SkPaint::kStroke_Style);
198 paint.setColor(kBorderDarkColor); 223 paint.setColor(kBorderDarkColor);
199 canvas->DrawPath(path, paint); 224 canvas->DrawPath(path, paint);
200 225
201 } 226 }
202 227
203 views::View* owner_; 228 views::View* owner_;
204 views::View* anchor_; 229 views::View* anchor_;
205 const int tray_arrow_offset_; 230 const int tray_arrow_offset_;
206 231
207 DISALLOW_COPY_AND_ASSIGN(TrayBubbleBorder); 232 DISALLOW_COPY_AND_ASSIGN(TrayBubbleBorder);
208 }; 233 };
209 234
210 } // namespace 235 } // namespace
211 236
212 namespace internal { 237 namespace internal {
213 238
239 // static
240 const int TrayBubbleView::InitParams::kArrowDefaultOffset = -1;
241
242 TrayBubbleView::InitParams::InitParams(AnchorType anchor_type,
243 ShelfAlignment shelf_alignment)
244 : anchor_type(anchor_type),
245 shelf_alignment(shelf_alignment),
246 bubble_width(kTrayPopupWidth),
247 max_height(0),
248 can_activate(false),
249 arrow_offset(kArrowDefaultOffset),
250 arrow_color(kHeaderBackgroundColorDark) {
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
214 TrayBubbleView::TrayBubbleView( 275 TrayBubbleView::TrayBubbleView(
276 const InitParams& init_params,
277 views::BubbleBorder::ArrowLocation arrow_location,
215 views::View* anchor, 278 views::View* anchor,
216 views::BubbleBorder::ArrowLocation arrow_location, 279 Host* host)
217 Host* host,
218 bool can_activate,
219 int bubble_width)
220 : views::BubbleDelegateView(anchor, arrow_location), 280 : views::BubbleDelegateView(anchor, arrow_location),
221 host_(host), 281 params_(init_params),
222 can_activate_(can_activate), 282 host_(host) {
223 max_height_(0),
224 bubble_width_(bubble_width) {
225 set_margins(gfx::Insets()); 283 set_margins(gfx::Insets());
226 set_parent_window(Shell::GetContainer( 284 set_parent_window(Shell::GetContainer(
227 anchor->GetWidget()->GetNativeWindow()->GetRootWindow(), 285 anchor->GetWidget()->GetNativeWindow()->GetRootWindow(),
228 internal::kShellWindowId_SettingBubbleContainer)); 286 internal::kShellWindowId_SettingBubbleContainer));
229 set_notify_enter_exit_on_child(true); 287 set_notify_enter_exit_on_child(true);
230 SetPaintToLayer(true); 288 SetPaintToLayer(true);
231 SetFillsBoundsOpaquely(true); 289 SetFillsBoundsOpaquely(true);
232 } 290 }
233 291
234 TrayBubbleView::~TrayBubbleView() { 292 TrayBubbleView::~TrayBubbleView() {
235 // Inform host items (models) that their views are being destroyed. 293 // Inform host items (models) that their views are being destroyed.
236 if (host_) 294 if (host_)
237 host_->BubbleViewDestroyed(); 295 host_->BubbleViewDestroyed();
238 } 296 }
239 297
240 void TrayBubbleView::SetBubbleBorder(int arrow_offset) {
241 DCHECK(GetWidget());
242 TrayBubbleBorder* bubble_border = new TrayBubbleBorder(
243 this, anchor_view(), arrow_location(), arrow_offset);
244 GetBubbleFrameView()->SetBubbleBorder(bubble_border);
245 // Recalculate size with new border.
246 SizeToContents();
247 }
248
249 void TrayBubbleView::UpdateBubble() { 298 void TrayBubbleView::UpdateBubble() {
250 SizeToContents(); 299 SizeToContents();
251 GetWidget()->GetRootView()->SchedulePaint(); 300 GetWidget()->GetRootView()->SchedulePaint();
252 } 301 }
253 302
254 void TrayBubbleView::SetMaxHeight(int height) { 303 void TrayBubbleView::SetMaxHeight(int height) {
255 max_height_ = height; 304 params_.max_height = height;
256 if (GetWidget()) 305 if (GetWidget())
257 SizeToContents(); 306 SizeToContents();
258 } 307 }
259 308
260 void TrayBubbleView::Init() { 309 void TrayBubbleView::Init() {
261 views::BoxLayout* layout = 310 views::BoxLayout* layout =
262 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0); 311 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0);
263 layout->set_spread_blank_space(true); 312 layout->set_spread_blank_space(true);
264 SetLayoutManager(layout); 313 SetLayoutManager(layout);
265 set_background(NULL); 314 set_background(NULL);
266 } 315 }
267 316
268 gfx::Rect TrayBubbleView::GetAnchorRect() { 317 gfx::Rect TrayBubbleView::GetAnchorRect() {
269 gfx::Rect rect; 318 gfx::Rect rect;
270 if (host_) 319
271 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
272 // 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.
273 if (rect.IsEmpty()) { 350 if (rect.IsEmpty()) {
274 rect = gfx::Screen::GetPrimaryDisplay().bounds(); 351 rect = gfx::Screen::GetPrimaryDisplay().bounds();
275 rect = gfx::Rect( 352 rect = gfx::Rect(
276 base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreenBottomAlignment : 353 base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreenBottomAlignment :
277 rect.width() - kPaddingFromRightEdgeOfScreenBottomAlignment, 354 rect.width() - kPaddingFromRightEdgeOfScreenBottomAlignment,
278 rect.height() - kPaddingFromBottomOfScreenBottomAlignment, 355 rect.height() - kPaddingFromBottomOfScreenBottomAlignment,
279 0, 0); 356 0, 0);
280 } 357 }
281 return rect; 358 return rect;
282 } 359 }
283 360
284 gfx::Rect TrayBubbleView::GetBubbleBounds() { 361 gfx::Rect TrayBubbleView::GetBubbleBounds() {
285 // Same as BubbleDelegateView implementation, but don't try mirroring. 362 // Same as BubbleDelegateView implementation, but don't try mirroring.
286 return GetBubbleFrameView()->GetUpdatedWindowBounds( 363 return GetBubbleFrameView()->GetUpdatedWindowBounds(
287 GetAnchorRect(), GetPreferredSize(), false /*try_mirroring_arrow*/); 364 GetAnchorRect(), GetPreferredSize(), false /*try_mirroring_arrow*/);
288 } 365 }
289 366
290 bool TrayBubbleView::CanActivate() const { 367 bool TrayBubbleView::CanActivate() const {
291 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 TrayBubbleBorder* bubble_border = new TrayBubbleBorder(
376 this, anchor_view(),
377 arrow_location(), params_.arrow_offset, params_.arrow_color);
378 return new views::BubbleFrameView(margins(), bubble_border);
292 } 379 }
293 380
294 gfx::Size TrayBubbleView::GetPreferredSize() { 381 gfx::Size TrayBubbleView::GetPreferredSize() {
295 gfx::Size size = views::BubbleDelegateView::GetPreferredSize(); 382 gfx::Size size = views::BubbleDelegateView::GetPreferredSize();
296 int height = size.height(); 383 int height = size.height();
297 if (max_height_ != 0 && height > max_height_) 384 if (params_.max_height != 0 && height > params_.max_height)
298 height = max_height_; 385 height = params_.max_height;
299 return gfx::Size(bubble_width_, height); 386 return gfx::Size(params_.bubble_width, height);
300 } 387 }
301 388
302 void TrayBubbleView::OnMouseEntered(const views::MouseEvent& event) { 389 void TrayBubbleView::OnMouseEntered(const views::MouseEvent& event) {
303 if (host_) 390 if (host_)
304 host_->OnMouseEnteredView(); 391 host_->OnMouseEnteredView();
305 } 392 }
306 393
307 void TrayBubbleView::OnMouseExited(const views::MouseEvent& event) { 394 void TrayBubbleView::OnMouseExited(const views::MouseEvent& event) {
308 if (host_) 395 if (host_)
309 host_->OnMouseExitedView(); 396 host_->OnMouseExitedView();
310 } 397 }
311 398
312 void TrayBubbleView::GetAccessibleState(ui::AccessibleViewState* state) { 399 void TrayBubbleView::GetAccessibleState(ui::AccessibleViewState* state) {
313 if (can_activate_) { 400 if (params_.can_activate) {
314 state->role = ui::AccessibilityTypes::ROLE_WINDOW; 401 state->role = ui::AccessibilityTypes::ROLE_WINDOW;
315 state->name = l10n_util::GetStringUTF16( 402 state->name = l10n_util::GetStringUTF16(
316 IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME); 403 IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME);
317 } 404 }
318 } 405 }
319 406
320 void TrayBubbleView::ChildPreferredSizeChanged(View* child) { 407 void TrayBubbleView::ChildPreferredSizeChanged(View* child) {
321 SizeToContents(); 408 SizeToContents();
322 } 409 }
323 410
(...skipping 10 matching lines...) Expand all
334 TrayBubbleView::Host::Host() 421 TrayBubbleView::Host::Host()
335 : widget_(NULL), 422 : widget_(NULL),
336 tray_view_(NULL) { 423 tray_view_(NULL) {
337 Shell::GetInstance()->AddEnvEventFilter(this); 424 Shell::GetInstance()->AddEnvEventFilter(this);
338 } 425 }
339 426
340 TrayBubbleView::Host::~Host() { 427 TrayBubbleView::Host::~Host() {
341 Shell::GetInstance()->RemoveEnvEventFilter(this); 428 Shell::GetInstance()->RemoveEnvEventFilter(this);
342 } 429 }
343 430
344 void TrayBubbleView::Host::InitializeHost(views::Widget* widget, 431 void TrayBubbleView::Host::InitializeAndShowBubble(views::Widget* widget,
345 views::View* tray_view) { 432 TrayBubbleView* bubble_view,
433 views::View* tray_view) {
346 widget_ = widget; 434 widget_ = widget;
347 tray_view_ = tray_view; 435 tray_view_ = tray_view;
436
437 // Must occur after call to BubbleDelegateView::CreateBubble().
438 bubble_view->SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE);
439
440 // Setup animation.
441 ash::SetWindowVisibilityAnimationType(
442 widget->GetNativeWindow(),
443 ash::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
444 ash::SetWindowVisibilityAnimationTransition(
445 widget->GetNativeWindow(),
446 ash::ANIMATE_BOTH);
447 ash::SetWindowVisibilityAnimationDuration(
448 widget->GetNativeWindow(),
449 base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMS));
450
451 bubble_view->Show();
452 bubble_view->UpdateBubble();
348 } 453 }
349 454
350 bool TrayBubbleView::Host::PreHandleKeyEvent(aura::Window* target, 455 bool TrayBubbleView::Host::PreHandleKeyEvent(aura::Window* target,
351 aura::KeyEvent* event) { 456 aura::KeyEvent* event) {
352 return false; 457 return false;
353 } 458 }
354 459
355 bool TrayBubbleView::Host::PreHandleMouseEvent(aura::Window* target, 460 bool TrayBubbleView::Host::PreHandleMouseEvent(aura::Window* target,
356 aura::MouseEvent* event) { 461 aura::MouseEvent* event) {
357 if (event->type() == ui::ET_MOUSE_PRESSED) 462 if (event->type() == ui::ET_MOUSE_PRESSED)
(...skipping 30 matching lines...) Expand all
388 return; 493 return;
389 } 494 }
390 // Handle clicking outside the bubble and tray. We don't block the event, so 495 // Handle clicking outside the bubble and tray. We don't block the event, so
391 // it will also be handled by whatever widget was clicked on. 496 // it will also be handled by whatever widget was clicked on.
392 OnClickedOutsideView(); 497 OnClickedOutsideView();
393 } 498 }
394 499
395 500
396 } // namespace internal 501 } // namespace internal
397 } // namespace ash 502 } // namespace ash
OLDNEW
« no previous file with comments | « ash/system/tray/tray_bubble_view.h ('k') | ash/system/tray_accessibility.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698