home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / vos2-121.zip / v / srcos2 / vspinc.cpp < prev    next >
C/C++ Source or Header  |  1999-02-24  |  11KB  |  352 lines

  1. //===============================================================
  2. // vspinc.cxx   - vSpinnerCmd - Windows
  3. //
  4. // Copyright (C) 1995,1996,1997,1998  Bruce E. Wampler
  5. //
  6. // This file is part of the V C++ GUI Framework, and is covered
  7. // under the terms of the GNU Library General Public License,
  8. // Version 2. This library has NO WARRANTY. See the source file
  9. // vapp.cxx for more complete information about license terms.
  10. //===============================================================
  11. #include <v/vos2.h>           // for OS/2 stuff
  12. #include <v/vspinc.h>   // our definitions
  13. #include <v/vcmdprnt.h> // a command parent
  14. #include <v/vapp.h>
  15. #include <v/vutil.h>
  16.  
  17. //=================>>> vSpinnerCmd::vSpinnerCmd <<<=======================
  18.   vSpinnerCmd::vSpinnerCmd(vCmdParent* dp, CommandObject* co) :
  19.         vCmd(dp, co)
  20.   {
  21.     initialize();                       // and initialize
  22.   }
  23. //=======================>>> vSpinnerCmd::~vSpinnerCmd <<<=====================
  24.   vSpinnerCmd::~vSpinnerCmd()
  25.   {
  26.     SysDebug(Constructor,"vSpinnerCmd::~vSpinnerCmd() Destructor\n")
  27.     if (_TextList == 2)
  28.       DosFreeMem ((PPVOID) &_fullList);
  29.   }
  30. //=====================>>> vSpinnerCmd::initialize <<<=======================
  31.   void vSpinnerCmd::initialize(void)
  32.   {
  33.     long style;
  34.     SysDebug(Constructor,"vSpinnerCmd::vSpinnerCmd() constructor\n")
  35.     CopyToLocal();                      // Make local copies of CmdObject
  36.  
  37.     // First, build the list parameters
  38.     _fullList = 0;
  39.     SetupList();
  40.  
  41.     style = SPBS_READONLY | SPBS_MASTER | SPBS_FASTSPIN; // readonly master control
  42.  
  43.     if (!(dlgCmd->attrs & CA_Hidden))   // Check for Hidden
  44.       style |= WS_VISIBLE;
  45.  
  46.     if (_TextList==1)   // array of strings
  47.     {
  48.       strncpy(_spinTitle, _fullList[_curSelection], 255);
  49.     }
  50.     else if (_TextList==2)   // array of non-consecutive integers
  51.     {
  52.       IntToStr(_curSelection, _spinTitle);
  53.     }
  54.     else             // numeric list
  55.     {
  56.       style |= SPBS_NUMERICONLY;
  57.       IntToStr(_curSelection, _spinTitle);
  58.       _scd.lLowerLimit = _minVal;
  59.       _scd.lUpperLimit = _maxVal;
  60.     }
  61.     _title = _spinTitle;
  62.  
  63.     _scd.cbSize = sizeof(SPBCDATA);
  64.  
  65.     _maxWidth = _maxWidth + 14;        // change chars to dialog pixels
  66.     _maxWidth = (dlgCmd->attrs & CA_Large) ? (_maxWidth * 3)/2
  67.                           : _maxWidth;
  68.     if (dlgCmd->size > 0 && dlgCmd->size < 2048)
  69.     {
  70.     _maxWidth = dlgCmd->size;
  71.         if (_maxWidth < 24 )  // trap ridiculous size
  72.           _maxWidth = 24;
  73.     }
  74.  
  75.     _w = _maxWidth;
  76.     _h = 11;
  77.  
  78.     _parentWin->SetPosition(_x, _y, _w, _h, dlgCmd->cFrame, dlgCmd->cRightOf,
  79.     dlgCmd->cBelow);
  80.  
  81.     _CtrlOffset = _parentWin->AddDlgControl(_x, _y , _w, _h, _cmdId,
  82.        style, WC_SPINBUTTON, _title, NULL, _scd.cbSize, &_scd);
  83.   }
  84.  
  85. //====================>>> vSpinnerCmd::SetupList <<<=======================
  86.   void vSpinnerCmd::SetupList(void)
  87.   {
  88.     // Set up the list for use
  89.     // Scans list and determines if text or numeric
  90.     // If text, sets _TextList=1, _step=1, _numItems, computes max
  91.     // field width (_maxWidth) and sets _curSelection to default value
  92.     //
  93.     // If numeric, sets _TextList=0, _minVal, _maxVal, _step,
  94.     // computes field width (_maxWidth), and sets _curSelection
  95.     // to default value
  96.  
  97.     int width;
  98.     _maxWidth = 0;                      // no items yet
  99.  
  100.     if (dlgCmd->attrs & CA_Text)        // A text list of values
  101.     {
  102.       _fullList = (char**)_itemList;              // list
  103.       _TextList = 1;                  // This is a text list
  104.       _step = 1;
  105.       for ( _numItems = 0 ; _fullList[_numItems] != 0 ; ++_numItems)
  106.       {
  107.     width = LabelWidth(_fullList[_numItems]) + 2;   // text width
  108.     if (width > _maxWidth)
  109.       _maxWidth = width;              // track largest so far
  110.       }
  111.       if (_numItems <= 0)
  112.       {
  113.     SysDebug(BadVals,"Bad list provided for ValueBox\n");
  114.       }
  115.       // Set to default value
  116.       if (_retVal >= 0 && _retVal < _numItems)
  117.     _curSelection = _retVal;
  118.       else
  119.     _curSelection = 0;          // item 0 by default
  120.     }
  121.     else       // an integer list with arbitrary step
  122.     {
  123.       _TextList = 0;                  // This is an integer list
  124.       int* minMaxList = (int *) _itemList;            // list
  125.       _minVal = 0; _maxVal = 0x7fff; _step = 1;
  126.  
  127.       if (minMaxList != 0)            // provided a range list
  128.       {
  129.     _minVal = minMaxList[0];
  130.     _maxVal = minMaxList[1];
  131.     _step = minMaxList[2];
  132.     _TextList = 2;                  // This is a non-consecutive integer list
  133.  
  134.     // Try to make the width pretty
  135.     char buff[20];
  136.     IntToStr(_minVal,buff);
  137.     int maxChars = strlen(buff);
  138.     _maxWidth = LabelWidth(buff) + 2;
  139.     IntToStr(_maxVal,buff);
  140.     int maxC = strlen(buff);
  141.     int maxW = LabelWidth(buff) + 2;
  142.     if (maxW > _maxWidth)
  143.       _maxWidth = maxW;
  144.     if (maxC > maxChars)
  145.       maxChars = maxC;
  146.  
  147.     // now build up an array of strings of each value
  148.     int i;
  149.  
  150.     // compute number of items and store in _numItems
  151.     for(_numItems=0, i=_minVal; i<=_maxVal; i+=_step, _numItems++);
  152.  
  153.     // build a character array of values if step!=1
  154.     if (_fullList != 0)   // check if re-allocation!
  155.       DosFreeMem ((PPVOID) &_fullList);
  156.     DosAllocMem ((PPVOID) &_fullList, _numItems*(maxChars+5), fALLOC);
  157.  
  158.     char *item;
  159.     item = (CHAR *) _fullList;  //set to first item
  160.         // reserve sapce for list of pointers to item strings
  161.     item += (_numItems)*4;
  162.     for(i=0; i<_numItems; i++)
  163.     {
  164.       IntToStr(_minVal + i*_step, item);
  165.       _fullList[i]=item;
  166.       item += maxChars+1;
  167.     }
  168.       }
  169.       else    // an integer list from 0 to 32767 with step=1
  170.       {       // (initial value _retVal)
  171.         _minVal = 0; _maxVal = 0x7fff; _step = 1;
  172.     // Try to make the width pretty
  173.     char buff[20];
  174.     IntToStr(_minVal,buff);
  175.     _maxWidth = LabelWidth(buff) + 2;
  176.     IntToStr(_maxVal,buff);
  177.     int maxW = LabelWidth(buff) + 2;
  178.     if (maxW > _maxWidth)
  179.       _maxWidth = maxW;
  180.       }
  181.       _curSelection = _retVal;
  182.     }
  183.   }
  184.  
  185. //==================>>> vSpinnerCmd::GetCmdValue <<<=========================
  186.   int vSpinnerCmd::GetCmdValue(ItemVal id) VCONST
  187.   {
  188.     if (id != _cmdId)
  189.     return -1;
  190.     return _curSelection;
  191.   }
  192. //=====================>>> vSpinnerCmd::SetCmdVal <<<=========================
  193.   void vSpinnerCmd::SetCmdVal(ItemVal val, ItemSetType st)
  194.   {
  195.     SysDebug2(Misc,"vSpinnerCmd::SetCmdVal(val:%d, type:%d)\n",val,st)
  196.     HWND myHwnd = GetMyHwnd(_cmdId);
  197.  
  198.     switch (st)
  199.     {
  200.       case Sensitive:
  201.     _Sensitive = val;               // set
  202.     WinEnableWindow (myHwnd, val);
  203.     break;
  204.  
  205.       case Hidden:
  206.     if (val)
  207.       WinShowWindow (myHwnd, FALSE);
  208.     else
  209.       WinShowWindow (myHwnd, TRUE);
  210.     break;
  211.  
  212.       case ChangeList:
  213.       case ChangeListPtr:
  214.       {
  215.     if (st == ChangeListPtr)
  216.        _itemList = dlgCmd->itemList;
  217.  
  218.     int oldMax = _maxWidth;         // track current max width
  219.  
  220.     SetupList();                    // reset the list variables
  221.  
  222.     if (oldMax > _maxWidth)
  223.         _maxWidth = oldMax;         // don't let it get narrower
  224.  
  225.     // redisplay text
  226.     // populate the listbox
  227.     if (_TextList)
  228.       WinSendMsg(myHwnd, SPBM_SETARRAY, _fullList, (MPARAM) _numItems);
  229.     else
  230.       WinSendMsg(myHwnd, SPBM_SETLIMITS, (MPARAM) _maxVal, (MPARAM) _minVal);
  231.  
  232.     WinEnableWindow (myHwnd, _Sensitive);
  233.  
  234.     if (dlgCmd->attrs & CA_Hidden)
  235.       WinShowWindow(myHwnd,FALSE);
  236.     else
  237.       WinShowWindow(myHwnd,TRUE);
  238.  
  239.     _curSelection = val;
  240.     SetCmdVal(_curSelection,Value);
  241.     return;
  242.       }
  243.  
  244.       case Value:       // select a given item
  245.       {
  246.     _curSelection = val;    // change the current value
  247.     // See if the currently selected item is in the list
  248.     if (_TextList == 1)          // handle like this for text list
  249.     {
  250.       if (_itemList)
  251.       {
  252.         if (_curSelection < 0)
  253.           _curSelection = 0;
  254.         if (_curSelection >= _numItems)
  255.           _curSelection = _numItems - 1;
  256.       }
  257.       // Now set appropriate _curSelection
  258.       WinSendMsg(myHwnd, SPBM_SETCURRENTVALUE,
  259.         MPFROMLONG(_curSelection), (MPARAM) NULL);
  260.     }
  261.     else if (_TextList == 2)       // numeric non-contiguous values
  262.     {
  263.       if (_curSelection < _minVal)
  264.         _curSelection = _minVal;
  265.       if (_curSelection >= _maxVal)
  266.         _curSelection = _maxVal;
  267.  
  268.       int index = (_curSelection - _minVal)/_step;
  269.       WinSendMsg(myHwnd, SPBM_SETCURRENTVALUE,
  270.           MPFROMLONG(index), (MPARAM) NULL);
  271.     }
  272.  
  273.     else                    // numeric contiguous values
  274.     {
  275.       if (_curSelection < _minVal)
  276.         _curSelection = _minVal;
  277.       if (_curSelection >= _maxVal)
  278.         _curSelection = _maxVal;
  279.       WinSendMsg(myHwnd, SPBM_SETCURRENTVALUE,
  280.           MPFROMLONG(_curSelection), (MPARAM) NULL);
  281.     }
  282.       }
  283.     }
  284.   }
  285. //===================>>> vSpinnerCmd::vCmdCallback <<<=======================
  286.   void vSpinnerCmd::CmdCallback(UINT uMsg, MPARAM mp1, MPARAM mp2)
  287.   {
  288.     // See if we are getting a message we care about
  289.     if (uMsg == WM_CONTROL)
  290.     {
  291. //    SysDebug1(OS2Dev,"vSpinnerCmd::CmdCallBack \n")
  292.       char buf[255];
  293.  
  294.       switch (SHORT2FROMMP(mp1))
  295.       {
  296.     case SPBN_DOWNARROW:        // Down one item
  297.     case SPBN_UPARROW:        // Up one item
  298.     {
  299.       // Retrieve the current selection
  300.       if (_TextList == 1)
  301.       {
  302.         // find out the spin button value and associate with its array index
  303.         WinSendDlgItemMsg(_parentWin->getParent(),_cmdId,
  304.           SPBM_QUERYVALUE, buf, MPFROM2SHORT(sizeof(buf), SPBQ_DONOTUPDATE));
  305.         for ( int i = 0 ; _fullList[i] != 0 ; ++i)
  306.         {
  307.           if(strcmp(buf, _fullList[i])==0)
  308.         _curSelection = i;
  309.         }
  310.         if (_curSelection >= _numItems)  // sanity check
  311.           _curSelection = _numItems -1;
  312.       }
  313.       else if (_TextList == 2)  // non-consecutive integers
  314.       {
  315.         // find out the spin button value and convert to integer
  316.         WinSendDlgItemMsg(_parentWin->getParent(),_cmdId,
  317.           SPBM_QUERYVALUE, buf, MPFROM2SHORT(sizeof(buf), SPBQ_DONOTUPDATE));
  318.         for ( int i = 0 ; i < _numItems ; ++i)
  319.         {
  320.           if(strcmp(buf, _fullList[i])==0)
  321.           {
  322. //        _curSelection = StrToLong(_fullList[i]);
  323.         _curSelection = atol(_fullList[i]);
  324.           }
  325.         }
  326.         if (_curSelection > _maxVal)  // sanity check
  327.           _curSelection = _maxVal;
  328.         if (_curSelection < _minVal)
  329.           _curSelection = _minVal;
  330.       }
  331.       else  // numeric
  332.       {
  333.         WinSendDlgItemMsg(_parentWin->getParent(),_cmdId, SPBM_QUERYVALUE,
  334.           (MPARAM) &_curSelection, MPFROM2SHORT(0, SPBQ_DONOTUPDATE));
  335.         if (_curSelection > _maxVal)  // sanity check
  336.           _curSelection = _maxVal;
  337.         if (_curSelection < _minVal)
  338.           _curSelection = _minVal;
  339.       }
  340.       if (!(dlgCmd->attrs & CA_NoNotify)) // Notify on each selection?
  341.         _parentWin->ProcessCmd(_cmdId, _curSelection, dlgCmd->cmdType);
  342.     break;
  343.     } // SPBM
  344.  
  345.     default:
  346.       return;                      // punt on other messages
  347.       }
  348.     } //uMsg
  349.   }
  350.  
  351.  
  352.