Skip to content

Commit

Permalink
Factored drawing of gear icon into a separate method. Made tracking a…
Browse files Browse the repository at this point in the history
…rea always be applied to the view, and use it to make the gear icon appear only when the mouse is somewhere over the view.
  • Loading branch information
Otyr Ugla authored and mbaltaks committed May 27, 2009
1 parent f329529 commit 909dbed
Showing 1 changed file with 119 additions and 80 deletions.
199 changes: 119 additions & 80 deletions Plugin/Plugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ - (void) _revertToOriginalOpacityAttributes;

- (void) _drawBackground;
- (BOOL) _isOptionPressed;
- (void) _addTrackingAreaForCTF;
- (void) _removeTrackingAreaForCTF;

- (void) _loadContent: (NSNotification*) notification;
- (void) _loadContentForWindow: (NSNotification*) notification;
Expand Down Expand Up @@ -320,13 +322,16 @@ - (id) initWithArguments:(NSDictionary *)arguments
}

[self setOriginalOpacityAttributes:originalOpacityDict];

[self _addTrackingAreaForCTF];
}

return self;
}

- (void) dealloc
{
[self _removeTrackingAreaForCTF];
[NSObject cancelPreviousPerformRequestsWithTarget:self];

[self _abortAlert]; // to be on the safe side
Expand Down Expand Up @@ -357,11 +362,14 @@ - (void) drawRect:(NSRect)rect
[self _drawBackground];
}

- (void) mouseDown:(NSEvent *)event
- (BOOL) _gearVisible
{
NSRect bounds = [ self bounds ];
float viewWidth = bounds.size.width;
float viewHeight = bounds.size.height;
return NSWidth( bounds ) > 32 && NSHeight( bounds ) > 32;
}

- (void) mouseDown:(NSEvent *)event
{
float margin = 5.0;
float gearImageHeight = 16.0;
float gearImageWidth = 16.0;
Expand All @@ -372,7 +380,8 @@ - (void) mouseDown:(NSEvent *)event
// if the view is 32 pixels or smaller in either direction,
// the gear image is not drawn, so we shouldn't pop-up the contextual
// menu on a single-click either
if ( (viewWidth > 32) && (viewHeight > 32) ) {
if ( [ self _gearVisible ] ) {
float viewHeight = NSHeight( [ self bounds ] );
NSPoint mouseLocation = [event locationInWindow];
NSPoint localMouseLocation = [self convertPoint:mouseLocation fromView:nil];

Expand All @@ -389,27 +398,11 @@ - (void) mouseDown:(NSEvent *)event
mouseIsDown = YES;
mouseInside = YES;
[self setNeedsDisplay:YES];

// 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.
trackingArea = [NSClassFromString(@"NSTrackingArea") alloc];
if (trackingArea != nil)
{
[trackingArea initWithRect:[self bounds]
options:MATrackingMouseEnteredAndExited | MATrackingActiveInKeyWindow | MATrackingEnabledDuringMouseDrag
owner:self
userInfo:nil];
[self addTrackingArea:trackingArea];
}
else
{
trackingArea = [NSClassFromString(@"MATrackingArea") alloc];
[trackingArea initWithRect:[self bounds]
options:MATrackingMouseEnteredAndExited | MATrackingActiveInKeyWindow | MATrackingEnabledDuringMouseDrag
owner:self
userInfo:nil];
[MATrackingArea addTrackingArea:trackingArea toView:self];
usingMATrackingArea = YES;
}
//[self _addTrackingAreaForCTF];
// Now that we track the mouse for mouse-over when the mouse is up
// for drawing the gear only on mouse-over, we don't need to add it here.
}
}

Expand All @@ -431,16 +424,9 @@ - (void) mouseUp:(NSEvent *)event
[self display];

// We're done tracking.
if (usingMATrackingArea)
{
[MATrackingArea removeTrackingArea:trackingArea fromView:self];
}
else
{
[self removeTrackingArea:trackingArea];
}
[trackingArea release];
trackingArea = nil;
//[self _removeTrackingAreaForCTF];
// Now that we track the mouse for mouse-over when the mouse is up
// for drawing the gear only on mouse-over, we don't remove it here.

if (mouseInside) {
if ([self _isOptionPressed] && ![self _isHostWhitelisted]) {
Expand Down Expand Up @@ -611,8 +597,6 @@ - (void) _drawBadgeWithPressed: (BOOL) pressed
// Set up for drawing.

NSRect bounds = [ self bounds ];
float viewWidth = bounds.size.width;
float viewHeight = bounds.size.height;

// How large would this text be?

Expand Down Expand Up @@ -645,15 +629,15 @@ - (void) _drawBadgeWithPressed: (BOOL) pressed

if( maxH + kMinMargin < kMinHeight )
return;

maxH = kMinHeight;
}

float scaleFactor = 1.0;

if( maxW < w )
scaleFactor = maxW / w;

if( maxH < h && maxH / h < scaleFactor )
scaleFactor = maxH / h;

Expand Down Expand Up @@ -689,55 +673,63 @@ - (void) _drawBadgeWithPressed: (BOOL) pressed

[ str drawAtPoint: loc withAttributes: attrs ];


// add the gear for the contextual menu, but only if the view is
// greater than a certain size

// de-apply the scaling factor first, otherwise drawing will be off
NSAffineTransform *xformTwo = [NSAffineTransform transform];
[xformTwo scaleBy: 1/scaleFactor];
[xformTwo concat];

if ((viewWidth > 32) && (viewHeight > 32)) {
float margin = 5.0;
NSImage *gearImage = [NSImage imageNamed:@"NSActionTemplate"];

NSColor *startingColor = [NSColor colorWithDeviceWhite:1.0 alpha:1.0];
NSColor *endingColor = [NSColor colorWithDeviceWhite:1.0 alpha:0.0];

NSPoint gearImageCenter = NSMakePoint(0 - viewWidth/2 + margin + [gearImage size].height/2,
viewHeight/2 - margin - [gearImage size].height/2);

id gradient = [NSClassFromString(@"NSGradient") alloc];
if (gradient != nil)
{
[gradient initWithStartingColor:startingColor endingColor:endingColor];

// draw gradient behind gear so that it's visible even on dark backgrounds
[gradient drawFromCenter:gearImageCenter
radius:0.0
toCenter:gearImageCenter
radius:[gearImage size].height/2*1.5
options:0];

[gradient release];
}

// draw the gear image
[gearImage drawAtPoint:NSMakePoint(0 - viewWidth/2 + margin,viewHeight/2 - margin - [gearImage size].height)
fromRect:NSZeroRect
operation:NSCompositeSourceOver
fraction:1.0];
}


// Now restore the graphics state:

CGContextEndTransparencyLayer( context );

[ NSGraphicsContext restoreGraphicsState ];
}

- (void) _drawGearIcon
{
// add the gear for the contextual menu, but only if the view is
// greater than a certain size

if ([self _gearVisible]) {
NSRect bounds = [ self bounds ];

float margin = 5.0;
NSImage *gearImage = [NSImage imageNamed:@"NSActionTemplate"];

if( gearImage ) {
CGContextRef context = [ [ NSGraphicsContext currentContext ] graphicsPort ];

CGContextSetAlpha( context, 0.25 );
CGContextBeginTransparencyLayer( context, nil );

NSPoint gearImageCenter = NSMakePoint(NSMinX( bounds ) + ( margin + [gearImage size].width/2 ),
NSMaxY( bounds ) - ( margin + [gearImage size].height/2 ));

id gradient = [NSClassFromString(@"NSGradient") alloc];
if (gradient != nil)
{
NSColor *startingColor = [NSColor colorWithDeviceWhite:1.0 alpha:1.0];
NSColor *endingColor = [NSColor colorWithDeviceWhite:1.0 alpha:0.0];

[gradient initWithStartingColor:startingColor endingColor:endingColor];

// draw gradient behind gear so that it's visible even on dark backgrounds
[gradient drawFromCenter:gearImageCenter
radius:0.0
toCenter:gearImageCenter
radius:[gearImage size].height/2*1.5
options:0];

[gradient release];
}

// draw the gear image
[gearImage drawAtPoint:NSMakePoint(gearImageCenter.x - [gearImage size].width/2,
gearImageCenter.y - [gearImage size].height/2)
fromRect:NSZeroRect
operation:NSCompositeSourceOver
fraction:1.0];

CGContextEndTransparencyLayer( context );
}
}
}

- (void) _drawBackground
{
NSRect selfBounds = [self bounds];
Expand Down Expand Up @@ -781,6 +773,53 @@ - (void) _drawBackground

// Draw label
[ self _drawBadgeWithPressed: mouseIsDown && mouseInside ];

// Draw the gear icon
if( mouseInside && !mouseIsDown )
[ self _drawGearIcon ];
}

- (void) _addTrackingAreaForCTF
{
if (trackingArea)
return;

trackingArea = [NSClassFromString(@"NSTrackingArea") alloc];
if (trackingArea != nil)
{
[trackingArea initWithRect:[self bounds]
options:MATrackingMouseEnteredAndExited | MATrackingActiveInKeyWindow | MATrackingEnabledDuringMouseDrag | MATrackingInVisibleRect
owner:self
userInfo:nil];
[self addTrackingArea:trackingArea];
}
else
{
trackingArea = [NSClassFromString(@"MATrackingArea") alloc];
[trackingArea initWithRect:[self bounds]
options:MATrackingMouseEnteredAndExited | MATrackingActiveInKeyWindow | MATrackingEnabledDuringMouseDrag | MATrackingInVisibleRect
owner:self
userInfo:nil];
[MATrackingArea addTrackingArea:trackingArea toView:self];
usingMATrackingArea = YES;
}
}

- (void) _removeTrackingAreaForCTF
{
if (trackingArea)
{
if (usingMATrackingArea)
{
[MATrackingArea removeTrackingArea:trackingArea fromView:self];
}
else
{
[self removeTrackingArea:trackingArea];
}
[trackingArea release];
trackingArea = nil;
}
}


Expand Down

0 comments on commit 909dbed

Please sign in to comment.