diff options
author | jianli@chromium.org <jianli@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-21 23:45:59 +0000 |
---|---|---|
committer | jianli@chromium.org <jianli@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-21 23:45:59 +0000 |
commit | bcf0eeac7fdeb911b28513d6509b18960861b779 (patch) | |
tree | 31e06725cc9f03d45d219f6907b396df0bd79235 /chrome/browser/ui/panels | |
parent | 85ece055a9c048a34a63670580b3bc89543f77e4 (diff) | |
download | chromium_src-bcf0eeac7fdeb911b28513d6509b18960861b779.zip chromium_src-bcf0eeac7fdeb911b28513d6509b18960861b779.tar.gz chromium_src-bcf0eeac7fdeb911b28513d6509b18960861b779.tar.bz2 |
Refactor intra-strip panel drags by introducing PanelDragController.
Changes:
1) Add PanelDragController that is created and owned by PanelManager. Currently it only contains the logic for intra-strip drags.
2) Add dragging related base methods to PanelStrip.
3) PanelManager dragging methods will now call PanelDragController and then delegate to PanelStrip methods.
4) Add delta_y parameter to Drag method.
5) Remove is_draggble from Panel and replace it with PanelStrip::CanDragPanel.
BUG=none
TEST=new tests to cover detached panels
Review URL: http://codereview.chromium.org/9403035
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@122914 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/ui/panels')
21 files changed, 328 insertions, 71 deletions
diff --git a/chrome/browser/ui/panels/detached_panel_browsertest.cc b/chrome/browser/ui/panels/detached_panel_browsertest.cc new file mode 100644 index 0000000..62a10f2 --- /dev/null +++ b/chrome/browser/ui/panels/detached_panel_browsertest.cc @@ -0,0 +1,90 @@ +// 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 "chrome/browser/ui/panels/base_panel_browser_test.h" +#include "chrome/browser/ui/panels/detached_panel_strip.h" +#include "chrome/browser/ui/panels/native_panel.h" +#include "chrome/browser/ui/panels/panel.h" +#include "chrome/browser/ui/panels/panel_manager.h" + +class DetachedPanelBrowserTest : public BasePanelBrowserTest { +}; + +IN_PROC_BROWSER_TEST_F(DetachedPanelBrowserTest, CheckDetachedPanelProperties) { + PanelManager* panel_manager = PanelManager::GetInstance(); + DetachedPanelStrip* detached_strip = panel_manager->detached_strip(); + + // Create 2 panels. + Panel* panel1 = CreatePanelWithBounds("Panel1", gfx::Rect(0, 0, 250, 200)); + Panel* panel2 = CreatePanelWithBounds("Panel2", gfx::Rect(0, 0, 300, 200)); + + EXPECT_TRUE(panel1->draggable()); + EXPECT_TRUE(panel2->draggable()); + + // Move panels to detached strip. + EXPECT_EQ(2, panel_manager->num_panels()); + EXPECT_EQ(0, detached_strip->num_panels()); + panel1->MoveToStrip(detached_strip); + panel2->MoveToStrip(detached_strip); + EXPECT_EQ(2, panel_manager->num_panels()); + EXPECT_EQ(2, detached_strip->num_panels()); + + std::vector<Panel*> panels = panel_manager->panels(); + EXPECT_EQ(panel1, panels[0]); + EXPECT_EQ(panel2, panels[1]); + + EXPECT_TRUE(panel1->draggable()); + EXPECT_TRUE(panel2->draggable()); + + panel_manager->CloseAll(); +} + +IN_PROC_BROWSER_TEST_F(DetachedPanelBrowserTest, DragDetachedPanel) { + PanelManager* panel_manager = PanelManager::GetInstance(); + DetachedPanelStrip* detached_strip = panel_manager->detached_strip(); + + // Create one detached panel. + Panel* panel = CreatePanelWithBounds("Panel1", gfx::Rect(0, 0, 250, 200)); + panel->MoveToStrip(detached_strip); + + // Test that the detached panel can be dragged anywhere. + scoped_ptr<NativePanelTesting> panel_testing( + NativePanelTesting::Create(panel->native_panel())); + gfx::Point origin = panel->GetBounds().origin(); + + panel_testing->PressLeftMouseButtonTitlebar(origin); + EXPECT_EQ(origin, panel->GetBounds().origin()); + + panel_testing->DragTitlebar(-51, 102); + origin.Offset(-51, 102); + EXPECT_EQ(origin, panel->GetBounds().origin()); + + panel_testing->DragTitlebar(37, -42); + origin.Offset(37, -42); + 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()); + + panel_testing->DragTitlebar(-51, 102); + origin.Offset(-51, 102); + EXPECT_EQ(origin, panel->GetBounds().origin()); + + panel_testing->DragTitlebar(37, -42); + origin.Offset(37, -42); + EXPECT_EQ(origin, panel->GetBounds().origin()); + + panel_testing->CancelDragTitlebar(); + EXPECT_EQ(original_position, panel->GetBounds().origin()); + + panel_manager->CloseAll(); +} diff --git a/chrome/browser/ui/panels/detached_panel_strip.cc b/chrome/browser/ui/panels/detached_panel_strip.cc index 44cc362..7eb137d 100644 --- a/chrome/browser/ui/panels/detached_panel_strip.cc +++ b/chrome/browser/ui/panels/detached_panel_strip.cc @@ -6,6 +6,7 @@ #include <algorithm> #include "base/logging.h" +#include "chrome/browser/ui/panels/panel_drag_controller.h" #include "chrome/browser/ui/panels/panel_manager.h" DetachedPanelStrip::DetachedPanelStrip(PanelManager* panel_manager) @@ -79,3 +80,25 @@ void DetachedPanelStrip::RestorePanel(Panel* panel) { NOTIMPLEMENTED(); } +bool DetachedPanelStrip::CanDragPanel(const Panel* panel) const { + // All detached panels are draggable. + return true; +} + +void DetachedPanelStrip::StartDraggingPanel(Panel* panel) { +} + +void DetachedPanelStrip::DragPanel(Panel* panel, int delta_x, int delta_y) { + gfx::Rect new_bounds(panel->GetBounds()); + new_bounds.Offset(delta_x, delta_y); + panel->SetPanelBounds(new_bounds); +} + +void DetachedPanelStrip::EndDraggingPanel(Panel* panel, bool cancelled) { + if (cancelled) { + gfx::Rect new_bounds(panel->GetBounds()); + new_bounds.set_origin( + panel_manager_->drag_controller()->dragging_panel_original_position()); + panel->SetPanelBounds(new_bounds); + } +} diff --git a/chrome/browser/ui/panels/detached_panel_strip.h b/chrome/browser/ui/panels/detached_panel_strip.h index 868093b..875547d 100644 --- a/chrome/browser/ui/panels/detached_panel_strip.h +++ b/chrome/browser/ui/panels/detached_panel_strip.h @@ -10,6 +10,7 @@ #include "base/basictypes.h" #include "chrome/browser/ui/panels/panel.h" #include "chrome/browser/ui/panels/panel_strip.h" +#include "ui/gfx/point.h" #include "ui/gfx/rect.h" class Browser; @@ -36,6 +37,10 @@ class DetachedPanelStrip : public PanelStrip { virtual void ActivatePanel(Panel* panel) OVERRIDE; virtual void MinimizePanel(Panel* panel) OVERRIDE; virtual void RestorePanel(Panel* panel) OVERRIDE; + virtual bool CanDragPanel(const Panel* panel) const OVERRIDE; + virtual void StartDraggingPanel(Panel* panel) OVERRIDE; + virtual void DragPanel(Panel* panel, int delta_x, int delta_y) OVERRIDE; + virtual void EndDraggingPanel(Panel* panel, bool cancelled) OVERRIDE; int num_panels() const { return panels_.size(); } const Panels& panels() const { return panels_; } diff --git a/chrome/browser/ui/panels/docked_panel_strip.cc b/chrome/browser/ui/panels/docked_panel_strip.cc index 40fbb25..48e5b33 100644 --- a/chrome/browser/ui/panels/docked_panel_strip.cc +++ b/chrome/browser/ui/panels/docked_panel_strip.cc @@ -11,6 +11,7 @@ #include "base/message_loop.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/panels/overflow_panel_strip.h" +#include "chrome/browser/ui/panels/panel_drag_controller.h" #include "chrome/browser/ui/panels/panel_manager.h" #include "chrome/browser/ui/panels/panel_mouse_watcher.h" #include "chrome/common/chrome_notification_types.h" @@ -59,7 +60,6 @@ DockedPanelStrip::DockedPanelStrip(PanelManager* panel_manager) minimized_panel_count_(0), are_titlebars_up_(false), disable_layout_refresh_(false), - dragging_panel_(NULL), dragging_panel_original_x_(0), delayed_titlebar_action_(NO_ACTION), titlebar_action_factory_(this) { @@ -183,7 +183,6 @@ void DockedPanelStrip::AddPanel(Panel* panel) { // Set panel properties for this strip. panel->SetAppIconVisibility(true); - panel->set_draggable(!panel->has_temporary_layout()); panel->ApplyVisualStyleForStrip(); if (panel->has_temporary_layout()) @@ -219,11 +218,10 @@ bool DockedPanelStrip::RemovePanel(Panel* panel) { return false; // If we're in the process of dragging, delay the removal. - if (dragging_panel_) { + if (panel_manager_->drag_controller()->IsDragging()) { panels_pending_to_remove_.push_back(panel); return true; } - DoRemove(panel); if (!disable_layout_refresh_) @@ -252,37 +250,39 @@ bool DockedPanelStrip::DoRemove(Panel* panel) { return true; } -void DockedPanelStrip::StartDragging(Panel* panel) { +bool DockedPanelStrip::CanDragPanel(const Panel* panel) const { + // Only the panels having temporary layout can't be dragged. + return !panel->has_temporary_layout(); +} + +void DockedPanelStrip::StartDraggingPanel(Panel* panel) { dragging_panel_iterator_ = find(panels_.begin(), panels_.end(), panel); DCHECK(dragging_panel_iterator_ != panels_.end()); - dragging_panel_ = panel; dragging_panel_bounds_ = panel->GetBounds(); dragging_panel_original_x_ = dragging_panel_bounds_.x(); } -void DockedPanelStrip::Drag(int delta_x) { - DCHECK(dragging_panel_); - +void DockedPanelStrip::DragPanel(Panel* panel, int delta_x, int delta_y) { if (!delta_x) return; // Moves this panel to the dragging position. - gfx::Rect new_bounds(dragging_panel_->GetBounds()); + gfx::Rect new_bounds(panel->GetBounds()); new_bounds.set_x(new_bounds.x() + delta_x); - dragging_panel_->SetPanelBounds(new_bounds); + panel->SetPanelBounds(new_bounds); // Checks and processes other affected panels. if (delta_x > 0) - DragRight(); + DragRight(panel); else - DragLeft(); + DragLeft(panel); } -void DockedPanelStrip::DragLeft() { +void DockedPanelStrip::DragLeft(Panel* dragging_panel) { // This is the left corner of the dragging panel. We use it to check against // all the panels on its left. - int dragging_panel_left_boundary = dragging_panel_->GetBounds().x(); + int dragging_panel_left_boundary = dragging_panel->GetBounds().x(); // This is the right corner which a panel will be moved to. int current_panel_right_boundary = @@ -308,7 +308,7 @@ void DockedPanelStrip::DragLeft() { // Swaps current panel and dragging panel. *dragging_panel_iterator_ = current_panel; - *current_panel_iterator = dragging_panel_; + *current_panel_iterator = dragging_panel; dragging_panel_iterator_ = current_panel_iterator; } @@ -318,11 +318,11 @@ void DockedPanelStrip::DragLeft() { dragging_panel_bounds_.width()); } -void DockedPanelStrip::DragRight() { +void DockedPanelStrip::DragRight(Panel* dragging_panel) { // This is the right corner of the dragging panel. We use it to check against // all the panels on its right. - int dragging_panel_right_boundary = dragging_panel_->GetBounds().x() + - dragging_panel_->GetBounds().width() - 1; + int dragging_panel_right_boundary = dragging_panel->GetBounds().x() + + dragging_panel->GetBounds().width() - 1; // This is the left corner which a panel will be moved to. int current_panel_left_boundary = dragging_panel_bounds_.x(); @@ -347,7 +347,7 @@ void DockedPanelStrip::DragRight() { // Swaps current panel and dragging panel. *dragging_panel_iterator_ = current_panel; - *current_panel_iterator = dragging_panel_; + *current_panel_iterator = dragging_panel; dragging_panel_iterator_ = current_panel_iterator; } @@ -356,15 +356,11 @@ void DockedPanelStrip::DragRight() { dragging_panel_bounds_.set_x(current_panel_left_boundary); } -void DockedPanelStrip::EndDragging(bool cancelled) { - DCHECK(dragging_panel_); - +void DockedPanelStrip::EndDraggingPanel(Panel* panel, bool cancelled) { if (cancelled) - Drag(dragging_panel_original_x_ - dragging_panel_->GetBounds().x()); + DragPanel(panel, dragging_panel_original_x_ - panel->GetBounds().x(), 0); else - dragging_panel_->SetPanelBounds(dragging_panel_bounds_); - - dragging_panel_ = NULL; + panel->SetPanelBounds(dragging_panel_bounds_); DelayedRemove(); } @@ -524,7 +520,8 @@ bool DockedPanelStrip::ShouldBringUpTitlebars(int mouse_x, int mouse_y) const { // If the panel is showing titlebar only, we want to keep it up when it is // being dragged. - if (state == Panel::TITLE_ONLY && is_dragging_panel()) + if (state == Panel::TITLE_ONLY && + panel == panel_manager_->drag_controller()->dragging_panel()) return true; // We do not want to bring up other minimized panels if the mouse is over @@ -744,7 +741,6 @@ void DockedPanelStrip::DelayedMovePanelToOverflow(Panel* panel) { void DockedPanelStrip::CloseAll() { // This should only be called at the end of tests to clean up. - DCHECK(!dragging_panel_); DCHECK(panels_in_temporary_layout_.empty()); // Make a copy of the iterator as closing panels can modify the vector. @@ -755,7 +751,3 @@ void DockedPanelStrip::CloseAll() { iter != panels_copy.rend(); ++iter) (*iter)->Close(); } - -bool DockedPanelStrip::is_dragging_panel() const { - return dragging_panel_ != NULL; -} diff --git a/chrome/browser/ui/panels/docked_panel_strip.h b/chrome/browser/ui/panels/docked_panel_strip.h index 55d6f54..b0f0bbf 100644 --- a/chrome/browser/ui/panels/docked_panel_strip.h +++ b/chrome/browser/ui/panels/docked_panel_strip.h @@ -53,11 +53,10 @@ class DockedPanelStrip : public PanelStrip, virtual void ActivatePanel(Panel* panel) OVERRIDE; virtual void MinimizePanel(Panel* panel) OVERRIDE; virtual void RestorePanel(Panel* panel) OVERRIDE; - - // Drags the given panel. - void StartDragging(Panel* panel); - void Drag(int delta_x); - void EndDragging(bool cancelled); + virtual bool CanDragPanel(const Panel* panel) const OVERRIDE; + virtual void StartDraggingPanel(Panel* panel) OVERRIDE; + virtual void DragPanel(Panel* panel, int delta_x, int delta_y) OVERRIDE; + virtual void EndDraggingPanel(Panel* panel, bool cancelled) OVERRIDE; // Invoked when a panel's expansion state changes. void OnPanelExpansionStateChanged(Panel* panel); @@ -80,7 +79,6 @@ class DockedPanelStrip : public PanelStrip, int num_panels() const { return panels_.size(); } const Panels& panels() const { return panels_; } - bool is_dragging_panel() const; gfx::Rect display_area() const { return display_area_; } int GetMaxPanelWidth() const; @@ -122,8 +120,8 @@ class DockedPanelStrip : public PanelStrip, bool DoRemove(Panel* panel); // Help functions to drag the given panel. - void DragLeft(); - void DragRight(); + void DragLeft(Panel* dragging_panel); + void DragRight(Panel* dragging_panel); // Does the real job of bringing up or down the titlebars. void DoBringUpOrDownTitlebars(bool bring_up); @@ -162,8 +160,7 @@ class DockedPanelStrip : public PanelStrip, // moving panels to overflow area to make room for a panel in this strip. bool disable_layout_refresh_; - // Panel to drag. - Panel* dragging_panel_; + // Iterator of panel being dragged. Panels::iterator dragging_panel_iterator_; // Original x coordinate of the panel to drag. This is used to get back to diff --git a/chrome/browser/ui/panels/overflow_panel_strip.cc b/chrome/browser/ui/panels/overflow_panel_strip.cc index 446dcb0..b5b1e8e 100644 --- a/chrome/browser/ui/panels/overflow_panel_strip.cc +++ b/chrome/browser/ui/panels/overflow_panel_strip.cc @@ -98,7 +98,6 @@ void OverflowPanelStrip::AddPanel(Panel* panel) { // Set panel properties for this strip. panel->SetAppIconVisibility(false); - panel->set_draggable(false); panel->ApplyVisualStyleForStrip(); if (num_panels() == 1) { @@ -182,6 +181,23 @@ void OverflowPanelStrip::RestorePanel(Panel* panel) { docked_strip->RestorePanel(panel); } +bool OverflowPanelStrip::CanDragPanel(const Panel* panel) const { + // All overflow panels are not draggable. + return false; +} + +void OverflowPanelStrip::StartDraggingPanel(Panel* panel) { + NOTREACHED(); +} + +void OverflowPanelStrip::DragPanel(Panel* panel, int delta_x, int delta_y) { + NOTREACHED(); +} + +void OverflowPanelStrip::EndDraggingPanel(Panel* panel, bool cancelled) { + NOTREACHED(); +} + void OverflowPanelStrip::RefreshLayout() { if (panels_.empty()) return; diff --git a/chrome/browser/ui/panels/overflow_panel_strip.h b/chrome/browser/ui/panels/overflow_panel_strip.h index af8f310..f3c407b 100644 --- a/chrome/browser/ui/panels/overflow_panel_strip.h +++ b/chrome/browser/ui/panels/overflow_panel_strip.h @@ -42,6 +42,10 @@ class OverflowPanelStrip : public PanelStrip, virtual void ActivatePanel(Panel* panel) OVERRIDE; virtual void MinimizePanel(Panel* panel) OVERRIDE; virtual void RestorePanel(Panel* panel) OVERRIDE; + virtual bool CanDragPanel(const Panel* panel) const OVERRIDE; + virtual void StartDraggingPanel(Panel* panel) OVERRIDE; + virtual void DragPanel(Panel* panel, int delta_x, int delta_y) OVERRIDE; + virtual void EndDraggingPanel(Panel* panel, bool cancelled) OVERRIDE; void OnFullScreenModeChanged(bool is_full_screen); diff --git a/chrome/browser/ui/panels/panel.cc b/chrome/browser/ui/panels/panel.cc index ed9ac9e..5ec698c 100644 --- a/chrome/browser/ui/panels/panel.cc +++ b/chrome/browser/ui/panels/panel.cc @@ -49,7 +49,6 @@ Panel::Panel(Browser* browser, const gfx::Size& requested_size) has_temporary_layout_(false), restored_size_(requested_size), auto_resizable_(false), - draggable_(true), expansion_state_(EXPANDED), old_expansion_state_(EXPANDED), app_icon_visible_(true) { @@ -76,6 +75,10 @@ PanelManager* Panel::manager() const { return PanelManager::GetInstance(); } +bool Panel::draggable() const { + return panel_strip()->CanDragPanel(this); +} + const Extension* Panel::GetExtension() const { return GetExtensionFromBrowser(browser()); } diff --git a/chrome/browser/ui/panels/panel.h b/chrome/browser/ui/panels/panel.h index f722629..8241d6a 100644 --- a/chrome/browser/ui/panels/panel.h +++ b/chrome/browser/ui/panels/panel.h @@ -234,8 +234,7 @@ class Panel : public BrowserWindow, const gfx::Size& max_size() const { return max_size_; } bool auto_resizable() const { return auto_resizable_; } - bool draggable() const { return draggable_; } - void set_draggable(bool can_drag) { draggable_ = can_drag; } + bool draggable() const; // The restored size is the size of the panel when it is expanded. gfx::Size restored_size() const { return restored_size_; } @@ -317,9 +316,6 @@ class Panel : public BrowserWindow, // True if this panel auto resizes based on content. bool auto_resizable_; - // True if this panel can be dragged. - bool draggable_; - // Platform specifc implementation for panels. It'd be one of // PanelBrowserWindowGtk/PanelBrowserView/PanelBrowserWindowCocoa. NativePanel* native_panel_; // Weak, owns us. diff --git a/chrome/browser/ui/panels/panel_browser_view.cc b/chrome/browser/ui/panels/panel_browser_view.cc index 758b4b2..7a86614 100644 --- a/chrome/browser/ui/panels/panel_browser_view.cc +++ b/chrome/browser/ui/panels/panel_browser_view.cc @@ -471,7 +471,7 @@ bool PanelBrowserView::OnTitlebarMouseDragged(const gfx::Point& location) { mouse_dragging_state_ = DRAGGING_STARTED; } if (mouse_dragging_state_ == DRAGGING_STARTED) - panel_->manager()->Drag(delta_x); + panel_->manager()->Drag(delta_x, delta_y); return true; } diff --git a/chrome/browser/ui/panels/panel_browser_window_gtk.cc b/chrome/browser/ui/panels/panel_browser_window_gtk.cc index 10c00c7..27179b6 100644 --- a/chrome/browser/ui/panels/panel_browser_window_gtk.cc +++ b/chrome/browser/ui/panels/panel_browser_window_gtk.cc @@ -514,7 +514,7 @@ void PanelBrowserWindowGtk::DidProcessEvent(GdkEvent* event) { } if (drag_widget_) { - panel_->manager()->Drag(new_x - old_x); + panel_->manager()->Drag(new_x - old_x, new_y - old_y); gdk_event_free(last_mouse_down_); last_mouse_down_ = gdk_event_copy(event); } diff --git a/chrome/browser/ui/panels/panel_browsertest.cc b/chrome/browser/ui/panels/panel_browsertest.cc index d6d1f10..f367201 100644 --- a/chrome/browser/ui/panels/panel_browsertest.cc +++ b/chrome/browser/ui/panels/panel_browsertest.cc @@ -770,7 +770,8 @@ IN_PROC_BROWSER_TEST_F(PanelBrowserTest, DragThreePanels) { IN_PROC_BROWSER_TEST_F(PanelBrowserTest, NotDraggable) { Panel* panel = CreatePanel("panel"); - panel->set_draggable(false); + // This is used to simulate making a docked panel not draggable. + panel->set_has_temporary_layout(true); Panel* panel2 = CreatePanel("panel2"); scoped_ptr<NativePanelTesting> panel_testing( @@ -783,6 +784,8 @@ IN_PROC_BROWSER_TEST_F(PanelBrowserTest, NotDraggable) { panel_testing->FinishDragTitlebar(); EXPECT_EQ(bounds.x(), panel->GetBounds().x()); + // Reset the simulation hack so that the panel can be closed correctly. + panel->set_has_temporary_layout(false); panel->Close(); panel2->Close(); } diff --git a/chrome/browser/ui/panels/panel_drag_controller.cc b/chrome/browser/ui/panels/panel_drag_controller.cc new file mode 100644 index 0000000..8c4132d --- /dev/null +++ b/chrome/browser/ui/panels/panel_drag_controller.cc @@ -0,0 +1,40 @@ +// 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 "chrome/browser/ui/panels/panel_drag_controller.h" + +#include "base/logging.h" +#include "chrome/browser/ui/panels/panel.h" +#include "chrome/browser/ui/panels/panel_strip.h" + +PanelDragController::PanelDragController() + : dragging_panel_(NULL) { +} + +PanelDragController::~PanelDragController() { +} + +void PanelDragController::StartDragging(Panel* panel) { + DCHECK(!dragging_panel_); + DCHECK(panel->draggable()); + + dragging_panel_ = panel; + dragging_panel_original_position_ = panel->GetBounds().origin(); + + dragging_panel_->panel_strip()->StartDraggingPanel(panel); +} + +void PanelDragController::Drag(int delta_x, int delta_y) { + DCHECK(dragging_panel_); + + dragging_panel_->panel_strip()->DragPanel(dragging_panel_, delta_x, delta_y); +} + +void PanelDragController::EndDragging(bool cancelled) { + DCHECK(dragging_panel_); + + dragging_panel_->panel_strip()->EndDraggingPanel(dragging_panel_, cancelled); + dragging_panel_ = NULL; +} + diff --git a/chrome/browser/ui/panels/panel_drag_controller.h b/chrome/browser/ui/panels/panel_drag_controller.h new file mode 100644 index 0000000..f684148 --- /dev/null +++ b/chrome/browser/ui/panels/panel_drag_controller.h @@ -0,0 +1,45 @@ +// 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. + +#ifndef CHROME_BROWSER_UI_PANELS_PANEL_DRAG_CONTROLLER_H_ +#define CHROME_BROWSER_UI_PANELS_PANEL_DRAG_CONTROLLER_H_ +#pragma once + +#include <set> +#include "base/basictypes.h" +#include "ui/gfx/point.h" + +class Panel; + +// Responsible for handling drags initiated for all panels, including both +// intra-strip and inter-strip drags. +class PanelDragController { + public: + PanelDragController(); + ~PanelDragController(); + + void StartDragging(Panel* panel); + void Drag(int delta_x, int delta_y); + void EndDragging(bool cancelled); + + bool IsDragging() const { return dragging_panel_ != NULL; } + + Panel* dragging_panel() const { return dragging_panel_; } + gfx::Point dragging_panel_original_position() const { + return dragging_panel_original_position_; + } + + private: + // Panel currently being dragged. + Panel* dragging_panel_; + + // Original position, in screen coordinate system, of the panel being dragged. + // This is used to get back to the original position when we cancel the + // dragging. + gfx::Point dragging_panel_original_position_; + + DISALLOW_COPY_AND_ASSIGN(PanelDragController); +}; + +#endif // CHROME_BROWSER_UI_PANELS_PANEL_DRAG_CONTROLLER_H_ diff --git a/chrome/browser/ui/panels/panel_manager.cc b/chrome/browser/ui/panels/panel_manager.cc index 4b4848b..84f430f 100644 --- a/chrome/browser/ui/panels/panel_manager.cc +++ b/chrome/browser/ui/panels/panel_manager.cc @@ -10,8 +10,10 @@ #include "chrome/browser/fullscreen.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" +#include "chrome/browser/ui/panels/detached_panel_strip.h" #include "chrome/browser/ui/panels/docked_panel_strip.h" #include "chrome/browser/ui/panels/overflow_panel_strip.h" +#include "chrome/browser/ui/panels/panel_drag_controller.h" #include "chrome/browser/ui/panels/panel_mouse_watcher.h" #include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_switches.h" @@ -63,8 +65,10 @@ PanelManager::PanelManager() : panel_mouse_watcher_(PanelMouseWatcher::Create()), auto_sizing_enabled_(true), is_full_screen_(false) { + detached_strip_.reset(new DetachedPanelStrip(this)); docked_strip_.reset(new DockedPanelStrip(this)); overflow_strip_.reset(new OverflowPanelStrip(this)); + drag_controller_.reset(new PanelDragController()); auto_hiding_desktop_bar_ = AutoHidingDesktopBar::Create(this); OnDisplayChanged(); } @@ -160,15 +164,15 @@ void PanelManager::OnPanelRemoved(Panel* panel) { } void PanelManager::StartDragging(Panel* panel) { - docked_strip_->StartDragging(panel); + drag_controller_->StartDragging(panel); } -void PanelManager::Drag(int delta_x) { - docked_strip_->Drag(delta_x); +void PanelManager::Drag(int delta_x, int delta_y) { + drag_controller_->Drag(delta_x, delta_y); } void PanelManager::EndDragging(bool cancelled) { - docked_strip_->EndDragging(cancelled); + drag_controller_->EndDragging(cancelled); } void PanelManager::OnPanelExpansionStateChanged(Panel* panel) { @@ -244,16 +248,25 @@ void PanelManager::OnAutoHidingDesktopBarVisibilityChanged( } void PanelManager::CloseAll() { + DCHECK(!drag_controller_->IsDragging()); + + detached_strip_->CloseAll(); docked_strip_->CloseAll(); overflow_strip_->CloseAll(); } int PanelManager::num_panels() const { - return docked_strip_->num_panels() + overflow_strip_->num_panels(); + return detached_strip_->num_panels() + + docked_strip_->num_panels() + + overflow_strip_->num_panels(); } std::vector<Panel*> PanelManager::panels() const { std::vector<Panel*> panels; + for (DetachedPanelStrip::Panels::const_iterator iter = + detached_strip_->panels().begin(); + iter != detached_strip_->panels().end(); ++iter) + panels.push_back(*iter); for (DockedPanelStrip::Panels::const_iterator iter = docked_strip_->panels().begin(); iter != docked_strip_->panels().end(); ++iter) diff --git a/chrome/browser/ui/panels/panel_manager.h b/chrome/browser/ui/panels/panel_manager.h index 1c21b24..1bef5ec 100644 --- a/chrome/browser/ui/panels/panel_manager.h +++ b/chrome/browser/ui/panels/panel_manager.h @@ -16,9 +16,11 @@ #include "ui/gfx/rect.h" class Browser; -class PanelMouseWatcher; -class OverflowPanelStrip; +class DetachedPanelStrip; class DockedPanelStrip; +class OverflowPanelStrip; +class PanelDragController; +class PanelMouseWatcher; // This class manages a set of panels. class PanelManager : public AutoHidingDesktopBar::Observer { @@ -46,7 +48,7 @@ class PanelManager : public AutoHidingDesktopBar::Observer { // Drags the given panel. void StartDragging(Panel* panel); - void Drag(int delta_x); + void Drag(int delta_x, int delta_y); void EndDragging(bool cancelled); // Invoked when a panel's expansion state changes. @@ -77,6 +79,10 @@ class PanelManager : public AutoHidingDesktopBar::Observer { int StartingRightPosition() const; std::vector<Panel*> panels() const; + PanelDragController* drag_controller() const { + return drag_controller_.get(); + } + AutoHidingDesktopBar* auto_hiding_desktop_bar() const { return auto_hiding_desktop_bar_; } @@ -85,6 +91,10 @@ class PanelManager : public AutoHidingDesktopBar::Observer { return panel_mouse_watcher_.get(); } + DetachedPanelStrip* detached_strip() const { + return detached_strip_.get(); + } + DockedPanelStrip* docked_strip() const { return docked_strip_.get(); } @@ -161,9 +171,12 @@ class PanelManager : public AutoHidingDesktopBar::Observer { // Tests may want to shorten time intervals to reduce running time. static bool shorten_time_intervals_; + scoped_ptr<DetachedPanelStrip> detached_strip_; scoped_ptr<DockedPanelStrip> docked_strip_; scoped_ptr<OverflowPanelStrip> overflow_strip_; + scoped_ptr<PanelDragController> drag_controller_; + // Use a mouse watcher to know when to bring up titlebars to "peek" at // minimized panels. Mouse movement is only tracked when there is a minimized // panel. diff --git a/chrome/browser/ui/panels/panel_strip.h b/chrome/browser/ui/panels/panel_strip.h index 7cd7f87..30d4ca3 100644 --- a/chrome/browser/ui/panels/panel_strip.h +++ b/chrome/browser/ui/panels/panel_strip.h @@ -62,6 +62,16 @@ class PanelStrip { virtual void MinimizePanel(Panel* panel) = 0; virtual void RestorePanel(Panel* panel) = 0; + // Returns true if |panel| is draggable. + virtual bool CanDragPanel(const Panel* panel) const = 0; + + // Drags |panel| in the bounds of this strip. + virtual void StartDraggingPanel(Panel* panel) = 0; + // |delta_x| and |delta_y| denotes how much the mouse has been moved since + // last time when DragPanel or StartDraggingPanel is called. + virtual void DragPanel(Panel* panel, int delta_x, int delta_y) = 0; + virtual void EndDraggingPanel(Panel* panel, bool cancelled) = 0; + protected: explicit PanelStrip(Type type); virtual ~PanelStrip(); diff --git a/chrome/browser/ui/panels/panel_titlebar_view_cocoa.h b/chrome/browser/ui/panels/panel_titlebar_view_cocoa.h index e9f04d9..a93f5b8 100644 --- a/chrome/browser/ui/panels/panel_titlebar_view_cocoa.h +++ b/chrome/browser/ui/panels/panel_titlebar_view_cocoa.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// 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. @@ -91,7 +91,8 @@ enum PanelDragState { // Helpers to control title drag operation, called from more then one place. - (void)startDrag; - (void)endDrag:(BOOL)cancelled; -- (void)dragWithDeltaX:(int)deltaX; +- (void)dragWithDeltaX:(int)deltaX + deltaY:(int)deltaY; // Update the visibility of settings button. - (void)updateSettingsButtonVisibility:(BOOL)mouseOverWindow; diff --git a/chrome/browser/ui/panels/panel_titlebar_view_cocoa.mm b/chrome/browser/ui/panels/panel_titlebar_view_cocoa.mm index c3ff9d4..f637494 100644 --- a/chrome/browser/ui/panels/panel_titlebar_view_cocoa.mm +++ b/chrome/browser/ui/panels/panel_titlebar_view_cocoa.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// 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. @@ -436,7 +436,8 @@ static NSEvent* MakeMouseEvent(NSEventType type, return; // Don't start real drag yet. [self startDrag]; } - [self dragWithDeltaX:[event deltaX]]; + [self dragWithDeltaX:[event deltaX] + deltaY:[event deltaY]]; break; case NSKeyUp: @@ -479,10 +480,12 @@ static NSEvent* MakeMouseEvent(NSEventType type, dragState_ = PANEL_DRAG_SUPPRESSED; } -- (void)dragWithDeltaX:(int)deltaX { +- (void)dragWithDeltaX:(int)deltaX + deltaY:(int)deltaY { if (dragState_ != PANEL_DRAG_IN_PROGRESS) return; - [controller_ dragWithDeltaX:deltaX]; + [controller_ dragWithDeltaX:deltaX + deltaY:deltaY]; } - (void)drawAttention { @@ -580,7 +583,8 @@ static NSEvent* MakeMouseEvent(NSEventType type, deltaY:(double)delta_y { if (dragState_ == PANEL_DRAG_CAN_START) [self startDrag]; - [self dragWithDeltaX:delta_x]; + [self dragWithDeltaX:delta_x + deltaY:delta_y]; } - (void)cancelDragTitlebar { diff --git a/chrome/browser/ui/panels/panel_window_controller_cocoa.h b/chrome/browser/ui/panels/panel_window_controller_cocoa.h index a14e736..6b17df0 100644 --- a/chrome/browser/ui/panels/panel_window_controller_cocoa.h +++ b/chrome/browser/ui/panels/panel_window_controller_cocoa.h @@ -101,7 +101,8 @@ class PanelBrowserWindowCocoa; - (BOOL)isDraggable; - (void)startDrag; - (void)endDrag:(BOOL)cancelled; -- (void)dragWithDeltaX:(int)deltaX; +- (void)dragWithDeltaX:(int)deltaX + deltaY:(int)deltaY; // Accessor for titlebar view. - (PanelTitlebarViewCocoa*)titlebarView; diff --git a/chrome/browser/ui/panels/panel_window_controller_cocoa.mm b/chrome/browser/ui/panels/panel_window_controller_cocoa.mm index 38df7c4..a6f6b33 100644 --- a/chrome/browser/ui/panels/panel_window_controller_cocoa.mm +++ b/chrome/browser/ui/panels/panel_window_controller_cocoa.mm @@ -412,8 +412,9 @@ enum { windowShim_->panel()->manager()->EndDragging(cancelled); } -- (void)dragWithDeltaX:(int)deltaX { - windowShim_->panel()->manager()->Drag(deltaX); +- (void)dragWithDeltaX:(int)deltaX + deltaY:(int)deltaY { + windowShim_->panel()->manager()->Drag(deltaX, deltaY); } - (void)setPanelFrame:(NSRect)frame |