home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / vos2-121.zip / v / srcos2 / vsliderc.cpp < prev    next >
C/C++ Source or Header  |  1999-01-31  |  9KB  |  284 lines

  1. //===============================================================
  2. // vsliderc.cxx - SliderCmd - 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/vsliderc.h> // our definitions
  13. #include <v/vcmdprnt.h> // a command parent
  14. #include <v/vapp.h>
  15.  
  16. // the windows slider code requires that when it is set, the
  17. // value it is to be set to must be in the range 0-100 regardless
  18. // of the minval/maxval range it was originally given by the contructor. It
  19. // will however respond with the value in the correct range.  This
  20. // heinously broken behavior is emulated in the OS/2 port by setting
  21. // the following variable (and needs to be set to get the *&%^* V icon
  22. // editor to work correctly...)
  23. #define EMULATE_BROKEN_WINDOZE_CODE
  24.  
  25. //=================>>> vSliderCmd::vSliderCmd <<<=======================
  26.   vSliderCmd::vSliderCmd(vCmdParent* dp, CommandObject* dc) :
  27.         vCmd(dp, dc)
  28.   {
  29.     initialize();                       // and initialize
  30.   }
  31.  
  32. //=======================>>> vSliderCmd::~vSliderCmd <<<=======================
  33.   vSliderCmd::~vSliderCmd()
  34.   {
  35.     SysDebug(Constructor,"vSliderCmd::~vSliderCmd() Destructor\n")
  36.   }
  37.  
  38. //=====================>>> vSliderCmd::initialize <<<=======================
  39.   void vSliderCmd::initialize()
  40.   {
  41.     SysDebug(Constructor,"vSliderCmd::vSliderCmd() constructor\n")
  42.  
  43.     _initialPosnSet=0;  // initial slider position not set yet
  44.  
  45.     long style = SLS_PRIMARYSCALE1 |
  46.          SLS_SNAPTOINCREMENT | SLS_RIBBONSTRIP;
  47.  
  48.     if (_parentWin->_dialogType != aCmdBar)
  49.     style |= WS_TABSTOP | WS_GROUP;  // default for a button
  50.     else
  51.     style |= WS_GROUP;
  52.  
  53.     CopyToLocal();                      // Make local copies of CmdObject
  54.  
  55.     if (!(dlgCmd->attrs & CA_Hidden))   // Check for Hidden
  56.     style |= WS_VISIBLE;
  57.  
  58.     // Set the size of the slider
  59.     if (dlgCmd->attrs & CA_Vertical)
  60.     {
  61.       style |= SLS_VERTICAL | SLS_HOMEBOTTOM | SLS_BUTTONSBOTTOM | SLS_LEFT;
  62.  
  63.       _w = 18;               // set my width
  64.       _h = 76;               // regular size
  65.       // the normal slider has a 0-100 range
  66.       _scd.usScale1Increments = 101;
  67.       _scd.usScale1Spacing = 1;
  68.       if (dlgCmd->attrs & CA_Large)
  69.       {
  70.     _h = 124;
  71.     _scd.usScale1Increments = 101;
  72.     _scd.usScale1Spacing = 2;
  73.       }
  74.       else if (dlgCmd->attrs & CA_Small)
  75.       {
  76.     _h = 50;
  77.         // the small slider has only a 0-50 range
  78.     _scd.usScale1Increments = 51;
  79.     _scd.usScale1Spacing = 1;
  80.       }
  81.       // user override
  82.       if (dlgCmd->size > 0 && dlgCmd->size < 2048)
  83.       {
  84.     _h = 25 + (dlgCmd->size/2);
  85.         // the user defined slider has a used defined range
  86.     _scd.usScale1Increments = dlgCmd->size;
  87.     _scd.usScale1Spacing = 1;
  88.       }
  89.     }
  90.     // else its a horizontal slider
  91.     else
  92.     {
  93.       style |= SLS_HORIZONTAL | SLS_HOMELEFT | SLS_BUTTONSLEFT | SLS_BOTTOM;
  94.       _h = 13;                 // default height
  95.  
  96.       _w = 100;
  97.       // the normal slider has a 0-100 range
  98.       _scd.usScale1Increments = 101;
  99.       _scd.usScale1Spacing = 1;
  100.       if (dlgCmd->attrs & CA_Large)
  101.       {
  102.     _w = 166;
  103.     _scd.usScale1Increments = 101;
  104.     _scd.usScale1Spacing = 2;
  105.       }
  106.       else if (dlgCmd->attrs & CA_Small)
  107.       {
  108.     _w = 67;
  109.         // the small slider has only a 0-50 range
  110.     _scd.usScale1Increments = 51;
  111.     _scd.usScale1Spacing = 1;
  112.       }
  113.       // user override
  114.       if (dlgCmd->size > 0 && dlgCmd->size < 2048)
  115.       {
  116.     _w = 35 + ((dlgCmd->size*65)/100);
  117.         // the user defined slider has a used defined range
  118.     _scd.usScale1Increments = dlgCmd->size;
  119.     _scd.usScale1Spacing = 1;
  120.       }
  121.     }
  122.  
  123.     int* minMax = (int *)_itemList;             // giving range?
  124.     _minVal = 0; _maxVal = 100;                 // default min/max
  125.  
  126.     if (minMax != 0)                            // They gave a range list
  127.     {
  128.     _minVal = minMax[0];
  129.     _maxVal = minMax[1];
  130.     }
  131.  
  132.     if (_minVal > _maxVal)
  133.     {
  134.     SysDebug2(BadVals,"vSliderCmd:vSliderCmd - bad range %d to %d\n",_minVal,_maxVal)
  135.     _minVal = 0; _maxVal = 100;     // make some sense!
  136.     }
  137.  
  138.     if (_retVal < _minVal)      // set a legal value for the top
  139.     _curVal = _minVal;
  140.     else if (_retVal > _maxVal)
  141.     _curVal = _maxVal;
  142.     else
  143.     _curVal = _retVal;
  144.  
  145.     _scd.cbSize = sizeof(SLDCDATA);
  146.     _scd.usScale2Increments = 101;
  147.     _scd.usScale2Spacing = 1;
  148.  
  149.     // SetPosition will compute the _x and _y position of the control based
  150.     // upon _w and _h and also its relationship to any frames and adjacent
  151.     // controls. In addition, the frame size will be adjusted to make sure
  152.     // it can hold the new control
  153.     _parentWin->SetPosition(_x, _y, _w, _h, dlgCmd->cFrame, dlgCmd->cRightOf,
  154.     dlgCmd->cBelow);
  155.  
  156.     if (dlgCmd->attrs & CA_Vertical)
  157.     {
  158.       _y += 2;
  159.       _h -= 2;   // we play this game to get better positioning in a frame
  160.     }
  161.     else if (dlgCmd->attrs & CA_Horizontal)
  162.     {
  163. //      _x += 1;
  164.       _y += 2;
  165.       _h -= 2;   // we play this game to get better positioning in a frame
  166.     }
  167.  
  168.     // AddDlgControl will create the control in the dialog template using
  169.     // the supplied x, y, w, h parameters.
  170.     _CtrlOffset = _parentWin->AddDlgControl(_x, _y, _w, _h, _cmdId,
  171.     style, WC_SLIDER, _title, NULL, _scd.cbSize, &_scd);
  172.  
  173.   }
  174.  
  175. //==================>>> vSliderCmd::GetCmdValue <<<=========================
  176.   int vSliderCmd::GetCmdValue(ItemVal id) VCONST
  177.   {
  178.     if (id != _cmdId)
  179.     return -1;
  180.     return _curVal;
  181.   }
  182.  
  183. //=====================>>> vSliderCmd::SetCmdVal <<<=========================
  184.   void vSliderCmd::SetCmdVal(ItemVal val, ItemSetType st)
  185.   {
  186.     SysDebug2(Misc,"vSliderCmd::SetCmdVal(val:%d, type:%d)\n",val,st)
  187.     HWND myHwnd = GetMyHwnd(_cmdId);
  188.  
  189.     switch (st)
  190.     {
  191.       case Sensitive:
  192.     _Sensitive = val;               // set
  193.     WinEnableWindow (myHwnd, val);
  194.     break;
  195.  
  196.       case Hidden:
  197.     if (val)
  198.       WinShowWindow (myHwnd, FALSE);
  199.     else
  200.       WinShowWindow (myHwnd, TRUE);
  201.     break;
  202.  
  203.       case Value:
  204.     if (val < _minVal || val > _maxVal )
  205.       return;
  206.     _curVal = val;
  207. #ifdef EMULATE_BROKEN_WINDOZE_CODE
  208.         // we assume the input range is always 0-100 to emulate the
  209.         // broken windoze port of V
  210.  
  211.         // the max slider position is given by _scd.usScale1Increments-1
  212.         // we take care to minimize rounding errors here
  213.         int percent = (_scd.usScale1Increments - 1)*val + 50;
  214.         percent /= 100;
  215. #else
  216.         // otherwise, we do this logically...
  217.     double frac = val - _minVal;
  218.     frac = frac/(_maxVal - _minVal);
  219.         // the max slider position is given by _scd.usScale1Increments-1
  220.     int percent = frac * (_scd.usScale1Increments - 1);
  221. #endif
  222.  
  223.     // Now set appropriate _curVal, scroll
  224.     WinSendMsg (myHwnd, SLM_SETSLIDERINFO,
  225.       MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_RANGEVALUE), (MPARAM) percent);
  226. //      MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), (MPARAM) percent);
  227.  
  228.     // set a few tick marks
  229.     SHORT ticksize=4;
  230.     SHORT tickposn[3] = {0, 50, 100};
  231.     tickposn[1] = (_scd.usScale1Increments - 1)/2;
  232.     tickposn[2] = (_scd.usScale1Increments - 1);
  233. /*
  234.     if (dlgCmd->attrs & CA_Small)
  235.     {
  236.       tickposn[0] = 0;
  237.       tickposn[1] = 25;
  238.       tickposn[2] = 50;
  239.     }
  240. */
  241.     for (int i=0; i<3; i++)
  242.         {
  243.       WinSendMsg (myHwnd, SLM_SETTICKSIZE,
  244.           MPFROM2SHORT(tickposn[i], ticksize), (MPARAM) NULL);
  245.         }
  246.     break;
  247.     }
  248.   }
  249.  
  250. //===================>>> vSliderCmd::vCmdCallback <<<=======================
  251.   void vSliderCmd::CmdCallback(UINT uMsg, MPARAM mp1, MPARAM mp2)
  252.   {
  253.     // See if we are getting a message we care about
  254.     if (uMsg == WM_CONTROL)
  255.     {
  256. //    SysDebug1(OS2Dev,"vSliderCmd::CmdCallBack \n")
  257.  
  258.       switch (SHORT2FROMMP(mp1))
  259.       {
  260.         case SLN_CHANGE:                // arm moved
  261.         case SLN_SLIDERTRACK:           // arm dragged by mouse
  262.       int val = LONGFROMMP(mp2);
  263.           // scale by slider length to get percent
  264.           double percent = val*100./(_scd.usScale1Increments - 1);
  265.           _curVal = (int)( (percent * (_maxVal-_minVal) / 100) + _minVal );
  266.  
  267. //          SysDebug2(OS2Dev,"vSliderCmd::CmdCallBack val=%u _curVal=%u\n", val, _curVal)
  268.  
  269.   // WorkAround... I'm getting traps because the inital slider position is
  270.   // set during WM_INITDLG which causes the slider to respond with a command
  271.   // message with the updated value and often the code isn't ready
  272.   // to handle that command this early on.  A good example of this is the
  273.   // vopengl shapes program which will trap because the slider command handler
  274.   // needs the timer object which is instantiated after the slider in the
  275.   // commandpane is built and initialized.
  276.  
  277.           if (_initialPosnSet)
  278.         _parentWin->ProcessCmd(_cmdId, _curVal, dlgCmd->cmdType);
  279.           else
  280.             _initialPosnSet=1;
  281.       }
  282.     }
  283.   }
  284.