1#
2#  TransitionSelectorView.rb
3#  CITransitionSelectorSample
4#
5#  Created by Laurent Sansonetti on 12/13/06.
6#  Copyright (c) 2006 Apple Computer. All rights reserved.
7#
8
9class TransitionSelectorView <  NSView
10
11  def awakeFromNib
12    @thumbnailWidth  = 340.0
13    @thumbnailHeight = 240.0
14    @thumbnailGap    = 20.0
15
16    @sourceImage = CIImageFromResources('Rose')
17    @targetImage = CIImageFromResources('Frog')
18
19    timer = NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats(
20      1.0 / 30.0, self, 'timerFired:', nil, true)
21    
22    @base = NSDate.timeIntervalSinceReferenceDate
23
24    crl = NSRunLoop.currentRunLoop
25    crl.addTimer_forMode(timer, NSDefaultRunLoopMode)
26    crl.addTimer_forMode(timer, NSEventTrackingRunLoopMode)
27  end
28
29  def shadingImage
30    @shadingImage ||= CIImageFromResources('Shading', 'tiff')
31  end
32  
33  def blankImage
34    @shadingImage ||= CIImageFromResources('Blank')
35  end
36  
37  def maskImage
38    @maskImage ||= CIImageFromResources('Mask')
39  end
40
41  def timerFired(sender)
42    setNeedsDisplay(true)
43  end
44
45  def imageForTransition_atTime(transitionNumber, time)
46    transition = @transitions[transitionNumber]
47    
48    images = [@sourceImage, @targetImage]
49    images.reverse! unless (time % 2.0) < 1.0
50    
51    transition.setValue_forKey(images.first, 'inputImage')
52    transition.setValue_forKey(images.last, 'inputTargetImage')
53    
54    f = 0.5 * (1 - Math.cos((time % 1.0) * Math::PI))
55    transition.setValue_forKey(NSNumber.numberWithFloat(f), 'inputTime')
56
57    crop = CIFilter.filterWithName('CICrop')
58    crop.setValue_forKey(transition.valueForKey('outputImage'), 'inputImage')
59    crop.setValue_forKey(CIVector.vectorWithX_Y_Z_W(0, 0, @thumbnailWidth, @thumbnailHeight), 'inputRectangle')
60  
61    return crop.valueForKey('outputImage')
62  end
63
64  def drawRect(rectangle)
65    thumbFrame = CGRect.new(CGPoint.new(0, 0), CGSize.new(@thumbnailWidth, @thumbnailHeight))
66    t = 0.4 * (NSDate.timeIntervalSinceReferenceDate - @base)
67    
68    context = NSGraphicsContext.currentContext.CIContext
69    
70    setupTransitions unless @transitions
71    
72    w = Math.sqrt(@transitions.length).ceil
73    
74    @transitions.length.times do |i|
75      point = CGPoint.new(((i % w) * (@thumbnailWidth  + @thumbnailGap)), 
76                          ((i / w) * (@thumbnailHeight  + @thumbnailGap)))
77      
78      if context
79        context.drawImage_atPoint_fromRect(imageForTransition_atTime(i, t + 0.1 * i), point, thumbFrame)
80      end
81    end
82  end
83
84  def CIImageFromResources(name, ext='jpg')
85    path = NSBundle.mainBundle.pathForResource_ofType(name, ext) 
86    CIImage.imageWithContentsOfURL(NSURL.fileURLWithPath(path))
87  end
88
89  def setupTransitions
90    w, h = @thumbnailWidth, @thumbnailHeight
91    extent = CIVector.vectorWithX_Y_Z_W(0, 0, w, h)
92    @transitions = []
93    
94    filter = CIFilter.filterWithName('CISwipeTransition')
95    filter.setValue_forKey(CIColor.colorWithRed_green_blue_alpha(0, 0, 0, 0), 'inputColor')
96    filter.setValue_forKey(NSNumber.numberWithFloat(0.3 * Math::PI), 'inputAngle')
97    filter.setValue_forKey(NSNumber.numberWithFloat(80.0), 'inputWidth')
98    filter.setValue_forKey(NSNumber.numberWithFloat(0.0), 'inputOpacity')
99    @transitions << filter
100    
101    @transitions << CIFilter.filterWithName('CIDissolveTransition')
102  
103    filter = CIFilter.filterWithName('CISwipeTransition')
104    filter.setValue_forKey(CIColor.colorWithRed_green_blue_alpha(0, 0, 0, 0), 'inputColor')
105    filter.setValue_forKey(NSNumber.numberWithFloat(Math::PI), 'inputAngle')
106    filter.setValue_forKey(NSNumber.numberWithFloat(2.0), 'inputWidth')
107    filter.setValue_forKey(NSNumber.numberWithFloat(0.2), 'inputOpacity')
108    @transitions << filter
109
110    filter = CIFilter.filterWithName('CIModTransition')
111    filter.setValue_forKey(CIVector.vectorWithX_Y(0.5 * w, 0.5 * h), 'inputCenter')
112    filter.setValue_forKey(NSNumber.numberWithFloat(0.1 * Math::PI), 'inputAngle')
113    filter.setValue_forKey(NSNumber.numberWithFloat(30.0), 'inputRadius')
114    filter.setValue_forKey(NSNumber.numberWithFloat(10.0), 'inputCompression')
115    @transitions << filter
116
117    filter = CIFilter.filterWithName('CIFlashTransition')
118    filter.setValue_forKey(extent, 'inputExtent')
119    filter.setValue_forKey(CIVector.vectorWithX_Y(0.3 * w, 0.7 * h), 'inputCenter')
120    filter.setValue_forKey(CIColor.colorWithRed_green_blue_alpha(1, 0.8, 0.6, 1), 'inputColor')
121    filter.setValue_forKey(NSNumber.numberWithFloat(2.5), 'inputMaxStriationRadius')
122    filter.setValue_forKey(NSNumber.numberWithFloat(0.5), 'inputStriationStrength')
123    filter.setValue_forKey(NSNumber.numberWithFloat(1.37), 'inputStriationContrast')
124    filter.setValue_forKey(NSNumber.numberWithFloat(0.85), 'inputFadeThreshold')
125    @transitions << filter
126
127    filter = CIFilter.filterWithName('CIDisintegrateWithMaskTransition')
128    filter.setValue_forKey(self.maskImage, 'inputMaskImage')
129    filter.setValue_forKey(NSNumber.numberWithFloat(10.0), 'inputShadowRadius')
130    filter.setValue_forKey(NSNumber.numberWithFloat(0.7), 'inputShadowDensity')
131    filter.setValue_forKey(CIVector.vectorWithX_Y(0.0, -0.05 * h), 'inputShadowOffset')
132    @transitions << filter
133
134    filter = CIFilter.filterWithName('CIRippleTransition')
135    filter.setValue_forKey(extent, 'inputExtent')
136    filter.setValue_forKey(self.shadingImage, 'inputShadingImage')
137    filter.setValue_forKey(CIVector.vectorWithX_Y(0.5 * w, 0.5 * h), 'inputCenter')
138    filter.setValue_forKey(NSNumber.numberWithFloat(80.0), 'inputWidth')
139    filter.setValue_forKey(NSNumber.numberWithFloat(30.0), 'inputScale')
140    @transitions << filter
141
142    filter = CIFilter.filterWithName('CICopyMachineTransition')
143    filter.setValue_forKey(extent, 'inputExtent')
144    filter.setValue_forKey(CIColor.colorWithRed_green_blue_alpha(0.6, 1, 0.8, 1), 'inputColor')
145    filter.setValue_forKey(NSNumber.numberWithFloat(0), 'inputAngle')
146    filter.setValue_forKey(NSNumber.numberWithFloat(40.0), 'inputWidth')
147    filter.setValue_forKey(NSNumber.numberWithFloat(1.0), 'inputOpacity')
148    @transitions << filter
149
150    filter = CIFilter.filterWithName('CIPageCurlTransition')
151    filter.setValue_forKey(extent, 'inputExtent')
152    filter.setValue_forKey(self.shadingImage, 'inputShadingImage')
153    filter.setValue_forKey(self.blankImage, 'inputBacksideImage')
154    filter.setValue_forKey(NSNumber.numberWithFloat(-0.2 * Math::PI), 'inputAngle')
155    filter.setValue_forKey(NSNumber.numberWithFloat(70.0), 'inputRadius')
156    @transitions << filter
157  end
158
159end
160