Annotation of Examples/AppKit/CalculatorLab/SimpleCalc.m, revision 1.1

1.1     ! root        1: /*
        !             2:  *     SimpleCalc -- Randy Nelson
        !             3:  *     A general class that directly supports a calculator interface
        !             4:  *     Created 8-8-90
        !             5:  *
        !             6:  *     You may freely copy, distribute and reuse the code in this example.
        !             7:  *     NeXT disclaims any warranty of any kind, expressed or implied, as to
        !             8:  *     its fitness for any particular use.
        !             9:  */
        !            10: 
        !            11: #import "SimpleCalc.h"
        !            12: #import <appkit/Application.h>
        !            13: #import <objc/NXStringTable.h>
        !            14: #import <appkit/Panel.h>
        !            15: #import <appkit/Text.h>
        !            16: #import <appkit/Button.h>
        !            17: #import <appkit/publicWraps.h>
        !            18: #import <stdio.h>
        !            19: #import <strings.h>
        !            20: 
        !            21: #define DECIMALPOINT 10
        !            22: #define DIVIDE 20
        !            23: #define MULTIPLY 21
        !            24: #define SUBTRACT 22
        !            25: #define ADD 23
        !            26: #define CLEAR 31
        !            27: #define CLEARALL 30
        !            28: 
        !            29: @implementation SimpleCalc
        !            30: - init
        !            31: {
        !            32:     [super init];
        !            33:     [self doInit];
        !            34:     return self;
        !            35: }
        !            36: 
        !            37: - doInit
        !            38: {
        !            39:     accumulator = 0;
        !            40:     operator = 0;
        !            41:     numberHasADecimal = NO;
        !            42:     startingSecondNumber = NO;
        !            43:     treatingOperationKeyLikeEqualKey = NO;
        !            44:     noFirstNumber = YES;
        !            45:     return self;
        !            46: }
        !            47: 
        !            48: - numberKeys:sender
        !            49: {
        !            50:     char       aDigit[2];
        !            51:     int        digit = [sender selectedTag];
        !            52:     
        !            53:     noFirstNumber = NO;
        !            54:     
        !            55:     /* clear the display in order to begin the second number */
        !            56:     if(startingSecondNumber == YES){
        !            57:        [display setStringValue:""];
        !            58:        startingSecondNumber = NO;
        !            59:     }
        !            60:     if(digit == DECIMALPOINT){
        !            61:        [self decimal];
        !            62:        return self;
        !            63:     }
        !            64:     sprintf(aDigit, "%d", digit);
        !            65:     [self appendToDisplay:(const char *)aDigit];
        !            66:     return self;
        !            67: }
        !            68: 
        !            69: - decimal
        !            70: {
        !            71:     if(numberHasADecimal == YES){
        !            72:        NXBeep();
        !            73:        return self;
        !            74:     }
        !            75:     /* internationalizable strings */
        !            76:     [self appendToDisplay:[stringSet valueForStringKey:"decimalPointString"]];
        !            77:     numberHasADecimal = YES;
        !            78:     return self;
        !            79: }
        !            80: 
        !            81: - operationKeys:sender
        !            82: {
        !            83:     //do nothing if noFirstNumber
        !            84:     if(noFirstNumber == YES){
        !            85:        NXBeep();
        !            86:        return self;
        !            87:     }
        !            88:     
        !            89:    /* if there's an operation and a first and second number
        !            90:     * act like the equal key was pressed
        !            91:     */
        !            92:     if((treatingOperationKeyLikeEqualKey == YES) &&
        !            93:       (startingSecondNumber == NO)){
        !            94:        [self equalsKey:self];
        !            95:     }
        !            96:     operator = [sender selectedTag];
        !            97:     switch(operator){
        !            98:        case DIVIDE: case MULTIPLY: case SUBTRACT: case ADD:{
        !            99:                accumulator = [display doubleValue];
        !           100:                numberHasADecimal = NO;
        !           101:                startingSecondNumber = YES;
        !           102:                treatingOperationKeyLikeEqualKey = YES;
        !           103:                break;
        !           104:        }
        !           105:        default:{
        !           106:                return self;
        !           107:        }
        !           108:     }
        !           109:     return self;
        !           110: }
        !           111: 
        !           112: - equalsKey:sender
        !           113: {
        !           114:     /* do nothing if noFirstNumber */
        !           115:     if(noFirstNumber == YES){
        !           116:            NXBeep();
        !           117:            return self;
        !           118:     }
        !           119:     switch(operator){
        !           120:        case DIVIDE:{
        !           121:            if([display doubleValue] == 0){
        !           122:                //can't divide by zero
        !           123:                NXBeep();
        !           124:                return self;
        !           125:            }
        !           126:            [display setDoubleValue:(accumulator / [display doubleValue])];
        !           127:            break;
        !           128:        }
        !           129:        case MULTIPLY:{
        !           130:            [display setDoubleValue:(accumulator * [display doubleValue])];
        !           131:            break;
        !           132:        }
        !           133:        case SUBTRACT:{
        !           134:            [display setDoubleValue:(accumulator - [display doubleValue])];
        !           135:            break;
        !           136:        }
        !           137:        case ADD:{
        !           138:            [display setDoubleValue:(accumulator + [display doubleValue])];
        !           139:            break;
        !           140:        }
        !           141:        default:{
        !           142:                return self;
        !           143:        }
        !           144:     }
        !           145:    /* just lke doInit
        !           146:     * but startingSecondNumber gets YES
        !           147:     * and noFirstNumber continues to be NO (there is a first number)
        !           148:     */
        !           149:     operator = 0;
        !           150:     accumulator = 0;
        !           151:     numberHasADecimal = NO;
        !           152:     startingSecondNumber = YES;
        !           153:     treatingOperationKeyLikeEqualKey = NO;
        !           154:     return self;
        !           155: }
        !           156: 
        !           157: - clearKeys:sender
        !           158: {
        !           159:     switch([sender selectedTag]){
        !           160:        case CLEAR:{
        !           161:            [display setStringValue:[stringSet
        !           162:                                        valueForStringKey:"zeroString"]];
        !           163:            numberHasADecimal = NO;
        !           164:            startingSecondNumber = YES;
        !           165:            break;
        !           166:        }
        !           167:        case CLEARALL:{
        !           168:            [display setStringValue:[stringSet
        !           169:                                         valueForStringKey:"zeroString"]];
        !           170:            [self doInit];
        !           171:            break;
        !           172:        }
        !           173:        default:{
        !           174:                break;
        !           175:        }
        !           176:     }
        !           177:     return self;
        !           178: }
        !           179: 
        !           180: - appendToDisplay:(const char *)theDigit
        !           181: {
        !           182:     char *copyOfDisplay = NXCopyStringBuffer([display stringValue]);
        !           183:     
        !           184:     /* if the display's current value is zero */
        !           185:     if([display doubleValue] == 0){
        !           186:        
        !           187:        /* and the zero doesn't have a decimal point */
        !           188:        if(numberHasADecimal == NO){
        !           189:                
        !           190:            /* replace the display with the digit passed */
        !           191:            [display setStringValue:theDigit];
        !           192:            return self;
        !           193:        }
        !           194:     }  
        !           195:    /* otherwise append the digit passed
        !           196:     * to the digits already in the display
        !           197:     */
        !           198:     [display setStringValue:strcat(copyOfDisplay, theDigit)];
        !           199:     
        !           200:     return self;
        !           201: }
        !           202: 
        !           203: - numberDirectFromDisplay:sender
        !           204: {
        !           205:     noFirstNumber = NO;
        !           206:     startingSecondNumber = YES;
        !           207:     return self;
        !           208: }
        !           209: 
        !           210: - appDidInit:sender
        !           211: {
        !           212:     /* enter key can't be set as key equivalent from IB */
        !           213:     [enterKey setKeyEquivalent:3];
        !           214:     [[display window] makeKeyAndOrderFront:self];
        !           215:     return self;
        !           216: }
        !           217: 
        !           218: - windowWillClose:window
        !           219: {
        !           220:     return [NXApp terminate:self];
        !           221: }
        !           222: 
        !           223: - infoPanel:sender
        !           224: {
        !           225:     if(infoPanel == nil){
        !           226:        [NXApp loadNibSection:"Info.nib" owner:self];
        !           227:     }
        !           228:     [infoPanel orderFront:sender];
        !           229:     return self;       
        !           230: }
        !           231: 
        !           232: - helpPanel:sender
        !           233: {
        !           234:     if(helpPanel == nil){
        !           235:        [NXApp loadNibSection:"Help.nib" owner:self];
        !           236:     }
        !           237:     [helpPanel orderFront:sender];
        !           238:     return self;       
        !           239: 
        !           240: }
        !           241: @end

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.