| 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/cocoa/gradient_button_cell.h" | 5 #include "chrome/browser/ui/cocoa/gradient_button_cell.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #import "base/mac/scoped_nsobject.h" | 10 #import "base/mac/scoped_nsobject.h" |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 YES : NO; | 199 YES : NO; |
| 200 } | 200 } |
| 201 | 201 |
| 202 #if 1 | 202 #if 1 |
| 203 // If we are not continuously pulsing, perform a pulse animation to | 203 // If we are not continuously pulsing, perform a pulse animation to |
| 204 // reflect our new state. | 204 // reflect our new state. |
| 205 - (void)setMouseInside:(BOOL)flag animate:(BOOL)animated { | 205 - (void)setMouseInside:(BOOL)flag animate:(BOOL)animated { |
| 206 isMouseInside_ = flag; | 206 isMouseInside_ = flag; |
| 207 if (pulseState_ != gradient_button_cell::kPulsingContinuous) { | 207 if (pulseState_ != gradient_button_cell::kPulsingContinuous) { |
| 208 if (animated) { | 208 if (animated) { |
| 209 // In Material Design, if the button is already fully on, don't pulse it | |
| 210 // on again if the mouse is within its bounds. | |
| 211 if ([self tag] == kMaterialStandardButtonTypeWithLimitedClickFeedback && | |
| 212 isMouseInside_ && pulseState_ == gradient_button_cell::kPulsedOn) { | |
| 213 return; | |
| 214 } | |
| 215 | |
| 216 [self setPulseState:(isMouseInside_ ? gradient_button_cell::kPulsingOn : | 209 [self setPulseState:(isMouseInside_ ? gradient_button_cell::kPulsingOn : |
| 217 gradient_button_cell::kPulsingOff)]; | 210 gradient_button_cell::kPulsingOff)]; |
| 218 } else { | 211 } else { |
| 219 [self setPulseState:(isMouseInside_ ? gradient_button_cell::kPulsedOn : | 212 [self setPulseState:(isMouseInside_ ? gradient_button_cell::kPulsedOn : |
| 220 gradient_button_cell::kPulsedOff)]; | 213 gradient_button_cell::kPulsedOff)]; |
| 221 } | 214 } |
| 222 } | 215 } |
| 223 } | 216 } |
| 224 #else | 217 #else |
| 225 | 218 |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 } | 312 } |
| 320 | 313 |
| 321 - (void)mouseExited:(NSEvent*)theEvent { | 314 - (void)mouseExited:(NSEvent*)theEvent { |
| 322 [self setMouseInside:NO animate:YES]; | 315 [self setMouseInside:NO animate:YES]; |
| 323 } | 316 } |
| 324 | 317 |
| 325 - (BOOL)isMouseInside { | 318 - (BOOL)isMouseInside { |
| 326 return trackingArea_ && isMouseInside_; | 319 return trackingArea_ && isMouseInside_; |
| 327 } | 320 } |
| 328 | 321 |
| 329 - (BOOL)startTrackingAt:(NSPoint)startPoint inView:(NSView *)controlView { | |
| 330 if ([self tag] == kMaterialStandardButtonTypeWithLimitedClickFeedback) { | |
| 331 // The user has just clicked down in the button. In Material Design, set the | |
| 332 // pulsed (hover) state to off now so that if the user keeps the mouse held | |
| 333 // down while dragging it out of the button's bounds, the button will draw | |
| 334 // itself in its normal state. This is unrelated to dragging the button | |
| 335 // in the button bar, which takes a different path through the code. | |
| 336 [self setPulseState:gradient_button_cell::kPulsedOff]; | |
| 337 } | |
| 338 | |
| 339 return [super startTrackingAt:startPoint inView:controlView]; | |
| 340 } | |
| 341 | |
| 342 // Since we have our own drawWithFrame:, we need to also have our own | 322 // Since we have our own drawWithFrame:, we need to also have our own |
| 343 // logic for determining when the mouse is inside for honoring this | 323 // logic for determining when the mouse is inside for honoring this |
| 344 // request. | 324 // request. |
| 345 - (void)setShowsBorderOnlyWhileMouseInside:(BOOL)showOnly { | 325 - (void)setShowsBorderOnlyWhileMouseInside:(BOOL)showOnly { |
| 346 [super setShowsBorderOnlyWhileMouseInside:showOnly]; | 326 [super setShowsBorderOnlyWhileMouseInside:showOnly]; |
| 347 if (showOnly) { | 327 if (showOnly) { |
| 348 [self updateTrackingAreas]; | 328 [self updateTrackingAreas]; |
| 349 } else { | 329 } else { |
| 350 if (trackingArea_) { | 330 if (trackingArea_) { |
| 351 [[self controlView] removeTrackingArea:trackingArea_]; | 331 [[self controlView] removeTrackingArea:trackingArea_]; |
| 352 trackingArea_.reset(nil); | 332 trackingArea_.reset(nil); |
| 353 if (isMouseInside_) { | 333 if (isMouseInside_) { |
| 354 isMouseInside_ = NO; | 334 isMouseInside_ = NO; |
| 355 [[self controlView] setNeedsDisplay:YES]; | 335 [[self controlView] setNeedsDisplay:YES]; |
| 356 } | 336 } |
| 357 } | 337 } |
| 358 } | 338 } |
| 359 } | 339 } |
| 360 | 340 |
| 361 // TODO(viettrungluu): clean up/reorganize. | 341 // TODO(viettrungluu): clean up/reorganize. |
| 362 - (void)drawBorderAndFillForTheme:(const ui::ThemeProvider*)themeProvider | 342 - (void)drawBorderAndFillForTheme:(const ui::ThemeProvider*)themeProvider |
| 363 controlView:(NSView*)controlView | 343 controlView:(NSView*)controlView |
| 364 innerPath:(NSBezierPath*)innerPath | 344 innerPath:(NSBezierPath*)innerPath |
| 365 showClickedGradient:(BOOL)showClickedGradient | 345 showClickedGradient:(BOOL)showClickedGradient |
| 366 showHighlightGradient:(BOOL)showHighlightGradient | 346 showHighlightGradient:(BOOL)showHighlightGradient |
| 367 hoverAlpha:(CGFloat)hoverAlpha | 347 hoverAlpha:(CGFloat)hoverAlpha |
| 368 active:(BOOL)active | 348 active:(BOOL)active |
| 369 cellFrame:(NSRect)cellFrame | 349 cellFrame:(NSRect)cellFrame |
| 370 defaultGradient:(NSGradient*)defaultGradient { | 350 defaultGradient:(NSGradient*)defaultGradient { |
| 371 // For Material Design, draw a solid rounded rect behind the button, based on | |
| 372 // the hover and pressed states. | |
| 373 if ([self tag] == kMaterialStandardButtonTypeWithLimitedClickFeedback) { | |
| 374 const CGFloat kEightPercentAlpha = 0.08; | |
| 375 const CGFloat kFourPercentAlpha = 0.04; | |
| 376 | |
| 377 // The alpha is always at least 8%. Default the color to black. | |
| 378 CGFloat alpha = kEightPercentAlpha; | |
| 379 CGFloat color = 0.0; | |
| 380 // If a dark theme, incrase the opacity slightly and use white. | |
| 381 if ([[controlView window] hasDarkTheme]) { | |
| 382 alpha += kFourPercentAlpha; | |
| 383 color = 1.0; | |
| 384 } | |
| 385 // If clicked or highlighted, the background is slightly more opaque. If not | |
| 386 // clicked or highlighted, adjust the alpha by the animation fade in | |
| 387 // percentage. | |
| 388 if (showClickedGradient || showHighlightGradient) { | |
| 389 alpha += kFourPercentAlpha; | |
| 390 } else { | |
| 391 alpha *= hoverAlpha; | |
| 392 } | |
| 393 | |
| 394 // Fill the path. | |
| 395 [[NSColor colorWithCalibratedWhite:color alpha:alpha] set]; | |
| 396 [innerPath fill]; | |
| 397 return; | |
| 398 } | |
| 399 | |
| 400 BOOL isFlatButton = [self showsBorderOnlyWhileMouseInside]; | 351 BOOL isFlatButton = [self showsBorderOnlyWhileMouseInside]; |
| 401 | 352 |
| 402 // For flat (unbordered when not hovered) buttons, never use the toolbar | 353 // For flat (unbordered when not hovered) buttons, never use the toolbar |
| 403 // button background image, but the modest gradient used for themed buttons. | 354 // button background image, but the modest gradient used for themed buttons. |
| 404 // To make things even more modest, scale the hover alpha down by 40 percent | 355 // To make things even more modest, scale the hover alpha down by 40 percent |
| 405 // unless clicked. | 356 // unless clicked. |
| 406 NSColor* backgroundImageColor; | 357 NSColor* backgroundImageColor; |
| 407 BOOL useThemeGradient; | 358 BOOL useThemeGradient; |
| 408 if (isFlatButton) { | 359 if (isFlatButton) { |
| 409 backgroundImageColor = nil; | 360 backgroundImageColor = nil; |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 [innerPath stroke]; | 454 [innerPath stroke]; |
| 504 } | 455 } |
| 505 | 456 |
| 506 // TODO(viettrungluu): clean this up. | 457 // TODO(viettrungluu): clean this up. |
| 507 // (Private) | 458 // (Private) |
| 508 - (void)getDrawParamsForFrame:(NSRect)cellFrame | 459 - (void)getDrawParamsForFrame:(NSRect)cellFrame |
| 509 inView:(NSView*)controlView | 460 inView:(NSView*)controlView |
| 510 innerFrame:(NSRect*)returnInnerFrame | 461 innerFrame:(NSRect*)returnInnerFrame |
| 511 innerPath:(NSBezierPath**)returnInnerPath | 462 innerPath:(NSBezierPath**)returnInnerPath |
| 512 clipPath:(NSBezierPath**)returnClipPath { | 463 clipPath:(NSBezierPath**)returnClipPath { |
| 513 const CGFloat kLineWidth = [controlView cr_lineWidth]; | 464 const CGFloat lineWidth = [controlView cr_lineWidth]; |
| 514 const CGFloat kHalfLineWidth = kLineWidth / 2.0; | 465 const CGFloat halfLineWidth = lineWidth / 2.0; |
| 515 | 466 |
| 516 NSRect drawFrame = cellFrame; | 467 // Constants from Cole. Will kConstant them once the feedback loop |
| 517 NSRect innerFrame = NSInsetRect(cellFrame, kLineWidth, kLineWidth); | 468 // is complete. |
| 518 CGFloat cornerRadius = 2; | 469 NSRect drawFrame = NSInsetRect(cellFrame, 1.5 * lineWidth, 1.5 * lineWidth); |
| 519 if ([self tag] != kMaterialStandardButtonTypeWithLimitedClickFeedback) { | 470 NSRect innerFrame = NSInsetRect(cellFrame, lineWidth, lineWidth); |
| 520 drawFrame = NSInsetRect(cellFrame, 1.5 * kLineWidth, 1.5 * kLineWidth); | 471 const CGFloat radius = 3; |
| 521 cornerRadius = 3; | |
| 522 } | |
| 523 | 472 |
| 524 ButtonType type = [[(NSControl*)controlView cell] tag]; | 473 ButtonType type = [[(NSControl*)controlView cell] tag]; |
| 525 switch (type) { | 474 switch (type) { |
| 526 case kMiddleButtonType: | 475 case kMiddleButtonType: |
| 527 drawFrame.size.width += 20; | 476 drawFrame.size.width += 20; |
| 528 innerFrame.size.width += 2; | 477 innerFrame.size.width += 2; |
| 529 // Fallthrough | 478 // Fallthrough |
| 530 case kRightButtonType: | 479 case kRightButtonType: |
| 531 drawFrame.origin.x -= 20; | 480 drawFrame.origin.x -= 20; |
| 532 innerFrame.origin.x -= 2; | 481 innerFrame.origin.x -= 2; |
| 533 // Fallthrough | 482 // Fallthrough |
| 534 case kLeftButtonType: | 483 case kLeftButtonType: |
| 535 case kLeftButtonWithShadowType: | 484 case kLeftButtonWithShadowType: |
| 536 drawFrame.size.width += 20; | 485 drawFrame.size.width += 20; |
| 537 innerFrame.size.width += 2; | 486 innerFrame.size.width += 2; |
| 538 default: | 487 default: |
| 539 break; | 488 break; |
| 540 } | 489 } |
| 541 if (type == kLeftButtonWithShadowType) | 490 if (type == kLeftButtonWithShadowType) |
| 542 innerFrame.size.width -= 1.0; | 491 innerFrame.size.width -= 1.0; |
| 543 | 492 |
| 544 // Return results if |return...| not null. | 493 // Return results if |return...| not null. |
| 545 if (returnInnerFrame) | 494 if (returnInnerFrame) |
| 546 *returnInnerFrame = innerFrame; | 495 *returnInnerFrame = innerFrame; |
| 547 if (returnInnerPath) { | 496 if (returnInnerPath) { |
| 548 DCHECK(*returnInnerPath == nil); | 497 DCHECK(*returnInnerPath == nil); |
| 549 *returnInnerPath = [NSBezierPath bezierPathWithRoundedRect:drawFrame | 498 *returnInnerPath = [NSBezierPath bezierPathWithRoundedRect:drawFrame |
| 550 xRadius:cornerRadius | 499 xRadius:radius |
| 551 yRadius:cornerRadius]; | 500 yRadius:radius]; |
| 552 [*returnInnerPath setLineWidth:kLineWidth]; | 501 [*returnInnerPath setLineWidth:lineWidth]; |
| 553 } | 502 } |
| 554 if (returnClipPath) { | 503 if (returnClipPath) { |
| 555 DCHECK(*returnClipPath == nil); | 504 DCHECK(*returnClipPath == nil); |
| 556 NSRect clipPathRect = | 505 NSRect clipPathRect = |
| 557 NSInsetRect(drawFrame, -kHalfLineWidth, -kHalfLineWidth); | 506 NSInsetRect(drawFrame, -halfLineWidth, -halfLineWidth); |
| 558 *returnClipPath = [NSBezierPath | 507 *returnClipPath = [NSBezierPath |
| 559 bezierPathWithRoundedRect:clipPathRect | 508 bezierPathWithRoundedRect:clipPathRect |
| 560 xRadius:cornerRadius + kHalfLineWidth | 509 xRadius:radius + halfLineWidth |
| 561 yRadius:cornerRadius + kHalfLineWidth]; | 510 yRadius:radius + halfLineWidth]; |
| 562 } | 511 } |
| 563 } | 512 } |
| 564 | 513 |
| 565 // TODO(viettrungluu): clean this up. | 514 // TODO(viettrungluu): clean this up. |
| 566 - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { | 515 - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { |
| 567 NSRect innerFrame; | 516 NSRect innerFrame; |
| 568 NSBezierPath* innerPath = nil; | 517 NSBezierPath* innerPath = nil; |
| 569 [self getDrawParamsForFrame:cellFrame | 518 [self getDrawParamsForFrame:cellFrame |
| 570 inView:controlView | 519 inView:controlView |
| 571 innerFrame:&innerFrame | 520 innerFrame:&innerFrame |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 609 ThemeProperties::COLOR_TOOLBAR_BUTTON_STROKE_INACTIVE) : | 558 ThemeProperties::COLOR_TOOLBAR_BUTTON_STROKE_INACTIVE) : |
| 610 [NSColor blackColor]; | 559 [NSColor blackColor]; |
| 611 | 560 |
| 612 [[stroke colorWithAlphaComponent:0.2] set]; | 561 [[stroke colorWithAlphaComponent:0.2] set]; |
| 613 NSRectFillUsingOperation(NSInsetRect(borderRect, 0, 2), | 562 NSRectFillUsingOperation(NSInsetRect(borderRect, 0, 2), |
| 614 NSCompositeSourceOver); | 563 NSCompositeSourceOver); |
| 615 } | 564 } |
| 616 [self drawInteriorWithFrame:innerFrame inView:controlView]; | 565 [self drawInteriorWithFrame:innerFrame inView:controlView]; |
| 617 } | 566 } |
| 618 | 567 |
| 619 - (CGFloat)textStartXOffset { | |
| 620 // 11 is the magic number needed to make this match the native | |
| 621 // NSButtonCell's label display. | |
| 622 return [[self image] size].width + 11; | |
| 623 } | |
| 624 | |
| 625 - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { | 568 - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { |
| 626 const CGFloat lineWidth = [controlView cr_lineWidth]; | 569 const CGFloat lineWidth = [controlView cr_lineWidth]; |
| 627 | 570 |
| 628 if (shouldTheme_) { | 571 if (shouldTheme_) { |
| 629 BOOL isTemplate = [[self image] isTemplate]; | 572 BOOL isTemplate = [[self image] isTemplate]; |
| 630 | 573 |
| 631 gfx::ScopedNSGraphicsContextSaveGState scopedGState; | 574 gfx::ScopedNSGraphicsContextSaveGState scopedGState; |
| 632 | 575 |
| 633 CGContextRef context = | 576 CGContextRef context = |
| 634 (CGContextRef)([[NSGraphicsContext currentContext] graphicsPort]); | 577 (CGContextRef)([[NSGraphicsContext currentContext] graphicsPort]); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 695 // get it to work with NSButtonCell. | 638 // get it to work with NSButtonCell. |
| 696 // TODO(jeremy): Move this to GTM. | 639 // TODO(jeremy): Move this to GTM. |
| 697 - (NSRect)drawTitle:(NSAttributedString*)title | 640 - (NSRect)drawTitle:(NSAttributedString*)title |
| 698 withFrame:(NSRect)cellFrame | 641 withFrame:(NSRect)cellFrame |
| 699 inView:(NSView*)controlView { | 642 inView:(NSView*)controlView { |
| 700 NSSize size = [title size]; | 643 NSSize size = [title size]; |
| 701 | 644 |
| 702 // Empirically, Cocoa will draw an extra 2 pixels past NSWidth(cellFrame) | 645 // Empirically, Cocoa will draw an extra 2 pixels past NSWidth(cellFrame) |
| 703 // before it clips the text. | 646 // before it clips the text. |
| 704 const CGFloat kOverflowBeforeClip = 2; | 647 const CGFloat kOverflowBeforeClip = 2; |
| 705 BOOL isModeMaterial = | 648 BOOL clipping = YES; |
| 706 [self tag] == kMaterialStandardButtonTypeWithLimitedClickFeedback; | |
| 707 // For Material Design we don't want to clip the text. For all other button | |
| 708 // cell modes, we do. | |
| 709 BOOL shouldClipTheTitle = !isModeMaterial; | |
| 710 if (std::floor(size.width) <= (NSWidth(cellFrame) + kOverflowBeforeClip)) { | 649 if (std::floor(size.width) <= (NSWidth(cellFrame) + kOverflowBeforeClip)) { |
| 711 cellFrame.origin.y += ([self verticalTextOffset] - 1); | 650 cellFrame.origin.y += ([self verticalTextOffset] - 1); |
| 712 shouldClipTheTitle = NO; | 651 clipping = NO; |
| 713 } | 652 } |
| 714 | 653 |
| 715 // Gradient is about twice our line height long. | 654 // Gradient is about twice our line height long. |
| 716 CGFloat gradientWidth = MIN(size.height * 2, NSWidth(cellFrame) / 4); | 655 CGFloat gradientWidth = MIN(size.height * 2, NSWidth(cellFrame) / 4); |
| 717 | 656 |
| 718 NSRect solidPart, gradientPart; | 657 NSRect solidPart, gradientPart; |
| 719 NSDivideRect(cellFrame, &gradientPart, &solidPart, gradientWidth, NSMaxXEdge); | 658 NSDivideRect(cellFrame, &gradientPart, &solidPart, gradientWidth, NSMaxXEdge); |
| 720 | 659 |
| 721 // Draw non-gradient part without transparency layer, as light text on a dark | 660 // Draw non-gradient part without transparency layer, as light text on a dark |
| 722 // background looks bad with a gradient layer. | 661 // background looks bad with a gradient layer. |
| 723 NSPoint textOffset = NSZeroPoint; | 662 NSPoint textOffset = NSZeroPoint; |
| 724 { | 663 { |
| 725 gfx::ScopedNSGraphicsContextSaveGState scopedGState; | 664 gfx::ScopedNSGraphicsContextSaveGState scopedGState; |
| 726 if (shouldClipTheTitle) | 665 if (clipping) |
| 727 [NSBezierPath clipRect:solidPart]; | 666 [NSBezierPath clipRect:solidPart]; |
| 728 | 667 |
| 729 CGFloat textLeft = [self textStartXOffset]; | 668 // 11 is the magic number needed to make this match the native |
| 669 // NSButtonCell's label display. |
| 670 CGFloat textLeft = [[self image] size].width + 11; |
| 730 | 671 |
| 731 // For some reason, the height of cellFrame as passed in is totally bogus. | 672 // For some reason, the height of cellFrame as passed in is totally bogus. |
| 732 // For vertical centering purposes, we need the bounds of the containing | 673 // For vertical centering purposes, we need the bounds of the containing |
| 733 // view. | 674 // view. |
| 734 NSRect buttonFrame = [[self controlView] frame]; | 675 NSRect buttonFrame = [[self controlView] frame]; |
| 735 | 676 |
| 736 // Call the vertical offset to match native NSButtonCell's version. | 677 // Call the vertical offset to match native NSButtonCell's version. |
| 737 textOffset = NSMakePoint(textLeft, | 678 textOffset = NSMakePoint(textLeft, |
| 738 (NSHeight(buttonFrame) - size.height) / 2 + | 679 (NSHeight(buttonFrame) - size.height) / 2 + |
| 739 [self verticalTextOffset]); | 680 [self verticalTextOffset]); |
| 740 // WIth Material Design we want an ellipsis if the title is too long to fit, | 681 [title drawAtPoint:textOffset]; |
| 741 // so have to use drawInRect: instead of drawAtPoint:. | |
| 742 if (isModeMaterial) { | |
| 743 NSRect textBounds = NSMakeRect(textOffset.x, | |
| 744 textOffset.y, | |
| 745 NSWidth(buttonFrame) - textOffset.x, | |
| 746 NSHeight(buttonFrame)); | |
| 747 [title drawInRect:textBounds]; | |
| 748 } else { | |
| 749 [title drawAtPoint:textOffset]; | |
| 750 } | |
| 751 } | 682 } |
| 752 | 683 |
| 753 if (!shouldClipTheTitle) | 684 if (!clipping) |
| 754 return cellFrame; | 685 return cellFrame; |
| 755 | 686 |
| 756 // Draw the gradient part with a transparency layer. This makes the text look | 687 // Draw the gradient part with a transparency layer. This makes the text look |
| 757 // suboptimal, but since it fades out, that's ok. | 688 // suboptimal, but since it fades out, that's ok. |
| 758 gfx::ScopedNSGraphicsContextSaveGState scopedGState; | 689 gfx::ScopedNSGraphicsContextSaveGState scopedGState; |
| 759 [NSBezierPath clipRect:gradientPart]; | 690 [NSBezierPath clipRect:gradientPart]; |
| 760 CGContextRef context = static_cast<CGContextRef>( | 691 CGContextRef context = static_cast<CGContextRef>( |
| 761 [[NSGraphicsContext currentContext] graphicsPort]); | 692 [[NSGraphicsContext currentContext] graphicsPort]); |
| 762 CGContextBeginTransparencyLayerWithRect(context, | 693 CGContextBeginTransparencyLayerWithRect(context, |
| 763 NSRectToCGRect(gradientPart), 0); | 694 NSRectToCGRect(gradientPart), 0); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 828 options:options | 759 options:options |
| 829 owner:self | 760 owner:self |
| 830 userInfo:nil]); | 761 userInfo:nil]); |
| 831 if (isMouseInside_ != mouseInView) { | 762 if (isMouseInside_ != mouseInView) { |
| 832 [self setMouseInside:mouseInView animate:NO]; | 763 [self setMouseInside:mouseInView animate:NO]; |
| 833 [controlView setNeedsDisplay:YES]; | 764 [controlView setNeedsDisplay:YES]; |
| 834 } | 765 } |
| 835 } | 766 } |
| 836 | 767 |
| 837 @end | 768 @end |
| OLD | NEW |