| OLD | NEW |
| 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 #import "chrome/browser/cocoa/tab_strip_controller.h" | 5 #import "chrome/browser/cocoa/tab_strip_controller.h" |
| 6 | 6 |
| 7 #import <QuartzCore/QuartzCore.h> | 7 #import <QuartzCore/QuartzCore.h> |
| 8 | 8 |
| 9 #include <limits> | 9 #include <limits> |
| 10 #include <string> | 10 #include <string> |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 - (void)layoutTabsWithAnimation:(BOOL)animate | 113 - (void)layoutTabsWithAnimation:(BOOL)animate |
| 114 regenerateSubviews:(BOOL)doUpdate; | 114 regenerateSubviews:(BOOL)doUpdate; |
| 115 - (void)animationDidStopForController:(TabController*)controller | 115 - (void)animationDidStopForController:(TabController*)controller |
| 116 finished:(BOOL)finished; | 116 finished:(BOOL)finished; |
| 117 - (NSInteger)indexFromModelIndex:(NSInteger)index; | 117 - (NSInteger)indexFromModelIndex:(NSInteger)index; |
| 118 - (NSInteger)numberOfOpenTabs; | 118 - (NSInteger)numberOfOpenTabs; |
| 119 - (NSInteger)numberOfOpenPinnedTabs; | 119 - (NSInteger)numberOfOpenPinnedTabs; |
| 120 - (NSInteger)numberOfOpenUnpinnedTabs; | 120 - (NSInteger)numberOfOpenUnpinnedTabs; |
| 121 - (void)mouseMoved:(NSEvent*)event; | 121 - (void)mouseMoved:(NSEvent*)event; |
| 122 - (void)setTabTrackingAreasEnabled:(BOOL)enabled; | 122 - (void)setTabTrackingAreasEnabled:(BOOL)enabled; |
| 123 - (void)droppingURLsAt:(NSPoint)location | 123 - (void)droppingURLsAt:(NSPoint)point |
| 124 givesIndex:(NSInteger*)index | 124 givesIndex:(NSInteger*)index |
| 125 disposition:(WindowOpenDisposition*)disposition; | 125 disposition:(WindowOpenDisposition*)disposition; |
| 126 @end | 126 @end |
| 127 | 127 |
| 128 // A simple view class that prevents the Window Server from dragging the area | 128 // A simple view class that prevents the Window Server from dragging the area |
| 129 // behind tabs. Sometimes core animation confuses it. Unfortunately, it can also | 129 // behind tabs. Sometimes core animation confuses it. Unfortunately, it can also |
| 130 // falsely pick up clicks during rapid tab closure, so we have to account for | 130 // falsely pick up clicks during rapid tab closure, so we have to account for |
| 131 // that. | 131 // that. |
| 132 @interface TabStripControllerDragBlockingView : NSView { | 132 @interface TabStripControllerDragBlockingView : NSView { |
| 133 TabStripController* controller_; // weak; owns us | 133 TabStripController* controller_; // weak; owns us |
| (...skipping 1295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1429 [subviews addObject:tabView]; | 1429 [subviews addObject:tabView]; |
| 1430 } | 1430 } |
| 1431 } | 1431 } |
| 1432 if (selectedTabView) { | 1432 if (selectedTabView) { |
| 1433 [subviews addObject:selectedTabView]; | 1433 [subviews addObject:selectedTabView]; |
| 1434 } | 1434 } |
| 1435 [tabStripView_ setSubviews:subviews]; | 1435 [tabStripView_ setSubviews:subviews]; |
| 1436 [self setTabTrackingAreasEnabled:mouseInside_]; | 1436 [self setTabTrackingAreasEnabled:mouseInside_]; |
| 1437 } | 1437 } |
| 1438 | 1438 |
| 1439 // Get the index and disposition for a potential URL(s) drop given a location | 1439 // Get the index and disposition for a potential URL(s) drop given a point (in |
| 1440 // (in window base coordinates). It considers x coordinate of the given | 1440 // the |TabStripView|'s coordinates). It considers only the x-coordinate of the |
| 1441 // location. If it's in the "middle" of a tab, it drops on that tab. If it's to | 1441 // given point. If it's in the "middle" of a tab, it drops on that tab. If it's |
| 1442 // the left, it inserts to the left, and similarly for the right. | 1442 // to the left, it inserts to the left, and similarly for the right. |
| 1443 - (void)droppingURLsAt:(NSPoint)location | 1443 - (void)droppingURLsAt:(NSPoint)point |
| 1444 givesIndex:(NSInteger*)index | 1444 givesIndex:(NSInteger*)index |
| 1445 disposition:(WindowOpenDisposition*)disposition { | 1445 disposition:(WindowOpenDisposition*)disposition { |
| 1446 // Proportion of the tab which is considered the "middle" (and causes things | 1446 // Proportion of the tab which is considered the "middle" (and causes things |
| 1447 // to drop on that tab). | 1447 // to drop on that tab). |
| 1448 const double kMiddleProportion = 0.5; | 1448 const double kMiddleProportion = 0.5; |
| 1449 const double kLRProportion = (1.0 - kMiddleProportion) / 2.0; | 1449 const double kLRProportion = (1.0 - kMiddleProportion) / 2.0; |
| 1450 | 1450 |
| 1451 DCHECK(index && disposition); | 1451 DCHECK(index && disposition); |
| 1452 NSInteger i = 0; | 1452 NSInteger i = 0; |
| 1453 for (TabController* tab in tabArray_.get()) { | 1453 for (TabController* tab in tabArray_.get()) { |
| 1454 NSView* view = [tab view]; | 1454 NSView* view = [tab view]; |
| 1455 DCHECK([view isKindOfClass:[TabView class]]); | 1455 DCHECK([view isKindOfClass:[TabView class]]); |
| 1456 | 1456 |
| 1457 // Recall that |-[NSView frame]| is in its superview's coordinates, so a | 1457 // Recall that |-[NSView frame]| is in its superview's coordinates, so a |
| 1458 // |TabView|'s frame is in the coordinates of the |TabStripView|. | 1458 // |TabView|'s frame is in the coordinates of the |TabStripView| (which |
| 1459 NSRect frame = [tabStripView_ convertRectToBase:[view frame]]; | 1459 // matches the coordinate system of |point|). |
| 1460 NSRect frame = [view frame]; |
| 1460 | 1461 |
| 1461 // Modify the frame to make it "unoverlapped". | 1462 // Modify the frame to make it "unoverlapped". |
| 1462 frame.origin.x += kTabOverlap / 2.0; | 1463 frame.origin.x += kTabOverlap / 2.0; |
| 1463 frame.size.width -= kTabOverlap; | 1464 frame.size.width -= kTabOverlap; |
| 1464 if (frame.size.width < 1.0) | 1465 if (frame.size.width < 1.0) |
| 1465 frame.size.width = 1.0; // try to avoid complete failure | 1466 frame.size.width = 1.0; // try to avoid complete failure |
| 1466 | 1467 |
| 1467 // Drop in a new tab to the left of tab |i|? | 1468 // Drop in a new tab to the left of tab |i|? |
| 1468 if (location.x < (frame.origin.x + kLRProportion * frame.size.width)) { | 1469 if (point.x < (frame.origin.x + kLRProportion * frame.size.width)) { |
| 1469 *index = i; | 1470 *index = i; |
| 1470 *disposition = NEW_FOREGROUND_TAB; | 1471 *disposition = NEW_FOREGROUND_TAB; |
| 1471 return; | 1472 return; |
| 1472 } | 1473 } |
| 1473 | 1474 |
| 1474 // Drop on tab |i|? | 1475 // Drop on tab |i|? |
| 1475 if (location.x <= (frame.origin.x + | 1476 if (point.x <= (frame.origin.x + |
| 1476 (1.0 - kLRProportion) * frame.size.width)) { | 1477 (1.0 - kLRProportion) * frame.size.width)) { |
| 1477 *index = i; | 1478 *index = i; |
| 1478 *disposition = CURRENT_TAB; | 1479 *disposition = CURRENT_TAB; |
| 1479 return; | 1480 return; |
| 1480 } | 1481 } |
| 1481 | 1482 |
| 1482 // (Dropping in a new tab to the right of tab |i| will be taken care of in | 1483 // (Dropping in a new tab to the right of tab |i| will be taken care of in |
| 1483 // the next iteration.) | 1484 // the next iteration.) |
| 1484 i++; | 1485 i++; |
| 1485 } | 1486 } |
| 1486 | 1487 |
| 1487 // If we've made it here, we want to append a new tab to the end. | 1488 // If we've made it here, we want to append a new tab to the end. |
| 1488 *index = -1; | 1489 *index = -1; |
| 1489 *disposition = NEW_FOREGROUND_TAB; | 1490 *disposition = NEW_FOREGROUND_TAB; |
| 1490 } | 1491 } |
| 1491 | 1492 |
| 1492 // Drop URLs at the given location. | 1493 // (URLDropTargetController protocol) |
| 1493 - (void)dropURLs:(NSArray*)urls at:(NSPoint)location { | 1494 - (void)dropURLs:(NSArray*)urls inView:(NSView*)view at:(NSPoint)point { |
| 1495 DCHECK_EQ(view, tabStripView_.get()); |
| 1496 |
| 1494 if ([urls count] < 1) { | 1497 if ([urls count] < 1) { |
| 1495 NOTREACHED(); | 1498 NOTREACHED(); |
| 1496 return; | 1499 return; |
| 1497 } | 1500 } |
| 1498 | 1501 |
| 1499 //TODO(viettrungluu): dropping multiple URLs. | 1502 //TODO(viettrungluu): dropping multiple URLs. |
| 1500 if ([urls count] > 1) | 1503 if ([urls count] > 1) |
| 1501 NOTIMPLEMENTED(); | 1504 NOTIMPLEMENTED(); |
| 1502 | 1505 |
| 1503 // Get the first URL and fix it up. | 1506 // Get the first URL and fix it up. |
| 1504 GURL url(URLFixerUpper::FixupURL( | 1507 GURL url(URLFixerUpper::FixupURL( |
| 1505 base::SysNSStringToUTF8([urls objectAtIndex:0]), std::string())); | 1508 base::SysNSStringToUTF8([urls objectAtIndex:0]), std::string())); |
| 1506 | 1509 |
| 1507 // Get the index and disposition. | 1510 // Get the index and disposition. |
| 1508 NSInteger index; | 1511 NSInteger index; |
| 1509 WindowOpenDisposition disposition; | 1512 WindowOpenDisposition disposition; |
| 1510 [self droppingURLsAt:location | 1513 [self droppingURLsAt:point |
| 1511 givesIndex:&index | 1514 givesIndex:&index |
| 1512 disposition:&disposition]; | 1515 disposition:&disposition]; |
| 1513 | 1516 |
| 1514 // Either insert a new tab or open in a current tab. | 1517 // Either insert a new tab or open in a current tab. |
| 1515 switch (disposition) { | 1518 switch (disposition) { |
| 1516 case NEW_FOREGROUND_TAB: | 1519 case NEW_FOREGROUND_TAB: |
| 1517 UserMetrics::RecordAction("Tab_DropURLBetweenTabs", browser_->profile()); | 1520 UserMetrics::RecordAction("Tab_DropURLBetweenTabs", browser_->profile()); |
| 1518 browser_->AddTabWithURL(url, GURL(), PageTransition::TYPED, true, index, | 1521 browser_->AddTabWithURL(url, GURL(), PageTransition::TYPED, true, index, |
| 1519 true, NULL); | 1522 true, NULL); |
| 1520 break; | 1523 break; |
| 1521 case CURRENT_TAB: | 1524 case CURRENT_TAB: |
| 1522 UserMetrics::RecordAction("Tab_DropURLOnTab", browser_->profile()); | 1525 UserMetrics::RecordAction("Tab_DropURLOnTab", browser_->profile()); |
| 1523 tabStripModel_->GetTabContentsAt(index)->OpenURL(url, GURL(), CURRENT_TAB, | 1526 tabStripModel_->GetTabContentsAt(index)->OpenURL(url, GURL(), CURRENT_TAB, |
| 1524 PageTransition::TYPED); | 1527 PageTransition::TYPED); |
| 1525 tabStripModel_->SelectTabContentsAt(index, true); | 1528 tabStripModel_->SelectTabContentsAt(index, true); |
| 1526 break; | 1529 break; |
| 1527 default: | 1530 default: |
| 1528 NOTIMPLEMENTED(); | 1531 NOTIMPLEMENTED(); |
| 1529 } | 1532 } |
| 1530 } | 1533 } |
| 1531 | 1534 |
| 1532 // Update (possibly showing) the indicator which indicates where an URL drop | 1535 // (URLDropTargetController protocol) |
| 1533 // would happen. | 1536 - (void)indicateDropURLsInView:(NSView*)view at:(NSPoint)point { |
| 1534 - (void)indicateDropURLsAt:(NSPoint)location { | 1537 DCHECK_EQ(view, tabStripView_.get()); |
| 1538 |
| 1535 // The minimum y-coordinate at which one should consider place the arrow. | 1539 // The minimum y-coordinate at which one should consider place the arrow. |
| 1536 const CGFloat arrowBaseY = 25; | 1540 const CGFloat arrowBaseY = 25; |
| 1537 | 1541 |
| 1538 NSInteger index; | 1542 NSInteger index; |
| 1539 WindowOpenDisposition disposition; | 1543 WindowOpenDisposition disposition; |
| 1540 [self droppingURLsAt:location | 1544 [self droppingURLsAt:point |
| 1541 givesIndex:&index | 1545 givesIndex:&index |
| 1542 disposition:&disposition]; | 1546 disposition:&disposition]; |
| 1543 | 1547 |
| 1544 NSPoint arrowPos = NSMakePoint(0, arrowBaseY); | 1548 NSPoint arrowPos = NSMakePoint(0, arrowBaseY); |
| 1545 if (index == -1) { | 1549 if (index == -1) { |
| 1546 // Append a tab at the end. | 1550 // Append a tab at the end. |
| 1547 DCHECK(disposition == NEW_FOREGROUND_TAB); | 1551 DCHECK(disposition == NEW_FOREGROUND_TAB); |
| 1548 NSInteger lastIndex = [tabArray_ count] - 1; | 1552 NSInteger lastIndex = [tabArray_ count] - 1; |
| 1549 NSRect overRect = [[[tabArray_ objectAtIndex:lastIndex] view] frame]; | 1553 NSRect overRect = [[[tabArray_ objectAtIndex:lastIndex] view] frame]; |
| 1550 arrowPos.x = overRect.origin.x + overRect.size.width - kTabOverlap / 2.0; | 1554 arrowPos.x = overRect.origin.x + overRect.size.width - kTabOverlap / 2.0; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1562 default: | 1566 default: |
| 1563 NOTREACHED(); | 1567 NOTREACHED(); |
| 1564 } | 1568 } |
| 1565 } | 1569 } |
| 1566 | 1570 |
| 1567 [tabStripView_ setDropArrowPosition:arrowPos]; | 1571 [tabStripView_ setDropArrowPosition:arrowPos]; |
| 1568 [tabStripView_ setDropArrowShown:YES]; | 1572 [tabStripView_ setDropArrowShown:YES]; |
| 1569 [tabStripView_ setNeedsDisplay:YES]; | 1573 [tabStripView_ setNeedsDisplay:YES]; |
| 1570 } | 1574 } |
| 1571 | 1575 |
| 1572 // Hide the indicator which indicates where an URL drop would happen. | 1576 // (URLDropTargetController protocol) |
| 1573 - (void)hideDropURLsIndicator { | 1577 - (void)hideDropURLsIndicatorInView:(NSView*)view { |
| 1578 DCHECK_EQ(view, tabStripView_.get()); |
| 1579 |
| 1574 if ([tabStripView_ dropArrowShown]) { | 1580 if ([tabStripView_ dropArrowShown]) { |
| 1575 [tabStripView_ setDropArrowShown:NO]; | 1581 [tabStripView_ setDropArrowShown:NO]; |
| 1576 [tabStripView_ setNeedsDisplay:YES]; | 1582 [tabStripView_ setNeedsDisplay:YES]; |
| 1577 } | 1583 } |
| 1578 } | 1584 } |
| 1579 | 1585 |
| 1580 - (GTMWindowSheetController*)sheetController { | 1586 - (GTMWindowSheetController*)sheetController { |
| 1581 if (!sheetController_.get()) | 1587 if (!sheetController_.get()) |
| 1582 sheetController_.reset([[GTMWindowSheetController alloc] | 1588 sheetController_.reset([[GTMWindowSheetController alloc] |
| 1583 initWithWindow:[switchView_ window] delegate:self]); | 1589 initWithWindow:[switchView_ window] delegate:self]); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1672 // Show next sheet | 1678 // Show next sheet |
| 1673 NSWindowController* controller = [[tab window] windowController]; | 1679 NSWindowController* controller = [[tab window] windowController]; |
| 1674 DCHECK([controller isKindOfClass:[BrowserWindowController class]]); | 1680 DCHECK([controller isKindOfClass:[BrowserWindowController class]]); |
| 1675 windows.front()->Realize( | 1681 windows.front()->Realize( |
| 1676 static_cast<BrowserWindowController*>(controller)); | 1682 static_cast<BrowserWindowController*>(controller)); |
| 1677 } | 1683 } |
| 1678 } | 1684 } |
| 1679 } | 1685 } |
| 1680 | 1686 |
| 1681 @end | 1687 @end |
| OLD | NEW |