Chromium Code Reviews| 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 #import "chrome/browser/ui/cocoa/tabs/tab_controller.h" | 5 #import "chrome/browser/ui/cocoa/tabs/tab_controller.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 | 8 |
| 9 #include "base/mac/bundle_locations.h" | 9 #include "base/mac/bundle_locations.h" |
| 10 #include "base/mac/mac_util.h" | 10 #include "base/mac/mac_util.h" |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 266 [self updateVisibility]; | 266 [self updateVisibility]; |
| 267 | 267 |
| 268 if (iconView_) | 268 if (iconView_) |
| 269 [[self view] addSubview:iconView_]; | 269 [[self view] addSubview:iconView_]; |
| 270 } | 270 } |
| 271 | 271 |
| 272 - (NSTextField*)titleView { | 272 - (NSTextField*)titleView { |
| 273 return titleView_; | 273 return titleView_; |
| 274 } | 274 } |
| 275 | 275 |
| 276 - (NSView*)audioIndicatorView { | |
| 277 return audioIndicatorView_; | |
| 278 } | |
| 279 | |
| 280 - (void)setAudioIndicatorView:(NSView*)audioIndicatorView { | |
| 281 [audioIndicatorView_ removeFromSuperview]; | |
| 282 audioIndicatorView_.reset([audioIndicatorView retain]); | |
| 283 [self updateVisibility]; | |
| 284 if (audioIndicatorView_) | |
| 285 [[self view] addSubview:audioIndicatorView_]; | |
| 286 } | |
| 287 | |
| 276 - (HoverCloseButton*)closeButton { | 288 - (HoverCloseButton*)closeButton { |
| 277 return closeButton_; | 289 return closeButton_; |
| 278 } | 290 } |
| 279 | 291 |
| 280 - (NSString*)toolTip { | 292 - (NSString*)toolTip { |
| 281 return [[self tabView] toolTipText]; | 293 return [[self tabView] toolTipText]; |
| 282 } | 294 } |
| 283 | 295 |
| 284 // Return a rough approximation of the number of icons we could fit in the | 296 // Return a rough approximation of the number of icons we could fit in the |
| 285 // tab. We never actually do this, but it's a helpful guide for determining | 297 // tab. We never actually do this, but it's a helpful guide for determining |
| 286 // how much space we have available. | 298 // how much space we have available. |
| 287 - (int)iconCapacity { | 299 - (int)iconCapacity { |
| 288 CGFloat width = NSMaxX([closeButton_ frame]) - NSMinX(originalIconFrame_); | 300 CGFloat width = NSMaxX([closeButton_ frame]) - NSMinX(originalIconFrame_); |
| 289 CGFloat iconWidth = NSWidth(originalIconFrame_); | 301 const int kPaddingBetweenIcons = 2; |
| 302 CGFloat iconWidth = NSWidth(originalIconFrame_) + kPaddingBetweenIcons; | |
| 290 | 303 |
| 291 return width / iconWidth; | 304 return width / iconWidth; |
| 292 } | 305 } |
| 293 | 306 |
| 294 // Returns YES if we should show the icon. When tabs get too small, we clip | 307 // Returns YES if we should show the icon. When tabs get too small, we clip |
| 295 // the favicon before the close button for selected tabs, and prefer the | 308 // the favicon before the close button for selected tabs, and prefer the |
| 296 // favicon for unselected tabs. The icon can also be suppressed more directly | 309 // favicon for unselected tabs. Exception: We clip the favicon before the audio |
| 310 // indicator in all cases. The icon can also be suppressed more directly | |
| 297 // by clearing iconView_. | 311 // by clearing iconView_. |
| 298 - (BOOL)shouldShowIcon { | 312 - (BOOL)shouldShowIcon { |
| 299 if (!iconView_) | 313 if (!iconView_) |
| 300 return NO; | 314 return NO; |
| 315 const BOOL should_show_audio_indicator = [self shouldShowAudioIndicator]; | |
|
sail
2013/09/11 19:18:37
should use camel case
miu
2013/09/11 21:35:06
Whoops; missed that one. Done.
| |
| 316 if ([self mini]) | |
| 317 return !should_show_audio_indicator; | |
| 318 int required_capacity = should_show_audio_indicator ? 2 : 1; | |
| 319 if ([self selected]) { | |
| 320 // Active tabs give priority to the close button, then the audio indicator, | |
| 321 // then the favicon. | |
| 322 ++required_capacity; | |
| 323 } else { | |
| 324 // Non-selected tabs give priority to the audio indicator, then the favicon, | |
| 325 // and finally the close button. | |
| 326 } | |
| 327 return [self iconCapacity] >= required_capacity; | |
| 328 } | |
| 301 | 329 |
| 330 // Returns YES if we should show the audio indicator. When tabs get too small, | |
| 331 // we clip the audio indicator before the close button for selected tabs, and | |
| 332 // prefer the audio indicator for unselected tabs. | |
| 333 - (BOOL)shouldShowAudioIndicator { | |
| 334 if (!audioIndicatorView_) | |
| 335 return NO; | |
| 302 if ([self mini]) | 336 if ([self mini]) |
| 303 return YES; | 337 return YES; |
| 304 | 338 if ([self selected]) { |
| 305 int iconCapacity = [self iconCapacity]; | 339 // The active tab clips the audio indicator before the close button. |
| 306 if ([self selected]) | 340 return [self iconCapacity] >= 2; |
| 307 return iconCapacity >= 2; | 341 } |
| 308 return iconCapacity >= 1; | 342 // Non-selected tabs clip close button before the audio indicator. |
| 343 return [self iconCapacity] >= 1; | |
| 309 } | 344 } |
| 310 | 345 |
| 311 // Returns YES if we should be showing the close button. The selected tab | 346 // Returns YES if we should be showing the close button. The selected tab |
| 312 // always shows the close button. | 347 // always shows the close button. |
| 313 - (BOOL)shouldShowCloseButton { | 348 - (BOOL)shouldShowCloseButton { |
| 314 if ([self mini]) | 349 if ([self mini]) |
| 315 return NO; | 350 return NO; |
| 316 return ([self selected] || [self iconCapacity] >= 3); | 351 return ([self selected] || [self iconCapacity] >= 3); |
| 317 } | 352 } |
| 318 | 353 |
| 319 - (void)updateVisibility { | 354 - (void)updateVisibility { |
| 320 // iconView_ may have been replaced or it may be nil, so [iconView_ isHidden] | 355 // iconView_ may have been replaced or it may be nil, so [iconView_ isHidden] |
| 321 // won't work. Instead, the state of the icon is tracked separately in | 356 // won't work. Instead, the state of the icon is tracked separately in |
| 322 // isIconShowing_. | 357 // isIconShowing_. |
| 323 BOOL newShowIcon = [self shouldShowIcon]; | 358 BOOL newShowIcon = [self shouldShowIcon]; |
| 324 | 359 |
| 325 [iconView_ setHidden:!newShowIcon]; | 360 [iconView_ setHidden:!newShowIcon]; |
| 326 isIconShowing_ = newShowIcon; | 361 isIconShowing_ = newShowIcon; |
| 327 | 362 |
| 328 // If the tab is a mini-tab, hide the title. | 363 // If the tab is a mini-tab, hide the title. |
| 329 [titleView_ setHidden:[self mini]]; | 364 [titleView_ setHidden:[self mini]]; |
| 330 | 365 |
| 331 BOOL newShowCloseButton = [self shouldShowCloseButton]; | 366 BOOL newShowCloseButton = [self shouldShowCloseButton]; |
| 332 | 367 |
| 333 [closeButton_ setHidden:!newShowCloseButton]; | 368 [closeButton_ setHidden:!newShowCloseButton]; |
| 334 | 369 |
| 370 BOOL newShowAudioIndicator = [self shouldShowAudioIndicator]; | |
| 371 | |
| 372 if (audioIndicatorView_) { | |
| 373 [audioIndicatorView_ setHidden:!newShowAudioIndicator]; | |
| 374 | |
| 375 NSRect newFrame = [audioIndicatorView_ frame]; | |
| 376 if ([self app] || [self mini]) { | |
| 377 // Tab is pinned: Position the audio indicator in the center. | |
| 378 const CGFloat tabWidth = [self app] ? | |
| 379 [TabController appTabWidth] : [TabController miniTabWidth]; | |
| 380 newFrame.origin.x = (tabWidth - NSWidth(newFrame)) / 2; | |
| 381 newFrame.origin.y = NSMinY(originalIconFrame_) - | |
| 382 (NSHeight(newFrame) - NSHeight(originalIconFrame_)) / 2; | |
| 383 } else { | |
| 384 // The Frame for the audioIndicatorView_ depends on whether iconView_ | |
| 385 // and/or closeButton_ are visible, and where they have been positioned. | |
| 386 const NSRect closeButtonFrame = [closeButton_ frame]; | |
| 387 newFrame.origin.x = NSMinX(closeButtonFrame); | |
| 388 // Position to the left of the close button when it is showing. | |
| 389 if (newShowCloseButton) | |
| 390 newFrame.origin.x -= NSWidth(newFrame); | |
| 391 // Audio indicator is centered vertically, with respect to closeButton_. | |
| 392 newFrame.origin.y = NSMinY(closeButtonFrame) - | |
| 393 (NSHeight(newFrame) - NSHeight(closeButtonFrame)) / 2; | |
| 394 } | |
| 395 [audioIndicatorView_ setFrame:newFrame]; | |
|
sail
2013/09/11 19:18:37
The frame should have integral values. You can eit
miu
2013/09/11 21:35:06
Done.
| |
| 396 } | |
| 397 | |
| 335 // Adjust the title view based on changes to the icon's and close button's | 398 // Adjust the title view based on changes to the icon's and close button's |
| 336 // visibility. | 399 // visibility. |
| 337 NSRect oldTitleFrame = [titleView_ frame]; | 400 NSRect oldTitleFrame = [titleView_ frame]; |
| 338 NSRect newTitleFrame; | 401 NSRect newTitleFrame; |
| 339 newTitleFrame.size.height = oldTitleFrame.size.height; | 402 newTitleFrame.size.height = oldTitleFrame.size.height; |
| 340 newTitleFrame.origin.y = oldTitleFrame.origin.y; | 403 newTitleFrame.origin.y = oldTitleFrame.origin.y; |
| 341 | 404 |
| 342 if (newShowIcon) { | 405 if (newShowIcon) { |
| 343 newTitleFrame.origin.x = originalIconFrame_.origin.x + iconTitleXOffset_; | 406 newTitleFrame.origin.x = originalIconFrame_.origin.x + iconTitleXOffset_; |
| 344 } else { | 407 } else { |
| 345 newTitleFrame.origin.x = originalIconFrame_.origin.x; | 408 newTitleFrame.origin.x = originalIconFrame_.origin.x; |
| 346 } | 409 } |
| 347 | 410 |
| 348 if (newShowCloseButton) { | 411 if (newShowAudioIndicator) { |
| 412 newTitleFrame.size.width = NSMinX([audioIndicatorView_ frame]) - | |
| 413 newTitleFrame.origin.x; | |
| 414 } else if (newShowCloseButton) { | |
| 349 newTitleFrame.size.width = NSMinX([closeButton_ frame]) - | 415 newTitleFrame.size.width = NSMinX([closeButton_ frame]) - |
| 350 newTitleFrame.origin.x; | 416 newTitleFrame.origin.x; |
| 351 } else { | 417 } else { |
| 352 newTitleFrame.size.width = NSMaxX([closeButton_ frame]) - | 418 newTitleFrame.size.width = NSMaxX([closeButton_ frame]) - |
| 353 newTitleFrame.origin.x; | 419 newTitleFrame.origin.x; |
| 354 } | 420 } |
| 355 | 421 |
| 356 [titleView_ setFrame:newTitleFrame]; | 422 [titleView_ setFrame:newTitleFrame]; |
| 357 } | 423 } |
| 358 | 424 |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 384 // TabStripDragController. | 450 // TabStripDragController. |
| 385 - (BOOL)tabCanBeDragged:(TabController*)controller { | 451 - (BOOL)tabCanBeDragged:(TabController*)controller { |
| 386 return [[target_ dragController] tabCanBeDragged:controller]; | 452 return [[target_ dragController] tabCanBeDragged:controller]; |
| 387 } | 453 } |
| 388 | 454 |
| 389 - (void)maybeStartDrag:(NSEvent*)event forTab:(TabController*)tab { | 455 - (void)maybeStartDrag:(NSEvent*)event forTab:(TabController*)tab { |
| 390 [[target_ dragController] maybeStartDrag:event forTab:tab]; | 456 [[target_ dragController] maybeStartDrag:event forTab:tab]; |
| 391 } | 457 } |
| 392 | 458 |
| 393 @end | 459 @end |
| OLD | NEW |