[email protected] | 1b62b89 | 2012-01-17 17:08:15 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | ae18b911 | 2011-11-07 16:59:13 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
[email protected] | 7634f96 | 2011-12-23 21:35:52 | [diff] [blame] | 5 | #include "ash/wm/shelf_layout_manager.h" |
[email protected] | ae18b911 | 2011-11-07 16:59:13 | [diff] [blame] | 6 | |
[email protected] | c2d58b4 | 2012-05-30 08:11:29 | [diff] [blame] | 7 | #include <algorithm> |
[email protected] | 91d966a7 | 2012-09-06 03:42:27 | [diff] [blame] | 8 | #include <cmath> |
[email protected] | c2d58b4 | 2012-05-30 08:11:29 | [diff] [blame] | 9 | |
[email protected] | fd42270 | 2012-09-25 17:45:14 | [diff] [blame] | 10 | #include "ash/ash_switches.h" |
[email protected] | 7634f96 | 2011-12-23 21:35:52 | [diff] [blame] | 11 | #include "ash/launcher/launcher.h" |
[email protected] | 88d7112 | 2012-10-18 07:11:01 | [diff] [blame] | 12 | #include "ash/root_window_controller.h" |
[email protected] | 1a2145b | 2012-03-13 21:09:17 | [diff] [blame] | 13 | #include "ash/screen_ash.h" |
[email protected] | b65bdda | 2011-12-23 23:35:31 | [diff] [blame] | 14 | #include "ash/shell.h" |
[email protected] | c758fbf | 2012-03-25 22:53:59 | [diff] [blame] | 15 | #include "ash/shell_delegate.h" |
| 16 | #include "ash/shell_window_ids.h" |
[email protected] | 6d6546e | 2012-05-30 23:12:02 | [diff] [blame] | 17 | #include "ash/system/status_area_widget.h" |
[email protected] | f4bb9fde | 2012-08-03 19:33:50 | [diff] [blame] | 18 | #include "ash/wm/workspace_controller.h" |
[email protected] | ba38e00 | 2012-10-12 16:39:41 | [diff] [blame] | 19 | #include "ash/wm/workspace/workspace_animations.h" |
[email protected] | 4bb1650 | 2011-12-06 14:44:58 | [diff] [blame] | 20 | #include "base/auto_reset.h" |
[email protected] | fd42270 | 2012-09-25 17:45:14 | [diff] [blame] | 21 | #include "base/command_line.h" |
[email protected] | e24b609 | 2012-04-12 18:58:51 | [diff] [blame] | 22 | #include "base/i18n/rtl.h" |
[email protected] | 8676f047 | 2012-03-29 20:30:12 | [diff] [blame] | 23 | #include "ui/aura/client/activation_client.h" |
[email protected] | b1c37fc | 2012-03-22 03:36:13 | [diff] [blame] | 24 | #include "ui/aura/event_filter.h" |
[email protected] | 99f07e0 | 2011-12-07 00:02:59 | [diff] [blame] | 25 | #include "ui/aura/root_window.h" |
[email protected] | 153472d7 | 2012-09-04 21:33:02 | [diff] [blame] | 26 | #include "ui/base/events/event.h" |
[email protected] | 116302fc | 2012-05-05 21:45:41 | [diff] [blame] | 27 | #include "ui/compositor/layer.h" |
| 28 | #include "ui/compositor/layer_animation_observer.h" |
| 29 | #include "ui/compositor/layer_animator.h" |
| 30 | #include "ui/compositor/scoped_layer_animation_settings.h" |
[email protected] | b82c42c4 | 2012-04-25 20:03:41 | [diff] [blame] | 31 | #include "ui/gfx/screen.h" |
[email protected] | c13be0d | 2011-11-22 02:09:58 | [diff] [blame] | 32 | #include "ui/views/widget/widget.h" |
[email protected] | ae18b911 | 2011-11-07 16:59:13 | [diff] [blame] | 33 | |
[email protected] | 55f59335 | 2011-12-24 05:42:46 | [diff] [blame] | 34 | namespace ash { |
[email protected] | ae18b911 | 2011-11-07 16:59:13 | [diff] [blame] | 35 | namespace internal { |
| 36 | |
| 37 | namespace { |
| 38 | |
[email protected] | cadd8c4 | 2012-03-27 02:44:31 | [diff] [blame] | 39 | // Delay before showing the launcher. This is after the mouse stops moving. |
| 40 | const int kAutoHideDelayMS = 200; |
[email protected] | 27f6af6 | 2012-03-21 05:34:40 | [diff] [blame] | 41 | |
[email protected] | 2e195f5 | 2012-09-22 00:24:46 | [diff] [blame] | 42 | // To avoid hiding the shelf when the mouse transitions from a message bubble |
| 43 | // into the shelf, the hit test area is enlarged by this amount of pixels to |
| 44 | // keep the shelf from hiding. |
| 45 | const int kNotificationBubbleGapHeight = 6; |
| 46 | |
[email protected] | ae18b911 | 2011-11-07 16:59:13 | [diff] [blame] | 47 | ui::Layer* GetLayer(views::Widget* widget) { |
| 48 | return widget->GetNativeView()->layer(); |
| 49 | } |
| 50 | |
[email protected] | fd42270 | 2012-09-25 17:45:14 | [diff] [blame] | 51 | bool IsDraggingTrayEnabled() { |
| 52 | static bool dragging_tray_allowed = CommandLine::ForCurrentProcess()-> |
| 53 | HasSwitch(ash::switches::kAshEnableTrayDragging); |
| 54 | return dragging_tray_allowed; |
| 55 | } |
| 56 | |
[email protected] | ae18b911 | 2011-11-07 16:59:13 | [diff] [blame] | 57 | } // namespace |
| 58 | |
[email protected] | bbb59f8 | 2012-03-14 04:04:35 | [diff] [blame] | 59 | // static |
| 60 | const int ShelfLayoutManager::kWorkspaceAreaBottomInset = 2; |
| 61 | |
[email protected] | b1c37fc | 2012-03-22 03:36:13 | [diff] [blame] | 62 | // static |
[email protected] | 7b675df61 | 2012-09-16 18:33:20 | [diff] [blame] | 63 | const int ShelfLayoutManager::kAutoHideSize = 3; |
[email protected] | b1c37fc | 2012-03-22 03:36:13 | [diff] [blame] | 64 | |
[email protected] | e4d9fe9 | 2012-09-10 14:04:49 | [diff] [blame] | 65 | // ShelfLayoutManager::AutoHideEventFilter ------------------------------------- |
| 66 | |
[email protected] | b1c37fc | 2012-03-22 03:36:13 | [diff] [blame] | 67 | // Notifies ShelfLayoutManager any time the mouse moves. |
| 68 | class ShelfLayoutManager::AutoHideEventFilter : public aura::EventFilter { |
| 69 | public: |
| 70 | explicit AutoHideEventFilter(ShelfLayoutManager* shelf); |
| 71 | virtual ~AutoHideEventFilter(); |
| 72 | |
[email protected] | 5f1d99dc | 2012-04-12 21:42:37 | [diff] [blame] | 73 | // Returns true if the last mouse event was a mouse drag. |
| 74 | bool in_mouse_drag() const { return in_mouse_drag_; } |
| 75 | |
[email protected] | b1c37fc | 2012-03-22 03:36:13 | [diff] [blame] | 76 | // Overridden from aura::EventFilter: |
| 77 | virtual bool PreHandleKeyEvent(aura::Window* target, |
[email protected] | ca706098 | 2012-08-08 18:05:25 | [diff] [blame] | 78 | ui::KeyEvent* event) OVERRIDE; |
[email protected] | b1c37fc | 2012-03-22 03:36:13 | [diff] [blame] | 79 | virtual bool PreHandleMouseEvent(aura::Window* target, |
[email protected] | ca706098 | 2012-08-08 18:05:25 | [diff] [blame] | 80 | ui::MouseEvent* event) OVERRIDE; |
| 81 | virtual ui::TouchStatus PreHandleTouchEvent( |
| 82 | aura::Window* target, |
[email protected] | 8ca8d246 | 2012-08-09 22:28:04 | [diff] [blame] | 83 | ui::TouchEvent* event) OVERRIDE; |
[email protected] | 5b174e0a | 2012-09-04 01:14:43 | [diff] [blame] | 84 | virtual ui::EventResult PreHandleGestureEvent( |
[email protected] | b1c37fc | 2012-03-22 03:36:13 | [diff] [blame] | 85 | aura::Window* target, |
[email protected] | 2487bee4 | 2012-08-10 16:21:44 | [diff] [blame] | 86 | ui::GestureEvent* event) OVERRIDE; |
[email protected] | b1c37fc | 2012-03-22 03:36:13 | [diff] [blame] | 87 | |
| 88 | private: |
| 89 | ShelfLayoutManager* shelf_; |
[email protected] | 5f1d99dc | 2012-04-12 21:42:37 | [diff] [blame] | 90 | bool in_mouse_drag_; |
[email protected] | b1c37fc | 2012-03-22 03:36:13 | [diff] [blame] | 91 | |
| 92 | DISALLOW_COPY_AND_ASSIGN(AutoHideEventFilter); |
| 93 | }; |
| 94 | |
| 95 | ShelfLayoutManager::AutoHideEventFilter::AutoHideEventFilter( |
| 96 | ShelfLayoutManager* shelf) |
[email protected] | 5f1d99dc | 2012-04-12 21:42:37 | [diff] [blame] | 97 | : shelf_(shelf), |
| 98 | in_mouse_drag_(false) { |
[email protected] | 1aad332 | 2012-06-06 06:37:09 | [diff] [blame] | 99 | Shell::GetInstance()->AddEnvEventFilter(this); |
[email protected] | b1c37fc | 2012-03-22 03:36:13 | [diff] [blame] | 100 | } |
| 101 | |
| 102 | ShelfLayoutManager::AutoHideEventFilter::~AutoHideEventFilter() { |
[email protected] | 1aad332 | 2012-06-06 06:37:09 | [diff] [blame] | 103 | Shell::GetInstance()->RemoveEnvEventFilter(this); |
[email protected] | b1c37fc | 2012-03-22 03:36:13 | [diff] [blame] | 104 | } |
| 105 | |
| 106 | bool ShelfLayoutManager::AutoHideEventFilter::PreHandleKeyEvent( |
| 107 | aura::Window* target, |
[email protected] | ca706098 | 2012-08-08 18:05:25 | [diff] [blame] | 108 | ui::KeyEvent* event) { |
[email protected] | b1c37fc | 2012-03-22 03:36:13 | [diff] [blame] | 109 | return false; // Always let the event propagate. |
| 110 | } |
| 111 | |
| 112 | bool ShelfLayoutManager::AutoHideEventFilter::PreHandleMouseEvent( |
| 113 | aura::Window* target, |
[email protected] | ca706098 | 2012-08-08 18:05:25 | [diff] [blame] | 114 | ui::MouseEvent* event) { |
[email protected] | 5f1d99dc | 2012-04-12 21:42:37 | [diff] [blame] | 115 | // This also checks IsShelfWindow() to make sure we don't attempt to hide the |
| 116 | // shelf if the mouse down occurs on the shelf. |
| 117 | in_mouse_drag_ = (event->type() == ui::ET_MOUSE_DRAGGED || |
| 118 | (in_mouse_drag_ && event->type() != ui::ET_MOUSE_RELEASED && |
| 119 | event->type() != ui::ET_MOUSE_CAPTURE_CHANGED)) && |
| 120 | !shelf_->IsShelfWindow(target); |
[email protected] | b1c37fc | 2012-03-22 03:36:13 | [diff] [blame] | 121 | if (event->type() == ui::ET_MOUSE_MOVED) |
| 122 | shelf_->UpdateAutoHideState(); |
| 123 | return false; // Not handled. |
| 124 | } |
| 125 | |
| 126 | ui::TouchStatus ShelfLayoutManager::AutoHideEventFilter::PreHandleTouchEvent( |
| 127 | aura::Window* target, |
[email protected] | 8ca8d246 | 2012-08-09 22:28:04 | [diff] [blame] | 128 | ui::TouchEvent* event) { |
[email protected] | b1c37fc | 2012-03-22 03:36:13 | [diff] [blame] | 129 | return ui::TOUCH_STATUS_UNKNOWN; // Not handled. |
| 130 | } |
| 131 | |
[email protected] | 5b174e0a | 2012-09-04 01:14:43 | [diff] [blame] | 132 | ui::EventResult |
[email protected] | b1c37fc | 2012-03-22 03:36:13 | [diff] [blame] | 133 | ShelfLayoutManager::AutoHideEventFilter::PreHandleGestureEvent( |
| 134 | aura::Window* target, |
[email protected] | 2487bee4 | 2012-08-10 16:21:44 | [diff] [blame] | 135 | ui::GestureEvent* event) { |
[email protected] | 5b174e0a | 2012-09-04 01:14:43 | [diff] [blame] | 136 | return ui::ER_UNHANDLED; // Not handled. |
[email protected] | b1c37fc | 2012-03-22 03:36:13 | [diff] [blame] | 137 | } |
| 138 | |
[email protected] | e4d9fe9 | 2012-09-10 14:04:49 | [diff] [blame] | 139 | // ShelfLayoutManager:UpdateShelfObserver -------------------------------------- |
| 140 | |
| 141 | // UpdateShelfObserver is used to delay updating the background until the |
| 142 | // animation completes. |
| 143 | class ShelfLayoutManager::UpdateShelfObserver |
| 144 | : public ui::ImplicitAnimationObserver { |
| 145 | public: |
| 146 | explicit UpdateShelfObserver(ShelfLayoutManager* shelf) : shelf_(shelf) { |
| 147 | shelf_->update_shelf_observer_ = this; |
| 148 | } |
| 149 | |
| 150 | void Detach() { |
| 151 | shelf_ = NULL; |
| 152 | } |
| 153 | |
| 154 | virtual void OnImplicitAnimationsCompleted() OVERRIDE { |
| 155 | if (shelf_) { |
| 156 | shelf_->UpdateShelfBackground( |
| 157 | internal::BackgroundAnimator::CHANGE_ANIMATE); |
| 158 | } |
| 159 | delete this; |
| 160 | } |
| 161 | |
| 162 | private: |
| 163 | virtual ~UpdateShelfObserver() { |
| 164 | if (shelf_) |
| 165 | shelf_->update_shelf_observer_ = NULL; |
| 166 | } |
| 167 | |
| 168 | // Shelf we're in. NULL if deleted before we're deleted. |
| 169 | ShelfLayoutManager* shelf_; |
| 170 | |
| 171 | DISALLOW_COPY_AND_ASSIGN(UpdateShelfObserver); |
| 172 | }; |
| 173 | |
| 174 | // ShelfLayoutManager ---------------------------------------------------------- |
[email protected] | 4bb1650 | 2011-12-06 14:44:58 | [diff] [blame] | 175 | |
[email protected] | 88d7112 | 2012-10-18 07:11:01 | [diff] [blame] | 176 | ShelfLayoutManager::ShelfLayoutManager(StatusAreaWidget* status_area_widget) |
| 177 | : root_window_(status_area_widget->GetNativeView()->GetRootWindow()), |
[email protected] | 8676f047 | 2012-03-29 20:30:12 | [diff] [blame] | 178 | in_layout_(false), |
[email protected] | eefd51b2 | 2012-09-25 20:26:24 | [diff] [blame] | 179 | auto_hide_behavior_(SHELF_AUTO_HIDE_BEHAVIOR_NEVER), |
[email protected] | 5544450 | 2012-05-10 15:43:53 | [diff] [blame] | 180 | alignment_(SHELF_ALIGNMENT_BOTTOM), |
[email protected] | 27f6af6 | 2012-03-21 05:34:40 | [diff] [blame] | 181 | launcher_(NULL), |
[email protected] | 88d7112 | 2012-10-18 07:11:01 | [diff] [blame] | 182 | status_area_widget_(status_area_widget), |
[email protected] | f4bb9fde | 2012-08-03 19:33:50 | [diff] [blame] | 183 | workspace_controller_(NULL), |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 184 | window_overlaps_shelf_(false), |
| 185 | gesture_drag_status_(GESTURE_DRAG_NONE), |
[email protected] | 4982ee1 | 2012-09-04 22:16:10 | [diff] [blame] | 186 | gesture_drag_amount_(0.f), |
[email protected] | e4d9fe9 | 2012-09-10 14:04:49 | [diff] [blame] | 187 | gesture_drag_auto_hide_state_(AUTO_HIDE_SHOWN), |
| 188 | update_shelf_observer_(NULL) { |
[email protected] | 8e43cdf4 | 2012-05-11 17:03:31 | [diff] [blame] | 189 | Shell::GetInstance()->AddShellObserver(this); |
[email protected] | e76310a9 | 2012-06-04 19:06:11 | [diff] [blame] | 190 | aura::client::GetActivationClient(root_window_)->AddObserver(this); |
[email protected] | ae18b911 | 2011-11-07 16:59:13 | [diff] [blame] | 191 | } |
| 192 | |
[email protected] | 4bb1650 | 2011-12-06 14:44:58 | [diff] [blame] | 193 | ShelfLayoutManager::~ShelfLayoutManager() { |
[email protected] | e4d9fe9 | 2012-09-10 14:04:49 | [diff] [blame] | 194 | if (update_shelf_observer_) |
| 195 | update_shelf_observer_->Detach(); |
| 196 | |
[email protected] | cbc278f | 2012-07-10 03:40:21 | [diff] [blame] | 197 | FOR_EACH_OBSERVER(Observer, observers_, WillDeleteShelf()); |
[email protected] | 8e43cdf4 | 2012-05-11 17:03:31 | [diff] [blame] | 198 | Shell::GetInstance()->RemoveShellObserver(this); |
[email protected] | e76310a9 | 2012-06-04 19:06:11 | [diff] [blame] | 199 | aura::client::GetActivationClient(root_window_)->RemoveObserver(this); |
[email protected] | ae18b911 | 2011-11-07 16:59:13 | [diff] [blame] | 200 | } |
| 201 | |
[email protected] | 09f3fc8 | 2012-03-26 23:26:56 | [diff] [blame] | 202 | void ShelfLayoutManager::SetAutoHideBehavior(ShelfAutoHideBehavior behavior) { |
| 203 | if (auto_hide_behavior_ == behavior) |
[email protected] | c758fbf | 2012-03-25 22:53:59 | [diff] [blame] | 204 | return; |
[email protected] | 09f3fc8 | 2012-03-26 23:26:56 | [diff] [blame] | 205 | auto_hide_behavior_ = behavior; |
[email protected] | c758fbf | 2012-03-25 22:53:59 | [diff] [blame] | 206 | UpdateVisibilityState(); |
[email protected] | cbc278f | 2012-07-10 03:40:21 | [diff] [blame] | 207 | FOR_EACH_OBSERVER(Observer, observers_, |
| 208 | OnAutoHideStateChanged(state_.auto_hide_state)); |
[email protected] | c758fbf | 2012-03-25 22:53:59 | [diff] [blame] | 209 | } |
| 210 | |
[email protected] | 40429f0 | 2012-03-28 20:38:50 | [diff] [blame] | 211 | bool ShelfLayoutManager::IsVisible() const { |
[email protected] | 88d7112 | 2012-10-18 07:11:01 | [diff] [blame] | 212 | return status_area_widget_->IsVisible() && |
| 213 | (state_.visibility_state == VISIBLE || |
| 214 | (state_.visibility_state == AUTO_HIDE && |
| 215 | state_.auto_hide_state == AUTO_HIDE_SHOWN)); |
[email protected] | 40429f0 | 2012-03-28 20:38:50 | [diff] [blame] | 216 | } |
| 217 | |
[email protected] | d9456cb | 2012-03-21 16:41:04 | [diff] [blame] | 218 | void ShelfLayoutManager::SetLauncher(Launcher* launcher) { |
| 219 | if (launcher == launcher_) |
| 220 | return; |
| 221 | |
| 222 | launcher_ = launcher; |
[email protected] | a5c63ce8 | 2012-07-18 18:48:57 | [diff] [blame] | 223 | if (launcher_) |
| 224 | launcher_->SetAlignment(alignment_); |
[email protected] | d9456cb | 2012-03-21 16:41:04 | [diff] [blame] | 225 | LayoutShelf(); |
| 226 | } |
| 227 | |
[email protected] | c2d58b4 | 2012-05-30 08:11:29 | [diff] [blame] | 228 | bool ShelfLayoutManager::SetAlignment(ShelfAlignment alignment) { |
[email protected] | 5544450 | 2012-05-10 15:43:53 | [diff] [blame] | 229 | if (alignment_ == alignment) |
[email protected] | c2d58b4 | 2012-05-30 08:11:29 | [diff] [blame] | 230 | return false; |
[email protected] | 5544450 | 2012-05-10 15:43:53 | [diff] [blame] | 231 | |
| 232 | alignment_ = alignment; |
| 233 | if (launcher_) |
| 234 | launcher_->SetAlignment(alignment); |
[email protected] | 88d7112 | 2012-10-18 07:11:01 | [diff] [blame] | 235 | status_area_widget_->SetShelfAlignment(alignment); |
[email protected] | 5544450 | 2012-05-10 15:43:53 | [diff] [blame] | 236 | LayoutShelf(); |
[email protected] | c2d58b4 | 2012-05-30 08:11:29 | [diff] [blame] | 237 | return true; |
[email protected] | 5544450 | 2012-05-10 15:43:53 | [diff] [blame] | 238 | } |
| 239 | |
| 240 | gfx::Rect ShelfLayoutManager::GetIdealBounds() { |
[email protected] | 8d625fb | 2012-07-18 16:40:06 | [diff] [blame] | 241 | // TODO(oshima): this is wrong. Figure out what display shelf is on |
| 242 | // and everything should be based on it. |
[email protected] | e2f64d10 | 2012-07-19 19:17:04 | [diff] [blame] | 243 | gfx::Rect bounds(ScreenAsh::GetDisplayBoundsInParent( |
[email protected] | 88d7112 | 2012-10-18 07:11:01 | [diff] [blame] | 244 | status_area_widget_->GetNativeView())); |
[email protected] | 5544450 | 2012-05-10 15:43:53 | [diff] [blame] | 245 | int width = 0, height = 0; |
| 246 | GetShelfSize(&width, &height); |
| 247 | switch (alignment_) { |
| 248 | case SHELF_ALIGNMENT_BOTTOM: |
| 249 | return gfx::Rect(bounds.x(), bounds.bottom() - height, |
| 250 | bounds.width(), height); |
| 251 | case SHELF_ALIGNMENT_LEFT: |
| 252 | return gfx::Rect(bounds.x(), bounds.y(), width, bounds.height()); |
| 253 | case SHELF_ALIGNMENT_RIGHT: |
[email protected] | 54a7c5a | 2012-05-24 19:54:20 | [diff] [blame] | 254 | return gfx::Rect(bounds.right() - width, bounds.y(), width, |
| 255 | bounds.height()); |
[email protected] | 5544450 | 2012-05-10 15:43:53 | [diff] [blame] | 256 | } |
| 257 | NOTREACHED(); |
| 258 | return gfx::Rect(); |
| 259 | } |
| 260 | |
[email protected] | 4bb1650 | 2011-12-06 14:44:58 | [diff] [blame] | 261 | void ShelfLayoutManager::LayoutShelf() { |
| 262 | AutoReset<bool> auto_reset_in_layout(&in_layout_, true); |
[email protected] | ae18b911 | 2011-11-07 16:59:13 | [diff] [blame] | 263 | StopAnimating(); |
| 264 | TargetBounds target_bounds; |
[email protected] | 27f6af6 | 2012-03-21 05:34:40 | [diff] [blame] | 265 | CalculateTargetBounds(state_, &target_bounds); |
[email protected] | d9456cb | 2012-03-21 16:41:04 | [diff] [blame] | 266 | if (launcher_widget()) { |
| 267 | GetLayer(launcher_widget())->SetOpacity(target_bounds.opacity); |
[email protected] | b7d0812 | 2012-09-16 18:24:46 | [diff] [blame] | 268 | launcher_->SetWidgetBounds( |
[email protected] | ec1930c3 | 2012-07-19 23:57:42 | [diff] [blame] | 269 | ScreenAsh::ConvertRectToScreen( |
| 270 | launcher_widget()->GetNativeView()->parent(), |
| 271 | target_bounds.launcher_bounds_in_root)); |
| 272 | launcher_->SetStatusSize(target_bounds.status_bounds_in_root.size()); |
[email protected] | 27f6af6 | 2012-03-21 05:34:40 | [diff] [blame] | 273 | } |
[email protected] | 88d7112 | 2012-10-18 07:11:01 | [diff] [blame] | 274 | GetLayer(status_area_widget_)->SetOpacity(target_bounds.opacity); |
| 275 | status_area_widget_->SetBounds( |
[email protected] | ec1930c3 | 2012-07-19 23:57:42 | [diff] [blame] | 276 | ScreenAsh::ConvertRectToScreen( |
[email protected] | 88d7112 | 2012-10-18 07:11:01 | [diff] [blame] | 277 | status_area_widget_->GetNativeView()->parent(), |
[email protected] | ec1930c3 | 2012-07-19 23:57:42 | [diff] [blame] | 278 | target_bounds.status_bounds_in_root)); |
[email protected] | 2e236a5 | 2012-06-27 22:21:47 | [diff] [blame] | 279 | Shell::GetInstance()->SetDisplayWorkAreaInsets( |
[email protected] | 42713f7 | 2012-05-25 00:41:50 | [diff] [blame] | 280 | Shell::GetPrimaryRootWindow(), |
[email protected] | ae18b911 | 2011-11-07 16:59:13 | [diff] [blame] | 281 | target_bounds.work_area_insets); |
[email protected] | 128fd373 | 2012-03-27 01:55:12 | [diff] [blame] | 282 | UpdateHitTestBounds(); |
[email protected] | ae18b911 | 2011-11-07 16:59:13 | [diff] [blame] | 283 | } |
| 284 | |
[email protected] | c758fbf | 2012-03-25 22:53:59 | [diff] [blame] | 285 | void ShelfLayoutManager::UpdateVisibilityState() { |
| 286 | ShellDelegate* delegate = Shell::GetInstance()->delegate(); |
| 287 | if (delegate && delegate->IsScreenLocked()) { |
| 288 | SetState(VISIBLE); |
[email protected] | 4982ee1 | 2012-09-04 22:16:10 | [diff] [blame] | 289 | } else if (gesture_drag_status_ == GESTURE_DRAG_COMPLETE_IN_PROGRESS) { |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 290 | SetState(AUTO_HIDE); |
[email protected] | c758fbf | 2012-03-25 22:53:59 | [diff] [blame] | 291 | } else { |
[email protected] | f4bb9fde | 2012-08-03 19:33:50 | [diff] [blame] | 292 | WorkspaceWindowState window_state(workspace_controller_->GetWindowState()); |
[email protected] | c758fbf | 2012-03-25 22:53:59 | [diff] [blame] | 293 | switch (window_state) { |
[email protected] | f4bb9fde | 2012-08-03 19:33:50 | [diff] [blame] | 294 | case WORKSPACE_WINDOW_STATE_FULL_SCREEN: |
[email protected] | c758fbf | 2012-03-25 22:53:59 | [diff] [blame] | 295 | SetState(HIDDEN); |
| 296 | break; |
| 297 | |
[email protected] | f4bb9fde | 2012-08-03 19:33:50 | [diff] [blame] | 298 | case WORKSPACE_WINDOW_STATE_MAXIMIZED: |
[email protected] | eefd51b2 | 2012-09-25 20:26:24 | [diff] [blame] | 299 | SetState(auto_hide_behavior_ == SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS ? |
| 300 | AUTO_HIDE : VISIBLE); |
[email protected] | c758fbf | 2012-03-25 22:53:59 | [diff] [blame] | 301 | break; |
| 302 | |
[email protected] | f4bb9fde | 2012-08-03 19:33:50 | [diff] [blame] | 303 | case WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF: |
| 304 | case WORKSPACE_WINDOW_STATE_DEFAULT: |
[email protected] | 09f3fc8 | 2012-03-26 23:26:56 | [diff] [blame] | 305 | SetState(auto_hide_behavior_ == SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS ? |
| 306 | AUTO_HIDE : VISIBLE); |
[email protected] | c758fbf | 2012-03-25 22:53:59 | [diff] [blame] | 307 | SetWindowOverlapsShelf(window_state == |
[email protected] | f4bb9fde | 2012-08-03 19:33:50 | [diff] [blame] | 308 | WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF); |
[email protected] | e4d9fe9 | 2012-09-10 14:04:49 | [diff] [blame] | 309 | break; |
[email protected] | c758fbf | 2012-03-25 22:53:59 | [diff] [blame] | 310 | } |
| 311 | } |
| 312 | } |
| 313 | |
| 314 | void ShelfLayoutManager::UpdateAutoHideState() { |
[email protected] | cadd8c4 | 2012-03-27 02:44:31 | [diff] [blame] | 315 | AutoHideState auto_hide_state = |
| 316 | CalculateAutoHideState(state_.visibility_state); |
| 317 | if (auto_hide_state != state_.auto_hide_state) { |
| 318 | if (auto_hide_state == AUTO_HIDE_HIDDEN) { |
| 319 | // Hides happen immediately. |
| 320 | SetState(state_.visibility_state); |
[email protected] | cbc278f | 2012-07-10 03:40:21 | [diff] [blame] | 321 | FOR_EACH_OBSERVER(Observer, observers_, |
| 322 | OnAutoHideStateChanged(auto_hide_state)); |
[email protected] | cadd8c4 | 2012-03-27 02:44:31 | [diff] [blame] | 323 | } else { |
| 324 | auto_hide_timer_.Stop(); |
[email protected] | c758fbf | 2012-03-25 22:53:59 | [diff] [blame] | 325 | auto_hide_timer_.Start( |
| 326 | FROM_HERE, |
| 327 | base::TimeDelta::FromMilliseconds(kAutoHideDelayMS), |
| 328 | this, &ShelfLayoutManager::UpdateAutoHideStateNow); |
[email protected] | cbc278f | 2012-07-10 03:40:21 | [diff] [blame] | 329 | FOR_EACH_OBSERVER(Observer, observers_, OnAutoHideStateChanged( |
| 330 | CalculateAutoHideState(state_.visibility_state))); |
[email protected] | c758fbf | 2012-03-25 22:53:59 | [diff] [blame] | 331 | } |
| 332 | } else { |
| 333 | auto_hide_timer_.Stop(); |
| 334 | } |
| 335 | } |
| 336 | |
| 337 | void ShelfLayoutManager::SetWindowOverlapsShelf(bool value) { |
| 338 | window_overlaps_shelf_ = value; |
| 339 | UpdateShelfBackground(internal::BackgroundAnimator::CHANGE_ANIMATE); |
| 340 | } |
| 341 | |
[email protected] | cbc278f | 2012-07-10 03:40:21 | [diff] [blame] | 342 | void ShelfLayoutManager::AddObserver(Observer* observer) { |
| 343 | observers_.AddObserver(observer); |
| 344 | } |
| 345 | |
| 346 | void ShelfLayoutManager::RemoveObserver(Observer* observer) { |
| 347 | observers_.RemoveObserver(observer); |
| 348 | } |
| 349 | |
[email protected] | c758fbf | 2012-03-25 22:53:59 | [diff] [blame] | 350 | //////////////////////////////////////////////////////////////////////////////// |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 351 | // ShelfLayoutManager, Gesture dragging: |
| 352 | |
| 353 | void ShelfLayoutManager::StartGestureDrag(const ui::GestureEvent& gesture) { |
| 354 | gesture_drag_status_ = GESTURE_DRAG_IN_PROGRESS; |
| 355 | gesture_drag_amount_ = 0.f; |
[email protected] | 4982ee1 | 2012-09-04 22:16:10 | [diff] [blame] | 356 | gesture_drag_auto_hide_state_ = visibility_state() == AUTO_HIDE ? |
| 357 | auto_hide_state() : AUTO_HIDE_SHOWN; |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 358 | UpdateShelfBackground(internal::BackgroundAnimator::CHANGE_ANIMATE); |
| 359 | } |
| 360 | |
[email protected] | c8e2e83 | 2012-09-12 21:48:28 | [diff] [blame] | 361 | ShelfLayoutManager::DragState ShelfLayoutManager::UpdateGestureDrag( |
| 362 | const ui::GestureEvent& gesture) { |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 363 | bool horizontal = alignment() == SHELF_ALIGNMENT_BOTTOM; |
| 364 | gesture_drag_amount_ += horizontal ? gesture.details().scroll_y() : |
| 365 | gesture.details().scroll_x(); |
| 366 | LayoutShelf(); |
[email protected] | c8e2e83 | 2012-09-12 21:48:28 | [diff] [blame] | 367 | |
| 368 | // Start reveling the status menu when: |
| 369 | // - dragging up on an already visible shelf |
| 370 | // - dragging up on a hidden shelf, but it is currently completely visible. |
| 371 | if (horizontal && gesture.details().scroll_y() < 0) { |
| 372 | int min_height = 0; |
| 373 | if (gesture_drag_auto_hide_state_ == AUTO_HIDE_HIDDEN && launcher_widget()) |
| 374 | min_height = launcher_widget()->GetContentsView()-> |
| 375 | GetPreferredSize().height(); |
| 376 | |
| 377 | if (min_height < launcher_widget()->GetWindowBoundsInScreen().height() && |
[email protected] | 88d7112 | 2012-10-18 07:11:01 | [diff] [blame] | 378 | gesture.root_location().x() >= |
| 379 | status_area_widget_->GetWindowBoundsInScreen().x() && |
[email protected] | fd42270 | 2012-09-25 17:45:14 | [diff] [blame] | 380 | IsDraggingTrayEnabled()) |
[email protected] | c8e2e83 | 2012-09-12 21:48:28 | [diff] [blame] | 381 | return DRAG_TRAY; |
| 382 | } |
| 383 | |
| 384 | return DRAG_SHELF; |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 385 | } |
| 386 | |
[email protected] | 4982ee1 | 2012-09-04 22:16:10 | [diff] [blame] | 387 | void ShelfLayoutManager::CompleteGestureDrag(const ui::GestureEvent& gesture) { |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 388 | bool horizontal = alignment() == SHELF_ALIGNMENT_BOTTOM; |
[email protected] | 4982ee1 | 2012-09-04 22:16:10 | [diff] [blame] | 389 | bool should_change = false; |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 390 | if (gesture.type() == ui::ET_GESTURE_SCROLL_END) { |
| 391 | // If the shelf was dragged X% towards the correct direction, then it is |
[email protected] | 4982ee1 | 2012-09-04 22:16:10 | [diff] [blame] | 392 | // hidden/shown. |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 393 | const float kDragHideThreshold = 0.4f; |
| 394 | gfx::Rect bounds = GetIdealBounds(); |
[email protected] | 4982ee1 | 2012-09-04 22:16:10 | [diff] [blame] | 395 | float drag_amount = gesture_drag_auto_hide_state_ == AUTO_HIDE_SHOWN ? |
| 396 | gesture_drag_amount_ : -gesture_drag_amount_; |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 397 | if (horizontal) |
[email protected] | 4982ee1 | 2012-09-04 22:16:10 | [diff] [blame] | 398 | should_change = drag_amount > kDragHideThreshold * bounds.height(); |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 399 | else if (alignment() == SHELF_ALIGNMENT_LEFT) |
[email protected] | 4982ee1 | 2012-09-04 22:16:10 | [diff] [blame] | 400 | should_change = -drag_amount > kDragHideThreshold * bounds.width(); |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 401 | else |
[email protected] | 4982ee1 | 2012-09-04 22:16:10 | [diff] [blame] | 402 | should_change = drag_amount > kDragHideThreshold * bounds.width(); |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 403 | } else if (gesture.type() == ui::ET_SCROLL_FLING_START) { |
| 404 | if (horizontal) |
[email protected] | 4982ee1 | 2012-09-04 22:16:10 | [diff] [blame] | 405 | should_change = gesture.details().velocity_y() > 0; |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 406 | else if (alignment() == SHELF_ALIGNMENT_LEFT) |
[email protected] | 4982ee1 | 2012-09-04 22:16:10 | [diff] [blame] | 407 | should_change = gesture.details().velocity_x() < 0; |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 408 | else |
[email protected] | 4982ee1 | 2012-09-04 22:16:10 | [diff] [blame] | 409 | should_change = gesture.details().velocity_x() > 0; |
| 410 | if (gesture_drag_auto_hide_state_ == AUTO_HIDE_HIDDEN) |
| 411 | should_change = !should_change; |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 412 | } else { |
| 413 | NOTREACHED(); |
| 414 | } |
| 415 | |
[email protected] | 4982ee1 | 2012-09-04 22:16:10 | [diff] [blame] | 416 | if (!should_change) { |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 417 | CancelGestureDrag(); |
| 418 | return; |
| 419 | } |
| 420 | |
[email protected] | 4982ee1 | 2012-09-04 22:16:10 | [diff] [blame] | 421 | gesture_drag_auto_hide_state_ = |
| 422 | gesture_drag_auto_hide_state_ == AUTO_HIDE_SHOWN ? AUTO_HIDE_HIDDEN : |
| 423 | AUTO_HIDE_SHOWN; |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 424 | if (launcher_widget()) |
| 425 | launcher_widget()->Deactivate(); |
[email protected] | 88d7112 | 2012-10-18 07:11:01 | [diff] [blame] | 426 | status_area_widget_->Deactivate(); |
[email protected] | e10392c | 2012-09-11 21:13:08 | [diff] [blame] | 427 | if (gesture_drag_auto_hide_state_ == AUTO_HIDE_HIDDEN && |
| 428 | auto_hide_behavior_ != SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS) { |
| 429 | gesture_drag_status_ = GESTURE_DRAG_NONE; |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 430 | SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); |
[email protected] | e10392c | 2012-09-11 21:13:08 | [diff] [blame] | 431 | } else if (gesture_drag_auto_hide_state_ == AUTO_HIDE_SHOWN && |
| 432 | auto_hide_behavior_ != SHELF_AUTO_HIDE_BEHAVIOR_NEVER) { |
| 433 | gesture_drag_status_ = GESTURE_DRAG_NONE; |
| 434 | SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); |
| 435 | } else { |
| 436 | gesture_drag_status_ = GESTURE_DRAG_COMPLETE_IN_PROGRESS; |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 437 | UpdateVisibilityState(); |
[email protected] | e10392c | 2012-09-11 21:13:08 | [diff] [blame] | 438 | gesture_drag_status_ = GESTURE_DRAG_NONE; |
| 439 | } |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 440 | } |
| 441 | |
| 442 | void ShelfLayoutManager::CancelGestureDrag() { |
[email protected] | e10392c | 2012-09-11 21:13:08 | [diff] [blame] | 443 | gesture_drag_status_ = GESTURE_DRAG_NONE; |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 444 | ui::ScopedLayerAnimationSettings |
| 445 | launcher_settings(GetLayer(launcher_widget())->GetAnimator()), |
[email protected] | 88d7112 | 2012-10-18 07:11:01 | [diff] [blame] | 446 | status_settings(GetLayer(status_area_widget_)->GetAnimator()); |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 447 | LayoutShelf(); |
| 448 | UpdateVisibilityState(); |
| 449 | UpdateShelfBackground(internal::BackgroundAnimator::CHANGE_ANIMATE); |
| 450 | } |
| 451 | |
| 452 | //////////////////////////////////////////////////////////////////////////////// |
[email protected] | c758fbf | 2012-03-25 22:53:59 | [diff] [blame] | 453 | // ShelfLayoutManager, aura::LayoutManager implementation: |
| 454 | |
| 455 | void ShelfLayoutManager::OnWindowResized() { |
| 456 | LayoutShelf(); |
| 457 | } |
| 458 | |
| 459 | void ShelfLayoutManager::OnWindowAddedToLayout(aura::Window* child) { |
| 460 | } |
| 461 | |
| 462 | void ShelfLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) { |
| 463 | } |
| 464 | |
[email protected] | fa893ab6 | 2012-04-20 01:26:51 | [diff] [blame] | 465 | void ShelfLayoutManager::OnWindowRemovedFromLayout(aura::Window* child) { |
| 466 | } |
| 467 | |
[email protected] | c758fbf | 2012-03-25 22:53:59 | [diff] [blame] | 468 | void ShelfLayoutManager::OnChildWindowVisibilityChanged(aura::Window* child, |
| 469 | bool visible) { |
| 470 | } |
| 471 | |
| 472 | void ShelfLayoutManager::SetChildBounds(aura::Window* child, |
| 473 | const gfx::Rect& requested_bounds) { |
| 474 | SetChildBoundsDirect(child, requested_bounds); |
[email protected] | 9d9b320 | 2012-09-09 22:39:32 | [diff] [blame] | 475 | // We may contain other widgets (such as frame maximize bubble) but they don't |
| 476 | // effect the layout in anyway. |
| 477 | if (!in_layout_ && |
| 478 | ((launcher_widget() && launcher_widget()->GetNativeView() == child) || |
[email protected] | 88d7112 | 2012-10-18 07:11:01 | [diff] [blame] | 479 | (status_area_widget_->GetNativeView() == child))) { |
[email protected] | c758fbf | 2012-03-25 22:53:59 | [diff] [blame] | 480 | LayoutShelf(); |
[email protected] | 9d9b320 | 2012-09-09 22:39:32 | [diff] [blame] | 481 | } |
[email protected] | c758fbf | 2012-03-25 22:53:59 | [diff] [blame] | 482 | } |
| 483 | |
[email protected] | 8e43cdf4 | 2012-05-11 17:03:31 | [diff] [blame] | 484 | void ShelfLayoutManager::OnLockStateChanged(bool locked) { |
| 485 | UpdateVisibilityState(); |
| 486 | } |
| 487 | |
[email protected] | e76310a9 | 2012-06-04 19:06:11 | [diff] [blame] | 488 | void ShelfLayoutManager::OnWindowActivated(aura::Window* active, |
| 489 | aura::Window* old_active) { |
| 490 | UpdateAutoHideStateNow(); |
[email protected] | 8676f047 | 2012-03-29 20:30:12 | [diff] [blame] | 491 | } |
| 492 | |
[email protected] | c758fbf | 2012-03-25 22:53:59 | [diff] [blame] | 493 | //////////////////////////////////////////////////////////////////////////////// |
| 494 | // ShelfLayoutManager, private: |
| 495 | |
[email protected] | 9e52129b9 | 2012-08-09 16:14:30 | [diff] [blame] | 496 | ShelfLayoutManager::TargetBounds::TargetBounds() : opacity(0.0f) {} |
| 497 | |
[email protected] | b1c37fc | 2012-03-22 03:36:13 | [diff] [blame] | 498 | void ShelfLayoutManager::SetState(VisibilityState visibility_state) { |
[email protected] | 751444a | 2012-04-03 04:57:14 | [diff] [blame] | 499 | ShellDelegate* delegate = Shell::GetInstance()->delegate(); |
[email protected] | 27f6af6 | 2012-03-21 05:34:40 | [diff] [blame] | 500 | State state; |
[email protected] | c758fbf | 2012-03-25 22:53:59 | [diff] [blame] | 501 | state.visibility_state = visibility_state; |
[email protected] | b1c37fc | 2012-03-22 03:36:13 | [diff] [blame] | 502 | state.auto_hide_state = CalculateAutoHideState(visibility_state); |
[email protected] | 751444a | 2012-04-03 04:57:14 | [diff] [blame] | 503 | state.is_screen_locked = delegate && delegate->IsScreenLocked(); |
[email protected] | 30676816 | 2012-02-02 02:04:41 | [diff] [blame] | 504 | |
[email protected] | b7d0812 | 2012-09-16 18:24:46 | [diff] [blame] | 505 | // It's possible for SetState() when a window becomes maximized but the state |
| 506 | // won't have changed value. Do the dimming check before the early exit. |
| 507 | if (launcher_ && workspace_controller_) { |
| 508 | launcher_->SetDimsShelf( |
| 509 | (state.visibility_state == VISIBLE) && |
| 510 | workspace_controller_->GetWindowState() == |
| 511 | WORKSPACE_WINDOW_STATE_MAXIMIZED); |
| 512 | } |
| 513 | |
[email protected] | 27f6af6 | 2012-03-21 05:34:40 | [diff] [blame] | 514 | if (state_.Equals(state)) |
[email protected] | ae18b911 | 2011-11-07 16:59:13 | [diff] [blame] | 515 | return; // Nothing changed. |
| 516 | |
[email protected] | cbc278f | 2012-07-10 03:40:21 | [diff] [blame] | 517 | FOR_EACH_OBSERVER(Observer, observers_, |
| 518 | WillChangeVisibilityState(visibility_state)); |
| 519 | |
[email protected] | b1c37fc | 2012-03-22 03:36:13 | [diff] [blame] | 520 | if (state.visibility_state == AUTO_HIDE) { |
| 521 | // When state is AUTO_HIDE we need to track when the mouse is over the |
| 522 | // launcher to unhide the shelf. AutoHideEventFilter does that for us. |
| 523 | if (!event_filter_.get()) |
| 524 | event_filter_.reset(new AutoHideEventFilter(this)); |
| 525 | } else { |
| 526 | event_filter_.reset(NULL); |
| 527 | } |
| 528 | |
| 529 | auto_hide_timer_.Stop(); |
| 530 | |
[email protected] | 27f6af6 | 2012-03-21 05:34:40 | [diff] [blame] | 531 | // Animating the background when transitioning from auto-hide & hidden to |
[email protected] | e4d9fe9 | 2012-09-10 14:04:49 | [diff] [blame] | 532 | // visible is janky. Update the background immediately in this case. |
[email protected] | a160baec | 2012-03-21 20:52:15 | [diff] [blame] | 533 | internal::BackgroundAnimator::ChangeType change_type = |
[email protected] | 27f6af6 | 2012-03-21 05:34:40 | [diff] [blame] | 534 | (state_.visibility_state == AUTO_HIDE && |
| 535 | state_.auto_hide_state == AUTO_HIDE_HIDDEN && |
| 536 | state.visibility_state == VISIBLE) ? |
[email protected] | a160baec | 2012-03-21 20:52:15 | [diff] [blame] | 537 | internal::BackgroundAnimator::CHANGE_IMMEDIATE : |
| 538 | internal::BackgroundAnimator::CHANGE_ANIMATE; |
[email protected] | ae18b911 | 2011-11-07 16:59:13 | [diff] [blame] | 539 | StopAnimating(); |
[email protected] | e10392c | 2012-09-11 21:13:08 | [diff] [blame] | 540 | |
| 541 | State old_state = state_; |
[email protected] | 27f6af6 | 2012-03-21 05:34:40 | [diff] [blame] | 542 | state_ = state; |
[email protected] | ae18b911 | 2011-11-07 16:59:13 | [diff] [blame] | 543 | TargetBounds target_bounds; |
[email protected] | 27f6af6 | 2012-03-21 05:34:40 | [diff] [blame] | 544 | CalculateTargetBounds(state_, &target_bounds); |
[email protected] | d9456cb | 2012-03-21 16:41:04 | [diff] [blame] | 545 | if (launcher_widget()) { |
[email protected] | 27f6af6 | 2012-03-21 05:34:40 | [diff] [blame] | 546 | ui::ScopedLayerAnimationSettings launcher_animation_setter( |
[email protected] | d9456cb | 2012-03-21 16:41:04 | [diff] [blame] | 547 | GetLayer(launcher_widget())->GetAnimator()); |
[email protected] | 27f6af6 | 2012-03-21 05:34:40 | [diff] [blame] | 548 | launcher_animation_setter.SetTransitionDuration( |
[email protected] | c96b981 | 2012-10-17 16:04:04 | [diff] [blame] | 549 | base::TimeDelta::FromMilliseconds(kWorkspaceSwitchTimeMS)); |
[email protected] | 27f6af6 | 2012-03-21 05:34:40 | [diff] [blame] | 550 | launcher_animation_setter.SetTweenType(ui::Tween::EASE_OUT); |
[email protected] | ec1930c3 | 2012-07-19 23:57:42 | [diff] [blame] | 551 | GetLayer(launcher_widget())->SetBounds( |
| 552 | target_bounds.launcher_bounds_in_root); |
[email protected] | d9456cb | 2012-03-21 16:41:04 | [diff] [blame] | 553 | GetLayer(launcher_widget())->SetOpacity(target_bounds.opacity); |
[email protected] | 27f6af6 | 2012-03-21 05:34:40 | [diff] [blame] | 554 | } |
[email protected] | 30676816 | 2012-02-02 02:04:41 | [diff] [blame] | 555 | ui::ScopedLayerAnimationSettings status_animation_setter( |
[email protected] | 88d7112 | 2012-10-18 07:11:01 | [diff] [blame] | 556 | GetLayer(status_area_widget_)->GetAnimator()); |
[email protected] | 27f6af6 | 2012-03-21 05:34:40 | [diff] [blame] | 557 | status_animation_setter.SetTransitionDuration( |
[email protected] | c96b981 | 2012-10-17 16:04:04 | [diff] [blame] | 558 | base::TimeDelta::FromMilliseconds(kWorkspaceSwitchTimeMS)); |
[email protected] | 27f6af6 | 2012-03-21 05:34:40 | [diff] [blame] | 559 | status_animation_setter.SetTweenType(ui::Tween::EASE_OUT); |
[email protected] | e10392c | 2012-09-11 21:13:08 | [diff] [blame] | 560 | |
[email protected] | e4d9fe9 | 2012-09-10 14:04:49 | [diff] [blame] | 561 | // Delay updating the background when going from AUTO_HIDE_SHOWN to |
| 562 | // AUTO_HIDE_HIDDEN until the shelf animates out. Otherwise during the |
| 563 | // animation you see the background change. |
[email protected] | e10392c | 2012-09-11 21:13:08 | [diff] [blame] | 564 | // Also delay the animation when the shelf was hidden, and has just been made |
| 565 | // visible (e.g. using a gesture-drag). |
| 566 | bool delay_shelf_update = |
| 567 | state.visibility_state == AUTO_HIDE && |
[email protected] | e4d9fe9 | 2012-09-10 14:04:49 | [diff] [blame] | 568 | state.auto_hide_state == AUTO_HIDE_HIDDEN && |
[email protected] | e10392c | 2012-09-11 21:13:08 | [diff] [blame] | 569 | old_state.visibility_state == AUTO_HIDE; |
| 570 | |
| 571 | if (state.visibility_state == VISIBLE && |
| 572 | old_state.visibility_state == AUTO_HIDE && |
| 573 | old_state.auto_hide_state == AUTO_HIDE_HIDDEN) |
| 574 | delay_shelf_update = true; |
| 575 | |
[email protected] | e4d9fe9 | 2012-09-10 14:04:49 | [diff] [blame] | 576 | if (delay_shelf_update) { |
| 577 | if (update_shelf_observer_) |
| 578 | update_shelf_observer_->Detach(); |
| 579 | // UpdateShelfBackground deletes itself when the animation is done. |
| 580 | update_shelf_observer_ = new UpdateShelfObserver(this); |
| 581 | status_animation_setter.AddObserver(update_shelf_observer_); |
| 582 | } |
[email protected] | 88d7112 | 2012-10-18 07:11:01 | [diff] [blame] | 583 | ui::Layer* layer = GetLayer(status_area_widget_); |
| 584 | layer->SetBounds(target_bounds.status_bounds_in_root); |
| 585 | layer->SetOpacity(target_bounds.opacity); |
[email protected] | 2e236a5 | 2012-06-27 22:21:47 | [diff] [blame] | 586 | Shell::GetInstance()->SetDisplayWorkAreaInsets( |
[email protected] | 42713f7 | 2012-05-25 00:41:50 | [diff] [blame] | 587 | Shell::GetPrimaryRootWindow(), |
[email protected] | 27f6af6 | 2012-03-21 05:34:40 | [diff] [blame] | 588 | target_bounds.work_area_insets); |
[email protected] | 128fd373 | 2012-03-27 01:55:12 | [diff] [blame] | 589 | UpdateHitTestBounds(); |
[email protected] | e4d9fe9 | 2012-09-10 14:04:49 | [diff] [blame] | 590 | if (!delay_shelf_update) |
| 591 | UpdateShelfBackground(change_type); |
[email protected] | 27f6af6 | 2012-03-21 05:34:40 | [diff] [blame] | 592 | } |
[email protected] | 63ef2159 | 2012-03-21 01:15:40 | [diff] [blame] | 593 | |
[email protected] | 4bb1650 | 2011-12-06 14:44:58 | [diff] [blame] | 594 | void ShelfLayoutManager::StopAnimating() { |
[email protected] | 88d7112 | 2012-10-18 07:11:01 | [diff] [blame] | 595 | ui::Layer* layer = GetLayer(status_area_widget_); |
[email protected] | d9456cb | 2012-03-21 16:41:04 | [diff] [blame] | 596 | if (launcher_widget()) |
[email protected] | 88d7112 | 2012-10-18 07:11:01 | [diff] [blame] | 597 | layer->GetAnimator()->StopAnimating(); |
| 598 | layer->GetAnimator()->StopAnimating(); |
[email protected] | ae18b911 | 2011-11-07 16:59:13 | [diff] [blame] | 599 | } |
| 600 | |
[email protected] | 5544450 | 2012-05-10 15:43:53 | [diff] [blame] | 601 | void ShelfLayoutManager::GetShelfSize(int* width, int* height) { |
| 602 | *width = *height = 0; |
[email protected] | 88d7112 | 2012-10-18 07:11:01 | [diff] [blame] | 603 | gfx::Size status_size(status_area_widget_->GetWindowBoundsInScreen().size()); |
[email protected] | 5544450 | 2012-05-10 15:43:53 | [diff] [blame] | 604 | gfx::Size launcher_size = launcher_ ? |
| 605 | launcher_widget()->GetContentsView()->GetPreferredSize() : gfx::Size(); |
[email protected] | 0ab08e5 | 2012-05-19 00:04:21 | [diff] [blame] | 606 | if (alignment_ == SHELF_ALIGNMENT_BOTTOM) |
[email protected] | ec1930c3 | 2012-07-19 23:57:42 | [diff] [blame] | 607 | *height = std::max(launcher_size.height(), status_size.height()); |
[email protected] | 0ab08e5 | 2012-05-19 00:04:21 | [diff] [blame] | 608 | else |
[email protected] | ec1930c3 | 2012-07-19 23:57:42 | [diff] [blame] | 609 | *width = std::max(launcher_size.width(), status_size.width()); |
[email protected] | 5544450 | 2012-05-10 15:43:53 | [diff] [blame] | 610 | } |
| 611 | |
| 612 | void ShelfLayoutManager::AdjustBoundsBasedOnAlignment(int inset, |
| 613 | gfx::Rect* bounds) const { |
| 614 | switch (alignment_) { |
| 615 | case SHELF_ALIGNMENT_BOTTOM: |
| 616 | bounds->Inset(gfx::Insets(0, 0, inset, 0)); |
| 617 | break; |
| 618 | case SHELF_ALIGNMENT_LEFT: |
| 619 | bounds->Inset(gfx::Insets(0, inset, 0, 0)); |
| 620 | break; |
| 621 | case SHELF_ALIGNMENT_RIGHT: |
| 622 | bounds->Inset(gfx::Insets(0, 0, 0, inset)); |
| 623 | break; |
| 624 | } |
| 625 | } |
| 626 | |
[email protected] | 27f6af6 | 2012-03-21 05:34:40 | [diff] [blame] | 627 | void ShelfLayoutManager::CalculateTargetBounds( |
| 628 | const State& state, |
[email protected] | 5544450 | 2012-05-10 15:43:53 | [diff] [blame] | 629 | TargetBounds* target_bounds) { |
[email protected] | 88d7112 | 2012-10-18 07:11:01 | [diff] [blame] | 630 | const gfx::Rect& available_bounds(root_window_->bounds()); |
| 631 | gfx::Rect status_size(status_area_widget_->GetWindowBoundsInScreen().size()); |
[email protected] | 5544450 | 2012-05-10 15:43:53 | [diff] [blame] | 632 | gfx::Size launcher_size = launcher_ ? |
| 633 | launcher_widget()->GetContentsView()->GetPreferredSize() : gfx::Size(); |
| 634 | int shelf_size = 0; |
| 635 | int shelf_width = 0, shelf_height = 0; |
| 636 | GetShelfSize(&shelf_width, &shelf_height); |
[email protected] | 27f6af6 | 2012-03-21 05:34:40 | [diff] [blame] | 637 | if (state.visibility_state == VISIBLE || |
| 638 | (state.visibility_state == AUTO_HIDE && |
[email protected] | 5544450 | 2012-05-10 15:43:53 | [diff] [blame] | 639 | state.auto_hide_state == AUTO_HIDE_SHOWN)) { |
| 640 | shelf_size = std::max(shelf_width, shelf_height); |
| 641 | } else if (state.visibility_state == AUTO_HIDE && |
| 642 | state.auto_hide_state == AUTO_HIDE_HIDDEN) { |
| 643 | shelf_size = kAutoHideSize; |
[email protected] | 7b675df61 | 2012-09-16 18:33:20 | [diff] [blame] | 644 | // Keep the launcher to its full height when dragging is in progress. |
| 645 | if (gesture_drag_status_ == GESTURE_DRAG_NONE) |
| 646 | launcher_size.set_height(kAutoHideSize); |
[email protected] | 27f6af6 | 2012-03-21 05:34:40 | [diff] [blame] | 647 | } |
[email protected] | 5544450 | 2012-05-10 15:43:53 | [diff] [blame] | 648 | if (alignment_ == SHELF_ALIGNMENT_BOTTOM) { |
| 649 | int y = available_bounds.bottom(); |
| 650 | y -= shelf_size; |
| 651 | // The status widget should extend to the bottom and right edges. |
[email protected] | ec1930c3 | 2012-07-19 23:57:42 | [diff] [blame] | 652 | target_bounds->status_bounds_in_root = gfx::Rect( |
[email protected] | 5544450 | 2012-05-10 15:43:53 | [diff] [blame] | 653 | base::i18n::IsRTL() ? available_bounds.x() : |
[email protected] | ec1930c3 | 2012-07-19 23:57:42 | [diff] [blame] | 654 | available_bounds.right() - status_size.width(), |
| 655 | y + shelf_height - status_size.height(), |
| 656 | status_size.width(), status_size.height()); |
[email protected] | 5544450 | 2012-05-10 15:43:53 | [diff] [blame] | 657 | if (launcher_widget()) { |
[email protected] | ec1930c3 | 2012-07-19 23:57:42 | [diff] [blame] | 658 | target_bounds->launcher_bounds_in_root = gfx::Rect( |
[email protected] | 5544450 | 2012-05-10 15:43:53 | [diff] [blame] | 659 | available_bounds.x(), |
[email protected] | 7b675df61 | 2012-09-16 18:33:20 | [diff] [blame] | 660 | y, |
[email protected] | 5544450 | 2012-05-10 15:43:53 | [diff] [blame] | 661 | available_bounds.width(), |
| 662 | launcher_size.height()); |
| 663 | } |
| 664 | target_bounds->work_area_insets.Set( |
| 665 | 0, 0, GetWorkAreaSize(state, shelf_height), 0); |
| 666 | } else { |
| 667 | int x = (alignment_ == SHELF_ALIGNMENT_LEFT) ? |
| 668 | available_bounds.x() + shelf_size - shelf_width : |
| 669 | available_bounds.right() - shelf_size; |
[email protected] | ec1930c3 | 2012-07-19 23:57:42 | [diff] [blame] | 670 | target_bounds->status_bounds_in_root = gfx::Rect( |
| 671 | x, available_bounds.bottom() - status_size.height(), |
| 672 | shelf_width, status_size.height()); |
[email protected] | 5544450 | 2012-05-10 15:43:53 | [diff] [blame] | 673 | if (launcher_widget()) { |
[email protected] | ec1930c3 | 2012-07-19 23:57:42 | [diff] [blame] | 674 | target_bounds->launcher_bounds_in_root = gfx::Rect( |
[email protected] | 5544450 | 2012-05-10 15:43:53 | [diff] [blame] | 675 | x, |
| 676 | available_bounds.y(), |
| 677 | launcher_size.width(), |
| 678 | available_bounds.height()); |
| 679 | } |
| 680 | if (alignment_ == SHELF_ALIGNMENT_LEFT) { |
| 681 | target_bounds->work_area_insets.Set( |
| 682 | 0, GetWorkAreaSize(state, shelf_width), 0, 0); |
| 683 | } else { |
| 684 | target_bounds->work_area_insets.Set( |
| 685 | 0, 0, 0, GetWorkAreaSize(state, shelf_width)); |
| 686 | } |
| 687 | } |
[email protected] | 27f6af6 | 2012-03-21 05:34:40 | [diff] [blame] | 688 | target_bounds->opacity = |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 689 | (gesture_drag_status_ != GESTURE_DRAG_NONE || |
| 690 | state.visibility_state == VISIBLE || |
[email protected] | 27f6af6 | 2012-03-21 05:34:40 | [diff] [blame] | 691 | state.visibility_state == AUTO_HIDE) ? 1.0f : 0.0f; |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 692 | if (gesture_drag_status_ == GESTURE_DRAG_IN_PROGRESS) |
| 693 | UpdateTargetBoundsForGesture(target_bounds); |
| 694 | } |
| 695 | |
| 696 | void ShelfLayoutManager::UpdateTargetBoundsForGesture( |
| 697 | TargetBounds* target_bounds) const { |
| 698 | CHECK_EQ(GESTURE_DRAG_IN_PROGRESS, gesture_drag_status_); |
| 699 | bool horizontal = alignment() == SHELF_ALIGNMENT_BOTTOM; |
[email protected] | 407ffd3 | 2012-09-11 17:47:36 | [diff] [blame] | 700 | int resistance_free_region = 0; |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 701 | |
[email protected] | c8e2e83 | 2012-09-12 21:48:28 | [diff] [blame] | 702 | if (gesture_drag_auto_hide_state_ == AUTO_HIDE_HIDDEN && |
| 703 | visibility_state() == AUTO_HIDE && auto_hide_state() != AUTO_HIDE_SHOWN) { |
| 704 | // If the shelf was hidden when the drag started (and the state hasn't |
| 705 | // changed since then, e.g. because the tray-menu was shown because of the |
| 706 | // drag), then allow the drag some resistance-free region at first to make |
| 707 | // sure the shelf sticks with the finger until the shelf is visible. |
[email protected] | 91d966a7 | 2012-09-06 03:42:27 | [diff] [blame] | 708 | resistance_free_region += horizontal ? |
[email protected] | 4982ee1 | 2012-09-04 22:16:10 | [diff] [blame] | 709 | target_bounds->launcher_bounds_in_root.height() : |
| 710 | target_bounds->launcher_bounds_in_root.width(); |
[email protected] | 91d966a7 | 2012-09-06 03:42:27 | [diff] [blame] | 711 | resistance_free_region -= kAutoHideSize; |
| 712 | } |
| 713 | |
| 714 | bool resist = false; |
| 715 | if (horizontal) |
| 716 | resist = gesture_drag_amount_ < -resistance_free_region; |
| 717 | else if (alignment() == SHELF_ALIGNMENT_LEFT) |
| 718 | resist = gesture_drag_amount_ > resistance_free_region; |
| 719 | else |
| 720 | resist = gesture_drag_amount_ < -resistance_free_region; |
| 721 | |
| 722 | float translate = 0.f; |
| 723 | if (resist) { |
| 724 | float diff = fabsf(gesture_drag_amount_) - resistance_free_region; |
[email protected] | 407ffd3 | 2012-09-11 17:47:36 | [diff] [blame] | 725 | diff = std::min(diff, sqrtf(diff)); |
[email protected] | 91d966a7 | 2012-09-06 03:42:27 | [diff] [blame] | 726 | if (gesture_drag_amount_ < 0) |
| 727 | translate = -resistance_free_region - diff; |
| 728 | else |
| 729 | translate = resistance_free_region + diff; |
[email protected] | 4982ee1 | 2012-09-04 22:16:10 | [diff] [blame] | 730 | } else { |
[email protected] | 91d966a7 | 2012-09-06 03:42:27 | [diff] [blame] | 731 | translate = gesture_drag_amount_; |
[email protected] | 4982ee1 | 2012-09-04 22:16:10 | [diff] [blame] | 732 | } |
| 733 | |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 734 | if (horizontal) { |
[email protected] | 91d966a7 | 2012-09-06 03:42:27 | [diff] [blame] | 735 | // Move the launcher with the gesture. |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 736 | target_bounds->launcher_bounds_in_root.Offset(0, translate); |
[email protected] | 91d966a7 | 2012-09-06 03:42:27 | [diff] [blame] | 737 | |
| 738 | if (translate > 0) { |
| 739 | // When dragging down, the statusbar should move. |
| 740 | target_bounds->status_bounds_in_root.Offset(0, translate); |
| 741 | } else { |
| 742 | // When dragging up, the launcher height should increase. |
[email protected] | 91d966a7 | 2012-09-06 03:42:27 | [diff] [blame] | 743 | float move = std::max(translate, |
| 744 | -static_cast<float>(resistance_free_region)); |
| 745 | target_bounds->launcher_bounds_in_root.set_height( |
| 746 | target_bounds->launcher_bounds_in_root.height() + move - translate); |
| 747 | |
[email protected] | 407ffd3 | 2012-09-11 17:47:36 | [diff] [blame] | 748 | // The statusbar should be in the center. |
| 749 | gfx::Rect status_y = target_bounds->launcher_bounds_in_root.Center( |
| 750 | target_bounds->status_bounds_in_root.size()); |
| 751 | target_bounds->status_bounds_in_root.set_y(status_y.y()); |
[email protected] | 91d966a7 | 2012-09-06 03:42:27 | [diff] [blame] | 752 | } |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 753 | } else { |
[email protected] | 91d966a7 | 2012-09-06 03:42:27 | [diff] [blame] | 754 | // Move the launcher with the gesture. |
| 755 | if (alignment() == SHELF_ALIGNMENT_RIGHT) |
| 756 | target_bounds->launcher_bounds_in_root.Offset(translate, 0); |
| 757 | |
| 758 | if ((translate > 0 && alignment() == SHELF_ALIGNMENT_RIGHT) || |
| 759 | (translate < 0 && alignment() == SHELF_ALIGNMENT_LEFT)) { |
| 760 | // When dragging towards the edge, the statusbar should move. |
| 761 | target_bounds->status_bounds_in_root.Offset(translate, 0); |
| 762 | } else { |
| 763 | // When dragging away from the edge, the launcher width should increase. |
[email protected] | 91d966a7 | 2012-09-06 03:42:27 | [diff] [blame] | 764 | float move = alignment() == SHELF_ALIGNMENT_RIGHT ? |
| 765 | std::max(translate, -static_cast<float>(resistance_free_region)) : |
| 766 | std::min(translate, static_cast<float>(resistance_free_region)); |
| 767 | |
| 768 | if (alignment() == SHELF_ALIGNMENT_RIGHT) { |
| 769 | target_bounds->launcher_bounds_in_root.set_width( |
| 770 | target_bounds->launcher_bounds_in_root.width() + move - translate); |
[email protected] | 91d966a7 | 2012-09-06 03:42:27 | [diff] [blame] | 771 | } else { |
| 772 | target_bounds->launcher_bounds_in_root.set_width( |
| 773 | target_bounds->launcher_bounds_in_root.width() - move + translate); |
[email protected] | 91d966a7 | 2012-09-06 03:42:27 | [diff] [blame] | 774 | } |
| 775 | |
[email protected] | 407ffd3 | 2012-09-11 17:47:36 | [diff] [blame] | 776 | // The statusbar should be in the center. |
| 777 | gfx::Rect status_x = target_bounds->launcher_bounds_in_root.Center( |
| 778 | target_bounds->status_bounds_in_root.size()); |
| 779 | target_bounds->status_bounds_in_root.set_x(status_x.x()); |
[email protected] | 91d966a7 | 2012-09-06 03:42:27 | [diff] [blame] | 780 | } |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 781 | } |
[email protected] | ae18b911 | 2011-11-07 16:59:13 | [diff] [blame] | 782 | } |
| 783 | |
[email protected] | a160baec | 2012-03-21 20:52:15 | [diff] [blame] | 784 | void ShelfLayoutManager::UpdateShelfBackground( |
| 785 | BackgroundAnimator::ChangeType type) { |
| 786 | bool launcher_paints = GetLauncherPaintsBackground(); |
| 787 | if (launcher_) |
| 788 | launcher_->SetPaintsBackground(launcher_paints, type); |
[email protected] | 71ac7f09 | 2012-08-21 02:31:50 | [diff] [blame] | 789 | // The status area normally draws a background, but we don't want it to draw a |
[email protected] | 8fbbf81 | 2012-09-17 15:09:18 | [diff] [blame] | 790 | // background when the launcher does or when we're at login/lock screen. |
[email protected] | 88d7112 | 2012-10-18 07:11:01 | [diff] [blame] | 791 | ShellDelegate* delegate = Shell::GetInstance()->delegate(); |
| 792 | bool delegate_allows_tray_bg = !delegate || |
| 793 | (delegate->IsUserLoggedIn() && !delegate->IsScreenLocked()); |
| 794 | bool status_area_paints = !launcher_paints && delegate_allows_tray_bg; |
| 795 | status_area_widget_->SetPaintsBackground(status_area_paints, type); |
[email protected] | a160baec | 2012-03-21 20:52:15 | [diff] [blame] | 796 | } |
| 797 | |
| 798 | bool ShelfLayoutManager::GetLauncherPaintsBackground() const { |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 799 | return gesture_drag_status_ != GESTURE_DRAG_NONE || |
| 800 | (!state_.is_screen_locked && window_overlaps_shelf_) || |
[email protected] | 7b675df61 | 2012-09-16 18:33:20 | [diff] [blame] | 801 | (state_.visibility_state == AUTO_HIDE) ; |
[email protected] | ae18b911 | 2011-11-07 16:59:13 | [diff] [blame] | 802 | } |
| 803 | |
[email protected] | b1c37fc | 2012-03-22 03:36:13 | [diff] [blame] | 804 | void ShelfLayoutManager::UpdateAutoHideStateNow() { |
| 805 | SetState(state_.visibility_state); |
| 806 | } |
| 807 | |
| 808 | ShelfLayoutManager::AutoHideState ShelfLayoutManager::CalculateAutoHideState( |
| 809 | VisibilityState visibility_state) const { |
| 810 | if (visibility_state != AUTO_HIDE || !launcher_widget()) |
| 811 | return AUTO_HIDE_HIDDEN; |
| 812 | |
[email protected] | 4982ee1 | 2012-09-04 22:16:10 | [diff] [blame] | 813 | if (gesture_drag_status_ == GESTURE_DRAG_COMPLETE_IN_PROGRESS) |
| 814 | return gesture_drag_auto_hide_state_; |
[email protected] | 3c6abbe | 2012-08-30 23:48:57 | [diff] [blame] | 815 | |
[email protected] | b1c37fc | 2012-03-22 03:36:13 | [diff] [blame] | 816 | Shell* shell = Shell::GetInstance(); |
[email protected] | 7510d108 | 2012-03-30 21:58:34 | [diff] [blame] | 817 | if (shell->GetAppListTargetVisibility()) |
| 818 | return AUTO_HIDE_SHOWN; |
| 819 | |
[email protected] | 88d7112 | 2012-10-18 07:11:01 | [diff] [blame] | 820 | if (status_area_widget_ && status_area_widget_->ShouldShowLauncher()) |
[email protected] | d9d5a92 | 2012-03-26 04:38:03 | [diff] [blame] | 821 | return AUTO_HIDE_SHOWN; |
[email protected] | b1c37fc | 2012-03-22 03:36:13 | [diff] [blame] | 822 | |
[email protected] | e9992b1 | 2012-03-27 00:11:27 | [diff] [blame] | 823 | if (launcher_ && launcher_->IsShowingMenu()) |
| 824 | return AUTO_HIDE_SHOWN; |
| 825 | |
[email protected] | 3475f5e | 2012-07-12 22:10:32 | [diff] [blame] | 826 | if (launcher_ && launcher_->IsShowingOverflowBubble()) |
| 827 | return AUTO_HIDE_SHOWN; |
| 828 | |
[email protected] | 88d7112 | 2012-10-18 07:11:01 | [diff] [blame] | 829 | if (launcher_widget()->IsActive() || status_area_widget_->IsActive()) |
[email protected] | 8676f047 | 2012-03-29 20:30:12 | [diff] [blame] | 830 | return AUTO_HIDE_SHOWN; |
| 831 | |
[email protected] | 5f1d99dc | 2012-04-12 21:42:37 | [diff] [blame] | 832 | // Don't show if the user is dragging the mouse. |
| 833 | if (event_filter_.get() && event_filter_->in_mouse_drag()) |
| 834 | return AUTO_HIDE_HIDDEN; |
| 835 | |
[email protected] | 2e195f5 | 2012-09-22 00:24:46 | [diff] [blame] | 836 | gfx::Rect shelf_region = launcher_widget()->GetWindowBoundsInScreen(); |
[email protected] | 88d7112 | 2012-10-18 07:11:01 | [diff] [blame] | 837 | if (status_area_widget_ && |
| 838 | status_area_widget_->IsMessageBubbleShown() && |
[email protected] | 2e195f5 | 2012-09-22 00:24:46 | [diff] [blame] | 839 | IsVisible()) { |
| 840 | // Increase the the hit test area to prevent the shelf from disappearing |
| 841 | // when the mouse is over the bubble gap. |
| 842 | shelf_region.Inset(alignment_ == SHELF_ALIGNMENT_RIGHT ? |
| 843 | -kNotificationBubbleGapHeight : 0, |
| 844 | alignment_ == SHELF_ALIGNMENT_BOTTOM ? |
| 845 | -kNotificationBubbleGapHeight : 0, |
| 846 | alignment_ == SHELF_ALIGNMENT_LEFT ? |
| 847 | -kNotificationBubbleGapHeight : 0, |
| 848 | 0); |
| 849 | } |
[email protected] | ffabb1e | 2012-10-12 19:51:17 | [diff] [blame] | 850 | return shelf_region.Contains(Shell::GetScreen()->GetCursorScreenPoint()) ? |
[email protected] | 2e195f5 | 2012-09-22 00:24:46 | [diff] [blame] | 851 | AUTO_HIDE_SHOWN : AUTO_HIDE_HIDDEN; |
[email protected] | b1c37fc | 2012-03-22 03:36:13 | [diff] [blame] | 852 | } |
| 853 | |
[email protected] | 128fd373 | 2012-03-27 01:55:12 | [diff] [blame] | 854 | void ShelfLayoutManager::UpdateHitTestBounds() { |
| 855 | gfx::Insets insets; |
| 856 | // Only modify the hit test when the shelf is visible, so we don't mess with |
| 857 | // hover hit testing in the auto-hide state. |
| 858 | if (state_.visibility_state == VISIBLE) { |
| 859 | // Let clicks at the very top of the launcher through so windows can be |
| 860 | // resized with the bottom-right corner and bottom edge. |
[email protected] | 5544450 | 2012-05-10 15:43:53 | [diff] [blame] | 861 | switch (alignment_) { |
| 862 | case SHELF_ALIGNMENT_BOTTOM: |
| 863 | insets.Set(kWorkspaceAreaBottomInset, 0, 0, 0); |
| 864 | break; |
| 865 | case SHELF_ALIGNMENT_LEFT: |
| 866 | insets.Set(0, 0, 0, kWorkspaceAreaBottomInset); |
| 867 | break; |
| 868 | case SHELF_ALIGNMENT_RIGHT: |
| 869 | insets.Set(0, kWorkspaceAreaBottomInset, 0, 0); |
| 870 | break; |
| 871 | } |
[email protected] | 128fd373 | 2012-03-27 01:55:12 | [diff] [blame] | 872 | } |
[email protected] | a86445b | 2012-08-09 19:42:39 | [diff] [blame] | 873 | if (launcher_widget() && launcher_widget()->GetNativeWindow()) { |
| 874 | launcher_widget()->GetNativeWindow()->SetHitTestBoundsOverrideOuter( |
| 875 | insets, 1); |
| 876 | } |
[email protected] | 88d7112 | 2012-10-18 07:11:01 | [diff] [blame] | 877 | status_area_widget_->GetNativeWindow()-> |
| 878 | SetHitTestBoundsOverrideOuter(insets, 1); |
[email protected] | 128fd373 | 2012-03-27 01:55:12 | [diff] [blame] | 879 | } |
| 880 | |
[email protected] | 5f1d99dc | 2012-04-12 21:42:37 | [diff] [blame] | 881 | bool ShelfLayoutManager::IsShelfWindow(aura::Window* window) { |
| 882 | if (!window) |
| 883 | return false; |
| 884 | return (launcher_widget() && |
| 885 | launcher_widget()->GetNativeWindow()->Contains(window)) || |
[email protected] | 88d7112 | 2012-10-18 07:11:01 | [diff] [blame] | 886 | (status_area_widget_->GetNativeWindow()->Contains(window)); |
[email protected] | 5f1d99dc | 2012-04-12 21:42:37 | [diff] [blame] | 887 | } |
| 888 | |
[email protected] | 5544450 | 2012-05-10 15:43:53 | [diff] [blame] | 889 | int ShelfLayoutManager::GetWorkAreaSize(const State& state, int size) const { |
| 890 | if (state.visibility_state == VISIBLE) |
| 891 | return size; |
| 892 | if (state.visibility_state == AUTO_HIDE) |
| 893 | return kAutoHideSize; |
| 894 | return 0; |
| 895 | } |
| 896 | |
[email protected] | 55f59335 | 2011-12-24 05:42:46 | [diff] [blame] | 897 | } // namespace internal |
| 898 | } // namespace ash |