This is GKHighScorePanel.m in view mode; [Download] [Up]
#import <gamekit/gamekit.h> @implementation GKHighScorePanel - initContent:(const NXRect *)contentRect style:(int)aStyle backing:(int)bufferingType buttonMask:(int)mask defer:(BOOL)flag; { [super initContent:contentRect style:aStyle backing:bufferingType buttonMask:mask defer:flag]; tableNum = 0; numSlots = GK_HS_DEFAULT_SLOTS; // assume that .nib is set up for this wantSlot = GK_HS_NO_SLOT; return self; } - keyDown:(NXEvent *)myevent // handle keyDown events (want to trap 'n') { // sent if no one else in the panel wants keys. if (myevent->data.key.charSet == NX_ASCIISET && (myevent->flags&(NX_CONTROLMASK|NX_ALTERNATEMASK|NX_COMMANDMASK)) == 0) { if (GKKEYCODE == 'n') { // allow new game [[NXApp delegate] startNewGame:self]; // re-start the game // returns nil if user changes mind... return self; // so we don't beep, since we got the keypress } } return [super keyDown:myevent]; } - setTable:(int)num { tableNum = num; return self; } // you have to refresh - changeTable:sender { // sent by pop up list to display a new table; // Note that which row you use determines the table's tag! tableNum = [sender selectedRow]; // row should correspond to table number // that the controller object is using. [self refresh]; return self; } - nameEntered:sender { // sent when player enters their name; need to send name to delegate id theCell; if (wantSlot == GK_HS_NO_SLOT) return self; theCell = [playerNameMatrix findCellWithTag:wantSlot]; if ([delegate respondsTo:@selector(nameForSlot:inTable:is:)]) [delegate nameForSlot:wantSlot inTable:wantTable is:[theCell stringValue]]; // if improper delegate, oh well. [theCell setBackgroundGray:NX_LTGRAY]; [theCell setBezeled:NO]; [theCell setEditable:NO]; wantSlot = GK_HS_NO_SLOT; return self; } - ok:sender { // ok button was hit, so enter the name and then get rid of the panel [self nameEntered:self]; [self orderOut:self]; return self; } - resizeMatrixTo:(int)num { // resize all matrices so that they have num cells. This only works // well if the matrices are in a ScrollView; if the numberMatrix is // connected to something, then we assume that we're in a ScrollView // since that matrix isn't needed otherwise. Returns nil if can't // resize *****This isn't working quite right. Doesn't erase xtra junk! // I've worked around it by forcing the table to be at least 10 slots // in size.***** int i; char *tempString = malloc(num/10 + 2); // won't be any longer than this if (num == numSlots) return self; // we're already the right size if (!numberMatrix) return nil; // don't have a number matrix-no resize if (num < 10) return nil; // won't resize to smaller than 10 numSlots = num; // add empty cells to all the matrices as needed [numberMatrix notifyAncestorWhenFrameChanged:YES]; [[elapsedTimeMatrix renewRows:numSlots cols:1] sizeToCells]; [[endLevelMatrix renewRows:numSlots cols:1] sizeToCells]; [[endTimeMatrix renewRows:numSlots cols:1] sizeToCells]; [[finalScoreMatrix renewRows:numSlots cols:1] sizeToCells]; [[machineNameMatrix renewRows:numSlots cols:1] sizeToCells]; [[playerNameMatrix renewRows:numSlots cols:1] sizeToCells]; [[startLevelMatrix renewRows:numSlots cols:1] sizeToCells]; [[startTimeMatrix renewRows:numSlots cols:1] sizeToCells]; [[userNameMatrix renewRows:numSlots cols:1] sizeToCells]; [[numberMatrix renewRows:numSlots cols:1] sizeToCells]; for (i=1; i<=numSlots; i++) { // number the slots from 1 to numSlots sprintf(tempString, "%d.", i); // note that value is copied by // the -setStringValue so that overwriting it is OK to do. [[numberMatrix cellAt:0 :(i-1)] setStringValue:tempString]; } return self; } - refresh { // get data from delegate and put it into the matrix and re-display id theTable; int i, slotsInTable; if ([delegate respondsTo:@selector(table:)]) theTable = [delegate table:tableNum]; else return self; // may as well bail if the delegate won't give us info! slotsInTable = [theTable count]; // try to resize matrix to #slots in the table. [[self disableFlushWindow] disableDisplay]; // hold off on the graphics... [self resizeMatrixTo:slotsInTable]; for (i=0; i<numSlots; i++) { // now fill the matrices w/slot data [[playerNameMatrix findCellWithTag:i] setStringValue:[[theTable objectAt:i] playerName]]; [[machineNameMatrix findCellWithTag:i] setStringValue:[[theTable objectAt:i] machineName]]; [[userNameMatrix findCellWithTag:i] setStringValue:[[theTable objectAt:i] userName]]; [[startTimeMatrix findCellWithTag:i] setStringValue:[[[theTable objectAt:i] startTime] stringValue]]; [[endTimeMatrix findCellWithTag:i] setStringValue:[[[theTable objectAt:i] endTime] stringValue]]; [[elapsedTimeMatrix findCellWithTag:i] setStringValue:[[[theTable objectAt:i] elapsedTime] stringValue]]; [[startLevelMatrix findCellWithTag:i] setIntValue:[[theTable objectAt:i] startLevel]]; [[endLevelMatrix findCellWithTag:i] setIntValue:[[theTable objectAt:i] endLevel]]; [[finalScoreMatrix findCellWithTag:i] setIntValue:[[theTable objectAt:i] finalScore]]; } [[self reenableDisplay] displayIfNeeded]; // do all drawing at once [[self reenableFlushWindow] flushWindowIfNeeded]; // flush it out once return self; } - getPlayerName:(int)index table:(int)table { // sent by HighScoreController to allow player to enter name id tempCell; // if already looking to fill the name in a slot... // user lost chance to enter name; send default name back to // the delegate and then make it uneditable to allow next slot // to be entered in by the user. Done by telling self user just // entered name, which, indirectly, has just happened. [self nameEntered:self]; // now can set up to enter a new name. if (table != tableNum) { // wants to put in a different table than the // one currently displayed. // so we update pop up list and then get the new table // 1. select a new cell in the matrix and then // 2. reset the title of the trigger button [[[selectPopUp target] itemList] selectCellAt:tableNum :0]; // 1. [selectPopUp setTitle:[[selectPopUp target] selectedItem]]; // 2. tableNum = table; // set up to load in new table } [self refresh]; // with new slot in there, we need a refresh wantSlot = index; tempCell = [playerNameMatrix findCellWithTag:wantSlot]; [tempCell setBackgroundGray:NX_WHITE]; [tempCell setEditable:YES]; [tempCell setBezeled:YES]; // ***** users have suggested pausing before this part since there's an // ***** annoying tendency to "keep playing" and thereby trashing the // ***** name by hitting a key which comes here rather than to the game // ***** view where the user thought it would go. This is needs fixing. // ***** maybe a complete event queue flush _and_ a short delay (such as // ***** a kind of ending sequence would be in order. I'm not so sure // ***** that this object should worry about it, however. [self makeKeyAndOrderFront:self]; // want user to enter name, so bring [self makeFirstResponder:playerNameMatrix]; // up new first responder [playerNameMatrix selectCell:tempCell]; // and select entry field return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.