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 |