1 // Copyright 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/shelf/overflow_bubble.h" 6 7 #include "ash/root_window_controller.h" 8 #include "ash/shelf/overflow_bubble_view.h" 9 #include "ash/shelf/shelf_layout_manager.h" 10 #include "ash/shelf/shelf_view.h" 11 #include "ash/shelf/shelf_widget.h" 12 #include "ash/shell.h" 13 #include "ash/system/tray/system_tray.h" 14 #include "ui/aura/client/screen_position_client.h" 15 #include "ui/aura/window_event_dispatcher.h" 16 #include "ui/events/event.h" 17 #include "ui/gfx/screen.h" 18 #include "ui/views/widget/widget.h" 19 20 namespace ash { 21 22 OverflowBubble::OverflowBubble() 23 : bubble_(NULL), 24 anchor_(NULL), 25 shelf_view_(NULL) { 26 } 27 28 OverflowBubble::~OverflowBubble() { 29 Hide(); 30 } 31 32 void OverflowBubble::Show(views::View* anchor, ShelfView* shelf_view) { 33 Hide(); 34 35 bubble_ = new OverflowBubbleView(); 36 bubble_->InitOverflowBubble(anchor, shelf_view); 37 shelf_view_ = shelf_view; 38 anchor_ = anchor; 39 40 Shell::GetInstance()->AddPreTargetHandler(this); 41 42 RootWindowController::ForWindow(anchor->GetWidget()->GetNativeView())-> 43 GetSystemTray()->InitializeBubbleAnimations(bubble_->GetWidget()); 44 bubble_->GetWidget()->AddObserver(this); 45 bubble_->GetWidget()->Show(); 46 } 47 48 void OverflowBubble::Hide() { 49 if (!IsShowing()) 50 return; 51 52 Shell::GetInstance()->RemovePreTargetHandler(this); 53 bubble_->GetWidget()->RemoveObserver(this); 54 bubble_->GetWidget()->Close(); 55 bubble_ = NULL; 56 anchor_ = NULL; 57 shelf_view_ = NULL; 58 } 59 60 void OverflowBubble::HideBubbleAndRefreshButton() { 61 if (!IsShowing()) 62 return; 63 64 views::View* anchor = anchor_; 65 Hide(); 66 // Update overflow button (|anchor|) status when overflow bubble is hidden 67 // by outside event of overflow button. 68 anchor->SchedulePaint(); 69 } 70 71 void OverflowBubble::ProcessPressedEvent(ui::LocatedEvent* event) { 72 aura::Window* target = static_cast<aura::Window*>(event->target()); 73 gfx::Point event_location_in_screen = event->location(); 74 aura::client::GetScreenPositionClient(target->GetRootWindow())-> 75 ConvertPointToScreen(target, &event_location_in_screen); 76 if (!shelf_view_->IsShowingMenu() && 77 !bubble_->GetBoundsInScreen().Contains(event_location_in_screen) && 78 !anchor_->GetBoundsInScreen().Contains(event_location_in_screen)) { 79 HideBubbleAndRefreshButton(); 80 } 81 } 82 83 void OverflowBubble::OnMouseEvent(ui::MouseEvent* event) { 84 if (event->type() == ui::ET_MOUSE_PRESSED) 85 ProcessPressedEvent(event); 86 } 87 88 void OverflowBubble::OnTouchEvent(ui::TouchEvent* event) { 89 if (event->type() == ui::ET_TOUCH_PRESSED) 90 ProcessPressedEvent(event); 91 } 92 93 void OverflowBubble::OnWidgetDestroying(views::Widget* widget) { 94 DCHECK(widget == bubble_->GetWidget()); 95 bubble_ = NULL; 96 anchor_ = NULL; 97 shelf_view_ = NULL; 98 ShelfLayoutManager::ForShelf( 99 widget->GetNativeView())->shelf_widget()->shelf()->SchedulePaint(); 100 } 101 102 } // namespace ash 103