home *** CD-ROM | disk | FTP | other *** search
- /*
- * SimpleCalc -- Randy Nelson
- * A general class that directly supports a calculator interface
- * Created 8-8-90
- *
- * 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 "SimpleCalc.h"
- #import <appkit/Application.h>
- #import <objc/NXStringTable.h>
- #import <appkit/Panel.h>
- #import <appkit/Text.h>
- #import <appkit/Button.h>
- #import <appkit/publicWraps.h>
- #import <stdio.h>
- #import <strings.h>
-
- #define DECIMALPOINT 10
- #define DIVIDE 20
- #define MULTIPLY 21
- #define SUBTRACT 22
- #define ADD 23
- #define CLEAR 31
- #define CLEARALL 30
-
- @implementation SimpleCalc
- - init
- {
- [super init];
- [self doInit];
- return self;
- }
-
- - doInit
- {
- accumulator = 0;
- operator = 0;
- numberHasADecimal = NO;
- startingSecondNumber = NO;
- treatingOperationKeyLikeEqualKey = NO;
- noFirstNumber = YES;
- return self;
- }
-
- - numberKeys:sender
- {
- c7& aDigit[2];
- int digit = [sender selectedTag];
-
- noFirstNumber = NO;
-
- /* clear the display in order to begin the second number */
- if(startingSecondNumber == YES){
- [display setStringValue:""];
- startingSecondNumber = NO;
- }
- if(digit == DECIMALPOINT){
- [self decimal];
- return self;
- }
- sprintf(aDigit, "%d", digit);
- [self appendToDisplay:(const char *)aDigit];
- return self;
- }
-
- - decimal
- {
- if(numberHasADecimal == YES){
- NXBeep();
- return self;
- }
- /* internationalizable strings */
- [self appendToDisplay:[stringSet valueForStringKey:"decimalPointString"]];
- numberHasADecimal = YES;
- return self;
- }
-
- - operationKeys:sender
- {
- //do nothing if noFirstNumber
- if(noFirstNumber == YES){
- NXBeep();
- return self;
- }
-
- /* if there's an operation and a first and second number
- * act like the equal key was pressed
- */
- if((treatingOperationKeyLikeEqualKey == YES) &&
- (startingSecondNumber == NO)){
- [self equalsKey:self];
- }
- operator = [sender selectedTag];
- switch(operator){
- case DIVIDE: case MULTIPLY: case SUBTRACT: case ADD:{
- accumulator = [display doubleValue];
- numberHasADecimal = NO;
- startingSecondNumber = YES;
- treatingOperationKeyLikeEqualKey = YES;
- break;
- }
- default:{
- return self;
- }
- }
- return self;
- }
-
- - equalsKey:sender
- {
- /* do nothing if noFirstNumber */
- if(noFirstNumber == YES){
- NXBeep();
- return self;
- }
- switch(operator){
- case DIVIDE:{
- if([display doubleValue] == 0){
- //can't divide by zero
- NXBeep();
- return self;
- }
- [display setDoubleValue:(accumulator / [display doubleValue])];
- break;
- }
- case MULTIPLY:{
- [display setDoubleValue:(accumulator * [display doubleValue])];
- break;
- }
- case SUBTRACT:{
- [display setDoubleValue:(accumulator - [display doubleValue])];
- break;
- }
- case ADD:{
- [display setDoubleValue:(accumulator + [display doubleValue])];
- break;
- }
- default:{
- return self;
- }
- }
- /* just lke doInit
- * but startingSecondNumber gets YES
- * and noFirstNumber continues to be NO (there is a first number)
- */
- operator = 0;
- accumulator = 0;
- numberHasADecimal = NO;
- startingSecondNumber = YES;
- treatingOperationKeyLikeEqualKey = NO;
- return self;
- }
-
- - clearKeys:sender
- {
- switch([sen7&selectedTag]){
- case CLEAR:{
- [display setStringValue:[stringSet
- valueForStringKey:"zeroString"]];
- numberHasADecimal = NO;
- startingSecondNumber = YES;
- break;
- }
- case CLEARALL:{
- [display setStringValue:[stringSet
- valueForStringKey:"zeroString"]];
- [self doInit];
- break;
- }
- default:{
- break;
- }
- }
- return self;
- }
-
- - appendToDisplay:(const char *)theDigit
- {
- char *copyOfDisplay = NXCopyStringBuffer([display stringValue]);
-
- /* if the display's current value is zero */
- if([display doubleValue] == 0){
-
- /* and the zero doesn't have a decimal point */
- if(numberHasADecimal == NO){
-
- /* replace the display with the digit passed */
- [display setStringValue:theDigit];
- return self;
- }
- }
- /* otherwise append the digit passed
- * to the digits already in the display
- */
- [display setStringValue:strcat(copyOfDisplay, theDigit)];
-
- return self;
- }
-
- - numberDirectFromDisplay:sender
- {
- noFirstNumber = NO;
- startingSecondNumber = YES;
- return self;
- }
-
- - appDidInit:sender
- {
- /* enter key can't be set as key equivalent from IB */
- [enterKey setKeyEquivalent:3];
- [[display window] makeKeyAndOrderFront:self];
- return self;
- }
-
- - windowWillClose:window
- {
- return [NXApp terminate:self];
- }
-
- - infoPanel:sender
- {
- if(infoPanel == nil){
- [NXApp loadNibSection:"Info.nib" owner:self];
- }
- [infoPanel orderFront:sender];
- return self;
- }
-
- - helpPanel:sender
- {
- if(helpPanel == nil){
- [NXApp loadNibSection:"Help.nib" owner:self];
- }
- [helpPanel orderFront:sender];
- return self;
-
- }
- @end
-