Created
February 27, 2011 09:22
-
-
Save cyberfox/846047 to your computer and use it in GitHub Desktop.
An NSTableView delegate with a yellow flash effect
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# TableDelegate.rb | |
# | |
# An example of capturing double-clicks and a yellow-fade technique in MacRuby. | |
# The yellow fade technique implementation is a ruby-ized translation | |
# of http://www.bdunagan.com/2009/04/26/core-animation-on-the-mac/ | |
# Created by Morgan Schweers on February 26, 2011. | |
framework 'Cocoa' | |
class TableDelegate | |
# Hook this up to your TableView in Interface Builder | |
attr_accessor :view | |
# Establish a double-click listener | |
def awakeFromNib | |
view.doubleAction = 'double_click:' | |
view.target = self | |
end | |
def double_click(sender) | |
# Do something with sender.clickedRow that updates it... | |
yellow_fade(sender) | |
end | |
# Utility function for a common ObjC pattern of 'create, then call several setters' | |
def mass_assign(obj, params) | |
obj.tap do |object| | |
params.keys.each do |key| | |
msg = "#{key}=" | |
object.send(msg, params[key]) | |
end | |
end | |
end | |
# Establish a fade-in and fade-out animation (color is set in the layer below) | |
def yellow_fade(sender) | |
rowIndex = sender.clickedRow | |
cellFrame = view.rectOfRow(rowIndex) | |
layer = CALayer.layer | |
layer.delegate = self | |
yellowFadeView = mass_assign(NSView.alloc.init, wantsLayer:true, frame:cellFrame, layer:layer, alphaValue:0.0) | |
layer.setNeedsDisplay | |
sender.addSubview(yellowFadeView) | |
# Fade from 0 alpha (invisible) to opaque | |
fadeIn = mass_assign(CABasicAnimation.animationWithKeyPath("alphaValue"), beginTime:0.0, fromValue:0.0, toValue:1.0, duration:0.25) | |
# Fade from opaque back to 0 alpha | |
fadeOut = mass_assign(CABasicAnimation.animationWithKeyPath("alphaValue"), beginTime:0.25, fromValue:1.0, toValue:0.0, duration:0.25) | |
# Pair the animations together | |
yfa = mass_assign(CAAnimationGroup.animation, delegate:self, animations:[fadeIn, fadeOut], duration:2.0) | |
yellowFadeView.animations = {"frameOrigin" => yfa} | |
# Start the animation | |
yellowFadeView.animator.frame = yellowFadeView.frame | |
end | |
# Utility function to extract the RGBA values from a color | |
def split_color(color) | |
r = Pointer.new(:double) | |
g = Pointer.new(:double) | |
b = Pointer.new(:double) | |
a = Pointer.new(:double) | |
color.getRed(r, green:g, blue:b, alpha:a) | |
[r[0], g[0], b[0], a[0]] | |
end | |
# This draws a simple layer of a yellow outline, with a translucent yellow interior. | |
# This layer is then faded in and out by the animation above. | |
def drawLayer(layer, inContext:ctx) | |
radius = 4 | |
nsGC = NSGraphicsContext.graphicsContextWithGraphicsPort(ctx, flipped:false) | |
NSGraphicsContext.saveGraphicsState | |
NSGraphicsContext.currentContext = nsGC | |
aRect = layer.frame | |
rect = NSMakeRect(aRect.origin.x, aRect.origin.y, aRect.size.width, aRect.size.height) | |
# Solid outside line | |
NSBezierPath.defaultLineWidth = 2 | |
highlightPath = NSBezierPath.bezierPathWithRoundedRect(rect, xRadius:radius, yRadius:radius) | |
NSColor.yellowColor.set | |
highlightPath.stroke | |
# Translucent inner filled rounded rectangle | |
r, g, b, a = split_color(NSColor.yellowColor) | |
transparentYellow = NSColor.colorWithCalibratedRed(r, green:g, blue:b, alpha:0.5) | |
fillPath = NSBezierPath.bezierPathWithRoundedRect(rect, xRadius:radius, yRadius:radius) | |
transparentYellow.set | |
fillPath.fill | |
NSGraphicsContext.restoreGraphicsState | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment