This is ThinkMore.m in view mode; [Download] [Up]
// ThinkMore.m // // Contains additional methods used in the Thinker class. // // You may freely copy, distribute, and reuse the code in this example. // NeXT disclaims any warranty of any kind, expressed or implied, as to its // fitness for any particular use. #import "Thinker.h" #import "SpaceView.h" #import "BackView.h" #import "SleepView.h" #import "BlackView.h" #import "Password.h" #import "psfuncts.h" #import <appkit/appkit.h> #import <objc/NXBundle.h> #define VIEWDIRECTORY "/LocalLibrary/BackSpaceViews" static char *compiledViewNames[] = { "Space", "Boink", "Black", }; #define COMVIEWCOUNT (sizeof(compiledViewNames)/sizeof(*compiledViewNames)) @implementation Thinker(thinkMore) //must invoke this before creating window or setting up the views - getViewType { int i; id theMatrix; char buf[MAXPATHLEN]; ModuleInfo *m; strcpy( buf, NXHomeDirectory()); strcat( buf, "/Library/BackSpaceViews"); moduleList = [[ModuleList alloc] init]; [self loadViewsFrom:buf]; [self loadViewsFrom: [self appDirectory]]; [self loadViewsFrom: VIEWDIRECTORY]; for (i = 0; i < COMVIEWCOUNT; i++) { m = [[ModuleInfo alloc] initWithView:nil name:compiledViewNames[i] path:NULL]; [moduleList addObject: m]; } [moduleList sort]; [viewSelectionBrowser loadColumnZero]; theMatrix = [viewSelectionBrowser matrixInColumn:0]; [theMatrix selectCellAt:realViewIndex :0]; [theMatrix scrollCellToVisible:realViewIndex :0]; return self; } - selectRealViewIndex:sender { //sender is the NXBrowser int index = [[viewSelectionBrowser matrixInColumn:0] selectedRow]; if (index == realViewIndex) return self; if (index == -1) { id theMatrix = [viewSelectionBrowser matrixInColumn:0]; [theMatrix selectCellAt:realViewIndex :0]; [theMatrix scrollCellToVisible:realViewIndex :0]; return self; } realViewIndex = index; [self setVirtualViewIndexAndIncrement:NO]; return self; } // this method is the actual view setting mechanism, // guaranteed to get called to set the view - setVirtualViewIndexAndIncrement:(BOOL)flag { id myView; id newInspector; if (realViewIndex) { virtualViewIndex = realViewIndex-1; [self selectScreenSaverViews]; } else { if (flag) { virtualViewIndex = random() % [moduleList count]; [self selectScreenSaverViews]; myView = [self backView]; while ([myView respondsTo:@selector(isBoringScreenSaver)] && [myView isBoringScreenSaver]) { if (++virtualViewIndex >= [moduleList count]) virtualViewIndex = 0; [self selectScreenSaverViews]; myView = [self backView]; } } else [self selectScreenSaverViews]; } //--------------------------------------------- // now plug in the inspector //--------------------------------------------- myView = [self backView]; if ([myView respondsTo:@selector(inspector:)]) { newInspector = [myView inspector:self]; if (!newInspector) newInspector = [self nullInspector]; } else newInspector = [self nullInspector]; if (newInspector != currentInspector) { if ([oldInspectorOwner respondsTo:@selector(inspectorWillBeRemoved)]) [oldInspectorOwner inspectorWillBeRemoved]; // either myView will be the inspector owner, or it won't care oldInspectorOwner = myView; // don't want it to resize the box. Suboptimal technique... [newInspector setFrame:&inspectorFrame]; [invisibleInspectorBox setContentView: newInspector]; currentInspector = newInspector; if ([myView respondsTo:@selector(inspectorInstalled)]) [myView inspectorInstalled]; [invisibleInspectorBox display]; } return self; } - selectScreenSaverViews { id theView, bigWindow; int myBacking; //need to order out big window if that's the type and buffering changed if(windowType == BACKWINDOW && modeType == SAVERMODE && doingSaver == NO) { return self; } theView = [self backView]; myBacking = [self backingTypeForView:theView]; [self createBigWindowIfNecessaryForView:theView]; if (myBacking == NX_BUFFERED) bigWindow = bigBufferedWindow; else bigWindow = bigUnbufferedWindow; if (windowType == BACKWINDOW) { if (spaceWindow != bigWindow) { [spaceWindow orderOut:self]; [self useBackWindow:globalTier]; } } spaceView = theView; [self installSpaceViewIntoWindow:spaceWindow]; if ([spaceView respondsTo:@selector(setImage:)]) [spaceView setImage: image]; if ([spaceView respondsTo:@selector(newWindow)]) [spaceView newWindow]; [self setWindowTitle]; if(modeType == SAVERMODE) { NXWriteDefault([NXApp appName], "viewType", (realViewIndex ? ([moduleList nameAt: realViewIndex-1]) : "All")); } if(modeType == BACKMODE) { NXWriteDefault([NXApp appName], "backViewType", (realViewIndex ? ([moduleList nameAt: realViewIndex-1]) : "All")); } if (windowType) { // the unbuffered window looks better if you just display // its contents, but for a buffered oneshot window, you must // display the window to make sure the window server window exists. if (myBacking == NX_BUFFERED) [spaceWindow display]; else { [spaceView fillBoundsWithBlack]; [spaceView display]; } } if (normalWindow && (windowType == NORMALWINDOW)) { if (myBacking == NX_BUFFERED) [normalWindow setBackingType:NX_BUFFERED]; else[normalWindow setBackingType:NX_RETAINED]; } return self; } - setWindowTitle { if ([spaceView respondsTo:@selector(windowTitle)]) { [normalWindow setTitle: NXLocalString([spaceView windowTitle],0,0)]; } else [normalWindow setTitle: NXLocalString("BackSpace",0,0)]; return self; } - getScreenLockerSetting { const char *ptr; [screenLocker setState:0]; ptr = NXGetDefaultValue([NXApp appName], "screenLocker"); if (!ptr || !strcmp(ptr,"Off")) [self setScreenLocker:NO andRemember:NO]; else [self setScreenLocker:YES andRemember:NO]; return self; } - changeScreenLockerSetting:sender { if (![password checkPassword: NXLocalString("Enter password to change screen lock setting:",0,0) randomPos:NO checkLock:NO withView:nil]) { [screenLocker setState:[password isLocked]]; return self; } if (![password validPassword] && ![password setPassword:self]) { [screenLocker setState:[password isLocked]]; return self; } [self setScreenLocker:([screenLocker state])andRemember:YES]; return self; } - setScreenLocker:(BOOL)val andRemember:(BOOL)rem { [screenLocker setState:val]; [password setLock: val]; if (rem) { if (val) NXWriteDefault([NXApp appName], "screenLocker", "On"); else NXRemoveDefault([NXApp appName], "screenLocker"); } return self; } //--------------------------------------------------- // View manager routines //--------------------------------------------------- - backView { NXRect aFrame = {{0,0},{200,200}}; id theView; if (![moduleList viewAt:virtualViewIndex]) { char path[MAXPATHLEN]; id myClass; const char *name; char *filenames[] = {path, NULL}; ModuleInfo *mp; struct mach_header *header; mp = [moduleList objectAt: virtualViewIndex]; name = [mp viewName]; // before I loaded all classes at launch time; now classes are // loaded only as needed. This idea and some of the code here is // from bill bumgarner, thanx! if ([mp path]) // we have path but no instance, must load class { long ret; do { sprintf(path, "%s/%sView.BackO", [mp path], name); ret = objc_loadModules(filenames, NULL, NULL, &header, NULL); // objc_loadModules succeeds with a warning if the architecture of the // object file is wrong, so we better check if we really got a class if (!ret) // load succeeded or was wrong architecture { sprintf(path,"%sView", name); myClass = objc_getClass(path); if (!myClass) ret = -1; } } while (ret && [mp useNextPath]); [mp discardAltPaths]; if (ret) { // Ugh, failed. Will instantiate a BlackView instead... NXRunAlertPanel([NXApp appName], NXLocalString( "Could not dynamically load class: %sView",0,0), NULL, NULL, NULL, name); name = "Black"; } else { [mp setHeader:header]; } } //at this point we must have a valid name for a loaded class sprintf(path,"%sView", name); myClass = objc_getClass(path); theView = [[myClass allocFromZone:backZone] initFrame:&aFrame]; [[moduleList objectAt:virtualViewIndex] setView:theView]; } theView = [moduleList viewAt:virtualViewIndex]; return theView; } - showInfoPanel:sender { if (!infoPanel) { if (![NXApp loadNibSection:"Info.nib" owner:self withNames:NO fromZone:[self zone]]) NXLogError ("Can't find Info.nib!"); } [infoPanel makeKeyAndOrderFront:sender]; return self; } #define SLEEPSIZE (3.0) - createSleepWindow { if (!sleepWindow) { NXRect sleep={{0, 0},{SLEEPSIZE, SLEEPSIZE}}; id aView = [[SleepView alloc] initFrame:&sleep]; sleepWindow = [[Window alloc] initContent:&sleep style:NX_TOKENSTYLE backing:NX_NONRETAINED buttonMask:0 defer:NO]; [sleepWindow setEventMask:(NX_MOUSEENTEREDMASK | NX_MOUSEEXITEDMASK)]; PSsetwindowlevel(SLEEPTIER, [sleepWindow windowNum]); PSWmakeWindowGray([sleepWindow windowNum]); [[sleepWindow setContentView: aView] free]; [sleepWindow setTrackingRect:&sleep inside:YES owner:aView tag:3 left:NO right:NO]; } return self; } - setSleepCorner:(int)val { NXRect screen={{0, 0}}; NXCoord x = 0.0, y = 0.0; if (val) { [NXApp getScreenSize:&(screen.size)]; [self createSleepWindow]; if (val == 2 || val == 3) x = screen.size.width - SLEEPSIZE; if (val == 3 || val == 4) y = screen.size.height - SLEEPSIZE; [sleepWindow moveTo:x :y]; [sleepWindow orderFront:self]; } else [sleepWindow orderOut:self]; return self; } - getHotCornerSetting { const char *ptr; int tval, val=0; ptr = NXGetDefaultValue([NXApp appName], "hotCorner"); if (ptr) { sscanf(ptr,"%d",&tval); if (tval >= 0 && tval <= 4) val = tval; } [cornerView setState:val]; [self setSleepCorner:val]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.