// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ash/shelf/overflow_bubble.h" #include "ash/root_window_controller.h" #include "ash/shelf/overflow_bubble_view.h" #include "ash/shelf/shelf_layout_manager.h" #include "ash/shelf/shelf_view.h" #include "ash/shelf/shelf_widget.h" #include "ash/shell.h" #include "ash/system/tray/system_tray.h" #include "ui/aura/client/screen_position_client.h" #include "ui/aura/window_event_dispatcher.h" #include "ui/events/event.h" #include "ui/gfx/screen.h" #include "ui/views/widget/widget.h" namespace ash { OverflowBubble::OverflowBubble() : bubble_(NULL), anchor_(NULL), shelf_view_(NULL) { } OverflowBubble::~OverflowBubble() { Hide(); } void OverflowBubble::Show(views::View* anchor, ShelfView* shelf_view) { Hide(); bubble_ = new OverflowBubbleView(); bubble_->InitOverflowBubble(anchor, shelf_view); shelf_view_ = shelf_view; anchor_ = anchor; Shell::GetInstance()->AddPreTargetHandler(this); RootWindowController::ForWindow(anchor->GetWidget()->GetNativeView())-> GetSystemTray()->InitializeBubbleAnimations(bubble_->GetWidget()); bubble_->GetWidget()->AddObserver(this); bubble_->GetWidget()->Show(); } void OverflowBubble::Hide() { if (!IsShowing()) return; Shell::GetInstance()->RemovePreTargetHandler(this); bubble_->GetWidget()->RemoveObserver(this); bubble_->GetWidget()->Close(); bubble_ = NULL; anchor_ = NULL; shelf_view_ = NULL; } void OverflowBubble::HideBubbleAndRefreshButton() { if (!IsShowing()) return; views::View* anchor = anchor_; Hide(); // Update overflow button (|anchor|) status when overflow bubble is hidden // by outside event of overflow button. anchor->SchedulePaint(); } void OverflowBubble::ProcessPressedEvent(ui::LocatedEvent* event) { aura::Window* target = static_cast(event->target()); gfx::Point event_location_in_screen = event->location(); aura::client::GetScreenPositionClient(target->GetRootWindow())-> ConvertPointToScreen(target, &event_location_in_screen); if (!shelf_view_->IsShowingMenu() && !bubble_->GetBoundsInScreen().Contains(event_location_in_screen) && !anchor_->GetBoundsInScreen().Contains(event_location_in_screen)) { HideBubbleAndRefreshButton(); } } void OverflowBubble::OnMouseEvent(ui::MouseEvent* event) { if (event->type() == ui::ET_MOUSE_PRESSED) ProcessPressedEvent(event); } void OverflowBubble::OnTouchEvent(ui::TouchEvent* event) { if (event->type() == ui::ET_TOUCH_PRESSED) ProcessPressedEvent(event); } void OverflowBubble::OnWidgetDestroying(views::Widget* widget) { DCHECK(widget == bubble_->GetWidget()); bubble_ = NULL; anchor_ = NULL; shelf_view_ = NULL; ShelfLayoutManager::ForShelf( widget->GetNativeView())->shelf_widget()->shelf()->SchedulePaint(); } } // namespace ash