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 #include "base/sys_string_conversions.h" | 7 #include "base/sys_string_conversions.h" |
8 #include "chrome/app/chrome_dll_resource.h" | 8 #include "chrome/app/chrome_dll_resource.h" |
9 #include "chrome/browser/browser.h" | 9 #include "chrome/browser/browser.h" |
10 #include "chrome/browser/profile.h" | 10 #include "chrome/browser/profile.h" |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 if (index >= 0 && tabModel_->ContainsIndex(index)) | 129 if (index >= 0 && tabModel_->ContainsIndex(index)) |
130 tabModel_->CloseTabContentsAt(index); | 130 tabModel_->CloseTabContentsAt(index); |
131 } else { | 131 } else { |
132 // Use the standard window close if this is the last tab | 132 // Use the standard window close if this is the last tab |
133 // this prevents the tab from being removed from the model until after | 133 // this prevents the tab from being removed from the model until after |
134 // the window dissapears | 134 // the window dissapears |
135 [[tabView_ window] performClose:nil]; | 135 [[tabView_ window] performClose:nil]; |
136 } | 136 } |
137 } | 137 } |
138 | 138 |
139 | |
140 - (void)insertPlaceholderForTab:(TabView*)tab | 139 - (void)insertPlaceholderForTab:(TabView*)tab |
141 frame:(NSRect)frame | 140 frame:(NSRect)frame |
142 yStretchiness:(CGFloat)yStretchiness { | 141 yStretchiness:(CGFloat)yStretchiness { |
143 placeholderTab_ = tab; | 142 placeholderTab_ = tab; |
144 placeholderFrame_ = frame; | 143 placeholderFrame_ = frame; |
145 placeholderStretchiness_ = yStretchiness; | 144 placeholderStretchiness_ = yStretchiness; |
146 [self layoutTabs]; | 145 [self layoutTabs]; |
147 } | 146 } |
148 | 147 |
149 | |
150 // Lay out all tabs in the order of their TabContentsControllers, which matches | 148 // Lay out all tabs in the order of their TabContentsControllers, which matches |
151 // the ordering in the TabStripModel. This call isn't that expensive, though | 149 // the ordering in the TabStripModel. This call isn't that expensive, though |
152 // it is O(n) in the number of tabs. Tabs will animate to their new position | 150 // it is O(n) in the number of tabs. Tabs will animate to their new position |
153 // if the window is visible. | 151 // if the window is visible. |
154 // TODO(pinkerton): Handle drag placeholders via proxy objects, perhaps a | 152 // TODO(pinkerton): Handle drag placeholders via proxy objects, perhaps a |
155 // subclass of TabContentsController with everything stubbed out or by | 153 // subclass of TabContentsController with everything stubbed out or by |
156 // abstracting a base class interface. | 154 // abstracting a base class interface. |
157 // TODO(pinkerton): Note this doesn't do too well when the number of min-sized | 155 // TODO(pinkerton): Note this doesn't do too well when the number of min-sized |
158 // tabs would cause an overflow. | 156 // tabs would cause an overflow. |
159 - (void)layoutTabs { | 157 - (void)layoutTabs { |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 atIndex:(NSInteger)index | 341 atIndex:(NSInteger)index |
344 loadingOnly:(BOOL)loading { | 342 loadingOnly:(BOOL)loading { |
345 if (!loading) | 343 if (!loading) |
346 [self setTabTitle:[tabArray_ objectAtIndex:index] withContents:contents]; | 344 [self setTabTitle:[tabArray_ objectAtIndex:index] withContents:contents]; |
347 | 345 |
348 TabContentsController* updatedController = | 346 TabContentsController* updatedController = |
349 [tabContentsArray_ objectAtIndex:index]; | 347 [tabContentsArray_ objectAtIndex:index]; |
350 [updatedController tabDidChange:contents]; | 348 [updatedController tabDidChange:contents]; |
351 } | 349 } |
352 | 350 |
| 351 // Called when a tab is moved (usually by drag&drop). Keep our parallel arrays |
| 352 // in sync with the tab strip model. |
| 353 - (void)tabMovedWithContents:(TabContents*)contents |
| 354 fromIndex:(NSInteger)from |
| 355 toIndex:(NSInteger)to { |
| 356 scoped_nsobject<TabContentsController> movedController( |
| 357 [[tabContentsArray_ objectAtIndex:from] retain]); |
| 358 [tabContentsArray_ removeObjectAtIndex:from]; |
| 359 [tabContentsArray_ insertObject:movedController.get() atIndex:to]; |
| 360 scoped_nsobject<TabView> movedView( |
| 361 [[tabArray_ objectAtIndex:from] retain]); |
| 362 [tabArray_ removeObjectAtIndex:from]; |
| 363 [tabArray_ insertObject:movedView.get() atIndex:to]; |
| 364 |
| 365 [self layoutTabs]; |
| 366 } |
| 367 |
353 - (NSView *)selectedTabView { | 368 - (NSView *)selectedTabView { |
354 int selectedIndex = tabModel_->selected_index(); | 369 int selectedIndex = tabModel_->selected_index(); |
355 return [self viewAtIndex:selectedIndex]; | 370 return [self viewAtIndex:selectedIndex]; |
356 } | 371 } |
357 | 372 |
358 - (void)dropTabView:(NSView *)view atIndex:(NSUInteger)index { | 373 // Find the index based on the x coordinate of the placeholder. If there is |
359 // TODO(pinkerton): implement drop | 374 // no placeholder, this returns the end of the tab strip. |
360 NOTIMPLEMENTED(); | 375 - (int)indexOfPlaceholder { |
| 376 double placeholderX = placeholderFrame_.origin.x; |
| 377 int index = 0; |
| 378 int location = 0; |
| 379 const int count = tabModel_->count(); |
| 380 while (index < count) { |
| 381 NSView* curr = [self viewAtIndex:index]; |
| 382 // The placeholder tab works by changing the frame of the tab being dragged |
| 383 // to be the bounds of the placeholder, so we need to skip it while we're |
| 384 // iterating, otherwise we'll end up off by one. Note This only effects |
| 385 // dragging to the right, not to the left. |
| 386 if (curr == placeholderTab_) { |
| 387 index++; |
| 388 continue; |
| 389 } |
| 390 if (placeholderX <= NSMinX([curr frame])) |
| 391 break; |
| 392 index++; |
| 393 location++; |
| 394 } |
| 395 return location; |
| 396 } |
| 397 |
| 398 // Move the given tab at index |from| in this window to the location of the |
| 399 // current placeholder. |
| 400 - (void)moveTabFromIndex:(NSInteger)from { |
| 401 int toIndex = [self indexOfPlaceholder]; |
| 402 tabModel_->MoveTabContentsAt(from, toIndex, true); |
| 403 } |
| 404 |
| 405 // Drop a given TabContents at the location of the current placeholder. If there |
| 406 // is no placeholder, it will go at the end. Used when dragging from another |
| 407 // window when we don't have access to the TabContents as part of our strip. |
| 408 - (void)dropTabContents:(TabContents*)contents { |
| 409 int index = [self indexOfPlaceholder]; |
| 410 |
| 411 // Insert it into this tab strip. We want it in the foreground and to not |
| 412 // inherit the current tab's group. |
| 413 tabModel_->InsertTabContentsAt(index, contents, true, false); |
361 } | 414 } |
362 | 415 |
363 // Return the rect, in WebKit coordinates (flipped), of the window's grow box | 416 // Return the rect, in WebKit coordinates (flipped), of the window's grow box |
364 // in the coordinate system of the content area of the currently selected tab. | 417 // in the coordinate system of the content area of the currently selected tab. |
365 - (NSRect)selectedTabGrowBoxRect { | 418 - (NSRect)selectedTabGrowBoxRect { |
366 int selectedIndex = tabModel_->selected_index(); | 419 int selectedIndex = tabModel_->selected_index(); |
367 if (selectedIndex == TabStripModel::kNoTab) { | 420 if (selectedIndex == TabStripModel::kNoTab) { |
368 // When the window is initially being constructed, there may be no currently | 421 // When the window is initially being constructed, there may be no currently |
369 // selected tab, so pick the first one. If there aren't any, just bail with | 422 // selected tab, so pick the first one. If there aren't any, just bail with |
370 // an empty rect. | 423 // an empty rect. |
371 selectedIndex = 0; | 424 selectedIndex = 0; |
372 } | 425 } |
373 TabContentsController* selectedController = | 426 TabContentsController* selectedController = |
374 [tabContentsArray_ objectAtIndex:selectedIndex]; | 427 [tabContentsArray_ objectAtIndex:selectedIndex]; |
375 if (!selectedController) | 428 if (!selectedController) |
376 return NSZeroRect; | 429 return NSZeroRect; |
377 return [selectedController growBoxRect]; | 430 return [selectedController growBoxRect]; |
378 } | 431 } |
379 | 432 |
380 @end | 433 @end |
OLD | NEW |