home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / contrib / src / ogl / constrnt.cpp < prev    next >
C/C++ Source or Header  |  2002-12-18  |  18KB  |  620 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        constrnt.cpp
  3. // Purpose:     OGL Constraint classes
  4. // Author:      Julian Smart
  5. // Modified by:
  6. // Created:     12/07/98
  7. // RCS-ID:      $Id: constrnt.cpp,v 1.2.2.1 2002/12/18 06:12:59 RD Exp $
  8. // Copyright:   (c) Julian Smart
  9. // Licence:       wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. #ifdef __GNUG__
  13. #pragma implementation "constrnt.h"
  14. #endif
  15.  
  16. // For compilers that support precompilation, includes "wx.h".
  17. #include "wx/wxprec.h"
  18.  
  19. #ifdef __BORLANDC__
  20. #pragma hdrstop
  21. #endif
  22.  
  23. #ifndef WX_PRECOMP
  24. #include <wx/wx.h>
  25. #endif
  26.  
  27. #include <wx/wxexpr.h>
  28.  
  29. #include <wx/ogl/basic.h>
  30. #include <wx/ogl/constrnt.h>
  31. #include <wx/ogl/canvas.h>
  32.  
  33. wxList *wxOGLConstraintTypes = NULL;
  34.  
  35. /*
  36.  * Constraint type
  37.  *
  38.  */
  39.  
  40. IMPLEMENT_DYNAMIC_CLASS(wxOGLConstraintType, wxObject)
  41.  
  42. wxOGLConstraintType::wxOGLConstraintType(int theType, const wxString& theName, const wxString& thePhrase)
  43. {
  44.   m_type = theType;
  45.   m_name = theName;
  46.   m_phrase = thePhrase;
  47. }
  48.  
  49. wxOGLConstraintType::~wxOGLConstraintType()
  50. {
  51. }
  52.  
  53. void OGLInitializeConstraintTypes()
  54. {
  55.     if (!wxOGLConstraintTypes)
  56.         return;
  57.  
  58.     wxOGLConstraintTypes = new wxList(wxKEY_INTEGER);
  59.  
  60.     wxOGLConstraintTypes->Append(gyCONSTRAINT_CENTRED_VERTICALLY,
  61.         new wxOGLConstraintType(gyCONSTRAINT_CENTRED_VERTICALLY, wxT("Centre vertically"), wxT("centred vertically w.r.t.")));
  62.  
  63.     wxOGLConstraintTypes->Append(gyCONSTRAINT_CENTRED_HORIZONTALLY,
  64.         new wxOGLConstraintType(gyCONSTRAINT_CENTRED_HORIZONTALLY, wxT("Centre horizontally"), wxT("centred horizontally w.r.t.")));
  65.  
  66.     wxOGLConstraintTypes->Append(gyCONSTRAINT_CENTRED_BOTH,
  67.         new wxOGLConstraintType(gyCONSTRAINT_CENTRED_BOTH, wxT("Centre"), wxT("centred w.r.t.")));
  68.  
  69.     wxOGLConstraintTypes->Append(gyCONSTRAINT_LEFT_OF,
  70.         new wxOGLConstraintType(gyCONSTRAINT_LEFT_OF, wxT("Left of"), wxT("left of")));
  71.  
  72.     wxOGLConstraintTypes->Append(gyCONSTRAINT_RIGHT_OF,
  73.         new wxOGLConstraintType(gyCONSTRAINT_RIGHT_OF, wxT("Right of"), wxT("right of")));
  74.  
  75.     wxOGLConstraintTypes->Append(gyCONSTRAINT_ABOVE,
  76.         new wxOGLConstraintType(gyCONSTRAINT_ABOVE, wxT("Above"), wxT("above")));
  77.  
  78.     wxOGLConstraintTypes->Append(gyCONSTRAINT_BELOW,
  79.         new wxOGLConstraintType(gyCONSTRAINT_BELOW, wxT("Below"), wxT("below")));
  80.  
  81.     // Alignment
  82.     wxOGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_TOP,
  83.         new wxOGLConstraintType(gyCONSTRAINT_ALIGNED_TOP, wxT("Top-aligned"), wxT("aligned to the top of")));
  84.  
  85.     wxOGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_BOTTOM,
  86.         new wxOGLConstraintType(gyCONSTRAINT_ALIGNED_BOTTOM, wxT("Bottom-aligned"), wxT("aligned to the bottom of")));
  87.  
  88.     wxOGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_LEFT,
  89.         new wxOGLConstraintType(gyCONSTRAINT_ALIGNED_LEFT, wxT("Left-aligned"), wxT("aligned to the left of")));
  90.  
  91.     wxOGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_RIGHT,
  92.         new wxOGLConstraintType(gyCONSTRAINT_ALIGNED_RIGHT, wxT("Right-aligned"), wxT("aligned to the right of")));
  93.  
  94.     // Mid-alignment
  95.     wxOGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_TOP,
  96.         new wxOGLConstraintType(gyCONSTRAINT_MIDALIGNED_TOP, wxT("Top-midaligned"), wxT("centred on the top of")));
  97.  
  98.     wxOGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_BOTTOM,
  99.         new wxOGLConstraintType(gyCONSTRAINT_MIDALIGNED_BOTTOM, wxT("Bottom-midaligned"), wxT("centred on the bottom of")));
  100.  
  101.     wxOGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_LEFT,
  102.         new wxOGLConstraintType(gyCONSTRAINT_MIDALIGNED_LEFT, wxT("Left-midaligned"), wxT("centred on the left of")));
  103.  
  104.     wxOGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_RIGHT,
  105.         new wxOGLConstraintType(gyCONSTRAINT_MIDALIGNED_RIGHT, wxT("Right-midaligned"), wxT("centred on the right of")));
  106. }
  107.  
  108. void OGLCleanUpConstraintTypes()
  109. {
  110.     if (!wxOGLConstraintTypes)
  111.         return;
  112.  
  113.     wxNode* node = wxOGLConstraintTypes->First();
  114.     while (node)
  115.     {
  116.         wxOGLConstraintType* ct = (wxOGLConstraintType*) node->Data();
  117.         delete ct;
  118.         node = node->Next();
  119.     }
  120.     delete wxOGLConstraintTypes;
  121.     wxOGLConstraintTypes = NULL;
  122. }
  123.  
  124. /*
  125.  * Constraint Stuff
  126.  *
  127.  */
  128.  
  129. IMPLEMENT_DYNAMIC_CLASS(wxOGLConstraint, wxObject)
  130.  
  131. wxOGLConstraint::wxOGLConstraint(int type, wxShape *constraining, wxList& constrained)
  132. {
  133.   m_xSpacing = 0.0;
  134.   m_ySpacing = 0.0;
  135.  
  136.   m_constraintType = type;
  137.   m_constrainingObject = constraining;
  138.  
  139.   m_constraintId = 0;
  140.   m_constraintName = wxT("noname");
  141.  
  142.   wxNode *node = constrained.First();
  143.   while (node)
  144.   {
  145.     m_constrainedObjects.Append(node->Data());
  146.     node = node->Next();
  147.   }
  148. }
  149.  
  150. wxOGLConstraint::~wxOGLConstraint()
  151. {
  152. }
  153.  
  154. bool wxOGLConstraint::Equals(double a, double b)
  155. {
  156.   double marg = 0.5;
  157.  
  158.   bool eq = ((b <= a + marg) && (b >= a - marg));
  159.   return eq;
  160. }
  161.  
  162. // Return TRUE if anything changed
  163. bool wxOGLConstraint::Evaluate()
  164. {
  165.   double maxWidth, maxHeight, minWidth, minHeight, x, y;
  166.   m_constrainingObject->GetBoundingBoxMax(&maxWidth, &maxHeight);
  167.   m_constrainingObject->GetBoundingBoxMin(&minWidth, &minHeight);
  168.   x = m_constrainingObject->GetX();
  169.   y = m_constrainingObject->GetY();
  170.  
  171.   wxClientDC dc(m_constrainingObject->GetCanvas());
  172.   m_constrainingObject->GetCanvas()->PrepareDC(dc);
  173.  
  174.   switch (m_constraintType)
  175.   {
  176.     case gyCONSTRAINT_CENTRED_VERTICALLY:
  177.     {
  178.       int n = m_constrainedObjects.Number();
  179.       double totalObjectHeight = 0.0;
  180.       wxNode *node = m_constrainedObjects.First();
  181.       while (node)
  182.       {
  183.         wxShape *constrainedObject = (wxShape *)node->Data();
  184.  
  185.         double width2, height2;
  186.         constrainedObject->GetBoundingBoxMax(&width2, &height2);
  187.         totalObjectHeight += height2;
  188.         node = node->Next();
  189.       }
  190.       double startY;
  191.       double spacingY;
  192.       // Check if within the constraining object...
  193.       if ((totalObjectHeight + (n + 1)*m_ySpacing) <= minHeight)
  194.       {
  195.         spacingY = (double)((minHeight - totalObjectHeight)/(n + 1));
  196.         startY = (double)(y - (minHeight/2.0));
  197.       }
  198.       // Otherwise, use default spacing
  199.       else
  200.       {
  201.         spacingY = m_ySpacing;
  202.         startY = (double)(y - ((totalObjectHeight + (n+1)*spacingY)/2.0));
  203.       }
  204.  
  205.       // Now position the objects
  206.       bool changed = FALSE;
  207.       node = m_constrainedObjects.First();
  208.       while (node)
  209.       {
  210.         wxShape *constrainedObject = (wxShape *)node->Data();
  211.         double width2, height2;
  212.         constrainedObject->GetBoundingBoxMax(&width2, &height2);
  213.         startY += (double)(spacingY + (height2/2.0));
  214.         if (!Equals(startY, constrainedObject->GetY()))
  215.         {
  216.           constrainedObject->Move(dc, constrainedObject->GetX(), startY, FALSE);
  217.           changed = TRUE;
  218.         }
  219.         startY += (double)(height2/2.0);
  220.         node = node->Next();
  221.       }
  222.       return changed;
  223.     }
  224.     case gyCONSTRAINT_CENTRED_HORIZONTALLY:
  225.     {
  226.       int n = m_constrainedObjects.Number();
  227.       double totalObjectWidth = 0.0;
  228.       wxNode *node = m_constrainedObjects.First();
  229.       while (node)
  230.       {
  231.         wxShape *constrainedObject = (wxShape *)node->Data();
  232.  
  233.         double width2, height2;
  234.         constrainedObject->GetBoundingBoxMax(&width2, &height2);
  235.         totalObjectWidth += width2;
  236.         node = node->Next();
  237.       }
  238.       double startX;
  239.       double spacingX;
  240.       // Check if within the constraining object...
  241.       if ((totalObjectWidth + (n + 1)*m_xSpacing) <= minWidth)
  242.       {
  243.         spacingX = (double)((minWidth - totalObjectWidth)/(n + 1));
  244.         startX = (double)(x - (minWidth/2.0));
  245.       }
  246.       // Otherwise, use default spacing
  247.       else
  248.       {
  249.         spacingX = m_xSpacing;
  250.         startX = (double)(x - ((totalObjectWidth + (n+1)*spacingX)/2.0));
  251.       }
  252.  
  253.       // Now position the objects
  254.       bool changed = FALSE;
  255.       node = m_constrainedObjects.First();
  256.       while (node)
  257.       {
  258.         wxShape *constrainedObject = (wxShape *)node->Data();
  259.         double width2, height2;
  260.         constrainedObject->GetBoundingBoxMax(&width2, &height2);
  261.         startX += (double)(spacingX + (width2/2.0));
  262.         if (!Equals(startX, constrainedObject->GetX()))
  263.         {
  264.           constrainedObject->Move(dc, startX, constrainedObject->GetY(), FALSE);
  265.           changed = TRUE;
  266.         }
  267.         startX += (double)(width2/2.0);
  268.         node = node->Next();
  269.       }
  270.       return changed;
  271.     }
  272.     case gyCONSTRAINT_CENTRED_BOTH:
  273.     {
  274.       int n = m_constrainedObjects.Number();
  275.       double totalObjectWidth = 0.0;
  276.       double totalObjectHeight = 0.0;
  277.       wxNode *node = m_constrainedObjects.First();
  278.       while (node)
  279.       {
  280.         wxShape *constrainedObject = (wxShape *)node->Data();
  281.  
  282.         double width2, height2;
  283.         constrainedObject->GetBoundingBoxMax(&width2, &height2);
  284.         totalObjectWidth += width2;
  285.         totalObjectHeight += height2;
  286.         node = node->Next();
  287.       }
  288.       double startX;
  289.       double spacingX;
  290.       double startY;
  291.       double spacingY;
  292.  
  293.       // Check if within the constraining object...
  294.       if ((totalObjectWidth + (n + 1)*m_xSpacing) <= minWidth)
  295.       {
  296.         spacingX = (double)((minWidth - totalObjectWidth)/(n + 1));
  297.         startX = (double)(x - (minWidth/2.0));
  298.       }
  299.       // Otherwise, use default spacing
  300.       else
  301.       {
  302.         spacingX = m_xSpacing;
  303.         startX = (double)(x - ((totalObjectWidth + (n+1)*spacingX)/2.0));
  304.       }
  305.  
  306.       // Check if within the constraining object...
  307.       if ((totalObjectHeight + (n + 1)*m_ySpacing) <= minHeight)
  308.       {
  309.         spacingY = (double)((minHeight - totalObjectHeight)/(n + 1));
  310.         startY = (double)(y - (minHeight/2.0));
  311.       }
  312.       // Otherwise, use default spacing
  313.       else
  314.       {
  315.         spacingY = m_ySpacing;
  316.         startY = (double)(y - ((totalObjectHeight + (n+1)*spacingY)/2.0));
  317.       }
  318.  
  319.       // Now position the objects
  320.       bool changed = FALSE;
  321.       node = m_constrainedObjects.First();
  322.       while (node)
  323.       {
  324.         wxShape *constrainedObject = (wxShape *)node->Data();
  325.         double width2, height2;
  326.         constrainedObject->GetBoundingBoxMax(&width2, &height2);
  327.         startX += (double)(spacingX + (width2/2.0));
  328.         startY += (double)(spacingY + (height2/2.0));
  329.  
  330.         if ((!Equals(startX, constrainedObject->GetX())) || (!Equals(startY, constrainedObject->GetY())))
  331.         {
  332.           constrainedObject->Move(dc, startX, startY, FALSE);
  333.           changed = TRUE;
  334.         }
  335.  
  336.         startX += (double)(width2/2.0);
  337.         startY += (double)(height2/2.0);
  338.  
  339.         node = node->Next();
  340.       }
  341.       return changed;
  342.     }
  343.     case gyCONSTRAINT_LEFT_OF:
  344.     {
  345.       bool changed = FALSE;
  346.  
  347.       wxNode *node = m_constrainedObjects.First();
  348.       while (node)
  349.       {
  350.         wxShape *constrainedObject = (wxShape *)node->Data();
  351.  
  352.         double width2, height2;
  353.         constrainedObject->GetBoundingBoxMax(&width2, &height2);
  354.  
  355.         double x3 = (double)(x - (minWidth/2.0) - (width2/2.0) - m_xSpacing);
  356.         if (!Equals(x3, constrainedObject->GetX()))
  357.         {
  358.           changed = TRUE;
  359.           constrainedObject->Move(dc, x3, constrainedObject->GetY(), FALSE);
  360.         }
  361.  
  362.         node = node->Next();
  363.       }
  364.       return changed;
  365.     }
  366.     case gyCONSTRAINT_RIGHT_OF:
  367.     {
  368.       bool changed = FALSE;
  369.  
  370.       wxNode *node = m_constrainedObjects.First();
  371.       while (node)
  372.       {
  373.         wxShape *constrainedObject = (wxShape *)node->Data();
  374.  
  375.         double width2, height2;
  376.         constrainedObject->GetBoundingBoxMax(&width2, &height2);
  377.  
  378.         double x3 = (double)(x + (minWidth/2.0) + (width2/2.0) + m_xSpacing);
  379.         if (!Equals(x3, constrainedObject->GetX()))
  380.         {
  381.           changed = TRUE;
  382.           constrainedObject->Move(dc, x3, constrainedObject->GetY(), FALSE);
  383.         }
  384.  
  385.         node = node->Next();
  386.       }
  387.       return changed;
  388.  
  389.       return FALSE;
  390.     }
  391.     case gyCONSTRAINT_ABOVE:
  392.     {
  393.       bool changed = FALSE;
  394.  
  395.       wxNode *node = m_constrainedObjects.First();
  396.       while (node)
  397.       {
  398.         wxShape *constrainedObject = (wxShape *)node->Data();
  399.  
  400.         double width2, height2;
  401.         constrainedObject->GetBoundingBoxMax(&width2, &height2);
  402.  
  403.         double y3 = (double)(y - (minHeight/2.0) - (height2/2.0) - m_ySpacing);
  404.         if (!Equals(y3, constrainedObject->GetY()))
  405.         {
  406.           changed = TRUE;
  407.           constrainedObject->Move(dc, constrainedObject->GetX(), y3, FALSE);
  408.         }
  409.  
  410.         node = node->Next();
  411.       }
  412.       return changed;
  413.     }
  414.     case gyCONSTRAINT_BELOW:
  415.     {
  416.       bool changed = FALSE;
  417.  
  418.       wxNode *node = m_constrainedObjects.First();
  419.       while (node)
  420.       {
  421.         wxShape *constrainedObject = (wxShape *)node->Data();
  422.  
  423.         double width2, height2;
  424.         constrainedObject->GetBoundingBoxMax(&width2, &height2);
  425.  
  426.         double y3 = (double)(y + (minHeight/2.0) + (height2/2.0) + m_ySpacing);
  427.         if (!Equals(y3, constrainedObject->GetY()))
  428.         {
  429.           changed = TRUE;
  430.           constrainedObject->Move(dc, constrainedObject->GetX(), y3, FALSE);
  431.         }
  432.  
  433.         node = node->Next();
  434.       }
  435.       return changed;
  436.     }
  437.     case gyCONSTRAINT_ALIGNED_LEFT:
  438.     {
  439.       bool changed = FALSE;
  440.  
  441.       wxNode *node = m_constrainedObjects.First();
  442.       while (node)
  443.       {
  444.         wxShape *constrainedObject = (wxShape *)node->Data();
  445.  
  446.         double width2, height2;
  447.         constrainedObject->GetBoundingBoxMax(&width2, &height2);
  448.  
  449.         double x3 = (double)(x - (minWidth/2.0) + (width2/2.0) + m_xSpacing);
  450.         if (!Equals(x3, constrainedObject->GetX()))
  451.         {
  452.           changed = TRUE;
  453.           constrainedObject->Move(dc, x3, constrainedObject->GetY(), FALSE);
  454.         }
  455.  
  456.         node = node->Next();
  457.       }
  458.       return changed;
  459.     }
  460.     case gyCONSTRAINT_ALIGNED_RIGHT:
  461.     {
  462.       bool changed = FALSE;
  463.  
  464.       wxNode *node = m_constrainedObjects.First();
  465.       while (node)
  466.       {
  467.         wxShape *constrainedObject = (wxShape *)node->Data();
  468.  
  469.         double width2, height2;
  470.         constrainedObject->GetBoundingBoxMax(&width2, &height2);
  471.  
  472.         double x3 = (double)(x + (minWidth/2.0) - (width2/2.0) - m_xSpacing);
  473.         if (!Equals(x3, constrainedObject->GetX()))
  474.         {
  475.           changed = TRUE;
  476.           constrainedObject->Move(dc, x3, constrainedObject->GetY(), FALSE);
  477.         }
  478.  
  479.         node = node->Next();
  480.       }
  481.       return changed;
  482.  
  483.       return FALSE;
  484.     }
  485.     case gyCONSTRAINT_ALIGNED_TOP:
  486.     {
  487.       bool changed = FALSE;
  488.  
  489.       wxNode *node = m_constrainedObjects.First();
  490.       while (node)
  491.       {
  492.         wxShape *constrainedObject = (wxShape *)node->Data();
  493.  
  494.         double width2, height2;
  495.         constrainedObject->GetBoundingBoxMax(&width2, &height2);
  496.  
  497.         double y3 = (double)(y - (minHeight/2.0) + (height2/2.0) + m_ySpacing);
  498.         if (!Equals(y3, constrainedObject->GetY()))
  499.         {
  500.           changed = TRUE;
  501.           constrainedObject->Move(dc, constrainedObject->GetX(), y3, FALSE);
  502.         }
  503.  
  504.         node = node->Next();
  505.       }
  506.       return changed;
  507.     }
  508.     case gyCONSTRAINT_ALIGNED_BOTTOM:
  509.     {
  510.       bool changed = FALSE;
  511.  
  512.       wxNode *node = m_constrainedObjects.First();
  513.       while (node)
  514.       {
  515.         wxShape *constrainedObject = (wxShape *)node->Data();
  516.  
  517.         double width2, height2;
  518.         constrainedObject->GetBoundingBoxMax(&width2, &height2);
  519.  
  520.         double y3 = (double)(y + (minHeight/2.0) - (height2/2.0) - m_ySpacing);
  521.         if (!Equals(y3, constrainedObject->GetY()))
  522.         {
  523.           changed = TRUE;
  524.           constrainedObject->Move(dc, constrainedObject->GetX(), y3, FALSE);
  525.         }
  526.  
  527.         node = node->Next();
  528.       }
  529.       return changed;
  530.     }
  531.     case gyCONSTRAINT_MIDALIGNED_LEFT:
  532.     {
  533.       bool changed = FALSE;
  534.  
  535.       wxNode *node = m_constrainedObjects.First();
  536.       while (node)
  537.       {
  538.         wxShape *constrainedObject = (wxShape *)node->Data();
  539.  
  540.         double x3 = (double)(x - (minWidth/2.0));
  541.         if (!Equals(x3, constrainedObject->GetX()))
  542.         {
  543.           changed = TRUE;
  544.           constrainedObject->Move(dc, x3, constrainedObject->GetY(), FALSE);
  545.         }
  546.  
  547.         node = node->Next();
  548.       }
  549.       return changed;
  550.     }
  551.     case gyCONSTRAINT_MIDALIGNED_RIGHT:
  552.     {
  553.       bool changed = FALSE;
  554.  
  555.       wxNode *node = m_constrainedObjects.First();
  556.       while (node)
  557.       {
  558.         wxShape *constrainedObject = (wxShape *)node->Data();
  559.  
  560.         double x3 = (double)(x + (minWidth/2.0));
  561.         if (!Equals(x3, constrainedObject->GetX()))
  562.         {
  563.           changed = TRUE;
  564.           constrainedObject->Move(dc, x3, constrainedObject->GetY(), FALSE);
  565.         }
  566.  
  567.         node = node->Next();
  568.       }
  569.       return changed;
  570.  
  571.       return FALSE;
  572.     }
  573.     case gyCONSTRAINT_MIDALIGNED_TOP:
  574.     {
  575.       bool changed = FALSE;
  576.  
  577.       wxNode *node = m_constrainedObjects.First();
  578.       while (node)
  579.       {
  580.         wxShape *constrainedObject = (wxShape *)node->Data();
  581.  
  582.         double y3 = (double)(y - (minHeight/2.0));
  583.         if (!Equals(y3, constrainedObject->GetY()))
  584.         {
  585.           changed = TRUE;
  586.           constrainedObject->Move(dc, constrainedObject->GetX(), y3, FALSE);
  587.         }
  588.  
  589.         node = node->Next();
  590.       }
  591.       return changed;
  592.     }
  593.     case gyCONSTRAINT_MIDALIGNED_BOTTOM:
  594.     {
  595.       bool changed = FALSE;
  596.  
  597.       wxNode *node = m_constrainedObjects.First();
  598.       while (node)
  599.       {
  600.         wxShape *constrainedObject = (wxShape *)node->Data();
  601.  
  602.         double y3 = (double)(y + (minHeight/2.0));
  603.         if (!Equals(y3, constrainedObject->GetY()))
  604.         {
  605.           changed = TRUE;
  606.           constrainedObject->Move(dc, constrainedObject->GetX(), y3, FALSE);
  607.         }
  608.  
  609.         node = node->Next();
  610.       }
  611.       return changed;
  612.     }
  613.  
  614.     default:
  615.       return FALSE;
  616.   }
  617.   return FALSE;
  618. }
  619.  
  620.