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

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

Issue 10381132: Allow Uber Tray popup pointing to the related tray item view. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase & offset position fix Created 8 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « ash/system/tray/system_tray.h ('k') | ash/system/tray/system_tray_bubble.h » ('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/system_tray.h" 5 #include "ash/system/tray/system_tray.h"
6 6
7 #include "ash/shell.h" 7 #include "ash/shell.h"
8 #include "ash/shell/panel_window.h" 8 #include "ash/shell/panel_window.h"
9 #include "ash/shell_window_ids.h" 9 #include "ash/shell_window_ids.h"
10 #include "ash/system/audio/tray_volume.h" 10 #include "ash/system/audio/tray_volume.h"
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 } 236 }
237 237
238 void SystemTray::AddTrayItem(SystemTrayItem* item) { 238 void SystemTray::AddTrayItem(SystemTrayItem* item) {
239 items_.push_back(item); 239 items_.push_back(item);
240 240
241 SystemTrayDelegate* delegate = Shell::GetInstance()->tray_delegate(); 241 SystemTrayDelegate* delegate = Shell::GetInstance()->tray_delegate();
242 views::View* tray_item = item->CreateTrayView(delegate->GetUserLoginStatus()); 242 views::View* tray_item = item->CreateTrayView(delegate->GetUserLoginStatus());
243 if (tray_item) { 243 if (tray_item) {
244 tray_container_->AddChildViewAt(tray_item, 0); 244 tray_container_->AddChildViewAt(tray_item, 0);
245 PreferredSizeChanged(); 245 PreferredSizeChanged();
246 tray_item_map_[item] = tray_item;
246 } 247 }
247 } 248 }
248 249
249 void SystemTray::RemoveTrayItem(SystemTrayItem* item) { 250 void SystemTray::RemoveTrayItem(SystemTrayItem* item) {
250 NOTIMPLEMENTED(); 251 NOTIMPLEMENTED();
251 } 252 }
252 253
253 void SystemTray::ShowDefaultView(BubbleCreationType creation_type) { 254 void SystemTray::ShowDefaultView(BubbleCreationType creation_type) {
254 ShowItems(items_.get(), false, true, creation_type); 255 ShowDefaultViewWithOffset(creation_type, -1);
255 } 256 }
256 257
257 void SystemTray::ShowDetailedView(SystemTrayItem* item, 258 void SystemTray::ShowDetailedView(SystemTrayItem* item,
258 int close_delay, 259 int close_delay,
259 bool activate, 260 bool activate,
260 BubbleCreationType creation_type) { 261 BubbleCreationType creation_type) {
261 std::vector<SystemTrayItem*> items; 262 std::vector<SystemTrayItem*> items;
262 items.push_back(item); 263 items.push_back(item);
263 ShowItems(items, true, activate, creation_type); 264 ShowItems(items, true, activate, creation_type, GetTrayXOffset(item));
264 bubble_->StartAutoCloseTimer(close_delay); 265 bubble_->StartAutoCloseTimer(close_delay);
265 } 266 }
266 267
267 void SystemTray::ShowNotificationView(SystemTrayItem* item) { 268 void SystemTray::ShowNotificationView(SystemTrayItem* item) {
268 if (std::find(notification_items_.begin(), notification_items_.end(), item) 269 if (std::find(notification_items_.begin(), notification_items_.end(), item)
269 != notification_items_.end()) 270 != notification_items_.end())
270 return; 271 return;
271 notification_items_.push_back(item); 272 notification_items_.push_back(item);
272 UpdateNotificationBubble(); 273 UpdateNotificationBubble();
273 } 274 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 NOTREACHED(); 329 NOTREACHED();
329 } 330 }
330 } 331 }
331 332
332 void SystemTray::SetPaintsBackground( 333 void SystemTray::SetPaintsBackground(
333 bool value, 334 bool value,
334 internal::BackgroundAnimator::ChangeType change_type) { 335 internal::BackgroundAnimator::ChangeType change_type) {
335 hide_background_animator_.SetPaintsBackground(value, change_type); 336 hide_background_animator_.SetPaintsBackground(value, change_type);
336 } 337 }
337 338
339 int SystemTray::GetTrayXOffset(SystemTrayItem* item) const {
340 std::map<SystemTrayItem*, views::View*>::const_iterator it =
341 tray_item_map_.find(item);
342 if (it == tray_item_map_.end())
343 return -1;
344
345 const views::View* item_view = it->second;
346 gfx::Rect item_bounds = item_view->bounds();
347 if (!item_bounds.IsEmpty()) {
348 int x_offset = item_bounds.x() + item_bounds.width() / 2;
349 return base::i18n::IsRTL() ? x_offset : tray_container_->width() - x_offset;
350 }
351
352 // The bounds of item could be still empty. It could happen in the case that
353 // the view appears for the first time in the current session, because the
354 // bounds is not calculated yet. In that case, we want to guess the offset
355 // from the position of its parent.
356 int x_offset = 0;
357 for (int i = 0; i < tray_container_->child_count(); ++i) {
358 const views::View* child = tray_container_->child_at(i);
359 if (child == item_view)
360 return base::i18n::IsRTL() ?
361 x_offset : tray_container_->width() - x_offset;
362
363 if (!child->visible())
364 continue;
365 x_offset = child->bounds().right();
366 }
367
368 return -1;
369 }
370
371 void SystemTray::ShowDefaultViewWithOffset(BubbleCreationType creation_type,
372 int arrow_offset) {
373 ShowItems(items_.get(), false, true, creation_type, arrow_offset);
374 }
375
338 void SystemTray::ShowItems(const std::vector<SystemTrayItem*>& items, 376 void SystemTray::ShowItems(const std::vector<SystemTrayItem*>& items,
339 bool detailed, 377 bool detailed,
340 bool can_activate, 378 bool can_activate,
341 BubbleCreationType creation_type) { 379 BubbleCreationType creation_type,
380 int arrow_offset) {
342 // Destroy any existing bubble and create a new one. 381 // Destroy any existing bubble and create a new one.
343 SystemTrayBubble::BubbleType bubble_type = detailed ? 382 SystemTrayBubble::BubbleType bubble_type = detailed ?
344 SystemTrayBubble::BUBBLE_TYPE_DETAILED : 383 SystemTrayBubble::BUBBLE_TYPE_DETAILED :
345 SystemTrayBubble::BUBBLE_TYPE_DEFAULT; 384 SystemTrayBubble::BUBBLE_TYPE_DEFAULT;
346 if (bubble_.get() && creation_type == BUBBLE_USE_EXISTING) { 385 if (bubble_.get() && creation_type == BUBBLE_USE_EXISTING) {
347 bubble_->UpdateView(items, bubble_type); 386 bubble_->UpdateView(items, bubble_type);
348 } else { 387 } else {
349 bubble_.reset(new SystemTrayBubble(this, items, bubble_type)); 388 bubble_.reset(new SystemTrayBubble(this, items, bubble_type));
350 ash::SystemTrayDelegate* delegate = 389 ash::SystemTrayDelegate* delegate =
351 ash::Shell::GetInstance()->tray_delegate(); 390 ash::Shell::GetInstance()->tray_delegate();
352 bubble_->InitView(tray_container_, SystemTrayBubble::ANCHOR_TYPE_TRAY, 391 views::View* anchor = tray_container_;
353 can_activate, delegate->GetUserLoginStatus()); 392 SystemTrayBubble::InitParams init_params(
393 SystemTrayBubble::ANCHOR_TYPE_TRAY);
394 init_params.anchor = anchor;
395 init_params.can_activate = can_activate;
396 init_params.login_status = delegate->GetUserLoginStatus();
397 if (arrow_offset >= 0)
398 init_params.arrow_offset = arrow_offset;
399 bubble_->InitView(init_params);
354 } 400 }
355 // If we have focus the shelf should be visible and we need to continue 401 // If we have focus the shelf should be visible and we need to continue
356 // showing the shelf when the popup is shown. 402 // showing the shelf when the popup is shown.
357 if (GetWidget()->IsActive()) 403 if (GetWidget()->IsActive())
358 should_show_launcher_ = true; 404 should_show_launcher_ = true;
359 UpdateNotificationBubble(); // State changed, re-create notifications. 405 UpdateNotificationBubble(); // State changed, re-create notifications.
360 } 406 }
361 407
362 void SystemTray::UpdateNotificationBubble() { 408 void SystemTray::UpdateNotificationBubble() {
363 // Only show the notification buble if we have notifications and we are not 409 // Only show the notification buble if we have notifications and we are not
364 // showing the default bubble. 410 // showing the default bubble.
365 if (notification_items_.empty() || 411 if (notification_items_.empty() ||
366 (bubble_.get() && 412 (bubble_.get() &&
367 bubble_->bubble_type() == SystemTrayBubble::BUBBLE_TYPE_DEFAULT)) { 413 bubble_->bubble_type() == SystemTrayBubble::BUBBLE_TYPE_DEFAULT)) {
368 notification_bubble_.reset(); 414 notification_bubble_.reset();
369 return; 415 return;
370 } 416 }
371 notification_bubble_.reset( 417 notification_bubble_.reset(
372 new SystemTrayBubble(this, notification_items_, 418 new SystemTrayBubble(this, notification_items_,
373 SystemTrayBubble::BUBBLE_TYPE_NOTIFICATION)); 419 SystemTrayBubble::BUBBLE_TYPE_NOTIFICATION));
374 views::View* anchor; 420 views::View* anchor;
375 SystemTrayBubble::AnchorType anchor_type; 421 SystemTrayBubble::AnchorType anchor_type;
376 if (bubble_.get()) { 422 if (bubble_.get()) {
377 anchor = bubble_->bubble_view(); 423 anchor = bubble_->bubble_view();
378 anchor_type = SystemTrayBubble::ANCHOR_TYPE_BUBBLE; 424 anchor_type = SystemTrayBubble::ANCHOR_TYPE_BUBBLE;
379 } else { 425 } else {
380 anchor = tray_container_; 426 anchor = tray_container_;
381 anchor_type = SystemTrayBubble::ANCHOR_TYPE_TRAY; 427 anchor_type = SystemTrayBubble::ANCHOR_TYPE_TRAY;
382 } 428 }
383 notification_bubble_->InitView( 429 SystemTrayBubble::InitParams init_params(anchor_type);
384 anchor, anchor_type, 430 init_params.anchor = anchor;
385 false /* can_activate */, 431 init_params.login_status =
386 ash::Shell::GetInstance()->tray_delegate()->GetUserLoginStatus()); 432 ash::Shell::GetInstance()->tray_delegate()->GetUserLoginStatus();
433 int arrow_offset = GetTrayXOffset(notification_items_[0]);
434 if (arrow_offset >= 0)
435 init_params.arrow_offset = arrow_offset;
436 notification_bubble_->InitView(init_params);
387 } 437 }
388 438
389 void SystemTray::UpdateNotificationAnchor() { 439 void SystemTray::UpdateNotificationAnchor() {
390 if (!notification_bubble_.get()) 440 if (!notification_bubble_.get())
391 return; 441 return;
392 notification_bubble_->bubble_view()->UpdateAnchor(); 442 notification_bubble_->bubble_view()->UpdateAnchor();
393 // Ensure that the notification buble is above the launcher/status area. 443 // Ensure that the notification buble is above the launcher/status area.
394 notification_bubble_->bubble_view()->GetWidget()->StackAtTop(); 444 notification_bubble_->bubble_view()->GetWidget()->StackAtTop();
395 } 445 }
396 446
397 bool SystemTray::PerformAction(const views::Event& event) { 447 bool SystemTray::PerformAction(const views::Event& event) {
398 // If we're already showing the default view, hide it; otherwise, show it 448 // If we're already showing the default view, hide it; otherwise, show it
399 // (and hide any popup that's currently shown). 449 // (and hide any popup that's currently shown).
400 if (bubble_.get() && 450 if (bubble_.get() &&
401 bubble_->bubble_type() == SystemTrayBubble::BUBBLE_TYPE_DEFAULT) { 451 bubble_->bubble_type() == SystemTrayBubble::BUBBLE_TYPE_DEFAULT) {
402 bubble_->Close(); 452 bubble_->Close();
403 } else { 453 } else {
404 ShowDefaultView(BUBBLE_CREATE_NEW); 454 int arrow_offset = -1;
455 if (event.IsMouseEvent() || event.IsTouchEvent()) {
456 const views::LocatedEvent& located_event =
457 static_cast<const views::LocatedEvent&>(event);
458 arrow_offset = base::i18n::IsRTL() ?
459 located_event.x() : tray_container_->width() - located_event.x();
460 }
461 ShowDefaultViewWithOffset(BUBBLE_CREATE_NEW, arrow_offset);
405 } 462 }
406 return true; 463 return true;
407 } 464 }
408 465
409 void SystemTray::OnMouseEntered(const views::MouseEvent& event) { 466 void SystemTray::OnMouseEntered(const views::MouseEvent& event) {
410 should_show_launcher_ = true; 467 should_show_launcher_ = true;
411 hover_background_animator_.SetPaintsBackground(true, 468 hover_background_animator_.SetPaintsBackground(true,
412 internal::BackgroundAnimator::CHANGE_ANIMATE); 469 internal::BackgroundAnimator::CHANGE_ANIMATE);
413 } 470 }
414 471
(...skipping 25 matching lines...) Expand all
440 canvas->DrawFocusRect(tray_container_->bounds()); 497 canvas->DrawFocusRect(tray_container_->bounds());
441 } 498 }
442 499
443 void SystemTray::UpdateBackground(int alpha) { 500 void SystemTray::UpdateBackground(int alpha) {
444 background_->set_alpha(hide_background_animator_.alpha() + 501 background_->set_alpha(hide_background_animator_.alpha() +
445 hover_background_animator_.alpha()); 502 hover_background_animator_.alpha());
446 SchedulePaint(); 503 SchedulePaint();
447 } 504 }
448 505
449 } // namespace ash 506 } // namespace ash
OLDNEW
« no previous file with comments | « ash/system/tray/system_tray.h ('k') | ash/system/tray/system_tray_bubble.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698