]> code.delx.au - gnu-emacs/blob - test/etags/objcpp-src/SimpleCalc.M
* test/automated/viper-tests.el (viper-test-undo-kmacro):
[gnu-emacs] / test / etags / objcpp-src / SimpleCalc.M
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.
4 //
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.
8 //
9 // Created 8-22-90
10 //
11 // C++ "linkage" directive - tells the C++ compiler that the following
12 // interface files contain Objective-C code.
13
14 extern "Objective-C"
15 {
16 #import <appkit/Application.h>
17 #import <appkit/Panel.h>
18 #import <appkit/TextField.h>
19 #import <appkit/Button.h>
20 }
21
22 extern "C"
23 {
24 #import <appkit/publicWraps.h>
25 #import <objc/error.h>
26 #import <objc/NXStringTable.h>
27 #import <strings.h>
28 }
29
30 // The C++ "linkage" directive serves two purposes (when importing
31 // interface files that contain straight ANSI-C/Objective-C code). It:
32 //
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++).
38 //
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.
43
44 #import "SimpleCalc.h"
45 #import "CalcEngine.h"
46 #import "InfoManager.h"
47
48 @implementation SimpleCalc
49
50 // Initialize an instance of the SimpleCalc class. One instance variable of
51 // that class is the C++ calculator engine.
52 - init
53 {
54 cplus_object = new CalcEngine; // new is a keyword in C++.
55 previousAction = 0;
56 return self;
57 }
58
59 // Append a new digit entered by the user to the text field display.
60 - appendToDisplay:(const char *)theDigit
61 {
62 char *copyOfDisplay = NXCopyStringBuffer([display stringValue]);
63
64 [display setStringValue: strcat(copyOfDisplay, theDigit)];
65
66 return self;
67 }
68
69 // We need to keep a history of one action to make decisions about the display.
70 - registerAction:(SEL)action
71 {
72 previousAction = action;
73 return self;
74 }
75
76 // The user has pushed the decimal key on the calculator.
77 - decimalKey:sender
78 {
79 if (previousAction == @selector(operationKeys:))
80 [display setStringValue:"."];
81 else {
82 if (strchr([display stringValue], '.'))
83 NXBeep();
84 else
85 [self appendToDisplay:"."];
86 }
87 return [self registerAction:_cmd];
88 }
89
90 // One of the number keys was selected by the user.
91 - numberKeys:sender
92 {
93 char aDigit[2];
94 int digit = [sender selectedTag];
95
96 sprintf(aDigit, "%d", digit);
97
98 if (previousAction == @selector(operationKeys:) ||
99 previousAction == @selector(equalsKey:))
100 {
101 [display setStringValue:aDigit];
102 } else {
103 if ([display doubleValue] == 0 && !strchr([display stringValue], '.'))
104 [display setStringValue:aDigit];
105 else
106 [self appendToDisplay:aDigit];
107 }
108 return [self registerAction:_cmd];
109 }
110
111 // The user pressed the equals key on the calculator interface.
112 - equalsKey:sender
113 {
114 if (previousAction == 0)
115 NXBeep();
116 else {
117 NX_DURING
118 [display setDoubleValue:
119 cplus_object->equalsKey([display doubleValue])];
120 NX_HANDLER
121 NXRunAlertPanel(
122 [myNXStringTable valueForStringKey:"operationFailed"],
123 [myNXStringTable valueForStringKey:NXLocalHandler.data1],
124 [myNXStringTable valueForStringKey:"OK"], NULL, NULL);
125 NX_ENDHANDLER
126 }
127 return [self registerAction:_cmd];
128 }
129
130 // The user pressed one of the operation keys.
131 - operationKeys:sender
132 {
133 if (previousAction == 0)
134 NXBeep();
135 else if (previousAction == @selector(operationKeys:))
136 cplus_object->setOperation([sender selectedTag]);
137 else {
138 NX_DURING
139 [display setDoubleValue:
140 cplus_object->operationKeys([sender selectedTag],
141 [display doubleValue])];
142 NX_HANDLER
143 NXRunAlertPanel(
144 [myNXStringTable valueForStringKey:"operationFailed"],
145 [myNXStringTable valueForStringKey:NXLocalHandler.data1],
146 [myNXStringTable valueForStringKey:"OK"], NULL, NULL);
147 NX_ENDHANDLER
148 }
149 return [self registerAction:_cmd];
150 }
151
152 // User pressed the Clear key.
153 - clearKey:sender
154 {
155 [display setStringValue:"0"];
156 return self;
157 }
158
159 // User pressed the Clear All key.
160 - clearAllKey:sender
161 {
162 cplus_object->clear();
163 [self registerAction:0];
164 return [self clearKey:sender];
165 }
166
167 // Called just after the application initializes and starts up.
168 - appDidInit:sender
169 {
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];
174 return self;
175 }
176
177 // Called just before the window closes.
178 - windowWillClose:sender
179 {
180 return [NXApp terminate:self];
181 }
182
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.
186 - infoPanel:sender
187 {
188 if(infoManager == nil){
189 infoManager = [[InfoManager alloc] init];
190 }
191 [infoManager orderInfoPanelFront:sender];
192 return self;
193 }
194
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.
198 - helpPanel:sender
199 {
200 if(infoManager == nil){
201 infoManager = [[InfoManager alloc] init];
202 }
203 [infoManager orderHelpPanelFront:sender];
204 return self;
205 }
206
207 @end