1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef ASH_WM_PANELS_PANEL_LAYOUT_MANAGER_H_ 6 #define ASH_WM_PANELS_PANEL_LAYOUT_MANAGER_H_ 7 8 #include <list> 9 10 #include "ash/ash_export.h" 11 #include "ash/display/display_controller.h" 12 #include "ash/shelf/shelf_icon_observer.h" 13 #include "ash/shelf/shelf_layout_manager_observer.h" 14 #include "ash/shell_observer.h" 15 #include "ash/wm/window_state_observer.h" 16 #include "base/basictypes.h" 17 #include "base/compiler_specific.h" 18 #include "base/memory/scoped_ptr.h" 19 #include "base/memory/weak_ptr.h" 20 #include "ui/aura/client/activation_change_observer.h" 21 #include "ui/aura/layout_manager.h" 22 #include "ui/aura/window_observer.h" 23 #include "ui/keyboard/keyboard_controller.h" 24 #include "ui/keyboard/keyboard_controller_observer.h" 25 26 namespace aura { 27 class Window; 28 class WindowTracker; 29 } 30 31 namespace gfx { 32 class Rect; 33 } 34 35 namespace views { 36 class Widget; 37 } 38 39 namespace ash { 40 class Launcher; 41 42 namespace internal { 43 class PanelCalloutWidget; 44 class ShelfLayoutManager; 45 46 // PanelLayoutManager is responsible for organizing panels within the 47 // workspace. It is associated with a specific container window (i.e. 48 // kShellWindowId_PanelContainer) and controls the layout of any windows 49 // added to that container. 50 // 51 // The constructor takes a |panel_container| argument which is expected to set 52 // its layout manager to this instance, e.g.: 53 // panel_container->SetLayoutManager(new PanelLayoutManager(panel_container)); 54 55 class ASH_EXPORT PanelLayoutManager 56 : public aura::LayoutManager, 57 public ShelfIconObserver, 58 public ShellObserver, 59 public aura::WindowObserver, 60 public aura::client::ActivationChangeObserver, 61 public keyboard::KeyboardControllerObserver, 62 public DisplayController::Observer, 63 public ShelfLayoutManagerObserver, 64 public wm::WindowStateObserver { 65 public: 66 explicit PanelLayoutManager(aura::Window* panel_container); 67 virtual ~PanelLayoutManager(); 68 69 // Call Shutdown() before deleting children of panel_container. 70 void Shutdown(); 71 72 void StartDragging(aura::Window* panel); 73 void FinishDragging(); 74 75 void ToggleMinimize(aura::Window* panel); 76 77 // Returns the callout widget (arrow) for |panel|. 78 views::Widget* GetCalloutWidgetForPanel(aura::Window* panel); 79 80 ash::Launcher* launcher() { return launcher_; } 81 void SetLauncher(ash::Launcher* launcher); 82 83 // Overridden from aura::LayoutManager: 84 virtual void OnWindowResized() OVERRIDE; 85 virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE; 86 virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE; 87 virtual void OnWindowRemovedFromLayout(aura::Window* child) OVERRIDE; 88 virtual void OnChildWindowVisibilityChanged(aura::Window* child, 89 bool visibile) OVERRIDE; 90 virtual void SetChildBounds(aura::Window* child, 91 const gfx::Rect& requested_bounds) OVERRIDE; 92 93 // Overridden from ShelfIconObserver 94 virtual void OnShelfIconPositionsChanged() OVERRIDE; 95 96 // Overridden from ShellObserver 97 virtual void OnShelfAlignmentChanged(aura::Window* root_window) OVERRIDE; 98 99 // Overridden from ash::wm::WindowStateObserver 100 virtual void OnWindowShowTypeChanged(wm::WindowState* window_state, 101 wm::WindowShowType old_type) OVERRIDE; 102 103 // Overridden from aura::WindowObserver 104 virtual void OnWindowVisibilityChanged(aura::Window* window, 105 bool visible) OVERRIDE; 106 107 // Overridden from aura::client::ActivationChangeObserver 108 virtual void OnWindowActivated(aura::Window* gained_active, 109 aura::Window* lost_active) OVERRIDE; 110 111 // Overridden from DisplayController::Observer 112 virtual void OnDisplayConfigurationChanged() OVERRIDE; 113 114 // Overridden from ShelfLayoutManagerObserver 115 virtual void WillChangeVisibilityState( 116 ShelfVisibilityState new_state) OVERRIDE; 117 118 private: 119 friend class PanelLayoutManagerTest; 120 friend class PanelWindowResizerTest; 121 friend class DockedWindowResizerTest; 122 friend class DockedWindowLayoutManagerTest; 123 124 views::Widget* CreateCalloutWidget(); 125 126 struct PanelInfo{ 127 PanelInfo() : window(NULL), callout_widget(NULL), slide_in(false) {} 128 129 bool operator==(const aura::Window* other_window) const { 130 return window == other_window; 131 } 132 133 // A weak pointer to the panel window. 134 aura::Window* window; 135 // The callout widget for this panel. This pointer must be managed 136 // manually as this structure is used in a std::list. See 137 // http://www.chromium.org/developers/smart-pointer-guidelines 138 PanelCalloutWidget* callout_widget; 139 140 // True on new and restored panel windows until the panel has been 141 // positioned. The first time Relayout is called the panel will slide into 142 // position and this will be set to false. 143 bool slide_in; 144 }; 145 146 typedef std::list<PanelInfo> PanelList; 147 148 void MinimizePanel(aura::Window* panel); 149 void RestorePanel(aura::Window* panel); 150 151 // Called whenever the panel layout might change. 152 void Relayout(); 153 154 // Called whenever the panel stacking order needs to be updated (e.g. focus 155 // changes or a panel is moved). 156 void UpdateStacking(aura::Window* active_panel); 157 158 // Update the callout arrows for all managed panels. 159 void UpdateCallouts(); 160 161 // Overridden from keyboard::KeyboardControllerObserver: 162 virtual void OnKeyboardBoundsChanging( 163 const gfx::Rect& keyboard_bounds) OVERRIDE; 164 165 // Parent window associated with this layout manager. 166 aura::Window* panel_container_; 167 // Protect against recursive calls to OnWindowAddedToLayout(). 168 bool in_add_window_; 169 // Protect against recursive calls to Relayout(). 170 bool in_layout_; 171 // Ordered list of unowned pointers to panel windows. 172 PanelList panel_windows_; 173 // The panel being dragged. 174 aura::Window* dragged_panel_; 175 // The launcher we are observing for launcher icon changes. 176 Launcher* launcher_; 177 // The shelf layout manager being observed for visibility changes. 178 ShelfLayoutManager* shelf_layout_manager_; 179 180 // When not NULL, the shelf is hidden (i.e. full screen) and this tracks the 181 // set of panel windows which have been temporarily hidden and need to be 182 // restored when the shelf becomes visible again. 183 scoped_ptr<aura::WindowTracker> restore_windows_on_shelf_visible_; 184 185 // The last active panel. Used to maintain stacking order even if no panels 186 // are currently focused. 187 aura::Window* last_active_panel_; 188 base::WeakPtrFactory<PanelLayoutManager> weak_factory_; 189 190 DISALLOW_COPY_AND_ASSIGN(PanelLayoutManager); 191 }; 192 193 } // namespace internal 194 } // namespace ash 195 196 #endif // ASH_WM_PANELS_PANEL_LAYOUT_MANAGER_H_ 197