@@ -63,6 +63,8 @@ - (void) _revertToOriginalOpacityAttributes;
63
63
64
64
- (void ) _drawBackground ;
65
65
- (BOOL ) _isOptionPressed ;
66
+ - (void ) _addTrackingAreaForCTF ;
67
+ - (void ) _removeTrackingAreaForCTF ;
66
68
67
69
- (void ) _loadContent : (NSNotification *) notification ;
68
70
- (void ) _loadContentForWindow : (NSNotification *) notification ;
@@ -320,13 +322,16 @@ - (id) initWithArguments:(NSDictionary *)arguments
320
322
}
321
323
322
324
[self setOriginalOpacityAttributes: originalOpacityDict];
325
+
326
+ [self _addTrackingAreaForCTF ];
323
327
}
324
328
325
329
return self;
326
330
}
327
331
328
332
- (void ) dealloc
329
333
{
334
+ [self _removeTrackingAreaForCTF ];
330
335
[NSObject cancelPreviousPerformRequestsWithTarget: self ];
331
336
332
337
[self _abortAlert ]; // to be on the safe side
@@ -357,11 +362,14 @@ - (void) drawRect:(NSRect)rect
357
362
[self _drawBackground ];
358
363
}
359
364
360
- - (void ) mouseDown : ( NSEvent *) event
365
+ - (BOOL ) _gearVisible
361
366
{
362
367
NSRect bounds = [ self bounds ];
363
- float viewWidth = bounds.size .width ;
364
- float viewHeight = bounds.size .height ;
368
+ return NSWidth ( bounds ) > 32 && NSHeight ( bounds ) > 32 ;
369
+ }
370
+
371
+ - (void ) mouseDown : (NSEvent *)event
372
+ {
365
373
float margin = 5.0 ;
366
374
float gearImageHeight = 16.0 ;
367
375
float gearImageWidth = 16.0 ;
@@ -372,7 +380,8 @@ - (void) mouseDown:(NSEvent *)event
372
380
// if the view is 32 pixels or smaller in either direction,
373
381
// the gear image is not drawn, so we shouldn't pop-up the contextual
374
382
// menu on a single-click either
375
- if ( (viewWidth > 32 ) && (viewHeight > 32 ) ) {
383
+ if ( [ self _gearVisible ] ) {
384
+ float viewHeight = NSHeight ( [ self bounds ] );
376
385
NSPoint mouseLocation = [event locationInWindow ];
377
386
NSPoint localMouseLocation = [self convertPoint: mouseLocation fromView: nil ];
378
387
@@ -389,27 +398,11 @@ - (void) mouseDown:(NSEvent *)event
389
398
mouseIsDown = YES ;
390
399
mouseInside = YES ;
391
400
[self setNeedsDisplay: YES ];
392
-
401
+
393
402
// Track the mouse so that we can undo our pressed-in look if the user drags the mouse outside the view, and reinstate it if the user drags it back in.
394
- trackingArea = [NSClassFromString (@" NSTrackingArea" ) alloc ];
395
- if (trackingArea != nil )
396
- {
397
- [trackingArea initWithRect: [self bounds ]
398
- options: MATrackingMouseEnteredAndExited | MATrackingActiveInKeyWindow | MATrackingEnabledDuringMouseDrag
399
- owner: self
400
- userInfo: nil ];
401
- [self addTrackingArea: trackingArea];
402
- }
403
- else
404
- {
405
- trackingArea = [NSClassFromString (@" MATrackingArea" ) alloc ];
406
- [trackingArea initWithRect: [self bounds ]
407
- options: MATrackingMouseEnteredAndExited | MATrackingActiveInKeyWindow | MATrackingEnabledDuringMouseDrag
408
- owner: self
409
- userInfo: nil ];
410
- [MATrackingArea addTrackingArea: trackingArea toView: self ];
411
- usingMATrackingArea = YES ;
412
- }
403
+ // [self _addTrackingAreaForCTF];
404
+ // Now that we track the mouse for mouse-over when the mouse is up
405
+ // for drawing the gear only on mouse-over, we don't need to add it here.
413
406
}
414
407
}
415
408
@@ -431,16 +424,9 @@ - (void) mouseUp:(NSEvent *)event
431
424
[self display ];
432
425
433
426
// We're done tracking.
434
- if (usingMATrackingArea)
435
- {
436
- [MATrackingArea removeTrackingArea: trackingArea fromView: self ];
437
- }
438
- else
439
- {
440
- [self removeTrackingArea: trackingArea];
441
- }
442
- [trackingArea release ];
443
- trackingArea = nil ;
427
+ // [self _removeTrackingAreaForCTF];
428
+ // Now that we track the mouse for mouse-over when the mouse is up
429
+ // for drawing the gear only on mouse-over, we don't remove it here.
444
430
445
431
if (mouseInside) {
446
432
if ([self _isOptionPressed ] && ![self _isHostWhitelisted ]) {
@@ -611,8 +597,6 @@ - (void) _drawBadgeWithPressed: (BOOL) pressed
611
597
// Set up for drawing.
612
598
613
599
NSRect bounds = [ self bounds ];
614
- float viewWidth = bounds.size .width ;
615
- float viewHeight = bounds.size .height ;
616
600
617
601
// How large would this text be?
618
602
@@ -645,15 +629,15 @@ - (void) _drawBadgeWithPressed: (BOOL) pressed
645
629
646
630
if ( maxH + kMinMargin < kMinHeight )
647
631
return ;
648
-
632
+
649
633
maxH = kMinHeight ;
650
634
}
651
635
652
636
float scaleFactor = 1.0 ;
653
637
654
638
if ( maxW < w )
655
639
scaleFactor = maxW / w;
656
-
640
+
657
641
if ( maxH < h && maxH / h < scaleFactor )
658
642
scaleFactor = maxH / h;
659
643
@@ -689,55 +673,63 @@ - (void) _drawBadgeWithPressed: (BOOL) pressed
689
673
690
674
[ str drawAtPoint: loc withAttributes: attrs ];
691
675
692
-
693
- // add the gear for the contextual menu, but only if the view is
694
- // greater than a certain size
695
-
696
- // de-apply the scaling factor first, otherwise drawing will be off
697
- NSAffineTransform *xformTwo = [NSAffineTransform transform ];
698
- [xformTwo scaleBy: 1 /scaleFactor];
699
- [xformTwo concat ];
700
-
701
- if ((viewWidth > 32 ) && (viewHeight > 32 )) {
702
- float margin = 5.0 ;
703
- NSImage *gearImage = [NSImage imageNamed: @" NSActionTemplate" ];
704
-
705
- NSColor *startingColor = [NSColor colorWithDeviceWhite: 1.0 alpha: 1.0 ];
706
- NSColor *endingColor = [NSColor colorWithDeviceWhite: 1.0 alpha: 0.0 ];
707
-
708
- NSPoint gearImageCenter = NSMakePoint (0 - viewWidth/2 + margin + [gearImage size ].height /2 ,
709
- viewHeight/2 - margin - [gearImage size ].height /2 );
710
-
711
- id gradient = [NSClassFromString (@" NSGradient" ) alloc ];
712
- if (gradient != nil )
713
- {
714
- [gradient initWithStartingColor: startingColor endingColor: endingColor];
715
-
716
- // draw gradient behind gear so that it's visible even on dark backgrounds
717
- [gradient drawFromCenter: gearImageCenter
718
- radius: 0.0
719
- toCenter: gearImageCenter
720
- radius: [gearImage size ].height/2 *1.5
721
- options: 0 ];
722
-
723
- [gradient release ];
724
- }
725
-
726
- // draw the gear image
727
- [gearImage drawAtPoint: NSMakePoint (0 - viewWidth/2 + margin,viewHeight/2 - margin - [gearImage size ].height)
728
- fromRect: NSZeroRect
729
- operation: NSCompositeSourceOver
730
- fraction: 1.0 ];
731
- }
732
-
733
-
734
676
// Now restore the graphics state:
735
677
736
678
CGContextEndTransparencyLayer ( context );
737
679
738
680
[ NSGraphicsContext restoreGraphicsState ];
739
681
}
740
682
683
+ - (void ) _drawGearIcon
684
+ {
685
+ // add the gear for the contextual menu, but only if the view is
686
+ // greater than a certain size
687
+
688
+ if ([self _gearVisible ]) {
689
+ NSRect bounds = [ self bounds ];
690
+
691
+ float margin = 5.0 ;
692
+ NSImage *gearImage = [NSImage imageNamed: @" NSActionTemplate" ];
693
+
694
+ if ( gearImage ) {
695
+ CGContextRef context = [ [ NSGraphicsContext currentContext ] graphicsPort ];
696
+
697
+ CGContextSetAlpha ( context, 0.25 );
698
+ CGContextBeginTransparencyLayer ( context, nil );
699
+
700
+ NSPoint gearImageCenter = NSMakePoint (NSMinX ( bounds ) + ( margin + [gearImage size ].width /2 ),
701
+ NSMaxY ( bounds ) - ( margin + [gearImage size ].height /2 ));
702
+
703
+ id gradient = [NSClassFromString (@" NSGradient" ) alloc ];
704
+ if (gradient != nil )
705
+ {
706
+ NSColor *startingColor = [NSColor colorWithDeviceWhite: 1.0 alpha: 1.0 ];
707
+ NSColor *endingColor = [NSColor colorWithDeviceWhite: 1.0 alpha: 0.0 ];
708
+
709
+ [gradient initWithStartingColor: startingColor endingColor: endingColor];
710
+
711
+ // draw gradient behind gear so that it's visible even on dark backgrounds
712
+ [gradient drawFromCenter: gearImageCenter
713
+ radius: 0.0
714
+ toCenter: gearImageCenter
715
+ radius: [gearImage size ].height/2 *1.5
716
+ options: 0 ];
717
+
718
+ [gradient release ];
719
+ }
720
+
721
+ // draw the gear image
722
+ [gearImage drawAtPoint: NSMakePoint (gearImageCenter.x - [gearImage size ].width/2 ,
723
+ gearImageCenter.y - [gearImage size ].height/2 )
724
+ fromRect: NSZeroRect
725
+ operation: NSCompositeSourceOver
726
+ fraction: 1.0 ];
727
+
728
+ CGContextEndTransparencyLayer ( context );
729
+ }
730
+ }
731
+ }
732
+
741
733
- (void ) _drawBackground
742
734
{
743
735
NSRect selfBounds = [self bounds ];
@@ -781,6 +773,53 @@ - (void) _drawBackground
781
773
782
774
// Draw label
783
775
[ self _drawBadgeWithPressed: mouseIsDown && mouseInside ];
776
+
777
+ // Draw the gear icon
778
+ if ( mouseInside && !mouseIsDown )
779
+ [ self _drawGearIcon ];
780
+ }
781
+
782
+ - (void ) _addTrackingAreaForCTF
783
+ {
784
+ if (trackingArea)
785
+ return ;
786
+
787
+ trackingArea = [NSClassFromString (@" NSTrackingArea" ) alloc ];
788
+ if (trackingArea != nil )
789
+ {
790
+ [trackingArea initWithRect: [self bounds ]
791
+ options: MATrackingMouseEnteredAndExited | MATrackingActiveInKeyWindow | MATrackingEnabledDuringMouseDrag | MATrackingInVisibleRect
792
+ owner: self
793
+ userInfo: nil ];
794
+ [self addTrackingArea: trackingArea];
795
+ }
796
+ else
797
+ {
798
+ trackingArea = [NSClassFromString (@" MATrackingArea" ) alloc ];
799
+ [trackingArea initWithRect: [self bounds ]
800
+ options: MATrackingMouseEnteredAndExited | MATrackingActiveInKeyWindow | MATrackingEnabledDuringMouseDrag | MATrackingInVisibleRect
801
+ owner: self
802
+ userInfo: nil ];
803
+ [MATrackingArea addTrackingArea: trackingArea toView: self ];
804
+ usingMATrackingArea = YES ;
805
+ }
806
+ }
807
+
808
+ - (void ) _removeTrackingAreaForCTF
809
+ {
810
+ if (trackingArea)
811
+ {
812
+ if (usingMATrackingArea)
813
+ {
814
+ [MATrackingArea removeTrackingArea: trackingArea fromView: self ];
815
+ }
816
+ else
817
+ {
818
+ [self removeTrackingArea: trackingArea];
819
+ }
820
+ [trackingArea release ];
821
+ trackingArea = nil ;
822
+ }
784
823
}
785
824
786
825
0 commit comments