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
19class PanelDragBrowserTest : public BasePanelBrowserTest {
20 public:
21  PanelDragBrowserTest() : BasePanelBrowserTest() {
22  }
23
24  virtual ~PanelDragBrowserTest() {
25  }
26
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|.
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|.
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.
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.
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
81  static gfx::Vector2d GetDragDeltaToRemainDocked() {
82    return gfx::Vector2d(
83        -5,
84        -(PanelDragController::GetDetachDockedPanelThresholdForTesting() / 2));
85  }
86
87  static gfx::Vector2d GetDragDeltaToDetach() {
88    return gfx::Vector2d(
89        -20,
90        -(PanelDragController::GetDetachDockedPanelThresholdForTesting() + 20));
91  }
92
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
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|.
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|.
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|.
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|.
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|.
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|.
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.
184  static gfx::Vector2d GetDragDeltaToUnsnap(Panel* panel) {
185    return gfx::Vector2d(
186        PanelDragController::GetGluePanelDistanceThresholdForTesting() * 2, 0);
187  }
188};
189
190IN_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
282IN_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
378IN_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
511IN_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
549IN_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
598IN_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
777IN_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
823IN_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
937IN_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
999IN_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
1061IN_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
1127IN_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
1183IN_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
1245IN_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
1328IN_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
1451IN_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
1479IN_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
1506IN_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
1533IN_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
1640IN_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
1748IN_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
1801IN_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
1862IN_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
1925IN_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
1982IN_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
2039IN_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
2110IN_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
2183IN_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
2272IN_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
2333IN_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
2383IN_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
2435IN_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
2496IN_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
2549IN_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
2596IN_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
2672IN_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
2746IN_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
2790IN_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
2841IN_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
2891IN_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
2927IN_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
2974IN_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
3028IN_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