Progress.cc
上传用户:kellyonhid
上传日期:2013-10-12
资源大小:932k
文件大小:5k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. //############################################################
  2. // 
  3. // Progress.cc
  4. //
  5. // Matt Ginzton
  6. // Mon Aug  3 13:17:07 PDT 1998
  7. //
  8. // C++ interface to tcl progressbar code.
  9. //
  10. //############################################################
  11. #include <tcl.h>
  12. #include <string.h>
  13. #include <stdlib.h>
  14. #include <vector.h>
  15. #ifdef WIN32
  16. # include "winGLdecs.h"
  17. #endif
  18. #include <GL/glu.h>
  19. #include "togl.h"
  20. #include "Progress.h"
  21. #include "BailDetector.h"
  22. #include "plvGlobals.h"
  23. #include "Timer.h"
  24. #include "ToglText.h"
  25. int Progress::nProgressBarsActive = 0;
  26. // performance tweaks -- higher values will seem less responsive,
  27. // but waste less time on progress bars.
  28. // can be changed through "plv_progress" public Tcl interface.
  29. // minimum amount of time to elapse between successive updates
  30. static int kUpdateFrequency = 300; // in ms
  31. // min. operation length to deserve a status bar
  32. static int kTransience = 4;        // in multiples of update frequency
  33. Progress::Progress (int end, const char* name, bool cancellable)
  34. {
  35.   _init (end, name);
  36. }
  37. Progress::Progress (int end, const char* operation, const char* name,
  38.     bool cancellable)
  39. {
  40.   char nameBuf[600];
  41.   sprintf (nameBuf, operation, name);
  42.   _init (end, nameBuf);
  43. }
  44. void Progress::_init (int end, const char* _name)
  45. {
  46.   value = 0;
  47.   maximum = end;
  48.   pBailDetector = new BailDetector;
  49.   lastUpdateTime = 0;
  50.   lastUpdateValue = 0;
  51.   nUpdates = 0;
  52.   iId = nProgressBarsActive++;
  53.   baseY = 5 + iId * 28;
  54.   if (strlen (_name) >= sizeof (name)) {
  55.     strncpy (name, _name, sizeof(name));
  56.     name[sizeof(name)-1] = 0;
  57.   } else {
  58.     strcpy (name, _name);
  59.   }
  60. }
  61. static void rect (int x1, int y1, int x2, int y2)
  62. {
  63.   glVertex2i (x1, y1);
  64.   glVertex2i (x2, y1);
  65.   glVertex2i (x2, y2);
  66.   glVertex2i (x1, y2);
  67. }
  68. Progress::~Progress()
  69. {
  70.   delete pBailDetector;
  71.   nProgressBarsActive--;
  72. }
  73. bool Progress::update (int current)
  74. {
  75.   if (g_bNoUI)
  76.     return true;
  77.   value = current;
  78.   unsigned int timestamp = Timer::get_system_tick_count();
  79.   if (value == lastUpdateValue ||
  80.       timestamp < (lastUpdateTime + kUpdateFrequency))
  81.     return true;
  82.   // make sure enough updates have happened to warrant a redraw
  83.   if (nUpdates++ % kTransience != 0)
  84.     return true;
  85.   glDrawBuffer (GL_FRONT);
  86.   
  87.   // save all the bits just so I don't turn off something
  88.   // that someone else expects to be on
  89.   glPushAttrib(GL_ALL_ATTRIB_BITS);
  90.   glDisable (GL_DEPTH_TEST);
  91.   glDisable (GL_LIGHTING);
  92.      
  93.   // clear the modelview matrix - save previous
  94.   glMatrixMode (GL_MODELVIEW);
  95.   glPushMatrix();
  96.   glLoadIdentity();
  97.   // clear the projection matrix - save previous
  98.   glMatrixMode (GL_PROJECTION);
  99.   glPushMatrix(); 
  100.   glLoadIdentity();
  101.     
  102.   // set orthagraphic to encompass the entire screen
  103.   gluOrtho2D (0, theWidth, 0, theHeight);
  104.   
  105.   glBegin (GL_QUADS);
  106.   glColor3f (.7, 0, 0); rect (0, baseY, theWidth - 1, baseY + 19);
  107.   glColor3f (.2, 0, 0); rect (1, baseY + 1, theWidth, baseY + 20);
  108.   glEnd();
  109.   // render new portion of progress bar
  110.   // subtract one so the bar "
  111.   int width = value / (double)maximum * theWidth; 
  112.   if (g_verbose) cerr << "width = " << width << endl;
  113.   glBegin (GL_QUADS);
  114.   glColor3f (1, 0, 0); rect (0, baseY + 2, width, baseY + 18);
  115.   glEnd();
  116.   // setup XOR mode
  117.   glEnable (GL_COLOR_LOGIC_OP);
  118.   glLogicOp (GL_XOR);
  119.   // draw text in red for past-end-of-bar
  120.   glColor3f (1, 0, 0);
  121.   glRasterPos2i (15, baseY + 6);
  122.   DrawText (toglCurrent, name);
  123.   glLogicOp (GL_COPY);
  124.   glDisable (GL_COLOR_LOGIC_OP);
  125.   
  126.   //pop the matrices
  127.   glMatrixMode (GL_PROJECTION);
  128.   glPopMatrix();
  129.   glMatrixMode (GL_MODELVIEW);
  130.   glPopMatrix();
  131.   glFinish();
  132.   glPopAttrib(); // restore the previous attributes
  133.   lastUpdateTime = timestamp;
  134.   lastUpdateValue = value;
  135.   return !(*pBailDetector)();
  136. }
  137. bool Progress::updateInc (int increment)
  138. {
  139.   return update (value + increment);
  140. }
  141. static vector<Progress*> inprogress;
  142. int
  143. PlvProgressCmd(ClientData clientData, Tcl_Interp *interp, 
  144.        int argc, char *argv[])
  145. {
  146.   if (argc < 2) {
  147.     interp->result = "missing args to plv_progress";
  148.     return TCL_ERROR;
  149.   }
  150.   bool result = true;
  151.   if (!strcmp (argv[1], "start")) {
  152.     Progress* prog = new Progress (atoi (argv[2]), argv[3]);
  153.     inprogress.push_back (prog);
  154.   } else if (!strcmp (argv[1], "update")) {
  155.     assert (inprogress.size() > 0);
  156.     result = inprogress.back()->update (atoi (argv[2]));
  157.   } else if (!strcmp (argv[1], "updateinc")) {
  158.     assert (inprogress.size() > 0);
  159.     if (argc == 2)
  160.       result = inprogress.back()->updateInc();
  161.     else
  162.       result = inprogress.back()->updateInc (atoi (argv[2]));
  163.   } else if (!strcmp (argv[1], "done")) {
  164.     assert (inprogress.size() > 0);
  165.     Progress* prog = inprogress.back();
  166.     inprogress.pop_back();
  167.     delete prog;
  168.   } else if (!strcmp (argv[1], "transience")) {
  169.     kTransience = atoi (argv[2]);
  170.   } else if (!strcmp (argv[1], "frequency")) {
  171.     kUpdateFrequency = atoi (argv[2]);
  172.   } else {
  173.     interp->result = "Bad arg to plv_progress";
  174.     return TCL_ERROR;
  175.   }
  176.   interp->result = result ? "1" : "0";
  177.   return TCL_OK;
  178. }