• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "base/message_loop/message_loop.h"
6 #include "chrome/browser/chrome_notification_types.h"
7 #include "chrome/browser/ui/panels/base_panel_browser_test.h"
8 #include "chrome/browser/ui/panels/detached_panel_collection.h"
9 #include "chrome/browser/ui/panels/docked_panel_collection.h"
10 #include "chrome/browser/ui/panels/native_panel.h"
11 #include "chrome/browser/ui/panels/panel.h"
12 #include "chrome/browser/ui/panels/panel_drag_controller.h"
13 #include "chrome/browser/ui/panels/panel_manager.h"
14 #include "chrome/browser/ui/panels/stacked_panel_collection.h"
15 #include "chrome/browser/ui/panels/test_panel_collection_squeeze_observer.h"
16 #include "content/public/browser/notification_service.h"
17 #include "content/public/test/test_utils.h"
18 
19 class PanelDragBrowserTest : public BasePanelBrowserTest {
20  public:
PanelDragBrowserTest()21   PanelDragBrowserTest() : BasePanelBrowserTest() {
22   }
23 
~PanelDragBrowserTest()24   virtual ~PanelDragBrowserTest() {
25   }
26 
SetUpOnMainThread()27   virtual void SetUpOnMainThread() OVERRIDE {
28     BasePanelBrowserTest::SetUpOnMainThread();
29 
30     // All the tests here assume using mocked 800x600 display area for the
31     // primary monitor. Do the check now.
32     gfx::Rect primary_display_area = PanelManager::GetInstance()->
33         display_settings_provider()->GetPrimaryDisplayArea();
34     DCHECK(primary_display_area.width() == 800);
35     DCHECK(primary_display_area.height() == 600);
36   }
37 
38   // Drag |panel| from its origin by the offset |delta|.
DragPanelByDelta(Panel * panel,const gfx::Vector2d & delta)39   void DragPanelByDelta(Panel* panel, const gfx::Vector2d& delta) {
40     scoped_ptr<NativePanelTesting> panel_testing(
41         CreateNativePanelTesting(panel));
42     gfx::Point mouse_location(panel->GetBounds().origin());
43     panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
44     panel_testing->DragTitlebar(mouse_location + delta);
45     panel_testing->FinishDragTitlebar();
46   }
47 
48   // Drag |panel| from its origin to |new_mouse_location|.
DragPanelToMouseLocation(Panel * panel,const gfx::Point & new_mouse_location)49   void DragPanelToMouseLocation(Panel* panel,
50                                 const gfx::Point& new_mouse_location) {
51     scoped_ptr<NativePanelTesting> panel_testing(
52         CreateNativePanelTesting(panel));
53     gfx::Point mouse_location(panel->GetBounds().origin());
54     panel_testing->PressLeftMouseButtonTitlebar(panel->GetBounds().origin());
55     panel_testing->DragTitlebar(new_mouse_location);
56     panel_testing->FinishDragTitlebar();
57   }
58 
59   // Return the bounds of a panel given its initial bounds and the bounds of the
60   // panel above it.
GetStackedAtBottomPanelBounds(const gfx::Rect & initial_bounds,const gfx::Rect & above_bounds)61   static gfx::Rect GetStackedAtBottomPanelBounds(
62       const gfx::Rect& initial_bounds,
63       const gfx::Rect& above_bounds) {
64     return gfx::Rect(above_bounds.x(),
65                      above_bounds.bottom(),
66                      above_bounds.width(),
67                      initial_bounds.height());
68   }
69 
70   // Return the bounds of a panel given its initial bounds and the bounds of the
71   // panel below it.
GetStackedAtTopPanelBounds(const gfx::Rect & initial_bounds,const gfx::Rect & below_bounds)72   static gfx::Rect GetStackedAtTopPanelBounds(
73       const gfx::Rect& initial_bounds,
74       const gfx::Rect& below_bounds) {
75     return gfx::Rect(below_bounds.x(),
76                      below_bounds.y() - initial_bounds.height(),
77                      initial_bounds.width(),
78                      initial_bounds.height());
79   }
80 
GetDragDeltaToRemainDocked()81   static gfx::Vector2d GetDragDeltaToRemainDocked() {
82     return gfx::Vector2d(
83         -5,
84         -(PanelDragController::GetDetachDockedPanelThresholdForTesting() / 2));
85   }
86 
GetDragDeltaToDetach()87   static gfx::Vector2d GetDragDeltaToDetach() {
88     return gfx::Vector2d(
89         -20,
90         -(PanelDragController::GetDetachDockedPanelThresholdForTesting() + 20));
91   }
92 
GetDragDeltaToRemainDetached(Panel * panel)93   static gfx::Vector2d GetDragDeltaToRemainDetached(Panel* panel) {
94     int distance =
95       panel->manager()->docked_collection()->work_area().bottom() -
96       panel->GetBounds().bottom();
97     return gfx::Vector2d(
98         -5,
99         distance -
100             PanelDragController::GetDockDetachedPanelThresholdForTesting() * 2);
101   }
102 
GetDragDeltaToAttach(Panel * panel)103   static gfx::Vector2d GetDragDeltaToAttach(Panel* panel) {
104     int distance =
105         panel->manager()->docked_collection()->work_area().bottom() -
106         panel->GetBounds().bottom();
107     return gfx::Vector2d(
108         -20,
109         distance -
110             PanelDragController::GetDockDetachedPanelThresholdForTesting() / 2);
111   }
112 
113   // Return the delta needed to drag |panel1| to stack to the bottom of
114   // |panel2|.
GetDragDeltaToStackToBottom(Panel * panel1,Panel * panel2)115   static gfx::Vector2d GetDragDeltaToStackToBottom(Panel* panel1,
116                                                    Panel* panel2) {
117     gfx::Rect bounds1 = panel1->GetBounds();
118     gfx::Rect bounds2 = panel2->GetBounds();
119     return gfx::Vector2d(
120         bounds2.x() - bounds1.x(),
121         bounds2.bottom() - bounds1.y() +
122             PanelDragController::GetGluePanelDistanceThresholdForTesting() / 2);
123   }
124 
125   // Return the delta needed to drag |panel1| to unstack from the bottom of
126   // |panel2|.
GetDragDeltaToUnstackFromBottom(Panel * panel1,Panel * panel2)127   static gfx::Vector2d GetDragDeltaToUnstackFromBottom(Panel* panel1,
128                                                        Panel* panel2) {
129     gfx::Rect bounds1 = panel1->GetBounds();
130     gfx::Rect bounds2 = panel2->GetBounds();
131     return gfx::Vector2d(
132         0, PanelDragController::GetGluePanelDistanceThresholdForTesting() * 2);
133   }
134 
135   // Return the delta needed to drag |panel1| to stack to the top of |panel2|.
GetDragDeltaToStackToTop(Panel * panel1,Panel * panel2)136   static gfx::Vector2d GetDragDeltaToStackToTop(Panel* panel1, Panel* panel2) {
137     gfx::Rect bounds1 = panel1->GetBounds();
138     gfx::Rect bounds2 = panel2->GetBounds();
139     StackedPanelCollection* stack1 = panel1->stack();
140     int bottom = stack1 ? stack1->bottom_panel()->GetBounds().bottom()
141                         : bounds1.bottom();
142     return gfx::Vector2d(
143         bounds2.x() - bounds1.x(),
144         bounds2.y() - bottom -
145             PanelDragController::GetGluePanelDistanceThresholdForTesting() / 2);
146   }
147 
148   // Return the delta needed to drag |panel1| to unstack from the top of
149   // |panel2|.
GetDragDeltaToUnstackFromTop(Panel * panel1,Panel * panel2)150   static gfx::Vector2d GetDragDeltaToUnstackFromTop(Panel* panel1,
151                                                     Panel* panel2) {
152     gfx::Rect bounds1 = panel1->GetBounds();
153     gfx::Rect bounds2 = panel2->GetBounds();
154     return gfx::Vector2d(
155         0, -PanelDragController::GetGluePanelDistanceThresholdForTesting() * 2);
156   }
157 
158   // Return the delta needed to drag |panel1| to snap to the left of |panel2|.
GetDragDeltaToSnapToLeft(Panel * panel1,Panel * panel2)159   static gfx::Vector2d GetDragDeltaToSnapToLeft(Panel* panel1,
160                                                 Panel* panel2) {
161     gfx::Rect bounds1 = panel1->GetBounds();
162     gfx::Rect bounds2 = panel2->GetBounds();
163     return gfx::Vector2d(
164         bounds2.x() - bounds1.width() - bounds1.x() -
165             PanelDragController::GetGluePanelDistanceThresholdForTesting() / 2,
166         bounds2.y() - bounds1.y() +
167             PanelDragController::GetGluePanelDistanceThresholdForTesting() * 2);
168   }
169 
170   // Return the delta needed to drag |panel1| to snap to the right of |panel2|.
GetDragDeltaToSnapToRight(Panel * panel1,Panel * panel2)171   static gfx::Vector2d GetDragDeltaToSnapToRight(Panel* panel1,
172                                                  Panel* panel2) {
173     gfx::Rect bounds1 = panel1->GetBounds();
174     gfx::Rect bounds2 = panel2->GetBounds();
175     return gfx::Vector2d(
176         bounds2.right() - bounds1.x() +
177             PanelDragController::GetGluePanelDistanceThresholdForTesting() / 2,
178         bounds2.y() - bounds1.y() +
179             PanelDragController::GetGluePanelDistanceThresholdForTesting() * 2);
180   }
181 
182   // Return the delta needed to drag |panel| to unsnap from its current
183   // position.
GetDragDeltaToUnsnap(Panel * panel)184   static gfx::Vector2d GetDragDeltaToUnsnap(Panel* panel) {
185     return gfx::Vector2d(
186         PanelDragController::GetGluePanelDistanceThresholdForTesting() * 2, 0);
187   }
188 };
189 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,DragOneDockedPanel)190 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DragOneDockedPanel) {
191   static const int big_delta_x = 70;
192   static const int big_delta_y = 30;  // Do not exceed the threshold to detach.
193 
194   Panel* panel = CreateDockedPanel("1", gfx::Rect(0, 0, 100, 100));
195   scoped_ptr<NativePanelTesting> panel_testing(
196       CreateNativePanelTesting(panel));
197   gfx::Rect panel_old_bounds = panel->GetBounds();
198 
199   // Drag left.
200   gfx::Point mouse_location = panel_old_bounds.origin();
201   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
202   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
203 
204   mouse_location.Offset(-big_delta_x, 0);
205   panel_testing->DragTitlebar(mouse_location);
206   gfx::Rect panel_new_bounds = panel_old_bounds;
207   panel_new_bounds.Offset(-big_delta_x, 0);
208   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
209 
210   panel_testing->FinishDragTitlebar();
211   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
212 
213   // Drag left and cancel.
214   mouse_location = panel_old_bounds.origin();
215   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
216   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
217 
218   mouse_location.Offset(-big_delta_x, 0);
219   panel_testing->DragTitlebar(mouse_location);
220   panel_new_bounds = panel_old_bounds;
221   panel_new_bounds.Offset(-big_delta_x, 0);
222   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
223 
224   panel_testing->CancelDragTitlebar();
225   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
226 
227   // Drag right.
228   mouse_location = panel_old_bounds.origin();
229   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
230   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
231 
232   mouse_location.Offset(big_delta_x, 0);
233   panel_testing->DragTitlebar(mouse_location);
234   panel_new_bounds = panel_old_bounds;
235   panel_new_bounds.Offset(big_delta_x, 0);
236   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
237 
238   panel_testing->FinishDragTitlebar();
239   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
240 
241   // Drag right and up.  Expect no vertical movement.
242   mouse_location = panel_old_bounds.origin();
243   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
244   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
245 
246   mouse_location.Offset(big_delta_x, big_delta_y);
247   panel_testing->DragTitlebar(mouse_location);
248   panel_new_bounds = panel_old_bounds;
249   panel_new_bounds.Offset(big_delta_x, 0);
250   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
251 
252   panel_testing->FinishDragTitlebar();
253   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
254 
255   // Drag up.  Expect no movement on drag.
256   mouse_location = panel_old_bounds.origin();
257   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
258   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
259 
260   mouse_location.Offset(0, -big_delta_y);
261   panel_testing->DragTitlebar(mouse_location);
262   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
263 
264   panel_testing->FinishDragTitlebar();
265   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
266 
267   // Drag down.  Expect no movement on drag.
268   mouse_location = panel_old_bounds.origin();
269   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
270   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
271 
272   mouse_location.Offset(0, big_delta_y);
273   panel_testing->DragTitlebar(mouse_location);
274   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
275 
276   panel_testing->FinishDragTitlebar();
277   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
278 
279   PanelManager::GetInstance()->CloseAll();
280 }
281 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,DragTwoDockedPanels)282 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DragTwoDockedPanels) {
283   static const gfx::Vector2d small_delta(10, 0);
284 
285   Panel* panel1 = CreateDockedPanel("1", gfx::Rect(0, 0, 100, 100));
286   Panel* panel2 = CreateDockedPanel("2", gfx::Rect(0, 0, 100, 100));
287   scoped_ptr<NativePanelTesting> panel1_testing(
288       CreateNativePanelTesting(panel1));
289   scoped_ptr<NativePanelTesting> panel2_testing(
290       CreateNativePanelTesting(panel2));
291   gfx::Point position1 = panel1->GetBounds().origin();
292   gfx::Point position2 = panel2->GetBounds().origin();
293 
294   // Drag right panel towards left with small delta.
295   // Expect no shuffle: P1 P2
296   gfx::Point mouse_location = position1;
297   panel1_testing->PressLeftMouseButtonTitlebar(mouse_location);
298   EXPECT_EQ(position1, panel1->GetBounds().origin());
299   EXPECT_EQ(position2, panel2->GetBounds().origin());
300 
301   mouse_location = mouse_location - small_delta;
302   panel1_testing->DragTitlebar(mouse_location);
303   EXPECT_EQ(mouse_location, panel1->GetBounds().origin());
304   EXPECT_EQ(position2, panel2->GetBounds().origin());
305 
306   panel1_testing->FinishDragTitlebar();
307   EXPECT_EQ(position1, panel1->GetBounds().origin());
308   EXPECT_EQ(position2, panel2->GetBounds().origin());
309 
310   // Drag right panel towards left with big delta.
311   // Expect shuffle: P2 P1
312   mouse_location = position1;
313   panel1_testing->PressLeftMouseButtonTitlebar(mouse_location);
314   EXPECT_EQ(position1, panel1->GetBounds().origin());
315   EXPECT_EQ(position2, panel2->GetBounds().origin());
316 
317   mouse_location = position2 + gfx::Vector2d(1, 0);
318   panel1_testing->DragTitlebar(mouse_location);
319   EXPECT_EQ(mouse_location, panel1->GetBounds().origin());
320   EXPECT_EQ(position1, panel2->GetBounds().origin());
321 
322   panel1_testing->FinishDragTitlebar();
323   EXPECT_EQ(position2, panel1->GetBounds().origin());
324   EXPECT_EQ(position1, panel2->GetBounds().origin());
325 
326   // Drag left panel towards right with small delta.
327   // Expect no shuffle: P2 P1
328   mouse_location = position2;
329   panel1_testing->PressLeftMouseButtonTitlebar(mouse_location);
330   EXPECT_EQ(position2, panel1->GetBounds().origin());
331   EXPECT_EQ(position1, panel2->GetBounds().origin());
332 
333   mouse_location = mouse_location + small_delta;
334   panel1_testing->DragTitlebar(mouse_location);
335   EXPECT_EQ(mouse_location, panel1->GetBounds().origin());
336   EXPECT_EQ(position1, panel2->GetBounds().origin());
337 
338   panel1_testing->FinishDragTitlebar();
339   EXPECT_EQ(position2, panel1->GetBounds().origin());
340   EXPECT_EQ(position1, panel2->GetBounds().origin());
341 
342   // Drag left panel towards right with big delta.
343   // Expect shuffle: P1 P2
344   mouse_location = position2;
345   panel1_testing->PressLeftMouseButtonTitlebar(mouse_location);
346   EXPECT_EQ(position2, panel1->GetBounds().origin());
347   EXPECT_EQ(position1, panel2->GetBounds().origin());
348 
349   mouse_location = position1 + gfx::Vector2d(1, 0);
350   panel1_testing->DragTitlebar(mouse_location);
351   EXPECT_EQ(mouse_location, panel1->GetBounds().origin());
352   EXPECT_EQ(position2, panel2->GetBounds().origin());
353 
354   panel1_testing->FinishDragTitlebar();
355   EXPECT_EQ(position1, panel1->GetBounds().origin());
356   EXPECT_EQ(position2, panel2->GetBounds().origin());
357 
358   // Drag right panel towards left with big delta and then cancel the drag.
359   // Expect shuffle after drag:   P2 P1
360   // Expect shuffle after cancel: P1 P2
361   mouse_location = position1;
362   panel1_testing->PressLeftMouseButtonTitlebar(mouse_location);
363   EXPECT_EQ(position1, panel1->GetBounds().origin());
364   EXPECT_EQ(position2, panel2->GetBounds().origin());
365 
366   mouse_location = position2 + gfx::Vector2d(1, 0);
367   panel1_testing->DragTitlebar(mouse_location);
368   EXPECT_EQ(mouse_location, panel1->GetBounds().origin());
369   EXPECT_EQ(position1, panel2->GetBounds().origin());
370 
371   panel1_testing->CancelDragTitlebar();
372   EXPECT_EQ(position1, panel1->GetBounds().origin());
373   EXPECT_EQ(position2, panel2->GetBounds().origin());
374 
375   PanelManager::GetInstance()->CloseAll();
376 }
377 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,DragThreeDockedPanels)378 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DragThreeDockedPanels) {
379   Panel* panel1 = CreateDockedPanel("1", gfx::Rect(0, 0, 100, 100));
380   Panel* panel2 = CreateDockedPanel("2", gfx::Rect(0, 0, 100, 100));
381   Panel* panel3 = CreateDockedPanel("3", gfx::Rect(0, 0, 100, 100));
382   scoped_ptr<NativePanelTesting> panel2_testing(
383       CreateNativePanelTesting(panel2));
384   scoped_ptr<NativePanelTesting> panel3_testing(
385       CreateNativePanelTesting(panel3));
386   gfx::Point position1 = panel1->GetBounds().origin();
387   gfx::Point position2 = panel2->GetBounds().origin();
388   gfx::Point position3 = panel3->GetBounds().origin();
389 
390   // Drag leftmost panel to become the rightmost in 2 drags. Each drag will
391   // shuffle one panel.
392   // Expect shuffle after 1st drag: P1 P3 P2
393   // Expect shuffle after 2nd drag: P3 P1 P2
394   gfx::Point mouse_location = position3;
395   panel3_testing->PressLeftMouseButtonTitlebar(mouse_location);
396   EXPECT_EQ(position1, panel1->GetBounds().origin());
397   EXPECT_EQ(position2, panel2->GetBounds().origin());
398   EXPECT_EQ(position3, panel3->GetBounds().origin());
399 
400   mouse_location = position2 + gfx::Vector2d(1, 0);
401   panel3_testing->DragTitlebar(mouse_location);
402   EXPECT_EQ(position1, panel1->GetBounds().origin());
403   EXPECT_EQ(position3, panel2->GetBounds().origin());
404   EXPECT_EQ(mouse_location, panel3->GetBounds().origin());
405 
406   mouse_location = position1 + gfx::Vector2d(1, 0);
407   panel3_testing->DragTitlebar(mouse_location);
408   EXPECT_EQ(position2, panel1->GetBounds().origin());
409   EXPECT_EQ(position3, panel2->GetBounds().origin());
410   EXPECT_EQ(mouse_location, panel3->GetBounds().origin());
411 
412   panel3_testing->FinishDragTitlebar();
413   EXPECT_EQ(position2, panel1->GetBounds().origin());
414   EXPECT_EQ(position3, panel2->GetBounds().origin());
415   EXPECT_EQ(position1, panel3->GetBounds().origin());
416 
417   // Drag rightmost panel to become the leftmost in 2 drags and then cancel the
418   // drag. Each drag will shuffle one panel and the cancellation will restore
419   // all panels.
420   // Expect shuffle after 1st drag: P1 P3 P2
421   // Expect shuffle after 2nd drag: P1 P2 P3
422   // Expect shuffle after cancel:   P3 P1 P2
423   mouse_location = position1;
424   panel3_testing->PressLeftMouseButtonTitlebar(mouse_location);
425   EXPECT_EQ(position2, panel1->GetBounds().origin());
426   EXPECT_EQ(position3, panel2->GetBounds().origin());
427   EXPECT_EQ(position1, panel3->GetBounds().origin());
428 
429   mouse_location = position2 + gfx::Vector2d(1, 0);
430   panel3_testing->DragTitlebar(mouse_location);
431   EXPECT_EQ(position1, panel1->GetBounds().origin());
432   EXPECT_EQ(position3, panel2->GetBounds().origin());
433   EXPECT_EQ(mouse_location, panel3->GetBounds().origin());
434 
435   mouse_location = position3 + gfx::Vector2d(1, 0);
436   panel3_testing->DragTitlebar(mouse_location);
437   EXPECT_EQ(position1, panel1->GetBounds().origin());
438   EXPECT_EQ(position2, panel2->GetBounds().origin());
439   EXPECT_EQ(mouse_location, panel3->GetBounds().origin());
440 
441   panel3_testing->CancelDragTitlebar();
442   EXPECT_EQ(position2, panel1->GetBounds().origin());
443   EXPECT_EQ(position3, panel2->GetBounds().origin());
444   EXPECT_EQ(position1, panel3->GetBounds().origin());
445 
446   // Drag leftmost panel to become the rightmost in a single drag. The drag will
447   // shuffle 2 panels at a time.
448   // Expect shuffle: P2 P3 P1
449   mouse_location = position3;
450   panel2_testing->PressLeftMouseButtonTitlebar(mouse_location);
451   EXPECT_EQ(position2, panel1->GetBounds().origin());
452   EXPECT_EQ(position3, panel2->GetBounds().origin());
453   EXPECT_EQ(position1, panel3->GetBounds().origin());
454 
455   mouse_location = position1 + gfx::Vector2d(1, 0);
456   panel2_testing->DragTitlebar(mouse_location);
457   EXPECT_EQ(position3, panel1->GetBounds().origin());
458   EXPECT_EQ(mouse_location, panel2->GetBounds().origin());
459   EXPECT_EQ(position2, panel3->GetBounds().origin());
460 
461   panel2_testing->FinishDragTitlebar();
462   EXPECT_EQ(position3, panel1->GetBounds().origin());
463   EXPECT_EQ(position1, panel2->GetBounds().origin());
464   EXPECT_EQ(position2, panel3->GetBounds().origin());
465 
466   // Drag rightmost panel to become the leftmost in a single drag. The drag will
467   // shuffle 2 panels at a time.
468   // Expect shuffle: P3 P1 P2
469   mouse_location = position1;
470   panel2_testing->PressLeftMouseButtonTitlebar(mouse_location);
471   EXPECT_EQ(position3, panel1->GetBounds().origin());
472   EXPECT_EQ(position1, panel2->GetBounds().origin());
473   EXPECT_EQ(position2, panel3->GetBounds().origin());
474 
475   mouse_location = position3 + gfx::Vector2d(1, 0);
476   panel2_testing->DragTitlebar(mouse_location);
477   EXPECT_EQ(position2, panel1->GetBounds().origin());
478   EXPECT_EQ(mouse_location, panel2->GetBounds().origin());
479   EXPECT_EQ(position1, panel3->GetBounds().origin());
480 
481   panel2_testing->FinishDragTitlebar();
482   EXPECT_EQ(position2, panel1->GetBounds().origin());
483   EXPECT_EQ(position3, panel2->GetBounds().origin());
484   EXPECT_EQ(position1, panel3->GetBounds().origin());
485 
486   // Drag rightmost panel to become the leftmost in a single drag and then
487   // cancel the drag. The drag will shuffle 2 panels and the cancellation will
488   // restore all panels.
489   // Expect shuffle after drag:   P1 P2 P3
490   // Expect shuffle after cancel: P3 P1 P2
491   mouse_location = position1;
492   panel3_testing->PressLeftMouseButtonTitlebar(mouse_location);
493   EXPECT_EQ(position2, panel1->GetBounds().origin());
494   EXPECT_EQ(position3, panel2->GetBounds().origin());
495   EXPECT_EQ(position1, panel3->GetBounds().origin());
496 
497   mouse_location = position3 + gfx::Vector2d(1, 0);
498   panel3_testing->DragTitlebar(mouse_location);
499   EXPECT_EQ(position1, panel1->GetBounds().origin());
500   EXPECT_EQ(position2, panel2->GetBounds().origin());
501   EXPECT_EQ(mouse_location, panel3->GetBounds().origin());
502 
503   panel3_testing->CancelDragTitlebar();
504   EXPECT_EQ(position2, panel1->GetBounds().origin());
505   EXPECT_EQ(position3, panel2->GetBounds().origin());
506   EXPECT_EQ(position1, panel3->GetBounds().origin());
507 
508   PanelManager::GetInstance()->CloseAll();
509 }
510 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,DragMinimizedPanel)511 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DragMinimizedPanel) {
512   Panel* panel = CreatePanel("panel1");
513   scoped_ptr<NativePanelTesting> panel_testing(
514       CreateNativePanelTesting(panel));
515 
516   panel->Minimize();
517   EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
518 
519   // Hover over minimized panel to bring up titlebar.
520   gfx::Point hover_point(panel->GetBounds().origin());
521   MoveMouseAndWaitForExpansionStateChange(panel, hover_point);
522   EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
523 
524   // Verify we can drag a minimized panel.
525   gfx::Rect panel_old_bounds = panel->GetBounds();
526   gfx::Point mouse_location = panel_old_bounds.origin();
527   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
528   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
529   EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
530 
531   mouse_location.Offset(-70, 0);
532   panel_testing->DragTitlebar(mouse_location);
533   gfx::Rect panel_new_bounds = panel_old_bounds;
534   panel_new_bounds.Offset(-70, 0);
535   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
536   EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
537 
538   // Verify panel returns to fully minimized state after dragging ends once
539   // mouse moves away from panel.
540   panel_testing->FinishDragTitlebar();
541   EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
542 
543   MoveMouseAndWaitForExpansionStateChange(panel, mouse_location);
544   EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
545 
546   panel->Close();
547 }
548 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,DragMinimizedPanelWhileDrawingAttention)549 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,
550                        DragMinimizedPanelWhileDrawingAttention) {
551   Panel* panel = CreatePanel("panel1");
552   scoped_ptr<NativePanelTesting> panel_testing(
553       CreateNativePanelTesting(panel));
554   CreatePanel("panel2");
555 
556   panel->Minimize();
557   EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
558 
559   panel->FlashFrame(true);
560   EXPECT_TRUE(panel->IsDrawingAttention());
561   EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
562 
563   // Drag the panel. Verify panel stays in title-only state after attention is
564   // cleared because it is being dragged.
565   gfx::Rect panel_old_bounds = panel->GetBounds();
566   gfx::Point mouse_location = panel_old_bounds.origin();
567   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
568   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
569   EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
570 
571   mouse_location.Offset(-70, 0);
572   panel_testing->DragTitlebar(mouse_location);
573   gfx::Rect panel_new_bounds = panel_old_bounds;
574   panel_new_bounds.Offset(-70, 0);
575   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
576 
577   panel->FlashFrame(false);
578   EXPECT_FALSE(panel->IsDrawingAttention());
579   EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
580 
581   // Typical user scenario will detect the mouse in the panel
582   // after attention is cleared, causing titles to pop up, so
583   // we simulate that here.
584   MoveMouse(mouse_location);
585 
586   // Verify panel returns to fully minimized state after dragging ends once
587   // mouse moves away from the panel.
588   panel_testing->FinishDragTitlebar();
589   EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state());
590 
591   mouse_location.Offset(0, -50);
592   MoveMouseAndWaitForExpansionStateChange(panel, mouse_location);
593   EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state());
594 
595   PanelManager::GetInstance()->CloseAll();
596 }
597 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,CloseDockedPanelOnDrag)598 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, CloseDockedPanelOnDrag) {
599   PanelManager* panel_manager = PanelManager::GetInstance();
600   PanelDragController* drag_controller = panel_manager->drag_controller();
601   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
602 
603   // Create 4 docked panels.
604   // We have:  P4  P3  P2  P1
605   Panel* panel1 = CreatePanelWithBounds("Panel1", gfx::Rect(0, 0, 100, 100));
606   Panel* panel2 = CreatePanelWithBounds("Panel2", gfx::Rect(0, 0, 100, 100));
607   Panel* panel3 = CreatePanelWithBounds("Panel3", gfx::Rect(0, 0, 100, 100));
608   Panel* panel4 = CreatePanelWithBounds("Panel4", gfx::Rect(0, 0, 100, 100));
609   ASSERT_EQ(4, docked_collection->num_panels());
610 
611   scoped_ptr<NativePanelTesting> panel1_testing(
612       CreateNativePanelTesting(panel1));
613   gfx::Point position1 = panel1->GetBounds().origin();
614   gfx::Point position2 = panel2->GetBounds().origin();
615   gfx::Point position3 = panel3->GetBounds().origin();
616   gfx::Point position4 = panel4->GetBounds().origin();
617 
618   // Test the scenario: drag a panel, close another panel, cancel the drag.
619   {
620     std::vector<Panel*> panels;
621     gfx::Point panel1_new_position = position1;
622     panel1_new_position.Offset(-500, 0);
623 
624     // Start dragging a panel.
625     // We have:  P1*  P4  P3  P2
626     gfx::Point mouse_location = panel1->GetBounds().origin();
627     panel1_testing->PressLeftMouseButtonTitlebar(mouse_location);
628     mouse_location.Offset(-500, -5);
629     panel1_testing->DragTitlebar(mouse_location);
630     EXPECT_TRUE(drag_controller->is_dragging());
631     EXPECT_EQ(panel1, drag_controller->dragging_panel());
632 
633     ASSERT_EQ(4, docked_collection->num_panels());
634     panels = PanelManager::GetInstance()->panels();
635     EXPECT_EQ(panel2, panels[0]);
636     EXPECT_EQ(panel3, panels[1]);
637     EXPECT_EQ(panel4, panels[2]);
638     EXPECT_EQ(panel1, panels[3]);
639     EXPECT_EQ(position1, panel2->GetBounds().origin());
640     EXPECT_EQ(position2, panel3->GetBounds().origin());
641     EXPECT_EQ(position3, panel4->GetBounds().origin());
642     EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin());
643 
644     // Closing another panel while dragging in progress will keep the dragging
645     // panel intact.
646     // We have:  P1*  P4  P3
647     CloseWindowAndWait(panel2);
648     EXPECT_TRUE(drag_controller->is_dragging());
649     EXPECT_EQ(panel1, drag_controller->dragging_panel());
650 
651     ASSERT_EQ(3, docked_collection->num_panels());
652     panels = PanelManager::GetInstance()->panels();
653     EXPECT_EQ(panel3, panels[0]);
654     EXPECT_EQ(panel4, panels[1]);
655     EXPECT_EQ(panel1, panels[2]);
656     EXPECT_EQ(position1, panel3->GetBounds().origin());
657     EXPECT_EQ(position2, panel4->GetBounds().origin());
658     EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin());
659 
660     // Cancel the drag.
661     // We have:  P4  P3  P1
662     panel1_testing->CancelDragTitlebar();
663     EXPECT_FALSE(drag_controller->is_dragging());
664 
665     ASSERT_EQ(3, docked_collection->num_panels());
666     panels = PanelManager::GetInstance()->panels();
667     EXPECT_EQ(panel1, panels[0]);
668     EXPECT_EQ(panel3, panels[1]);
669     EXPECT_EQ(panel4, panels[2]);
670     EXPECT_EQ(position1, panel1->GetBounds().origin());
671     EXPECT_EQ(position2, panel3->GetBounds().origin());
672     EXPECT_EQ(position3, panel4->GetBounds().origin());
673   }
674 
675   // Test the scenario: drag a panel, close another panel, end the drag.
676   {
677     std::vector<Panel*> panels;
678     gfx::Point panel1_new_position = position1;
679     panel1_new_position.Offset(-500, 0);
680 
681     // Start dragging a panel.
682     // We have:  P1*  P4  P3
683     gfx::Point mouse_location = panel1->GetBounds().origin();
684     panel1_testing->PressLeftMouseButtonTitlebar(mouse_location);
685     mouse_location.Offset(-500, -5);
686     panel1_testing->DragTitlebar(mouse_location);
687     EXPECT_TRUE(drag_controller->is_dragging());
688     EXPECT_EQ(panel1, drag_controller->dragging_panel());
689 
690     ASSERT_EQ(3, docked_collection->num_panels());
691     panels = PanelManager::GetInstance()->panels();
692     EXPECT_EQ(panel3, panels[0]);
693     EXPECT_EQ(panel4, panels[1]);
694     EXPECT_EQ(panel1, panels[2]);
695     EXPECT_EQ(position1, panel3->GetBounds().origin());
696     EXPECT_EQ(position2, panel4->GetBounds().origin());
697     EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin());
698 
699     // Closing another panel while dragging in progress will keep the dragging
700     // panel intact.
701     // We have:  P1*  P4
702     CloseWindowAndWait(panel3);
703     EXPECT_TRUE(drag_controller->is_dragging());
704     EXPECT_EQ(panel1, drag_controller->dragging_panel());
705 
706     ASSERT_EQ(2, docked_collection->num_panels());
707     panels = PanelManager::GetInstance()->panels();
708     EXPECT_EQ(panel4, panels[0]);
709     EXPECT_EQ(panel1, panels[1]);
710     EXPECT_EQ(position1, panel4->GetBounds().origin());
711     EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin());
712 
713     // Finish the drag.
714     // We have:  P1  P4
715     panel1_testing->FinishDragTitlebar();
716     EXPECT_FALSE(drag_controller->is_dragging());
717 
718     ASSERT_EQ(2, docked_collection->num_panels());
719     panels = PanelManager::GetInstance()->panels();
720     EXPECT_EQ(panel4, panels[0]);
721     EXPECT_EQ(panel1, panels[1]);
722     EXPECT_EQ(position1, panel4->GetBounds().origin());
723     EXPECT_EQ(position2, panel1->GetBounds().origin());
724   }
725 
726   // Test the scenario: drag a panel and close the dragging panel.
727   {
728     std::vector<Panel*> panels;
729     gfx::Point panel1_new_position = position2;
730     panel1_new_position.Offset(-500, 0);
731 
732     // Start dragging a panel again.
733     // We have:  P1*  P4
734     gfx::Point mouse_location = panel1->GetBounds().origin();
735     panel1_testing->PressLeftMouseButtonTitlebar(mouse_location);
736     mouse_location.Offset(-500, -5);
737     panel1_testing->DragTitlebar(mouse_location);
738     EXPECT_TRUE(drag_controller->is_dragging());
739     EXPECT_EQ(panel1, drag_controller->dragging_panel());
740     EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin());
741 
742     ASSERT_EQ(2, docked_collection->num_panels());
743     panels = PanelManager::GetInstance()->panels();
744     EXPECT_EQ(panel4, panels[0]);
745     EXPECT_EQ(panel1, panels[1]);
746     EXPECT_EQ(position1, panel4->GetBounds().origin());
747 
748     // Closing the dragging panel should make the drag controller abort.
749     // We have:  P4
750     content::WindowedNotificationObserver signal(
751         chrome::NOTIFICATION_PANEL_CLOSED, content::Source<Panel>(panel1));
752     panel1->Close();
753     EXPECT_FALSE(drag_controller->is_dragging());
754 
755     // Continue the drag to ensure the drag controller does not crash.
756     panel1_new_position.Offset(20, 30);
757     panel1_testing->DragTitlebar(panel1_new_position);
758     panel1_testing->FinishDragTitlebar();
759 
760     // Wait till the panel is fully closed.
761     signal.Wait();
762     ASSERT_EQ(1, docked_collection->num_panels());
763     panels = PanelManager::GetInstance()->panels();
764     EXPECT_EQ(panel4, panels[0]);
765     EXPECT_EQ(position1, panel4->GetBounds().origin());
766   }
767 
768   panel_manager->CloseAll();
769 }
770 
771 // http://crbug.com/175760; several panel tests failing regularly on mac.
772 #if defined(OS_MACOSX)
773 #define MAYBE_DragOneDetachedPanel DISABLED_DragOneDetachedPanel
774 #else
775 #define MAYBE_DragOneDetachedPanel DragOneDetachedPanel
776 #endif
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,MAYBE_DragOneDetachedPanel)777 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, MAYBE_DragOneDetachedPanel) {
778   Panel* panel = CreateDetachedPanel("1", gfx::Rect(300, 200, 250, 200));
779 
780   // Test that the detached panel can be dragged almost anywhere except getting
781   // close to the bottom of the docked area to trigger the attach.
782   scoped_ptr<NativePanelTesting> panel_testing(
783       CreateNativePanelTesting(panel));
784   gfx::Point origin = panel->GetBounds().origin();
785 
786   panel_testing->PressLeftMouseButtonTitlebar(origin);
787   EXPECT_EQ(origin, panel->GetBounds().origin());
788 
789   origin.Offset(-51, -102);
790   panel_testing->DragTitlebar(origin);
791   EXPECT_EQ(origin, panel->GetBounds().origin());
792 
793   origin.Offset(37, 45);
794   panel_testing->DragTitlebar(origin);
795   EXPECT_EQ(origin, panel->GetBounds().origin());
796 
797   panel_testing->FinishDragTitlebar();
798   EXPECT_EQ(origin, panel->GetBounds().origin());
799 
800   // Test that cancelling the drag will return the panel the the original
801   // position.
802   gfx::Point original_position = panel->GetBounds().origin();
803   origin = original_position;
804 
805   panel_testing->PressLeftMouseButtonTitlebar(origin);
806   EXPECT_EQ(origin, panel->GetBounds().origin());
807 
808   origin.Offset(-51, -102);
809   panel_testing->DragTitlebar(origin);
810   EXPECT_EQ(origin, panel->GetBounds().origin());
811 
812   origin.Offset(37, 45);
813   panel_testing->DragTitlebar(origin);
814   EXPECT_EQ(origin, panel->GetBounds().origin());
815 
816   panel_testing->CancelDragTitlebar();
817   WaitForBoundsAnimationFinished(panel);
818   EXPECT_EQ(original_position, panel->GetBounds().origin());
819 
820   PanelManager::GetInstance()->CloseAll();
821 }
822 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,CloseDetachedPanelOnDrag)823 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, CloseDetachedPanelOnDrag) {
824   PanelManager* panel_manager = PanelManager::GetInstance();
825   PanelDragController* drag_controller = panel_manager->drag_controller();
826   DetachedPanelCollection* detached_collection =
827       panel_manager->detached_collection();
828 
829   // Create 1 detached panel.
830   Panel* panel1 = CreateDetachedPanel("1", gfx::Rect(100, 200, 100, 100));
831   ASSERT_EQ(1, detached_collection->num_panels());
832 
833   scoped_ptr<NativePanelTesting> panel1_testing(
834       CreateNativePanelTesting(panel1));
835   gfx::Point panel1_old_position = panel1->GetBounds().origin();
836 
837   // Test the scenario: drag a panel, close another panel, cancel the drag.
838   {
839     // Create a panel to be closed.
840     Panel* panel2 = CreateDetachedPanel("2", gfx::Rect(300, 210, 110, 110));
841 
842     // Start dragging a panel.
843     panel1_testing->PressLeftMouseButtonTitlebar(panel1->GetBounds().origin());
844     gfx::Point panel1_new_position = panel1_old_position;
845     panel1_new_position.Offset(-51, -102);
846     panel1_testing->DragTitlebar(panel1_new_position);
847     EXPECT_TRUE(drag_controller->is_dragging());
848     EXPECT_EQ(panel1, drag_controller->dragging_panel());
849 
850     ASSERT_EQ(2, detached_collection->num_panels());
851     EXPECT_TRUE(detached_collection->HasPanel(panel1));
852     EXPECT_TRUE(detached_collection->HasPanel(panel2));
853     EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin());
854 
855     // Closing another panel while dragging in progress will keep the dragging
856     // panel intact.
857     CloseWindowAndWait(panel2);
858     EXPECT_TRUE(drag_controller->is_dragging());
859     EXPECT_EQ(panel1, drag_controller->dragging_panel());
860 
861     ASSERT_EQ(1, detached_collection->num_panels());
862     EXPECT_TRUE(detached_collection->HasPanel(panel1));
863     EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin());
864 
865     // Cancel the drag.
866     panel1_testing->CancelDragTitlebar();
867     WaitForBoundsAnimationFinished(panel1);
868     EXPECT_FALSE(drag_controller->is_dragging());
869     EXPECT_EQ(panel1_old_position, panel1->GetBounds().origin());
870   }
871 
872   // Test the scenario: drag a panel, close another panel, end the drag.
873   {
874     // Create a panel to be closed.
875     Panel* panel2 = CreateDetachedPanel("2", gfx::Rect(300, 210, 110, 110));
876 
877     // Start dragging a panel.
878     panel1_testing->PressLeftMouseButtonTitlebar(panel1->GetBounds().origin());
879     gfx::Point panel1_new_position = panel1_old_position;
880     panel1_new_position.Offset(-51, -102);
881     panel1_testing->DragTitlebar(panel1_new_position);
882     EXPECT_TRUE(drag_controller->is_dragging());
883     EXPECT_EQ(panel1, drag_controller->dragging_panel());
884 
885     ASSERT_EQ(2, detached_collection->num_panels());
886     EXPECT_TRUE(detached_collection->HasPanel(panel1));
887     EXPECT_TRUE(detached_collection->HasPanel(panel2));
888     EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin());
889 
890     // Closing another panel while dragging in progress will keep the dragging
891     // panel intact.
892     CloseWindowAndWait(panel2);
893     EXPECT_TRUE(drag_controller->is_dragging());
894     EXPECT_EQ(panel1, drag_controller->dragging_panel());
895 
896     ASSERT_EQ(1, detached_collection->num_panels());
897     EXPECT_TRUE(detached_collection->HasPanel(panel1));
898     EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin());
899 
900     // Finish the drag.
901     panel1_testing->FinishDragTitlebar();
902     EXPECT_FALSE(drag_controller->is_dragging());
903     EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin());
904   }
905 
906   // Test the scenario: drag a panel and close the dragging panel.
907   {
908     // Start dragging a panel again.
909     panel1_testing->PressLeftMouseButtonTitlebar(panel1->GetBounds().origin());
910     gfx::Point panel1_new_position = panel1->GetBounds().origin();
911     panel1_new_position.Offset(45, 67);
912     panel1_testing->DragTitlebar(panel1_new_position);
913     EXPECT_TRUE(drag_controller->is_dragging());
914     EXPECT_EQ(panel1, drag_controller->dragging_panel());
915 
916     ASSERT_EQ(1, detached_collection->num_panels());
917     EXPECT_TRUE(detached_collection->HasPanel(panel1));
918     EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin());
919 
920     // Closing the dragging panel should make the drag controller abort.
921     content::WindowedNotificationObserver signal(
922         chrome::NOTIFICATION_PANEL_CLOSED, content::Source<Panel>(panel1));
923     panel1->Close();
924     EXPECT_FALSE(drag_controller->is_dragging());
925 
926     // Continue the drag to ensure the drag controller does not crash.
927     panel1_new_position.Offset(20, 30);
928     panel1_testing->DragTitlebar(panel1_new_position);
929     panel1_testing->FinishDragTitlebar();
930 
931     // Wait till the panel is fully closed.
932     signal.Wait();
933     ASSERT_EQ(0, detached_collection->num_panels());
934   }
935 }
936 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,Detach)937 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, Detach) {
938   PanelManager* panel_manager = PanelManager::GetInstance();
939   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
940   DetachedPanelCollection* detached_collection =
941       panel_manager->detached_collection();
942 
943   // Create one docked panel.
944   Panel* panel = CreateDockedPanel("1", gfx::Rect(0, 0, 100, 100));
945   ASSERT_EQ(1, docked_collection->num_panels());
946   ASSERT_EQ(0, detached_collection->num_panels());
947 
948   gfx::Rect panel_old_bounds = panel->GetBounds();
949 
950   // Press on title-bar.
951   scoped_ptr<NativePanelTesting> panel_testing(
952       CreateNativePanelTesting(panel));
953   gfx::Point mouse_location(panel->GetBounds().origin());
954   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
955 
956   // Drag up the panel in a small offset that does not trigger the detach.
957   // Expect that the panel is still docked and only x coordinate of its position
958   // is changed.
959   gfx::Vector2d drag_delta_to_remain_docked = GetDragDeltaToRemainDocked();
960   mouse_location = mouse_location + drag_delta_to_remain_docked;
961   panel_testing->DragTitlebar(mouse_location);
962   ASSERT_EQ(1, docked_collection->num_panels());
963   ASSERT_EQ(0, detached_collection->num_panels());
964   EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type());
965   gfx::Rect panel_new_bounds = panel_old_bounds;
966   panel_new_bounds.Offset(drag_delta_to_remain_docked.x(), 0);
967   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
968 
969   // Continue dragging up the panel in big offset that triggers the detach.
970   // Expect that the panel is previewed as detached.
971   gfx::Vector2d drag_delta_to_detach = GetDragDeltaToDetach();
972   mouse_location = mouse_location + drag_delta_to_detach;
973   panel_testing->DragTitlebar(mouse_location);
974   ASSERT_EQ(0, docked_collection->num_panels());
975   ASSERT_EQ(1, detached_collection->num_panels());
976   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
977   panel_new_bounds.Offset(
978       drag_delta_to_detach.x(),
979       drag_delta_to_detach.y() + drag_delta_to_remain_docked.y());
980   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
981 
982   // Finish the drag.
983   // Expect that the panel stays as detached.
984   panel_testing->FinishDragTitlebar();
985   ASSERT_EQ(0, docked_collection->num_panels());
986   ASSERT_EQ(1, detached_collection->num_panels());
987   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
988   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
989 
990   panel_manager->CloseAll();
991 }
992 
993 // http://crbug.com/175760; several panel tests failing regularly on mac.
994 #if defined(OS_MACOSX)
995 #define MAYBE_DetachAndCancel DISABLED_DetachAndCancel
996 #else
997 #define MAYBE_DetachAndCancel DetachAndCancel
998 #endif
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,MAYBE_DetachAndCancel)999 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, MAYBE_DetachAndCancel) {
1000   PanelManager* panel_manager = PanelManager::GetInstance();
1001   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
1002   DetachedPanelCollection* detached_collection =
1003       panel_manager->detached_collection();
1004 
1005   // Create one docked panel.
1006   Panel* panel = CreateDockedPanel("1", gfx::Rect(0, 0, 100, 100));
1007   ASSERT_EQ(1, docked_collection->num_panels());
1008   ASSERT_EQ(0, detached_collection->num_panels());
1009 
1010   gfx::Rect panel_old_bounds = panel->GetBounds();
1011 
1012   // Press on title-bar.
1013   scoped_ptr<NativePanelTesting> panel_testing(
1014       CreateNativePanelTesting(panel));
1015   gfx::Point mouse_location(panel->GetBounds().origin());
1016   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
1017 
1018   // Drag up the panel in a small offset that does not trigger the detach.
1019   // Expect that the panel is still docked and only x coordinate of its position
1020   // is changed.
1021   gfx::Vector2d drag_delta_to_remain_docked = GetDragDeltaToRemainDocked();
1022   mouse_location = mouse_location + drag_delta_to_remain_docked;
1023   panel_testing->DragTitlebar(mouse_location);
1024   ASSERT_EQ(1, docked_collection->num_panels());
1025   ASSERT_EQ(0, detached_collection->num_panels());
1026   EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type());
1027   gfx::Rect panel_new_bounds = panel_old_bounds;
1028   panel_new_bounds.Offset(drag_delta_to_remain_docked.x(), 0);
1029   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
1030 
1031   // Continue dragging up the panel in big offset that triggers the detach.
1032   // Expect that the panel is previewed as detached.
1033   gfx::Vector2d drag_delta_to_detach = GetDragDeltaToDetach();
1034   mouse_location = mouse_location + drag_delta_to_detach;
1035   panel_testing->DragTitlebar(mouse_location);
1036   ASSERT_EQ(0, docked_collection->num_panels());
1037   ASSERT_EQ(1, detached_collection->num_panels());
1038   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
1039   panel_new_bounds.Offset(
1040       drag_delta_to_detach.x(),
1041       drag_delta_to_detach.y() + drag_delta_to_remain_docked.y());
1042   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
1043 
1044   // Cancel the drag.
1045   // Expect that the panel is back as docked.
1046   panel_testing->CancelDragTitlebar();
1047   ASSERT_EQ(1, docked_collection->num_panels());
1048   ASSERT_EQ(0, detached_collection->num_panels());
1049   EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type());
1050   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
1051 
1052   panel_manager->CloseAll();
1053 }
1054 
1055 // http://crbug.com/175760; several panel tests failing regularly on mac.
1056 #if defined(OS_MACOSX)
1057 #define MAYBE_Attach DISABLED_Attach
1058 #else
1059 #define MAYBE_Attach Attach
1060 #endif
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,MAYBE_Attach)1061 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, MAYBE_Attach) {
1062   PanelManager* panel_manager = PanelManager::GetInstance();
1063   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
1064   DetachedPanelCollection* detached_collection =
1065       panel_manager->detached_collection();
1066 
1067   // Create one detached panel.
1068   Panel* panel = CreateDetachedPanel("1", gfx::Rect(400, 300, 100, 100));
1069   ASSERT_EQ(0, docked_collection->num_panels());
1070   ASSERT_EQ(1, detached_collection->num_panels());
1071   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
1072 
1073   gfx::Rect panel_old_bounds = panel->GetBounds();
1074 
1075   // Press on title-bar.
1076   scoped_ptr<NativePanelTesting> panel_testing(
1077       CreateNativePanelTesting(panel));
1078   gfx::Point mouse_location(panel->GetBounds().origin());
1079   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
1080 
1081   // Drag down the panel but not close enough to the bottom of work area.
1082   // Expect that the panel is still detached.
1083   gfx::Vector2d drag_delta_to_remain_detached =
1084       GetDragDeltaToRemainDetached(panel);
1085   mouse_location = mouse_location + drag_delta_to_remain_detached;
1086   panel_testing->DragTitlebar(mouse_location);
1087   ASSERT_EQ(0, docked_collection->num_panels());
1088   ASSERT_EQ(1, detached_collection->num_panels());
1089   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
1090   gfx::Rect panel_new_bounds = panel_old_bounds;
1091   panel_new_bounds.Offset(drag_delta_to_remain_detached);
1092   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
1093 
1094   // Continue dragging down the panel to make it close enough to the bottom of
1095   // work area.
1096   // Expect that the panel is previewed as docked.
1097   gfx::Vector2d drag_delta_to_attach = GetDragDeltaToAttach(panel);
1098   mouse_location = mouse_location + drag_delta_to_attach;
1099   panel_testing->DragTitlebar(mouse_location);
1100   ASSERT_EQ(1, docked_collection->num_panels());
1101   ASSERT_EQ(0, detached_collection->num_panels());
1102   EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type());
1103   panel_new_bounds.Offset(drag_delta_to_attach);
1104   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
1105 
1106   // Finish the drag.
1107   // Expect that the panel stays as docked and moves to the final position.
1108   panel_testing->FinishDragTitlebar();
1109   ASSERT_EQ(1, docked_collection->num_panels());
1110   ASSERT_EQ(0, detached_collection->num_panels());
1111   EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type());
1112   panel_new_bounds.set_x(
1113       docked_collection->StartingRightPosition() - panel_new_bounds.width());
1114   panel_new_bounds.set_y(
1115       docked_collection->work_area().bottom() - panel_new_bounds.height());
1116   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
1117 
1118   panel_manager->CloseAll();
1119 }
1120 
1121 // http://crbug.com/175760; several panel tests failing regularly on mac.
1122 #if defined(OS_MACOSX)
1123 #define MAYBE_AttachAndCancel DISABLED_AttachAndCancel
1124 #else
1125 #define MAYBE_AttachAndCancel AttachAndCancel
1126 #endif
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,MAYBE_AttachAndCancel)1127 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, MAYBE_AttachAndCancel) {
1128   PanelManager* panel_manager = PanelManager::GetInstance();
1129   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
1130   DetachedPanelCollection* detached_collection =
1131       panel_manager->detached_collection();
1132 
1133   // Create one detached panel.
1134   Panel* panel = CreateDetachedPanel("1", gfx::Rect(400, 300, 100, 100));
1135   ASSERT_EQ(0, docked_collection->num_panels());
1136   ASSERT_EQ(1, detached_collection->num_panels());
1137   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
1138 
1139   gfx::Rect panel_old_bounds = panel->GetBounds();
1140 
1141   // Press on title-bar.
1142   scoped_ptr<NativePanelTesting> panel_testing(
1143       CreateNativePanelTesting(panel));
1144   gfx::Point mouse_location(panel->GetBounds().origin());
1145   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
1146 
1147   // Drag down the panel but not close enough to the bottom of work area.
1148   // Expect that the panel is still detached.
1149   gfx::Vector2d drag_delta_to_remain_detached =
1150       GetDragDeltaToRemainDetached(panel);
1151   mouse_location = mouse_location + drag_delta_to_remain_detached;
1152   panel_testing->DragTitlebar(mouse_location);
1153   ASSERT_EQ(0, docked_collection->num_panels());
1154   ASSERT_EQ(1, detached_collection->num_panels());
1155   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
1156   gfx::Rect panel_new_bounds = panel_old_bounds;
1157   panel_new_bounds.Offset(drag_delta_to_remain_detached);
1158   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
1159 
1160   // Continue dragging down the panel to make it close enough to the bottom of
1161   // work area.
1162   // Expect that the panel is previewed as docked.
1163   gfx::Vector2d drag_delta_to_attach = GetDragDeltaToAttach(panel);
1164   mouse_location = mouse_location + drag_delta_to_attach;
1165   panel_testing->DragTitlebar(mouse_location);
1166   ASSERT_EQ(1, docked_collection->num_panels());
1167   ASSERT_EQ(0, detached_collection->num_panels());
1168   EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type());
1169   panel_new_bounds.Offset(drag_delta_to_attach);
1170   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
1171 
1172   // Cancel the drag.
1173   // Expect that the panel is back as detached.
1174   panel_testing->CancelDragTitlebar();
1175   ASSERT_EQ(0, docked_collection->num_panels());
1176   ASSERT_EQ(1, detached_collection->num_panels());
1177   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
1178   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
1179 
1180   panel_manager->CloseAll();
1181 }
1182 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,DetachAttachAndCancel)1183 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DetachAttachAndCancel) {
1184   PanelManager* panel_manager = PanelManager::GetInstance();
1185   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
1186   DetachedPanelCollection* detached_collection =
1187       panel_manager->detached_collection();
1188 
1189   // Create one docked panel.
1190   Panel* panel = CreateDockedPanel("1", gfx::Rect(0, 0, 100, 100));
1191   ASSERT_EQ(1, docked_collection->num_panels());
1192   ASSERT_EQ(0, detached_collection->num_panels());
1193 
1194   gfx::Rect panel_old_bounds = panel->GetBounds();
1195 
1196   // Press on title-bar.
1197   scoped_ptr<NativePanelTesting> panel_testing(
1198       CreateNativePanelTesting(panel));
1199   gfx::Point mouse_location(panel->GetBounds().origin());
1200   panel_testing->PressLeftMouseButtonTitlebar(mouse_location);
1201 
1202   // Drag up the panel to trigger the detach.
1203   // Expect that the panel is previewed as detached.
1204   gfx::Vector2d drag_delta_to_detach = GetDragDeltaToDetach();
1205   mouse_location = mouse_location + drag_delta_to_detach;
1206   panel_testing->DragTitlebar(mouse_location);
1207   ASSERT_EQ(0, docked_collection->num_panels());
1208   ASSERT_EQ(1, detached_collection->num_panels());
1209   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
1210   gfx::Rect panel_new_bounds = panel_old_bounds;
1211   panel_new_bounds.Offset(drag_delta_to_detach);
1212   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
1213 
1214   // Continue dragging down the panel to trigger the re-attach.
1215   gfx::Vector2d drag_delta_to_reattach = GetDragDeltaToAttach(panel);
1216   mouse_location = mouse_location + drag_delta_to_reattach;
1217   panel_testing->DragTitlebar(mouse_location);
1218   ASSERT_EQ(1, docked_collection->num_panels());
1219   ASSERT_EQ(0, detached_collection->num_panels());
1220   EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type());
1221   panel_new_bounds.Offset(drag_delta_to_reattach);
1222   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
1223 
1224   // Continue dragging up the panel to trigger the detach again.
1225   gfx::Vector2d drag_delta_to_detach_again = GetDragDeltaToDetach();
1226   mouse_location = mouse_location + drag_delta_to_detach_again;
1227   panel_testing->DragTitlebar(mouse_location);
1228   ASSERT_EQ(0, docked_collection->num_panels());
1229   ASSERT_EQ(1, detached_collection->num_panels());
1230   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
1231   panel_new_bounds.Offset(drag_delta_to_detach_again);
1232   EXPECT_EQ(panel_new_bounds, panel->GetBounds());
1233 
1234   // Cancel the drag.
1235   // Expect that the panel stays as docked.
1236   panel_testing->CancelDragTitlebar();
1237   ASSERT_EQ(1, docked_collection->num_panels());
1238   ASSERT_EQ(0, detached_collection->num_panels());
1239   EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type());
1240   EXPECT_EQ(panel_old_bounds, panel->GetBounds());
1241 
1242   panel_manager->CloseAll();
1243 }
1244 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,DetachWithSqueeze)1245 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DetachWithSqueeze) {
1246   PanelManager* panel_manager = PanelManager::GetInstance();
1247   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
1248   DetachedPanelCollection* detached_collection =
1249       panel_manager->detached_collection();
1250 
1251   // Create some docked panels.
1252   //   docked:    P1  P2  P3  P4  P5
1253   Panel* panel1 = CreateDockedPanel("1", gfx::Rect(0, 0, 200, 100));
1254   Panel* panel2 = CreateDockedPanel("2", gfx::Rect(0, 0, 200, 100));
1255   Panel* panel3 = CreateDockedPanel("3", gfx::Rect(0, 0, 200, 100));
1256   Panel* panel4 = CreateDockedPanel("4", gfx::Rect(0, 0, 200, 100));
1257   Panel* panel5 = CreateDockedPanel("5", gfx::Rect(0, 0, 200, 100));
1258   ASSERT_EQ(0, detached_collection->num_panels());
1259   ASSERT_EQ(5, docked_collection->num_panels());
1260 
1261   // Drag to detach the middle docked panel.
1262   // Expect to have:
1263   //   detached:  P2
1264   //   docked:    P1  P3  P4 P5
1265   gfx::Point panel2_docked_position = panel2->GetBounds().origin();
1266   gfx::Vector2d drag_delta_to_detach_panel2(-20, -100);
1267   DragPanelByDelta(panel2, drag_delta_to_detach_panel2);
1268   ASSERT_EQ(1, detached_collection->num_panels());
1269   ASSERT_EQ(4, docked_collection->num_panels());
1270   EXPECT_EQ(PanelCollection::DOCKED, panel1->collection()->type());
1271   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
1272   EXPECT_EQ(PanelCollection::DOCKED, panel3->collection()->type());
1273   EXPECT_EQ(PanelCollection::DOCKED, panel4->collection()->type());
1274   EXPECT_EQ(PanelCollection::DOCKED, panel5->collection()->type());
1275   gfx::Point panel2_new_position =
1276       panel2_docked_position + drag_delta_to_detach_panel2;
1277   EXPECT_EQ(panel2_new_position, panel2->GetBounds().origin());
1278 
1279   // Drag to detach the left-most docked panel.
1280   // Expect to have:
1281   //   detached:  P2  P4
1282   //   docked:    P1  P3  P5
1283   gfx::Point panel4_docked_position = panel4->GetBounds().origin();
1284   gfx::Vector2d drag_delta_to_detach_panel4(-40, -250);
1285   DragPanelByDelta(panel4, drag_delta_to_detach_panel4);
1286   ASSERT_EQ(2, detached_collection->num_panels());
1287   ASSERT_EQ(3, docked_collection->num_panels());
1288   EXPECT_EQ(PanelCollection::DOCKED, panel1->collection()->type());
1289   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
1290   EXPECT_EQ(PanelCollection::DOCKED, panel3->collection()->type());
1291   EXPECT_EQ(PanelCollection::DETACHED, panel4->collection()->type());
1292   EXPECT_EQ(PanelCollection::DOCKED, panel5->collection()->type());
1293   EXPECT_EQ(panel2_new_position, panel2->GetBounds().origin());
1294   gfx::Point panel4_new_position =
1295       panel4_docked_position + drag_delta_to_detach_panel4;
1296   EXPECT_EQ(panel4_new_position, panel4->GetBounds().origin());
1297 
1298   // Drag to detach the right-most docked panel.
1299   // Expect to have:
1300   //   detached:  P1  P2  P4
1301   //   docked:    P3  P5
1302   gfx::Point docked_position1 = panel1->GetBounds().origin();
1303   gfx::Point docked_position2 = panel3->GetBounds().origin();
1304   gfx::Vector2d drag_delta_to_detach_panel1(-60, -400);
1305   DragPanelByDelta(panel1, drag_delta_to_detach_panel1);
1306   ASSERT_EQ(3, detached_collection->num_panels());
1307   ASSERT_EQ(2, docked_collection->num_panels());
1308   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
1309   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
1310   EXPECT_EQ(PanelCollection::DOCKED, panel3->collection()->type());
1311   EXPECT_EQ(PanelCollection::DETACHED, panel4->collection()->type());
1312   EXPECT_EQ(PanelCollection::DOCKED, panel5->collection()->type());
1313   gfx::Point panel1_new_position =
1314       docked_position1 + drag_delta_to_detach_panel1;
1315   EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin());
1316   EXPECT_EQ(panel2_new_position, panel2->GetBounds().origin());
1317   EXPECT_EQ(panel4_new_position, panel4->GetBounds().origin());
1318 
1319   // No more squeeze, docked panels should stay put.
1320   EXPECT_EQ(docked_position1, panel3->GetBounds().origin());
1321   EXPECT_EQ(panel1->GetBounds().width(), panel1->GetRestoredBounds().width());
1322   EXPECT_EQ(docked_position2, panel5->GetBounds().origin());
1323   EXPECT_EQ(panel2->GetBounds().width(), panel2->GetRestoredBounds().width());
1324 
1325   panel_manager->CloseAll();
1326 }
1327 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,AttachWithSqueeze)1328 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, AttachWithSqueeze) {
1329   PanelManager* panel_manager = PanelManager::GetInstance();
1330   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
1331   DetachedPanelCollection* detached_collection =
1332       panel_manager->detached_collection();
1333 
1334   // Create some detached, docked panels.
1335   //   detached:  P1  P2  P3
1336   //   docked:    P4  P5  P6  P7
1337   Panel* panel1 = CreateInactiveDetachedPanel(
1338       "1", gfx::Rect(100, 300, 200, 100));
1339   Panel* panel2 = CreateInactiveDetachedPanel(
1340       "2", gfx::Rect(200, 300, 200, 100));
1341   Panel* panel3 = CreateInactiveDetachedPanel(
1342       "3", gfx::Rect(400, 300, 200, 100));
1343   Panel* panel4 = CreateInactiveDockedPanel("4", gfx::Rect(0, 0, 200, 100));
1344   Panel* panel5 = CreateInactiveDockedPanel("5", gfx::Rect(0, 0, 200, 100));
1345   Panel* panel6 = CreateInactiveDockedPanel("6", gfx::Rect(0, 0, 200, 100));
1346   Panel* panel7 = CreateDockedPanel("7", gfx::Rect(0, 0, 200, 100));
1347   ASSERT_EQ(3, detached_collection->num_panels());
1348   ASSERT_EQ(4, docked_collection->num_panels());
1349 
1350   // Wait for active states to settle.
1351   PanelCollectionSqueezeObserver panel7_settled(docked_collection, panel7);
1352   panel7_settled.Wait();
1353 
1354   gfx::Point detached_position1 = panel1->GetBounds().origin();
1355   gfx::Point detached_position2 = panel2->GetBounds().origin();
1356   gfx::Point detached_position3 = panel3->GetBounds().origin();
1357   gfx::Point docked_position4 = panel4->GetBounds().origin();
1358   gfx::Point docked_position5 = panel5->GetBounds().origin();
1359   gfx::Point docked_position6 = panel6->GetBounds().origin();
1360   gfx::Point docked_position7 = panel7->GetBounds().origin();
1361 
1362   // Drag to attach a detached panel between 2 docked panels.
1363   // Expect to have:
1364   //   detached:  P1  P2
1365   //   docked:    P4  P3  P5  P6  P7
1366   gfx::Point drag_to_location(panel5->GetBounds().x() + 10,
1367                               panel5->GetBounds().y());
1368   DragPanelToMouseLocation(panel3, drag_to_location);
1369   ASSERT_EQ(2, detached_collection->num_panels());
1370   ASSERT_EQ(5, docked_collection->num_panels());
1371   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
1372   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
1373   EXPECT_EQ(PanelCollection::DOCKED, panel3->collection()->type());
1374   EXPECT_EQ(PanelCollection::DOCKED, panel4->collection()->type());
1375   EXPECT_EQ(PanelCollection::DOCKED, panel5->collection()->type());
1376   EXPECT_EQ(PanelCollection::DOCKED, panel6->collection()->type());
1377   EXPECT_EQ(PanelCollection::DOCKED, panel7->collection()->type());
1378   EXPECT_EQ(detached_position1, panel1->GetBounds().origin());
1379   EXPECT_EQ(detached_position2, panel2->GetBounds().origin());
1380 
1381   // Wait for active states to settle.
1382   base::MessageLoopForUI::current()->RunUntilIdle();
1383 
1384   // Panel positions should have shifted because of the "squeeze" mode.
1385   EXPECT_NE(docked_position4, panel4->GetBounds().origin());
1386   EXPECT_LT(panel4->GetBounds().width(), panel4->GetRestoredBounds().width());
1387   EXPECT_NE(docked_position5, panel5->GetBounds().origin());
1388   EXPECT_LT(panel5->GetBounds().width(), panel5->GetRestoredBounds().width());
1389 
1390 #if defined(OS_WIN)
1391   // The panel we dragged becomes the active one.
1392   EXPECT_EQ(true, panel3->IsActive());
1393   EXPECT_EQ(panel3->GetBounds().width(), panel3->GetRestoredBounds().width());
1394 
1395   EXPECT_NE(docked_position6, panel6->GetBounds().origin());
1396 #else
1397   // The last panel is active so these positions do not change.
1398   // TODO (ABurago) this is wrong behavior, a panel should activate
1399   // when it is dragged (it does in real usage, but not when drag is
1400   // simulated in a test). Change this test when the behavior is fixed.
1401   EXPECT_EQ(true, panel7->IsActive());
1402   EXPECT_EQ(panel7->GetBounds().width(), panel7->GetRestoredBounds().width());
1403 
1404   EXPECT_EQ(docked_position6, panel6->GetBounds().origin());
1405 #endif
1406   EXPECT_EQ(docked_position7, panel7->GetBounds().origin());
1407 
1408   // Drag to attach a detached panel to most-right.
1409   // Expect to have:
1410   //   detached:  P1
1411   //   docked:    P2  P4  P3  P5  P6  P7
1412   gfx::Point drag_to_location2(panel4->GetBounds().right() + 10,
1413                                panel4->GetBounds().y());
1414   DragPanelToMouseLocation(panel2, drag_to_location2);
1415   ASSERT_EQ(1, detached_collection->num_panels());
1416   ASSERT_EQ(6, docked_collection->num_panels());
1417   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
1418   EXPECT_EQ(PanelCollection::DOCKED, panel2->collection()->type());
1419   EXPECT_EQ(PanelCollection::DOCKED, panel3->collection()->type());
1420   EXPECT_EQ(PanelCollection::DOCKED, panel4->collection()->type());
1421   EXPECT_EQ(PanelCollection::DOCKED, panel5->collection()->type());
1422   EXPECT_EQ(PanelCollection::DOCKED, panel6->collection()->type());
1423   EXPECT_EQ(PanelCollection::DOCKED, panel7->collection()->type());
1424   EXPECT_EQ(detached_position1, panel1->GetBounds().origin());
1425 
1426   // Drag to attach a detached panel to most-left.
1427   // Expect to have:
1428   //   docked:    P2  P4  P1  P3  P5  P6  P7
1429   gfx::Point drag_to_location3(panel3->GetBounds().x() - 10,
1430                                panel3->GetBounds().y());
1431   DragPanelToMouseLocation(panel1, drag_to_location3);
1432   ASSERT_EQ(0, detached_collection->num_panels());
1433   ASSERT_EQ(7, docked_collection->num_panels());
1434   EXPECT_EQ(PanelCollection::DOCKED, panel1->collection()->type());
1435   EXPECT_EQ(PanelCollection::DOCKED, panel2->collection()->type());
1436   EXPECT_EQ(PanelCollection::DOCKED, panel3->collection()->type());
1437   EXPECT_EQ(PanelCollection::DOCKED, panel4->collection()->type());
1438   EXPECT_EQ(PanelCollection::DOCKED, panel5->collection()->type());
1439   EXPECT_EQ(PanelCollection::DOCKED, panel6->collection()->type());
1440   EXPECT_EQ(PanelCollection::DOCKED, panel7->collection()->type());
1441 
1442   panel_manager->CloseAll();
1443 }
1444 
1445 // http://crbug.com/175760; several panel tests failing regularly on mac.
1446 #if defined(OS_MACOSX)
1447 #define MAYBE_DragDetachedPanelToTop DISABLED_DragDetachedPanelToTop
1448 #else
1449 #define MAYBE_DragDetachedPanelToTop DragDetachedPanelToTop
1450 #endif
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,MAYBE_DragDetachedPanelToTop)1451 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, MAYBE_DragDetachedPanelToTop) {
1452   // Setup the test areas to have top-aligned bar excluded from work area.
1453   const gfx::Rect primary_display_area(0, 0, 800, 600);
1454   const gfx::Rect primary_work_area(0, 10, 800, 590);
1455   mock_display_settings_provider()->SetPrimaryDisplay(
1456       primary_display_area, primary_work_area);
1457 
1458   PanelManager* panel_manager = PanelManager::GetInstance();
1459   Panel* panel = CreateDetachedPanel("1", gfx::Rect(300, 200, 250, 200));
1460 
1461   // Drag up the panel. Expect that the panel should not go outside the top of
1462   // the work area.
1463   gfx::Point drag_to_location(250, 0);
1464   DragPanelToMouseLocation(panel, drag_to_location);
1465   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
1466   EXPECT_EQ(drag_to_location.x(), panel->GetBounds().origin().x());
1467   EXPECT_EQ(primary_work_area.y(), panel->GetBounds().origin().y());
1468 
1469   // Drag down the panel. Expect that the panel can be dragged without
1470   // constraint.
1471   drag_to_location = gfx::Point(280, 150);
1472   DragPanelToMouseLocation(panel, drag_to_location);
1473   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
1474   EXPECT_EQ(drag_to_location, panel->GetBounds().origin());
1475 
1476   panel_manager->CloseAll();
1477 }
1478 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,DragDockedPanelToSecondaryDisplay)1479 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,
1480                        DragDockedPanelToSecondaryDisplay) {
1481   // Setup 2 displays with secondary display on the right side of primary
1482   // display.
1483   mock_display_settings_provider()->SetPrimaryDisplay(
1484       gfx::Rect(0, 0, 400, 600), gfx::Rect(0, 0, 400, 560));
1485   gfx::Rect secondary_display_area(400, 100, 400, 500);
1486   mock_display_settings_provider()->SetSecondaryDisplay(
1487       secondary_display_area, secondary_display_area);
1488 
1489   // Create a docked panel.
1490   gfx::Size panel_size(100, 100);
1491   Panel* panel = CreateDockedPanel("1", gfx::Rect(gfx::Point(), panel_size));
1492   EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type());
1493 
1494   // Drag the panel to the secondary display horizontally.
1495   // Expected that the panel should become detached.
1496   gfx::Point drag_to_location(secondary_display_area.x() + 100,
1497                               panel->GetBounds().y());
1498   DragPanelToMouseLocation(panel, drag_to_location);
1499   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
1500   gfx::Rect expected_bounds(drag_to_location, panel_size);
1501   EXPECT_EQ(expected_bounds, panel->GetBounds());
1502 
1503   PanelManager::GetInstance()->CloseAll();
1504 }
1505 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,DragDetachedPanelToSecondaryDisplay)1506 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,
1507                        DragDetachedPanelToSecondaryDisplay) {
1508   // Setup 2 displays with secondary display at the bottom of primary display.
1509   mock_display_settings_provider()->SetPrimaryDisplay(
1510       gfx::Rect(0, 0, 800, 300), gfx::Rect(0, 0, 800, 260));
1511   gfx::Rect secondary_display_area(100, 300, 700, 250);
1512   mock_display_settings_provider()->SetSecondaryDisplay(
1513       secondary_display_area, secondary_display_area);
1514 
1515   // Create a detached panel on the primary display.
1516   gfx::Rect initial_panel_bounds(300, 50, 100, 100);
1517   Panel* panel = CreateDetachedPanel("1", initial_panel_bounds);
1518   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
1519   EXPECT_EQ(initial_panel_bounds, panel->GetBounds());
1520 
1521   // Drag down the panel to the secondary display vertically.
1522   // Expected that the panel should remain detached.
1523   gfx::Point drag_to_location(initial_panel_bounds.x(),
1524                               secondary_display_area.y() + 100);
1525   DragPanelToMouseLocation(panel, drag_to_location);
1526   EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
1527   gfx::Rect expected_bounds(drag_to_location, initial_panel_bounds.size());
1528   EXPECT_EQ(expected_bounds, panel->GetBounds());
1529 
1530   PanelManager::GetInstance()->CloseAll();
1531 }
1532 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,GroupPanelAndPanelFromBottom)1533 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupPanelAndPanelFromBottom) {
1534   PanelManager* panel_manager = PanelManager::GetInstance();
1535   DetachedPanelCollection* detached_collection =
1536       panel_manager->detached_collection();
1537 
1538   // Create two detached panels.
1539   Panel* panel1 = CreateDetachedPanel("1", gfx::Rect(300, 200, 200, 100));
1540   Panel* panel2 = CreateDetachedPanel("2", gfx::Rect(100, 100, 150, 150));
1541   ASSERT_EQ(2, detached_collection->num_panels());
1542   ASSERT_EQ(0, panel_manager->num_stacks());
1543   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
1544   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
1545 
1546   gfx::Rect panel1_old_bounds = panel1->GetBounds();
1547   gfx::Rect panel2_old_bounds = panel2->GetBounds();
1548 
1549   // Press on title-bar of P2.
1550   scoped_ptr<NativePanelTesting> panel2_testing(
1551       CreateNativePanelTesting(panel2));
1552   gfx::Point mouse_location(panel2->GetBounds().origin());
1553   gfx::Point original_mouse_location = mouse_location;
1554   panel2_testing->PressLeftMouseButtonTitlebar(mouse_location);
1555 
1556   // Drag P2 close to the bottom of P1 to trigger the stacking. Expect:
1557   // 1) P1 and P2 form a stack.
1558   // 2) P2 jumps vertcially to align to the bottom edge of P1.
1559   // 3) P2 moves horizontally by the dragging delta.
1560   // 4) The width of P2 remains unchanged.
1561   gfx::Vector2d drag_delta_to_stack =
1562       GetDragDeltaToStackToBottom(panel2, panel1);
1563   mouse_location = mouse_location + drag_delta_to_stack;
1564   panel2_testing->DragTitlebar(mouse_location);
1565   ASSERT_EQ(0, detached_collection->num_panels());
1566   ASSERT_EQ(1, panel_manager->num_stacks());
1567   EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type());
1568   EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type());
1569   EXPECT_EQ(panel1_old_bounds, panel1->GetBounds());
1570   gfx::Rect panel2_new_bounds(panel2_old_bounds.x() + drag_delta_to_stack.x(),
1571                               panel1_old_bounds.bottom(),
1572                               panel2_old_bounds.width(),
1573                               panel2_old_bounds.height());
1574   EXPECT_EQ(panel2_new_bounds, panel2->GetBounds());
1575 
1576   // Drag P2 somewhat away from the bottom of P1 to trigger the unstacking.
1577   // Expect P1 and P2 become detached.
1578   gfx::Vector2d drag_delta_to_unstack =
1579       GetDragDeltaToUnstackFromBottom(panel2, panel1);
1580   mouse_location = mouse_location + drag_delta_to_unstack;
1581   panel2_testing->DragTitlebar(mouse_location);
1582   ASSERT_EQ(2, detached_collection->num_panels());
1583   ASSERT_EQ(0, panel_manager->num_stacks());
1584   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
1585   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
1586   EXPECT_EQ(panel1_old_bounds, panel1->GetBounds());
1587   panel2_new_bounds.set_origin(panel2_old_bounds.origin());
1588   panel2_new_bounds.Offset(mouse_location - original_mouse_location);
1589   EXPECT_EQ(panel2_new_bounds, panel2->GetBounds());
1590 
1591   // Drag P2 close to the bottom of P1 to trigger the stacking again. Expect:
1592   // 1) P1 and P2 form a stack.
1593   // 2) P2 jumps vertcially to align to the bottom edge of P1.
1594   // 3) P2 moves horizontally by the dragging delta.
1595   // 4) The width of P2 remains unchanged.
1596   drag_delta_to_stack = GetDragDeltaToStackToBottom(panel2, panel1);
1597   mouse_location = mouse_location + drag_delta_to_stack;
1598   panel2_testing->DragTitlebar(mouse_location);
1599   ASSERT_EQ(0, detached_collection->num_panels());
1600   ASSERT_EQ(1, panel_manager->num_stacks());
1601   EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type());
1602   EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type());
1603   EXPECT_EQ(panel1_old_bounds, panel1->GetBounds());
1604   panel2_new_bounds.set_x(panel2_new_bounds.x() + drag_delta_to_stack.x());
1605   panel2_new_bounds.set_y(panel1_old_bounds.bottom());
1606   EXPECT_EQ(panel2_new_bounds, panel2->GetBounds());
1607 
1608   // Move the mouse a little bit. Expect P2 only moves horizontally. P2 should
1609   // not move vertically since its top edge already glues to the bottom edge
1610   // of P1.
1611   gfx::Vector2d small_delta(1, -1);
1612   mouse_location = mouse_location + small_delta;
1613   panel2_testing->DragTitlebar(mouse_location);
1614   ASSERT_EQ(0, detached_collection->num_panels());
1615   ASSERT_EQ(1, panel_manager->num_stacks());
1616   EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type());
1617   EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type());
1618   EXPECT_EQ(panel1_old_bounds, panel1->GetBounds());
1619   panel2_new_bounds.set_x(panel2_new_bounds.x() + small_delta.x());
1620   EXPECT_EQ(panel2_new_bounds, panel2->GetBounds());
1621 
1622   // Finish the drag. Expect:
1623   // 1) P1 and P2 remain stacked.
1624   // 2) P2 moves horizontally to align with P1.
1625   // 3) The width of P2 is adjusted to be same as the one of P1.
1626   panel2_testing->FinishDragTitlebar();
1627   WaitForBoundsAnimationFinished(panel2);
1628   ASSERT_EQ(0, detached_collection->num_panels());
1629   ASSERT_EQ(1, panel_manager->num_stacks());
1630   EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type());
1631   EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type());
1632   EXPECT_EQ(panel1_old_bounds, panel1->GetBounds());
1633   panel2_new_bounds.set_x(panel1_old_bounds.x());
1634   panel2_new_bounds.set_width(panel1_old_bounds.width());
1635   EXPECT_EQ(panel2_new_bounds, panel2->GetBounds());
1636 
1637   panel_manager->CloseAll();
1638 }
1639 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,GroupPanelAndPanelFromTop)1640 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupPanelAndPanelFromTop) {
1641   PanelManager* panel_manager = PanelManager::GetInstance();
1642   DetachedPanelCollection* detached_collection =
1643       panel_manager->detached_collection();
1644 
1645   // Create two detached panels.
1646   Panel* panel1 = CreateDetachedPanel("1", gfx::Rect(300, 300, 200, 100));
1647   Panel* panel2 = CreateDetachedPanel("2", gfx::Rect(100, 200, 150, 150));
1648   ASSERT_EQ(2, detached_collection->num_panels());
1649   ASSERT_EQ(0, panel_manager->num_stacks());
1650   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
1651   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
1652 
1653   gfx::Rect panel1_old_bounds = panel1->GetBounds();
1654   gfx::Rect panel2_old_bounds = panel2->GetBounds();
1655 
1656   // Press on title-bar of P2.
1657   scoped_ptr<NativePanelTesting> panel2_testing(
1658       CreateNativePanelTesting(panel2));
1659   gfx::Point mouse_location(panel2->GetBounds().origin());
1660   gfx::Point original_mouse_location = mouse_location;
1661   panel2_testing->PressLeftMouseButtonTitlebar(mouse_location);
1662 
1663   // Drag P2 close to the top of P1 to trigger the stacking. Expect:
1664   // 1) P2 and P1 form a stack.
1665   // 2) P2 jumps vertcially to align to the top edge of P1.
1666   // 3) P2 moves horizontally by the dragging delta.
1667   // 4) The width of both P1 and P2 remains unchanged.
1668   gfx::Vector2d drag_delta_to_stack = GetDragDeltaToStackToTop(panel2, panel1);
1669   mouse_location = mouse_location + drag_delta_to_stack;
1670   panel2_testing->DragTitlebar(mouse_location);
1671   ASSERT_EQ(0, detached_collection->num_panels());
1672   ASSERT_EQ(1, panel_manager->num_stacks());
1673   EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type());
1674   EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type());
1675   EXPECT_EQ(panel1_old_bounds, panel1->GetBounds());
1676   gfx::Rect panel2_new_bounds(
1677       panel2_old_bounds.x() + drag_delta_to_stack.x(),
1678       panel1_old_bounds.y() - panel2_old_bounds.height(),
1679       panel2_old_bounds.width(),
1680       panel2_old_bounds.height());
1681   EXPECT_EQ(panel2_new_bounds, panel2->GetBounds());
1682 
1683   // Drag P2 somewhat away from the top of P1 to trigger the unstacking.
1684   // Expect P1 and P2 become detached.
1685   gfx::Vector2d drag_delta_to_unstack =
1686       GetDragDeltaToUnstackFromTop(panel2, panel1);
1687   mouse_location = mouse_location + drag_delta_to_unstack;
1688   panel2_testing->DragTitlebar(mouse_location);
1689   ASSERT_EQ(2, detached_collection->num_panels());
1690   ASSERT_EQ(0, panel_manager->num_stacks());
1691   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
1692   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
1693   EXPECT_EQ(panel1_old_bounds, panel1->GetBounds());
1694   panel2_new_bounds.set_origin(panel2_old_bounds.origin());
1695   panel2_new_bounds.Offset(mouse_location - original_mouse_location);
1696   EXPECT_EQ(panel2_new_bounds, panel2->GetBounds());
1697 
1698   // Drag P2 close to the top of P1 to trigger the stacking again. Expect:
1699   // 1) P2 and P1 form a stack.
1700   // 2) P2 jumps vertcially to align to the top edge of P1.
1701   // 3) P2 moves horizontally by the dragging delta.
1702   // 4) The width of both P1 and P2 remains unchanged.
1703   drag_delta_to_stack = GetDragDeltaToStackToTop(panel2, panel1);
1704   mouse_location = mouse_location + drag_delta_to_stack;
1705   panel2_testing->DragTitlebar(mouse_location);
1706   ASSERT_EQ(0, detached_collection->num_panels());
1707   ASSERT_EQ(1, panel_manager->num_stacks());
1708   EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type());
1709   EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type());
1710   EXPECT_EQ(panel1_old_bounds, panel1->GetBounds());
1711   panel2_new_bounds.set_x(panel2_new_bounds.x() + drag_delta_to_stack.x());
1712   panel2_new_bounds.set_y(panel1_old_bounds.y() - panel2_old_bounds.height());
1713   EXPECT_EQ(panel2_new_bounds, panel2->GetBounds());
1714 
1715   // Move the mouse a little bit. Expect only P2 moves horizontally. P2 should
1716   // not move vertically because its bottom edge already glues to the top edge
1717   // of P1.
1718   gfx::Vector2d small_delta(1, -1);
1719   mouse_location = mouse_location + small_delta;
1720   panel2_testing->DragTitlebar(mouse_location);
1721   ASSERT_EQ(0, detached_collection->num_panels());
1722   ASSERT_EQ(1, panel_manager->num_stacks());
1723   EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type());
1724   EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type());
1725   EXPECT_EQ(panel1_old_bounds, panel1->GetBounds());
1726   panel2_new_bounds.set_x(panel2_new_bounds.x() + small_delta.x());
1727   EXPECT_EQ(panel2_new_bounds, panel2->GetBounds());
1728 
1729   // Finish the drag. Expect:
1730   // 1) P2 and P1 remain stacked.
1731   // 2) P2 moves horizontally to align with P1.
1732   // 3) The width of P1 is adjusted to be same as the one of P2.
1733   panel2_testing->FinishDragTitlebar();
1734   WaitForBoundsAnimationFinished(panel1);
1735   ASSERT_EQ(0, detached_collection->num_panels());
1736   ASSERT_EQ(1, panel_manager->num_stacks());
1737   EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type());
1738   EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type());
1739   gfx::Rect panel1_new_bounds = panel1_old_bounds;
1740   panel1_new_bounds.set_width(panel2_new_bounds.width());
1741   EXPECT_EQ(panel1_new_bounds, panel1->GetBounds());
1742   panel2_new_bounds.set_x(panel1_new_bounds.x());
1743   EXPECT_EQ(panel2_new_bounds, panel2->GetBounds());
1744 
1745   panel_manager->CloseAll();
1746 }
1747 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,GroupAndCancel)1748 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupAndCancel) {
1749   PanelManager* panel_manager = PanelManager::GetInstance();
1750   DetachedPanelCollection* detached_collection =
1751       panel_manager->detached_collection();
1752 
1753   // Create two detached panels.
1754   Panel* panel1 = CreateDetachedPanel("1", gfx::Rect(300, 200, 200, 100));
1755   Panel* panel2 = CreateDetachedPanel("2", gfx::Rect(100, 100, 150, 150));
1756   ASSERT_EQ(2, detached_collection->num_panels());
1757   ASSERT_EQ(0, panel_manager->num_stacks());
1758   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
1759   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
1760 
1761   gfx::Rect panel1_old_bounds = panel1->GetBounds();
1762   gfx::Rect panel2_old_bounds = panel2->GetBounds();
1763 
1764   // Press on title-bar.
1765   scoped_ptr<NativePanelTesting> panel2_testing(
1766       CreateNativePanelTesting(panel2));
1767   gfx::Point mouse_location(panel2->GetBounds().origin());
1768   gfx::Point original_mouse_location = mouse_location;
1769   panel2_testing->PressLeftMouseButtonTitlebar(mouse_location);
1770 
1771   // Drag P2 close to the bottom of P1 to trigger the stacking.
1772   // Expect that P2 stacks to P1 and P2's width remains unchanged.
1773   gfx::Vector2d drag_delta_to_stack =
1774       GetDragDeltaToStackToBottom(panel2, panel1);
1775   mouse_location = mouse_location + drag_delta_to_stack;
1776   panel2_testing->DragTitlebar(mouse_location);
1777   ASSERT_EQ(0, detached_collection->num_panels());
1778   ASSERT_EQ(1, panel_manager->num_stacks());
1779   EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type());
1780   EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type());
1781   EXPECT_EQ(panel1_old_bounds, panel1->GetBounds());
1782   gfx::Rect panel2_new_bounds(panel1_old_bounds.x(),
1783                               panel1_old_bounds.bottom(),
1784                               panel2_old_bounds.width(),
1785                               panel2_old_bounds.height());
1786   EXPECT_EQ(panel2_new_bounds, panel2->GetBounds());
1787 
1788   // Cancel the drag.
1789   // Expect that the P1 and P2 become detached.
1790   panel2_testing->CancelDragTitlebar();
1791   ASSERT_EQ(2, detached_collection->num_panels());
1792   ASSERT_EQ(0, panel_manager->num_stacks());
1793   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
1794   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
1795   EXPECT_EQ(panel1_old_bounds, panel1->GetBounds());
1796   EXPECT_EQ(panel2_old_bounds, panel2->GetBounds());
1797 
1798   panel_manager->CloseAll();
1799 }
1800 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,GroupPanelAndStackFromBottom)1801 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupPanelAndStackFromBottom) {
1802   PanelManager* panel_manager = PanelManager::GetInstance();
1803   DetachedPanelCollection* detached_collection =
1804       panel_manager->detached_collection();
1805 
1806   // Create 2 stacked panels.
1807   StackedPanelCollection* stack = panel_manager->CreateStack();
1808   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 100, 200, 150);
1809   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
1810   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
1811   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
1812   ASSERT_EQ(0, detached_collection->num_panels());
1813   ASSERT_EQ(1, panel_manager->num_stacks());
1814   ASSERT_EQ(2, stack->num_panels());
1815   EXPECT_EQ(stack, panel1->collection());
1816   EXPECT_EQ(stack, panel2->collection());
1817 
1818   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
1819   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
1820   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
1821       panel2_initial_bounds, panel1_expected_bounds);
1822   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
1823 
1824   // Create 1 detached panel.
1825   gfx::Rect panel3_initial_bounds = gfx::Rect(300, 200, 100, 100);
1826   Panel* panel3 = CreateDetachedPanel("3", panel3_initial_bounds);
1827   ASSERT_EQ(1, detached_collection->num_panels());
1828   gfx::Rect panel3_expected_bounds(panel3_initial_bounds);
1829   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
1830 
1831   // Drag P3 close to the bottom edge of P1 that is not the bottom panel.
1832   // Expect no stacking.
1833   gfx::Vector2d drag_delta_to_stack =
1834       GetDragDeltaToStackToBottom(panel3, panel1);
1835   DragPanelByDelta(panel3, drag_delta_to_stack);
1836   ASSERT_EQ(1, detached_collection->num_panels());
1837   ASSERT_EQ(2, stack->num_panels());
1838   ASSERT_EQ(1, panel_manager->num_stacks());
1839 
1840   // Drag P3 close to the bottom edge of P2 that is the bottom panel.
1841   // Expect that P3 becomes the bottom panel of the stack.
1842   drag_delta_to_stack = GetDragDeltaToStackToBottom(panel3, panel2);
1843   DragPanelByDelta(panel3, drag_delta_to_stack);
1844   WaitForBoundsAnimationFinished(panel3);
1845   ASSERT_EQ(0, detached_collection->num_panels());
1846   ASSERT_EQ(3, stack->num_panels());
1847   ASSERT_EQ(1, panel_manager->num_stacks());
1848   EXPECT_EQ(stack, panel1->collection());
1849   EXPECT_EQ(stack, panel2->collection());
1850   EXPECT_EQ(stack, panel3->collection());
1851   EXPECT_EQ(panel3, stack->bottom_panel());
1852 
1853   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
1854   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
1855   panel3_expected_bounds = GetStackedAtBottomPanelBounds(
1856       panel3_initial_bounds, panel2_expected_bounds);
1857   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
1858 
1859   panel_manager->CloseAll();
1860 }
1861 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,GroupPanelAndStackFromTop)1862 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupPanelAndStackFromTop) {
1863   PanelManager* panel_manager = PanelManager::GetInstance();
1864   DetachedPanelCollection* detached_collection =
1865       panel_manager->detached_collection();
1866 
1867   // Create 2 stacked panels.
1868   StackedPanelCollection* stack = panel_manager->CreateStack();
1869   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 300, 200, 150);
1870   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
1871   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
1872   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
1873   ASSERT_EQ(0, detached_collection->num_panels());
1874   ASSERT_EQ(1, panel_manager->num_stacks());
1875   ASSERT_EQ(2, stack->num_panels());
1876   EXPECT_EQ(stack, panel1->collection());
1877   EXPECT_EQ(stack, panel2->collection());
1878 
1879   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
1880   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
1881   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
1882       panel2_initial_bounds, panel1_expected_bounds);
1883   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
1884 
1885   // Create 1 detached panel.
1886   gfx::Rect panel3_initial_bounds = gfx::Rect(300, 200, 100, 100);
1887   Panel* panel3 = CreateDetachedPanel("3", panel3_initial_bounds);
1888   ASSERT_EQ(1, detached_collection->num_panels());
1889   gfx::Rect panel3_expected_bounds(panel3_initial_bounds);
1890   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
1891 
1892   // Drag P3 close to the top edge of P2 that is not the top panel.
1893   // Expect no stacking.
1894   gfx::Vector2d drag_delta_to_stack = GetDragDeltaToStackToTop(panel3, panel2);
1895   DragPanelByDelta(panel3, drag_delta_to_stack);
1896   ASSERT_EQ(1, detached_collection->num_panels());
1897   ASSERT_EQ(2, stack->num_panels());
1898   ASSERT_EQ(1, panel_manager->num_stacks());
1899 
1900   // Drag P3 close to the top edge of P1 that is the top panel.
1901   // Expect that P3 becomes the top panel of the stack.
1902   drag_delta_to_stack = GetDragDeltaToStackToTop(panel3, panel1);
1903   DragPanelByDelta(panel3, drag_delta_to_stack);
1904   WaitForBoundsAnimationFinished(panel1);
1905   WaitForBoundsAnimationFinished(panel2);
1906   ASSERT_EQ(0, detached_collection->num_panels());
1907   ASSERT_EQ(3, stack->num_panels());
1908   ASSERT_EQ(1, panel_manager->num_stacks());
1909   EXPECT_EQ(stack, panel1->collection());
1910   EXPECT_EQ(stack, panel2->collection());
1911   EXPECT_EQ(stack, panel3->collection());
1912   EXPECT_EQ(panel3, stack->top_panel());
1913 
1914   panel3_expected_bounds = GetStackedAtTopPanelBounds(
1915       panel3_initial_bounds, panel1_expected_bounds);
1916   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
1917   panel1_expected_bounds.set_width(panel3_expected_bounds.width());
1918   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
1919   panel2_expected_bounds.set_width(panel3_expected_bounds.width());
1920   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
1921 
1922   panel_manager->CloseAll();
1923 }
1924 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,GroupStackAndPanelFromBottom)1925 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupStackAndPanelFromBottom) {
1926   PanelManager* panel_manager = PanelManager::GetInstance();
1927   DetachedPanelCollection* detached_collection =
1928       panel_manager->detached_collection();
1929 
1930   // Create 2 stacked panels.
1931   StackedPanelCollection* stack = panel_manager->CreateStack();
1932   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 100, 200, 150);
1933   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
1934   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
1935   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
1936   ASSERT_EQ(0, detached_collection->num_panels());
1937   ASSERT_EQ(1, panel_manager->num_stacks());
1938   ASSERT_EQ(2, stack->num_panels());
1939   EXPECT_EQ(stack, panel1->stack());
1940   EXPECT_EQ(stack, panel2->stack());
1941 
1942   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
1943   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
1944   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
1945       panel2_initial_bounds, panel1_expected_bounds);
1946   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
1947 
1948   // Create 1 detached panel.
1949   gfx::Rect panel3_initial_bounds = gfx::Rect(300, 200, 100, 100);
1950   Panel* panel3 = CreateDetachedPanel("3", panel3_initial_bounds);
1951   ASSERT_EQ(1, detached_collection->num_panels());
1952   gfx::Rect panel3_expected_bounds(panel3_initial_bounds);
1953   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
1954 
1955   // Drag P1 (together with P2) to stack to the bottom of P3.
1956   // Expect that P1 and P2 append to the bottom of P3 and all 3 panels are in
1957   // one stack.
1958   gfx::Vector2d drag_delta_to_stack =
1959       GetDragDeltaToStackToBottom(panel1, panel3);
1960   DragPanelByDelta(panel1, drag_delta_to_stack);
1961   WaitForBoundsAnimationFinished(panel1);
1962   WaitForBoundsAnimationFinished(panel2);
1963   ASSERT_EQ(0, detached_collection->num_panels());
1964   ASSERT_EQ(1, panel_manager->num_stacks());
1965   StackedPanelCollection* final_stack = panel_manager->stacks().front();
1966   ASSERT_EQ(3, final_stack->num_panels());
1967   EXPECT_EQ(final_stack, panel1->stack());
1968   EXPECT_EQ(final_stack, panel2->stack());
1969   EXPECT_EQ(final_stack, panel3->stack());
1970 
1971   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
1972   panel1_expected_bounds = GetStackedAtBottomPanelBounds(
1973       panel1_initial_bounds, panel3_expected_bounds);
1974   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
1975   panel2_expected_bounds = GetStackedAtBottomPanelBounds(
1976       panel2_initial_bounds, panel1_expected_bounds);
1977   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
1978 
1979   panel_manager->CloseAll();
1980 }
1981 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,GroupStackAndPanelFromTop)1982 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupStackAndPanelFromTop) {
1983   PanelManager* panel_manager = PanelManager::GetInstance();
1984   DetachedPanelCollection* detached_collection =
1985       panel_manager->detached_collection();
1986 
1987   // Create 2 stacked panels.
1988   StackedPanelCollection* stack = panel_manager->CreateStack();
1989   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 100, 200, 150);
1990   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
1991   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
1992   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
1993   ASSERT_EQ(0, detached_collection->num_panels());
1994   ASSERT_EQ(1, panel_manager->num_stacks());
1995   ASSERT_EQ(2, stack->num_panels());
1996   EXPECT_EQ(stack, panel1->stack());
1997   EXPECT_EQ(stack, panel2->stack());
1998 
1999   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
2000   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2001   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
2002       panel2_initial_bounds, panel1_expected_bounds);
2003   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2004 
2005   // Create 1 detached panel.
2006   gfx::Rect panel3_initial_bounds = gfx::Rect(300, 450, 100, 100);
2007   Panel* panel3 = CreateDetachedPanel("3", panel3_initial_bounds);
2008   ASSERT_EQ(1, detached_collection->num_panels());
2009   gfx::Rect panel3_expected_bounds(panel3_initial_bounds);
2010   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
2011 
2012   // Drag P1 (together with P2) to stack to the top of P3.
2013   // Expect that P1 and P2 add to the top of P3 and all 3 panels are in
2014   // one stack. P1 and P2 should align to top of P3 while P3 should update its
2015   // width to be same as the width of P1 and P2.
2016   gfx::Vector2d drag_delta_to_stack = GetDragDeltaToStackToTop(panel1, panel3);
2017   DragPanelByDelta(panel1, drag_delta_to_stack);
2018   WaitForBoundsAnimationFinished(panel3);
2019   ASSERT_EQ(0, detached_collection->num_panels());
2020   ASSERT_EQ(1, panel_manager->num_stacks());
2021   StackedPanelCollection* final_stack = panel_manager->stacks().front();
2022   ASSERT_EQ(3, final_stack->num_panels());
2023   EXPECT_EQ(final_stack, panel1->stack());
2024   EXPECT_EQ(final_stack, panel2->stack());
2025   EXPECT_EQ(final_stack, panel3->stack());
2026 
2027   panel3_expected_bounds.set_width(panel1_expected_bounds.width());
2028   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
2029   panel2_expected_bounds = GetStackedAtTopPanelBounds(
2030       panel2_expected_bounds, panel3_expected_bounds);
2031   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2032   panel1_expected_bounds = GetStackedAtTopPanelBounds(
2033       panel1_expected_bounds, panel2_expected_bounds);
2034   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2035 
2036   panel_manager->CloseAll();
2037 }
2038 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,GroupStackAndStackFromBottom)2039 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupStackAndStackFromBottom) {
2040   PanelManager* panel_manager = PanelManager::GetInstance();
2041   DetachedPanelCollection* detached_collection =
2042       panel_manager->detached_collection();
2043 
2044   // Create 2 stacked panels.
2045   StackedPanelCollection* stack1 = panel_manager->CreateStack();
2046   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 50, 200, 150);
2047   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack1);
2048   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
2049   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack1);
2050   ASSERT_EQ(0, detached_collection->num_panels());
2051   ASSERT_EQ(1, panel_manager->num_stacks());
2052   ASSERT_EQ(2, stack1->num_panels());
2053   EXPECT_EQ(stack1, panel1->stack());
2054   EXPECT_EQ(stack1, panel2->stack());
2055 
2056   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
2057   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2058   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
2059       panel2_initial_bounds, panel1_expected_bounds);
2060   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2061 
2062   // Create 2 more stacked panels in another stack.
2063   StackedPanelCollection* stack2 = panel_manager->CreateStack();
2064   gfx::Rect panel3_initial_bounds = gfx::Rect(300, 100, 220, 120);
2065   Panel* panel3 = CreateStackedPanel("3", panel3_initial_bounds, stack2);
2066   gfx::Rect panel4_initial_bounds = gfx::Rect(0, 0, 180, 140);
2067   Panel* panel4 = CreateStackedPanel("4", panel4_initial_bounds, stack2);
2068   ASSERT_EQ(0, detached_collection->num_panels());
2069   ASSERT_EQ(2, panel_manager->num_stacks());
2070   ASSERT_EQ(2, stack2->num_panels());
2071   EXPECT_EQ(stack2, panel3->stack());
2072   EXPECT_EQ(stack2, panel4->stack());
2073 
2074   gfx::Rect panel3_expected_bounds(panel3_initial_bounds);
2075   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
2076   gfx::Rect panel4_expected_bounds = GetStackedAtBottomPanelBounds(
2077       panel4_initial_bounds, panel3_expected_bounds);
2078   EXPECT_EQ(panel4_expected_bounds, panel4->GetBounds());
2079 
2080   // Drag P3 (together with P4) to stack to the bottom of the stack consisting
2081   // P1 and P2.
2082   // Expect that P3 and P4 append to the bottom of P2 and all 4 panels are in
2083   // one stack.
2084   gfx::Vector2d drag_delta_to_stack =
2085       GetDragDeltaToStackToBottom(panel3, panel2);
2086   DragPanelByDelta(panel3, drag_delta_to_stack);
2087   WaitForBoundsAnimationFinished(panel3);
2088   WaitForBoundsAnimationFinished(panel4);
2089   ASSERT_EQ(0, detached_collection->num_panels());
2090   ASSERT_EQ(1, panel_manager->num_stacks());
2091   StackedPanelCollection* final_stack = panel_manager->stacks().front();
2092   ASSERT_EQ(4, final_stack->num_panels());
2093   EXPECT_EQ(final_stack, panel1->stack());
2094   EXPECT_EQ(final_stack, panel2->stack());
2095   EXPECT_EQ(final_stack, panel3->stack());
2096   EXPECT_EQ(final_stack, panel4->stack());
2097 
2098   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2099   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2100   panel3_expected_bounds = GetStackedAtBottomPanelBounds(
2101       panel3_initial_bounds, panel2_expected_bounds);
2102   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
2103   panel4_expected_bounds = GetStackedAtBottomPanelBounds(
2104       panel4_initial_bounds, panel3_expected_bounds);
2105   EXPECT_EQ(panel4_expected_bounds, panel4->GetBounds());
2106 
2107   panel_manager->CloseAll();
2108 }
2109 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,GroupStackAndStackFromTop)2110 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupStackAndStackFromTop) {
2111   PanelManager* panel_manager = PanelManager::GetInstance();
2112   DetachedPanelCollection* detached_collection =
2113       panel_manager->detached_collection();
2114 
2115   // Create 2 stacked panels.
2116   StackedPanelCollection* stack1 = panel_manager->CreateStack();
2117   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 50, 200, 150);
2118   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack1);
2119   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
2120   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack1);
2121   ASSERT_EQ(0, detached_collection->num_panels());
2122   ASSERT_EQ(1, panel_manager->num_stacks());
2123   ASSERT_EQ(2, stack1->num_panels());
2124   EXPECT_EQ(stack1, panel1->stack());
2125   EXPECT_EQ(stack1, panel2->stack());
2126 
2127   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
2128   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2129   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
2130       panel2_initial_bounds, panel1_expected_bounds);
2131   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2132 
2133   // Create 2 more stacked panels in another stack.
2134   StackedPanelCollection* stack2 = panel_manager->CreateStack();
2135   gfx::Rect panel3_initial_bounds = gfx::Rect(300, 350, 220, 110);
2136   Panel* panel3 = CreateStackedPanel("3", panel3_initial_bounds, stack2);
2137   gfx::Rect panel4_initial_bounds = gfx::Rect(0, 0, 180, 100);
2138   Panel* panel4 = CreateStackedPanel("4", panel4_initial_bounds, stack2);
2139   ASSERT_EQ(0, detached_collection->num_panels());
2140   ASSERT_EQ(2, panel_manager->num_stacks());
2141   ASSERT_EQ(2, stack2->num_panels());
2142   EXPECT_EQ(stack2, panel3->stack());
2143   EXPECT_EQ(stack2, panel4->stack());
2144 
2145   gfx::Rect panel3_expected_bounds(panel3_initial_bounds);
2146   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
2147   gfx::Rect panel4_expected_bounds = GetStackedAtBottomPanelBounds(
2148       panel4_initial_bounds, panel3_expected_bounds);
2149   EXPECT_EQ(panel4_expected_bounds, panel4->GetBounds());
2150 
2151   // Drag P1 (together with P2) to stack to the top of the stack consisting
2152   // P3 and P4.
2153   // Expect that P1 and P2 add to the top of P3 and all 4 panels are in
2154   // one stack. P1 and P2 should align to top of P3 while P3 and P4 should
2155   // update their width to be same as the width of P1 and P2.
2156   gfx::Vector2d drag_delta_to_stack = GetDragDeltaToStackToTop(panel1, panel3);
2157   DragPanelByDelta(panel1, drag_delta_to_stack);
2158   WaitForBoundsAnimationFinished(panel3);
2159   WaitForBoundsAnimationFinished(panel4);
2160   ASSERT_EQ(0, detached_collection->num_panels());
2161   ASSERT_EQ(1, panel_manager->num_stacks());
2162   StackedPanelCollection* final_stack = panel_manager->stacks().front();
2163   ASSERT_EQ(4, final_stack->num_panels());
2164   EXPECT_EQ(final_stack, panel1->stack());
2165   EXPECT_EQ(final_stack, panel2->stack());
2166   EXPECT_EQ(final_stack, panel3->stack());
2167   EXPECT_EQ(final_stack, panel4->stack());
2168 
2169   panel4_expected_bounds.set_width(panel1_expected_bounds.width());
2170   EXPECT_EQ(panel4_expected_bounds, panel4->GetBounds());
2171   panel3_expected_bounds.set_width(panel1_expected_bounds.width());
2172   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
2173   panel2_expected_bounds = GetStackedAtTopPanelBounds(
2174       panel2_expected_bounds, panel3_expected_bounds);
2175   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2176   panel1_expected_bounds = GetStackedAtTopPanelBounds(
2177       panel1_expected_bounds, panel2_expected_bounds);
2178   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2179 
2180   panel_manager->CloseAll();
2181 }
2182 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,UngroupTwoPanelStack)2183 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, UngroupTwoPanelStack) {
2184   PanelManager* panel_manager = PanelManager::GetInstance();
2185   DetachedPanelCollection* detached_collection =
2186       panel_manager->detached_collection();
2187 
2188   // Create 2 stacked panels.
2189   StackedPanelCollection* stack = panel_manager->CreateStack();
2190   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 50, 200, 150);
2191   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
2192   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
2193   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
2194   ASSERT_EQ(0, detached_collection->num_panels());
2195   ASSERT_EQ(2, stack->num_panels());
2196   ASSERT_EQ(1, panel_manager->num_stacks());
2197   EXPECT_EQ(stack, panel1->stack());
2198   EXPECT_EQ(stack, panel2->stack());
2199 
2200   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
2201   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2202   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
2203       panel2_initial_bounds, panel1_expected_bounds);
2204   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2205   gfx::Rect panel2_old_bounds = panel2_expected_bounds;
2206 
2207   // Press on title-bar.
2208   scoped_ptr<NativePanelTesting> panel2_testing(
2209       CreateNativePanelTesting(panel2));
2210   gfx::Point mouse_location(panel2->GetBounds().origin());
2211   gfx::Point original_mouse_location = mouse_location;
2212   panel2_testing->PressLeftMouseButtonTitlebar(mouse_location);
2213 
2214   // Drag P2 away from the bottom of P1 to trigger the unstacking.
2215   // Expect that P1 and P2 get detached.
2216   gfx::Vector2d drag_delta_to_unstack =
2217       GetDragDeltaToUnstackFromBottom(panel2, panel1);
2218   mouse_location = mouse_location + drag_delta_to_unstack;
2219   panel2_testing->DragTitlebar(mouse_location);
2220   ASSERT_EQ(2, detached_collection->num_panels());
2221   ASSERT_TRUE(stack->num_panels() == 0);
2222   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
2223   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
2224   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2225   panel2_expected_bounds.Offset(drag_delta_to_unstack);
2226   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2227 
2228   // Drag P2 a bit closer to the bottom of P1 to trigger the stacking.
2229   // Expect P1 and P2 get stacked together.
2230   gfx::Vector2d drag_delta_to_stack =
2231       GetDragDeltaToStackToBottom(panel2, panel1);
2232   mouse_location = mouse_location + drag_delta_to_stack;
2233   panel2_testing->DragTitlebar(mouse_location);
2234   ASSERT_EQ(0, detached_collection->num_panels());
2235   // Note that the empty stack might still exist until the drag ends.
2236   ASSERT_GE(panel_manager->num_stacks(), 1);
2237   EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type());
2238   EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type());
2239   EXPECT_EQ(panel1->stack(), panel2->stack());
2240   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2241   panel2_expected_bounds = GetStackedAtBottomPanelBounds(
2242       panel2_initial_bounds, panel1_expected_bounds);
2243   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2244 
2245   // Drag P2 away from the bottom of P1 to trigger the unstacking again.
2246   // Expect that P1 and P2 get detached.
2247   drag_delta_to_unstack = GetDragDeltaToUnstackFromBottom(panel2, panel1);
2248   mouse_location = mouse_location + drag_delta_to_unstack;
2249   panel2_testing->DragTitlebar(mouse_location);
2250   ASSERT_EQ(2, detached_collection->num_panels());
2251   ASSERT_TRUE(stack->num_panels() == 0);
2252   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
2253   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
2254   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2255   panel2_expected_bounds = panel2_old_bounds;
2256   panel2_expected_bounds.Offset(mouse_location - original_mouse_location);
2257   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2258 
2259   // Finish the drag.
2260   // Expect that the P1 and P2 stay detached.
2261   panel2_testing->FinishDragTitlebar();
2262   ASSERT_EQ(2, detached_collection->num_panels());
2263   ASSERT_EQ(0, panel_manager->num_stacks());
2264   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
2265   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
2266   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2267   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2268 
2269   panel_manager->CloseAll();
2270 }
2271 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,UngroupAndCancel)2272 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, UngroupAndCancel) {
2273   PanelManager* panel_manager = PanelManager::GetInstance();
2274   DetachedPanelCollection* detached_collection =
2275       panel_manager->detached_collection();
2276 
2277   // Create 2 stacked panels.
2278   StackedPanelCollection* stack = panel_manager->CreateStack();
2279   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 50, 200, 150);
2280   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
2281   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
2282   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
2283   ASSERT_EQ(0, detached_collection->num_panels());
2284   ASSERT_EQ(2, stack->num_panels());
2285   ASSERT_EQ(1, panel_manager->num_stacks());
2286   EXPECT_EQ(stack, panel1->stack());
2287   EXPECT_EQ(stack, panel2->stack());
2288 
2289   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
2290   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2291   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
2292       panel2_initial_bounds, panel1_expected_bounds);
2293   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2294   gfx::Rect panel2_old_bounds = panel2->GetBounds();
2295 
2296   // Press on title-bar.
2297   scoped_ptr<NativePanelTesting> panel2_testing(
2298       CreateNativePanelTesting(panel2));
2299   gfx::Point mouse_location(panel2->GetBounds().origin());
2300   gfx::Point original_mouse_location = mouse_location;
2301   panel2_testing->PressLeftMouseButtonTitlebar(mouse_location);
2302 
2303   // Drag P2 away from the bottom of P1 to trigger the unstacking.
2304   // Expect that P1 and P2 get detached.
2305   gfx::Vector2d drag_delta_to_unstack =
2306       GetDragDeltaToUnstackFromBottom(panel2, panel1);
2307   mouse_location = mouse_location + drag_delta_to_unstack;
2308   panel2_testing->DragTitlebar(mouse_location);
2309   ASSERT_EQ(2, detached_collection->num_panels());
2310   ASSERT_TRUE(stack->num_panels() == 0);
2311   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
2312   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
2313   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2314   panel2_expected_bounds.Offset(drag_delta_to_unstack);
2315   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2316 
2317   // Cancel the drag.
2318   // Expect that the P1 and P2 put back to the same stack.
2319   panel2_testing->CancelDragTitlebar();
2320   WaitForBoundsAnimationFinished(panel2);
2321   ASSERT_EQ(0, detached_collection->num_panels());
2322   ASSERT_EQ(1, panel_manager->num_stacks());
2323   EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type());
2324   EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type());
2325   EXPECT_EQ(stack, panel1->stack());
2326   EXPECT_EQ(stack, panel2->stack());
2327   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2328   EXPECT_EQ(panel2_old_bounds, panel2->GetBounds());
2329 
2330   panel_manager->CloseAll();
2331 }
2332 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,UngroupBottomPanelInThreePanelStack)2333 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,
2334                        UngroupBottomPanelInThreePanelStack) {
2335   PanelManager* panel_manager = PanelManager::GetInstance();
2336   DetachedPanelCollection* detached_collection =
2337       panel_manager->detached_collection();
2338 
2339   // Create 3 stacked panels.
2340   StackedPanelCollection* stack = panel_manager->CreateStack();
2341   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 50, 200, 150);
2342   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
2343   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
2344   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
2345   gfx::Rect panel3_initial_bounds = gfx::Rect(0, 0, 120, 120);
2346   Panel* panel3 = CreateStackedPanel("3", panel3_initial_bounds, stack);
2347   ASSERT_EQ(0, detached_collection->num_panels());
2348   ASSERT_EQ(1, panel_manager->num_stacks());
2349   ASSERT_EQ(3, stack->num_panels());
2350   EXPECT_EQ(stack, panel1->stack());
2351   EXPECT_EQ(stack, panel2->stack());
2352   EXPECT_EQ(stack, panel3->stack());
2353 
2354   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
2355   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2356   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
2357       panel2_initial_bounds, panel1_expected_bounds);
2358   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2359   gfx::Rect panel3_expected_bounds = GetStackedAtBottomPanelBounds(
2360       panel3_initial_bounds, panel2_expected_bounds);
2361   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
2362 
2363   // Drag P3 away to unstack from P2 and P1.
2364   // Expect that P1 and P2 are still in the stack while P3 gets detached.
2365   gfx::Vector2d drag_delta_to_unstack =
2366       GetDragDeltaToUnstackFromBottom(panel3, panel2);
2367   DragPanelByDelta(panel3, drag_delta_to_unstack);
2368   ASSERT_EQ(1, detached_collection->num_panels());
2369   ASSERT_EQ(1, panel_manager->num_stacks());
2370   ASSERT_EQ(2, stack->num_panels());
2371   EXPECT_EQ(stack, panel1->stack());
2372   EXPECT_EQ(stack, panel2->stack());
2373   EXPECT_EQ(PanelCollection::DETACHED, panel3->collection()->type());
2374 
2375   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2376   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2377   panel3_expected_bounds.Offset(drag_delta_to_unstack);
2378   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
2379 
2380   panel_manager->CloseAll();
2381 }
2382 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,UngroupMiddlePanelInThreePanelStack)2383 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,
2384                        UngroupMiddlePanelInThreePanelStack) {
2385   PanelManager* panel_manager = PanelManager::GetInstance();
2386   DetachedPanelCollection* detached_collection =
2387       panel_manager->detached_collection();
2388 
2389   // Create 3 stacked panels.
2390   StackedPanelCollection* stack = panel_manager->CreateStack();
2391   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 50, 200, 150);
2392   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
2393   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
2394   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
2395   gfx::Rect panel3_initial_bounds = gfx::Rect(0, 0, 120, 120);
2396   Panel* panel3 = CreateStackedPanel("3", panel3_initial_bounds, stack);
2397   ASSERT_EQ(0, detached_collection->num_panels());
2398   ASSERT_EQ(1, panel_manager->num_stacks());
2399   ASSERT_EQ(3, stack->num_panels());
2400   EXPECT_EQ(stack, panel1->stack());
2401   EXPECT_EQ(stack, panel2->stack());
2402   EXPECT_EQ(stack, panel3->stack());
2403 
2404   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
2405   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2406   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
2407       panel2_initial_bounds, panel1_expected_bounds);
2408   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2409   gfx::Rect panel3_expected_bounds = GetStackedAtBottomPanelBounds(
2410       panel3_initial_bounds, panel2_expected_bounds);
2411   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
2412 
2413   // Drag P2 (together with P3) away to unstack from P1.
2414   // Expect that P2 and P3 are still in a stack while P1 gets detached.
2415   gfx::Vector2d drag_delta_to_unstack =
2416       GetDragDeltaToUnstackFromBottom(panel2, panel1);
2417   DragPanelByDelta(panel2, drag_delta_to_unstack);
2418   ASSERT_EQ(1, detached_collection->num_panels());
2419   ASSERT_EQ(1, panel_manager->num_stacks());
2420   StackedPanelCollection* final_stack = panel_manager->stacks().front();
2421   ASSERT_EQ(2, final_stack->num_panels());
2422   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
2423   EXPECT_EQ(final_stack, panel2->stack());
2424   EXPECT_EQ(final_stack, panel3->stack());
2425 
2426   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2427   panel2_expected_bounds.Offset(drag_delta_to_unstack);
2428   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2429   panel3_expected_bounds.Offset(drag_delta_to_unstack);
2430   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
2431 
2432   panel_manager->CloseAll();
2433 }
2434 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,UngroupThirdPanelInFourPanelStack)2435 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,
2436                        UngroupThirdPanelInFourPanelStack) {
2437   PanelManager* panel_manager = PanelManager::GetInstance();
2438   DetachedPanelCollection* detached_collection =
2439       panel_manager->detached_collection();
2440 
2441   // Create 4 stacked panels.
2442   StackedPanelCollection* stack = panel_manager->CreateStack();
2443   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 120, 200, 100);
2444   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
2445   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
2446   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
2447   gfx::Rect panel3_initial_bounds = gfx::Rect(0, 0, 120, 120);
2448   Panel* panel3 = CreateStackedPanel("3", panel3_initial_bounds, stack);
2449   gfx::Rect panel4_initial_bounds = gfx::Rect(0, 0, 120, 110);
2450   Panel* panel4 = CreateStackedPanel("4", panel4_initial_bounds, stack);
2451   ASSERT_EQ(0, detached_collection->num_panels());
2452   ASSERT_EQ(1, panel_manager->num_stacks());
2453   ASSERT_EQ(4, stack->num_panels());
2454   EXPECT_EQ(stack, panel1->stack());
2455   EXPECT_EQ(stack, panel2->stack());
2456   EXPECT_EQ(stack, panel3->stack());
2457   EXPECT_EQ(stack, panel4->stack());
2458 
2459   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
2460   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2461   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
2462       panel2_initial_bounds, panel1_expected_bounds);
2463   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2464   gfx::Rect panel3_expected_bounds = GetStackedAtBottomPanelBounds(
2465       panel3_initial_bounds, panel2_expected_bounds);
2466   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
2467   gfx::Rect panel4_expected_bounds = GetStackedAtBottomPanelBounds(
2468       panel4_initial_bounds, panel3_expected_bounds);
2469   EXPECT_EQ(panel4_expected_bounds, panel4->GetBounds());
2470 
2471   // Drag P3 (together with P4) away to unstack from P2.
2472   // Expect that P1 and P2 are in one stack while P3 and P4 are in different
2473   // stack.
2474   gfx::Vector2d drag_delta_to_unstack =
2475       GetDragDeltaToUnstackFromBottom(panel3, panel2);
2476   DragPanelByDelta(panel3, drag_delta_to_unstack);
2477   ASSERT_EQ(0, detached_collection->num_panels());
2478   ASSERT_EQ(2, panel_manager->num_stacks());
2479   StackedPanelCollection* final_stack1 = panel_manager->stacks().front();
2480   ASSERT_EQ(2, final_stack1->num_panels());
2481   StackedPanelCollection* final_stack2 = panel_manager->stacks().back();
2482   ASSERT_EQ(2, final_stack2->num_panels());
2483   EXPECT_EQ(panel1->stack(), panel2->stack());
2484   EXPECT_EQ(panel3->stack(), panel4->stack());
2485 
2486   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2487   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2488   panel3_expected_bounds.Offset(drag_delta_to_unstack);
2489   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
2490   panel4_expected_bounds.Offset(drag_delta_to_unstack);
2491   EXPECT_EQ(panel4_expected_bounds, panel4->GetBounds());
2492 
2493   panel_manager->CloseAll();
2494 }
2495 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,UngroupAndGroup)2496 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, UngroupAndGroup) {
2497   PanelManager* panel_manager = PanelManager::GetInstance();
2498   DetachedPanelCollection* detached_collection =
2499       panel_manager->detached_collection();
2500 
2501   // Create 2 stacked panels.
2502   StackedPanelCollection* stack = panel_manager->CreateStack();
2503   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 50, 200, 150);
2504   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
2505   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
2506   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
2507   ASSERT_EQ(0, detached_collection->num_panels());
2508   ASSERT_EQ(2, stack->num_panels());
2509   ASSERT_EQ(1, panel_manager->num_stacks());
2510   EXPECT_EQ(stack, panel1->stack());
2511   EXPECT_EQ(stack, panel2->stack());
2512 
2513   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
2514   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2515   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
2516       panel2_initial_bounds, panel1_expected_bounds);
2517   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2518 
2519   // Create 1 detached panel.
2520   gfx::Rect panel3_initial_bounds = gfx::Rect(300, 200, 100, 100);
2521   Panel* panel3 = CreateDetachedPanel("3", panel3_initial_bounds);
2522   ASSERT_EQ(1, detached_collection->num_panels());
2523   gfx::Rect panel3_expected_bounds(panel3_initial_bounds);
2524   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
2525 
2526   // Drag P2 to the bottom edge of P3 to trigger both unstacking and stacking.
2527   // Expect that P3 and P2 are stacked together while P1 gets detached.
2528   gfx::Vector2d drag_delta_to_unstack_and_stack =
2529       GetDragDeltaToStackToBottom(panel2, panel3);
2530   DragPanelByDelta(panel2, drag_delta_to_unstack_and_stack);
2531   WaitForBoundsAnimationFinished(panel2);
2532   ASSERT_EQ(1, detached_collection->num_panels());
2533   ASSERT_EQ(1, panel_manager->num_stacks());
2534   StackedPanelCollection* final_stack = panel_manager->stacks().front();
2535   ASSERT_EQ(2, final_stack->num_panels());
2536   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
2537   EXPECT_EQ(final_stack, panel2->stack());
2538   EXPECT_EQ(final_stack, panel3->stack());
2539 
2540   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2541   panel2_expected_bounds = GetStackedAtBottomPanelBounds(
2542       panel2_initial_bounds, panel3_expected_bounds);
2543   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2544   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
2545 
2546   panel_manager->CloseAll();
2547 }
2548 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,UngroupAndAttach)2549 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, UngroupAndAttach) {
2550   PanelManager* panel_manager = PanelManager::GetInstance();
2551   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
2552   DetachedPanelCollection* detached_collection =
2553       panel_manager->detached_collection();
2554 
2555   // Create 2 stacked panels.
2556   StackedPanelCollection* stack = panel_manager->CreateStack();
2557   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 50, 200, 150);
2558   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
2559   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
2560   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
2561   ASSERT_EQ(0, docked_collection->num_panels());
2562   ASSERT_EQ(0, detached_collection->num_panels());
2563   ASSERT_EQ(2, stack->num_panels());
2564   ASSERT_EQ(1, panel_manager->num_stacks());
2565   EXPECT_EQ(stack, panel1->stack());
2566   EXPECT_EQ(stack, panel2->stack());
2567 
2568   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
2569   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2570   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
2571       panel2_initial_bounds, panel1_expected_bounds);
2572   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2573 
2574   // Drag P2 close to the bottom of the work area to trigger both unstacking and
2575   // docking for P2.
2576   // Expect that P2 gets docked while P2 gets detached.
2577   gfx::Vector2d drag_delta_to_unstack_and_attach = GetDragDeltaToAttach(panel2);
2578   DragPanelByDelta(panel2, drag_delta_to_unstack_and_attach);
2579   WaitForBoundsAnimationFinished(panel2);
2580   ASSERT_EQ(1, docked_collection->num_panels());
2581   ASSERT_EQ(1, detached_collection->num_panels());
2582   ASSERT_EQ(0, panel_manager->num_stacks());
2583   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
2584   EXPECT_EQ(PanelCollection::DOCKED, panel2->collection()->type());
2585 
2586   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2587   panel2_expected_bounds.set_x(docked_collection->StartingRightPosition() -
2588       panel2_expected_bounds.width());
2589   panel2_expected_bounds.set_y(docked_collection->work_area().bottom() -
2590       panel2_expected_bounds.height());
2591   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2592 
2593   panel_manager->CloseAll();
2594 }
2595 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,SnapPanelToPanelLeft)2596 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, SnapPanelToPanelLeft) {
2597   PanelManager* panel_manager = PanelManager::GetInstance();
2598   DetachedPanelCollection* detached_collection =
2599       panel_manager->detached_collection();
2600 
2601   // Create 2 detached panels.
2602   gfx::Rect panel1_initial_bounds = gfx::Rect(300, 200, 300, 200);
2603   Panel* panel1 = CreateDetachedPanel("1", panel1_initial_bounds);
2604   gfx::Rect panel2_initial_bounds = gfx::Rect(100, 100, 100, 250);
2605   Panel* panel2 = CreateDetachedPanel("2", panel2_initial_bounds);
2606   ASSERT_EQ(2, detached_collection->num_panels());
2607 
2608   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
2609   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2610   gfx::Rect panel2_expected_bounds(panel2_initial_bounds);
2611   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2612 
2613   // Press on title-bar.
2614   scoped_ptr<NativePanelTesting> panel2_testing(
2615       CreateNativePanelTesting(panel2));
2616   gfx::Point mouse_location(panel2->GetBounds().origin());
2617   gfx::Point original_mouse_location = mouse_location;
2618   panel2_testing->PressLeftMouseButtonTitlebar(mouse_location);
2619 
2620   // Drag P2 close to the left of P1 to trigger the snapping.
2621   gfx::Vector2d drag_delta_to_snap = GetDragDeltaToSnapToLeft(panel2, panel1);
2622   mouse_location = mouse_location + drag_delta_to_snap;
2623   panel2_testing->DragTitlebar(mouse_location);
2624   ASSERT_EQ(2, detached_collection->num_panels());
2625   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2626   panel2_expected_bounds.Offset(drag_delta_to_snap);
2627   panel2_expected_bounds.set_x(
2628       panel1_expected_bounds.x() - panel2_expected_bounds.width());
2629   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2630 
2631   // Drag P2 a bit away from the left of P1 to trigger the unsnapping.
2632   gfx::Vector2d drag_delta_to_unsnap = GetDragDeltaToUnsnap(panel1);
2633   mouse_location = mouse_location + drag_delta_to_unsnap;
2634   panel2_testing->DragTitlebar(mouse_location);
2635   ASSERT_EQ(2, detached_collection->num_panels());
2636   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2637   panel2_expected_bounds = panel2_initial_bounds;
2638   panel2_expected_bounds.Offset(mouse_location - original_mouse_location);
2639   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2640 
2641   // Drag P2 close to the left of P1 to trigger the snapping again.
2642   drag_delta_to_snap = GetDragDeltaToSnapToLeft(panel2, panel1);
2643   mouse_location = mouse_location + drag_delta_to_snap;
2644   panel2_testing->DragTitlebar(mouse_location);
2645   ASSERT_EQ(2, detached_collection->num_panels());
2646   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2647   panel2_expected_bounds.Offset(drag_delta_to_snap);
2648   panel2_expected_bounds.set_x(
2649       panel1_expected_bounds.x() - panel2_expected_bounds.width());
2650   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2651 
2652   // Drag P2 vertically with a little bit of horizontal movement should still
2653   // keep the snapping.
2654   gfx::Vector2d drag_delta_almost_vertically(2, 20);
2655   mouse_location = mouse_location + drag_delta_almost_vertically;
2656   panel2_testing->DragTitlebar(mouse_location);
2657   ASSERT_EQ(2, detached_collection->num_panels());
2658   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2659   panel2_expected_bounds.set_y(
2660       panel2_expected_bounds.y() + drag_delta_almost_vertically.y());
2661   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2662 
2663   // Finish the drag.
2664   panel2_testing->FinishDragTitlebar();
2665   ASSERT_EQ(2, detached_collection->num_panels());
2666   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2667   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2668 
2669   panel_manager->CloseAll();
2670 }
2671 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,SnapPanelToPanelRight)2672 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, SnapPanelToPanelRight) {
2673   PanelManager* panel_manager = PanelManager::GetInstance();
2674   DetachedPanelCollection* detached_collection =
2675       panel_manager->detached_collection();
2676 
2677   // Create 2 detached panels.
2678   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 200, 100, 200);
2679   Panel* panel1 = CreateDetachedPanel("1", panel1_initial_bounds);
2680   gfx::Rect panel2_initial_bounds = gfx::Rect(300, 100, 200, 250);
2681   Panel* panel2 = CreateDetachedPanel("2", panel2_initial_bounds);
2682   ASSERT_EQ(2, detached_collection->num_panels());
2683 
2684   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
2685   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2686   gfx::Rect panel2_expected_bounds(panel2_initial_bounds);
2687   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2688 
2689   // Press on title-bar.
2690   scoped_ptr<NativePanelTesting> panel2_testing(
2691       CreateNativePanelTesting(panel2));
2692   gfx::Point mouse_location(panel2->GetBounds().origin());
2693   gfx::Point original_mouse_location = mouse_location;
2694   panel2_testing->PressLeftMouseButtonTitlebar(mouse_location);
2695 
2696   // Drag P1 close to the right of P2 to trigger the snapping.
2697   gfx::Vector2d drag_delta_to_snap = GetDragDeltaToSnapToRight(panel2, panel1);
2698   mouse_location = mouse_location + drag_delta_to_snap;
2699   panel2_testing->DragTitlebar(mouse_location);
2700   ASSERT_EQ(2, detached_collection->num_panels());
2701   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2702   panel2_expected_bounds.Offset(drag_delta_to_snap);
2703   panel2_expected_bounds.set_x(panel1_expected_bounds.right());
2704   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2705 
2706   // Drag P2 a bit away from the right of P1 to trigger the unsnapping.
2707   gfx::Vector2d drag_delta_to_unsnap = GetDragDeltaToUnsnap(panel1);
2708   mouse_location = mouse_location + drag_delta_to_unsnap;
2709   panel2_testing->DragTitlebar(mouse_location);
2710   ASSERT_EQ(2, detached_collection->num_panels());
2711   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2712   panel2_expected_bounds = panel2_initial_bounds;
2713   panel2_expected_bounds.Offset(mouse_location - original_mouse_location);
2714   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2715 
2716   // Drag P2 close to the right of P1 to trigger the snapping again.
2717   drag_delta_to_snap = GetDragDeltaToSnapToRight(panel2, panel1);
2718   mouse_location = mouse_location + drag_delta_to_snap;
2719   panel2_testing->DragTitlebar(mouse_location);
2720   ASSERT_EQ(2, detached_collection->num_panels());
2721   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2722   panel2_expected_bounds.Offset(drag_delta_to_snap);
2723   panel2_expected_bounds.set_x(panel1_expected_bounds.right());
2724   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2725 
2726   // Drag P2 vertically with a little bit of horizontal movement should still
2727   // keep the snapping.
2728   gfx::Vector2d drag_delta_almost_vertically(2, -20);
2729   mouse_location = mouse_location + drag_delta_almost_vertically;
2730   panel2_testing->DragTitlebar(mouse_location);
2731   ASSERT_EQ(2, detached_collection->num_panels());
2732   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2733   panel2_expected_bounds.set_y(
2734       panel2_expected_bounds.y() + drag_delta_almost_vertically.y());
2735   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2736 
2737   // Finish the drag.
2738   panel2_testing->FinishDragTitlebar();
2739   ASSERT_EQ(2, detached_collection->num_panels());
2740   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2741   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2742 
2743   panel_manager->CloseAll();
2744 }
2745 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,SnapAndCancel)2746 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, SnapAndCancel) {
2747   PanelManager* panel_manager = PanelManager::GetInstance();
2748   DetachedPanelCollection* detached_collection =
2749       panel_manager->detached_collection();
2750 
2751   // Create 2 detached panels.
2752   gfx::Rect panel1_initial_bounds = gfx::Rect(300, 200, 300, 200);
2753   Panel* panel1 = CreateDetachedPanel("1", panel1_initial_bounds);
2754   gfx::Rect panel2_initial_bounds = gfx::Rect(100, 100, 100, 250);
2755   Panel* panel2 = CreateDetachedPanel("2", panel2_initial_bounds);
2756   ASSERT_EQ(2, detached_collection->num_panels());
2757 
2758   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
2759   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2760   gfx::Rect panel2_expected_bounds(panel2_initial_bounds);
2761   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2762 
2763   // Press on title-bar.
2764   scoped_ptr<NativePanelTesting> panel2_testing(
2765       CreateNativePanelTesting(panel2));
2766   gfx::Point mouse_location(panel2->GetBounds().origin());
2767   gfx::Point original_mouse_location = mouse_location;
2768   panel2_testing->PressLeftMouseButtonTitlebar(mouse_location);
2769 
2770   // Drag P2 close to the left of P1 to trigger the snapping.
2771   gfx::Vector2d drag_delta_to_snap = GetDragDeltaToSnapToLeft(panel2, panel1);
2772   mouse_location = mouse_location + drag_delta_to_snap;
2773   panel2_testing->DragTitlebar(mouse_location);
2774   ASSERT_EQ(2, detached_collection->num_panels());
2775   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2776   panel2_expected_bounds.Offset(drag_delta_to_snap);
2777   panel2_expected_bounds.set_x(
2778       panel1_expected_bounds.x() - panel2_expected_bounds.width());
2779   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2780 
2781   // Cancel the drag.
2782   panel2_testing->CancelDragTitlebar();
2783   ASSERT_EQ(2, detached_collection->num_panels());
2784   EXPECT_EQ(panel1_initial_bounds, panel1->GetBounds());
2785   EXPECT_EQ(panel2_initial_bounds, panel2->GetBounds());
2786 
2787   panel_manager->CloseAll();
2788 }
2789 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,SnapPanelToStackLeft)2790 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, SnapPanelToStackLeft) {
2791   PanelManager* panel_manager = PanelManager::GetInstance();
2792   DetachedPanelCollection* detached_collection =
2793       panel_manager->detached_collection();
2794 
2795   // Create 2 stacked panels.
2796   StackedPanelCollection* stack = panel_manager->CreateStack();
2797   gfx::Rect panel1_initial_bounds = gfx::Rect(300, 100, 200, 150);
2798   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
2799   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
2800   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
2801   ASSERT_EQ(0, detached_collection->num_panels());
2802   ASSERT_EQ(1, panel_manager->num_stacks());
2803   ASSERT_EQ(2, stack->num_panels());
2804   EXPECT_EQ(stack, panel1->collection());
2805   EXPECT_EQ(stack, panel2->collection());
2806 
2807   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
2808   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2809   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
2810       panel2_initial_bounds, panel1_expected_bounds);
2811   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2812 
2813   // Create 1 detached panel.
2814   gfx::Rect panel3_initial_bounds = gfx::Rect(100, 200, 100, 100);
2815   Panel* panel3 = CreateDetachedPanel("3", panel3_initial_bounds);
2816   ASSERT_EQ(1, detached_collection->num_panels());
2817   EXPECT_EQ(PanelCollection::DETACHED, panel3->collection()->type());
2818   gfx::Rect panel3_expected_bounds(panel3_initial_bounds);
2819   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
2820 
2821   // Drag P3 close to the left of the stack of P1 and P2 to trigger the
2822   // snapping.
2823   gfx::Vector2d drag_delta_to_snap = GetDragDeltaToSnapToLeft(panel3, panel1);
2824   DragPanelByDelta(panel3, drag_delta_to_snap);
2825   ASSERT_EQ(1, detached_collection->num_panels());
2826   ASSERT_EQ(1, panel_manager->num_stacks());
2827   ASSERT_EQ(2, stack->num_panels());
2828   EXPECT_EQ(stack, panel1->collection());
2829   EXPECT_EQ(stack, panel2->collection());
2830   EXPECT_EQ(PanelCollection::DETACHED, panel3->collection()->type());
2831   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2832   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2833   panel3_expected_bounds.Offset(drag_delta_to_snap);
2834   panel3_expected_bounds.set_x(
2835       panel1_expected_bounds.x() - panel3_expected_bounds.width());
2836   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
2837 
2838   panel_manager->CloseAll();
2839 }
2840 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,SnapPanelToStackRight)2841 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, SnapPanelToStackRight) {
2842   PanelManager* panel_manager = PanelManager::GetInstance();
2843   DetachedPanelCollection* detached_collection =
2844       panel_manager->detached_collection();
2845 
2846   // Create 2 stacked panels.
2847   StackedPanelCollection* stack = panel_manager->CreateStack();
2848   gfx::Rect panel1_initial_bounds = gfx::Rect(100, 100, 200, 150);
2849   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
2850   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
2851   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
2852   ASSERT_EQ(0, detached_collection->num_panels());
2853   ASSERT_EQ(1, panel_manager->num_stacks());
2854   ASSERT_EQ(2, stack->num_panels());
2855   EXPECT_EQ(stack, panel1->collection());
2856   EXPECT_EQ(stack, panel2->collection());
2857 
2858   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
2859   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2860   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
2861       panel2_initial_bounds, panel1_expected_bounds);
2862   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2863 
2864   // Create 1 detached panel.
2865   gfx::Rect panel3_initial_bounds = gfx::Rect(300, 200, 100, 100);
2866   Panel* panel3 = CreateDetachedPanel("3", panel3_initial_bounds);
2867   ASSERT_EQ(1, detached_collection->num_panels());
2868   EXPECT_EQ(PanelCollection::DETACHED, panel3->collection()->type());
2869   gfx::Rect panel3_expected_bounds(panel3_initial_bounds);
2870   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
2871 
2872   // Drag P3 close to the right of the stack of P1 and P2 to trigger the
2873   // snapping.
2874   gfx::Vector2d drag_delta_to_snap = GetDragDeltaToSnapToRight(panel3, panel1);
2875   DragPanelByDelta(panel3, drag_delta_to_snap);
2876   ASSERT_EQ(1, detached_collection->num_panels());
2877   ASSERT_EQ(1, panel_manager->num_stacks());
2878   ASSERT_EQ(2, stack->num_panels());
2879   EXPECT_EQ(stack, panel1->collection());
2880   EXPECT_EQ(stack, panel2->collection());
2881   EXPECT_EQ(PanelCollection::DETACHED, panel3->collection()->type());
2882   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2883   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2884   panel3_expected_bounds.Offset(drag_delta_to_snap);
2885   panel3_expected_bounds.set_x(panel1_expected_bounds.right());
2886   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
2887 
2888   panel_manager->CloseAll();
2889 }
2890 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,DetachAndSnap)2891 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DetachAndSnap) {
2892   PanelManager* panel_manager = PanelManager::GetInstance();
2893   DockedPanelCollection* docked_collection = panel_manager->docked_collection();
2894   DetachedPanelCollection* detached_collection =
2895       panel_manager->detached_collection();
2896 
2897   // Create 1 detached panel.
2898   Panel* panel1 = CreateDetachedPanel("1", gfx::Rect(300, 200, 100, 100));
2899   ASSERT_EQ(0, docked_collection->num_panels());
2900   ASSERT_EQ(1, detached_collection->num_panels());
2901   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
2902   gfx::Rect panel1_bounds = panel1->GetBounds();
2903 
2904   // Create 1 docked panel.
2905   Panel* panel2 = CreateDockedPanel("2", gfx::Rect(0, 0, 150, 150));
2906   ASSERT_EQ(1, docked_collection->num_panels());
2907   ASSERT_EQ(1, detached_collection->num_panels());
2908   EXPECT_EQ(PanelCollection::DOCKED, panel2->collection()->type());
2909   gfx::Rect panel2_bounds = panel2->GetBounds();
2910 
2911   // Drag P2 close to the right of P1 to trigger both detaching and snapping.
2912   gfx::Vector2d drag_delta_to_detach_and_snap =
2913       GetDragDeltaToSnapToRight(panel2, panel1);
2914   DragPanelByDelta(panel2, drag_delta_to_detach_and_snap);
2915   ASSERT_EQ(0, docked_collection->num_panels());
2916   ASSERT_EQ(2, detached_collection->num_panels());
2917   EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type());
2918   EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type());
2919   EXPECT_EQ(panel1_bounds, panel1->GetBounds());
2920   panel2_bounds.Offset(drag_delta_to_detach_and_snap);
2921   panel2_bounds.set_x(panel1_bounds.right());
2922   EXPECT_EQ(panel2_bounds, panel2->GetBounds());
2923 
2924   panel_manager->CloseAll();
2925 }
2926 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,DragTopStackedPanel)2927 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DragTopStackedPanel) {
2928   PanelManager* panel_manager = PanelManager::GetInstance();
2929 
2930   // Create 3 stacked panels.
2931   StackedPanelCollection* stack = panel_manager->CreateStack();
2932   gfx::Rect panel1_initial_bounds = gfx::Rect(300, 100, 200, 150);
2933   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
2934   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
2935   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
2936   gfx::Rect panel3_initial_bounds = gfx::Rect(0, 0, 150, 200);
2937   Panel* panel3 = CreateStackedPanel("3", panel3_initial_bounds, stack);
2938   ASSERT_EQ(3, stack->num_panels());
2939   ASSERT_EQ(1, panel_manager->num_stacks());
2940   EXPECT_EQ(stack, panel1->collection());
2941   EXPECT_EQ(stack, panel2->collection());
2942   EXPECT_EQ(stack, panel3->collection());
2943 
2944   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
2945   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2946   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
2947       panel2_initial_bounds, panel1_expected_bounds);
2948   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2949   gfx::Rect panel3_expected_bounds = GetStackedAtBottomPanelBounds(
2950       panel3_initial_bounds, panel2_expected_bounds);
2951   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
2952 
2953   // Drag the top panel by a delta.
2954   // Expect all panels are still in the same stack and they are all moved by the
2955   // same delta.
2956   gfx::Vector2d drag_delta(-50, -20);
2957   DragPanelByDelta(panel1, drag_delta);
2958   ASSERT_EQ(3, stack->num_panels());
2959   ASSERT_EQ(1, panel_manager->num_stacks());
2960   EXPECT_EQ(stack, panel1->collection());
2961   EXPECT_EQ(stack, panel2->collection());
2962   EXPECT_EQ(stack, panel3->collection());
2963 
2964   panel1_expected_bounds.Offset(drag_delta);
2965   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
2966   panel2_expected_bounds.Offset(drag_delta);
2967   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
2968   panel3_expected_bounds.Offset(drag_delta);
2969   EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds());
2970 
2971   panel_manager->CloseAll();
2972 }
2973 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,SnapDetachedPanelToScreenEdge)2974 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, SnapDetachedPanelToScreenEdge) {
2975   PanelManager* panel_manager = PanelManager::GetInstance();
2976   int small_distance =
2977       PanelDragController::GetSnapPanelToScreenEdgeThresholdForTesting() / 2;
2978 
2979   // Setup 2 displays with secondary display on the right side of primary
2980   // display.
2981   gfx::Rect primary_display_area(0, 0, 400, 600);
2982   gfx::Rect primary_work_area(0, 0, 400, 560);
2983   mock_display_settings_provider()->SetPrimaryDisplay(
2984       primary_display_area, primary_work_area);
2985   gfx::Rect secondary_display_area(400, 100, 400, 500);
2986   gfx::Rect secondary_work_area(400, 140, 400, 460);
2987   mock_display_settings_provider()->SetSecondaryDisplay(
2988       secondary_display_area, secondary_work_area);
2989 
2990   // Create one detached panel on the primary display.
2991   gfx::Rect initial_bounds = gfx::Rect(100, 100, 200, 150);
2992   Panel* panel = CreateDetachedPanel("1", initial_bounds);
2993   gfx::Rect expected_bounds(initial_bounds);
2994   EXPECT_EQ(expected_bounds, panel->GetBounds());
2995 
2996   // Drag the panel close to the right edge of the primary display.
2997   // Expect that the panel should snap to the right edge.
2998   gfx::Point drag_to_location(
2999       primary_work_area.right() - small_distance - panel->GetBounds().width(),
3000       panel->GetBounds().y());
3001   DragPanelToMouseLocation(panel, drag_to_location);
3002   expected_bounds.set_x(primary_work_area.right() - panel->GetBounds().width());
3003   EXPECT_EQ(expected_bounds, panel->GetBounds());
3004 
3005   // Drag the panel close to the top-left corner of the primary display.
3006   // Expect that the panel should snap to the top-left corner.
3007   drag_to_location = gfx::Point(
3008       primary_work_area.x() + small_distance,
3009       primary_work_area.y() - small_distance);
3010   DragPanelToMouseLocation(panel, drag_to_location);
3011   expected_bounds.set_origin(primary_work_area.origin());
3012   EXPECT_EQ(expected_bounds, panel->GetBounds());
3013 
3014   // Drag the panel close to the top-right corner of the secondary display.
3015   // Expect that the panel should snap to the top-right corner.
3016   drag_to_location = gfx::Point(
3017       secondary_work_area.right() - small_distance - panel->GetBounds().width(),
3018       secondary_work_area.y() + small_distance);
3019   DragPanelToMouseLocation(panel, drag_to_location);
3020   expected_bounds.set_x(
3021       secondary_work_area.right() - panel->GetBounds().width());
3022   expected_bounds.set_y(secondary_work_area.y());
3023   EXPECT_EQ(expected_bounds, panel->GetBounds());
3024 
3025   panel_manager->CloseAll();
3026 }
3027 
IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest,SnapStackedPanelToScreenEdge)3028 IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, SnapStackedPanelToScreenEdge) {
3029   PanelManager* panel_manager = PanelManager::GetInstance();
3030   int small_distance =
3031       PanelDragController::GetSnapPanelToScreenEdgeThresholdForTesting() / 2;
3032 
3033   // Setup 2 displays with secondary display on the right side of primary
3034   // display.
3035   gfx::Rect primary_display_area(0, 0, 400, 600);
3036   gfx::Rect primary_work_area(0, 0, 400, 560);
3037   mock_display_settings_provider()->SetPrimaryDisplay(
3038       primary_display_area, primary_work_area);
3039   gfx::Rect secondary_display_area(400, 100, 400, 500);
3040   gfx::Rect secondary_work_area(400, 140, 400, 460);
3041   mock_display_settings_provider()->SetSecondaryDisplay(
3042       secondary_display_area, secondary_work_area);
3043 
3044   // Create 2 stacked panels on the primary display.
3045   StackedPanelCollection* stack = panel_manager->CreateStack();
3046   gfx::Rect panel1_initial_bounds = gfx::Rect(300, 100, 200, 150);
3047   Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack);
3048   gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100);
3049   Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack);
3050 
3051   gfx::Rect panel1_expected_bounds(panel1_initial_bounds);
3052   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
3053   gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds(
3054       panel2_initial_bounds, panel1_expected_bounds);
3055   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
3056 
3057   // Drag the stack close to the left edge of the primary display.
3058   // Expect that the stack should snap to the left edge.
3059   gfx::Point drag_to_location(
3060       primary_work_area.x() + small_distance, panel1->GetBounds().y());
3061   DragPanelToMouseLocation(panel1, drag_to_location);
3062 
3063   panel1_expected_bounds.set_x(primary_work_area.x());
3064   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
3065   panel2_expected_bounds.set_x(primary_work_area.x());
3066   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
3067 
3068   // Drag the stack close to the bottom-right corner of the primary display.
3069   // Expect that the stack should snap to the bottom-right corner.
3070   drag_to_location = gfx::Point(
3071       primary_work_area.right() + small_distance - panel1->GetBounds().width(),
3072       primary_work_area.bottom() - small_distance -
3073           panel1->GetBounds().height() - panel2->GetBounds().height());
3074   DragPanelToMouseLocation(panel1, drag_to_location);
3075 
3076   int expected_x = primary_work_area.right() - panel1->GetBounds().width();
3077   panel1_expected_bounds.set_x(expected_x);
3078   panel1_expected_bounds.set_y(primary_work_area.bottom() -
3079       panel1->GetBounds().height() - panel2->GetBounds().height());
3080   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
3081   panel2_expected_bounds.set_x(expected_x);
3082   panel2_expected_bounds.set_y(primary_work_area.bottom() -
3083       panel2->GetBounds().height());
3084   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
3085 
3086   // Drag the stack close to the top-left corner of the secondary display.
3087   // Expect that the stack should snap to the top-left corner.
3088   drag_to_location = gfx::Point(
3089       secondary_work_area.x() + small_distance,
3090       secondary_work_area.y() + small_distance);
3091   DragPanelToMouseLocation(panel1, drag_to_location);
3092 
3093   expected_x = secondary_work_area.x();
3094   panel1_expected_bounds.set_x(expected_x);
3095   panel1_expected_bounds.set_y(secondary_work_area.y());
3096   EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds());
3097   panel2_expected_bounds.set_x(expected_x);
3098   panel2_expected_bounds.set_y(panel1_expected_bounds.bottom());
3099   EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds());
3100 
3101   panel_manager->CloseAll();
3102 }
3103