1 // SimpleCalc -- Randy Nelson -- NeXT Developer Training
2 // A general class that serves as a liaison between a calculator interface
3 // and a calculator engine.
5 // You may freely copy, distribute and reuse the code in this example.
6 // NeXT disclaims any warranty of any kind, expressed or implied, as to
7 // its fitness for any particular use.
11 // C++ "linkage" directive - tells the C++ compiler that the following
12 // interface files contain Objective-C code.
16 #import <appkit/Application.h>
17 #import <appkit/Panel.h>
18 #import <appkit/TextField.h>
19 #import <appkit/Button.h>
24 #import <appkit/publicWraps.h>
25 #import <objc/error.h>
26 #import <objc/NXStringTable.h>
30 // The C++ "linkage" directive serves two purposes (when importing
31 // interface files that contain straight ANSI-C/Objective-C code). It:
33 // (a) allows you to link with libraries that have not been compiled with
34 // the C++ compiler. Since libraries on the NeXT computer are compiled
35 // with the Objective-C compiler (cc, not cc++), you must use the C++
36 // linkage directive when importing interface files that represent NeXT
37 // libraries (or any library that is not compiled with cc++).
39 // (b) tells the compiler to ignore C++ keywords that will result in
40 // syntax errors when importing ANSI-C/Objective-C interface files.
41 // The linkage directive essentially tells the C++ compiler to treat
42 // keywords (such as "new", "delete", etc.) as normal identifiers.
44 #import "SimpleCalc.h"
45 #import "CalcEngine.h"
46 #import "InfoManager.h"
48 @implementation SimpleCalc
50 // Initialize an instance of the SimpleCalc class. One instance variable of
51 // that class is the C++ calculator engine.
54 cplus_object = new CalcEngine; // new is a keyword in C++.
59 // Append a new digit entered by the user to the text field display.
60 - appendToDisplay:(const char *)theDigit
62 char *copyOfDisplay = NXCopyStringBuffer([display stringValue]);
64 [display setStringValue: strcat(copyOfDisplay, theDigit)];
69 // We need to keep a history of one action to make decisions about the display.
70 - registerAction:(SEL)action
72 previousAction = action;
76 // The user has pushed the decimal key on the calculator.
79 if (previousAction == @selector(operationKeys:))
80 [display setStringValue:"."];
82 if (strchr([display stringValue], '.'))
85 [self appendToDisplay:"."];
87 return [self registerAction:_cmd];
90 // One of the number keys was selected by the user.
94 int digit = [sender selectedTag];
96 sprintf(aDigit, "%d", digit);
98 if (previousAction == @selector(operationKeys:) ||
99 previousAction == @selector(equalsKey:))
101 [display setStringValue:aDigit];
103 if ([display doubleValue] == 0 && !strchr([display stringValue], '.'))
104 [display setStringValue:aDigit];
106 [self appendToDisplay:aDigit];
108 return [self registerAction:_cmd];
111 // The user pressed the equals key on the calculator interface.
114 if (previousAction == 0)
118 [display setDoubleValue:
119 cplus_object->equalsKey([display doubleValue])];
122 [myNXStringTable valueForStringKey:"operationFailed"],
123 [myNXStringTable valueForStringKey:NXLocalHandler.data1],
124 [myNXStringTable valueForStringKey:"OK"], NULL, NULL);
127 return [self registerAction:_cmd];
130 // The user pressed one of the operation keys.
131 - operationKeys:sender
133 if (previousAction == 0)
135 else if (previousAction == @selector(operationKeys:))
136 cplus_object->setOperation([sender selectedTag]);
139 [display setDoubleValue:
140 cplus_object->operationKeys([sender selectedTag],
141 [display doubleValue])];
144 [myNXStringTable valueForStringKey:"operationFailed"],
145 [myNXStringTable valueForStringKey:NXLocalHandler.data1],
146 [myNXStringTable valueForStringKey:"OK"], NULL, NULL);
149 return [self registerAction:_cmd];
152 // User pressed the Clear key.
155 [display setStringValue:"0"];
159 // User pressed the Clear All key.
162 cplus_object->clear();
163 [self registerAction:0];
164 return [self clearKey:sender];
167 // Called just after the application initializes and starts up.
170 // Set the Enter key on the keypad to be equivalent to the = key.
171 [[display window] addToEventMask:NX_SYMBOLSET];
172 [enterKey setKeyEquivalent:3];
173 [[display window] makeKeyAndOrderFront:self];
177 // Called just before the window closes.
178 - windowWillClose:sender
180 return [NXApp terminate:self];
183 // Brings up the Info panel. Not done on startup because it's in a separate
184 // interface file. Saves startup time for the user if we do this when they ask
185 // for it, and not before.
188 if(infoManager == nil){
189 infoManager = [[InfoManager alloc] init];
191 [infoManager orderInfoPanelFront:sender];
195 // Brings up the Help panel. Not done on startup because it's in a separate
196 // interface file. Saves startup time for the user if we do this when they ask
197 // for it, and not before.
200 if(infoManager == nil){
201 infoManager = [[InfoManager alloc] init];
203 [infoManager orderHelpPanelFront:sender];