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

Side by Side Diff: chrome/browser/views/tabs/tab_overview_drag_controller.cc

Issue 151169: Improves tab overview. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 5 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/views/tabs/tab_overview_drag_controller.h" 5 #include "chrome/browser/views/tabs/tab_overview_drag_controller.h"
6 6
7 #include "chrome/browser/browser.h" 7 #include "chrome/browser/browser.h"
8 #include "chrome/browser/browser_window.h" 8 #include "chrome/browser/browser_window.h"
9 #include "chrome/browser/dock_info.h" 9 #include "chrome/browser/dock_info.h"
10 #include "chrome/browser/gtk/browser_window_gtk.h"
10 #include "chrome/browser/tab_contents/tab_contents.h" 11 #include "chrome/browser/tab_contents/tab_contents.h"
11 #include "chrome/browser/tabs/tab_strip_model.h" 12 #include "chrome/browser/tabs/tab_strip_model.h"
12 #include "chrome/browser/tab_contents/tab_contents.h" 13 #include "chrome/browser/tab_contents/tab_contents.h"
13 #include "chrome/browser/views/tabs/tab_overview_cell.h" 14 #include "chrome/browser/views/tabs/tab_overview_cell.h"
14 #include "chrome/browser/views/tabs/tab_overview_controller.h" 15 #include "chrome/browser/views/tabs/tab_overview_controller.h"
15 #include "chrome/browser/views/tabs/tab_overview_grid.h" 16 #include "chrome/browser/views/tabs/tab_overview_grid.h"
16 #include "chrome/browser/views/tabs/tab_overview_types.h" 17 #include "chrome/browser/views/tabs/tab_overview_types.h"
17 #include "chrome/common/notification_service.h" 18 #include "chrome/common/notification_service.h"
18 #include "views/fill_layout.h" 19 #include "views/fill_layout.h"
19 #include "views/view.h" 20 #include "views/view.h"
20 #include "views/widget/root_view.h" 21 #include "views/widget/root_view.h"
21 #include "views/widget/widget_gtk.h" 22 #include "views/widget/widget_gtk.h"
22 23
23 TabOverviewDragController::TabOverviewDragController( 24 TabOverviewDragController::TabOverviewDragController(
24 TabOverviewController* controller) 25 TabOverviewController* controller)
25 : controller_(controller), 26 : controller_(controller),
26 original_model_(controller->model()), 27 original_model_(controller->model()),
27 current_index_(-1), 28 current_index_(-1),
28 original_index_(-1), 29 original_index_(-1),
29 detached_tab_(NULL), 30 detached_tab_(NULL),
30 original_delegate_(NULL), 31 original_delegate_(NULL),
31 x_offset_(0), 32 x_offset_(0),
32 y_offset_(0), 33 y_offset_(0),
33 dragging_(false), 34 dragging_(false),
34 modifying_model_(false), 35 modifying_model_(false),
35 detached_window_(NULL) { 36 detached_window_(NULL),
37 hidden_browser_(NULL),
38 mouse_over_mini_window_(false) {
36 } 39 }
37 40
38 TabOverviewDragController::~TabOverviewDragController() { 41 TabOverviewDragController::~TabOverviewDragController() {
39 if (dragging_) 42 if (dragging_)
40 controller_->DragEnded(); 43 controller_->DragEnded();
41 if (original_index_ != -1) 44 if (original_index_ != -1)
42 RevertDrag(); 45 RevertDrag(false);
43 } 46 }
44 47
45 bool TabOverviewDragController::Configure(const gfx::Point& location) { 48 bool TabOverviewDragController::Configure(const gfx::Point& location) {
46 // Find the cell the user clicked on. 49 // Find the cell the user clicked on.
47 TabOverviewCell* cell = NULL; 50 TabOverviewCell* cell = NULL;
48 int index = -1; 51 int index = -1;
49 for (int i = 0; i < grid()->GetChildViewCount(); ++i) { 52 for (int i = 0; i < grid()->GetChildViewCount(); ++i) {
50 views::View* child = grid()->GetChildViewAt(i); 53 views::View* child = grid()->GetChildViewAt(i);
51 if (child->bounds().Contains(location)) { 54 if (child->bounds().Contains(location)) {
52 index = i; 55 index = i;
(...skipping 10 matching lines...) Expand all
63 if (!cell->IsPointInThumbnail(cell_point)) 66 if (!cell->IsPointInThumbnail(cell_point))
64 return false; 67 return false;
65 68
66 current_index_ = original_index_ = index; 69 current_index_ = original_index_ = index;
67 origin_ = location; 70 origin_ = location;
68 x_offset_ = location.x() - cell->bounds().x(); 71 x_offset_ = location.x() - cell->bounds().x();
69 y_offset_ = location.y() - cell->bounds().y(); 72 y_offset_ = location.y() - cell->bounds().y();
70 73
71 // Ask the controller to select the cell. 74 // Ask the controller to select the cell.
72 controller_->SelectTab(index); 75 controller_->SelectTab(index);
76
77 if (controller_->browser()) {
78 browser_window_size_ =
79 controller_->browser()->window()->GetNormalBounds().size();
80 }
81
73 return true; 82 return true;
74 } 83 }
75 84
76 void TabOverviewDragController::Drag(const gfx::Point& location) { 85 void TabOverviewDragController::Drag(const gfx::Point& location) {
77 if (original_index_ == -1) 86 if (original_index_ == -1)
78 return; 87 return;
79 88
80 if (!dragging_ && 89 if (!dragging_ &&
81 views::View::ExceededDragThreshold(location.x() - origin_.x(), 90 views::View::ExceededDragThreshold(location.x() - origin_.x(),
82 location.y() - origin_.y())) { 91 location.y() - origin_.y())) {
83 // Start dragging. 92 // Start dragging.
84 dragging_ = true; 93 dragging_ = true;
85 controller_->DragStarted(); 94 controller_->DragStarted();
86 grid()->set_floating_index(current_index_); 95 grid()->set_floating_index(current_index_);
87 } 96 }
88 if (dragging_) 97 if (dragging_)
89 DragCell(location); 98 DragCell(location);
90 } 99 }
91 100
92 void TabOverviewDragController::CommitDrag(const gfx::Point& location) { 101 void TabOverviewDragController::CommitDrag(const gfx::Point& location) {
93 if (original_index_ == -1) 102 if (original_index_ == -1)
94 return; 103 return;
95 104
96 Drag(location); 105 Drag(location);
97 if (detached_tab_) { 106 if (detached_tab_) {
98 DropTab(location); 107 if (mouse_over_mini_window_) {
108 // Dragged over a mini window, add as the last tab to the browser.
109 Attach(model()->count());
110 } else {
111 DropTab(location);
112 }
99 } else if (!dragging_ ) { 113 } else if (!dragging_ ) {
100 // We haven't started dragging. Tell the controller to focus the browser. 114 // We haven't started dragging. Tell the controller to focus the browser.
101 controller_->FocusBrowser(); 115 controller_->FocusBrowser();
102 } else { 116 } else {
103 // The tab is already in position, nothing to do but animate the change. 117 // The tab is already in position, nothing to do but animate the change.
104 grid()->set_floating_index(-1); 118 grid()->set_floating_index(-1);
105 grid()->AnimateToTargetBounds(); 119 grid()->AnimateToTargetBounds();
106 } 120 }
107 121
108 // Set the index to -1 so we know not to do any cleanup. 122 // Set the index to -1 so we know not to do any cleanup.
109 original_index_ = -1; 123 original_index_ = -1;
110 } 124 }
111 125
112 void TabOverviewDragController::RevertDrag() { 126 void TabOverviewDragController::RevertDrag(bool tab_destroyed) {
113 if (original_index_ == -1) 127 if (original_index_ == -1)
114 return; 128 return;
115 129
116 modifying_model_ = true; 130 modifying_model_ = true;
117 if (detached_tab_) { 131 if (detached_tab_) {
118 // Tab is currently detached, add it back to the original tab strip. 132 // Tab is currently detached, add it back to the original tab strip.
119 original_model_->InsertTabContentsAt(original_index_, 133 if (!tab_destroyed) {
120 detached_tab_, true, false); 134 original_model_->InsertTabContentsAt(original_index_,
135 detached_tab_, true, false);
136 }
121 SetDetachedContents(NULL); 137 SetDetachedContents(NULL);
122 detached_window_->Close(); 138 detached_window_->Close();
123 detached_window_ = NULL; 139 detached_window_ = NULL;
124 } else if (original_model_ != model()) { 140
141 if (hidden_browser_) {
142 gtk_widget_show(GTK_WIDGET(static_cast<BrowserWindowGtk*>(
143 hidden_browser_->window())->GetNativeHandle()));
144 }
145 } else if (original_model_ != model() && !tab_destroyed) {
125 // The tab was added to a different tab strip. Move it back to the 146 // The tab was added to a different tab strip. Move it back to the
126 // original. 147 // original.
127 TabContents* contents = model()->DetachTabContentsAt(current_index_); 148 TabContents* contents = model()->DetachTabContentsAt(current_index_);
128 original_model_->InsertTabContentsAt(original_index_, contents, true, 149 original_model_->InsertTabContentsAt(original_index_, contents, true,
129 false); 150 false);
130 } else if (current_index_ != original_index_) { 151 } else if (current_index_ != original_index_ && !tab_destroyed) {
131 original_model_->MoveTabContentsAt(current_index_, original_index_, true); 152 original_model_->MoveTabContentsAt(current_index_, original_index_, true);
132 } 153 }
133 modifying_model_ = false; 154 modifying_model_ = false;
134 155
135 // Set the index to -1 so we know not to do any cleanup. 156 // Set the index to -1 so we know not to do any cleanup.
136 original_index_ = -1; 157 original_index_ = -1;
137 } 158 }
138 159
139 TabOverviewGrid* TabOverviewDragController::grid() const { 160 TabOverviewGrid* TabOverviewDragController::grid() const {
140 return controller_->grid(); 161 return controller_->grid();
141 } 162 }
142 163
143 TabStripModel* TabOverviewDragController::model() const { 164 TabStripModel* TabOverviewDragController::model() const {
144 return controller_->model(); 165 return controller_->model();
145 } 166 }
146 167
147 void TabOverviewDragController::Observe(NotificationType type, 168 void TabOverviewDragController::Observe(NotificationType type,
148 const NotificationSource& source, 169 const NotificationSource& source,
149 const NotificationDetails& details) { 170 const NotificationDetails& details) {
150 DCHECK(type == NotificationType::TAB_CONTENTS_DESTROYED); 171 DCHECK(type == NotificationType::TAB_CONTENTS_DESTROYED);
151 DCHECK(Source<TabContents>(source).ptr() == detached_tab_); 172 DCHECK(Source<TabContents>(source).ptr() == detached_tab_);
152 RevertDrag(); 173 RevertDrag(true);
153 } 174 }
154 175
155 void TabOverviewDragController::OpenURLFromTab( 176 void TabOverviewDragController::OpenURLFromTab(
156 TabContents* source, 177 TabContents* source,
157 const GURL& url, 178 const GURL& url,
158 const GURL& referrer, 179 const GURL& referrer,
159 WindowOpenDisposition disposition, 180 WindowOpenDisposition disposition,
160 PageTransition::Type transition) { 181 PageTransition::Type transition) {
161 if (original_delegate_) { 182 if (original_delegate_) {
162 if (disposition == CURRENT_TAB) 183 if (disposition == CURRENT_TAB)
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 340
320 grid()->set_floating_index(-1); 341 grid()->set_floating_index(-1);
321 SetDetachedContents(model()->GetTabContentsAt(current_index_)); 342 SetDetachedContents(model()->GetTabContentsAt(current_index_));
322 if (model()->count() == 1) { 343 if (model()->count() == 1) {
323 // The model is going to be empty. Tell the host to move us offscreen. 344 // The model is going to be empty. Tell the host to move us offscreen.
324 // NOTE: it would be nice to hide and destroy the window here but this 345 // NOTE: it would be nice to hide and destroy the window here but this
325 // causes two problems: we'll stop getting events, and we don't want 346 // causes two problems: we'll stop getting events, and we don't want
326 // to empty out the tabstrip as otherwise they may trigger Chrome to 347 // to empty out the tabstrip as otherwise they may trigger Chrome to
327 // exit. 348 // exit.
328 controller_->MoveOffscreen(); 349 controller_->MoveOffscreen();
350 hidden_browser_ = controller_->browser();
351 gtk_widget_hide(GTK_WIDGET(static_cast<BrowserWindowGtk*>(
352 hidden_browser_->window())->GetNativeHandle()));
329 } 353 }
330 modifying_model_ = true; 354 modifying_model_ = true;
331 model()->DetachTabContentsAt(current_index_); 355 model()->DetachTabContentsAt(current_index_);
332 modifying_model_ = false; 356 modifying_model_ = false;
333 } 357 }
334 358
335 void TabOverviewDragController::DropTab(const gfx::Point& location) { 359 void TabOverviewDragController::DropTab(const gfx::Point& location) {
336 TabContents* contents = detached_tab_; 360 TabContents* contents = detached_tab_;
337 SetDetachedContents(NULL); 361 SetDetachedContents(NULL);
338 362
339 gfx::Rect browser_rect = controller_->browser()->window()->GetNormalBounds();
340 gfx::Point screen_loc(location); 363 gfx::Point screen_loc(location);
341 grid()->ConvertPointToScreen(grid(), &screen_loc); 364 grid()->ConvertPointToScreen(grid(), &screen_loc);
342 gfx::Rect window_bounds( 365 gfx::Rect window_bounds(screen_loc, browser_window_size_);
343 screen_loc, gfx::Size(browser_rect.width(), browser_rect.height())); 366 Browser* new_browser =
344 Browser* new_browser = model()->delegate()->CreateNewStripWithContents( 367 original_model_->delegate()->CreateNewStripWithContents(
345 contents, window_bounds, DockInfo()); 368 contents, window_bounds, DockInfo());
346 new_browser->window()->Show(); 369 new_browser->window()->Show();
347 370
348 detached_window_->Close(); 371 detached_window_->Close();
349 detached_window_ = NULL; 372 detached_window_ = NULL;
350 } 373 }
351 374
352 void TabOverviewDragController::MoveDetachedWindow( 375 void TabOverviewDragController::MoveDetachedWindow(
353 const gfx::Point& location) { 376 const gfx::Point& location) {
354 gfx::Point screen_loc = location; 377 gfx::Point screen_loc = location;
355 screen_loc.Offset(-x_offset_, -y_offset_); 378 screen_loc.Offset(-x_offset_, -y_offset_);
356 grid()->ConvertPointToScreen(grid(), &screen_loc); 379 grid()->ConvertPointToScreen(grid(), &screen_loc);
357 detached_window_->SetBounds( 380 detached_window_->SetBounds(
358 gfx::Rect(screen_loc, 381 gfx::Rect(screen_loc,
359 detached_window_->GetRootView()->GetPreferredSize())); 382 detached_window_->GetRootView()->GetPreferredSize()));
383
384 // Notify the wm of the move.
385 TabOverviewTypes::Message message;
386 message.set_type(TabOverviewTypes::Message::WM_MOVE_FLOATING_TAB);
387 message.set_param(0, x11_util::GetX11WindowFromGtkWidget(
388 detached_window_->GetNativeView()));
389 message.set_param(1, screen_loc.x() + x_offset_);
390 message.set_param(2, screen_loc.y() + y_offset_);
391 TabOverviewTypes::instance()->SendMessage(message);
360 } 392 }
361 393
362 views::Widget* TabOverviewDragController::CreateDetachedWindow( 394 views::Widget* TabOverviewDragController::CreateDetachedWindow(
363 const gfx::Point& location, 395 const gfx::Point& location,
364 TabContents* tab_contents) { 396 TabContents* tab_contents) {
365 // TODO: wrap the cell in another view that provides a background. 397 // TODO: wrap the cell in another view that provides a background.
366 views::WidgetGtk* widget = 398 views::WidgetGtk* widget =
367 new views::WidgetGtk(views::WidgetGtk::TYPE_POPUP); 399 new views::WidgetGtk(views::WidgetGtk::TYPE_WINDOW);
368 widget->MakeTransparent(); 400 widget->MakeTransparent();
369 gfx::Point screen_loc = location; 401 gfx::Point screen_loc = location;
370 screen_loc.Offset(-x_offset_, -y_offset_); 402 screen_loc.Offset(-x_offset_, -y_offset_);
371 grid()->ConvertPointToScreen(grid(), &screen_loc); 403 grid()->ConvertPointToScreen(grid(), &screen_loc);
372 TabOverviewCell* cell = new TabOverviewCell(); 404 TabOverviewCell* cell = new TabOverviewCell();
373 cell->set_preferred_size( 405 cell->set_preferred_size(
374 gfx::Size(grid()->cell_width(), grid()->cell_height())); 406 gfx::Size(grid()->cell_width(), grid()->cell_height()));
375 controller_->ConfigureCell(cell, tab_contents); 407 controller_->ConfigureCell(cell, tab_contents);
376 widget->Init(NULL, gfx::Rect(screen_loc, cell->GetPreferredSize()), true); 408 widget->Init(NULL, gfx::Rect(screen_loc, cell->GetPreferredSize()), true);
377 widget->GetRootView()->SetLayoutManager(new views::FillLayout()); 409 widget->GetRootView()->SetLayoutManager(new views::FillLayout());
(...skipping 30 matching lines...) Expand all
408 Source<TabContents>(tab)); 440 Source<TabContents>(tab));
409 441
410 // We need to be the delegate so we receive messages about stuff, 442 // We need to be the delegate so we receive messages about stuff,
411 // otherwise our dragged contents may be replaced and subsequently 443 // otherwise our dragged contents may be replaced and subsequently
412 // collected/destroyed while the drag is in process, leading to 444 // collected/destroyed while the drag is in process, leading to
413 // nasty crashes. 445 // nasty crashes.
414 original_delegate_ = tab->delegate(); 446 original_delegate_ = tab->delegate();
415 tab->set_delegate(this); 447 tab->set_delegate(this);
416 } 448 }
417 } 449 }
OLDNEW
« no previous file with comments | « chrome/browser/views/tabs/tab_overview_drag_controller.h ('k') | chrome/browser/views/tabs/tab_overview_grid.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698