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 |