home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
NeXTSTEP 3.2 (Developer)
/
NS_dev_3.2.iso
/
NextDeveloper
/
Examples
/
AppKit
/
CalculatorLab
/
SimpleCalc.m
< prev
Wrap
Text File
|
1990-10-29
|
5KB
|
242 lines
/*
* 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
{
char 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([sender 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