blob: aa02b3434232dfed811b609f5a1bbe82f10e2107 [file] [log] [blame]
Ben Murdochca12bfa2013-07-23 11:17:05 +01001// Copyright (c) 2013 The Chromium Authors. All rights reserved.
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +01002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef ASH_WM_DOCK_DOCKED_WINDOW_LAYOUT_MANAGER_H_
6#define ASH_WM_DOCK_DOCKED_WINDOW_LAYOUT_MANAGER_H_
7
8#include "ash/ash_export.h"
9#include "ash/shelf/shelf_layout_manager_observer.h"
10#include "ash/shell_observer.h"
11#include "ash/wm/dock/dock_types.h"
12#include "ash/wm/property_util.h"
13#include "base/basictypes.h"
14#include "base/compiler_specific.h"
Ben Murdochca12bfa2013-07-23 11:17:05 +010015#include "base/gtest_prod_util.h"
Ben Murdochbb1529c2013-08-08 10:24:53 +010016#include "base/memory/scoped_ptr.h"
Ben Murdochca12bfa2013-07-23 11:17:05 +010017#include "base/observer_list.h"
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010018#include "ui/aura/client/activation_change_observer.h"
19#include "ui/aura/layout_manager.h"
20#include "ui/aura/window_observer.h"
Ben Murdochca12bfa2013-07-23 11:17:05 +010021#include "ui/gfx/rect.h"
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010022#include "ui/keyboard/keyboard_controller_observer.h"
23
24namespace aura {
25class Window;
26}
27
28namespace gfx {
29class Point;
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010030}
31
Ben Murdochbb1529c2013-08-08 10:24:53 +010032namespace views {
33class Widget;
34}
35
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010036namespace ash {
37class Launcher;
38
39namespace internal {
Ben Murdochca12bfa2013-07-23 11:17:05 +010040class DockedWindowLayoutManagerObserver;
41class DockedWindowResizerTest;
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010042class ShelfLayoutManager;
43
44// DockedWindowLayoutManager is responsible for organizing windows when they are
45// docked to the side of a screen. It is associated with a specific container
46// window (i.e. kShellWindowId_DockContainer) and controls the layout of any
47// windows added to that container.
48//
49// The constructor takes a |dock_container| argument which is expected to set
50// its layout manager to this instance, e.g.:
51// dock_container->SetLayoutManager(
52// new DockedWindowLayoutManager(dock_container));
53
54class ASH_EXPORT DockedWindowLayoutManager
55 : public aura::LayoutManager,
56 public ash::ShellObserver,
57 public aura::WindowObserver,
58 public aura::client::ActivationChangeObserver,
59 public keyboard::KeyboardControllerObserver,
60 public ash::ShelfLayoutManagerObserver {
61 public:
62 explicit DockedWindowLayoutManager(aura::Window* dock_container);
63 virtual ~DockedWindowLayoutManager();
64
Ben Murdochca12bfa2013-07-23 11:17:05 +010065 // Disconnects observers before container windows get destroyed.
66 void Shutdown();
67
68 // Management of the observer list.
69 virtual void AddObserver(DockedWindowLayoutManagerObserver* observer);
70 virtual void RemoveObserver(DockedWindowLayoutManagerObserver* observer);
71
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010072 // Called by a DockedWindowResizer to update which window is being dragged.
73 void StartDragging(aura::Window* window);
74 void FinishDragging();
75
76 // Returns true if a window is touching the side of the screen except 2 cases:
77 // when some other windows are already docked on the other side or
78 // when launcher (shelf) is aligned on the same side.
79 static bool ShouldWindowDock(aura::Window* window,
80 const gfx::Point& location);
81
82 ash::Launcher* launcher() { return launcher_; }
83 void SetLauncher(ash::Launcher* launcher);
84
85 // Used to snap docked windows to the side of screen during drag.
Ben Murdochca12bfa2013-07-23 11:17:05 +010086 DockedAlignment CalculateAlignment() const;
87
88 // Returns current bounding rectangle of docked windows area.
89 const gfx::Rect& docked_bounds() const { return docked_bounds_; }
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010090
91 // Currently dragged window should be able to dock on another screen
92 aura::Window* dragged_window() const { return dragged_window_;}
93
94 // aura::LayoutManager:
95 virtual void OnWindowResized() OVERRIDE;
96 virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE;
Ben Murdochca12bfa2013-07-23 11:17:05 +010097 virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE {}
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010098 virtual void OnWindowRemovedFromLayout(aura::Window* child) OVERRIDE;
99 virtual void OnChildWindowVisibilityChanged(aura::Window* child,
100 bool visibile) OVERRIDE;
101 virtual void SetChildBounds(aura::Window* child,
102 const gfx::Rect& requested_bounds) OVERRIDE;
103
104 // ash::ShellObserver:
105 virtual void OnShelfAlignmentChanged(aura::RootWindow* root_window) OVERRIDE;
106
107 // aura::WindowObserver:
108 virtual void OnWindowPropertyChanged(aura::Window* window,
109 const void* key,
110 intptr_t old) OVERRIDE;
Ben Murdochbbcdd452013-07-25 10:06:34 +0100111 virtual void OnWindowBoundsChanged(aura::Window* window,
112 const gfx::Rect& old_bounds,
113 const gfx::Rect& new_bounds) OVERRIDE;
114 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100115
116 // aura::client::ActivationChangeObserver:
117 virtual void OnWindowActivated(aura::Window* gained_active,
118 aura::Window* lost_active) OVERRIDE;
119
120 // ShelfLayoutManagerObserver:
121 virtual void WillChangeVisibilityState(
122 ShelfVisibilityState new_state) OVERRIDE;
123
124 private:
Ben Murdochca12bfa2013-07-23 11:17:05 +0100125 FRIEND_TEST_ALL_PREFIXES(DockedWindowResizerTest, AttachTwoWindowsDetachOne);
126 FRIEND_TEST_ALL_PREFIXES(DockedWindowResizerTest, AttachWindowMaximizeOther);
127 FRIEND_TEST_ALL_PREFIXES(DockedWindowResizerTest, AttachOneTestSticky);
128 FRIEND_TEST_ALL_PREFIXES(DockedWindowResizerTest, ResizeTwoWindows);
129 FRIEND_TEST_ALL_PREFIXES(DockedWindowResizerTest, DragToShelf);
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100130 friend class DockedWindowLayoutManagerTest;
131 friend class DockedWindowResizerTest;
132
Ben Murdochca12bfa2013-07-23 11:17:05 +0100133 // Minimum width of the docked windows area.
134 static const int kMinDockWidth;
135
136 // Maximum width of the docked windows area.
137 static const int kMaxDockWidth;
138
139 // Width of the gap between the docked windows and a workspace.
140 static const int kMinDockGap;
141
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100142 // Minimize / restore window and relayout.
143 void MinimizeWindow(aura::Window* window);
144 void RestoreWindow(aura::Window* window);
145
Ben Murdochca12bfa2013-07-23 11:17:05 +0100146 // Calculates if a window is touching the screen edges and returns edge.
147 DockedAlignment AlignmentOfWindow(const aura::Window* window) const;
148
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100149 // Called whenever the window layout might change.
150 void Relayout();
151
Ben Murdochca12bfa2013-07-23 11:17:05 +0100152 // Updates |docked_bounds_| and workspace insets when bounds of docked windows
153 // area change.
154 void UpdateDockBounds();
155
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100156 // Called whenever the window stacking order needs to be updated (e.g. focus
157 // changes or a window is moved).
158 void UpdateStacking(aura::Window* active_window);
159
160 // keyboard::KeyboardControllerObserver:
161 virtual void OnKeyboardBoundsChanging(
162 const gfx::Rect& keyboard_bounds) OVERRIDE;
163
164 // Parent window associated with this layout manager.
165 aura::Window* dock_container_;
166 // Protect against recursive calls to Relayout().
167 bool in_layout_;
168 // The docked window being dragged.
169 aura::Window* dragged_window_;
170 // The launcher we are observing for launcher icon changes.
171 Launcher* launcher_;
172 // The shelf layout manager being observed for visibility changes.
173 ShelfLayoutManager* shelf_layout_manager_;
174 // Tracks the visibility of the shelf. Defaults to false when there is no
175 // shelf.
176 bool shelf_hidden_;
Ben Murdochca12bfa2013-07-23 11:17:05 +0100177 // Current width of the dock.
178 int docked_width_;
179
180 // Last bounds that were sent to observers.
181 gfx::Rect docked_bounds_;
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100182
183 // Side of the screen that the dock is positioned at.
184 DockedAlignment alignment_;
185
Ben Murdochbbcdd452013-07-25 10:06:34 +0100186 // The last active window. Used to maintain stacking order even if no windows
187 // are currently focused.
188 aura::Window* last_active_window_;
189
Ben Murdochbb1529c2013-08-08 10:24:53 +0100190 // Widget used to paint a background for the docked area.
191 scoped_ptr<views::Widget> background_widget_;
192
Ben Murdochca12bfa2013-07-23 11:17:05 +0100193 // Observers of dock bounds changes.
194 ObserverList<DockedWindowLayoutManagerObserver> observer_list_;
195
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100196 DISALLOW_COPY_AND_ASSIGN(DockedWindowLayoutManager);
197};
198
199} // namespace internal
200} // namespace ash
201
202#endif // ASH_WM_DOCK_DOCKED_WINDOW_LAYOUT_MANAGER_H_