// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/message_loop/message_loop.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/ui/panels/base_panel_browser_test.h" #include "chrome/browser/ui/panels/detached_panel_collection.h" #include "chrome/browser/ui/panels/docked_panel_collection.h" #include "chrome/browser/ui/panels/native_panel.h" #include "chrome/browser/ui/panels/panel.h" #include "chrome/browser/ui/panels/panel_drag_controller.h" #include "chrome/browser/ui/panels/panel_manager.h" #include "chrome/browser/ui/panels/stacked_panel_collection.h" #include "chrome/browser/ui/panels/test_panel_collection_squeeze_observer.h" #include "content/public/browser/notification_service.h" #include "content/public/test/test_utils.h" class PanelDragBrowserTest : public BasePanelBrowserTest { public: PanelDragBrowserTest() : BasePanelBrowserTest() { } virtual ~PanelDragBrowserTest() { } virtual void SetUpOnMainThread() OVERRIDE { BasePanelBrowserTest::SetUpOnMainThread(); // All the tests here assume using mocked 800x600 display area for the // primary monitor. Do the check now. gfx::Rect primary_display_area = PanelManager::GetInstance()-> display_settings_provider()->GetPrimaryDisplayArea(); DCHECK(primary_display_area.width() == 800); DCHECK(primary_display_area.height() == 600); } // Drag |panel| from its origin by the offset |delta|. void DragPanelByDelta(Panel* panel, const gfx::Vector2d& delta) { scoped_ptr panel_testing( CreateNativePanelTesting(panel)); gfx::Point mouse_location(panel->GetBounds().origin()); panel_testing->PressLeftMouseButtonTitlebar(mouse_location); panel_testing->DragTitlebar(mouse_location + delta); panel_testing->FinishDragTitlebar(); } // Drag |panel| from its origin to |new_mouse_location|. void DragPanelToMouseLocation(Panel* panel, const gfx::Point& new_mouse_location) { scoped_ptr panel_testing( CreateNativePanelTesting(panel)); gfx::Point mouse_location(panel->GetBounds().origin()); panel_testing->PressLeftMouseButtonTitlebar(panel->GetBounds().origin()); panel_testing->DragTitlebar(new_mouse_location); panel_testing->FinishDragTitlebar(); } // Return the bounds of a panel given its initial bounds and the bounds of the // panel above it. static gfx::Rect GetStackedAtBottomPanelBounds( const gfx::Rect& initial_bounds, const gfx::Rect& above_bounds) { return gfx::Rect(above_bounds.x(), above_bounds.bottom(), above_bounds.width(), initial_bounds.height()); } // Return the bounds of a panel given its initial bounds and the bounds of the // panel below it. static gfx::Rect GetStackedAtTopPanelBounds( const gfx::Rect& initial_bounds, const gfx::Rect& below_bounds) { return gfx::Rect(below_bounds.x(), below_bounds.y() - initial_bounds.height(), initial_bounds.width(), initial_bounds.height()); } static gfx::Vector2d GetDragDeltaToRemainDocked() { return gfx::Vector2d( -5, -(PanelDragController::GetDetachDockedPanelThresholdForTesting() / 2)); } static gfx::Vector2d GetDragDeltaToDetach() { return gfx::Vector2d( -20, -(PanelDragController::GetDetachDockedPanelThresholdForTesting() + 20)); } static gfx::Vector2d GetDragDeltaToRemainDetached(Panel* panel) { int distance = panel->manager()->docked_collection()->work_area().bottom() - panel->GetBounds().bottom(); return gfx::Vector2d( -5, distance - PanelDragController::GetDockDetachedPanelThresholdForTesting() * 2); } static gfx::Vector2d GetDragDeltaToAttach(Panel* panel) { int distance = panel->manager()->docked_collection()->work_area().bottom() - panel->GetBounds().bottom(); return gfx::Vector2d( -20, distance - PanelDragController::GetDockDetachedPanelThresholdForTesting() / 2); } // Return the delta needed to drag |panel1| to stack to the bottom of // |panel2|. static gfx::Vector2d GetDragDeltaToStackToBottom(Panel* panel1, Panel* panel2) { gfx::Rect bounds1 = panel1->GetBounds(); gfx::Rect bounds2 = panel2->GetBounds(); return gfx::Vector2d( bounds2.x() - bounds1.x(), bounds2.bottom() - bounds1.y() + PanelDragController::GetGluePanelDistanceThresholdForTesting() / 2); } // Return the delta needed to drag |panel1| to unstack from the bottom of // |panel2|. static gfx::Vector2d GetDragDeltaToUnstackFromBottom(Panel* panel1, Panel* panel2) { gfx::Rect bounds1 = panel1->GetBounds(); gfx::Rect bounds2 = panel2->GetBounds(); return gfx::Vector2d( 0, PanelDragController::GetGluePanelDistanceThresholdForTesting() * 2); } // Return the delta needed to drag |panel1| to stack to the top of |panel2|. static gfx::Vector2d GetDragDeltaToStackToTop(Panel* panel1, Panel* panel2) { gfx::Rect bounds1 = panel1->GetBounds(); gfx::Rect bounds2 = panel2->GetBounds(); StackedPanelCollection* stack1 = panel1->stack(); int bottom = stack1 ? stack1->bottom_panel()->GetBounds().bottom() : bounds1.bottom(); return gfx::Vector2d( bounds2.x() - bounds1.x(), bounds2.y() - bottom - PanelDragController::GetGluePanelDistanceThresholdForTesting() / 2); } // Return the delta needed to drag |panel1| to unstack from the top of // |panel2|. static gfx::Vector2d GetDragDeltaToUnstackFromTop(Panel* panel1, Panel* panel2) { gfx::Rect bounds1 = panel1->GetBounds(); gfx::Rect bounds2 = panel2->GetBounds(); return gfx::Vector2d( 0, -PanelDragController::GetGluePanelDistanceThresholdForTesting() * 2); } // Return the delta needed to drag |panel1| to snap to the left of |panel2|. static gfx::Vector2d GetDragDeltaToSnapToLeft(Panel* panel1, Panel* panel2) { gfx::Rect bounds1 = panel1->GetBounds(); gfx::Rect bounds2 = panel2->GetBounds(); return gfx::Vector2d( bounds2.x() - bounds1.width() - bounds1.x() - PanelDragController::GetGluePanelDistanceThresholdForTesting() / 2, bounds2.y() - bounds1.y() + PanelDragController::GetGluePanelDistanceThresholdForTesting() * 2); } // Return the delta needed to drag |panel1| to snap to the right of |panel2|. static gfx::Vector2d GetDragDeltaToSnapToRight(Panel* panel1, Panel* panel2) { gfx::Rect bounds1 = panel1->GetBounds(); gfx::Rect bounds2 = panel2->GetBounds(); return gfx::Vector2d( bounds2.right() - bounds1.x() + PanelDragController::GetGluePanelDistanceThresholdForTesting() / 2, bounds2.y() - bounds1.y() + PanelDragController::GetGluePanelDistanceThresholdForTesting() * 2); } // Return the delta needed to drag |panel| to unsnap from its current // position. static gfx::Vector2d GetDragDeltaToUnsnap(Panel* panel) { return gfx::Vector2d( PanelDragController::GetGluePanelDistanceThresholdForTesting() * 2, 0); } }; IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DragOneDockedPanel) { static const int big_delta_x = 70; static const int big_delta_y = 30; // Do not exceed the threshold to detach. Panel* panel = CreateDockedPanel("1", gfx::Rect(0, 0, 100, 100)); scoped_ptr panel_testing( CreateNativePanelTesting(panel)); gfx::Rect panel_old_bounds = panel->GetBounds(); // Drag left. gfx::Point mouse_location = panel_old_bounds.origin(); panel_testing->PressLeftMouseButtonTitlebar(mouse_location); EXPECT_EQ(panel_old_bounds, panel->GetBounds()); mouse_location.Offset(-big_delta_x, 0); panel_testing->DragTitlebar(mouse_location); gfx::Rect panel_new_bounds = panel_old_bounds; panel_new_bounds.Offset(-big_delta_x, 0); EXPECT_EQ(panel_new_bounds, panel->GetBounds()); panel_testing->FinishDragTitlebar(); EXPECT_EQ(panel_old_bounds, panel->GetBounds()); // Drag left and cancel. mouse_location = panel_old_bounds.origin(); panel_testing->PressLeftMouseButtonTitlebar(mouse_location); EXPECT_EQ(panel_old_bounds, panel->GetBounds()); mouse_location.Offset(-big_delta_x, 0); panel_testing->DragTitlebar(mouse_location); panel_new_bounds = panel_old_bounds; panel_new_bounds.Offset(-big_delta_x, 0); EXPECT_EQ(panel_new_bounds, panel->GetBounds()); panel_testing->CancelDragTitlebar(); EXPECT_EQ(panel_old_bounds, panel->GetBounds()); // Drag right. mouse_location = panel_old_bounds.origin(); panel_testing->PressLeftMouseButtonTitlebar(mouse_location); EXPECT_EQ(panel_old_bounds, panel->GetBounds()); mouse_location.Offset(big_delta_x, 0); panel_testing->DragTitlebar(mouse_location); panel_new_bounds = panel_old_bounds; panel_new_bounds.Offset(big_delta_x, 0); EXPECT_EQ(panel_new_bounds, panel->GetBounds()); panel_testing->FinishDragTitlebar(); EXPECT_EQ(panel_old_bounds, panel->GetBounds()); // Drag right and up. Expect no vertical movement. mouse_location = panel_old_bounds.origin(); panel_testing->PressLeftMouseButtonTitlebar(mouse_location); EXPECT_EQ(panel_old_bounds, panel->GetBounds()); mouse_location.Offset(big_delta_x, big_delta_y); panel_testing->DragTitlebar(mouse_location); panel_new_bounds = panel_old_bounds; panel_new_bounds.Offset(big_delta_x, 0); EXPECT_EQ(panel_new_bounds, panel->GetBounds()); panel_testing->FinishDragTitlebar(); EXPECT_EQ(panel_old_bounds, panel->GetBounds()); // Drag up. Expect no movement on drag. mouse_location = panel_old_bounds.origin(); panel_testing->PressLeftMouseButtonTitlebar(mouse_location); EXPECT_EQ(panel_old_bounds, panel->GetBounds()); mouse_location.Offset(0, -big_delta_y); panel_testing->DragTitlebar(mouse_location); EXPECT_EQ(panel_old_bounds, panel->GetBounds()); panel_testing->FinishDragTitlebar(); EXPECT_EQ(panel_old_bounds, panel->GetBounds()); // Drag down. Expect no movement on drag. mouse_location = panel_old_bounds.origin(); panel_testing->PressLeftMouseButtonTitlebar(mouse_location); EXPECT_EQ(panel_old_bounds, panel->GetBounds()); mouse_location.Offset(0, big_delta_y); panel_testing->DragTitlebar(mouse_location); EXPECT_EQ(panel_old_bounds, panel->GetBounds()); panel_testing->FinishDragTitlebar(); EXPECT_EQ(panel_old_bounds, panel->GetBounds()); PanelManager::GetInstance()->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DragTwoDockedPanels) { static const gfx::Vector2d small_delta(10, 0); Panel* panel1 = CreateDockedPanel("1", gfx::Rect(0, 0, 100, 100)); Panel* panel2 = CreateDockedPanel("2", gfx::Rect(0, 0, 100, 100)); scoped_ptr panel1_testing( CreateNativePanelTesting(panel1)); scoped_ptr panel2_testing( CreateNativePanelTesting(panel2)); gfx::Point position1 = panel1->GetBounds().origin(); gfx::Point position2 = panel2->GetBounds().origin(); // Drag right panel towards left with small delta. // Expect no shuffle: P1 P2 gfx::Point mouse_location = position1; panel1_testing->PressLeftMouseButtonTitlebar(mouse_location); EXPECT_EQ(position1, panel1->GetBounds().origin()); EXPECT_EQ(position2, panel2->GetBounds().origin()); mouse_location = mouse_location - small_delta; panel1_testing->DragTitlebar(mouse_location); EXPECT_EQ(mouse_location, panel1->GetBounds().origin()); EXPECT_EQ(position2, panel2->GetBounds().origin()); panel1_testing->FinishDragTitlebar(); EXPECT_EQ(position1, panel1->GetBounds().origin()); EXPECT_EQ(position2, panel2->GetBounds().origin()); // Drag right panel towards left with big delta. // Expect shuffle: P2 P1 mouse_location = position1; panel1_testing->PressLeftMouseButtonTitlebar(mouse_location); EXPECT_EQ(position1, panel1->GetBounds().origin()); EXPECT_EQ(position2, panel2->GetBounds().origin()); mouse_location = position2 + gfx::Vector2d(1, 0); panel1_testing->DragTitlebar(mouse_location); EXPECT_EQ(mouse_location, panel1->GetBounds().origin()); EXPECT_EQ(position1, panel2->GetBounds().origin()); panel1_testing->FinishDragTitlebar(); EXPECT_EQ(position2, panel1->GetBounds().origin()); EXPECT_EQ(position1, panel2->GetBounds().origin()); // Drag left panel towards right with small delta. // Expect no shuffle: P2 P1 mouse_location = position2; panel1_testing->PressLeftMouseButtonTitlebar(mouse_location); EXPECT_EQ(position2, panel1->GetBounds().origin()); EXPECT_EQ(position1, panel2->GetBounds().origin()); mouse_location = mouse_location + small_delta; panel1_testing->DragTitlebar(mouse_location); EXPECT_EQ(mouse_location, panel1->GetBounds().origin()); EXPECT_EQ(position1, panel2->GetBounds().origin()); panel1_testing->FinishDragTitlebar(); EXPECT_EQ(position2, panel1->GetBounds().origin()); EXPECT_EQ(position1, panel2->GetBounds().origin()); // Drag left panel towards right with big delta. // Expect shuffle: P1 P2 mouse_location = position2; panel1_testing->PressLeftMouseButtonTitlebar(mouse_location); EXPECT_EQ(position2, panel1->GetBounds().origin()); EXPECT_EQ(position1, panel2->GetBounds().origin()); mouse_location = position1 + gfx::Vector2d(1, 0); panel1_testing->DragTitlebar(mouse_location); EXPECT_EQ(mouse_location, panel1->GetBounds().origin()); EXPECT_EQ(position2, panel2->GetBounds().origin()); panel1_testing->FinishDragTitlebar(); EXPECT_EQ(position1, panel1->GetBounds().origin()); EXPECT_EQ(position2, panel2->GetBounds().origin()); // Drag right panel towards left with big delta and then cancel the drag. // Expect shuffle after drag: P2 P1 // Expect shuffle after cancel: P1 P2 mouse_location = position1; panel1_testing->PressLeftMouseButtonTitlebar(mouse_location); EXPECT_EQ(position1, panel1->GetBounds().origin()); EXPECT_EQ(position2, panel2->GetBounds().origin()); mouse_location = position2 + gfx::Vector2d(1, 0); panel1_testing->DragTitlebar(mouse_location); EXPECT_EQ(mouse_location, panel1->GetBounds().origin()); EXPECT_EQ(position1, panel2->GetBounds().origin()); panel1_testing->CancelDragTitlebar(); EXPECT_EQ(position1, panel1->GetBounds().origin()); EXPECT_EQ(position2, panel2->GetBounds().origin()); PanelManager::GetInstance()->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DragThreeDockedPanels) { Panel* panel1 = CreateDockedPanel("1", gfx::Rect(0, 0, 100, 100)); Panel* panel2 = CreateDockedPanel("2", gfx::Rect(0, 0, 100, 100)); Panel* panel3 = CreateDockedPanel("3", gfx::Rect(0, 0, 100, 100)); scoped_ptr panel2_testing( CreateNativePanelTesting(panel2)); scoped_ptr panel3_testing( CreateNativePanelTesting(panel3)); gfx::Point position1 = panel1->GetBounds().origin(); gfx::Point position2 = panel2->GetBounds().origin(); gfx::Point position3 = panel3->GetBounds().origin(); // Drag leftmost panel to become the rightmost in 2 drags. Each drag will // shuffle one panel. // Expect shuffle after 1st drag: P1 P3 P2 // Expect shuffle after 2nd drag: P3 P1 P2 gfx::Point mouse_location = position3; panel3_testing->PressLeftMouseButtonTitlebar(mouse_location); EXPECT_EQ(position1, panel1->GetBounds().origin()); EXPECT_EQ(position2, panel2->GetBounds().origin()); EXPECT_EQ(position3, panel3->GetBounds().origin()); mouse_location = position2 + gfx::Vector2d(1, 0); panel3_testing->DragTitlebar(mouse_location); EXPECT_EQ(position1, panel1->GetBounds().origin()); EXPECT_EQ(position3, panel2->GetBounds().origin()); EXPECT_EQ(mouse_location, panel3->GetBounds().origin()); mouse_location = position1 + gfx::Vector2d(1, 0); panel3_testing->DragTitlebar(mouse_location); EXPECT_EQ(position2, panel1->GetBounds().origin()); EXPECT_EQ(position3, panel2->GetBounds().origin()); EXPECT_EQ(mouse_location, panel3->GetBounds().origin()); panel3_testing->FinishDragTitlebar(); EXPECT_EQ(position2, panel1->GetBounds().origin()); EXPECT_EQ(position3, panel2->GetBounds().origin()); EXPECT_EQ(position1, panel3->GetBounds().origin()); // Drag rightmost panel to become the leftmost in 2 drags and then cancel the // drag. Each drag will shuffle one panel and the cancellation will restore // all panels. // Expect shuffle after 1st drag: P1 P3 P2 // Expect shuffle after 2nd drag: P1 P2 P3 // Expect shuffle after cancel: P3 P1 P2 mouse_location = position1; panel3_testing->PressLeftMouseButtonTitlebar(mouse_location); EXPECT_EQ(position2, panel1->GetBounds().origin()); EXPECT_EQ(position3, panel2->GetBounds().origin()); EXPECT_EQ(position1, panel3->GetBounds().origin()); mouse_location = position2 + gfx::Vector2d(1, 0); panel3_testing->DragTitlebar(mouse_location); EXPECT_EQ(position1, panel1->GetBounds().origin()); EXPECT_EQ(position3, panel2->GetBounds().origin()); EXPECT_EQ(mouse_location, panel3->GetBounds().origin()); mouse_location = position3 + gfx::Vector2d(1, 0); panel3_testing->DragTitlebar(mouse_location); EXPECT_EQ(position1, panel1->GetBounds().origin()); EXPECT_EQ(position2, panel2->GetBounds().origin()); EXPECT_EQ(mouse_location, panel3->GetBounds().origin()); panel3_testing->CancelDragTitlebar(); EXPECT_EQ(position2, panel1->GetBounds().origin()); EXPECT_EQ(position3, panel2->GetBounds().origin()); EXPECT_EQ(position1, panel3->GetBounds().origin()); // Drag leftmost panel to become the rightmost in a single drag. The drag will // shuffle 2 panels at a time. // Expect shuffle: P2 P3 P1 mouse_location = position3; panel2_testing->PressLeftMouseButtonTitlebar(mouse_location); EXPECT_EQ(position2, panel1->GetBounds().origin()); EXPECT_EQ(position3, panel2->GetBounds().origin()); EXPECT_EQ(position1, panel3->GetBounds().origin()); mouse_location = position1 + gfx::Vector2d(1, 0); panel2_testing->DragTitlebar(mouse_location); EXPECT_EQ(position3, panel1->GetBounds().origin()); EXPECT_EQ(mouse_location, panel2->GetBounds().origin()); EXPECT_EQ(position2, panel3->GetBounds().origin()); panel2_testing->FinishDragTitlebar(); EXPECT_EQ(position3, panel1->GetBounds().origin()); EXPECT_EQ(position1, panel2->GetBounds().origin()); EXPECT_EQ(position2, panel3->GetBounds().origin()); // Drag rightmost panel to become the leftmost in a single drag. The drag will // shuffle 2 panels at a time. // Expect shuffle: P3 P1 P2 mouse_location = position1; panel2_testing->PressLeftMouseButtonTitlebar(mouse_location); EXPECT_EQ(position3, panel1->GetBounds().origin()); EXPECT_EQ(position1, panel2->GetBounds().origin()); EXPECT_EQ(position2, panel3->GetBounds().origin()); mouse_location = position3 + gfx::Vector2d(1, 0); panel2_testing->DragTitlebar(mouse_location); EXPECT_EQ(position2, panel1->GetBounds().origin()); EXPECT_EQ(mouse_location, panel2->GetBounds().origin()); EXPECT_EQ(position1, panel3->GetBounds().origin()); panel2_testing->FinishDragTitlebar(); EXPECT_EQ(position2, panel1->GetBounds().origin()); EXPECT_EQ(position3, panel2->GetBounds().origin()); EXPECT_EQ(position1, panel3->GetBounds().origin()); // Drag rightmost panel to become the leftmost in a single drag and then // cancel the drag. The drag will shuffle 2 panels and the cancellation will // restore all panels. // Expect shuffle after drag: P1 P2 P3 // Expect shuffle after cancel: P3 P1 P2 mouse_location = position1; panel3_testing->PressLeftMouseButtonTitlebar(mouse_location); EXPECT_EQ(position2, panel1->GetBounds().origin()); EXPECT_EQ(position3, panel2->GetBounds().origin()); EXPECT_EQ(position1, panel3->GetBounds().origin()); mouse_location = position3 + gfx::Vector2d(1, 0); panel3_testing->DragTitlebar(mouse_location); EXPECT_EQ(position1, panel1->GetBounds().origin()); EXPECT_EQ(position2, panel2->GetBounds().origin()); EXPECT_EQ(mouse_location, panel3->GetBounds().origin()); panel3_testing->CancelDragTitlebar(); EXPECT_EQ(position2, panel1->GetBounds().origin()); EXPECT_EQ(position3, panel2->GetBounds().origin()); EXPECT_EQ(position1, panel3->GetBounds().origin()); PanelManager::GetInstance()->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DragMinimizedPanel) { Panel* panel = CreatePanel("panel1"); scoped_ptr panel_testing( CreateNativePanelTesting(panel)); panel->Minimize(); EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state()); // Hover over minimized panel to bring up titlebar. gfx::Point hover_point(panel->GetBounds().origin()); MoveMouseAndWaitForExpansionStateChange(panel, hover_point); EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state()); // Verify we can drag a minimized panel. gfx::Rect panel_old_bounds = panel->GetBounds(); gfx::Point mouse_location = panel_old_bounds.origin(); panel_testing->PressLeftMouseButtonTitlebar(mouse_location); EXPECT_EQ(panel_old_bounds, panel->GetBounds()); EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state()); mouse_location.Offset(-70, 0); panel_testing->DragTitlebar(mouse_location); gfx::Rect panel_new_bounds = panel_old_bounds; panel_new_bounds.Offset(-70, 0); EXPECT_EQ(panel_new_bounds, panel->GetBounds()); EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state()); // Verify panel returns to fully minimized state after dragging ends once // mouse moves away from panel. panel_testing->FinishDragTitlebar(); EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state()); MoveMouseAndWaitForExpansionStateChange(panel, mouse_location); EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state()); panel->Close(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DragMinimizedPanelWhileDrawingAttention) { Panel* panel = CreatePanel("panel1"); scoped_ptr panel_testing( CreateNativePanelTesting(panel)); CreatePanel("panel2"); panel->Minimize(); EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state()); panel->FlashFrame(true); EXPECT_TRUE(panel->IsDrawingAttention()); EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state()); // Drag the panel. Verify panel stays in title-only state after attention is // cleared because it is being dragged. gfx::Rect panel_old_bounds = panel->GetBounds(); gfx::Point mouse_location = panel_old_bounds.origin(); panel_testing->PressLeftMouseButtonTitlebar(mouse_location); EXPECT_EQ(panel_old_bounds, panel->GetBounds()); EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state()); mouse_location.Offset(-70, 0); panel_testing->DragTitlebar(mouse_location); gfx::Rect panel_new_bounds = panel_old_bounds; panel_new_bounds.Offset(-70, 0); EXPECT_EQ(panel_new_bounds, panel->GetBounds()); panel->FlashFrame(false); EXPECT_FALSE(panel->IsDrawingAttention()); EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state()); // Typical user scenario will detect the mouse in the panel // after attention is cleared, causing titles to pop up, so // we simulate that here. MoveMouse(mouse_location); // Verify panel returns to fully minimized state after dragging ends once // mouse moves away from the panel. panel_testing->FinishDragTitlebar(); EXPECT_EQ(Panel::TITLE_ONLY, panel->expansion_state()); mouse_location.Offset(0, -50); MoveMouseAndWaitForExpansionStateChange(panel, mouse_location); EXPECT_EQ(Panel::MINIMIZED, panel->expansion_state()); PanelManager::GetInstance()->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, CloseDockedPanelOnDrag) { PanelManager* panel_manager = PanelManager::GetInstance(); PanelDragController* drag_controller = panel_manager->drag_controller(); DockedPanelCollection* docked_collection = panel_manager->docked_collection(); // Create 4 docked panels. // We have: P4 P3 P2 P1 Panel* panel1 = CreatePanelWithBounds("Panel1", gfx::Rect(0, 0, 100, 100)); Panel* panel2 = CreatePanelWithBounds("Panel2", gfx::Rect(0, 0, 100, 100)); Panel* panel3 = CreatePanelWithBounds("Panel3", gfx::Rect(0, 0, 100, 100)); Panel* panel4 = CreatePanelWithBounds("Panel4", gfx::Rect(0, 0, 100, 100)); ASSERT_EQ(4, docked_collection->num_panels()); scoped_ptr panel1_testing( CreateNativePanelTesting(panel1)); gfx::Point position1 = panel1->GetBounds().origin(); gfx::Point position2 = panel2->GetBounds().origin(); gfx::Point position3 = panel3->GetBounds().origin(); gfx::Point position4 = panel4->GetBounds().origin(); // Test the scenario: drag a panel, close another panel, cancel the drag. { std::vector panels; gfx::Point panel1_new_position = position1; panel1_new_position.Offset(-500, 0); // Start dragging a panel. // We have: P1* P4 P3 P2 gfx::Point mouse_location = panel1->GetBounds().origin(); panel1_testing->PressLeftMouseButtonTitlebar(mouse_location); mouse_location.Offset(-500, -5); panel1_testing->DragTitlebar(mouse_location); EXPECT_TRUE(drag_controller->is_dragging()); EXPECT_EQ(panel1, drag_controller->dragging_panel()); ASSERT_EQ(4, docked_collection->num_panels()); panels = PanelManager::GetInstance()->panels(); EXPECT_EQ(panel2, panels[0]); EXPECT_EQ(panel3, panels[1]); EXPECT_EQ(panel4, panels[2]); EXPECT_EQ(panel1, panels[3]); EXPECT_EQ(position1, panel2->GetBounds().origin()); EXPECT_EQ(position2, panel3->GetBounds().origin()); EXPECT_EQ(position3, panel4->GetBounds().origin()); EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin()); // Closing another panel while dragging in progress will keep the dragging // panel intact. // We have: P1* P4 P3 CloseWindowAndWait(panel2); EXPECT_TRUE(drag_controller->is_dragging()); EXPECT_EQ(panel1, drag_controller->dragging_panel()); ASSERT_EQ(3, docked_collection->num_panels()); panels = PanelManager::GetInstance()->panels(); EXPECT_EQ(panel3, panels[0]); EXPECT_EQ(panel4, panels[1]); EXPECT_EQ(panel1, panels[2]); EXPECT_EQ(position1, panel3->GetBounds().origin()); EXPECT_EQ(position2, panel4->GetBounds().origin()); EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin()); // Cancel the drag. // We have: P4 P3 P1 panel1_testing->CancelDragTitlebar(); EXPECT_FALSE(drag_controller->is_dragging()); ASSERT_EQ(3, docked_collection->num_panels()); panels = PanelManager::GetInstance()->panels(); EXPECT_EQ(panel1, panels[0]); EXPECT_EQ(panel3, panels[1]); EXPECT_EQ(panel4, panels[2]); EXPECT_EQ(position1, panel1->GetBounds().origin()); EXPECT_EQ(position2, panel3->GetBounds().origin()); EXPECT_EQ(position3, panel4->GetBounds().origin()); } // Test the scenario: drag a panel, close another panel, end the drag. { std::vector panels; gfx::Point panel1_new_position = position1; panel1_new_position.Offset(-500, 0); // Start dragging a panel. // We have: P1* P4 P3 gfx::Point mouse_location = panel1->GetBounds().origin(); panel1_testing->PressLeftMouseButtonTitlebar(mouse_location); mouse_location.Offset(-500, -5); panel1_testing->DragTitlebar(mouse_location); EXPECT_TRUE(drag_controller->is_dragging()); EXPECT_EQ(panel1, drag_controller->dragging_panel()); ASSERT_EQ(3, docked_collection->num_panels()); panels = PanelManager::GetInstance()->panels(); EXPECT_EQ(panel3, panels[0]); EXPECT_EQ(panel4, panels[1]); EXPECT_EQ(panel1, panels[2]); EXPECT_EQ(position1, panel3->GetBounds().origin()); EXPECT_EQ(position2, panel4->GetBounds().origin()); EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin()); // Closing another panel while dragging in progress will keep the dragging // panel intact. // We have: P1* P4 CloseWindowAndWait(panel3); EXPECT_TRUE(drag_controller->is_dragging()); EXPECT_EQ(panel1, drag_controller->dragging_panel()); ASSERT_EQ(2, docked_collection->num_panels()); panels = PanelManager::GetInstance()->panels(); EXPECT_EQ(panel4, panels[0]); EXPECT_EQ(panel1, panels[1]); EXPECT_EQ(position1, panel4->GetBounds().origin()); EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin()); // Finish the drag. // We have: P1 P4 panel1_testing->FinishDragTitlebar(); EXPECT_FALSE(drag_controller->is_dragging()); ASSERT_EQ(2, docked_collection->num_panels()); panels = PanelManager::GetInstance()->panels(); EXPECT_EQ(panel4, panels[0]); EXPECT_EQ(panel1, panels[1]); EXPECT_EQ(position1, panel4->GetBounds().origin()); EXPECT_EQ(position2, panel1->GetBounds().origin()); } // Test the scenario: drag a panel and close the dragging panel. { std::vector panels; gfx::Point panel1_new_position = position2; panel1_new_position.Offset(-500, 0); // Start dragging a panel again. // We have: P1* P4 gfx::Point mouse_location = panel1->GetBounds().origin(); panel1_testing->PressLeftMouseButtonTitlebar(mouse_location); mouse_location.Offset(-500, -5); panel1_testing->DragTitlebar(mouse_location); EXPECT_TRUE(drag_controller->is_dragging()); EXPECT_EQ(panel1, drag_controller->dragging_panel()); EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin()); ASSERT_EQ(2, docked_collection->num_panels()); panels = PanelManager::GetInstance()->panels(); EXPECT_EQ(panel4, panels[0]); EXPECT_EQ(panel1, panels[1]); EXPECT_EQ(position1, panel4->GetBounds().origin()); // Closing the dragging panel should make the drag controller abort. // We have: P4 content::WindowedNotificationObserver signal( chrome::NOTIFICATION_PANEL_CLOSED, content::Source(panel1)); panel1->Close(); EXPECT_FALSE(drag_controller->is_dragging()); // Continue the drag to ensure the drag controller does not crash. panel1_new_position.Offset(20, 30); panel1_testing->DragTitlebar(panel1_new_position); panel1_testing->FinishDragTitlebar(); // Wait till the panel is fully closed. signal.Wait(); ASSERT_EQ(1, docked_collection->num_panels()); panels = PanelManager::GetInstance()->panels(); EXPECT_EQ(panel4, panels[0]); EXPECT_EQ(position1, panel4->GetBounds().origin()); } panel_manager->CloseAll(); } // http://crbug.com/175760; several panel tests failing regularly on mac. #if defined(OS_MACOSX) #define MAYBE_DragOneDetachedPanel DISABLED_DragOneDetachedPanel #else #define MAYBE_DragOneDetachedPanel DragOneDetachedPanel #endif IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, MAYBE_DragOneDetachedPanel) { Panel* panel = CreateDetachedPanel("1", gfx::Rect(300, 200, 250, 200)); // Test that the detached panel can be dragged almost anywhere except getting // close to the bottom of the docked area to trigger the attach. scoped_ptr panel_testing( CreateNativePanelTesting(panel)); gfx::Point origin = panel->GetBounds().origin(); panel_testing->PressLeftMouseButtonTitlebar(origin); EXPECT_EQ(origin, panel->GetBounds().origin()); origin.Offset(-51, -102); panel_testing->DragTitlebar(origin); EXPECT_EQ(origin, panel->GetBounds().origin()); origin.Offset(37, 45); panel_testing->DragTitlebar(origin); EXPECT_EQ(origin, panel->GetBounds().origin()); panel_testing->FinishDragTitlebar(); EXPECT_EQ(origin, panel->GetBounds().origin()); // Test that cancelling the drag will return the panel the the original // position. gfx::Point original_position = panel->GetBounds().origin(); origin = original_position; panel_testing->PressLeftMouseButtonTitlebar(origin); EXPECT_EQ(origin, panel->GetBounds().origin()); origin.Offset(-51, -102); panel_testing->DragTitlebar(origin); EXPECT_EQ(origin, panel->GetBounds().origin()); origin.Offset(37, 45); panel_testing->DragTitlebar(origin); EXPECT_EQ(origin, panel->GetBounds().origin()); panel_testing->CancelDragTitlebar(); WaitForBoundsAnimationFinished(panel); EXPECT_EQ(original_position, panel->GetBounds().origin()); PanelManager::GetInstance()->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, CloseDetachedPanelOnDrag) { PanelManager* panel_manager = PanelManager::GetInstance(); PanelDragController* drag_controller = panel_manager->drag_controller(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create 1 detached panel. Panel* panel1 = CreateDetachedPanel("1", gfx::Rect(100, 200, 100, 100)); ASSERT_EQ(1, detached_collection->num_panels()); scoped_ptr panel1_testing( CreateNativePanelTesting(panel1)); gfx::Point panel1_old_position = panel1->GetBounds().origin(); // Test the scenario: drag a panel, close another panel, cancel the drag. { // Create a panel to be closed. Panel* panel2 = CreateDetachedPanel("2", gfx::Rect(300, 210, 110, 110)); // Start dragging a panel. panel1_testing->PressLeftMouseButtonTitlebar(panel1->GetBounds().origin()); gfx::Point panel1_new_position = panel1_old_position; panel1_new_position.Offset(-51, -102); panel1_testing->DragTitlebar(panel1_new_position); EXPECT_TRUE(drag_controller->is_dragging()); EXPECT_EQ(panel1, drag_controller->dragging_panel()); ASSERT_EQ(2, detached_collection->num_panels()); EXPECT_TRUE(detached_collection->HasPanel(panel1)); EXPECT_TRUE(detached_collection->HasPanel(panel2)); EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin()); // Closing another panel while dragging in progress will keep the dragging // panel intact. CloseWindowAndWait(panel2); EXPECT_TRUE(drag_controller->is_dragging()); EXPECT_EQ(panel1, drag_controller->dragging_panel()); ASSERT_EQ(1, detached_collection->num_panels()); EXPECT_TRUE(detached_collection->HasPanel(panel1)); EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin()); // Cancel the drag. panel1_testing->CancelDragTitlebar(); WaitForBoundsAnimationFinished(panel1); EXPECT_FALSE(drag_controller->is_dragging()); EXPECT_EQ(panel1_old_position, panel1->GetBounds().origin()); } // Test the scenario: drag a panel, close another panel, end the drag. { // Create a panel to be closed. Panel* panel2 = CreateDetachedPanel("2", gfx::Rect(300, 210, 110, 110)); // Start dragging a panel. panel1_testing->PressLeftMouseButtonTitlebar(panel1->GetBounds().origin()); gfx::Point panel1_new_position = panel1_old_position; panel1_new_position.Offset(-51, -102); panel1_testing->DragTitlebar(panel1_new_position); EXPECT_TRUE(drag_controller->is_dragging()); EXPECT_EQ(panel1, drag_controller->dragging_panel()); ASSERT_EQ(2, detached_collection->num_panels()); EXPECT_TRUE(detached_collection->HasPanel(panel1)); EXPECT_TRUE(detached_collection->HasPanel(panel2)); EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin()); // Closing another panel while dragging in progress will keep the dragging // panel intact. CloseWindowAndWait(panel2); EXPECT_TRUE(drag_controller->is_dragging()); EXPECT_EQ(panel1, drag_controller->dragging_panel()); ASSERT_EQ(1, detached_collection->num_panels()); EXPECT_TRUE(detached_collection->HasPanel(panel1)); EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin()); // Finish the drag. panel1_testing->FinishDragTitlebar(); EXPECT_FALSE(drag_controller->is_dragging()); EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin()); } // Test the scenario: drag a panel and close the dragging panel. { // Start dragging a panel again. panel1_testing->PressLeftMouseButtonTitlebar(panel1->GetBounds().origin()); gfx::Point panel1_new_position = panel1->GetBounds().origin(); panel1_new_position.Offset(45, 67); panel1_testing->DragTitlebar(panel1_new_position); EXPECT_TRUE(drag_controller->is_dragging()); EXPECT_EQ(panel1, drag_controller->dragging_panel()); ASSERT_EQ(1, detached_collection->num_panels()); EXPECT_TRUE(detached_collection->HasPanel(panel1)); EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin()); // Closing the dragging panel should make the drag controller abort. content::WindowedNotificationObserver signal( chrome::NOTIFICATION_PANEL_CLOSED, content::Source(panel1)); panel1->Close(); EXPECT_FALSE(drag_controller->is_dragging()); // Continue the drag to ensure the drag controller does not crash. panel1_new_position.Offset(20, 30); panel1_testing->DragTitlebar(panel1_new_position); panel1_testing->FinishDragTitlebar(); // Wait till the panel is fully closed. signal.Wait(); ASSERT_EQ(0, detached_collection->num_panels()); } } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, Detach) { PanelManager* panel_manager = PanelManager::GetInstance(); DockedPanelCollection* docked_collection = panel_manager->docked_collection(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create one docked panel. Panel* panel = CreateDockedPanel("1", gfx::Rect(0, 0, 100, 100)); ASSERT_EQ(1, docked_collection->num_panels()); ASSERT_EQ(0, detached_collection->num_panels()); gfx::Rect panel_old_bounds = panel->GetBounds(); // Press on title-bar. scoped_ptr panel_testing( CreateNativePanelTesting(panel)); gfx::Point mouse_location(panel->GetBounds().origin()); panel_testing->PressLeftMouseButtonTitlebar(mouse_location); // Drag up the panel in a small offset that does not trigger the detach. // Expect that the panel is still docked and only x coordinate of its position // is changed. gfx::Vector2d drag_delta_to_remain_docked = GetDragDeltaToRemainDocked(); mouse_location = mouse_location + drag_delta_to_remain_docked; panel_testing->DragTitlebar(mouse_location); ASSERT_EQ(1, docked_collection->num_panels()); ASSERT_EQ(0, detached_collection->num_panels()); EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type()); gfx::Rect panel_new_bounds = panel_old_bounds; panel_new_bounds.Offset(drag_delta_to_remain_docked.x(), 0); EXPECT_EQ(panel_new_bounds, panel->GetBounds()); // Continue dragging up the panel in big offset that triggers the detach. // Expect that the panel is previewed as detached. gfx::Vector2d drag_delta_to_detach = GetDragDeltaToDetach(); mouse_location = mouse_location + drag_delta_to_detach; panel_testing->DragTitlebar(mouse_location); ASSERT_EQ(0, docked_collection->num_panels()); ASSERT_EQ(1, detached_collection->num_panels()); EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type()); panel_new_bounds.Offset( drag_delta_to_detach.x(), drag_delta_to_detach.y() + drag_delta_to_remain_docked.y()); EXPECT_EQ(panel_new_bounds, panel->GetBounds()); // Finish the drag. // Expect that the panel stays as detached. panel_testing->FinishDragTitlebar(); ASSERT_EQ(0, docked_collection->num_panels()); ASSERT_EQ(1, detached_collection->num_panels()); EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type()); EXPECT_EQ(panel_new_bounds, panel->GetBounds()); panel_manager->CloseAll(); } // http://crbug.com/175760; several panel tests failing regularly on mac. #if defined(OS_MACOSX) #define MAYBE_DetachAndCancel DISABLED_DetachAndCancel #else #define MAYBE_DetachAndCancel DetachAndCancel #endif IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, MAYBE_DetachAndCancel) { PanelManager* panel_manager = PanelManager::GetInstance(); DockedPanelCollection* docked_collection = panel_manager->docked_collection(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create one docked panel. Panel* panel = CreateDockedPanel("1", gfx::Rect(0, 0, 100, 100)); ASSERT_EQ(1, docked_collection->num_panels()); ASSERT_EQ(0, detached_collection->num_panels()); gfx::Rect panel_old_bounds = panel->GetBounds(); // Press on title-bar. scoped_ptr panel_testing( CreateNativePanelTesting(panel)); gfx::Point mouse_location(panel->GetBounds().origin()); panel_testing->PressLeftMouseButtonTitlebar(mouse_location); // Drag up the panel in a small offset that does not trigger the detach. // Expect that the panel is still docked and only x coordinate of its position // is changed. gfx::Vector2d drag_delta_to_remain_docked = GetDragDeltaToRemainDocked(); mouse_location = mouse_location + drag_delta_to_remain_docked; panel_testing->DragTitlebar(mouse_location); ASSERT_EQ(1, docked_collection->num_panels()); ASSERT_EQ(0, detached_collection->num_panels()); EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type()); gfx::Rect panel_new_bounds = panel_old_bounds; panel_new_bounds.Offset(drag_delta_to_remain_docked.x(), 0); EXPECT_EQ(panel_new_bounds, panel->GetBounds()); // Continue dragging up the panel in big offset that triggers the detach. // Expect that the panel is previewed as detached. gfx::Vector2d drag_delta_to_detach = GetDragDeltaToDetach(); mouse_location = mouse_location + drag_delta_to_detach; panel_testing->DragTitlebar(mouse_location); ASSERT_EQ(0, docked_collection->num_panels()); ASSERT_EQ(1, detached_collection->num_panels()); EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type()); panel_new_bounds.Offset( drag_delta_to_detach.x(), drag_delta_to_detach.y() + drag_delta_to_remain_docked.y()); EXPECT_EQ(panel_new_bounds, panel->GetBounds()); // Cancel the drag. // Expect that the panel is back as docked. panel_testing->CancelDragTitlebar(); ASSERT_EQ(1, docked_collection->num_panels()); ASSERT_EQ(0, detached_collection->num_panels()); EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type()); EXPECT_EQ(panel_old_bounds, panel->GetBounds()); panel_manager->CloseAll(); } // http://crbug.com/175760; several panel tests failing regularly on mac. #if defined(OS_MACOSX) #define MAYBE_Attach DISABLED_Attach #else #define MAYBE_Attach Attach #endif IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, MAYBE_Attach) { PanelManager* panel_manager = PanelManager::GetInstance(); DockedPanelCollection* docked_collection = panel_manager->docked_collection(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create one detached panel. Panel* panel = CreateDetachedPanel("1", gfx::Rect(400, 300, 100, 100)); ASSERT_EQ(0, docked_collection->num_panels()); ASSERT_EQ(1, detached_collection->num_panels()); EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type()); gfx::Rect panel_old_bounds = panel->GetBounds(); // Press on title-bar. scoped_ptr panel_testing( CreateNativePanelTesting(panel)); gfx::Point mouse_location(panel->GetBounds().origin()); panel_testing->PressLeftMouseButtonTitlebar(mouse_location); // Drag down the panel but not close enough to the bottom of work area. // Expect that the panel is still detached. gfx::Vector2d drag_delta_to_remain_detached = GetDragDeltaToRemainDetached(panel); mouse_location = mouse_location + drag_delta_to_remain_detached; panel_testing->DragTitlebar(mouse_location); ASSERT_EQ(0, docked_collection->num_panels()); ASSERT_EQ(1, detached_collection->num_panels()); EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type()); gfx::Rect panel_new_bounds = panel_old_bounds; panel_new_bounds.Offset(drag_delta_to_remain_detached); EXPECT_EQ(panel_new_bounds, panel->GetBounds()); // Continue dragging down the panel to make it close enough to the bottom of // work area. // Expect that the panel is previewed as docked. gfx::Vector2d drag_delta_to_attach = GetDragDeltaToAttach(panel); mouse_location = mouse_location + drag_delta_to_attach; panel_testing->DragTitlebar(mouse_location); ASSERT_EQ(1, docked_collection->num_panels()); ASSERT_EQ(0, detached_collection->num_panels()); EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type()); panel_new_bounds.Offset(drag_delta_to_attach); EXPECT_EQ(panel_new_bounds, panel->GetBounds()); // Finish the drag. // Expect that the panel stays as docked and moves to the final position. panel_testing->FinishDragTitlebar(); ASSERT_EQ(1, docked_collection->num_panels()); ASSERT_EQ(0, detached_collection->num_panels()); EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type()); panel_new_bounds.set_x( docked_collection->StartingRightPosition() - panel_new_bounds.width()); panel_new_bounds.set_y( docked_collection->work_area().bottom() - panel_new_bounds.height()); EXPECT_EQ(panel_new_bounds, panel->GetBounds()); panel_manager->CloseAll(); } // http://crbug.com/175760; several panel tests failing regularly on mac. #if defined(OS_MACOSX) #define MAYBE_AttachAndCancel DISABLED_AttachAndCancel #else #define MAYBE_AttachAndCancel AttachAndCancel #endif IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, MAYBE_AttachAndCancel) { PanelManager* panel_manager = PanelManager::GetInstance(); DockedPanelCollection* docked_collection = panel_manager->docked_collection(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create one detached panel. Panel* panel = CreateDetachedPanel("1", gfx::Rect(400, 300, 100, 100)); ASSERT_EQ(0, docked_collection->num_panels()); ASSERT_EQ(1, detached_collection->num_panels()); EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type()); gfx::Rect panel_old_bounds = panel->GetBounds(); // Press on title-bar. scoped_ptr panel_testing( CreateNativePanelTesting(panel)); gfx::Point mouse_location(panel->GetBounds().origin()); panel_testing->PressLeftMouseButtonTitlebar(mouse_location); // Drag down the panel but not close enough to the bottom of work area. // Expect that the panel is still detached. gfx::Vector2d drag_delta_to_remain_detached = GetDragDeltaToRemainDetached(panel); mouse_location = mouse_location + drag_delta_to_remain_detached; panel_testing->DragTitlebar(mouse_location); ASSERT_EQ(0, docked_collection->num_panels()); ASSERT_EQ(1, detached_collection->num_panels()); EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type()); gfx::Rect panel_new_bounds = panel_old_bounds; panel_new_bounds.Offset(drag_delta_to_remain_detached); EXPECT_EQ(panel_new_bounds, panel->GetBounds()); // Continue dragging down the panel to make it close enough to the bottom of // work area. // Expect that the panel is previewed as docked. gfx::Vector2d drag_delta_to_attach = GetDragDeltaToAttach(panel); mouse_location = mouse_location + drag_delta_to_attach; panel_testing->DragTitlebar(mouse_location); ASSERT_EQ(1, docked_collection->num_panels()); ASSERT_EQ(0, detached_collection->num_panels()); EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type()); panel_new_bounds.Offset(drag_delta_to_attach); EXPECT_EQ(panel_new_bounds, panel->GetBounds()); // Cancel the drag. // Expect that the panel is back as detached. panel_testing->CancelDragTitlebar(); ASSERT_EQ(0, docked_collection->num_panels()); ASSERT_EQ(1, detached_collection->num_panels()); EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type()); EXPECT_EQ(panel_old_bounds, panel->GetBounds()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DetachAttachAndCancel) { PanelManager* panel_manager = PanelManager::GetInstance(); DockedPanelCollection* docked_collection = panel_manager->docked_collection(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create one docked panel. Panel* panel = CreateDockedPanel("1", gfx::Rect(0, 0, 100, 100)); ASSERT_EQ(1, docked_collection->num_panels()); ASSERT_EQ(0, detached_collection->num_panels()); gfx::Rect panel_old_bounds = panel->GetBounds(); // Press on title-bar. scoped_ptr panel_testing( CreateNativePanelTesting(panel)); gfx::Point mouse_location(panel->GetBounds().origin()); panel_testing->PressLeftMouseButtonTitlebar(mouse_location); // Drag up the panel to trigger the detach. // Expect that the panel is previewed as detached. gfx::Vector2d drag_delta_to_detach = GetDragDeltaToDetach(); mouse_location = mouse_location + drag_delta_to_detach; panel_testing->DragTitlebar(mouse_location); ASSERT_EQ(0, docked_collection->num_panels()); ASSERT_EQ(1, detached_collection->num_panels()); EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type()); gfx::Rect panel_new_bounds = panel_old_bounds; panel_new_bounds.Offset(drag_delta_to_detach); EXPECT_EQ(panel_new_bounds, panel->GetBounds()); // Continue dragging down the panel to trigger the re-attach. gfx::Vector2d drag_delta_to_reattach = GetDragDeltaToAttach(panel); mouse_location = mouse_location + drag_delta_to_reattach; panel_testing->DragTitlebar(mouse_location); ASSERT_EQ(1, docked_collection->num_panels()); ASSERT_EQ(0, detached_collection->num_panels()); EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type()); panel_new_bounds.Offset(drag_delta_to_reattach); EXPECT_EQ(panel_new_bounds, panel->GetBounds()); // Continue dragging up the panel to trigger the detach again. gfx::Vector2d drag_delta_to_detach_again = GetDragDeltaToDetach(); mouse_location = mouse_location + drag_delta_to_detach_again; panel_testing->DragTitlebar(mouse_location); ASSERT_EQ(0, docked_collection->num_panels()); ASSERT_EQ(1, detached_collection->num_panels()); EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type()); panel_new_bounds.Offset(drag_delta_to_detach_again); EXPECT_EQ(panel_new_bounds, panel->GetBounds()); // Cancel the drag. // Expect that the panel stays as docked. panel_testing->CancelDragTitlebar(); ASSERT_EQ(1, docked_collection->num_panels()); ASSERT_EQ(0, detached_collection->num_panels()); EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type()); EXPECT_EQ(panel_old_bounds, panel->GetBounds()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DetachWithSqueeze) { PanelManager* panel_manager = PanelManager::GetInstance(); DockedPanelCollection* docked_collection = panel_manager->docked_collection(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create some docked panels. // docked: P1 P2 P3 P4 P5 Panel* panel1 = CreateDockedPanel("1", gfx::Rect(0, 0, 200, 100)); Panel* panel2 = CreateDockedPanel("2", gfx::Rect(0, 0, 200, 100)); Panel* panel3 = CreateDockedPanel("3", gfx::Rect(0, 0, 200, 100)); Panel* panel4 = CreateDockedPanel("4", gfx::Rect(0, 0, 200, 100)); Panel* panel5 = CreateDockedPanel("5", gfx::Rect(0, 0, 200, 100)); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(5, docked_collection->num_panels()); // Drag to detach the middle docked panel. // Expect to have: // detached: P2 // docked: P1 P3 P4 P5 gfx::Point panel2_docked_position = panel2->GetBounds().origin(); gfx::Vector2d drag_delta_to_detach_panel2(-20, -100); DragPanelByDelta(panel2, drag_delta_to_detach_panel2); ASSERT_EQ(1, detached_collection->num_panels()); ASSERT_EQ(4, docked_collection->num_panels()); EXPECT_EQ(PanelCollection::DOCKED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type()); EXPECT_EQ(PanelCollection::DOCKED, panel3->collection()->type()); EXPECT_EQ(PanelCollection::DOCKED, panel4->collection()->type()); EXPECT_EQ(PanelCollection::DOCKED, panel5->collection()->type()); gfx::Point panel2_new_position = panel2_docked_position + drag_delta_to_detach_panel2; EXPECT_EQ(panel2_new_position, panel2->GetBounds().origin()); // Drag to detach the left-most docked panel. // Expect to have: // detached: P2 P4 // docked: P1 P3 P5 gfx::Point panel4_docked_position = panel4->GetBounds().origin(); gfx::Vector2d drag_delta_to_detach_panel4(-40, -250); DragPanelByDelta(panel4, drag_delta_to_detach_panel4); ASSERT_EQ(2, detached_collection->num_panels()); ASSERT_EQ(3, docked_collection->num_panels()); EXPECT_EQ(PanelCollection::DOCKED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type()); EXPECT_EQ(PanelCollection::DOCKED, panel3->collection()->type()); EXPECT_EQ(PanelCollection::DETACHED, panel4->collection()->type()); EXPECT_EQ(PanelCollection::DOCKED, panel5->collection()->type()); EXPECT_EQ(panel2_new_position, panel2->GetBounds().origin()); gfx::Point panel4_new_position = panel4_docked_position + drag_delta_to_detach_panel4; EXPECT_EQ(panel4_new_position, panel4->GetBounds().origin()); // Drag to detach the right-most docked panel. // Expect to have: // detached: P1 P2 P4 // docked: P3 P5 gfx::Point docked_position1 = panel1->GetBounds().origin(); gfx::Point docked_position2 = panel3->GetBounds().origin(); gfx::Vector2d drag_delta_to_detach_panel1(-60, -400); DragPanelByDelta(panel1, drag_delta_to_detach_panel1); ASSERT_EQ(3, detached_collection->num_panels()); ASSERT_EQ(2, docked_collection->num_panels()); EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type()); EXPECT_EQ(PanelCollection::DOCKED, panel3->collection()->type()); EXPECT_EQ(PanelCollection::DETACHED, panel4->collection()->type()); EXPECT_EQ(PanelCollection::DOCKED, panel5->collection()->type()); gfx::Point panel1_new_position = docked_position1 + drag_delta_to_detach_panel1; EXPECT_EQ(panel1_new_position, panel1->GetBounds().origin()); EXPECT_EQ(panel2_new_position, panel2->GetBounds().origin()); EXPECT_EQ(panel4_new_position, panel4->GetBounds().origin()); // No more squeeze, docked panels should stay put. EXPECT_EQ(docked_position1, panel3->GetBounds().origin()); EXPECT_EQ(panel1->GetBounds().width(), panel1->GetRestoredBounds().width()); EXPECT_EQ(docked_position2, panel5->GetBounds().origin()); EXPECT_EQ(panel2->GetBounds().width(), panel2->GetRestoredBounds().width()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, AttachWithSqueeze) { PanelManager* panel_manager = PanelManager::GetInstance(); DockedPanelCollection* docked_collection = panel_manager->docked_collection(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create some detached, docked panels. // detached: P1 P2 P3 // docked: P4 P5 P6 P7 Panel* panel1 = CreateInactiveDetachedPanel( "1", gfx::Rect(100, 300, 200, 100)); Panel* panel2 = CreateInactiveDetachedPanel( "2", gfx::Rect(200, 300, 200, 100)); Panel* panel3 = CreateInactiveDetachedPanel( "3", gfx::Rect(400, 300, 200, 100)); Panel* panel4 = CreateInactiveDockedPanel("4", gfx::Rect(0, 0, 200, 100)); Panel* panel5 = CreateInactiveDockedPanel("5", gfx::Rect(0, 0, 200, 100)); Panel* panel6 = CreateInactiveDockedPanel("6", gfx::Rect(0, 0, 200, 100)); Panel* panel7 = CreateDockedPanel("7", gfx::Rect(0, 0, 200, 100)); ASSERT_EQ(3, detached_collection->num_panels()); ASSERT_EQ(4, docked_collection->num_panels()); // Wait for active states to settle. PanelCollectionSqueezeObserver panel7_settled(docked_collection, panel7); panel7_settled.Wait(); gfx::Point detached_position1 = panel1->GetBounds().origin(); gfx::Point detached_position2 = panel2->GetBounds().origin(); gfx::Point detached_position3 = panel3->GetBounds().origin(); gfx::Point docked_position4 = panel4->GetBounds().origin(); gfx::Point docked_position5 = panel5->GetBounds().origin(); gfx::Point docked_position6 = panel6->GetBounds().origin(); gfx::Point docked_position7 = panel7->GetBounds().origin(); // Drag to attach a detached panel between 2 docked panels. // Expect to have: // detached: P1 P2 // docked: P4 P3 P5 P6 P7 gfx::Point drag_to_location(panel5->GetBounds().x() + 10, panel5->GetBounds().y()); DragPanelToMouseLocation(panel3, drag_to_location); ASSERT_EQ(2, detached_collection->num_panels()); ASSERT_EQ(5, docked_collection->num_panels()); EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type()); EXPECT_EQ(PanelCollection::DOCKED, panel3->collection()->type()); EXPECT_EQ(PanelCollection::DOCKED, panel4->collection()->type()); EXPECT_EQ(PanelCollection::DOCKED, panel5->collection()->type()); EXPECT_EQ(PanelCollection::DOCKED, panel6->collection()->type()); EXPECT_EQ(PanelCollection::DOCKED, panel7->collection()->type()); EXPECT_EQ(detached_position1, panel1->GetBounds().origin()); EXPECT_EQ(detached_position2, panel2->GetBounds().origin()); // Wait for active states to settle. base::MessageLoopForUI::current()->RunUntilIdle(); // Panel positions should have shifted because of the "squeeze" mode. EXPECT_NE(docked_position4, panel4->GetBounds().origin()); EXPECT_LT(panel4->GetBounds().width(), panel4->GetRestoredBounds().width()); EXPECT_NE(docked_position5, panel5->GetBounds().origin()); EXPECT_LT(panel5->GetBounds().width(), panel5->GetRestoredBounds().width()); #if defined(OS_WIN) // The panel we dragged becomes the active one. EXPECT_EQ(true, panel3->IsActive()); EXPECT_EQ(panel3->GetBounds().width(), panel3->GetRestoredBounds().width()); EXPECT_NE(docked_position6, panel6->GetBounds().origin()); #else // The last panel is active so these positions do not change. // TODO (ABurago) this is wrong behavior, a panel should activate // when it is dragged (it does in real usage, but not when drag is // simulated in a test). Change this test when the behavior is fixed. EXPECT_EQ(true, panel7->IsActive()); EXPECT_EQ(panel7->GetBounds().width(), panel7->GetRestoredBounds().width()); EXPECT_EQ(docked_position6, panel6->GetBounds().origin()); #endif EXPECT_EQ(docked_position7, panel7->GetBounds().origin()); // Drag to attach a detached panel to most-right. // Expect to have: // detached: P1 // docked: P2 P4 P3 P5 P6 P7 gfx::Point drag_to_location2(panel4->GetBounds().right() + 10, panel4->GetBounds().y()); DragPanelToMouseLocation(panel2, drag_to_location2); ASSERT_EQ(1, detached_collection->num_panels()); ASSERT_EQ(6, docked_collection->num_panels()); EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::DOCKED, panel2->collection()->type()); EXPECT_EQ(PanelCollection::DOCKED, panel3->collection()->type()); EXPECT_EQ(PanelCollection::DOCKED, panel4->collection()->type()); EXPECT_EQ(PanelCollection::DOCKED, panel5->collection()->type()); EXPECT_EQ(PanelCollection::DOCKED, panel6->collection()->type()); EXPECT_EQ(PanelCollection::DOCKED, panel7->collection()->type()); EXPECT_EQ(detached_position1, panel1->GetBounds().origin()); // Drag to attach a detached panel to most-left. // Expect to have: // docked: P2 P4 P1 P3 P5 P6 P7 gfx::Point drag_to_location3(panel3->GetBounds().x() - 10, panel3->GetBounds().y()); DragPanelToMouseLocation(panel1, drag_to_location3); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(7, docked_collection->num_panels()); EXPECT_EQ(PanelCollection::DOCKED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::DOCKED, panel2->collection()->type()); EXPECT_EQ(PanelCollection::DOCKED, panel3->collection()->type()); EXPECT_EQ(PanelCollection::DOCKED, panel4->collection()->type()); EXPECT_EQ(PanelCollection::DOCKED, panel5->collection()->type()); EXPECT_EQ(PanelCollection::DOCKED, panel6->collection()->type()); EXPECT_EQ(PanelCollection::DOCKED, panel7->collection()->type()); panel_manager->CloseAll(); } // http://crbug.com/175760; several panel tests failing regularly on mac. #if defined(OS_MACOSX) #define MAYBE_DragDetachedPanelToTop DISABLED_DragDetachedPanelToTop #else #define MAYBE_DragDetachedPanelToTop DragDetachedPanelToTop #endif IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, MAYBE_DragDetachedPanelToTop) { // Setup the test areas to have top-aligned bar excluded from work area. const gfx::Rect primary_display_area(0, 0, 800, 600); const gfx::Rect primary_work_area(0, 10, 800, 590); mock_display_settings_provider()->SetPrimaryDisplay( primary_display_area, primary_work_area); PanelManager* panel_manager = PanelManager::GetInstance(); Panel* panel = CreateDetachedPanel("1", gfx::Rect(300, 200, 250, 200)); // Drag up the panel. Expect that the panel should not go outside the top of // the work area. gfx::Point drag_to_location(250, 0); DragPanelToMouseLocation(panel, drag_to_location); EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type()); EXPECT_EQ(drag_to_location.x(), panel->GetBounds().origin().x()); EXPECT_EQ(primary_work_area.y(), panel->GetBounds().origin().y()); // Drag down the panel. Expect that the panel can be dragged without // constraint. drag_to_location = gfx::Point(280, 150); DragPanelToMouseLocation(panel, drag_to_location); EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type()); EXPECT_EQ(drag_to_location, panel->GetBounds().origin()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DragDockedPanelToSecondaryDisplay) { // Setup 2 displays with secondary display on the right side of primary // display. mock_display_settings_provider()->SetPrimaryDisplay( gfx::Rect(0, 0, 400, 600), gfx::Rect(0, 0, 400, 560)); gfx::Rect secondary_display_area(400, 100, 400, 500); mock_display_settings_provider()->SetSecondaryDisplay( secondary_display_area, secondary_display_area); // Create a docked panel. gfx::Size panel_size(100, 100); Panel* panel = CreateDockedPanel("1", gfx::Rect(gfx::Point(), panel_size)); EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type()); // Drag the panel to the secondary display horizontally. // Expected that the panel should become detached. gfx::Point drag_to_location(secondary_display_area.x() + 100, panel->GetBounds().y()); DragPanelToMouseLocation(panel, drag_to_location); EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type()); gfx::Rect expected_bounds(drag_to_location, panel_size); EXPECT_EQ(expected_bounds, panel->GetBounds()); PanelManager::GetInstance()->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DragDetachedPanelToSecondaryDisplay) { // Setup 2 displays with secondary display at the bottom of primary display. mock_display_settings_provider()->SetPrimaryDisplay( gfx::Rect(0, 0, 800, 300), gfx::Rect(0, 0, 800, 260)); gfx::Rect secondary_display_area(100, 300, 700, 250); mock_display_settings_provider()->SetSecondaryDisplay( secondary_display_area, secondary_display_area); // Create a detached panel on the primary display. gfx::Rect initial_panel_bounds(300, 50, 100, 100); Panel* panel = CreateDetachedPanel("1", initial_panel_bounds); EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type()); EXPECT_EQ(initial_panel_bounds, panel->GetBounds()); // Drag down the panel to the secondary display vertically. // Expected that the panel should remain detached. gfx::Point drag_to_location(initial_panel_bounds.x(), secondary_display_area.y() + 100); DragPanelToMouseLocation(panel, drag_to_location); EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type()); gfx::Rect expected_bounds(drag_to_location, initial_panel_bounds.size()); EXPECT_EQ(expected_bounds, panel->GetBounds()); PanelManager::GetInstance()->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupPanelAndPanelFromBottom) { PanelManager* panel_manager = PanelManager::GetInstance(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create two detached panels. Panel* panel1 = CreateDetachedPanel("1", gfx::Rect(300, 200, 200, 100)); Panel* panel2 = CreateDetachedPanel("2", gfx::Rect(100, 100, 150, 150)); ASSERT_EQ(2, detached_collection->num_panels()); ASSERT_EQ(0, panel_manager->num_stacks()); EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type()); gfx::Rect panel1_old_bounds = panel1->GetBounds(); gfx::Rect panel2_old_bounds = panel2->GetBounds(); // Press on title-bar of P2. scoped_ptr panel2_testing( CreateNativePanelTesting(panel2)); gfx::Point mouse_location(panel2->GetBounds().origin()); gfx::Point original_mouse_location = mouse_location; panel2_testing->PressLeftMouseButtonTitlebar(mouse_location); // Drag P2 close to the bottom of P1 to trigger the stacking. Expect: // 1) P1 and P2 form a stack. // 2) P2 jumps vertcially to align to the bottom edge of P1. // 3) P2 moves horizontally by the dragging delta. // 4) The width of P2 remains unchanged. gfx::Vector2d drag_delta_to_stack = GetDragDeltaToStackToBottom(panel2, panel1); mouse_location = mouse_location + drag_delta_to_stack; panel2_testing->DragTitlebar(mouse_location); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type()); EXPECT_EQ(panel1_old_bounds, panel1->GetBounds()); gfx::Rect panel2_new_bounds(panel2_old_bounds.x() + drag_delta_to_stack.x(), panel1_old_bounds.bottom(), panel2_old_bounds.width(), panel2_old_bounds.height()); EXPECT_EQ(panel2_new_bounds, panel2->GetBounds()); // Drag P2 somewhat away from the bottom of P1 to trigger the unstacking. // Expect P1 and P2 become detached. gfx::Vector2d drag_delta_to_unstack = GetDragDeltaToUnstackFromBottom(panel2, panel1); mouse_location = mouse_location + drag_delta_to_unstack; panel2_testing->DragTitlebar(mouse_location); ASSERT_EQ(2, detached_collection->num_panels()); ASSERT_EQ(0, panel_manager->num_stacks()); EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type()); EXPECT_EQ(panel1_old_bounds, panel1->GetBounds()); panel2_new_bounds.set_origin(panel2_old_bounds.origin()); panel2_new_bounds.Offset(mouse_location - original_mouse_location); EXPECT_EQ(panel2_new_bounds, panel2->GetBounds()); // Drag P2 close to the bottom of P1 to trigger the stacking again. Expect: // 1) P1 and P2 form a stack. // 2) P2 jumps vertcially to align to the bottom edge of P1. // 3) P2 moves horizontally by the dragging delta. // 4) The width of P2 remains unchanged. drag_delta_to_stack = GetDragDeltaToStackToBottom(panel2, panel1); mouse_location = mouse_location + drag_delta_to_stack; panel2_testing->DragTitlebar(mouse_location); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type()); EXPECT_EQ(panel1_old_bounds, panel1->GetBounds()); panel2_new_bounds.set_x(panel2_new_bounds.x() + drag_delta_to_stack.x()); panel2_new_bounds.set_y(panel1_old_bounds.bottom()); EXPECT_EQ(panel2_new_bounds, panel2->GetBounds()); // Move the mouse a little bit. Expect P2 only moves horizontally. P2 should // not move vertically since its top edge already glues to the bottom edge // of P1. gfx::Vector2d small_delta(1, -1); mouse_location = mouse_location + small_delta; panel2_testing->DragTitlebar(mouse_location); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type()); EXPECT_EQ(panel1_old_bounds, panel1->GetBounds()); panel2_new_bounds.set_x(panel2_new_bounds.x() + small_delta.x()); EXPECT_EQ(panel2_new_bounds, panel2->GetBounds()); // Finish the drag. Expect: // 1) P1 and P2 remain stacked. // 2) P2 moves horizontally to align with P1. // 3) The width of P2 is adjusted to be same as the one of P1. panel2_testing->FinishDragTitlebar(); WaitForBoundsAnimationFinished(panel2); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type()); EXPECT_EQ(panel1_old_bounds, panel1->GetBounds()); panel2_new_bounds.set_x(panel1_old_bounds.x()); panel2_new_bounds.set_width(panel1_old_bounds.width()); EXPECT_EQ(panel2_new_bounds, panel2->GetBounds()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupPanelAndPanelFromTop) { PanelManager* panel_manager = PanelManager::GetInstance(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create two detached panels. Panel* panel1 = CreateDetachedPanel("1", gfx::Rect(300, 300, 200, 100)); Panel* panel2 = CreateDetachedPanel("2", gfx::Rect(100, 200, 150, 150)); ASSERT_EQ(2, detached_collection->num_panels()); ASSERT_EQ(0, panel_manager->num_stacks()); EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type()); gfx::Rect panel1_old_bounds = panel1->GetBounds(); gfx::Rect panel2_old_bounds = panel2->GetBounds(); // Press on title-bar of P2. scoped_ptr panel2_testing( CreateNativePanelTesting(panel2)); gfx::Point mouse_location(panel2->GetBounds().origin()); gfx::Point original_mouse_location = mouse_location; panel2_testing->PressLeftMouseButtonTitlebar(mouse_location); // Drag P2 close to the top of P1 to trigger the stacking. Expect: // 1) P2 and P1 form a stack. // 2) P2 jumps vertcially to align to the top edge of P1. // 3) P2 moves horizontally by the dragging delta. // 4) The width of both P1 and P2 remains unchanged. gfx::Vector2d drag_delta_to_stack = GetDragDeltaToStackToTop(panel2, panel1); mouse_location = mouse_location + drag_delta_to_stack; panel2_testing->DragTitlebar(mouse_location); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type()); EXPECT_EQ(panel1_old_bounds, panel1->GetBounds()); gfx::Rect panel2_new_bounds( panel2_old_bounds.x() + drag_delta_to_stack.x(), panel1_old_bounds.y() - panel2_old_bounds.height(), panel2_old_bounds.width(), panel2_old_bounds.height()); EXPECT_EQ(panel2_new_bounds, panel2->GetBounds()); // Drag P2 somewhat away from the top of P1 to trigger the unstacking. // Expect P1 and P2 become detached. gfx::Vector2d drag_delta_to_unstack = GetDragDeltaToUnstackFromTop(panel2, panel1); mouse_location = mouse_location + drag_delta_to_unstack; panel2_testing->DragTitlebar(mouse_location); ASSERT_EQ(2, detached_collection->num_panels()); ASSERT_EQ(0, panel_manager->num_stacks()); EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type()); EXPECT_EQ(panel1_old_bounds, panel1->GetBounds()); panel2_new_bounds.set_origin(panel2_old_bounds.origin()); panel2_new_bounds.Offset(mouse_location - original_mouse_location); EXPECT_EQ(panel2_new_bounds, panel2->GetBounds()); // Drag P2 close to the top of P1 to trigger the stacking again. Expect: // 1) P2 and P1 form a stack. // 2) P2 jumps vertcially to align to the top edge of P1. // 3) P2 moves horizontally by the dragging delta. // 4) The width of both P1 and P2 remains unchanged. drag_delta_to_stack = GetDragDeltaToStackToTop(panel2, panel1); mouse_location = mouse_location + drag_delta_to_stack; panel2_testing->DragTitlebar(mouse_location); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type()); EXPECT_EQ(panel1_old_bounds, panel1->GetBounds()); panel2_new_bounds.set_x(panel2_new_bounds.x() + drag_delta_to_stack.x()); panel2_new_bounds.set_y(panel1_old_bounds.y() - panel2_old_bounds.height()); EXPECT_EQ(panel2_new_bounds, panel2->GetBounds()); // Move the mouse a little bit. Expect only P2 moves horizontally. P2 should // not move vertically because its bottom edge already glues to the top edge // of P1. gfx::Vector2d small_delta(1, -1); mouse_location = mouse_location + small_delta; panel2_testing->DragTitlebar(mouse_location); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type()); EXPECT_EQ(panel1_old_bounds, panel1->GetBounds()); panel2_new_bounds.set_x(panel2_new_bounds.x() + small_delta.x()); EXPECT_EQ(panel2_new_bounds, panel2->GetBounds()); // Finish the drag. Expect: // 1) P2 and P1 remain stacked. // 2) P2 moves horizontally to align with P1. // 3) The width of P1 is adjusted to be same as the one of P2. panel2_testing->FinishDragTitlebar(); WaitForBoundsAnimationFinished(panel1); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type()); gfx::Rect panel1_new_bounds = panel1_old_bounds; panel1_new_bounds.set_width(panel2_new_bounds.width()); EXPECT_EQ(panel1_new_bounds, panel1->GetBounds()); panel2_new_bounds.set_x(panel1_new_bounds.x()); EXPECT_EQ(panel2_new_bounds, panel2->GetBounds()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupAndCancel) { PanelManager* panel_manager = PanelManager::GetInstance(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create two detached panels. Panel* panel1 = CreateDetachedPanel("1", gfx::Rect(300, 200, 200, 100)); Panel* panel2 = CreateDetachedPanel("2", gfx::Rect(100, 100, 150, 150)); ASSERT_EQ(2, detached_collection->num_panels()); ASSERT_EQ(0, panel_manager->num_stacks()); EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type()); gfx::Rect panel1_old_bounds = panel1->GetBounds(); gfx::Rect panel2_old_bounds = panel2->GetBounds(); // Press on title-bar. scoped_ptr panel2_testing( CreateNativePanelTesting(panel2)); gfx::Point mouse_location(panel2->GetBounds().origin()); gfx::Point original_mouse_location = mouse_location; panel2_testing->PressLeftMouseButtonTitlebar(mouse_location); // Drag P2 close to the bottom of P1 to trigger the stacking. // Expect that P2 stacks to P1 and P2's width remains unchanged. gfx::Vector2d drag_delta_to_stack = GetDragDeltaToStackToBottom(panel2, panel1); mouse_location = mouse_location + drag_delta_to_stack; panel2_testing->DragTitlebar(mouse_location); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type()); EXPECT_EQ(panel1_old_bounds, panel1->GetBounds()); gfx::Rect panel2_new_bounds(panel1_old_bounds.x(), panel1_old_bounds.bottom(), panel2_old_bounds.width(), panel2_old_bounds.height()); EXPECT_EQ(panel2_new_bounds, panel2->GetBounds()); // Cancel the drag. // Expect that the P1 and P2 become detached. panel2_testing->CancelDragTitlebar(); ASSERT_EQ(2, detached_collection->num_panels()); ASSERT_EQ(0, panel_manager->num_stacks()); EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type()); EXPECT_EQ(panel1_old_bounds, panel1->GetBounds()); EXPECT_EQ(panel2_old_bounds, panel2->GetBounds()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupPanelAndStackFromBottom) { PanelManager* panel_manager = PanelManager::GetInstance(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create 2 stacked panels. StackedPanelCollection* stack = panel_manager->CreateStack(); gfx::Rect panel1_initial_bounds = gfx::Rect(100, 100, 200, 150); Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack); gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100); Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); ASSERT_EQ(2, stack->num_panels()); EXPECT_EQ(stack, panel1->collection()); EXPECT_EQ(stack, panel2->collection()); gfx::Rect panel1_expected_bounds(panel1_initial_bounds); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds( panel2_initial_bounds, panel1_expected_bounds); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Create 1 detached panel. gfx::Rect panel3_initial_bounds = gfx::Rect(300, 200, 100, 100); Panel* panel3 = CreateDetachedPanel("3", panel3_initial_bounds); ASSERT_EQ(1, detached_collection->num_panels()); gfx::Rect panel3_expected_bounds(panel3_initial_bounds); EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds()); // Drag P3 close to the bottom edge of P1 that is not the bottom panel. // Expect no stacking. gfx::Vector2d drag_delta_to_stack = GetDragDeltaToStackToBottom(panel3, panel1); DragPanelByDelta(panel3, drag_delta_to_stack); ASSERT_EQ(1, detached_collection->num_panels()); ASSERT_EQ(2, stack->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); // Drag P3 close to the bottom edge of P2 that is the bottom panel. // Expect that P3 becomes the bottom panel of the stack. drag_delta_to_stack = GetDragDeltaToStackToBottom(panel3, panel2); DragPanelByDelta(panel3, drag_delta_to_stack); WaitForBoundsAnimationFinished(panel3); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(3, stack->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); EXPECT_EQ(stack, panel1->collection()); EXPECT_EQ(stack, panel2->collection()); EXPECT_EQ(stack, panel3->collection()); EXPECT_EQ(panel3, stack->bottom_panel()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); panel3_expected_bounds = GetStackedAtBottomPanelBounds( panel3_initial_bounds, panel2_expected_bounds); EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupPanelAndStackFromTop) { PanelManager* panel_manager = PanelManager::GetInstance(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create 2 stacked panels. StackedPanelCollection* stack = panel_manager->CreateStack(); gfx::Rect panel1_initial_bounds = gfx::Rect(100, 300, 200, 150); Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack); gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100); Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); ASSERT_EQ(2, stack->num_panels()); EXPECT_EQ(stack, panel1->collection()); EXPECT_EQ(stack, panel2->collection()); gfx::Rect panel1_expected_bounds(panel1_initial_bounds); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds( panel2_initial_bounds, panel1_expected_bounds); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Create 1 detached panel. gfx::Rect panel3_initial_bounds = gfx::Rect(300, 200, 100, 100); Panel* panel3 = CreateDetachedPanel("3", panel3_initial_bounds); ASSERT_EQ(1, detached_collection->num_panels()); gfx::Rect panel3_expected_bounds(panel3_initial_bounds); EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds()); // Drag P3 close to the top edge of P2 that is not the top panel. // Expect no stacking. gfx::Vector2d drag_delta_to_stack = GetDragDeltaToStackToTop(panel3, panel2); DragPanelByDelta(panel3, drag_delta_to_stack); ASSERT_EQ(1, detached_collection->num_panels()); ASSERT_EQ(2, stack->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); // Drag P3 close to the top edge of P1 that is the top panel. // Expect that P3 becomes the top panel of the stack. drag_delta_to_stack = GetDragDeltaToStackToTop(panel3, panel1); DragPanelByDelta(panel3, drag_delta_to_stack); WaitForBoundsAnimationFinished(panel1); WaitForBoundsAnimationFinished(panel2); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(3, stack->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); EXPECT_EQ(stack, panel1->collection()); EXPECT_EQ(stack, panel2->collection()); EXPECT_EQ(stack, panel3->collection()); EXPECT_EQ(panel3, stack->top_panel()); panel3_expected_bounds = GetStackedAtTopPanelBounds( panel3_initial_bounds, panel1_expected_bounds); EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds()); panel1_expected_bounds.set_width(panel3_expected_bounds.width()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); panel2_expected_bounds.set_width(panel3_expected_bounds.width()); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupStackAndPanelFromBottom) { PanelManager* panel_manager = PanelManager::GetInstance(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create 2 stacked panels. StackedPanelCollection* stack = panel_manager->CreateStack(); gfx::Rect panel1_initial_bounds = gfx::Rect(100, 100, 200, 150); Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack); gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100); Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); ASSERT_EQ(2, stack->num_panels()); EXPECT_EQ(stack, panel1->stack()); EXPECT_EQ(stack, panel2->stack()); gfx::Rect panel1_expected_bounds(panel1_initial_bounds); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds( panel2_initial_bounds, panel1_expected_bounds); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Create 1 detached panel. gfx::Rect panel3_initial_bounds = gfx::Rect(300, 200, 100, 100); Panel* panel3 = CreateDetachedPanel("3", panel3_initial_bounds); ASSERT_EQ(1, detached_collection->num_panels()); gfx::Rect panel3_expected_bounds(panel3_initial_bounds); EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds()); // Drag P1 (together with P2) to stack to the bottom of P3. // Expect that P1 and P2 append to the bottom of P3 and all 3 panels are in // one stack. gfx::Vector2d drag_delta_to_stack = GetDragDeltaToStackToBottom(panel1, panel3); DragPanelByDelta(panel1, drag_delta_to_stack); WaitForBoundsAnimationFinished(panel1); WaitForBoundsAnimationFinished(panel2); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); StackedPanelCollection* final_stack = panel_manager->stacks().front(); ASSERT_EQ(3, final_stack->num_panels()); EXPECT_EQ(final_stack, panel1->stack()); EXPECT_EQ(final_stack, panel2->stack()); EXPECT_EQ(final_stack, panel3->stack()); EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds()); panel1_expected_bounds = GetStackedAtBottomPanelBounds( panel1_initial_bounds, panel3_expected_bounds); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); panel2_expected_bounds = GetStackedAtBottomPanelBounds( panel2_initial_bounds, panel1_expected_bounds); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupStackAndPanelFromTop) { PanelManager* panel_manager = PanelManager::GetInstance(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create 2 stacked panels. StackedPanelCollection* stack = panel_manager->CreateStack(); gfx::Rect panel1_initial_bounds = gfx::Rect(100, 100, 200, 150); Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack); gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100); Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); ASSERT_EQ(2, stack->num_panels()); EXPECT_EQ(stack, panel1->stack()); EXPECT_EQ(stack, panel2->stack()); gfx::Rect panel1_expected_bounds(panel1_initial_bounds); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds( panel2_initial_bounds, panel1_expected_bounds); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Create 1 detached panel. gfx::Rect panel3_initial_bounds = gfx::Rect(300, 450, 100, 100); Panel* panel3 = CreateDetachedPanel("3", panel3_initial_bounds); ASSERT_EQ(1, detached_collection->num_panels()); gfx::Rect panel3_expected_bounds(panel3_initial_bounds); EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds()); // Drag P1 (together with P2) to stack to the top of P3. // Expect that P1 and P2 add to the top of P3 and all 3 panels are in // one stack. P1 and P2 should align to top of P3 while P3 should update its // width to be same as the width of P1 and P2. gfx::Vector2d drag_delta_to_stack = GetDragDeltaToStackToTop(panel1, panel3); DragPanelByDelta(panel1, drag_delta_to_stack); WaitForBoundsAnimationFinished(panel3); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); StackedPanelCollection* final_stack = panel_manager->stacks().front(); ASSERT_EQ(3, final_stack->num_panels()); EXPECT_EQ(final_stack, panel1->stack()); EXPECT_EQ(final_stack, panel2->stack()); EXPECT_EQ(final_stack, panel3->stack()); panel3_expected_bounds.set_width(panel1_expected_bounds.width()); EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds()); panel2_expected_bounds = GetStackedAtTopPanelBounds( panel2_expected_bounds, panel3_expected_bounds); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); panel1_expected_bounds = GetStackedAtTopPanelBounds( panel1_expected_bounds, panel2_expected_bounds); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupStackAndStackFromBottom) { PanelManager* panel_manager = PanelManager::GetInstance(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create 2 stacked panels. StackedPanelCollection* stack1 = panel_manager->CreateStack(); gfx::Rect panel1_initial_bounds = gfx::Rect(100, 50, 200, 150); Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack1); gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100); Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack1); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); ASSERT_EQ(2, stack1->num_panels()); EXPECT_EQ(stack1, panel1->stack()); EXPECT_EQ(stack1, panel2->stack()); gfx::Rect panel1_expected_bounds(panel1_initial_bounds); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds( panel2_initial_bounds, panel1_expected_bounds); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Create 2 more stacked panels in another stack. StackedPanelCollection* stack2 = panel_manager->CreateStack(); gfx::Rect panel3_initial_bounds = gfx::Rect(300, 100, 220, 120); Panel* panel3 = CreateStackedPanel("3", panel3_initial_bounds, stack2); gfx::Rect panel4_initial_bounds = gfx::Rect(0, 0, 180, 140); Panel* panel4 = CreateStackedPanel("4", panel4_initial_bounds, stack2); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(2, panel_manager->num_stacks()); ASSERT_EQ(2, stack2->num_panels()); EXPECT_EQ(stack2, panel3->stack()); EXPECT_EQ(stack2, panel4->stack()); gfx::Rect panel3_expected_bounds(panel3_initial_bounds); EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds()); gfx::Rect panel4_expected_bounds = GetStackedAtBottomPanelBounds( panel4_initial_bounds, panel3_expected_bounds); EXPECT_EQ(panel4_expected_bounds, panel4->GetBounds()); // Drag P3 (together with P4) to stack to the bottom of the stack consisting // P1 and P2. // Expect that P3 and P4 append to the bottom of P2 and all 4 panels are in // one stack. gfx::Vector2d drag_delta_to_stack = GetDragDeltaToStackToBottom(panel3, panel2); DragPanelByDelta(panel3, drag_delta_to_stack); WaitForBoundsAnimationFinished(panel3); WaitForBoundsAnimationFinished(panel4); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); StackedPanelCollection* final_stack = panel_manager->stacks().front(); ASSERT_EQ(4, final_stack->num_panels()); EXPECT_EQ(final_stack, panel1->stack()); EXPECT_EQ(final_stack, panel2->stack()); EXPECT_EQ(final_stack, panel3->stack()); EXPECT_EQ(final_stack, panel4->stack()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); panel3_expected_bounds = GetStackedAtBottomPanelBounds( panel3_initial_bounds, panel2_expected_bounds); EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds()); panel4_expected_bounds = GetStackedAtBottomPanelBounds( panel4_initial_bounds, panel3_expected_bounds); EXPECT_EQ(panel4_expected_bounds, panel4->GetBounds()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, GroupStackAndStackFromTop) { PanelManager* panel_manager = PanelManager::GetInstance(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create 2 stacked panels. StackedPanelCollection* stack1 = panel_manager->CreateStack(); gfx::Rect panel1_initial_bounds = gfx::Rect(100, 50, 200, 150); Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack1); gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100); Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack1); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); ASSERT_EQ(2, stack1->num_panels()); EXPECT_EQ(stack1, panel1->stack()); EXPECT_EQ(stack1, panel2->stack()); gfx::Rect panel1_expected_bounds(panel1_initial_bounds); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds( panel2_initial_bounds, panel1_expected_bounds); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Create 2 more stacked panels in another stack. StackedPanelCollection* stack2 = panel_manager->CreateStack(); gfx::Rect panel3_initial_bounds = gfx::Rect(300, 350, 220, 110); Panel* panel3 = CreateStackedPanel("3", panel3_initial_bounds, stack2); gfx::Rect panel4_initial_bounds = gfx::Rect(0, 0, 180, 100); Panel* panel4 = CreateStackedPanel("4", panel4_initial_bounds, stack2); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(2, panel_manager->num_stacks()); ASSERT_EQ(2, stack2->num_panels()); EXPECT_EQ(stack2, panel3->stack()); EXPECT_EQ(stack2, panel4->stack()); gfx::Rect panel3_expected_bounds(panel3_initial_bounds); EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds()); gfx::Rect panel4_expected_bounds = GetStackedAtBottomPanelBounds( panel4_initial_bounds, panel3_expected_bounds); EXPECT_EQ(panel4_expected_bounds, panel4->GetBounds()); // Drag P1 (together with P2) to stack to the top of the stack consisting // P3 and P4. // Expect that P1 and P2 add to the top of P3 and all 4 panels are in // one stack. P1 and P2 should align to top of P3 while P3 and P4 should // update their width to be same as the width of P1 and P2. gfx::Vector2d drag_delta_to_stack = GetDragDeltaToStackToTop(panel1, panel3); DragPanelByDelta(panel1, drag_delta_to_stack); WaitForBoundsAnimationFinished(panel3); WaitForBoundsAnimationFinished(panel4); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); StackedPanelCollection* final_stack = panel_manager->stacks().front(); ASSERT_EQ(4, final_stack->num_panels()); EXPECT_EQ(final_stack, panel1->stack()); EXPECT_EQ(final_stack, panel2->stack()); EXPECT_EQ(final_stack, panel3->stack()); EXPECT_EQ(final_stack, panel4->stack()); panel4_expected_bounds.set_width(panel1_expected_bounds.width()); EXPECT_EQ(panel4_expected_bounds, panel4->GetBounds()); panel3_expected_bounds.set_width(panel1_expected_bounds.width()); EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds()); panel2_expected_bounds = GetStackedAtTopPanelBounds( panel2_expected_bounds, panel3_expected_bounds); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); panel1_expected_bounds = GetStackedAtTopPanelBounds( panel1_expected_bounds, panel2_expected_bounds); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, UngroupTwoPanelStack) { PanelManager* panel_manager = PanelManager::GetInstance(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create 2 stacked panels. StackedPanelCollection* stack = panel_manager->CreateStack(); gfx::Rect panel1_initial_bounds = gfx::Rect(100, 50, 200, 150); Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack); gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100); Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(2, stack->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); EXPECT_EQ(stack, panel1->stack()); EXPECT_EQ(stack, panel2->stack()); gfx::Rect panel1_expected_bounds(panel1_initial_bounds); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds( panel2_initial_bounds, panel1_expected_bounds); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); gfx::Rect panel2_old_bounds = panel2_expected_bounds; // Press on title-bar. scoped_ptr panel2_testing( CreateNativePanelTesting(panel2)); gfx::Point mouse_location(panel2->GetBounds().origin()); gfx::Point original_mouse_location = mouse_location; panel2_testing->PressLeftMouseButtonTitlebar(mouse_location); // Drag P2 away from the bottom of P1 to trigger the unstacking. // Expect that P1 and P2 get detached. gfx::Vector2d drag_delta_to_unstack = GetDragDeltaToUnstackFromBottom(panel2, panel1); mouse_location = mouse_location + drag_delta_to_unstack; panel2_testing->DragTitlebar(mouse_location); ASSERT_EQ(2, detached_collection->num_panels()); ASSERT_TRUE(stack->num_panels() == 0); EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); panel2_expected_bounds.Offset(drag_delta_to_unstack); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Drag P2 a bit closer to the bottom of P1 to trigger the stacking. // Expect P1 and P2 get stacked together. gfx::Vector2d drag_delta_to_stack = GetDragDeltaToStackToBottom(panel2, panel1); mouse_location = mouse_location + drag_delta_to_stack; panel2_testing->DragTitlebar(mouse_location); ASSERT_EQ(0, detached_collection->num_panels()); // Note that the empty stack might still exist until the drag ends. ASSERT_GE(panel_manager->num_stacks(), 1); EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type()); EXPECT_EQ(panel1->stack(), panel2->stack()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); panel2_expected_bounds = GetStackedAtBottomPanelBounds( panel2_initial_bounds, panel1_expected_bounds); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Drag P2 away from the bottom of P1 to trigger the unstacking again. // Expect that P1 and P2 get detached. drag_delta_to_unstack = GetDragDeltaToUnstackFromBottom(panel2, panel1); mouse_location = mouse_location + drag_delta_to_unstack; panel2_testing->DragTitlebar(mouse_location); ASSERT_EQ(2, detached_collection->num_panels()); ASSERT_TRUE(stack->num_panels() == 0); EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); panel2_expected_bounds = panel2_old_bounds; panel2_expected_bounds.Offset(mouse_location - original_mouse_location); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Finish the drag. // Expect that the P1 and P2 stay detached. panel2_testing->FinishDragTitlebar(); ASSERT_EQ(2, detached_collection->num_panels()); ASSERT_EQ(0, panel_manager->num_stacks()); EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, UngroupAndCancel) { PanelManager* panel_manager = PanelManager::GetInstance(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create 2 stacked panels. StackedPanelCollection* stack = panel_manager->CreateStack(); gfx::Rect panel1_initial_bounds = gfx::Rect(100, 50, 200, 150); Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack); gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100); Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(2, stack->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); EXPECT_EQ(stack, panel1->stack()); EXPECT_EQ(stack, panel2->stack()); gfx::Rect panel1_expected_bounds(panel1_initial_bounds); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds( panel2_initial_bounds, panel1_expected_bounds); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); gfx::Rect panel2_old_bounds = panel2->GetBounds(); // Press on title-bar. scoped_ptr panel2_testing( CreateNativePanelTesting(panel2)); gfx::Point mouse_location(panel2->GetBounds().origin()); gfx::Point original_mouse_location = mouse_location; panel2_testing->PressLeftMouseButtonTitlebar(mouse_location); // Drag P2 away from the bottom of P1 to trigger the unstacking. // Expect that P1 and P2 get detached. gfx::Vector2d drag_delta_to_unstack = GetDragDeltaToUnstackFromBottom(panel2, panel1); mouse_location = mouse_location + drag_delta_to_unstack; panel2_testing->DragTitlebar(mouse_location); ASSERT_EQ(2, detached_collection->num_panels()); ASSERT_TRUE(stack->num_panels() == 0); EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); panel2_expected_bounds.Offset(drag_delta_to_unstack); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Cancel the drag. // Expect that the P1 and P2 put back to the same stack. panel2_testing->CancelDragTitlebar(); WaitForBoundsAnimationFinished(panel2); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); EXPECT_EQ(PanelCollection::STACKED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::STACKED, panel2->collection()->type()); EXPECT_EQ(stack, panel1->stack()); EXPECT_EQ(stack, panel2->stack()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); EXPECT_EQ(panel2_old_bounds, panel2->GetBounds()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, UngroupBottomPanelInThreePanelStack) { PanelManager* panel_manager = PanelManager::GetInstance(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create 3 stacked panels. StackedPanelCollection* stack = panel_manager->CreateStack(); gfx::Rect panel1_initial_bounds = gfx::Rect(100, 50, 200, 150); Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack); gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100); Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack); gfx::Rect panel3_initial_bounds = gfx::Rect(0, 0, 120, 120); Panel* panel3 = CreateStackedPanel("3", panel3_initial_bounds, stack); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); ASSERT_EQ(3, stack->num_panels()); EXPECT_EQ(stack, panel1->stack()); EXPECT_EQ(stack, panel2->stack()); EXPECT_EQ(stack, panel3->stack()); gfx::Rect panel1_expected_bounds(panel1_initial_bounds); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds( panel2_initial_bounds, panel1_expected_bounds); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); gfx::Rect panel3_expected_bounds = GetStackedAtBottomPanelBounds( panel3_initial_bounds, panel2_expected_bounds); EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds()); // Drag P3 away to unstack from P2 and P1. // Expect that P1 and P2 are still in the stack while P3 gets detached. gfx::Vector2d drag_delta_to_unstack = GetDragDeltaToUnstackFromBottom(panel3, panel2); DragPanelByDelta(panel3, drag_delta_to_unstack); ASSERT_EQ(1, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); ASSERT_EQ(2, stack->num_panels()); EXPECT_EQ(stack, panel1->stack()); EXPECT_EQ(stack, panel2->stack()); EXPECT_EQ(PanelCollection::DETACHED, panel3->collection()->type()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); panel3_expected_bounds.Offset(drag_delta_to_unstack); EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, UngroupMiddlePanelInThreePanelStack) { PanelManager* panel_manager = PanelManager::GetInstance(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create 3 stacked panels. StackedPanelCollection* stack = panel_manager->CreateStack(); gfx::Rect panel1_initial_bounds = gfx::Rect(100, 50, 200, 150); Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack); gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100); Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack); gfx::Rect panel3_initial_bounds = gfx::Rect(0, 0, 120, 120); Panel* panel3 = CreateStackedPanel("3", panel3_initial_bounds, stack); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); ASSERT_EQ(3, stack->num_panels()); EXPECT_EQ(stack, panel1->stack()); EXPECT_EQ(stack, panel2->stack()); EXPECT_EQ(stack, panel3->stack()); gfx::Rect panel1_expected_bounds(panel1_initial_bounds); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds( panel2_initial_bounds, panel1_expected_bounds); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); gfx::Rect panel3_expected_bounds = GetStackedAtBottomPanelBounds( panel3_initial_bounds, panel2_expected_bounds); EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds()); // Drag P2 (together with P3) away to unstack from P1. // Expect that P2 and P3 are still in a stack while P1 gets detached. gfx::Vector2d drag_delta_to_unstack = GetDragDeltaToUnstackFromBottom(panel2, panel1); DragPanelByDelta(panel2, drag_delta_to_unstack); ASSERT_EQ(1, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); StackedPanelCollection* final_stack = panel_manager->stacks().front(); ASSERT_EQ(2, final_stack->num_panels()); EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type()); EXPECT_EQ(final_stack, panel2->stack()); EXPECT_EQ(final_stack, panel3->stack()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); panel2_expected_bounds.Offset(drag_delta_to_unstack); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); panel3_expected_bounds.Offset(drag_delta_to_unstack); EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, UngroupThirdPanelInFourPanelStack) { PanelManager* panel_manager = PanelManager::GetInstance(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create 4 stacked panels. StackedPanelCollection* stack = panel_manager->CreateStack(); gfx::Rect panel1_initial_bounds = gfx::Rect(100, 120, 200, 100); Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack); gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100); Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack); gfx::Rect panel3_initial_bounds = gfx::Rect(0, 0, 120, 120); Panel* panel3 = CreateStackedPanel("3", panel3_initial_bounds, stack); gfx::Rect panel4_initial_bounds = gfx::Rect(0, 0, 120, 110); Panel* panel4 = CreateStackedPanel("4", panel4_initial_bounds, stack); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); ASSERT_EQ(4, stack->num_panels()); EXPECT_EQ(stack, panel1->stack()); EXPECT_EQ(stack, panel2->stack()); EXPECT_EQ(stack, panel3->stack()); EXPECT_EQ(stack, panel4->stack()); gfx::Rect panel1_expected_bounds(panel1_initial_bounds); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds( panel2_initial_bounds, panel1_expected_bounds); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); gfx::Rect panel3_expected_bounds = GetStackedAtBottomPanelBounds( panel3_initial_bounds, panel2_expected_bounds); EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds()); gfx::Rect panel4_expected_bounds = GetStackedAtBottomPanelBounds( panel4_initial_bounds, panel3_expected_bounds); EXPECT_EQ(panel4_expected_bounds, panel4->GetBounds()); // Drag P3 (together with P4) away to unstack from P2. // Expect that P1 and P2 are in one stack while P3 and P4 are in different // stack. gfx::Vector2d drag_delta_to_unstack = GetDragDeltaToUnstackFromBottom(panel3, panel2); DragPanelByDelta(panel3, drag_delta_to_unstack); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(2, panel_manager->num_stacks()); StackedPanelCollection* final_stack1 = panel_manager->stacks().front(); ASSERT_EQ(2, final_stack1->num_panels()); StackedPanelCollection* final_stack2 = panel_manager->stacks().back(); ASSERT_EQ(2, final_stack2->num_panels()); EXPECT_EQ(panel1->stack(), panel2->stack()); EXPECT_EQ(panel3->stack(), panel4->stack()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); panel3_expected_bounds.Offset(drag_delta_to_unstack); EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds()); panel4_expected_bounds.Offset(drag_delta_to_unstack); EXPECT_EQ(panel4_expected_bounds, panel4->GetBounds()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, UngroupAndGroup) { PanelManager* panel_manager = PanelManager::GetInstance(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create 2 stacked panels. StackedPanelCollection* stack = panel_manager->CreateStack(); gfx::Rect panel1_initial_bounds = gfx::Rect(100, 50, 200, 150); Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack); gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100); Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(2, stack->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); EXPECT_EQ(stack, panel1->stack()); EXPECT_EQ(stack, panel2->stack()); gfx::Rect panel1_expected_bounds(panel1_initial_bounds); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds( panel2_initial_bounds, panel1_expected_bounds); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Create 1 detached panel. gfx::Rect panel3_initial_bounds = gfx::Rect(300, 200, 100, 100); Panel* panel3 = CreateDetachedPanel("3", panel3_initial_bounds); ASSERT_EQ(1, detached_collection->num_panels()); gfx::Rect panel3_expected_bounds(panel3_initial_bounds); EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds()); // Drag P2 to the bottom edge of P3 to trigger both unstacking and stacking. // Expect that P3 and P2 are stacked together while P1 gets detached. gfx::Vector2d drag_delta_to_unstack_and_stack = GetDragDeltaToStackToBottom(panel2, panel3); DragPanelByDelta(panel2, drag_delta_to_unstack_and_stack); WaitForBoundsAnimationFinished(panel2); ASSERT_EQ(1, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); StackedPanelCollection* final_stack = panel_manager->stacks().front(); ASSERT_EQ(2, final_stack->num_panels()); EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type()); EXPECT_EQ(final_stack, panel2->stack()); EXPECT_EQ(final_stack, panel3->stack()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); panel2_expected_bounds = GetStackedAtBottomPanelBounds( panel2_initial_bounds, panel3_expected_bounds); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, UngroupAndAttach) { PanelManager* panel_manager = PanelManager::GetInstance(); DockedPanelCollection* docked_collection = panel_manager->docked_collection(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create 2 stacked panels. StackedPanelCollection* stack = panel_manager->CreateStack(); gfx::Rect panel1_initial_bounds = gfx::Rect(100, 50, 200, 150); Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack); gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100); Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack); ASSERT_EQ(0, docked_collection->num_panels()); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(2, stack->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); EXPECT_EQ(stack, panel1->stack()); EXPECT_EQ(stack, panel2->stack()); gfx::Rect panel1_expected_bounds(panel1_initial_bounds); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds( panel2_initial_bounds, panel1_expected_bounds); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Drag P2 close to the bottom of the work area to trigger both unstacking and // docking for P2. // Expect that P2 gets docked while P2 gets detached. gfx::Vector2d drag_delta_to_unstack_and_attach = GetDragDeltaToAttach(panel2); DragPanelByDelta(panel2, drag_delta_to_unstack_and_attach); WaitForBoundsAnimationFinished(panel2); ASSERT_EQ(1, docked_collection->num_panels()); ASSERT_EQ(1, detached_collection->num_panels()); ASSERT_EQ(0, panel_manager->num_stacks()); EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::DOCKED, panel2->collection()->type()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); panel2_expected_bounds.set_x(docked_collection->StartingRightPosition() - panel2_expected_bounds.width()); panel2_expected_bounds.set_y(docked_collection->work_area().bottom() - panel2_expected_bounds.height()); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, SnapPanelToPanelLeft) { PanelManager* panel_manager = PanelManager::GetInstance(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create 2 detached panels. gfx::Rect panel1_initial_bounds = gfx::Rect(300, 200, 300, 200); Panel* panel1 = CreateDetachedPanel("1", panel1_initial_bounds); gfx::Rect panel2_initial_bounds = gfx::Rect(100, 100, 100, 250); Panel* panel2 = CreateDetachedPanel("2", panel2_initial_bounds); ASSERT_EQ(2, detached_collection->num_panels()); gfx::Rect panel1_expected_bounds(panel1_initial_bounds); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); gfx::Rect panel2_expected_bounds(panel2_initial_bounds); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Press on title-bar. scoped_ptr panel2_testing( CreateNativePanelTesting(panel2)); gfx::Point mouse_location(panel2->GetBounds().origin()); gfx::Point original_mouse_location = mouse_location; panel2_testing->PressLeftMouseButtonTitlebar(mouse_location); // Drag P2 close to the left of P1 to trigger the snapping. gfx::Vector2d drag_delta_to_snap = GetDragDeltaToSnapToLeft(panel2, panel1); mouse_location = mouse_location + drag_delta_to_snap; panel2_testing->DragTitlebar(mouse_location); ASSERT_EQ(2, detached_collection->num_panels()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); panel2_expected_bounds.Offset(drag_delta_to_snap); panel2_expected_bounds.set_x( panel1_expected_bounds.x() - panel2_expected_bounds.width()); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Drag P2 a bit away from the left of P1 to trigger the unsnapping. gfx::Vector2d drag_delta_to_unsnap = GetDragDeltaToUnsnap(panel1); mouse_location = mouse_location + drag_delta_to_unsnap; panel2_testing->DragTitlebar(mouse_location); ASSERT_EQ(2, detached_collection->num_panels()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); panel2_expected_bounds = panel2_initial_bounds; panel2_expected_bounds.Offset(mouse_location - original_mouse_location); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Drag P2 close to the left of P1 to trigger the snapping again. drag_delta_to_snap = GetDragDeltaToSnapToLeft(panel2, panel1); mouse_location = mouse_location + drag_delta_to_snap; panel2_testing->DragTitlebar(mouse_location); ASSERT_EQ(2, detached_collection->num_panels()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); panel2_expected_bounds.Offset(drag_delta_to_snap); panel2_expected_bounds.set_x( panel1_expected_bounds.x() - panel2_expected_bounds.width()); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Drag P2 vertically with a little bit of horizontal movement should still // keep the snapping. gfx::Vector2d drag_delta_almost_vertically(2, 20); mouse_location = mouse_location + drag_delta_almost_vertically; panel2_testing->DragTitlebar(mouse_location); ASSERT_EQ(2, detached_collection->num_panels()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); panel2_expected_bounds.set_y( panel2_expected_bounds.y() + drag_delta_almost_vertically.y()); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Finish the drag. panel2_testing->FinishDragTitlebar(); ASSERT_EQ(2, detached_collection->num_panels()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, SnapPanelToPanelRight) { PanelManager* panel_manager = PanelManager::GetInstance(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create 2 detached panels. gfx::Rect panel1_initial_bounds = gfx::Rect(100, 200, 100, 200); Panel* panel1 = CreateDetachedPanel("1", panel1_initial_bounds); gfx::Rect panel2_initial_bounds = gfx::Rect(300, 100, 200, 250); Panel* panel2 = CreateDetachedPanel("2", panel2_initial_bounds); ASSERT_EQ(2, detached_collection->num_panels()); gfx::Rect panel1_expected_bounds(panel1_initial_bounds); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); gfx::Rect panel2_expected_bounds(panel2_initial_bounds); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Press on title-bar. scoped_ptr panel2_testing( CreateNativePanelTesting(panel2)); gfx::Point mouse_location(panel2->GetBounds().origin()); gfx::Point original_mouse_location = mouse_location; panel2_testing->PressLeftMouseButtonTitlebar(mouse_location); // Drag P1 close to the right of P2 to trigger the snapping. gfx::Vector2d drag_delta_to_snap = GetDragDeltaToSnapToRight(panel2, panel1); mouse_location = mouse_location + drag_delta_to_snap; panel2_testing->DragTitlebar(mouse_location); ASSERT_EQ(2, detached_collection->num_panels()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); panel2_expected_bounds.Offset(drag_delta_to_snap); panel2_expected_bounds.set_x(panel1_expected_bounds.right()); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Drag P2 a bit away from the right of P1 to trigger the unsnapping. gfx::Vector2d drag_delta_to_unsnap = GetDragDeltaToUnsnap(panel1); mouse_location = mouse_location + drag_delta_to_unsnap; panel2_testing->DragTitlebar(mouse_location); ASSERT_EQ(2, detached_collection->num_panels()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); panel2_expected_bounds = panel2_initial_bounds; panel2_expected_bounds.Offset(mouse_location - original_mouse_location); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Drag P2 close to the right of P1 to trigger the snapping again. drag_delta_to_snap = GetDragDeltaToSnapToRight(panel2, panel1); mouse_location = mouse_location + drag_delta_to_snap; panel2_testing->DragTitlebar(mouse_location); ASSERT_EQ(2, detached_collection->num_panels()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); panel2_expected_bounds.Offset(drag_delta_to_snap); panel2_expected_bounds.set_x(panel1_expected_bounds.right()); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Drag P2 vertically with a little bit of horizontal movement should still // keep the snapping. gfx::Vector2d drag_delta_almost_vertically(2, -20); mouse_location = mouse_location + drag_delta_almost_vertically; panel2_testing->DragTitlebar(mouse_location); ASSERT_EQ(2, detached_collection->num_panels()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); panel2_expected_bounds.set_y( panel2_expected_bounds.y() + drag_delta_almost_vertically.y()); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Finish the drag. panel2_testing->FinishDragTitlebar(); ASSERT_EQ(2, detached_collection->num_panels()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, SnapAndCancel) { PanelManager* panel_manager = PanelManager::GetInstance(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create 2 detached panels. gfx::Rect panel1_initial_bounds = gfx::Rect(300, 200, 300, 200); Panel* panel1 = CreateDetachedPanel("1", panel1_initial_bounds); gfx::Rect panel2_initial_bounds = gfx::Rect(100, 100, 100, 250); Panel* panel2 = CreateDetachedPanel("2", panel2_initial_bounds); ASSERT_EQ(2, detached_collection->num_panels()); gfx::Rect panel1_expected_bounds(panel1_initial_bounds); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); gfx::Rect panel2_expected_bounds(panel2_initial_bounds); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Press on title-bar. scoped_ptr panel2_testing( CreateNativePanelTesting(panel2)); gfx::Point mouse_location(panel2->GetBounds().origin()); gfx::Point original_mouse_location = mouse_location; panel2_testing->PressLeftMouseButtonTitlebar(mouse_location); // Drag P2 close to the left of P1 to trigger the snapping. gfx::Vector2d drag_delta_to_snap = GetDragDeltaToSnapToLeft(panel2, panel1); mouse_location = mouse_location + drag_delta_to_snap; panel2_testing->DragTitlebar(mouse_location); ASSERT_EQ(2, detached_collection->num_panels()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); panel2_expected_bounds.Offset(drag_delta_to_snap); panel2_expected_bounds.set_x( panel1_expected_bounds.x() - panel2_expected_bounds.width()); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Cancel the drag. panel2_testing->CancelDragTitlebar(); ASSERT_EQ(2, detached_collection->num_panels()); EXPECT_EQ(panel1_initial_bounds, panel1->GetBounds()); EXPECT_EQ(panel2_initial_bounds, panel2->GetBounds()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, SnapPanelToStackLeft) { PanelManager* panel_manager = PanelManager::GetInstance(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create 2 stacked panels. StackedPanelCollection* stack = panel_manager->CreateStack(); gfx::Rect panel1_initial_bounds = gfx::Rect(300, 100, 200, 150); Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack); gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100); Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); ASSERT_EQ(2, stack->num_panels()); EXPECT_EQ(stack, panel1->collection()); EXPECT_EQ(stack, panel2->collection()); gfx::Rect panel1_expected_bounds(panel1_initial_bounds); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds( panel2_initial_bounds, panel1_expected_bounds); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Create 1 detached panel. gfx::Rect panel3_initial_bounds = gfx::Rect(100, 200, 100, 100); Panel* panel3 = CreateDetachedPanel("3", panel3_initial_bounds); ASSERT_EQ(1, detached_collection->num_panels()); EXPECT_EQ(PanelCollection::DETACHED, panel3->collection()->type()); gfx::Rect panel3_expected_bounds(panel3_initial_bounds); EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds()); // Drag P3 close to the left of the stack of P1 and P2 to trigger the // snapping. gfx::Vector2d drag_delta_to_snap = GetDragDeltaToSnapToLeft(panel3, panel1); DragPanelByDelta(panel3, drag_delta_to_snap); ASSERT_EQ(1, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); ASSERT_EQ(2, stack->num_panels()); EXPECT_EQ(stack, panel1->collection()); EXPECT_EQ(stack, panel2->collection()); EXPECT_EQ(PanelCollection::DETACHED, panel3->collection()->type()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); panel3_expected_bounds.Offset(drag_delta_to_snap); panel3_expected_bounds.set_x( panel1_expected_bounds.x() - panel3_expected_bounds.width()); EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, SnapPanelToStackRight) { PanelManager* panel_manager = PanelManager::GetInstance(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create 2 stacked panels. StackedPanelCollection* stack = panel_manager->CreateStack(); gfx::Rect panel1_initial_bounds = gfx::Rect(100, 100, 200, 150); Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack); gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100); Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack); ASSERT_EQ(0, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); ASSERT_EQ(2, stack->num_panels()); EXPECT_EQ(stack, panel1->collection()); EXPECT_EQ(stack, panel2->collection()); gfx::Rect panel1_expected_bounds(panel1_initial_bounds); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds( panel2_initial_bounds, panel1_expected_bounds); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Create 1 detached panel. gfx::Rect panel3_initial_bounds = gfx::Rect(300, 200, 100, 100); Panel* panel3 = CreateDetachedPanel("3", panel3_initial_bounds); ASSERT_EQ(1, detached_collection->num_panels()); EXPECT_EQ(PanelCollection::DETACHED, panel3->collection()->type()); gfx::Rect panel3_expected_bounds(panel3_initial_bounds); EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds()); // Drag P3 close to the right of the stack of P1 and P2 to trigger the // snapping. gfx::Vector2d drag_delta_to_snap = GetDragDeltaToSnapToRight(panel3, panel1); DragPanelByDelta(panel3, drag_delta_to_snap); ASSERT_EQ(1, detached_collection->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); ASSERT_EQ(2, stack->num_panels()); EXPECT_EQ(stack, panel1->collection()); EXPECT_EQ(stack, panel2->collection()); EXPECT_EQ(PanelCollection::DETACHED, panel3->collection()->type()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); panel3_expected_bounds.Offset(drag_delta_to_snap); panel3_expected_bounds.set_x(panel1_expected_bounds.right()); EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DetachAndSnap) { PanelManager* panel_manager = PanelManager::GetInstance(); DockedPanelCollection* docked_collection = panel_manager->docked_collection(); DetachedPanelCollection* detached_collection = panel_manager->detached_collection(); // Create 1 detached panel. Panel* panel1 = CreateDetachedPanel("1", gfx::Rect(300, 200, 100, 100)); ASSERT_EQ(0, docked_collection->num_panels()); ASSERT_EQ(1, detached_collection->num_panels()); EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type()); gfx::Rect panel1_bounds = panel1->GetBounds(); // Create 1 docked panel. Panel* panel2 = CreateDockedPanel("2", gfx::Rect(0, 0, 150, 150)); ASSERT_EQ(1, docked_collection->num_panels()); ASSERT_EQ(1, detached_collection->num_panels()); EXPECT_EQ(PanelCollection::DOCKED, panel2->collection()->type()); gfx::Rect panel2_bounds = panel2->GetBounds(); // Drag P2 close to the right of P1 to trigger both detaching and snapping. gfx::Vector2d drag_delta_to_detach_and_snap = GetDragDeltaToSnapToRight(panel2, panel1); DragPanelByDelta(panel2, drag_delta_to_detach_and_snap); ASSERT_EQ(0, docked_collection->num_panels()); ASSERT_EQ(2, detached_collection->num_panels()); EXPECT_EQ(PanelCollection::DETACHED, panel1->collection()->type()); EXPECT_EQ(PanelCollection::DETACHED, panel2->collection()->type()); EXPECT_EQ(panel1_bounds, panel1->GetBounds()); panel2_bounds.Offset(drag_delta_to_detach_and_snap); panel2_bounds.set_x(panel1_bounds.right()); EXPECT_EQ(panel2_bounds, panel2->GetBounds()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DragTopStackedPanel) { PanelManager* panel_manager = PanelManager::GetInstance(); // Create 3 stacked panels. StackedPanelCollection* stack = panel_manager->CreateStack(); gfx::Rect panel1_initial_bounds = gfx::Rect(300, 100, 200, 150); Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack); gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100); Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack); gfx::Rect panel3_initial_bounds = gfx::Rect(0, 0, 150, 200); Panel* panel3 = CreateStackedPanel("3", panel3_initial_bounds, stack); ASSERT_EQ(3, stack->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); EXPECT_EQ(stack, panel1->collection()); EXPECT_EQ(stack, panel2->collection()); EXPECT_EQ(stack, panel3->collection()); gfx::Rect panel1_expected_bounds(panel1_initial_bounds); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds( panel2_initial_bounds, panel1_expected_bounds); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); gfx::Rect panel3_expected_bounds = GetStackedAtBottomPanelBounds( panel3_initial_bounds, panel2_expected_bounds); EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds()); // Drag the top panel by a delta. // Expect all panels are still in the same stack and they are all moved by the // same delta. gfx::Vector2d drag_delta(-50, -20); DragPanelByDelta(panel1, drag_delta); ASSERT_EQ(3, stack->num_panels()); ASSERT_EQ(1, panel_manager->num_stacks()); EXPECT_EQ(stack, panel1->collection()); EXPECT_EQ(stack, panel2->collection()); EXPECT_EQ(stack, panel3->collection()); panel1_expected_bounds.Offset(drag_delta); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); panel2_expected_bounds.Offset(drag_delta); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); panel3_expected_bounds.Offset(drag_delta); EXPECT_EQ(panel3_expected_bounds, panel3->GetBounds()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, SnapDetachedPanelToScreenEdge) { PanelManager* panel_manager = PanelManager::GetInstance(); int small_distance = PanelDragController::GetSnapPanelToScreenEdgeThresholdForTesting() / 2; // Setup 2 displays with secondary display on the right side of primary // display. gfx::Rect primary_display_area(0, 0, 400, 600); gfx::Rect primary_work_area(0, 0, 400, 560); mock_display_settings_provider()->SetPrimaryDisplay( primary_display_area, primary_work_area); gfx::Rect secondary_display_area(400, 100, 400, 500); gfx::Rect secondary_work_area(400, 140, 400, 460); mock_display_settings_provider()->SetSecondaryDisplay( secondary_display_area, secondary_work_area); // Create one detached panel on the primary display. gfx::Rect initial_bounds = gfx::Rect(100, 100, 200, 150); Panel* panel = CreateDetachedPanel("1", initial_bounds); gfx::Rect expected_bounds(initial_bounds); EXPECT_EQ(expected_bounds, panel->GetBounds()); // Drag the panel close to the right edge of the primary display. // Expect that the panel should snap to the right edge. gfx::Point drag_to_location( primary_work_area.right() - small_distance - panel->GetBounds().width(), panel->GetBounds().y()); DragPanelToMouseLocation(panel, drag_to_location); expected_bounds.set_x(primary_work_area.right() - panel->GetBounds().width()); EXPECT_EQ(expected_bounds, panel->GetBounds()); // Drag the panel close to the top-left corner of the primary display. // Expect that the panel should snap to the top-left corner. drag_to_location = gfx::Point( primary_work_area.x() + small_distance, primary_work_area.y() - small_distance); DragPanelToMouseLocation(panel, drag_to_location); expected_bounds.set_origin(primary_work_area.origin()); EXPECT_EQ(expected_bounds, panel->GetBounds()); // Drag the panel close to the top-right corner of the secondary display. // Expect that the panel should snap to the top-right corner. drag_to_location = gfx::Point( secondary_work_area.right() - small_distance - panel->GetBounds().width(), secondary_work_area.y() + small_distance); DragPanelToMouseLocation(panel, drag_to_location); expected_bounds.set_x( secondary_work_area.right() - panel->GetBounds().width()); expected_bounds.set_y(secondary_work_area.y()); EXPECT_EQ(expected_bounds, panel->GetBounds()); panel_manager->CloseAll(); } IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, SnapStackedPanelToScreenEdge) { PanelManager* panel_manager = PanelManager::GetInstance(); int small_distance = PanelDragController::GetSnapPanelToScreenEdgeThresholdForTesting() / 2; // Setup 2 displays with secondary display on the right side of primary // display. gfx::Rect primary_display_area(0, 0, 400, 600); gfx::Rect primary_work_area(0, 0, 400, 560); mock_display_settings_provider()->SetPrimaryDisplay( primary_display_area, primary_work_area); gfx::Rect secondary_display_area(400, 100, 400, 500); gfx::Rect secondary_work_area(400, 140, 400, 460); mock_display_settings_provider()->SetSecondaryDisplay( secondary_display_area, secondary_work_area); // Create 2 stacked panels on the primary display. StackedPanelCollection* stack = panel_manager->CreateStack(); gfx::Rect panel1_initial_bounds = gfx::Rect(300, 100, 200, 150); Panel* panel1 = CreateStackedPanel("1", panel1_initial_bounds, stack); gfx::Rect panel2_initial_bounds = gfx::Rect(0, 0, 150, 100); Panel* panel2 = CreateStackedPanel("2", panel2_initial_bounds, stack); gfx::Rect panel1_expected_bounds(panel1_initial_bounds); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); gfx::Rect panel2_expected_bounds = GetStackedAtBottomPanelBounds( panel2_initial_bounds, panel1_expected_bounds); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Drag the stack close to the left edge of the primary display. // Expect that the stack should snap to the left edge. gfx::Point drag_to_location( primary_work_area.x() + small_distance, panel1->GetBounds().y()); DragPanelToMouseLocation(panel1, drag_to_location); panel1_expected_bounds.set_x(primary_work_area.x()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); panel2_expected_bounds.set_x(primary_work_area.x()); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Drag the stack close to the bottom-right corner of the primary display. // Expect that the stack should snap to the bottom-right corner. drag_to_location = gfx::Point( primary_work_area.right() + small_distance - panel1->GetBounds().width(), primary_work_area.bottom() - small_distance - panel1->GetBounds().height() - panel2->GetBounds().height()); DragPanelToMouseLocation(panel1, drag_to_location); int expected_x = primary_work_area.right() - panel1->GetBounds().width(); panel1_expected_bounds.set_x(expected_x); panel1_expected_bounds.set_y(primary_work_area.bottom() - panel1->GetBounds().height() - panel2->GetBounds().height()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); panel2_expected_bounds.set_x(expected_x); panel2_expected_bounds.set_y(primary_work_area.bottom() - panel2->GetBounds().height()); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); // Drag the stack close to the top-left corner of the secondary display. // Expect that the stack should snap to the top-left corner. drag_to_location = gfx::Point( secondary_work_area.x() + small_distance, secondary_work_area.y() + small_distance); DragPanelToMouseLocation(panel1, drag_to_location); expected_x = secondary_work_area.x(); panel1_expected_bounds.set_x(expected_x); panel1_expected_bounds.set_y(secondary_work_area.y()); EXPECT_EQ(panel1_expected_bounds, panel1->GetBounds()); panel2_expected_bounds.set_x(expected_x); panel2_expected_bounds.set_y(panel1_expected_bounds.bottom()); EXPECT_EQ(panel2_expected_bounds, panel2->GetBounds()); panel_manager->CloseAll(); }