home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tv20cpp.zip / demos / calc.cpp < prev    next >
C/C++ Source or Header  |  1999-06-01  |  8KB  |  347 lines

  1. /*------------------------------------------------------------*/
  2. /*                                                            */
  3. /*   Calc.cpp:  TCalcDisplay member functions and TCalculator */
  4. /*              constructor                                   */
  5. /*                                                            */
  6. /*------------------------------------------------------------*/
  7. /*
  8.  *      Turbo Vision - Version 2.0
  9.  *
  10.  *      Copyright (c) 1994 by Borland International
  11.  *      All Rights Reserved.
  12.  *
  13.  */
  14. /*
  15.  * Modified by Sergio Sigala <ssigala@globalnet.it>
  16.  */
  17.  
  18. #define Uses_TRect
  19. #define Uses_TEvent
  20. #define Uses_TButton
  21. #define Uses_TKeys
  22. #define Uses_TDrawBuffer
  23. #define Uses_TStreamableClass
  24. #define Uses_TStreamable
  25. #define Uses_TView
  26. #define Uses_TDialog
  27. #include <tvision/tv.h>
  28. __link( RView )
  29. __link( RDialog )
  30. __link( RButton )
  31.  
  32. #include <string.h>
  33. #include <stdlib.h>
  34. #include <ctype.h>
  35. #include <strstream.h>
  36. #include <iomanip.h>
  37.  
  38. #include "calc.h"
  39.  
  40.  
  41. #define cpCalcPalette   "\x13"
  42.  
  43.  
  44. //
  45. // TCalcDisplay functions
  46. //
  47.  
  48. const char * const TCalcDisplay::name = "TCalcDisplay";
  49.  
  50. void TCalcDisplay::write( opstream& os )
  51. {
  52.     TView::write( os );
  53.     os.writeBytes(&status, sizeof(status));
  54.     os.writeString(number);
  55.     os.writeByte(sign);
  56.     os.writeByte(operate);
  57.     os.writeBytes(&operand, sizeof(operand));
  58. }
  59.  
  60.  
  61. void *TCalcDisplay::read( ipstream& is )
  62. {
  63.     TView::read( is );
  64.     number = new char[DISPLAYLEN];
  65.     is.readBytes(&status, sizeof(status));
  66.     is.readString(number, DISPLAYLEN);
  67.     sign = is.readByte();
  68.     operate = is.readByte();
  69.     is.readBytes(&operand, sizeof(operand));
  70.     return this;
  71. }
  72.  
  73.  
  74. TStreamable *TCalcDisplay::build()
  75. {
  76.     return new TCalcDisplay( streamableInit );
  77. }
  78.  
  79.  
  80. TStreamableClass RCalcDisplay( TCalcDisplay::name,
  81.                                TCalcDisplay::build,
  82.                                __DELTA(TCalcDisplay)
  83.                              );
  84.  
  85.  
  86. TCalcDisplay::TCalcDisplay(TRect& r) : TView ( r )
  87. {
  88.     options |= ofSelectable;
  89.     eventMask = (evKeyboard | evBroadcast);
  90.     number = new char[DISPLAYLEN];
  91.     clear();
  92.  
  93. }
  94.  
  95. TCalcDisplay::~TCalcDisplay()
  96. {
  97.    delete number;
  98. }
  99.  
  100. TPalette& TCalcDisplay::getPalette() const
  101. {
  102.     static TPalette palette( cpCalcPalette, sizeof(cpCalcPalette)-1 );
  103.     return palette;
  104. }
  105.  
  106.  
  107. void TCalcDisplay::handleEvent(TEvent& event)
  108. {
  109.     TView::handleEvent(event);
  110.  
  111.     switch(event.what)
  112.         {
  113.         case evKeyboard:
  114.             calcKey(event.keyDown.charScan.charCode);
  115.             clearEvent(event);
  116.             break;
  117.         case evBroadcast:
  118.             if(event.message.command == cmCalcButton)
  119.                 {
  120.                 calcKey( ((TButton *) event.message.infoPtr)->title[0]);
  121.                 clearEvent(event);
  122.                 }
  123.             break;
  124.         }
  125. }
  126.  
  127.  
  128. void TCalcDisplay::draw()
  129. {
  130.     char color = getColor(1);
  131.     short i;
  132.     TDrawBuffer buf;
  133.  
  134.     i = (short)(size.x - strlen(number) - 2);
  135.     buf.moveChar(0, ' ', color, (short)size.x);
  136.     buf.moveChar(i, sign, color, (short)1 );
  137.     buf.moveStr((short)(i+1), number, color);
  138.     writeLine(0, 0, (short)size.x, 1, buf);
  139. }
  140.  
  141.  
  142. void TCalcDisplay::error()
  143. {
  144.     status = csError;
  145.     strcpy(number, "Error");
  146.     sign = ' ';
  147. }
  148.  
  149.  
  150. void TCalcDisplay::clear()
  151. {
  152.     status = csFirst;
  153.     strcpy(number, "0");
  154.     sign = ' ';
  155.     operate = '=';
  156. }
  157.  
  158.  
  159. void TCalcDisplay::setDisplay(double r)
  160. {
  161.     int  len;
  162.     char str[64];
  163.     ostrstream displayStr( str, sizeof str );
  164.  
  165.     if(r < 0.0)
  166.         {
  167.         sign = '-';
  168.         displayStr << -r << ends;
  169.         }
  170.     else
  171.         {
  172.         displayStr << r << ends;
  173.         sign = ' ';
  174.         }
  175.  
  176.     len = strlen(str) - 1;          // Minus one so we can use as an index.
  177.  
  178.     if(len > DISPLAYLEN)
  179.         error();
  180.     else
  181.         strcpy(number, str);
  182. }
  183.  
  184.  
  185. void TCalcDisplay::checkFirst()
  186. {
  187.     if( status == csFirst)
  188.         {
  189.         status = csValid;
  190.         strcpy(number, "0");
  191.         sign = ' ';
  192.         }
  193. }
  194.  
  195.  
  196. void TCalcDisplay::calcKey(unsigned char key)
  197. {
  198.     char stub[2] = " ";
  199.     double r;
  200.  
  201.     key = (unsigned char)toupper(key);
  202.     if( status == csError && key != 'C')
  203.         key = ' ';
  204.  
  205.     switch(key)
  206.         {
  207.         case '0':   case '1':   case '2':   case '3':   case '4':
  208.         case '5':   case '6':   case '7':   case '8':   case '9':
  209.             checkFirst();
  210.             if (strlen(number) < 15) 
  211.                 {                       // 15 is max visible display length
  212.                 if (strcmp(number, "0") == 0)
  213.                     number[0] = '\0';
  214.                 stub[0] = key;
  215.                 strcat(number, stub);
  216.                 }
  217.             break;
  218.  
  219.         case '.':
  220.             checkFirst();
  221.             if(strchr(number, '.') == NULL)
  222.                 {
  223.                 stub[0] = '.';
  224.                 strcat(number, stub);
  225.                 }
  226.             break;
  227.  
  228.         case 8:
  229.         case 27:
  230.             int len;
  231.  
  232.             checkFirst();
  233.             if( (len = strlen(number)) == 1 )
  234.                 strcpy(number, "0");
  235.             else
  236.                 number[len-1] = '\0';
  237.             break;
  238.  
  239.         case '_':                   // underscore (keyboard version of +/-)
  240.         case 241:                   // +/- extended character.
  241.             if (sign==' ')
  242.               sign='-';
  243.             else
  244.               sign=' ';
  245.             break;
  246.  
  247.         case '+':   case '-':   case '*':   case '/':
  248.         case '=':   case '%':   case 13:
  249.             if(status == csValid)
  250.                 {
  251.                 status = csFirst;
  252.                 r = getDisplay() * ((sign == '-') ? -1.0 : 1.0);
  253.                 if( key == '%' )
  254.                     {
  255.                     if(operate == '+' || operate == '-')
  256.                         r = (operand * r) / 100;
  257.                     else
  258.                         r /= 100;
  259.                     }
  260.                 switch( operate )
  261.                     {
  262.                     case '+':
  263.                         setDisplay(operand + r);
  264.                         break;
  265.  
  266.                     case '-':
  267.                         setDisplay(operand - r);
  268.                         break;
  269.  
  270.                     case '*':
  271.                         setDisplay(operand * r);
  272.                         break;
  273.  
  274.                     case '/':
  275.                         if(r == 0)
  276.                             error();
  277.                         else
  278.                             setDisplay(operand / r);
  279.                         break;
  280.  
  281.                     }
  282.                 }
  283.             operate = key;
  284.             operand = getDisplay() * ((sign == '-') ? -1.0 : 1.0);
  285.             break;
  286.  
  287.         case 'C':
  288.             clear();
  289.             break;
  290.  
  291.         }
  292.     drawView();
  293. }
  294.  
  295.  
  296.  
  297. static char *keyChar[20] =
  298.     {    "C", "\x1B",    "%", "\xF1",   // 0x1B is escape, 0xF1 is +/- char.
  299.          "7",    "8",    "9",    "/",
  300.          "4",    "5",    "6",    "*",
  301.          "1",    "2",    "3",    "-",
  302.          "0",    ".",    "=",    "+"
  303.     };
  304.  
  305.  
  306. //
  307. // TCalculator functions
  308. //
  309.  
  310. const char * const TCalculator::name = "TCalculator";
  311.  
  312. TStreamable *TCalculator::build()
  313. {
  314.     return new TCalculator( streamableInit );
  315. }
  316.  
  317.  
  318. TStreamableClass RCalculator( TCalculator::name,
  319.                               TCalculator::build,
  320.                               __DELTA(TCalculator)
  321.                             );
  322.  
  323.  
  324. TCalculator::TCalculator() :
  325.     TDialog( TRect(5, 3, 29, 18), "Calculator" ),
  326.     TWindowInit( &TCalculator::initFrame )
  327. {
  328.     TView *tv;
  329.     TRect r;
  330.  
  331.     options |= ofFirstClick;
  332.  
  333.     for(int i = 0; i <= 19; i++)
  334.         {
  335.         int x = (i%4)*5+2;
  336.         int y = (i/4)*2+4;
  337.         r = TRect( x, y, x+5, y+2 );
  338.  
  339.         tv = new TButton( r, keyChar[i], cmCalcButton, bfNormal | bfBroadcast );
  340.         tv->options &= ~ofSelectable;
  341.         insert( tv );
  342.         }
  343.     r = TRect( 3, 2, 21, 3 );
  344.     insert( new TCalcDisplay(r) );
  345. }
  346.  
  347.