Annotation of Examples/AppKit/CalculatorLab/SimpleCalc.m, revision 1.1.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.