This is NetTalkThinker.IconAnim.m in view mode; [Download] [Up]
#import "NetTalkThinker.h" #import <appkit/appkit.h> #import <dpsclient/dpsNeXT.h> #define _PATTERN_END 15 static int newClientPattern[_PATTERN_END] = {0, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 0}; static int newRequestPattern[_PATTERN_END] = {0, 1, 2, 3, 2, 1, 2, 3, 2, 1, 2, 3, 2, 1, 2}; static int *animationPattern; static int patternIterator; static int loopCount; @implementation NetTalkThinker(IconAnimation) - _display: anImage { // NXAppTile is composited first at 0,0 of the icon window's content view // (this is required in order to maintain the NeXT icon look). 'anImage' is // then composited at center (centering is also a requirement). NXPoint contentViewOrigin = { 0.0, 0.0 }; NXPoint centerPoint = { 8.0, 8.0 }; [appIconContentView lockFocus]; [appTile composite:NX_SOVER toPoint:&contentViewOrigin]; [anImage composite:NX_SOVER toPoint:¢erPoint]; [appIconContentView unlockFocus]; [appIconContentView display]; return self; } - _animate { // This contains logic for the icon animation (image sequencing). Three // images are used (contained in imageList). The animationPattern // provides an index into that list, giving us the right image at the right // time. The icon will 'ring' twice, and leave the phone off-hook to indicate // unanswered calls. static int offset; [self _display: [imageList objectAt: animationPattern[patternIterator++]]]; if (patternIterator == (_PATTERN_END - offset)) { [self removeTimedEntry]; patternIterator = 0; loopCount++; if (loopCount < 2) { offset = 1; if (animationPattern == newClientPattern) [self perform: @selector(newClient:) with:self afterDelay:500 cancelPrevious:YES]; else [self perform: @selector(newRequest:) with:self afterDelay:500 cancelPrevious:YES]; } else { loopCount = offset = 0; if (animationPattern == newClientPattern) [self _display:[imageList objectAt:0]]; else if ([requestList count] == 0) [self _display:[imageList objectAt:0]]; else [self _display:[imageList objectAt:3]]; } } return self; } void Animate (DPSTimedEntry timedEntry, double now, id self) { [(id)self _animate]; } - removeTimedEntry { if (timedEntry) { DPSRemoveTimedEntry (timedEntry); timedEntry = 0; } return self; } - newClient:sender { if (timedEntry) return self; animationPattern = newClientPattern; timedEntry = DPSAddTimedEntry(0.2, (DPSTimedEntryProc)Animate, (void*)self, NX_MODALRESPTHRESHOLD); return self; } - newRequest:sender { if (timedEntry) [self removeTimedEntry]; if (strcmp(NXGetDefaultValue(APPNAME, NTD_MUTEALARM), NTD_NO) == 0) [[[[Sound alloc] initFromSoundfile:NXGetDefaultValue(APPNAME, NTD_SOUNDNAME)] play: nil] free]; animationPattern = newRequestPattern; timedEntry = DPSAddTimedEntry(0.2, (DPSTimedEntryProc)Animate, (void*)self, NX_MODALRESPTHRESHOLD); return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.