home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Borland / Cplus45 / BC45 / MTHREAD.PAK / ARTY.CPP next >
C/C++ Source or Header  |  1995-08-29  |  10KB  |  363 lines

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