home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / MTHREAD.PAK / ARTY.CPP next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  9.8 KB  |  395 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1991, 1995 by Borland International, All Rights Reserved
  4. //
  5. // Multi-thread arty demo window object
  6. //----------------------------------------------------------------------------
  7. #include <owl/pch.h>
  8. #include <owl/dc.h>
  9. #include <owl/static.h>
  10. #include <stdlib.h>
  11. #include "arty.h"           // class definition for TArtyWindow
  12. #include "artypriv.h"       // internal component classes of TArtyWindow
  13. #include <stdlib.h>
  14.  
  15.  
  16. //----------------------------------------------------------------------------
  17. // TList
  18.  
  19. //
  20. // The low-level line draw routine
  21. //
  22. static void
  23. LineDraw(TDC& dc, int x1, int y1, int x2, int y2)
  24. {
  25.   dc.MoveTo(x1, y1);
  26.   dc.LineTo(x2, y2);
  27. }
  28.  
  29. //
  30. // Initialize the list-of-lines object
  31. //
  32. TList::TList(int _max)
  33. {
  34.   MaxLines = min(_max, MaxLineCount);
  35.   CurrentLine = 1;
  36.   Xmax = 0;
  37.   Ymax = 0;
  38.   ColorDuration = MaxColorDuration;
  39.   IncrementCount = 0;
  40.   MaxDelta = 10;
  41.   PenColor = TColor(random(256), random(256), random(256));
  42. }
  43.  
  44. //
  45. // Keep X within range, and reverse Delta if necessary to do so
  46. //
  47. void
  48. TList::AdjustX(int& x, int& deltaX)
  49. {
  50.   int testX = x + deltaX;
  51.   if (testX < 1 || testX > Xmax) {
  52.     testX = x;
  53.     deltaX = -deltaX;
  54.   }
  55.   x = testX;
  56. }
  57.  
  58. //
  59. // Keep Y within range, and reverse Delta if necessary to do so
  60. //
  61. void
  62. TList::AdjustY(int& y, int& deltaY)
  63. {
  64.   int testY = y + deltaY;
  65.   if (testY < 1 || testY > Ymax) {
  66.     testY = y;
  67.     deltaY = -deltaY;
  68.   }
  69.   y = testY;
  70. }
  71.  
  72. //
  73. // Clear the array of lines
  74. //
  75. void
  76. TList::ResetLines()
  77. {
  78.   int startX = Xmax / 2;
  79.   int startY = Ymax / 2;
  80.   for (int i = 0; i < MaxLines; i++) {
  81.     Line[i].LX1 = startX;
  82.     Line[i].LX2 = startX;
  83.     Line[i].LY1 = startY;
  84.     Line[i].LY2 = startY;
  85.     Line[i].Color = 0;
  86.   }
  87.   X1 = startX;
  88.   X2 = startX;
  89.   Y1 = startY;
  90.   Y2 = startY;
  91. }
  92.  
  93. //
  94. // Scale the old line coordinates to the new Xmax and Ymax coordinates.
  95. //  The new Xmax and new Ymax are passed in as parameters so we can
  96. //  calculate the scaling ratios.
  97. //
  98. #define ScaleX( val ) val = (val*newXmax)/Xmax
  99. #define ScaleY( val ) val = (val*newYmax)/Ymax
  100.  
  101. void
  102. TList::ScaleTo(int newXmax, int newYmax)
  103. {
  104.   if (!Xmax || !Ymax) {    // at startup, Xmax and Ymax are zero
  105.     Xmax = newXmax;
  106.     Ymax = newYmax;
  107.     ResetLines();
  108.   }
  109.   else {
  110.     ScaleX(X1);
  111.     ScaleX(X2);
  112.     ScaleY(Y1);
  113.     ScaleY(Y2);
  114.     for (int i = 0; i < MaxLines; i++) {
  115.  
  116.       ScaleX(Line[i].LX1);
  117.       ScaleX(Line[i].LX2);
  118.       ScaleY(Line[i].LY1);
  119.       ScaleY(Line[i].LY2);
  120.     }
  121.   }
  122.   Xmax = newXmax;
  123.   Ymax = newYmax;
  124. }
  125.  
  126. //
  127. // The high-level Draw method of the object.
  128. //
  129. void
  130. TList::DrawLine(TDC& dc, int index)
  131. {
  132.   TPen pen(Line[index].Color);
  133.   dc.SelectObject(pen);
  134.   LineDraw(dc, Line[index].LX1, Line[index].LY1,
  135.                Line[index].LX2, Line[index].LY2);
  136.   dc.RestorePen();
  137. }
  138.  
  139. // The high-level draw which erases a line.
  140. //
  141. void TList::EraseLine(TDC& dc, int index)
  142. {
  143.   dc.SelectStockObject(BLACK_PEN);
  144.   LineDraw(dc, Line[index].LX1, Line[index].LY1,
  145.                Line[index].LX2, Line[index].LY2);
  146. }
  147.  
  148. //
  149. // Redraw all the lines in the array.
  150. //
  151. void
  152. TList::Redraw(TDC& dc)
  153. {
  154.   for (int i = 0; i < MaxLines; i++)
  155.     DrawLine(dc, i);
  156. }
  157.  
  158. //
  159. // Reset the color counter and pick a random color.
  160. //
  161. void
  162. TList::SelectNewColor()
  163. {
  164.   ColorDuration = MaxColorDuration;
  165.   PenColor = TColor(random(256), random(256), random(256));
  166. }
  167.  
  168. //
  169. // Pick random directional deltas and reset the delta counter.
  170. //
  171. void
  172. TList::SelectNewDeltaValues()
  173. {
  174.   DeltaX1 = random(MaxDelta) - MaxDelta/2;
  175.   DeltaX2 = random(MaxDelta) - MaxDelta/2;
  176.   DeltaY1 = random(MaxDelta) - MaxDelta/2;
  177.   DeltaY2 = random(MaxDelta) - MaxDelta/2;
  178.   IncrementCount = 2 * (1 + random(10));
  179. }
  180.  
  181. //
  182. // Process the movement of one line.
  183. //
  184. void
  185. TList::LineTick(TDC& dc)
  186. {
  187.   EraseLine(dc, CurrentLine);
  188.   if (ColorDuration < 0)
  189.     SelectNewColor();
  190.   if (!IncrementCount)
  191.     SelectNewDeltaValues();
  192.   AdjustX(X1, DeltaX1);
  193.   AdjustX(X2, DeltaX2);
  194.   AdjustY(Y1, DeltaY1);
  195.   AdjustY(Y2, DeltaY2);
  196.  
  197.   Line[CurrentLine].LX1 = X1;
  198.   Line[CurrentLine].LX2 = X2;
  199.   Line[CurrentLine].LY1 = Y1;
  200.   Line[CurrentLine].LY2 = Y2;
  201.   Line[CurrentLine].Color = PenColor;
  202.  
  203.   DrawLine(dc, CurrentLine);
  204.   CurrentLine++;
  205.   if (CurrentLine >= MaxLines)
  206.     CurrentLine = 1;
  207.   ColorDuration--;
  208.   IncrementCount--;
  209. }
  210.  
  211.  
  212. //----------------------------------------------------------------------------
  213. // TQuadList
  214.  
  215. //
  216. // Draw the line and 3 reflections of it.
  217. //
  218. void
  219. TQuadList::DrawLine(TDC& dc, int index)
  220. {
  221.   TPen pen(Line[index].Color);
  222.   dc.SelectObject(pen);
  223.   LineDraw(dc, Line[index].LX1, Line[index].LY1,
  224.                Line[index].LX2, Line[index].LY2);
  225.   LineDraw(dc, Xmax - Line[index].LX1, Line[index].LY1,
  226.                Xmax - Line[index].LX2, Line[index].LY2);
  227.   LineDraw(dc, Line[index].LX1, Ymax - Line[index].LY1,
  228.                Line[index].LX2, Ymax - Line[index].LY2);
  229.   LineDraw(dc, Xmax - Line[index].LX1, Ymax - Line[index].LY1,
  230.                Xmax - Line[index].LX2, Ymax - Line[index].LY2);
  231.   dc.RestorePen();
  232. }
  233.  
  234. //
  235. // Erase the line and 3 reflections of it.
  236. //
  237. void
  238. TQuadList::EraseLine(TDC& dc, int index)
  239. {
  240.   dc.SelectStockObject(BLACK_PEN);
  241.   LineDraw(dc, Line[index].LX1, Line[index].LY1,
  242.                Line[index].LX2, Line[index].LY2);
  243.   LineDraw(dc, Xmax - Line[index].LX1, Line[index].LY1,
  244.                Xmax - Line[index].LX2, Line[index].LY2);
  245.   LineDraw(dc, Line[index].LX1, Ymax - Line[index].LY1,
  246.                Line[index].LX2, Ymax - Line[index].LY2);
  247.   LineDraw(dc, Xmax - Line[index].LX1, Ymax - Line[index].LY1,
  248.                Xmax - Line[index].LX2, Ymax - Line[index].LY2);
  249. }
  250.  
  251. //----------------------------------------------------------------------------
  252. // TArtyWindow
  253.  
  254. DEFINE_RESPONSE_TABLE1(TArtyWindow, TBaseDemoWindow)
  255.   EV_WM_LBUTTONDOWN,
  256.   EV_WM_RBUTTONDOWN,
  257.   EV_WM_SIZE,
  258. END_RESPONSE_TABLE;
  259.  
  260. IMPLEMENT_CASTABLE1(TArtyWindow, TBaseDemoWindow);
  261.  
  262. //
  263. //
  264. //
  265. TArtyWindow::TArtyWindow() : TBaseDemoWindow()
  266. {
  267.   StaticControl = new TStatic(this, 100,
  268.     "Press Left Button to pause, Right Button to Clear",10,10,10,10,0);
  269.   Iconized = false;
  270.   TextHeight = 20;
  271.   Paused = false;
  272.  
  273.   // Initialize two line list objects:
  274.   //    BigLineList is the 4-reflection artwork that is displayed in
  275.   //    a full sized window.  Mouse clicks will pause or clear
  276.   //    the display, and the line list will be scaled to the
  277.   //    new window coordinates when the window is resized.
  278.   //
  279.   //    IconicLineList is a smaller list implementing a single-line
  280.   //    quark to display in the iconized window region.  Since
  281.   //    mouse clicks are not sent to iconized windows, the icon
  282.   //    cannot be paused or cleared, and since there is only one
  283.   //    icon window size, scaling the lines to new coordinates
  284.   //    has no visual effect.
  285.   //
  286.   //  The List pointer will be toggled between the two line list
  287.   //  objects: when the window is iconized, List will point to the
  288.   //  IconicLineList object.  When the window is restored to full
  289.   //  size, List will be made to point to the BigLineList object.
  290.   //  This is so the window routines don't have to know which kind
  291.   //  of list they're dealing with.  Keyword: polymorphism.
  292.  
  293.   BigLineList = new TQuadList(MaxLineCount);
  294.   IconicLineList = new TList(MaxIconicLineCount);
  295.   List = BigLineList;
  296.  
  297.   SetBkgndColor(TColor::Black);
  298.  
  299.   Start();
  300. }
  301.  
  302. //
  303. // Dispose of the objects that this window object created.  There's
  304. //  no need to dispose the List pointer, since it will only point to
  305. //  one of these two objects which are being disposed by their
  306. //  primary pointers
  307. //
  308. TArtyWindow::~TArtyWindow()
  309. {
  310.   delete BigLineList;
  311.   delete IconicLineList;
  312. }
  313.  
  314. //
  315. // When the window is resized, scale the line list to fit the new
  316. //  window extent, or switch between full size and iconized window
  317. //  states.
  318. //
  319. void
  320. TArtyWindow::EvSize(uint sizeType, TSize& size)
  321. {
  322.   TBaseDemoWindow::EvSize(sizeType, size);
  323.  
  324.   // Force Windows to repaint the entire window region
  325.   //
  326.   Invalidate(true);
  327.  
  328.   int newXmax = size.cx;
  329.   int newYmax = size.cy;
  330.   if (sizeType == SIZE_MINIMIZED) {
  331.     if (!Iconized) {
  332.       Iconized = true;
  333.       List = IconicLineList;
  334.     }
  335.   }
  336.   else {
  337.     if (Iconized) {
  338.       Iconized = false;
  339.       List = BigLineList;
  340.     }
  341.     newYmax -= TextHeight;  // allow room for the text at the bottom
  342.   }
  343.  
  344.   List->ScaleTo(newXmax, newYmax);  // scale the lines in the list
  345.   if (StaticControl)
  346.     StaticControl->MoveWindow(0, newYmax, newXmax, TextHeight, true);
  347. }
  348.  
  349. //
  350. // Toggle the window's Paused status.  Since the window will
  351. //  not receive mouse clicks when iconized, this will not pause the
  352. //  iconized lines display.
  353. //
  354. void
  355. TArtyWindow::EvLButtonDown(uint, TPoint&)
  356. {
  357.   Paused = !Paused;
  358. }
  359.  
  360. //
  361. // Clear the line list when the user presses the right mouse
  362. //  button.  Same comments as above on iconized windows.
  363. //
  364. void
  365. TArtyWindow::EvRButtonDown(uint, TPoint&)
  366. {
  367.   Invalidate(true);
  368.   List->ResetLines();
  369. }
  370.  
  371. //
  372. // When the window is resized, or some other window blots out part
  373. // of our client area, redraw the entire line list.
  374. //
  375. void
  376. TArtyWindow::Paint(TDC& dc, bool, TRect&)
  377. {
  378.   List->Redraw(dc);
  379. }
  380.  
  381. //
  382. // The main do-er function for this thread window. Beware that any form of
  383. // SendMessage() to a window in this app here will deadlock this thread with
  384. // the app. This is because this window is really 'owned' by the app thread.
  385. //
  386. // Fetch a device context, pass it to the line list object, then release the
  387. // device context back to Windows.
  388. //
  389. void
  390. TArtyWindow::ClockTick()
  391. {
  392.   if (!Paused)
  393.     List->LineTick(TClientDC(Iconized ? Parent->GetHandle() : GetHandle()));
  394. }
  395.