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 20namespace ash { 21 22OverflowBubble::OverflowBubble() 23 : bubble_(NULL), 24 anchor_(NULL), 25 shelf_view_(NULL) { 26} 27 28OverflowBubble::~OverflowBubble() { 29 Hide(); 30} 31 32void 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 48void 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 60void 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 71void 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 83void OverflowBubble::OnMouseEvent(ui::MouseEvent* event) { 84 if (event->type() == ui::ET_MOUSE_PRESSED) 85 ProcessPressedEvent(event); 86} 87 88void OverflowBubble::OnTouchEvent(ui::TouchEvent* event) { 89 if (event->type() == ui::ET_TOUCH_PRESSED) 90 ProcessPressedEvent(event); 91} 92 93void 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