home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer) / NeXT_Developer-3.3.iso / NextDeveloper / Examples / AppKit / CalculatorLab++ / SimpleCalc.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-10-29  |  5.5 KB  |  208 lines

  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
  208.