| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 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/ui/views/tabs/tab_drag_controller.h" | 5 #include "chrome/browser/ui/views/tabs/tab_drag_controller.h" |
| 6 | 6 |
| 7 #include <math.h> | 7 #include <math.h> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "ash/accelerators/accelerator_commands.h" | 10 #include "ash/accelerators/accelerator_commands.h" |
| (...skipping 1228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1239 } | 1239 } |
| 1240 DCHECK(attached_tabstrip_); | 1240 DCHECK(attached_tabstrip_); |
| 1241 attached_tabstrip_->GetWidget()->SetCapture(attached_tabstrip_); | 1241 attached_tabstrip_->GetWidget()->SetCapture(attached_tabstrip_); |
| 1242 } else if (active_) { | 1242 } else if (active_) { |
| 1243 EndDrag(result == views::Widget::MOVE_LOOP_CANCELED ? | 1243 EndDrag(result == views::Widget::MOVE_LOOP_CANCELED ? |
| 1244 END_DRAG_CANCEL : END_DRAG_COMPLETE); | 1244 END_DRAG_CANCEL : END_DRAG_COMPLETE); |
| 1245 } | 1245 } |
| 1246 } | 1246 } |
| 1247 | 1247 |
| 1248 int TabDragController::GetInsertionIndexFrom(const gfx::Rect& dragged_bounds, | 1248 int TabDragController::GetInsertionIndexFrom(const gfx::Rect& dragged_bounds, |
| 1249 int start, | 1249 int start) const { |
| 1250 int delta) const { | 1250 const int last_tab = attached_tabstrip_->tab_count() - 1; |
| 1251 for (int i = start, tab_count = attached_tabstrip_->tab_count(); | 1251 // Make the actual "drag insertion point" be just after the leading edge of |
| 1252 i >= 0 && i < tab_count; i += delta) { | 1252 // the first dragged tab. This is closer to where the user thinks of the tab |
| 1253 // as "starting" than just dragged_bounds.x(), especially with narrow tabs. |
| 1254 const int dragged_x = dragged_bounds.x() + Tab::leading_width_for_drag(); |
| 1255 if (start < 0 || start > last_tab || |
| 1256 dragged_x < attached_tabstrip_->ideal_bounds(start).x()) |
| 1257 return -1; |
| 1258 |
| 1259 for (int i = start; i <= last_tab; ++i) { |
| 1253 const gfx::Rect& ideal_bounds = attached_tabstrip_->ideal_bounds(i); | 1260 const gfx::Rect& ideal_bounds = attached_tabstrip_->ideal_bounds(i); |
| 1254 gfx::Rect left_half, right_half; | 1261 if (dragged_x < (ideal_bounds.x() + (ideal_bounds.width() / 2))) |
| 1255 ideal_bounds.SplitVertically(&left_half, &right_half); | 1262 return i; |
| 1256 if (dragged_bounds.x() >= right_half.x() && | 1263 } |
| 1257 dragged_bounds.x() < right_half.right()) { | 1264 |
| 1265 return (dragged_x < attached_tabstrip_->ideal_bounds(last_tab).right()) ? |
| 1266 (last_tab + 1) : -1; |
| 1267 } |
| 1268 |
| 1269 int TabDragController::GetInsertionIndexFromReversed( |
| 1270 const gfx::Rect& dragged_bounds, |
| 1271 int start) const { |
| 1272 // Make the actual "drag insertion point" be just after the leading edge of |
| 1273 // the first dragged tab. This is closer to where the user thinks of the tab |
| 1274 // as "starting" than just dragged_bounds.x(), especially with narrow tabs. |
| 1275 const int dragged_x = dragged_bounds.x() + Tab::leading_width_for_drag(); |
| 1276 if (start < 0 || start >= attached_tabstrip_->tab_count() || |
| 1277 dragged_x >= attached_tabstrip_->ideal_bounds(start).right()) |
| 1278 return -1; |
| 1279 |
| 1280 for (int i = start; i >= 0; --i) { |
| 1281 const gfx::Rect& ideal_bounds = attached_tabstrip_->ideal_bounds(i); |
| 1282 if (dragged_x >= (ideal_bounds.x() + (ideal_bounds.width() / 2))) |
| 1258 return i + 1; | 1283 return i + 1; |
| 1259 } else if (dragged_bounds.x() >= left_half.x() && | |
| 1260 dragged_bounds.x() < left_half.right()) { | |
| 1261 return i; | |
| 1262 } | |
| 1263 } | 1284 } |
| 1264 return -1; | 1285 |
| 1286 return (dragged_x >= attached_tabstrip_->ideal_bounds(0).x()) ? 0 : -1; |
| 1265 } | 1287 } |
| 1266 | 1288 |
| 1267 int TabDragController::GetInsertionIndexForDraggedBounds( | 1289 int TabDragController::GetInsertionIndexForDraggedBounds( |
| 1268 const gfx::Rect& dragged_bounds) const { | 1290 const gfx::Rect& dragged_bounds) const { |
| 1269 int index = -1; | 1291 int index = -1; |
| 1270 if (attached_tabstrip_->touch_layout_.get()) { | 1292 if (attached_tabstrip_->touch_layout_.get()) { |
| 1271 index = GetInsertionIndexForDraggedBoundsStacked(dragged_bounds); | 1293 index = GetInsertionIndexForDraggedBoundsStacked(dragged_bounds); |
| 1272 if (index != -1) { | 1294 if (index != -1) { |
| 1273 // Only move the tab to the left/right if the user actually moved the | 1295 // Only move the tab to the left/right if the user actually moved the |
| 1274 // mouse that way. This is necessary as tabs with stacked tabs | 1296 // mouse that way. This is necessary as tabs with stacked tabs |
| 1275 // before/after them have multiple drag positions. | 1297 // before/after them have multiple drag positions. |
| 1276 int active_index = attached_tabstrip_->touch_layout_->active_index(); | 1298 int active_index = attached_tabstrip_->touch_layout_->active_index(); |
| 1277 if ((index < active_index && | 1299 if ((index < active_index && |
| 1278 (mouse_move_direction_ & kMovedMouseLeft) == 0) || | 1300 (mouse_move_direction_ & kMovedMouseLeft) == 0) || |
| 1279 (index > active_index && | 1301 (index > active_index && |
| 1280 (mouse_move_direction_ & kMovedMouseRight) == 0)) { | 1302 (mouse_move_direction_ & kMovedMouseRight) == 0)) { |
| 1281 index = active_index; | 1303 index = active_index; |
| 1282 } | 1304 } |
| 1283 } | 1305 } |
| 1284 } else { | 1306 } else { |
| 1285 index = GetInsertionIndexFrom(dragged_bounds, 0, 1); | 1307 index = GetInsertionIndexFrom(dragged_bounds, 0); |
| 1286 } | 1308 } |
| 1287 if (index == -1) { | 1309 if (index == -1) { |
| 1288 int tab_count = attached_tabstrip_->tab_count(); | 1310 int tab_count = attached_tabstrip_->tab_count(); |
| 1289 int right_tab_x = tab_count == 0 ? 0 : | 1311 int right_tab_x = tab_count == 0 ? 0 : |
| 1290 attached_tabstrip_->ideal_bounds(tab_count - 1).right(); | 1312 attached_tabstrip_->ideal_bounds(tab_count - 1).right(); |
| 1291 if (dragged_bounds.right() > right_tab_x) { | 1313 if (dragged_bounds.right() > right_tab_x) { |
| 1292 index = GetModel(attached_tabstrip_)->count(); | 1314 index = GetModel(attached_tabstrip_)->count(); |
| 1293 } else { | 1315 } else { |
| 1294 index = 0; | 1316 index = 0; |
| 1295 } | 1317 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1311 int index) const { | 1333 int index) const { |
| 1312 if (index + 1 >= attached_tabstrip_->tab_count() || | 1334 if (index + 1 >= attached_tabstrip_->tab_count() || |
| 1313 !attached_tabstrip_->touch_layout_->IsStacked(index + 1) || | 1335 !attached_tabstrip_->touch_layout_->IsStacked(index + 1) || |
| 1314 (mouse_move_direction_ & kMovedMouseRight) == 0) | 1336 (mouse_move_direction_ & kMovedMouseRight) == 0) |
| 1315 return false; | 1337 return false; |
| 1316 | 1338 |
| 1317 int active_x = attached_tabstrip_->ideal_bounds(index).x(); | 1339 int active_x = attached_tabstrip_->ideal_bounds(index).x(); |
| 1318 int next_x = attached_tabstrip_->ideal_bounds(index + 1).x(); | 1340 int next_x = attached_tabstrip_->ideal_bounds(index + 1).x(); |
| 1319 int mid_x = std::min(next_x - kStackedDistance, | 1341 int mid_x = std::min(next_x - kStackedDistance, |
| 1320 active_x + (next_x - active_x) / 4); | 1342 active_x + (next_x - active_x) / 4); |
| 1343 // TODO(pkasting): Should this add Tab::leading_width_for_drag() as |
| 1344 // GetInsertionIndexFrom() does? |
| 1321 return dragged_bounds.x() >= mid_x; | 1345 return dragged_bounds.x() >= mid_x; |
| 1322 } | 1346 } |
| 1323 | 1347 |
| 1324 bool TabDragController::ShouldDragToPreviousStackedTab( | 1348 bool TabDragController::ShouldDragToPreviousStackedTab( |
| 1325 const gfx::Rect& dragged_bounds, | 1349 const gfx::Rect& dragged_bounds, |
| 1326 int index) const { | 1350 int index) const { |
| 1327 if (index - 1 < attached_tabstrip_->GetMiniTabCount() || | 1351 if (index - 1 < attached_tabstrip_->GetMiniTabCount() || |
| 1328 !attached_tabstrip_->touch_layout_->IsStacked(index - 1) || | 1352 !attached_tabstrip_->touch_layout_->IsStacked(index - 1) || |
| 1329 (mouse_move_direction_ & kMovedMouseLeft) == 0) | 1353 (mouse_move_direction_ & kMovedMouseLeft) == 0) |
| 1330 return false; | 1354 return false; |
| 1331 | 1355 |
| 1332 int active_x = attached_tabstrip_->ideal_bounds(index).x(); | 1356 int active_x = attached_tabstrip_->ideal_bounds(index).x(); |
| 1333 int previous_x = attached_tabstrip_->ideal_bounds(index - 1).x(); | 1357 int previous_x = attached_tabstrip_->ideal_bounds(index - 1).x(); |
| 1334 int mid_x = std::max(previous_x + kStackedDistance, | 1358 int mid_x = std::max(previous_x + kStackedDistance, |
| 1335 active_x - (active_x - previous_x) / 4); | 1359 active_x - (active_x - previous_x) / 4); |
| 1360 // TODO(pkasting): Should this add Tab::leading_width_for_drag() as |
| 1361 // GetInsertionIndexFrom() does? |
| 1336 return dragged_bounds.x() <= mid_x; | 1362 return dragged_bounds.x() <= mid_x; |
| 1337 } | 1363 } |
| 1338 | 1364 |
| 1339 int TabDragController::GetInsertionIndexForDraggedBoundsStacked( | 1365 int TabDragController::GetInsertionIndexForDraggedBoundsStacked( |
| 1340 const gfx::Rect& dragged_bounds) const { | 1366 const gfx::Rect& dragged_bounds) const { |
| 1341 StackedTabStripLayout* touch_layout = attached_tabstrip_->touch_layout_.get(); | 1367 StackedTabStripLayout* touch_layout = attached_tabstrip_->touch_layout_.get(); |
| 1342 int active_index = touch_layout->active_index(); | 1368 int active_index = touch_layout->active_index(); |
| 1343 // Search from the active index to the front of the tabstrip. Do this as tabs | 1369 // Search from the active index to the front of the tabstrip. Do this as tabs |
| 1344 // overlap each other from the active index. | 1370 // overlap each other from the active index. |
| 1345 int index = GetInsertionIndexFrom(dragged_bounds, active_index, -1); | 1371 int index = GetInsertionIndexFromReversed(dragged_bounds, active_index); |
| 1346 if (index != active_index) | 1372 if (index != active_index) |
| 1347 return index; | 1373 return index; |
| 1348 if (index == -1) | 1374 if (index == -1) |
| 1349 return GetInsertionIndexFrom(dragged_bounds, active_index + 1, 1); | 1375 return GetInsertionIndexFrom(dragged_bounds, active_index + 1); |
| 1350 | 1376 |
| 1351 // The position to drag to corresponds to the active tab. If the next/previous | 1377 // The position to drag to corresponds to the active tab. If the next/previous |
| 1352 // tab is stacked, then shorten the distance used to determine insertion | 1378 // tab is stacked, then shorten the distance used to determine insertion |
| 1353 // bounds. We do this as GetInsertionIndexFrom() uses the bounds of the | 1379 // bounds. We do this as GetInsertionIndexFrom() uses the bounds of the |
| 1354 // tabs. When tabs are stacked the next/previous tab is on top of the tab. | 1380 // tabs. When tabs are stacked the next/previous tab is on top of the tab. |
| 1355 if (active_index + 1 < attached_tabstrip_->tab_count() && | 1381 if (active_index + 1 < attached_tabstrip_->tab_count() && |
| 1356 touch_layout->IsStacked(active_index + 1)) { | 1382 touch_layout->IsStacked(active_index + 1)) { |
| 1357 index = GetInsertionIndexFrom(dragged_bounds, active_index + 1, 1); | 1383 index = GetInsertionIndexFrom(dragged_bounds, active_index + 1); |
| 1358 if (index == -1 && ShouldDragToNextStackedTab(dragged_bounds, active_index)) | 1384 if (index == -1 && ShouldDragToNextStackedTab(dragged_bounds, active_index)) |
| 1359 index = active_index + 1; | 1385 index = active_index + 1; |
| 1360 else if (index == -1) | 1386 else if (index == -1) |
| 1361 index = active_index; | 1387 index = active_index; |
| 1362 } else if (ShouldDragToPreviousStackedTab(dragged_bounds, active_index)) { | 1388 } else if (ShouldDragToPreviousStackedTab(dragged_bounds, active_index)) { |
| 1363 index = active_index - 1; | 1389 index = active_index - 1; |
| 1364 } | 1390 } |
| 1365 return index; | 1391 return index; |
| 1366 } | 1392 } |
| 1367 | 1393 |
| (...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1921 it != browser_list->end(); ++it) { | 1947 it != browser_list->end(); ++it) { |
| 1922 if ((*it)->tab_strip_model()->empty()) | 1948 if ((*it)->tab_strip_model()->empty()) |
| 1923 exclude.insert((*it)->window()->GetNativeWindow()); | 1949 exclude.insert((*it)->window()->GetNativeWindow()); |
| 1924 } | 1950 } |
| 1925 #endif | 1951 #endif |
| 1926 return GetLocalProcessWindowAtPoint(host_desktop_type_, | 1952 return GetLocalProcessWindowAtPoint(host_desktop_type_, |
| 1927 screen_point, | 1953 screen_point, |
| 1928 exclude); | 1954 exclude); |
| 1929 | 1955 |
| 1930 } | 1956 } |
| OLD | NEW |