Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(254)

Unified Diff: chrome/browser/ui/panels/panel_drag_controller.cc

Issue 9546001: Support detaching/attaching panels via inter-strip drags. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/panels/panel_drag_controller.cc
diff --git a/chrome/browser/ui/panels/panel_drag_controller.cc b/chrome/browser/ui/panels/panel_drag_controller.cc
index 2a21cd28b7ffdf9af6b959ce845b07a30c172a51..effcf471886765162645746fa42d580f37312a23 100644
--- a/chrome/browser/ui/panels/panel_drag_controller.cc
+++ b/chrome/browser/ui/panels/panel_drag_controller.cc
@@ -5,30 +5,86 @@
#include "chrome/browser/ui/panels/panel_drag_controller.h"
#include "base/logging.h"
+#include "chrome/browser/ui/panels/detached_panel_strip.h"
+#include "chrome/browser/ui/panels/docked_panel_strip.h"
#include "chrome/browser/ui/panels/panel.h"
+#include "chrome/browser/ui/panels/panel_manager.h"
#include "chrome/browser/ui/panels/panel_strip.h"
-PanelDragController::PanelDragController()
- : dragging_panel_(NULL) {
+namespace {
+
+// The threshold to detach the docked panel to make it free-floating.
+const int kDetachDockedPanelThreshold = -80;
jennb 2012/03/01 00:33:38 Thresholds are usually positive amounts.
jianli 2012/03/02 22:42:43 Done.
+
+// The threshold to dock the detached panel.
+const int kDockDetachedPanelThreshold = -10;
+
+} // namespace
+
+PanelDragController::PanelDragController(PanelManager* panel_manager)
+ : panel_manager_(panel_manager),
+ dragging_panel_(NULL),
+ dragging_panel_original_strip_(NULL),
+ has_dragged_to_other_strip_(false) {
}
PanelDragController::~PanelDragController() {
}
-void PanelDragController::StartDragging(Panel* panel) {
+void PanelDragController::StartDragging(Panel* panel,
+ const gfx::Point& mouse_location) {
DCHECK(!dragging_panel_);
DCHECK(panel->draggable());
dragging_panel_ = panel;
+ dragging_panel_original_strip_ = dragging_panel_->panel_strip();
dragging_panel_original_position_ = panel->GetBounds().origin();
+ has_dragged_to_other_strip_ = false;
+ total_ommitted_delta_y_ = 0;
jennb 2012/03/01 00:33:38 Seems cleaner to store original mouse location at
jianli 2012/03/02 22:42:43 Removed. We now use original mouse location at sta
- dragging_panel_->panel_strip()->StartDraggingPanel(panel);
+ // When the detached panel is being dragged, it should be always-on-top. This
+ // is to make sure it will not get obscured by other docked panels.
+ if (dragging_panel_original_strip_->type() == PanelStrip::DETACHED)
+ panel->SetAlwaysOnTop(true);
jennb 2012/03/01 00:33:38 Always-on-top should only be set if panel is in th
jianli 2012/03/02 22:42:43 Done.
+
+ dragging_panel_original_strip_->StartDraggingPanel(panel);
+
+ last_mouse_location_ = mouse_location;
}
-void PanelDragController::Drag(int delta_x, int delta_y) {
+void PanelDragController::Drag(const gfx::Point& mouse_location) {
DCHECK(dragging_panel_);
- dragging_panel_->panel_strip()->DragPanel(dragging_panel_, delta_x, delta_y);
+ int delta_x = mouse_location.x() - last_mouse_location_.x();
+ int delta_y = mouse_location.y() - last_mouse_location_.y();
+
+ PanelStrip* strip_to_drag_to = CanDragToDockedStrip(mouse_location);
jennb 2012/03/01 00:33:38 PanelStrip* target_strip = ComputeDragTarget(mouse
jianli 2012/03/02 22:42:43 Done.
+ if (!strip_to_drag_to)
+ strip_to_drag_to = CanDragToDetachedStrip(mouse_location);
+
+ if (strip_to_drag_to) {
+ has_dragged_to_other_strip_ = true;
+
+ // Compensate all the y-coordinate drag movements that could be omitted
+ // in previous intra-strip drag.
+ gfx::Point new_position = dragging_panel_->GetBounds().origin();
+ new_position.Offset(delta_x, delta_y + total_ommitted_delta_y_);
+ total_ommitted_delta_y_ = 0;
+
+ MoveToStrip(dragging_panel_, strip_to_drag_to, new_position);
+ } else {
+ gfx::Point old_position = dragging_panel_->GetBounds().origin();
+ dragging_panel_->panel_strip()->DragPanel(dragging_panel_,
+ delta_x,
+ delta_y);
+
+ // Track all the y-coordinate drag movements that could be omitted
+ // in previous intra-strip drag.
+ gfx::Point new_position = dragging_panel_->GetBounds().origin();
+ total_ommitted_delta_y_ += delta_y - new_position.y() + old_position.y();
+ }
+
+ last_mouse_location_ = mouse_location;
}
void PanelDragController::EndDragging(bool cancelled) {
@@ -39,7 +95,74 @@ void PanelDragController::EndDragging(bool cancelled) {
// this.
Panel* panel = dragging_panel_;
dragging_panel_ = NULL;
+
+ // If the drag is cancelled and the dragging panel is still in the different
+ // strip from the original strip, put it back to the original strip first.
+ if (cancelled && panel->panel_strip() != dragging_panel_original_strip_) {
jennb 2012/03/01 00:33:38 I'm having a hard time picturing what happens here
jianli 2012/03/02 22:42:43 Changed per discussed.
+ MoveToStrip(panel,
+ dragging_panel_original_strip_,
+ panel->GetBounds().origin());
+ }
+
panel->panel_strip()->EndDraggingPanel(panel, cancelled);
+
+ // When the drag ends, the dragging panel will stop staying always-on-top if
+ // it ends with the detached state.
+ if (panel->panel_strip()->type() == PanelStrip::DETACHED)
+ panel->SetAlwaysOnTop(false);
jennb 2012/03/01 00:33:38 Again, it seems like the responsibility of the str
jianli 2012/03/02 22:42:43 Done.
+}
+
+PanelStrip* PanelDragController::CanDragToDockedStrip(
jennb 2012/03/01 00:33:38 Seems like this function and CanDragToDetachedStri
jianli 2012/03/02 22:42:43 I think it is cleaner to split the different check
+ const gfx::Point& mouse_location) const {
+ // It has to come from the detached strip.
+ if (dragging_panel_->panel_strip()->type() != PanelStrip::DETACHED)
+ return NULL;
+
+ // The bottom of the panel should come very close to or fall below the bottom
+ // of the docked area.
+ int new_panel_bottom = dragging_panel_->GetBounds().bottom() +
jennb 2012/03/01 00:33:38 Would it be cleaner to do computations using start
jianli 2012/03/02 22:42:43 The triggering condition for attach is to check th
+ mouse_location.y() - last_mouse_location_.y();
+ int docked_area_bottom =
+ panel_manager_->docked_strip()->display_area().bottom();
jennb 2012/03/01 00:33:38 Should dock strip be the one to decide if a panel
jianli 2012/03/02 22:42:43 Docked strip can only decide if a docked panel can
+ if (new_panel_bottom - docked_area_bottom < kDockDetachedPanelThreshold)
jennb 2012/03/03 02:19:33 if new_panel_bottom is above the bottom of the doc
+ return NULL;
+
+ return panel_manager_->docked_strip();
+}
+
+PanelStrip* PanelDragController::CanDragToDetachedStrip(
+ const gfx::Point& mouse_location) const {
+ // It has to come from the docked strip.
+ if (dragging_panel_->panel_strip()->type() != PanelStrip::DOCKED)
+ return NULL;
+
+ // The minimized docked panel is not allowed to detach.
+ if (dragging_panel_->expansion_state() != Panel::EXPANDED)
+ return NULL;
+
+ // The panel should be dragged up higher enough to pass certain threshold.
+ int delta_y = total_ommitted_delta_y_ +
+ mouse_location.y() - last_mouse_location_.y();
+ if (delta_y > kDetachDockedPanelThreshold)
+ return NULL;
+
+ return panel_manager_->detached_strip();
+}
+
+void PanelDragController::MoveToStrip(Panel* panel,
+ PanelStrip* new_strip,
+ const gfx::Point& new_position) {
+ // Stop dragging in old strip. This needs to be done before moving the panel.
+ PanelStrip* old_strip = panel->panel_strip();
+ old_strip->EndDraggingPanel(panel, false);
jennb 2012/03/01 00:33:38 Confusing. Dragging isn't really ended. For instan
jianli 2012/03/02 22:42:43 Per discussion, this is what we want.
+
+ // Move the panel to new strip.
jennb 2012/03/01 00:33:38 I'd prefer if moving a panel between strips was al
jianli 2012/03/02 22:42:43 I agree. I would merge with your patch later.
+ old_strip->RemovePanel(panel);
+ panel->set_panel_strip(new_strip);
+ new_strip->AddPanelAtPosition(panel, new_position);
+
+ // Start dragging in new strip.
+ new_strip->StartDraggingPanel(panel);
jennb 2012/03/01 00:33:38 Very weird logic flow: EndDragging() MoveToStrip(
jianli 2012/03/02 22:42:43 Per discussion, this is what we want. Renamed drag
}
void PanelDragController::OnPanelClosed(Panel* panel) {

Powered by Google App Engine
This is Rietveld 408576698