1from Cocoa import * 2from Quartz import * 3 4import math 5 6TRANSITION_COUNT=9 7 8class TransitionSelectorView (NSView): 9 _sourceImage = objc.ivar() 10 _targetImage = objc.ivar() 11 _shadingImage = objc.ivar() 12 _blankImage = objc.ivar() 13 _maskImage = objc.ivar() 14 transitions = objc.ivar() # Array 15 16 base = objc.ivar(type=objc._C_DBL) 17 18 thumbnailWidth = objc.ivar(type=objc._C_FLT) 19 thumbnailHeight = objc.ivar(type=objc._C_FLT) 20 thumbnailGap = objc.ivar(type=objc._C_FLT) 21 22 23 def awakeFromNib(self): 24 self.thumbnailWidth = 340.0 25 self.thumbnailHeight = 240.0 26 self.thumbnailGap = 20.0 27 28 29 url = NSURL.fileURLWithPath_( 30 NSBundle.mainBundle().pathForResource_ofType_("Rose", "jpg")) 31 self.setSourceImage_(CIImage.imageWithContentsOfURL_(url)) 32 33 34 url = NSURL.fileURLWithPath_( 35 NSBundle.mainBundle().pathForResource_ofType_("Frog", "jpg")) 36 self.setTargetImage_(CIImage.imageWithContentsOfURL_(url)) 37 38 39 timer = NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_( 40 1.0/30.0, self, 'timerFired:', None, True) 41 42 self.base = NSDate.pyobjc_classMethods.timeIntervalSinceReferenceDate() 43 NSRunLoop.currentRunLoop().addTimer_forMode_(timer, NSDefaultRunLoopMode) 44 NSRunLoop.currentRunLoop().addTimer_forMode_(timer, NSEventTrackingRunLoopMode) 45 46 def setSourceImage_(self, source): 47 self._sourceImage = source 48 49 def setTargetImage_(self, target): 50 self._targetImage = target 51 52 def shadingImage(self): 53 if self._shadingImage is None: 54 url = NSURL.fileURLWithPath_( 55 NSBundle.mainBundle().pathForResource_ofType_("Shading", "tiff")) 56 self._shadingImage = CIImage.alloc().initWithContentsOfURL_(url) 57 58 return self._shadingImage 59 60 def blankImage(self): 61 if self._blankImage is None: 62 url = NSURL.fileURLWithPath_( 63 NSBundle.mainBundle().pathForResource_ofType_("Blank", "jpg")) 64 self._blankImage = CIImage.alloc().initWithContentsOfURL_(url) 65 66 return self._blankImage 67 68 def maskImage(self): 69 if self._maskImage is None: 70 url = NSURL.fileURLWithPath_( 71 NSBundle.mainBundle().pathForResource_ofType_("Mask", "jpg")) 72 self._maskImage = CIImage.alloc().initWithContentsOfURL_(url) 73 74 return self._maskImage 75 76 def timerFired_(self, sender): 77 self.setNeedsDisplay_(True) 78 79 80 def imageForTransition_atTime_(self, transitionNumber, t): 81 transition = self.transitions[transitionNumber] 82 83 if t % 2.0 < 1.0: 84 transition.setValue_forKey_(self._sourceImage, "inputImage") 85 transition.setValue_forKey_(self._targetImage, "inputTargetImage") 86 else: 87 transition.setValue_forKey_(self._targetImage, "inputImage") 88 transition.setValue_forKey_(self._sourceImage, "inputTargetImage") 89 90 transition._.inputTime = t % 1.0 91 92 crop = CIFilter.filterWithName_("CICrop") 93 crop._.inputImage = transition._.outputImage 94 crop._.inputRectangle = CIVector.vectorWithX_Y_Z_W_( 95 0, 0, self.thumbnailWidth, self.thumbnailHeight) 96 return crop._.outputImage 97 98 def drawRect_(self, rectangle): 99 thumbFrame = CGRectMake(0, 0, self.thumbnailWidth, self.thumbnailHeight) 100 t = 0.4*(NSDate.pyobjc_classMethods.timeIntervalSinceReferenceDate() - self.base) 101 102 context = NSGraphicsContext.currentContext().CIContext() 103 104 if self.transitions is None: 105 self.transitions = [None] * TRANSITION_COUNT 106 self.setupTransitions() 107 108 w = int(math.ceil(math.sqrt(TRANSITION_COUNT))) 109 origin = CGPoint() 110 111 for i in xrange(TRANSITION_COUNT): 112 origin.x = (i % w) * (self.thumbnailWidth + self.thumbnailGap) 113 origin.y = (i / w) * (self.thumbnailHeight + self.thumbnailGap) 114 115 if context is not None: 116 context.drawImage_atPoint_fromRect_( 117 self.imageForTransition_atTime_(i, t + 0.1 * i), origin, thumbFrame) 118 119 120 def setupTransitions(self): 121 w = self.thumbnailWidth 122 h = self.thumbnailHeight 123 124 extent = CIVector.vectorWithX_Y_Z_W_(0, 0, w, h) 125 126 self.transitions[0] = CIFilter.filterWithName_("CISwipeTransition") 127 self.transitions[0]._.inputExtent = extent 128 self.transitions[0]._.inputColor = CIColor.colorWithRed_green_blue_alpha_(0, 0, 0, 0) 129 self.transitions[0]._.inputAngle = 0.3 * math.pi 130 self.transitions[0]._.inputWidth = 80.0 131 self.transitions[0]._.inputOpacity = 0.0 132 133 self.transitions[1] = CIFilter.filterWithName_("CIDissolveTransition") 134 135 self.transitions[2] = CIFilter.filterWithName_("CISwipeTransition") # dupe 136 self.transitions[2]._.inputExtent = extent 137 self.transitions[2]._.inputColor = CIColor.colorWithRed_green_blue_alpha_(0, 0, 0, 0) 138 self.transitions[2]._.inputAngle = math.pi 139 self.transitions[2]._.inputWidth = 2.0 140 self.transitions[2]._.inputOpacity = 0.2 141 142 self.transitions[3] = CIFilter.filterWithName_("CIModTransition") 143 self.transitions[3]._.inputCenter = CIVector.vectorWithX_Y_(0.5*w, 0.5*h) 144 self.transitions[3]._.inputAngle = math.pi*0.1 145 self.transitions[3]._.inputRadius = 30.0 146 self.transitions[3]._.inputCompression = 10.0 147 148 self.transitions[4] = CIFilter.filterWithName_("CIFlashTransition") 149 self.transitions[4]._.inputExtent = extent 150 self.transitions[4]._.inputCenter = CIVector.vectorWithX_Y_(0.3*w, 0.7*h) 151 self.transitions[4]._.inputColor = CIColor.colorWithRed_green_blue_alpha_(1, 0.8, 0.6, 1) 152 self.transitions[4]._.inputMaxStriationRadius = 2.5 153 self.transitions[4]._.inputStriationStrength = 0.5 154 self.transitions[4]._.inputStriationContrast = 1.37 155 self.transitions[4]._.inputFadeThreshold = 0.85 156 157 self.transitions[5] = CIFilter.filterWithName_("CIDisintegrateWithMaskTransition") 158 self.transitions[5]._.inputMaskImage = self.maskImage() 159 self.transitions[5]._.inputShadowRadius = 10.0 160 self.transitions[5]._.inputShadowDensity = 0.7 161 self.transitions[5]._.inputShadowOffset = CIVector.vectorWithX_Y_(0.0, -0.05*h) 162 163 self.transitions[6] = CIFilter.filterWithName_("CIRippleTransition") 164 self.transitions[6]._.inputExtent = extent 165 self.transitions[6]._.inputShadingImage = self.shadingImage() 166 self.transitions[6]._.inputCenter = CIVector.vectorWithX_Y_(0.5*w, 0.5*h) 167 self.transitions[6]._.inputWidth = 80.0 168 self.transitions[6]._.inputScale = 30.0 169 170 self.transitions[7] = CIFilter.filterWithName_("CICopyMachineTransition") 171 self.transitions[7]._.inputExtent = extent 172 self.transitions[7]._.inputColor = CIColor.colorWithRed_green_blue_alpha_(0.6, 1, 0.8, 1) 173 self.transitions[7]._.inputAngle = 0 174 self.transitions[7]._.inputWidth = 40 175 self.transitions[7]._.inputOpacity = 1.0 176 177 self.transitions[8] = CIFilter.filterWithName_("CIPageCurlTransition") 178 self.transitions[8]._.inputExtent = extent 179 self.transitions[8]._.inputShadingImage = self.shadingImage() 180 self.transitions[8]._.inputBacksideImage = self.blankImage() 181 self.transitions[8]._.inputAngle = -0.2 * math.pi 182 self.transitions[8]._.inputRadius = 70.0 183 184