shelf_layout_manager.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shelf/shelf_layout_manager.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <algorithm>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <cmath>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/ash_switches.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/launcher/launcher.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/launcher/launcher_types.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/root_window_controller.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/screen_ash.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ash/session_state_delegate.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shelf/shelf_widget.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shell.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shell_window_ids.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/system/status_area_widget.h"
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ash/wm/gestures/shelf_gesture_handler.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/wm/property_util.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/wm/window_cycle_controller.h"
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ash/wm/window_properties.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/wm/window_util.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/wm/workspace_controller.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/wm/workspace/workspace_animations.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/auto_reset.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/i18n/rtl.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/client/activation_client.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/root_window.h"
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/events/event.h"
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/events/event_handler.h"
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/compositor/layer.h"
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/compositor/layer_animation_observer.h"
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/compositor/layer_animator.h"
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/compositor/scoped_layer_animation_settings.h"
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/screen.h"
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/widget/widget.h"
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace ash {
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace internal {
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Delay before showing the launcher. This is after the mouse stops moving.
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kAutoHideDelayMS = 200;
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// To avoid hiding the shelf when the mouse transitions from a message bubble
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// into the shelf, the hit test area is enlarged by this amount of pixels to
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// keep the shelf from hiding.
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kNotificationBubbleGapHeight = 6;
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ui::Layer* GetLayer(views::Widget* widget) {
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return widget->GetNativeView()->layer();
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsDraggingTrayEnabled() {
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static bool dragging_tray_allowed = CommandLine::ForCurrentProcess()->
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      HasSwitch(ash::switches::kAshEnableTrayDragging);
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return dragging_tray_allowed;
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int ShelfLayoutManager::kWorkspaceAreaVisibleInset = 2;
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int ShelfLayoutManager::kWorkspaceAreaAutoHideInset = 5;
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int ShelfLayoutManager::kAutoHideSize = 3;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShelfLayoutManager::AutoHideEventFilter -------------------------------------
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Notifies ShelfLayoutManager any time the mouse moves.
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ShelfLayoutManager::AutoHideEventFilter : public ui::EventHandler {
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit AutoHideEventFilter(ShelfLayoutManager* shelf);
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~AutoHideEventFilter();
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns true if the last mouse event was a mouse drag.
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool in_mouse_drag() const { return in_mouse_drag_; }
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from ui::EventHandler:
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE;
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShelfLayoutManager* shelf_;
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool in_mouse_drag_;
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ShelfGestureHandler gesture_handler_;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AutoHideEventFilter);
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::AutoHideEventFilter::AutoHideEventFilter(
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ShelfLayoutManager* shelf)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : shelf_(shelf),
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      in_mouse_drag_(false) {
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->AddPreTargetHandler(this);
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::AutoHideEventFilter::~AutoHideEventFilter() {
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->RemovePreTargetHandler(this);
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::AutoHideEventFilter::OnMouseEvent(
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::MouseEvent* event) {
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This also checks IsShelfWindow() to make sure we don't attempt to hide the
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // shelf if the mouse down occurs on the shelf.
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  in_mouse_drag_ = (event->type() == ui::ET_MOUSE_DRAGGED ||
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    (in_mouse_drag_ && event->type() != ui::ET_MOUSE_RELEASED &&
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     event->type() != ui::ET_MOUSE_CAPTURE_CHANGED)) &&
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !shelf_->IsShelfWindow(static_cast<aura::Window*>(event->target()));
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (event->type() == ui::ET_MOUSE_MOVED)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_->UpdateAutoHideState();
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return;
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ShelfLayoutManager::AutoHideEventFilter::OnGestureEvent(
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ui::GestureEvent* event) {
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (gesture_handler_.ProcessGestureEvent(*event))
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    event->StopPropagation();
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShelfLayoutManager:UpdateShelfObserver --------------------------------------
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// UpdateShelfObserver is used to delay updating the background until the
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// animation completes.
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ShelfLayoutManager::UpdateShelfObserver
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public ui::ImplicitAnimationObserver {
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit UpdateShelfObserver(ShelfLayoutManager* shelf) : shelf_(shelf) {
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_->update_shelf_observer_ = this;
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Detach() {
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_ = NULL;
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnImplicitAnimationsCompleted() OVERRIDE {
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (shelf_) {
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_->UpdateShelfBackground(BackgroundAnimator::CHANGE_ANIMATE);
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete this;
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~UpdateShelfObserver() {
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (shelf_)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_->update_shelf_observer_ = NULL;
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Shelf we're in. NULL if deleted before we're deleted.
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShelfLayoutManager* shelf_;
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(UpdateShelfObserver);
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShelfLayoutManager ----------------------------------------------------------
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::ShelfLayoutManager(ShelfWidget* shelf)
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : root_window_(shelf->GetNativeView()->GetRootWindow()),
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      in_layout_(false),
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      auto_hide_behavior_(SHELF_AUTO_HIDE_BEHAVIOR_NEVER),
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      alignment_(SHELF_ALIGNMENT_BOTTOM),
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_(shelf),
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      workspace_controller_(NULL),
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      window_overlaps_shelf_(false),
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_status_(GESTURE_DRAG_NONE),
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_amount_(0.f),
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_auto_hide_state_(SHELF_AUTO_HIDE_SHOWN),
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      update_shelf_observer_(NULL) {
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->AddShellObserver(this);
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::client::GetActivationClient(root_window_)->AddObserver(this);
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::~ShelfLayoutManager() {
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (update_shelf_observer_)
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    update_shelf_observer_->Detach();
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FOR_EACH_OBSERVER(Observer, observers_, WillDeleteShelf());
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->RemoveShellObserver(this);
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::client::GetActivationClient(root_window_)->RemoveObserver(this);
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::SetAutoHideBehavior(ShelfAutoHideBehavior behavior) {
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (auto_hide_behavior_ == behavior)
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  auto_hide_behavior_ = behavior;
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateVisibilityState();
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FOR_EACH_OBSERVER(Observer, observers_,
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    OnAutoHideStateChanged(state_.auto_hide_state));
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FOR_EACH_OBSERVER(Observer, observers_,
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    OnAutoHideBehaviorChanged(auto_hide_behavior_));
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShelfLayoutManager::IsVisible() const {
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return shelf_->status_area_widget()->IsVisible() &&
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (state_.visibility_state == SHELF_VISIBLE ||
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       (state_.visibility_state == SHELF_AUTO_HIDE &&
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        state_.auto_hide_state == SHELF_AUTO_HIDE_SHOWN));
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShelfLayoutManager::SetAlignment(ShelfAlignment alignment) {
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (alignment_ == alignment)
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  alignment_ = alignment;
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shelf_->launcher())
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_->launcher()->SetAlignment(alignment);
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  shelf_->status_area_widget()->SetShelfAlignment(alignment);
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayoutShelf();
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Rect ShelfLayoutManager::GetIdealBounds() {
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect bounds(
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ScreenAsh::GetDisplayBoundsInParent(shelf_->GetNativeView()));
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int width = 0, height = 0;
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetShelfSize(&width, &height);
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SelectValueForShelfAlignment(
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(bounds.x(), bounds.bottom() - height, bounds.width(), height),
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(bounds.x(), bounds.y(), width, bounds.height()),
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(bounds.right() - width, bounds.y(), width, bounds.height()),
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(bounds.x(), bounds.y(), bounds.width(), height));
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::LayoutShelf() {
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::AutoReset<bool> auto_reset_in_layout(&in_layout_, true);
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StopAnimating();
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TargetBounds target_bounds;
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CalculateTargetBounds(state_, &target_bounds);
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetLayer(shelf_)->SetOpacity(target_bounds.opacity);
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  shelf_->SetWidgetBounds(
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ScreenAsh::ConvertRectToScreen(
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          shelf_->GetNativeView()->parent(),
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          target_bounds.shelf_bounds_in_root));
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shelf_->launcher())
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_->launcher()->SetLauncherViewBounds(
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        target_bounds.launcher_bounds_in_shelf);
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetLayer(shelf_->status_area_widget())->SetOpacity(target_bounds.opacity);
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(harrym): Once status area widget is a child view of shelf
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // this can be simplified.
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect status_bounds = target_bounds.status_bounds_in_shelf;
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  status_bounds.set_x(status_bounds.x() +
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      target_bounds.shelf_bounds_in_root.x());
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  status_bounds.set_y(status_bounds.y() +
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      target_bounds.shelf_bounds_in_root.y());
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  shelf_->status_area_widget()->SetBounds(
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ScreenAsh::ConvertRectToScreen(
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          shelf_->status_area_widget()->GetNativeView()->parent(),
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          status_bounds));
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->SetDisplayWorkAreaInsets(
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      root_window_, target_bounds.work_area_insets);
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateHitTestBounds();
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfVisibilityState ShelfLayoutManager::CalculateShelfVisibility() {
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch(auto_hide_behavior_) {
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS:
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return SHELF_AUTO_HIDE;
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case SHELF_AUTO_HIDE_BEHAVIOR_NEVER:
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return SHELF_VISIBLE;
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case SHELF_AUTO_HIDE_ALWAYS_HIDDEN:
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return SHELF_HIDDEN;
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SHELF_VISIBLE;
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfVisibilityState
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::CalculateShelfVisibilityWhileDragging() {
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch(auto_hide_behavior_) {
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS:
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case SHELF_AUTO_HIDE_BEHAVIOR_NEVER:
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return SHELF_AUTO_HIDE;
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case SHELF_AUTO_HIDE_ALWAYS_HIDDEN:
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return SHELF_HIDDEN;
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SHELF_VISIBLE;
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::UpdateVisibilityState() {
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (Shell::GetInstance()->session_state_delegate()->IsScreenLocked()) {
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetState(SHELF_VISIBLE);
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (gesture_drag_status_ == GESTURE_DRAG_COMPLETE_IN_PROGRESS) {
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(zelidrag): Verify shelf drag animation still shows on the device
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // when we are in SHELF_AUTO_HIDE_ALWAYS_HIDDEN.
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetState(CalculateShelfVisibilityWhileDragging());
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WorkspaceWindowState window_state(workspace_controller_->GetWindowState());
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    switch (window_state) {
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case WORKSPACE_WINDOW_STATE_FULL_SCREEN:
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      {
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        aura::Window* fullscreen_window =
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetRootWindowController(root_window_)->GetFullscreenWindow();
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (fullscreen_window->GetProperty(kFullscreenUsesMinimalChromeKey)) {
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          DCHECK_NE(auto_hide_behavior_, SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          SetState(SHELF_AUTO_HIDE);
302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        } else {
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          SetState(SHELF_HIDDEN);
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case WORKSPACE_WINDOW_STATE_MAXIMIZED:
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        SetState(CalculateShelfVisibility());
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF:
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case WORKSPACE_WINDOW_STATE_DEFAULT:
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        SetState(CalculateShelfVisibility());
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        SetWindowOverlapsShelf(window_state ==
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF);
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::UpdateAutoHideState() {
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShelfAutoHideState auto_hide_state =
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CalculateAutoHideState(state_.visibility_state);
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (auto_hide_state != state_.auto_hide_state) {
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (auto_hide_state == SHELF_AUTO_HIDE_HIDDEN) {
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Hides happen immediately.
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SetState(state_.visibility_state);
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FOR_EACH_OBSERVER(Observer, observers_,
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        OnAutoHideStateChanged(auto_hide_state));
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      auto_hide_timer_.Stop();
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      auto_hide_timer_.Start(
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          FROM_HERE,
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::TimeDelta::FromMilliseconds(kAutoHideDelayMS),
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          this, &ShelfLayoutManager::UpdateAutoHideStateNow);
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FOR_EACH_OBSERVER(Observer, observers_, OnAutoHideStateChanged(
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          CalculateAutoHideState(state_.visibility_state)));
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    auto_hide_timer_.Stop();
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::SetWindowOverlapsShelf(bool value) {
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window_overlaps_shelf_ = value;
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateShelfBackground(BackgroundAnimator::CHANGE_ANIMATE);
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::AddObserver(Observer* observer) {
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.AddObserver(observer);
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::RemoveObserver(Observer* observer) {
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.RemoveObserver(observer);
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShelfLayoutManager, Gesture dragging:
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::StartGestureDrag(const ui::GestureEvent& gesture) {
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gesture_drag_status_ = GESTURE_DRAG_IN_PROGRESS;
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gesture_drag_amount_ = 0.f;
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gesture_drag_auto_hide_state_ = visibility_state() == SHELF_AUTO_HIDE ?
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      auto_hide_state() : SHELF_AUTO_HIDE_SHOWN;
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateShelfBackground(BackgroundAnimator::CHANGE_ANIMATE);
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::DragState ShelfLayoutManager::UpdateGestureDrag(
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ui::GestureEvent& gesture) {
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool horizontal = IsHorizontalAlignment();
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gesture_drag_amount_ += horizontal ? gesture.details().scroll_y() :
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       gesture.details().scroll_x();
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayoutShelf();
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Start reveling the status menu when:
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   - dragging up on an already visible shelf
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   - dragging up on a hidden shelf, but it is currently completely visible.
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (horizontal && gesture.details().scroll_y() < 0) {
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int min_height = 0;
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_HIDDEN && shelf_)
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      min_height = shelf_->GetContentsView()->GetPreferredSize().height();
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (min_height < shelf_->GetWindowBoundsInScreen().height() &&
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gesture.root_location().x() >=
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        shelf_->status_area_widget()->GetWindowBoundsInScreen().x() &&
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IsDraggingTrayEnabled())
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return DRAG_TRAY;
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return DRAG_SHELF;
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::CompleteGestureDrag(const ui::GestureEvent& gesture) {
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool horizontal = IsHorizontalAlignment();
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool should_change = false;
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gesture.type() == ui::ET_GESTURE_SCROLL_END) {
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The visibility of the shelf changes only if the shelf was dragged X%
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // along the correct axis. If the shelf was already visible, then the
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // direction of the drag does not matter.
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const float kDragHideThreshold = 0.4f;
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect bounds = GetIdealBounds();
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    float drag_ratio = fabs(gesture_drag_amount_) /
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       (horizontal ?  bounds.height() : bounds.width());
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN) {
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      should_change = drag_ratio > kDragHideThreshold;
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bool correct_direction = false;
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      switch (alignment_) {
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        case SHELF_ALIGNMENT_BOTTOM:
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        case SHELF_ALIGNMENT_RIGHT:
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          correct_direction = gesture_drag_amount_ < 0;
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          break;
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        case SHELF_ALIGNMENT_LEFT:
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        case SHELF_ALIGNMENT_TOP:
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          correct_direction = gesture_drag_amount_ > 0;
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          break;
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      should_change = correct_direction && drag_ratio > kDragHideThreshold;
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (gesture.type() == ui::ET_SCROLL_FLING_START) {
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN) {
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      should_change = horizontal ? fabs(gesture.details().velocity_y()) > 0 :
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   fabs(gesture.details().velocity_x()) > 0;
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      should_change = SelectValueForShelfAlignment(
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gesture.details().velocity_y() < 0,
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gesture.details().velocity_x() > 0,
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gesture.details().velocity_x() < 0,
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gesture.details().velocity_y() > 0);
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTREACHED();
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!should_change) {
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CancelGestureDrag();
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gesture_drag_auto_hide_state_ =
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN ?
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SHELF_AUTO_HIDE_HIDDEN : SHELF_AUTO_HIDE_SHOWN;
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shelf_)
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_->Deactivate();
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  shelf_->status_area_widget()->Deactivate();
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_HIDDEN &&
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      auto_hide_behavior_ != SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS) {
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gesture_drag_status_ = GESTURE_DRAG_NONE;
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN &&
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             auto_hide_behavior_ != SHELF_AUTO_HIDE_BEHAVIOR_NEVER) {
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gesture_drag_status_ = GESTURE_DRAG_NONE;
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gesture_drag_status_ = GESTURE_DRAG_COMPLETE_IN_PROGRESS;
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateVisibilityState();
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gesture_drag_status_ = GESTURE_DRAG_NONE;
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LayoutShelf();
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::CancelGestureDrag() {
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gesture_drag_status_ = GESTURE_DRAG_NONE;
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::ScopedLayerAnimationSettings
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      launcher_settings(GetLayer(shelf_)->GetAnimator()),
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      status_settings(GetLayer(shelf_->status_area_widget())->GetAnimator());
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayoutShelf();
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateVisibilityState();
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateShelfBackground(BackgroundAnimator::CHANGE_ANIMATE);
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShelfLayoutManager, aura::LayoutManager implementation:
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnWindowResized() {
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayoutShelf();
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnWindowAddedToLayout(aura::Window* child) {
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) {
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnWindowRemovedFromLayout(aura::Window* child) {
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnChildWindowVisibilityChanged(aura::Window* child,
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                        bool visible) {
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::SetChildBounds(aura::Window* child,
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        const gfx::Rect& requested_bounds) {
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetChildBoundsDirect(child, requested_bounds);
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We may contain other widgets (such as frame maximize bubble) but they don't
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // effect the layout in anyway.
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!in_layout_ &&
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ((shelf_->GetNativeView() == child) ||
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       (shelf_->status_area_widget()->GetNativeView() == child))) {
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayoutShelf();
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnLockStateChanged(bool locked) {
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateVisibilityState();
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnWindowActivated(aura::Window* gained_active,
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           aura::Window* lost_active) {
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAutoHideStateNow();
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShelfLayoutManager::IsHorizontalAlignment() const {
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return alignment_ == SHELF_ALIGNMENT_BOTTOM ||
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         alignment_ == SHELF_ALIGNMENT_TOP;
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager* ShelfLayoutManager::ForLauncher(aura::Window* window) {
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShelfWidget* shelf = RootWindowController::ForLauncher(window)->shelf();
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return shelf ? shelf->shelf_layout_manager() : NULL;
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShelfLayoutManager, private:
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::TargetBounds::TargetBounds() : opacity(0.0f) {}
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::TargetBounds::~TargetBounds() {}
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::SetState(ShelfVisibilityState visibility_state) {
531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!shelf_->GetNativeView())
532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  State state;
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state.visibility_state = visibility_state;
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state.auto_hide_state = CalculateAutoHideState(visibility_state);
537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  state.is_screen_locked =
538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      Shell::GetInstance()->session_state_delegate()->IsScreenLocked();
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // It's possible for SetState() when a window becomes maximized but the state
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // won't have changed value. Do the dimming check before the early exit.
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (workspace_controller_) {
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_->SetDimsShelf(
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        (state.visibility_state == SHELF_VISIBLE) &&
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          workspace_controller_->GetWindowState() ==
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              WORKSPACE_WINDOW_STATE_MAXIMIZED);
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (state_.Equals(state))
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;  // Nothing changed.
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FOR_EACH_OBSERVER(Observer, observers_,
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    WillChangeVisibilityState(visibility_state));
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (state.visibility_state == SHELF_AUTO_HIDE) {
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // When state is SHELF_AUTO_HIDE we need to track when the mouse is over the
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // launcher to unhide the shelf. AutoHideEventFilter does that for us.
558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!event_filter_)
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      event_filter_.reset(new AutoHideEventFilter(this));
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event_filter_.reset(NULL);
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  auto_hide_timer_.Stop();
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Animating the background when transitioning from auto-hide & hidden to
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // visible is janky. Update the background immediately in this case.
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BackgroundAnimator::ChangeType change_type =
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (state_.visibility_state == SHELF_AUTO_HIDE &&
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       state_.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN &&
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       state.visibility_state == SHELF_VISIBLE) ?
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      BackgroundAnimator::CHANGE_IMMEDIATE : BackgroundAnimator::CHANGE_ANIMATE;
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StopAnimating();
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  State old_state = state_;
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state_ = state;
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TargetBounds target_bounds;
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CalculateTargetBounds(state_, &target_bounds);
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::ScopedLayerAnimationSettings launcher_animation_setter(
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetLayer(shelf_)->GetAnimator());
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  launcher_animation_setter.SetTransitionDuration(
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(kWorkspaceSwitchTimeMS));
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  launcher_animation_setter.SetTweenType(ui::Tween::EASE_OUT);
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetLayer(shelf_)->SetBounds(
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      target_bounds.shelf_bounds_in_root);
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetLayer(shelf_)->SetOpacity(target_bounds.opacity);
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::ScopedLayerAnimationSettings status_animation_setter(
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetLayer(shelf_->status_area_widget())->GetAnimator());
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  status_animation_setter.SetTransitionDuration(
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(kWorkspaceSwitchTimeMS));
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  status_animation_setter.SetTweenType(ui::Tween::EASE_OUT);
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Delay updating the background when going from SHELF_AUTO_HIDE_SHOWN to
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // SHELF_AUTO_HIDE_HIDDEN until the shelf animates out. Otherwise during the
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // animation you see the background change.
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Also delay the animation when the shelf was hidden, and has just been made
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // visible (e.g. using a gesture-drag).
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool delay_shelf_update =
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      state.visibility_state == SHELF_AUTO_HIDE &&
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      state.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN &&
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      old_state.visibility_state == SHELF_AUTO_HIDE;
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (state.visibility_state == SHELF_VISIBLE &&
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      old_state.visibility_state == SHELF_AUTO_HIDE &&
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      old_state.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN)
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delay_shelf_update = true;
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (delay_shelf_update) {
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (update_shelf_observer_)
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      update_shelf_observer_->Detach();
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // UpdateShelfBackground deletes itself when the animation is done.
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    update_shelf_observer_ = new UpdateShelfObserver(this);
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    status_animation_setter.AddObserver(update_shelf_observer_);
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::Layer* layer = GetLayer(shelf_->status_area_widget());
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(harrym): Remove when status_area is view (crbug.com/180422).
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect status_bounds = target_bounds.status_bounds_in_shelf;
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  status_bounds.set_x(status_bounds.x() +
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      target_bounds.shelf_bounds_in_root.x());
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  status_bounds.set_y(status_bounds.y() +
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      target_bounds.shelf_bounds_in_root.y());
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(status_bounds);
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetOpacity(target_bounds.opacity);
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->SetDisplayWorkAreaInsets(
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      root_window_, target_bounds.work_area_insets);
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateHitTestBounds();
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!delay_shelf_update)
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateShelfBackground(change_type);
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::StopAnimating() {
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetLayer(shelf_)->GetAnimator()->StopAnimating();
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetLayer(shelf_->status_area_widget())->GetAnimator()->StopAnimating();
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::GetShelfSize(int* width, int* height) {
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *width = *height = 0;
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size status_size(
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_->status_area_widget()->GetWindowBoundsInScreen().size());
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsHorizontalAlignment())
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *height = std::max(kLauncherPreferredSize, status_size.height());
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *width = std::max(kLauncherPreferredSize, status_size.width());
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::AdjustBoundsBasedOnAlignment(int inset,
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                      gfx::Rect* bounds) const {
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bounds->Inset(SelectValueForShelfAlignment(
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(0, 0, inset, 0),
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(0, inset, 0, 0),
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(0, 0, 0, inset),
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(inset, 0, 0, 0)));
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::CalculateTargetBounds(
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const State& state,
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TargetBounds* target_bounds) {
659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const gfx::Rect available_bounds(GetAvailableBounds());
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect status_size(
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_->status_area_widget()->GetWindowBoundsInScreen().size());
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int shelf_width = 0, shelf_height = 0;
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetShelfSize(&shelf_width, &shelf_height);
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsHorizontalAlignment())
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_width = available_bounds.width();
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_height = available_bounds.height();
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (state.visibility_state == SHELF_AUTO_HIDE &&
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      state.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN) {
671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Auto-hidden shelf always starts with the default size. If a gesture-drag
672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // is in progress, then the call to UpdateTargetBoundsForGesture() below
673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // takes care of setting the height properly.
674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (IsHorizontalAlignment())
675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      shelf_height = kAutoHideSize;
676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    else
677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      shelf_width = kAutoHideSize;
678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (state.visibility_state == SHELF_HIDDEN ||
679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      !keyboard_bounds_.IsEmpty()) {
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsHorizontalAlignment())
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_height = 0;
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_width = 0;
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target_bounds->shelf_bounds_in_root = SelectValueForShelfAlignment(
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(available_bounds.x(), available_bounds.bottom() - shelf_height,
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    available_bounds.width(), shelf_height),
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(available_bounds.x(), available_bounds.y(),
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    shelf_width, available_bounds.height()),
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(available_bounds.right() - shelf_width, available_bounds.y(),
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    shelf_width, available_bounds.height()),
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(available_bounds.x(), available_bounds.y(),
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    available_bounds.width(), shelf_height));
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int status_inset = (kLauncherPreferredSize -
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PrimaryAxisValue(status_size.height(), status_size.width()));
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target_bounds->status_bounds_in_shelf = SelectValueForShelfAlignment(
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(base::i18n::IsRTL() ? 0 : shelf_width - status_size.width(),
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    status_inset, status_size.width(), status_size.height()),
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(shelf_width - (status_size.width() + status_inset),
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    shelf_height - status_size.height(), status_size.width(),
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    status_size.height()),
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(status_inset, shelf_height - status_size.height(),
7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    status_size.width(), status_size.height()),
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(base::i18n::IsRTL() ? 0 : shelf_width - status_size.width(),
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    shelf_height - (status_size.height() + status_inset),
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    status_size.width(), status_size.height()));
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target_bounds->work_area_insets = SelectValueForShelfAlignment(
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(0, 0, GetWorkAreaSize(state, shelf_height), 0),
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(0, GetWorkAreaSize(state, shelf_width), 0, 0),
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(0, 0, 0, GetWorkAreaSize(state, shelf_width)),
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(GetWorkAreaSize(state, shelf_height), 0, 0, 0));
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Also push in the work area inset for the keyboard if it is visible.
718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!keyboard_bounds_.IsEmpty()) {
719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    target_bounds->work_area_insets.Set(
720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        target_bounds->work_area_insets.top(),
721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        target_bounds->work_area_insets.left(),
722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        target_bounds->work_area_insets.bottom() + keyboard_bounds_.height(),
723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        target_bounds->work_area_insets.right());
724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target_bounds->opacity =
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (gesture_drag_status_ != GESTURE_DRAG_NONE ||
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       state.visibility_state == SHELF_VISIBLE ||
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       state.visibility_state == SHELF_AUTO_HIDE) ? 1.0f : 0.0f;
730c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gesture_drag_status_ == GESTURE_DRAG_IN_PROGRESS)
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTargetBoundsForGesture(target_bounds);
733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This needs to happen after calling UpdateTargetBoundsForGesture(), because
735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // that can change the size of the shelf.
736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  target_bounds->launcher_bounds_in_shelf = SelectValueForShelfAlignment(
737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      gfx::Rect(base::i18n::IsRTL() ? status_size.width() : 0, 0,
738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    shelf_width - status_size.width(),
739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    target_bounds->shelf_bounds_in_root.height()),
740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      gfx::Rect(0, 0, shelf_width, shelf_height - status_size.height()),
741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      gfx::Rect(0, 0, shelf_width, shelf_height - status_size.height()),
742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      gfx::Rect(base::i18n::IsRTL() ? status_size.width() : 0, 0,
743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    shelf_width - status_size.width(),
744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    target_bounds->shelf_bounds_in_root.height()));
7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::UpdateTargetBoundsForGesture(
7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TargetBounds* target_bounds) const {
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK_EQ(GESTURE_DRAG_IN_PROGRESS, gesture_drag_status_);
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool horizontal = IsHorizontalAlignment();
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const gfx::Rect& available_bounds(root_window_->bounds());
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int resistance_free_region = 0;
7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_HIDDEN &&
7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      visibility_state() == SHELF_AUTO_HIDE &&
7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      auto_hide_state() != SHELF_AUTO_HIDE_SHOWN) {
7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If the shelf was hidden when the drag started (and the state hasn't
7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // changed since then, e.g. because the tray-menu was shown because of the
7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // drag), then allow the drag some resistance-free region at first to make
7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // sure the shelf sticks with the finger until the shelf is visible.
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resistance_free_region = kLauncherPreferredSize - kAutoHideSize;
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool resist = SelectValueForShelfAlignment(
7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_amount_ < -resistance_free_region,
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_amount_ > resistance_free_region,
7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_amount_ < -resistance_free_region,
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_amount_ > resistance_free_region);
7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float translate = 0.f;
7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (resist) {
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    float diff = fabsf(gesture_drag_amount_) - resistance_free_region;
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    diff = std::min(diff, sqrtf(diff));
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gesture_drag_amount_ < 0)
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      translate = -resistance_free_region - diff;
7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      translate = resistance_free_region + diff;
7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    translate = gesture_drag_amount_;
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (horizontal) {
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Move and size the launcher with the gesture.
784c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int shelf_height = target_bounds->shelf_bounds_in_root.height() - translate;
785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shelf_height = std::max(shelf_height, kAutoHideSize);
786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    target_bounds->shelf_bounds_in_root.set_height(shelf_height);
7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (alignment_ == SHELF_ALIGNMENT_BOTTOM) {
788c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      target_bounds->shelf_bounds_in_root.set_y(
789c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          available_bounds.bottom() - shelf_height);
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The statusbar should be in the center of the shelf.
7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect status_y = target_bounds->shelf_bounds_in_root;
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    status_y.set_y(0);
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    status_y.ClampToCenteredSize(
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        target_bounds->status_bounds_in_shelf.size());
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    target_bounds->status_bounds_in_shelf.set_y(status_y.y());
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Move and size the launcher with the gesture.
800c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int shelf_width = target_bounds->shelf_bounds_in_root.width() - translate;
801c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shelf_width = std::max(shelf_width, kAutoHideSize);
802c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    target_bounds->shelf_bounds_in_root.set_width(shelf_width);
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (alignment_ == SHELF_ALIGNMENT_RIGHT) {
804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      target_bounds->shelf_bounds_in_root.set_y(
805c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          available_bounds.right() - shelf_width);
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The statusbar should be in the center of the shelf.
8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect status_x = target_bounds->shelf_bounds_in_root;
8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    status_x.set_x(0);
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    status_x.ClampToCenteredSize(
8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        target_bounds->status_bounds_in_shelf.size());
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    target_bounds->status_bounds_in_shelf.set_x(status_x.x());
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::UpdateShelfBackground(
8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BackgroundAnimator::ChangeType type) {
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool launcher_paints = GetLauncherPaintsBackground();
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  shelf_->SetPaintsBackground(launcher_paints, type);
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShelfLayoutManager::GetLauncherPaintsBackground() const {
8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return gesture_drag_status_ != GESTURE_DRAG_NONE ||
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (!state_.is_screen_locked && window_overlaps_shelf_) ||
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (state_.visibility_state == SHELF_AUTO_HIDE) ;
8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::UpdateAutoHideStateNow() {
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetState(state_.visibility_state);
8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfAutoHideState ShelfLayoutManager::CalculateAutoHideState(
8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ShelfVisibilityState visibility_state) const {
8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (visibility_state != SHELF_AUTO_HIDE || !shelf_)
8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_HIDDEN;
8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gesture_drag_status_ == GESTURE_DRAG_COMPLETE_IN_PROGRESS)
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return gesture_drag_auto_hide_state_;
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell* shell = Shell::GetInstance();
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shell->GetAppListTargetVisibility())
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_SHOWN;
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shelf_->status_area_widget() &&
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_->status_area_widget()->ShouldShowLauncher())
8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_SHOWN;
8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shelf_->launcher() && shelf_->launcher()->IsShowingMenu())
8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_SHOWN;
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shelf_->launcher() && shelf_->launcher()->IsShowingOverflowBubble())
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_SHOWN;
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shelf_->IsActive() || shelf_->status_area_widget()->IsActive())
8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_SHOWN;
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Don't show if the user is dragging the mouse.
8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (event_filter_.get() && event_filter_->in_mouse_drag())
8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_HIDDEN;
8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect shelf_region = shelf_->GetWindowBoundsInScreen();
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shelf_->status_area_widget() &&
8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_->status_area_widget()->IsMessageBubbleShown() &&
8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      IsVisible()) {
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Increase the the hit test area to prevent the shelf from disappearing
8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // when the mouse is over the bubble gap.
8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_region.Inset(alignment_ == SHELF_ALIGNMENT_RIGHT ?
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           -kNotificationBubbleGapHeight : 0,
8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       alignment_ == SHELF_ALIGNMENT_BOTTOM ?
8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           -kNotificationBubbleGapHeight : 0,
8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       alignment_ == SHELF_ALIGNMENT_LEFT ?
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           -kNotificationBubbleGapHeight : 0,
8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       alignment_ == SHELF_ALIGNMENT_TOP ?
8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           -kNotificationBubbleGapHeight : 0);
8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shelf_region.Contains(Shell::GetScreen()->GetCursorScreenPoint()))
8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_SHOWN;
8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::vector<aura::Window*> windows =
882c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ash::WindowCycleController::BuildWindowList(NULL, false);
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Process the window list and check if there are any visible windows.
8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < windows.size(); ++i) {
8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (windows[i] && windows[i]->IsVisible() &&
887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        !ash::wm::IsWindowMinimized(windows[i]) &&
888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        root_window_ == windows[i]->GetRootWindow())
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return SHELF_AUTO_HIDE_HIDDEN;
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If there are no visible windows do not hide the shelf.
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SHELF_AUTO_HIDE_SHOWN;
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::UpdateHitTestBounds() {
897c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Insets mouse_insets;
898c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Insets touch_insets;
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (state_.visibility_state == SHELF_VISIBLE) {
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Let clicks at the very top of the launcher through so windows can be
9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // resized with the bottom-right corner and bottom edge.
902c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    mouse_insets = GetInsetsForAlignment(kWorkspaceAreaVisibleInset);
903c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (state_.visibility_state == SHELF_AUTO_HIDE) {
904c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Extend the touch hit target out a bit to allow users to drag shelf out
905c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // while hidden.
906c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    touch_insets = GetInsetsForAlignment(-kWorkspaceAreaAutoHideInset);
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
908c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
909c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (shelf_ && shelf_->GetNativeWindow())
910c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      shelf_->GetNativeWindow()->SetHitTestBoundsOverrideOuter(mouse_insets,
911c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                               touch_insets);
912c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shelf_->status_area_widget()->GetNativeWindow()->
913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        SetHitTestBoundsOverrideOuter(mouse_insets, touch_insets);
9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShelfLayoutManager::IsShelfWindow(aura::Window* window) {
9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!window)
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (shelf_ &&
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          shelf_->GetNativeWindow()->Contains(window)) ||
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (shelf_->status_area_widget()->GetNativeWindow()->Contains(window));
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int ShelfLayoutManager::GetWorkAreaSize(const State& state, int size) const {
9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (state.visibility_state == SHELF_VISIBLE)
9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return size;
9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (state.visibility_state == SHELF_AUTO_HIDE)
9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kAutoHideSize;
9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return 0;
9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
932c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)gfx::Rect ShelfLayoutManager::GetAvailableBounds() const {
933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Rect bounds(root_window_->bounds());
934c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bounds.set_height(bounds.height() - keyboard_bounds_.height());
935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return bounds;
936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ShelfLayoutManager::OnKeyboardBoundsChanging(
939c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const gfx::Rect& keyboard_bounds) {
940c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  keyboard_bounds_ = keyboard_bounds;
941c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  OnWindowResized();
942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)gfx::Insets ShelfLayoutManager::GetInsetsForAlignment(int distance) const {
945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  switch (alignment_) {
946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case SHELF_ALIGNMENT_BOTTOM:
947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return gfx::Insets(distance, 0, 0, 0);
948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case SHELF_ALIGNMENT_LEFT:
949c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return gfx::Insets(0, 0, 0, distance);
950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case SHELF_ALIGNMENT_RIGHT:
951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return gfx::Insets(0, distance, 0, 0);
952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case SHELF_ALIGNMENT_TOP:
953c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return gfx::Insets(0, 0, distance, 0);
954c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
955c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NOTREACHED();
956c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return gfx::Insets();
957c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
958c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace internal
9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace ash
961