OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CHROME_BROWSER_UI_PANELS_PANEL_MANAGER_H_ | 5 #ifndef CHROME_BROWSER_UI_PANELS_PANEL_STRIP_H_ |
6 #define CHROME_BROWSER_UI_PANELS_PANEL_MANAGER_H_ | 6 #define CHROME_BROWSER_UI_PANELS_PANEL_STRIP_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <vector> | 9 #include <vector> |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
11 #include "base/lazy_instance.h" | |
12 #include "base/memory/scoped_ptr.h" | |
13 #include "base/memory/weak_ptr.h" | 11 #include "base/memory/weak_ptr.h" |
14 #include "chrome/browser/ui/panels/auto_hiding_desktop_bar.h" | 12 #include "chrome/browser/ui/panels/auto_hiding_desktop_bar.h" |
| 13 #include "chrome/browser/ui/panels/panel_mouse_watcher_observer.h" |
15 #include "chrome/browser/ui/panels/panel.h" | 14 #include "chrome/browser/ui/panels/panel.h" |
16 #include "chrome/browser/ui/panels/panel_mouse_watcher_observer.h" | |
17 #include "ui/gfx/rect.h" | 15 #include "ui/gfx/rect.h" |
18 | 16 |
19 class Browser; | 17 class Browser; |
20 class Panel; | 18 class PanelManager; |
21 class PanelMouseWatcher; | |
22 | 19 |
23 // This class manages a set of panels. | 20 // This class manages a group of panels displayed in a horizontal strip, |
24 // Note that the ref count is needed by using PostTask in the implementation. | 21 // positioning the panels and controlling how they are displayed. |
25 class PanelManager : public PanelMouseWatcherObserver, | 22 // Panels in the strip appear minimized, showing title-only or expanded. |
26 public AutoHidingDesktopBar::Observer { | 23 // All panels in the strip are contained within the bounds of the strip. |
| 24 class PanelStrip : public PanelMouseWatcherObserver { |
27 public: | 25 public: |
28 typedef std::vector<Panel*> Panels; | 26 typedef std::vector<Panel*> Panels; |
29 | 27 |
30 // Returns a single instance. | 28 explicit PanelStrip(PanelManager* panel_manager); |
31 static PanelManager* GetInstance(); | 29 virtual ~PanelStrip(); |
32 | 30 |
33 // Called when the display is changed, i.e. work area is updated. | 31 // Sets the bounds of the panel strip. |
34 void OnDisplayChanged(); | 32 // |bounds| is in screen coordinates. |
| 33 void SetBounds(const gfx::Rect bounds); |
35 | 34 |
36 // Creates a panel and returns it. The panel might be queued for display | 35 // Adds a panel to the strip. The panel may be a newly created panel or one |
37 // later. | 36 // that is transitioning from another grouping of panels. |
38 Panel* CreatePanel(Browser* browser); | 37 void AddPanel(Panel* panel); |
39 | 38 |
40 void Remove(Panel* panel); | 39 // Returns |false| if the panel is not in the strip. |
| 40 bool Remove(Panel* panel); |
41 void RemoveAll(); | 41 void RemoveAll(); |
42 | 42 |
43 // Drags the given panel. | 43 // Drags the given panel. |
44 void StartDragging(Panel* panel); | 44 void StartDragging(Panel* panel); |
45 void Drag(int delta_x); | 45 void Drag(int delta_x); |
46 void EndDragging(bool cancelled); | 46 void EndDragging(bool cancelled); |
47 | 47 |
48 // Invoked when a panel's expansion state changes. | 48 // Invoked when a panel's expansion state changes. |
49 void OnPanelExpansionStateChanged(Panel::ExpansionState old_state, | 49 void OnPanelExpansionStateChanged(Panel::ExpansionState old_state, |
50 Panel::ExpansionState new_state); | 50 Panel::ExpansionState new_state); |
51 | 51 |
52 // Invoked when the preferred window size of the given panel might need to | 52 // Invoked when the preferred window size of the given panel might need to |
53 // get changed. | 53 // get changed. |
54 void OnPreferredWindowSizeChanged( | 54 void OnPreferredWindowSizeChanged( |
55 Panel* panel, const gfx::Size& preferred_window_size); | 55 Panel* panel, const gfx::Size& preferred_window_size); |
56 | 56 |
57 // Returns true if we should bring up the titlebars, given the current mouse | 57 // Returns true if we should bring up the titlebars, given the current mouse |
58 // point. | 58 // point. |
59 bool ShouldBringUpTitlebars(int mouse_x, int mouse_y) const; | 59 bool ShouldBringUpTitlebars(int mouse_x, int mouse_y) const; |
60 | 60 |
61 // Brings up or down the titlebars for all minimized panels. | 61 // Brings up or down the titlebars for all minimized panels. |
62 void BringUpOrDownTitlebars(bool bring_up); | 62 void BringUpOrDownTitlebars(bool bring_up); |
63 | 63 |
64 // Returns the bottom position for the panel per its expansion state. If auto- | 64 // Returns the bottom position for the panel per its expansion state. If auto- |
65 // hide bottom bar is present, we want to move the minimized panel to the | 65 // hide bottom bar is present, we want to move the minimized panel to the |
66 // bottom of the screen, not the bottom of the work area. | 66 // bottom of the screen, not the bottom of the work area. |
67 int GetBottomPositionForExpansionState( | 67 int GetBottomPositionForExpansionState( |
68 Panel::ExpansionState expansion_state) const; | 68 Panel::ExpansionState expansion_state) const; |
69 | 69 |
70 // Returns the next browser window which could be either panel window or | |
71 // tabbed window, to switch to if the given panel is going to be deactivated. | |
72 // Returns NULL if such window cannot be found. | |
73 BrowserWindow* GetNextBrowserWindowToActivate(Panel* panel) const; | |
74 | |
75 int num_panels() const { return panels_.size(); } | 70 int num_panels() const { return panels_.size(); } |
76 bool is_dragging_panel() const; | 71 bool is_dragging_panel() const; |
77 const Panels& panels() const { return panels_; } | 72 const Panels& panels() const { return panels_; } |
78 | 73 |
79 int GetMaxPanelWidth() const; | 74 int GetMaxPanelWidth() const; |
80 int GetMaxPanelHeight() const; | 75 int GetMaxPanelHeight() const; |
81 int StartingRightPosition() const; | 76 int StartingRightPosition() const; |
82 | 77 |
83 // Moves a panel to the panel strip. The panel does not currently | |
84 // belong in any other strip. This may cause other panels to be | |
85 // bumped out of the panel strip. | |
86 void MoveToPanelStrip(Panel* panel); | |
87 | |
88 // Moves a panel to the overflow strip. The panel does not currently | |
89 // belong in any other strip. | |
90 // |is_new| is true if the panel was just created. | |
91 void MoveToOverflowStrip(Panel* panel, bool is_new); | |
92 | |
93 // Overridden from PanelMouseWatcherObserver: | 78 // Overridden from PanelMouseWatcherObserver: |
94 virtual void OnMouseMove(const gfx::Point& mouse_position) OVERRIDE; | 79 virtual void OnMouseMove(const gfx::Point& mouse_position) OVERRIDE; |
95 | 80 |
| 81 void OnAutoHidingDesktopBarVisibilityChanged( |
| 82 AutoHidingDesktopBar::Alignment alignment, |
| 83 AutoHidingDesktopBar::Visibility visibility); |
| 84 |
96 #ifdef UNIT_TEST | 85 #ifdef UNIT_TEST |
97 static int horizontal_spacing() { return kPanelsHorizontalSpacing; } | 86 static int horizontal_spacing() { return kPanelsHorizontalSpacing; } |
98 | 87 |
99 const gfx::Rect& work_area() const { | |
100 return work_area_; | |
101 } | |
102 | |
103 void set_auto_hiding_desktop_bar( | |
104 AutoHidingDesktopBar* auto_hiding_desktop_bar) { | |
105 auto_hiding_desktop_bar_ = auto_hiding_desktop_bar; | |
106 } | |
107 | |
108 void enable_auto_sizing(bool enabled) { | |
109 auto_sizing_enabled_ = enabled; | |
110 } | |
111 | |
112 void SetWorkAreaForTesting(const gfx::Rect& work_area) { | |
113 SetWorkArea(work_area); | |
114 } | |
115 | |
116 void remove_delays_for_testing() { | 88 void remove_delays_for_testing() { |
117 remove_delays_for_testing_ = true; | 89 remove_delays_for_testing_ = true; |
118 } | 90 } |
119 | 91 |
120 int minimized_panel_count() { | 92 int minimized_panel_count() { |
121 return minimized_panel_count_; | 93 return minimized_panel_count_; |
122 } | 94 } |
123 | |
124 // Tests should disable mouse watching if mouse movements will be simulated. | |
125 void disable_mouse_watching() { | |
126 mouse_watching_disabled_ = true; | |
127 } | |
128 #endif | 95 #endif |
129 | 96 |
130 private: | 97 private: |
131 friend struct base::DefaultLazyInstanceTraits<PanelManager>; | |
132 FRIEND_TEST_ALL_PREFIXES(PanelBrowserTest, SizeClamping); | |
133 | |
134 enum TitlebarAction { | 98 enum TitlebarAction { |
135 NO_ACTION, | 99 NO_ACTION, |
136 BRING_UP, | 100 BRING_UP, |
137 BRING_DOWN | 101 BRING_DOWN |
138 }; | 102 }; |
139 | 103 |
140 PanelManager(); | 104 // Helper functions to add a panel to the strip. |
141 virtual ~PanelManager(); | 105 void AddNewPanel(Panel* panel); |
142 | 106 void AddExistingPanel(Panel* panel); |
143 // Overridden from AutoHidingDesktopBar::Observer: | |
144 virtual void OnAutoHidingDesktopBarThicknessChanged() OVERRIDE; | |
145 virtual void OnAutoHidingDesktopBarVisibilityChanged( | |
146 AutoHidingDesktopBar::Alignment alignment, | |
147 AutoHidingDesktopBar::Visibility visibility) OVERRIDE; | |
148 | |
149 // Applies the new work area. This is called by OnDisplayChanged and the test | |
150 // code. | |
151 void SetWorkArea(const gfx::Rect& work_area); | |
152 | |
153 // Adjusts the work area to exclude the influence of auto-hiding desktop bars. | |
154 void AdjustWorkAreaForAutoHidingDesktopBars(); | |
155 | 107 |
156 // Keep track of the minimized panels to control mouse watching. | 108 // Keep track of the minimized panels to control mouse watching. |
157 void IncrementMinimizedPanels(); | 109 void IncrementMinimizedPanels(); |
158 void DecrementMinimizedPanels(); | 110 void DecrementMinimizedPanels(); |
159 | 111 |
160 // Handles all the panels that're delayed to be removed. | 112 // Handles all the panels that're delayed to be removed. |
161 void DelayedRemove(); | 113 void DelayedRemove(); |
162 | 114 |
163 // Does the remove. Called from Remove and DelayedRemove. | 115 // Does the remove. Called from Remove and DelayedRemove. |
164 void DoRemove(Panel* panel); | 116 void DoRemove(Panel* panel); |
165 | 117 |
166 // Rearranges the positions of the panels starting from the given iterator. | 118 // Rearranges the positions of the panels starting from the given iterator. |
167 // This is called when the display space has been changed, i.e. working | 119 // This is called when the display space has been changed, i.e. working |
168 // area being changed or a panel being closed. | 120 // area being changed or a panel being closed. |
169 void Rearrange(Panels::iterator iter_to_start, int rightmost_position); | 121 void Rearrange(Panels::iterator iter_to_start, int rightmost_position); |
170 | 122 |
171 // Help functions to drag the given panel. | 123 // Help functions to drag the given panel. |
172 void DragLeft(); | 124 void DragLeft(); |
173 void DragRight(); | 125 void DragRight(); |
174 | 126 |
175 // Does the real job of bringing up or down the titlebars. | 127 // Does the real job of bringing up or down the titlebars. |
176 void DoBringUpOrDownTitlebars(bool bring_up); | 128 void DoBringUpOrDownTitlebars(bool bring_up); |
177 // The callback for a delyed task, checks if it still need to perform | 129 // The callback for a delyed task, checks if it still need to perform |
178 // the delayed action. | 130 // the delayed action. |
179 void DelayedBringUpOrDownTitlebarsCheck(); | 131 void DelayedBringUpOrDownTitlebarsCheck(); |
180 | 132 |
181 int GetRightMostAvailablePosition() const; | 133 int GetRightMostAvailablePosition() const; |
182 | 134 |
| 135 PanelManager* panel_manager_; // Weak, owns us. |
| 136 |
| 137 // All panels in the panel strip must fit within this area. |
| 138 gfx::Rect strip_bounds_; |
| 139 |
183 Panels panels_; | 140 Panels panels_; |
184 | 141 |
185 // Stores the panels that are pending to remove. We want to delay the removal | 142 // Stores the panels that are pending to remove. We want to delay the removal |
186 // when we're in the process of the dragging. | 143 // when we're in the process of the dragging. |
187 Panels panels_pending_to_remove_; | 144 Panels panels_pending_to_remove_; |
188 | 145 |
189 // Use a mouse watcher to know when to bring up titlebars to "peek" at | |
190 // minimized panels. Mouse movement is only tracked when there is a minimized | |
191 // panel. | |
192 scoped_ptr<PanelMouseWatcher> panel_mouse_watcher_; | |
193 int minimized_panel_count_; | 146 int minimized_panel_count_; |
194 bool are_titlebars_up_; | 147 bool are_titlebars_up_; |
195 | 148 |
196 // The maximum work area avaialble. This area does not include the area taken | |
197 // by the always-visible (non-auto-hiding) desktop bars. | |
198 gfx::Rect work_area_; | |
199 | |
200 // The useable work area for computing the panel bounds. This area excludes | |
201 // the potential area that could be taken by the auto-hiding desktop | |
202 // bars (we only consider those bars that are aligned to bottom, left, and | |
203 // right of the screen edges) when they become fully visible. | |
204 gfx::Rect adjusted_work_area_; | |
205 | |
206 // Panel to drag. | 149 // Panel to drag. |
207 size_t dragging_panel_index_; | 150 size_t dragging_panel_index_; |
208 | 151 |
209 // Original x coordinate of the panel to drag. This is used to get back to | 152 // Original x coordinate of the panel to drag. This is used to get back to |
210 // the original position when we cancel the dragging. | 153 // the original position when we cancel the dragging. |
211 int dragging_panel_original_x_; | 154 int dragging_panel_original_x_; |
212 | 155 |
213 // Bounds of the panel to drag. It is first set to the original bounds when | 156 // Bounds of the panel to drag. It is first set to the original bounds when |
214 // the dragging happens. Then it is updated to the position that will be set | 157 // the dragging happens. Then it is updated to the position that will be set |
215 // to when the dragging ends. | 158 // to when the dragging ends. |
216 gfx::Rect dragging_panel_bounds_; | 159 gfx::Rect dragging_panel_bounds_; |
217 | 160 |
218 scoped_refptr<AutoHidingDesktopBar> auto_hiding_desktop_bar_; | |
219 | |
220 // Delayed transitions support. Sometimes transitions between minimized and | 161 // Delayed transitions support. Sometimes transitions between minimized and |
221 // title-only states are delayed, for better usability with Taskbars/Docks. | 162 // title-only states are delayed, for better usability with Taskbars/Docks. |
222 TitlebarAction delayed_titlebar_action_; | 163 TitlebarAction delayed_titlebar_action_; |
223 bool remove_delays_for_testing_; | 164 bool remove_delays_for_testing_; |
224 // Owned by MessageLoop after posting. | 165 // Owned by MessageLoop after posting. |
225 base::WeakPtrFactory<PanelManager> titlebar_action_factory_; | 166 base::WeakPtrFactory<PanelStrip> titlebar_action_factory_; |
226 | |
227 // Whether or not bounds will be updated when the preferred content size is | |
228 // changed. The testing code could set this flag to false so that other tests | |
229 // will not be affected. | |
230 bool auto_sizing_enabled_; | |
231 | |
232 bool mouse_watching_disabled_; // For tests to simulate mouse movements. | |
233 | 167 |
234 static const int kPanelsHorizontalSpacing = 4; | 168 static const int kPanelsHorizontalSpacing = 4; |
235 | 169 |
236 // Absolute minimum width and height for panels, including non-client area. | 170 // Absolute minimum width and height for panels, including non-client area. |
237 // Should only be big enough to accomodate a close button on the reasonably | 171 // Should only be big enough to accomodate a close button on the reasonably |
238 // recognisable titlebar. | 172 // recognisable titlebar. |
239 static const int kPanelMinWidth; | 173 static const int kPanelMinWidth; |
240 static const int kPanelMinHeight; | 174 static const int kPanelMinHeight; |
241 | 175 |
242 DISALLOW_COPY_AND_ASSIGN(PanelManager); | 176 DISALLOW_COPY_AND_ASSIGN(PanelStrip); |
243 }; | 177 }; |
244 | 178 |
245 #endif // CHROME_BROWSER_UI_PANELS_PANEL_MANAGER_H_ | 179 #endif // CHROME_BROWSER_UI_PANELS_PANEL_STRIP_H_ |
OLD | NEW |