]> git.saurik.com Git - wxWidgets.git/blobdiff - src/ogl/composit.cpp
Removed OGL prior to re-adding; some Watcom corrections
[wxWidgets.git] / src / ogl / composit.cpp
diff --git a/src/ogl/composit.cpp b/src/ogl/composit.cpp
deleted file mode 100644 (file)
index ba237db..0000000
+++ /dev/null
@@ -1,1784 +0,0 @@
-/////////////////////////////////////////////////////////////////////////////
-// Name:        composit.cpp
-// Purpose:     Composite OGL class
-// Author:      Julian Smart
-// Modified by:
-// Created:     12/07/98
-// RCS-ID:      $Id$
-// Copyright:   (c) Julian Smart
-// Licence:    wxWindows licence
-/////////////////////////////////////////////////////////////////////////////
-
-#ifdef __GNUG__
-#pragma implementation "composit.h"
-#endif
-
-// For compilers that support precompilation, includes "wx.h".
-#include <wx/wxprec.h>
-
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-
-#ifndef WX_PRECOMP
-#include <wx/wx.h>
-#endif
-
-#include <wx/wxexpr.h>
-
-#include <wx/ogl/basic.h>
-#include <wx/ogl/basicp.h>
-#include <wx/ogl/constrnt.h>
-#include <wx/ogl/composit.h>
-#include <wx/ogl/misc.h>
-#include <wx/ogl/canvas.h>
-
-// Sometimes, objects need to access the whole database to
-// construct themselves.
-wxExprDatabase *GlobalwxExprDatabase = NULL;
-
-
-/*
- * Division control point
- */
-
-class wxDivisionControlPoint: public wxControlPoint
-{
- DECLARE_DYNAMIC_CLASS(wxDivisionControlPoint)
- public:
-  wxDivisionControlPoint() {}
-  wxDivisionControlPoint(wxShapeCanvas *the_canvas, wxShape *object, double size, double the_xoffset, double the_yoffset, int the_type);
-  ~wxDivisionControlPoint();
-
-  void OnDragLeft(bool draw, double x, double y, int keys=0, int attachment = 0);
-  void OnBeginDragLeft(double x, double y, int keys=0, int attachment = 0);
-  void OnEndDragLeft(double x, double y, int keys=0, int attachment = 0);
-};
-
-IMPLEMENT_DYNAMIC_CLASS(wxDivisionControlPoint, wxControlPoint)
-
-/*
- * Composite object
- *
- */
-
-IMPLEMENT_DYNAMIC_CLASS(wxCompositeShape, wxRectangleShape)
-
-wxCompositeShape::wxCompositeShape(): wxRectangleShape(10.0, 10.0)
-{
-//  selectable = FALSE;
-  m_oldX = m_xpos;
-  m_oldY = m_ypos;
-}
-
-wxCompositeShape::~wxCompositeShape()
-{
-  wxNode *node = m_constraints.First();
-  while (node)
-  {
-    wxOGLConstraint *constraint = (wxOGLConstraint *)node->Data();
-    delete constraint;
-    node = node->Next();
-  }
-  node = m_children.First();
-  while (node)
-  {
-    wxShape *object = (wxShape *)node->Data();
-    wxNode *next = node->Next();
-    object->Unlink();
-    delete object;
-    node = next;
-  }
-}
-
-void wxCompositeShape::OnDraw(wxDC& dc)
-{
-  double x1 = (double)(m_xpos - m_width/2.0);
-  double y1 = (double)(m_ypos - m_height/2.0);
-
-  if (m_shadowMode != SHADOW_NONE)
-  {
-    if (m_shadowBrush)
-      dc.SetBrush(* m_shadowBrush);
-    dc.SetPen(* g_oglTransparentPen);
-
-    if (m_cornerRadius != 0.0)
-      dc.DrawRoundedRectangle(WXROUND(x1 + m_shadowOffsetX), WXROUND(y1 + m_shadowOffsetY),
-                               WXROUND(m_width), WXROUND(m_height), m_cornerRadius);
-    else
-      dc.DrawRectangle(WXROUND(x1 + m_shadowOffsetX), WXROUND(y1 + m_shadowOffsetY), WXROUND(m_width), WXROUND(m_height));
-  }
-}
-
-void wxCompositeShape::OnDrawContents(wxDC& dc)
-{
-  wxNode *node = m_children.First();
-  while (node)
-  {
-    wxShape *object = (wxShape *)node->Data();
-    object->Draw(dc);
-    object->DrawLinks(dc);
-    node = node->Next();
-  }
-  wxShape::OnDrawContents(dc);
-}
-
-bool wxCompositeShape::OnMovePre(wxDC& dc, double x, double y, double oldx, double oldy, bool display)
-{
-  double diffX = x - oldx;
-  double diffY = y - oldy;
-  wxNode *node = m_children.First();
-  while (node)
-  {
-    wxShape *object = (wxShape *)node->Data();
-
-    object->Erase(dc);
-    object->Move(dc, object->GetX() + diffX, object->GetY() + diffY, display);
-
-    node = node->Next();
-  }
-  return TRUE;
-}
-
-void wxCompositeShape::OnErase(wxDC& dc)
-{
-  wxRectangleShape::OnErase(dc);
-  wxNode *node = m_children.First();
-  while (node)
-  {
-    wxShape *object = (wxShape *)node->Data();
-    object->Erase(dc);
-    node = node->Next();
-  }
-}
-
-static double objectStartX = 0.0;
-static double objectStartY = 0.0;
-
-void wxCompositeShape::OnDragLeft(bool draw, double x, double y, int keys, int attachment)
-{
-  double xx = x;
-  double yy = y;
-  m_canvas->Snap(&xx, &yy);
-  double offsetX = xx - objectStartX;
-  double offsetY = yy - objectStartY;
-
-  wxClientDC dc(GetCanvas());
-  GetCanvas()->PrepareDC(dc);
-
-  dc.SetLogicalFunction(OGLRBLF);
-  wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT);
-  dc.SetPen(dottedPen);
-  dc.SetBrush((* wxTRANSPARENT_BRUSH));
-
-  GetEventHandler()->OnDrawOutline(dc, GetX() + offsetX, GetY() + offsetY, GetWidth(), GetHeight());
-//  wxShape::OnDragLeft(draw, x, y, keys, attachment);
-}
-
-void wxCompositeShape::OnBeginDragLeft(double x, double y, int keys, int attachment)
-{
-  objectStartX = x;
-  objectStartY = y;
-
-  wxClientDC dc(GetCanvas());
-  GetCanvas()->PrepareDC(dc);
-
-  Erase(dc);
-
-  dc.SetLogicalFunction(OGLRBLF);
-
-  wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT);
-  dc.SetPen(dottedPen);
-  dc.SetBrush((* wxTRANSPARENT_BRUSH));
-  m_canvas->CaptureMouse();
-
-  double xx = x;
-  double yy = y;
-  m_canvas->Snap(&xx, &yy);
-  double offsetX = xx - objectStartX;
-  double offsetY = yy - objectStartY;
-
-  GetEventHandler()->OnDrawOutline(dc, GetX() + offsetX, GetY() + offsetY, GetWidth(), GetHeight());
-
-//  wxShape::OnBeginDragLeft(x, y, keys, attachment);
-}
-
-void wxCompositeShape::OnEndDragLeft(double x, double y, int keys, int attachment)
-{
-//  wxShape::OnEndDragLeft(x, y, keys, attachment);
-
-  wxClientDC dc(GetCanvas());
-  GetCanvas()->PrepareDC(dc);
-
-  m_canvas->ReleaseMouse();
-
-  if (!m_draggable)
-  {
-    if (m_parent) m_parent->GetEventHandler()->OnEndDragLeft(x, y, keys, 0);
-    return;
-  }
-
-  dc.SetLogicalFunction(wxCOPY);
-  double xx = x;
-  double yy = y;
-  m_canvas->Snap(&xx, &yy);
-  double offsetX = xx - objectStartX;
-  double offsetY = yy - objectStartY;
-
-  Move(dc, GetX() + offsetX, GetY() + offsetY);
-
-  if (m_canvas && !m_canvas->GetQuickEditMode()) m_canvas->Redraw(dc);
-}
-
-void wxCompositeShape::OnRightClick(double x, double y, int keys, int attachment)
-{
-  // If we get a ctrl-right click, this means send the message to
-  // the division, so we can invoke a user interface for dealing with regions.
-  if (keys & KEY_CTRL)
-  {
-    wxNode *node = m_divisions.First();
-    while (node)
-    {
-      wxDivisionShape *division = (wxDivisionShape *)node->Data();
-      wxNode *next = node->Next();
-      int attach = 0;
-      double dist = 0.0;
-      if (division->HitTest(x, y, &attach, &dist))
-      {
-        division->GetEventHandler()->OnRightClick(x, y, keys, attach);
-        node = NULL;
-      }
-      if (node)
-        node = next;
-    }
-  }
-}
-
-void wxCompositeShape::SetSize(double w, double h, bool recursive)
-{
-  SetAttachmentSize(w, h);
-
-  double xScale = (double)(w/(wxMax(1.0, GetWidth())));
-  double yScale = (double)(h/(wxMax(1.0, GetHeight())));
-
-  m_width = w;
-  m_height = h;
-
-  if (!recursive) return;
-
-  wxNode *node = m_children.First();
-
-  wxClientDC dc(GetCanvas());
-  GetCanvas()->PrepareDC(dc);
-
-  double xBound, yBound;
-  while (node)
-  {
-    wxShape *object = (wxShape *)node->Data();
-
-    // Scale the position first
-    double newX = (double)(((object->GetX() - GetX())*xScale) + GetX());
-    double newY = (double)(((object->GetY() - GetY())*yScale) + GetY());
-    object->Show(FALSE);
-    object->Move(dc, newX, newY);
-    object->Show(TRUE);
-
-    // Now set the scaled size
-    object->GetBoundingBoxMin(&xBound, &yBound);
-    object->SetSize(object->GetFixedWidth() ? xBound : xScale*xBound,
-                    object->GetFixedHeight() ? yBound : yScale*yBound);
-
-    node = node->Next();
-  }
-  SetDefaultRegionSize();
-}
-
-void wxCompositeShape::AddChild(wxShape *child, wxShape *addAfter)
-{
-  m_children.Append(child);
-  child->SetParent(this);
-  if (m_canvas)
-  {
-    // Ensure we add at the right position
-    if (addAfter)
-      child->RemoveFromCanvas(m_canvas);
-    child->AddToCanvas(m_canvas, addAfter);
-  }
-}
-
-void wxCompositeShape::RemoveChild(wxShape *child)
-{
-  m_children.DeleteObject(child);
-  m_divisions.DeleteObject(child);
-  RemoveChildFromConstraints(child);
-  child->SetParent(NULL);
-}
-
-void wxCompositeShape::DeleteConstraintsInvolvingChild(wxShape *child)
-{
-  wxNode *node = m_constraints.First();
-  while (node)
-  {
-    wxOGLConstraint *constraint = (wxOGLConstraint *)node->Data();
-    wxNode *nextNode = node->Next();
-
-    if ((constraint->m_constrainingObject == child) ||
-        constraint->m_constrainedObjects.Member(child))
-    {
-      delete constraint;
-      delete node;
-    }
-    node = nextNode;
-  }
-}
-
-void wxCompositeShape::RemoveChildFromConstraints(wxShape *child)
-{
-  wxNode *node = m_constraints.First();
-  while (node)
-  {
-    wxOGLConstraint *constraint = (wxOGLConstraint *)node->Data();
-    wxNode *nextNode = node->Next();
-
-    if (constraint->m_constrainedObjects.Member(child))
-      constraint->m_constrainedObjects.DeleteObject(child);
-    if (constraint->m_constrainingObject == child)
-      constraint->m_constrainingObject = NULL;
-
-    // Delete the constraint if no participants left
-    if (!constraint->m_constrainingObject)
-    {
-      delete constraint;
-      delete node;
-    }
-
-    node = nextNode;
-  }
-}
-
-void wxCompositeShape::Copy(wxShape& copy)
-{
-  wxRectangleShape::Copy(copy);
-
-  wxASSERT( copy.IsKindOf(CLASSINFO(wxCompositeShape)) ) ;
-
-  wxCompositeShape& compositeCopy = (wxCompositeShape&) copy;
-
-  // Associate old and new copies for compositeCopying constraints and division geometry
-  oglObjectCopyMapping.Append((long)this, &compositeCopy);
-
-  // Copy the children
-  wxNode *node = m_children.First();
-  while (node)
-  {
-    wxShape *object = (wxShape *)node->Data();
-    wxShape *newObject = object->CreateNewCopy(FALSE, FALSE);
-    if (newObject->GetId() == 0)
-      newObject->SetId(wxNewId());
-
-    newObject->SetParent(&compositeCopy);
-    compositeCopy.m_children.Append(newObject);
-
-    // Some m_children may be divisions
-    if (m_divisions.Member(object))
-      compositeCopy.m_divisions.Append(newObject);
-
-    oglObjectCopyMapping.Append((long)object, newObject);
-
-    node = node->Next();
-  }
-
-  // Copy the constraints
-  node = m_constraints.First();
-  while (node)
-  {
-    wxOGLConstraint *constraint = (wxOGLConstraint *)node->Data();
-
-    wxShape *newConstraining = (wxShape *)(oglObjectCopyMapping.Find((long)constraint->m_constrainingObject)->Data());
-
-    wxList newConstrainedList;
-    wxNode *node2 = constraint->m_constrainedObjects.First();
-    while (node2)
-    {
-      wxShape *constrainedObject = (wxShape *)node2->Data();
-      wxShape *newConstrained = (wxShape *)(oglObjectCopyMapping.Find((long)constrainedObject)->Data());
-      newConstrainedList.Append(newConstrained);
-      node2 = node2->Next();
-    }
-
-    wxOGLConstraint *newConstraint = new wxOGLConstraint(constraint->m_constraintType, newConstraining,
-                                            newConstrainedList);
-    newConstraint->m_constraintId = constraint->m_constraintId;
-    if (constraint->m_constraintName)
-    {
-      newConstraint->m_constraintName = constraint->m_constraintName;
-    }
-    newConstraint->SetSpacing(constraint->m_xSpacing, constraint->m_ySpacing);
-    compositeCopy.m_constraints.Append(newConstraint);
-
-    node = node->Next();
-  }
-
-  // Now compositeCopy the division geometry
-  node = m_divisions.First();
-  while (node)
-  {
-    wxDivisionShape *division = (wxDivisionShape *)node->Data();
-    wxNode *node1 = oglObjectCopyMapping.Find((long)division);
-    wxNode *leftNode = NULL;
-    wxNode *topNode = NULL;
-    wxNode *rightNode = NULL;
-    wxNode *bottomNode = NULL;
-    if (division->GetLeftSide())
-      leftNode = oglObjectCopyMapping.Find((long)division->GetLeftSide());
-    if (division->GetTopSide())
-      topNode = oglObjectCopyMapping.Find((long)division->GetTopSide());
-    if (division->GetRightSide())
-      rightNode = oglObjectCopyMapping.Find((long)division->GetRightSide());
-    if (division->GetBottomSide())
-      bottomNode = oglObjectCopyMapping.Find((long)division->GetBottomSide());
-    if (node1)
-    {
-      wxDivisionShape *newDivision = (wxDivisionShape *)node1->Data();
-      if (leftNode)
-        newDivision->SetLeftSide((wxDivisionShape *)leftNode->Data());
-      if (topNode)
-        newDivision->SetTopSide((wxDivisionShape *)topNode->Data());
-      if (rightNode)
-        newDivision->SetRightSide((wxDivisionShape *)rightNode->Data());
-      if (bottomNode)
-        newDivision->SetBottomSide((wxDivisionShape *)bottomNode->Data());
-    }
-    node = node->Next();
-  }
-}
-
-wxOGLConstraint *wxCompositeShape::AddConstraint(wxOGLConstraint *constraint)
-{
-  m_constraints.Append(constraint);
-  if (constraint->m_constraintId == 0)
-    constraint->m_constraintId = wxNewId();
-  return constraint;
-}
-
-wxOGLConstraint *wxCompositeShape::AddConstraint(int type, wxShape *constraining, wxList& constrained)
-{
-  wxOGLConstraint *constraint = new wxOGLConstraint(type, constraining, constrained);
-  if (constraint->m_constraintId == 0)
-    constraint->m_constraintId = wxNewId();
-  m_constraints.Append(constraint);
-  return constraint;
-}
-
-wxOGLConstraint *wxCompositeShape::AddConstraint(int type, wxShape *constraining, wxShape *constrained)
-{
-  wxList l;
-  l.Append(constrained);
-  wxOGLConstraint *constraint = new wxOGLConstraint(type, constraining, l);
-  if (constraint->m_constraintId == 0)
-    constraint->m_constraintId = wxNewId();
-  m_constraints.Append(constraint);
-  return constraint;
-}
-
-wxOGLConstraint *wxCompositeShape::FindConstraint(long cId, wxCompositeShape **actualComposite)
-{
-  wxNode *node = m_constraints.First();
-  while (node)
-  {
-    wxOGLConstraint *constraint = (wxOGLConstraint *)node->Data();
-    if (constraint->m_constraintId == cId)
-    {
-      if (actualComposite)
-        *actualComposite = this;
-      return constraint;
-    }
-    node = node->Next();
-  }
-  // If not found, try children.
-  node = m_children.First();
-  while (node)
-  {
-    wxShape *child = (wxShape *)node->Data();
-    if (child->IsKindOf(CLASSINFO(wxCompositeShape)))
-    {
-      wxOGLConstraint *constraint = ((wxCompositeShape *)child)->FindConstraint(cId, actualComposite);
-      if (constraint)
-      {
-        if (actualComposite)
-          *actualComposite = (wxCompositeShape *)child;
-        return constraint;
-      }
-    }
-    node = node->Next();
-  }
-  return NULL;
-}
-
-void wxCompositeShape::DeleteConstraint(wxOGLConstraint *constraint)
-{
-  m_constraints.DeleteObject(constraint);
-  delete constraint;
-}
-
-void wxCompositeShape::CalculateSize()
-{
-  double maxX = (double) -999999.9;
-  double maxY = (double) -999999.9;
-  double minX = (double)  999999.9;
-  double minY = (double)  999999.9;
-
-  double w, h;
-  wxNode *node = m_children.First();
-  while (node)
-  {
-    wxShape *object = (wxShape *)node->Data();
-
-    // Recalculate size of composite objects because may not conform
-    // to size it was set to - depends on the children.
-    object->CalculateSize();
-
-    object->GetBoundingBoxMax(&w, &h);
-    if ((object->GetX() + (w/2.0)) > maxX)
-      maxX = (double)(object->GetX() + (w/2.0));
-    if ((object->GetX() - (w/2.0)) < minX)
-      minX = (double)(object->GetX() - (w/2.0));
-    if ((object->GetY() + (h/2.0)) > maxY)
-      maxY = (double)(object->GetY() + (h/2.0));
-    if ((object->GetY() - (h/2.0)) < minY)
-      minY = (double)(object->GetY() - (h/2.0));
-
-    node = node->Next();
-  }
-  m_width = maxX - minX;
-  m_height = maxY - minY;
-  m_xpos = (double)(m_width/2.0 + minX);
-  m_ypos = (double)(m_height/2.0 + minY);
-}
-
-bool wxCompositeShape::Recompute()
-{
-  int noIterations = 0;
-  bool changed = TRUE;
-  while (changed && (noIterations < 500))
-  {
-    changed = Constrain();
-    noIterations ++;
-  }
-/*
-#ifdef wx_x
-  if (changed)
-    cerr << "Warning: constraint algorithm failed after 500 iterations.\n";
-#endif
-*/
-  return (!changed);
-}
-
-bool wxCompositeShape::Constrain()
-{
-  CalculateSize();
-
-  bool changed = FALSE;
-  wxNode *node = m_children.First();
-  while (node)
-  {
-    wxShape *object = (wxShape *)node->Data();
-    if (object->Constrain())
-      changed = TRUE;
-    node = node->Next();
-  }
-
-  node = m_constraints.First();
-  while (node)
-  {
-    wxOGLConstraint *constraint = (wxOGLConstraint *)node->Data();
-    if (constraint->Evaluate()) changed = TRUE;
-    node = node->Next();
-  }
-  return changed;
-}
-
-#ifdef PROLOGIO
-void wxCompositeShape::WriteAttributes(wxExpr *clause)
-{
-  wxRectangleShape::WriteAttributes(clause);
-
-//  clause->AddAttributeValue("selectable", (long)selectable);
-
-  // Output constraints as constraint1 = (...), constraint2 = (...), etc.
-  int constraintNo = 1;
-  char m_constraintNameBuf[20];
-  wxNode *node = m_constraints.First();
-  while (node)
-  {
-    wxOGLConstraint *constraint = (wxOGLConstraint *)node->Data();
-    sprintf(m_constraintNameBuf, "constraint%d", constraintNo);
-
-    // Each constraint is stored in the form
-    // (type name id xspacing yspacing m_constrainingObjectId constrainedObjectIdList)
-    wxExpr *constraintExpr = new wxExpr(wxExprList);
-    constraintExpr->Append(new wxExpr((long)constraint->m_constraintType));
-    constraintExpr->Append(new wxExpr(wxExprString, constraint->m_constraintName));
-    constraintExpr->Append(new wxExpr(constraint->m_constraintId));
-    constraintExpr->Append(new wxExpr(constraint->m_xSpacing));
-    constraintExpr->Append(new wxExpr(constraint->m_ySpacing));
-    constraintExpr->Append(new wxExpr(constraint->m_constrainingObject->GetId()));
-
-    wxExpr *objectList = new wxExpr(wxExprList);
-    wxNode *node1 = constraint->m_constrainedObjects.First();
-    while (node1)
-    {
-      wxShape *obj = (wxShape *)node1->Data();
-      objectList->Append(new wxExpr(obj->GetId()));
-      node1 = node1->Next();
-    }
-    constraintExpr->Append(objectList);
-
-    clause->AddAttributeValue(m_constraintNameBuf, constraintExpr);
-
-    node = node->Next();
-    constraintNo ++;
-  }
-
-  // Write the ids of all the child images
-  wxExpr *childrenExpr = new wxExpr(wxExprList);
-  node = m_children.First();
-  while (node)
-  {
-    wxShape *child = (wxShape *)node->Data();
-    childrenExpr->Append(new wxExpr(child->GetId()));
-    node = node->Next();
-  }
-  clause->AddAttributeValue("children", childrenExpr);
-
-  // Write the ids of all the division images
-  if (m_divisions.Number() > 0)
-  {
-    wxExpr *divisionsExpr = new wxExpr(wxExprList);
-    node = m_divisions.First();
-    while (node)
-    {
-      wxShape *child = (wxShape *)node->Data();
-      divisionsExpr->Append(new wxExpr(child->GetId()));
-      node = node->Next();
-    }
-    clause->AddAttributeValue("divisions", divisionsExpr);
-  }
-}
-
-// Problem. Child images are always written AFTER the parent
-// so as to be able to link up to parent. So we may not be able
-// to find the constraint participants until we've read everything
-// in. Need to have another pass for composites.
-void wxCompositeShape::ReadAttributes(wxExpr *clause)
-{
-  wxRectangleShape::ReadAttributes(clause);
-
-//  clause->GetAttributeValue("selectable", selectable);
-}
-
-void wxCompositeShape::ReadConstraints(wxExpr *clause, wxExprDatabase *database)
-{
-  // Constraints are output as constraint1 = (...), constraint2 = (...), etc.
-  int constraintNo = 1;
-  char m_constraintNameBuf[20];
-  bool haveConstraints = TRUE;
-
-  while (haveConstraints)
-  {
-    sprintf(m_constraintNameBuf, "constraint%d", constraintNo);
-    wxExpr *constraintExpr = NULL;
-    clause->GetAttributeValue(m_constraintNameBuf, &constraintExpr);
-    if (!constraintExpr)
-    {
-      haveConstraints = FALSE;
-      break;
-    }
-    int cType = 0;
-    double cXSpacing = 0.0;
-    double cYSpacing = 0.0;
-    wxString cName("");
-    long cId = 0;
-    wxShape *m_constrainingObject = NULL;
-    wxList m_constrainedObjects;
-
-    // Each constraint is stored in the form
-    // (type name id xspacing yspacing m_constrainingObjectId constrainedObjectIdList)
-
-    wxExpr *typeExpr = constraintExpr->Nth(0);
-    wxExpr *nameExpr = constraintExpr->Nth(1);
-    wxExpr *idExpr = constraintExpr->Nth(2);
-    wxExpr *xExpr = constraintExpr->Nth(3);
-    wxExpr *yExpr = constraintExpr->Nth(4);
-    wxExpr *constrainingExpr = constraintExpr->Nth(5);
-    wxExpr *constrainedExpr = constraintExpr->Nth(6);
-
-    cType = (int)typeExpr->IntegerValue();
-    cXSpacing = xExpr->RealValue();
-    cYSpacing = yExpr->RealValue();
-    cName = nameExpr->StringValue();
-    cId = idExpr->IntegerValue();
-
-    wxExpr *objExpr1 = database->HashFind("node_image", constrainingExpr->IntegerValue());
-    if (objExpr1 && objExpr1->GetClientData())
-      m_constrainingObject = (wxShape *)objExpr1->GetClientData();
-    else
-      wxFatalError("Couldn't find constraining image of composite.", "Object graphics error");
-
-    int i = 0;
-    wxExpr *currentIdExpr = constrainedExpr->Nth(i);
-    while (currentIdExpr)
-    {
-      long currentId = currentIdExpr->IntegerValue();
-      wxExpr *objExpr2 = database->HashFind("node_image", currentId);
-      if (objExpr2 && objExpr2->GetClientData())
-      {
-        m_constrainedObjects.Append((wxShape *)objExpr2->GetClientData());
-      }
-      else
-      {
-        wxFatalError("Couldn't find constrained image of composite.", "Object graphics error");
-      }
-
-      i ++;
-      currentIdExpr = constrainedExpr->Nth(i);
-    }
-    wxOGLConstraint *newConstraint = AddConstraint(cType, m_constrainingObject, m_constrainedObjects);
-    newConstraint->SetSpacing(cXSpacing, cYSpacing);
-    newConstraint->m_constraintId = cId;
-    newConstraint->m_constraintName = (const char*) cName;
-    constraintNo ++;
-  }
-}
-#endif
-
-// Make this composite into a container by creating one wxDivisionShape
-void wxCompositeShape::MakeContainer()
-{
-  wxDivisionShape *division = OnCreateDivision();
-  m_divisions.Append(division);
-  AddChild(division);
-
-  division->SetSize(m_width, m_height);
-
-  wxClientDC dc(GetCanvas());
-  GetCanvas()->PrepareDC(dc);
-
-  division->Move(dc, GetX(), GetY());
-  Recompute();
-  division->Show(TRUE);
-}
-
-wxDivisionShape *wxCompositeShape::OnCreateDivision()
-{
-  return new wxDivisionShape;
-}
-
-wxShape *wxCompositeShape::FindContainerImage()
-{
-  wxNode *node = m_children.First();
-  while (node)
-  {
-    wxShape *child = (wxShape *)node->Data();
-    if (!m_divisions.Member(child))
-      return child;
-    node = node->Next();
-  }
-  return NULL;
-}
-
-// Returns TRUE if division is a descendant of this container
-bool wxCompositeShape::ContainsDivision(wxDivisionShape *division)
-{
-  if (m_divisions.Member(division))
-    return TRUE;
-  wxNode *node = m_children.First();
-  while (node)
-  {
-    wxShape *child = (wxShape *)node->Data();
-    if (child->IsKindOf(CLASSINFO(wxCompositeShape)))
-    {
-      bool ans = ((wxCompositeShape *)child)->ContainsDivision(division);
-      if (ans)
-        return TRUE;
-    }
-    node = node->Next();
-  }
-  return FALSE;
-}
-
-/*
- * Division object
- *
- */
-
-IMPLEMENT_DYNAMIC_CLASS(wxDivisionShape, wxCompositeShape)
-
-wxDivisionShape::wxDivisionShape()
-{
-  SetSensitivityFilter(OP_CLICK_LEFT | OP_CLICK_RIGHT | OP_DRAG_RIGHT);
-  SetCentreResize(FALSE);
-  SetAttachmentMode(TRUE);
-  m_leftSide = NULL;
-  m_rightSide = NULL;
-  m_topSide = NULL;
-  m_bottomSide = NULL;
-  m_handleSide = DIVISION_SIDE_NONE;
-  m_leftSidePen = wxBLACK_PEN;
-  m_topSidePen = wxBLACK_PEN;
-  m_leftSideColour = "BLACK";
-  m_topSideColour = "BLACK";
-  m_leftSideStyle = "Solid";
-  m_topSideStyle = "Solid";
-  ClearRegions();
-}
-
-wxDivisionShape::~wxDivisionShape()
-{
-}
-
-void wxDivisionShape::OnDraw(wxDC& dc)
-{
-    dc.SetBrush(* wxTRANSPARENT_BRUSH);
-    dc.SetBackgroundMode(wxTRANSPARENT);
-
-    double x1 = (double)(GetX() - (GetWidth()/2.0));
-    double y1 = (double)(GetY() - (GetHeight()/2.0));
-    double x2 = (double)(GetX() + (GetWidth()/2.0));
-    double y2 = (double)(GetY() + (GetHeight()/2.0));
-
-    // Should subtract 1 pixel if drawing under Windows
-#ifdef __WXMSW__
-    y2 -= (double)1.0;
-#endif
-
-    if (m_leftSide)
-    {
-      dc.SetPen(* m_leftSidePen);
-      dc.DrawLine(WXROUND(x1), WXROUND(y2), WXROUND(x1), WXROUND(y1));
-    }
-    if (m_topSide)
-    {
-      dc.SetPen(* m_topSidePen);
-      dc.DrawLine(WXROUND(x1), WXROUND(y1), WXROUND(x2), WXROUND(y1));
-    }
-
-    // For testing purposes, draw a rectangle so we know
-    // how big the division is.
-//    SetBrush(* wxCYAN_BRUSH);
-//    wxRectangleShape::OnDraw(dc);
-}
-
-void wxDivisionShape::OnDrawContents(wxDC& dc)
-{
-  wxCompositeShape::OnDrawContents(dc);
-}
-
-bool wxDivisionShape::OnMovePre(wxDC& dc, double x, double y, double oldx, double oldy, bool display)
-{
-  double diffX = x - oldx;
-  double diffY = y - oldy;
-  wxNode *node = m_children.First();
-  while (node)
-  {
-    wxShape *object = (wxShape *)node->Data();
-    object->Erase(dc);
-    object->Move(dc, object->GetX() + diffX, object->GetY() + diffY, display);
-    node = node->Next();
-  }
-  return TRUE;
-}
-
-void wxDivisionShape::OnDragLeft(bool draw, double x, double y, int keys, int attachment)
-{
-  if ((m_sensitivity & OP_DRAG_LEFT) != OP_DRAG_LEFT)
-  {
-    attachment = 0;
-    double dist;
-    if (m_parent)
-    {
-      m_parent->HitTest(x, y, &attachment, &dist);
-      m_parent->GetEventHandler()->OnDragLeft(draw, x, y, keys, attachment);
-    }
-    return;
-  }
-  wxShape::OnDragLeft(draw, x, y, keys, attachment);
-}
-
-void wxDivisionShape::OnBeginDragLeft(double x, double y, int keys, int attachment)
-{
-  if ((m_sensitivity & OP_DRAG_LEFT) != OP_DRAG_LEFT)
-  {
-    attachment = 0;
-    double dist;
-    if (m_parent)
-    {
-      m_parent->HitTest(x, y, &attachment, &dist);
-      m_parent->GetEventHandler()->OnBeginDragLeft(x, y, keys, attachment);
-    }
-    return;
-  }
-
-  wxShape::OnBeginDragLeft(x, y, keys, attachment);
-}
-
-void wxDivisionShape::OnEndDragLeft(double x, double y, int keys, int attachment)
-{
-  m_canvas->ReleaseMouse();
-  if ((m_sensitivity & OP_DRAG_LEFT) != OP_DRAG_LEFT)
-  {
-    attachment = 0;
-    double dist;
-    if (m_parent)
-    {
-      m_parent->HitTest(x, y, &attachment, &dist);
-      m_parent->GetEventHandler()->OnEndDragLeft(x, y, keys, attachment);
-    }
-    return;
-  }
-
-  wxClientDC dc(GetCanvas());
-  GetCanvas()->PrepareDC(dc);
-
-  dc.SetLogicalFunction(wxCOPY);
-
-  m_canvas->Snap(&m_xpos, &m_ypos);
-  GetEventHandler()->OnMovePre(dc, x, y, m_oldX, m_oldY);
-
-  ResetControlPoints();
-  Draw(dc);
-  MoveLinks(dc);
-  GetEventHandler()->OnDrawControlPoints(dc);
-
-  if (m_canvas && !m_canvas->GetQuickEditMode()) m_canvas->Redraw(dc);
-}
-
-void wxDivisionShape::SetSize(double w, double h, bool recursive)
-{
-  m_width = w;
-  m_height = h;
-  wxRectangleShape::SetSize(w, h, recursive);
-}
-
-void wxDivisionShape::CalculateSize()
-{
-}
-
-void wxDivisionShape::Copy(wxShape& copy)
-{
-  wxCompositeShape::Copy(copy);
-
-  wxASSERT( copy.IsKindOf(CLASSINFO(wxDivisionShape)) ) ;
-
-  wxDivisionShape& divisionCopy = (wxDivisionShape&) copy;
-
-  divisionCopy.m_leftSideStyle = m_leftSideStyle;
-  divisionCopy.m_topSideStyle = m_topSideStyle;
-  divisionCopy.m_leftSideColour = m_leftSideColour;
-  divisionCopy.m_topSideColour = m_topSideColour;
-
-  divisionCopy.m_leftSidePen = m_leftSidePen;
-  divisionCopy.m_topSidePen = m_topSidePen;
-  divisionCopy.m_handleSide = m_handleSide;
-
-  // Division geometry copying is handled at the wxCompositeShape level.
-}
-
-#ifdef PROLOGIO
-void wxDivisionShape::WriteAttributes(wxExpr *clause)
-{
-  wxCompositeShape::WriteAttributes(clause);
-
-  if (m_leftSide)
-    clause->AddAttributeValue("left_side", (long)m_leftSide->GetId());
-  if (m_topSide)
-    clause->AddAttributeValue("top_side", (long)m_topSide->GetId());
-  if (m_rightSide)
-    clause->AddAttributeValue("right_side", (long)m_rightSide->GetId());
-  if (m_bottomSide)
-    clause->AddAttributeValue("bottom_side", (long)m_bottomSide->GetId());
-
-  clause->AddAttributeValue("handle_side", (long)m_handleSide);
-  clause->AddAttributeValueString("left_colour", m_leftSideColour);
-  clause->AddAttributeValueString("top_colour", m_topSideColour);
-  clause->AddAttributeValueString("left_style", m_leftSideStyle);
-  clause->AddAttributeValueString("top_style", m_topSideStyle);
-}
-
-void wxDivisionShape::ReadAttributes(wxExpr *clause)
-{
-  wxCompositeShape::ReadAttributes(clause);
-
-  clause->GetAttributeValue("handle_side", m_handleSide);
-  clause->GetAttributeValue("left_colour", m_leftSideColour);
-  clause->GetAttributeValue("top_colour", m_topSideColour);
-  clause->GetAttributeValue("left_style", m_leftSideStyle);
-  clause->GetAttributeValue("top_style", m_topSideStyle);
-}
-#endif
-
-// Experimental
-void wxDivisionShape::OnRightClick(double x, double y, int keys, int attachment)
-{
-  if (keys & KEY_CTRL)
-  {
-    PopupMenu(x, y);
-  }
-/*
-  else if (keys & KEY_SHIFT)
-  {
-    if (m_leftSide || m_topSide || m_rightSide || m_bottomSide)
-    {
-      if (Selected())
-      {
-        Select(FALSE);
-        GetParent()->Draw(dc);
-      }
-      else
-        Select(TRUE);
-    }
-  }
-*/
-  else
-  {
-    attachment = 0;
-    double dist;
-    if (m_parent)
-    {
-      m_parent->HitTest(x, y, &attachment, &dist);
-      m_parent->GetEventHandler()->OnRightClick(x, y, keys, attachment);
-    }
-    return;
-  }
-}
-
-
-// Divide wxHORIZONTALly or wxVERTICALly
-bool wxDivisionShape::Divide(int direction)
-{
-  // Calculate existing top-left, bottom-right
-  double x1 = (double)(GetX() - (GetWidth()/2.0));
-  double y1 = (double)(GetY() - (GetHeight()/2.0));
-  wxCompositeShape *compositeParent = (wxCompositeShape *)GetParent();
-  double oldWidth = GetWidth();
-  double oldHeight = GetHeight();
-  if (Selected())
-    Select(FALSE);
-
-  wxClientDC dc(GetCanvas());
-  GetCanvas()->PrepareDC(dc);
-
-  if (direction == wxVERTICAL)
-  {
-    // Dividing vertically means notionally putting a horizontal line through it.
-    // Break existing piece into two.
-    double newXPos1 = GetX();
-    double newYPos1 = (double)(y1 + (GetHeight()/4.0));
-    double newXPos2 = GetX();
-    double newYPos2 = (double)(y1 + (3.0*GetHeight()/4.0));
-    wxDivisionShape *newDivision = compositeParent->OnCreateDivision();
-    newDivision->Show(TRUE);
-
-    Erase(dc);
-
-    // Anything adjoining the bottom of this division now adjoins the
-    // bottom of the new division.
-    wxNode *node = compositeParent->GetDivisions().First();
-    while (node)
-    {
-      wxDivisionShape *obj = (wxDivisionShape *)node->Data();
-      if (obj->GetTopSide() == this)
-        obj->SetTopSide(newDivision);
-      node = node->Next();
-    }
-    newDivision->SetTopSide(this);
-    newDivision->SetBottomSide(m_bottomSide);
-    newDivision->SetLeftSide(m_leftSide);
-    newDivision->SetRightSide(m_rightSide);
-    m_bottomSide = newDivision;
-
-    compositeParent->GetDivisions().Append(newDivision);
-
-    // CHANGE: Need to insert this division at start of divisions in the object
-    // list, because e.g.:
-    // 1) Add division
-    // 2) Add contained object
-    // 3) Add division
-    // Division is now receiving mouse events _before_ the contained object,
-    // because it was added last (on top of all others)
-
-    // Add after the image that visualizes the container
-    compositeParent->AddChild(newDivision, compositeParent->FindContainerImage());
-
-    m_handleSide = DIVISION_SIDE_BOTTOM;
-    newDivision->SetHandleSide(DIVISION_SIDE_TOP);
-
-    SetSize(oldWidth, (double)(oldHeight/2.0));
-    Move(dc, newXPos1, newYPos1);
-
-    newDivision->SetSize(oldWidth, (double)(oldHeight/2.0));
-    newDivision->Move(dc, newXPos2, newYPos2);
-  }
-  else
-  {
-    // Dividing horizontally means notionally putting a vertical line through it.
-    // Break existing piece into two.
-    double newXPos1 = (double)(x1 + (GetWidth()/4.0));
-    double newYPos1 = GetY();
-    double newXPos2 = (double)(x1 + (3.0*GetWidth()/4.0));
-    double newYPos2 = GetY();
-    wxDivisionShape *newDivision = compositeParent->OnCreateDivision();
-    newDivision->Show(TRUE);
-
-    Erase(dc);
-
-    // Anything adjoining the left of this division now adjoins the
-    // left of the new division.
-    wxNode *node = compositeParent->GetDivisions().First();
-    while (node)
-    {
-      wxDivisionShape *obj = (wxDivisionShape *)node->Data();
-      if (obj->GetLeftSide() == this)
-        obj->SetLeftSide(newDivision);
-      node = node->Next();
-    }
-    newDivision->SetTopSide(m_topSide);
-    newDivision->SetBottomSide(m_bottomSide);
-    newDivision->SetLeftSide(this);
-    newDivision->SetRightSide(m_rightSide);
-    m_rightSide = newDivision;
-
-    compositeParent->GetDivisions().Append(newDivision);
-    compositeParent->AddChild(newDivision, compositeParent->FindContainerImage());
-
-    m_handleSide = DIVISION_SIDE_RIGHT;
-    newDivision->SetHandleSide(DIVISION_SIDE_LEFT);
-
-    SetSize((double)(oldWidth/2.0), oldHeight);
-    Move(dc, newXPos1, newYPos1);
-
-    newDivision->SetSize((double)(oldWidth/2.0), oldHeight);
-    newDivision->Move(dc, newXPos2, newYPos2);
-  }
-  if (compositeParent->Selected())
-  {
-    compositeParent->DeleteControlPoints(& dc);
-    compositeParent->MakeControlPoints();
-    compositeParent->MakeMandatoryControlPoints();
-  }
-  compositeParent->Draw(dc);
-  return TRUE;
-}
-
-// Make one control point for every visible line
-void wxDivisionShape::MakeControlPoints()
-{
-  MakeMandatoryControlPoints();
-}
-
-void wxDivisionShape::MakeMandatoryControlPoints()
-{
-  double maxX, maxY;
-
-  GetBoundingBoxMax(&maxX, &maxY);
-  double x, y;
-  int direction;
-/*
-  if (m_leftSide)
-  {
-    x = (double)(-maxX/2.0);
-    y = 0.0;
-    wxDivisionControlPoint *control = new wxDivisionControlPoint(m_canvas, this, CONTROL_POINT_SIZE, x, y,
-                                             CONTROL_POINT_HORIZONTAL);
-    m_canvas->AddShape(control);
-    m_controlPoints.Append(control);
-  }
-  if (m_topSide)
-  {
-    x = 0.0;
-    y = (double)(-maxY/2.0);
-    wxDivisionControlPoint *control = new wxDivisionControlPoint(m_canvas, this, CONTROL_POINT_SIZE, x, y,
-                                             CONTROL_POINT_VERTICAL);
-    m_canvas->AddShape(control);
-    m_controlPoints.Append(control);
-  }
-*/
-  switch (m_handleSide)
-  {
-    case DIVISION_SIDE_LEFT:
-    {
-      x = (double)(-maxX/2.0);
-      y = 0.0;
-      direction = CONTROL_POINT_HORIZONTAL;
-      break;
-    }
-    case DIVISION_SIDE_TOP:
-    {
-      x = 0.0;
-      y = (double)(-maxY/2.0);
-      direction = CONTROL_POINT_VERTICAL;
-      break;
-    }
-    case DIVISION_SIDE_RIGHT:
-    {
-      x = (double)(maxX/2.0);
-      y = 0.0;
-      direction = CONTROL_POINT_HORIZONTAL;
-      break;
-    }
-    case DIVISION_SIDE_BOTTOM:
-    {
-      x = 0.0;
-      y = (double)(maxY/2.0);
-      direction = CONTROL_POINT_VERTICAL;
-      break;
-    }
-    default:
-      break;
-  }
-  if (m_handleSide != DIVISION_SIDE_NONE)
-  {
-    wxDivisionControlPoint *control = new wxDivisionControlPoint(m_canvas, this, CONTROL_POINT_SIZE, x, y,
-                                             direction);
-    m_canvas->AddShape(control);
-    m_controlPoints.Append(control);
-  }
-}
-
-void wxDivisionShape::ResetControlPoints()
-{
-  ResetMandatoryControlPoints();
-}
-
-void wxDivisionShape::ResetMandatoryControlPoints()
-{
-  if (m_controlPoints.Number() < 1)
-    return;
-
-  double maxX, maxY;
-
-  GetBoundingBoxMax(&maxX, &maxY);
-/*
-  wxNode *node = m_controlPoints.First();
-  while (node)
-  {
-    wxDivisionControlPoint *control = (wxDivisionControlPoint *)node->Data();
-    if (control->type == CONTROL_POINT_HORIZONTAL)
-    {
-      control->xoffset = (double)(-maxX/2.0); control->m_yoffset = 0.0;
-    }
-    else if (control->type == CONTROL_POINT_VERTICAL)
-    {
-      control->xoffset = 0.0; control->m_yoffset = (double)(-maxY/2.0);
-    }
-    node = node->Next();
-  }
-*/
-  wxNode *node = m_controlPoints.First();
-  if ((m_handleSide == DIVISION_SIDE_LEFT) && node)
-  {
-    wxDivisionControlPoint *control = (wxDivisionControlPoint *)node->Data();
-    control->m_xoffset = (double)(-maxX/2.0); control->m_yoffset = 0.0;
-  }
-
-  if ((m_handleSide == DIVISION_SIDE_TOP) && node)
-  {
-    wxDivisionControlPoint *control = (wxDivisionControlPoint *)node->Data();
-    control->m_xoffset = 0.0; control->m_yoffset = (double)(-maxY/2.0);
-  }
-
-  if ((m_handleSide == DIVISION_SIDE_RIGHT) && node)
-  {
-    wxDivisionControlPoint *control = (wxDivisionControlPoint *)node->Data();
-    control->m_xoffset = (double)(maxX/2.0); control->m_yoffset = 0.0;
-  }
-
-  if ((m_handleSide == DIVISION_SIDE_BOTTOM) && node)
-  {
-    wxDivisionControlPoint *control = (wxDivisionControlPoint *)node->Data();
-    control->m_xoffset = 0.0; control->m_yoffset = (double)(maxY/2.0);
-  }
-}
-
-// Adjust a side, returning FALSE if it's not physically possible.
-bool wxDivisionShape::AdjustLeft(double left, bool test)
-{
-  double x2 = (double)(GetX() + (GetWidth()/2.0));
-
-  if (left >= x2)
-    return FALSE;
-  if (test)
-    return TRUE;
-
-  double newW = x2 - left;
-  double newX = (double)(left + newW/2.0);
-  SetSize(newW, GetHeight());
-
-  wxClientDC dc(GetCanvas());
-  GetCanvas()->PrepareDC(dc);
-
-  Move(dc, newX, GetY());
-
-  return TRUE;
-}
-
-bool wxDivisionShape::AdjustTop(double top, bool test)
-{
-  double y2 = (double)(GetY() + (GetHeight()/2.0));
-
-  if (top >= y2)
-    return FALSE;
-  if (test)
-    return TRUE;
-
-  double newH = y2 - top;
-  double newY = (double)(top + newH/2.0);
-  SetSize(GetWidth(), newH);
-
-  wxClientDC dc(GetCanvas());
-  GetCanvas()->PrepareDC(dc);
-
-  Move(dc, GetX(), newY);
-
-  return TRUE;
-}
-
-bool wxDivisionShape::AdjustRight(double right, bool test)
-{
-  double x1 = (double)(GetX() - (GetWidth()/2.0));
-
-  if (right <= x1)
-    return FALSE;
-  if (test)
-    return TRUE;
-
-  double newW = right - x1;
-  double newX = (double)(x1 + newW/2.0);
-  SetSize(newW, GetHeight());
-
-  wxClientDC dc(GetCanvas());
-  GetCanvas()->PrepareDC(dc);
-
-  Move(dc, newX, GetY());
-
-  return TRUE;
-}
-
-bool wxDivisionShape::AdjustBottom(double bottom, bool test)
-{
-  double y1 = (double)(GetY() - (GetHeight()/2.0));
-
-  if (bottom <= y1)
-    return FALSE;
-  if (test)
-    return TRUE;
-
-  double newH = bottom - y1;
-  double newY = (double)(y1 + newH/2.0);
-  SetSize(GetWidth(), newH);
-
-  wxClientDC dc(GetCanvas());
-  GetCanvas()->PrepareDC(dc);
-
-  Move(dc, GetX(), newY);
-
-  return TRUE;
-}
-
-wxDivisionControlPoint::wxDivisionControlPoint(wxShapeCanvas *the_canvas, wxShape *object, double size, double the_xoffset, double the_yoffset, int the_type):
-  wxControlPoint(the_canvas, object, size, the_xoffset, the_yoffset, the_type)
-{
-  SetEraseObject(FALSE);
-}
-
-wxDivisionControlPoint::~wxDivisionControlPoint()
-{
-}
-
-static double originalX = 0.0;
-static double originalY = 0.0;
-static double originalW = 0.0;
-static double originalH = 0.0;
-
-// Implement resizing of canvas object
-void wxDivisionControlPoint::OnDragLeft(bool draw, double x, double y, int keys, int attachment)
-{
-  wxControlPoint::OnDragLeft(draw, x, y, keys, attachment);
-}
-
-void wxDivisionControlPoint::OnBeginDragLeft(double x, double y, int keys, int attachment)
-{
-  wxDivisionShape *division = (wxDivisionShape *)m_shape;
-  originalX = division->GetX();
-  originalY = division->GetY();
-  originalW = division->GetWidth();
-  originalH = division->GetHeight();
-
-  wxControlPoint::OnBeginDragLeft(x, y, keys, attachment);
-}
-
-void wxDivisionControlPoint::OnEndDragLeft(double x, double y, int keys, int attachment)
-{
-  wxControlPoint::OnEndDragLeft(x, y, keys, attachment);
-
-  wxClientDC dc(GetCanvas());
-  GetCanvas()->PrepareDC(dc);
-
-  wxDivisionShape *division = (wxDivisionShape *)m_shape;
-  wxCompositeShape *divisionParent = (wxCompositeShape *)division->GetParent();
-
-  // Need to check it's within the bounds of the parent composite.
-  double x1 = (double)(divisionParent->GetX() - (divisionParent->GetWidth()/2.0));
-  double y1 = (double)(divisionParent->GetY() - (divisionParent->GetHeight()/2.0));
-  double x2 = (double)(divisionParent->GetX() + (divisionParent->GetWidth()/2.0));
-  double y2 = (double)(divisionParent->GetY() + (divisionParent->GetHeight()/2.0));
-
-  // Need to check it has not made the division zero or negative width/height
-  double dx1 = (double)(division->GetX() - (division->GetWidth()/2.0));
-  double dy1 = (double)(division->GetY() - (division->GetHeight()/2.0));
-  double dx2 = (double)(division->GetX() + (division->GetWidth()/2.0));
-  double dy2 = (double)(division->GetY() + (division->GetHeight()/2.0));
-
-  bool success = TRUE;
-  switch (division->GetHandleSide())
-  {
-    case DIVISION_SIDE_LEFT:
-    {
-      if ((x <= x1) || (x >= x2) || (x >= dx2))
-        success = FALSE;
-      // Try it out first...
-      else if (!division->ResizeAdjoining(DIVISION_SIDE_LEFT, x, TRUE))
-        success = FALSE;
-      else
-        division->ResizeAdjoining(DIVISION_SIDE_LEFT, x, FALSE);
-
-      break;
-    }
-    case DIVISION_SIDE_TOP:
-    {
-      if ((y <= y1) || (y >= y2) || (y >= dy2))
-        success = FALSE;
-      else if (!division->ResizeAdjoining(DIVISION_SIDE_TOP, y, TRUE))
-        success = FALSE;
-      else
-        division->ResizeAdjoining(DIVISION_SIDE_TOP, y, FALSE);
-
-      break;
-    }
-    case DIVISION_SIDE_RIGHT:
-    {
-      if ((x <= x1) || (x >= x2) || (x <= dx1))
-        success = FALSE;
-      else if (!division->ResizeAdjoining(DIVISION_SIDE_RIGHT, x, TRUE))
-        success = FALSE;
-      else
-        division->ResizeAdjoining(DIVISION_SIDE_RIGHT, x, FALSE);
-
-      break;
-    }
-    case DIVISION_SIDE_BOTTOM:
-    {
-      if ((y <= y1) || (y >= y2) || (y <= dy1))
-        success = FALSE;
-      else if (!division->ResizeAdjoining(DIVISION_SIDE_BOTTOM, y, TRUE))
-        success = FALSE;
-      else
-        division->ResizeAdjoining(DIVISION_SIDE_BOTTOM, y, FALSE);
-
-      break;
-    }
-  }
-  if (!success)
-  {
-    division->SetSize(originalW, originalH);
-    division->Move(dc, originalX, originalY);
-  }
-  divisionParent->Draw(dc);
-  division->GetEventHandler()->OnDrawControlPoints(dc);
-}
-
-/* Resize adjoining divisions.
- *
-   Behaviour should be as follows:
-   If right edge moves, find all objects whose left edge
-   adjoins this object, and move left edge accordingly.
-   If left..., move ... right.
-   If top..., move ... bottom.
-   If bottom..., move top.
-   If size goes to zero or end position is other side of start position,
-   resize to original size and return.
- */
-bool wxDivisionShape::ResizeAdjoining(int side, double newPos, bool test)
-{
-  wxCompositeShape *divisionParent = (wxCompositeShape *)GetParent();
-  wxNode *node = divisionParent->GetDivisions().First();
-  while (node)
-  {
-    wxDivisionShape *division = (wxDivisionShape *)node->Data();
-    switch (side)
-    {
-      case DIVISION_SIDE_LEFT:
-      {
-        if (division->m_rightSide == this)
-        {
-          bool success = division->AdjustRight(newPos, test);
-          if (!success && test)
-            return FALSE;
-        }
-        break;
-      }
-      case DIVISION_SIDE_TOP:
-      {
-        if (division->m_bottomSide == this)
-        {
-          bool success = division->AdjustBottom(newPos, test);
-          if (!success && test)
-            return FALSE;
-        }
-        break;
-      }
-      case DIVISION_SIDE_RIGHT:
-      {
-        if (division->m_leftSide == this)
-        {
-          bool success = division->AdjustLeft(newPos, test);
-          if (!success && test)
-            return FALSE;
-        }
-        break;
-      }
-      case DIVISION_SIDE_BOTTOM:
-      {
-        if (division->m_topSide == this)
-        {
-          bool success = division->AdjustTop(newPos, test);
-          if (!success && test)
-            return FALSE;
-        }
-        break;
-      }
-      default:
-        break;
-    }
-    node = node->Next();
-  }
-
-  return TRUE;
-}
-
-/*
- * Popup menu for editing divisions
- *
- */
-class OGLPopupDivisionMenu : public wxMenu {
-public:
-    OGLPopupDivisionMenu() : wxMenu() {
-        Append(DIVISION_MENU_SPLIT_HORIZONTALLY, "Split horizontally");
-        Append(DIVISION_MENU_SPLIT_VERTICALLY, "Split vertically");
-        AppendSeparator();
-        Append(DIVISION_MENU_EDIT_LEFT_EDGE, "Edit left edge");
-        Append(DIVISION_MENU_EDIT_TOP_EDGE, "Edit top edge");
-    }
-
-    void OnMenu(wxCommandEvent& event);
-
-    DECLARE_EVENT_TABLE()
-};
-
-BEGIN_EVENT_TABLE(OGLPopupDivisionMenu, wxMenu)
-    EVT_CUSTOM_RANGE(wxEVT_COMMAND_MENU_SELECTED,
-                     DIVISION_MENU_SPLIT_HORIZONTALLY,
-                     DIVISION_MENU_EDIT_BOTTOM_EDGE,
-                     OGLPopupDivisionMenu::OnMenu)
-END_EVENT_TABLE()
-
-
-void OGLPopupDivisionMenu::OnMenu(wxCommandEvent& event)
-{
-  wxDivisionShape *division = (wxDivisionShape *)GetClientData();
-  switch (event.GetInt())
-  {
-    case DIVISION_MENU_SPLIT_HORIZONTALLY:
-    {
-      division->Divide(wxHORIZONTAL);
-      break;
-    }
-    case DIVISION_MENU_SPLIT_VERTICALLY:
-    {
-      division->Divide(wxVERTICAL);
-      break;
-    }
-    case DIVISION_MENU_EDIT_LEFT_EDGE:
-    {
-      division->EditEdge(DIVISION_SIDE_LEFT);
-      break;
-    }
-    case DIVISION_MENU_EDIT_TOP_EDGE:
-    {
-      division->EditEdge(DIVISION_SIDE_TOP);
-      break;
-    }
-    default:
-      break;
-  }
-}
-
-void wxDivisionShape::EditEdge(int side)
-{
-  wxMessageBox("EditEdge() not implemented", "OGL", wxOK);
-
-#if 0
-  wxBeginBusyCursor();
-
-  wxPen *currentPen = NULL;
-  char **pColour = NULL;
-  char **pStyle = NULL;
-  if (side == DIVISION_SIDE_LEFT)
-  {
-    currentPen = m_leftSidePen;
-    pColour = &m_leftSideColour;
-    pStyle = &m_leftSideStyle;
-  }
-  else
-  {
-    currentPen = m_topSidePen;
-    pColour = &m_topSideColour;
-    pStyle = &m_topSideStyle;
-  }
-
-  GraphicsForm *form = new GraphicsForm("Containers");
-  int lineWidth = currentPen->GetWidth();
-
-  form->Add(wxMakeFormShort("Width", &lineWidth, wxFORM_DEFAULT, NULL, NULL, wxVERTICAL,
-               150));
-  form->Add(wxMakeFormString("Colour", pColour, wxFORM_CHOICE,
-            new wxList(wxMakeConstraintStrings(
-  "BLACK"            ,
-  "BLUE"             ,
-  "BROWN"            ,
-  "CORAL"            ,
-  "CYAN"             ,
-  "DARK GREY"        ,
-  "DARK GREEN"       ,
-  "DIM GREY"         ,
-  "GREY"             ,
-  "GREEN"            ,
-  "LIGHT BLUE"       ,
-  "LIGHT GREY"       ,
-  "MAGENTA"          ,
-  "MAROON"           ,
-  "NAVY"             ,
-  "ORANGE"           ,
-  "PURPLE"           ,
-  "RED"              ,
-  "TURQUOISE"        ,
-  "VIOLET"           ,
-  "WHITE"            ,
-  "YELLOW"           ,
-  NULL),
-  NULL), NULL, wxVERTICAL, 150));
-  form->Add(wxMakeFormString("Style", pStyle, wxFORM_CHOICE,
-            new wxList(wxMakeConstraintStrings(
-  "Solid"            ,
-  "Short Dash"       ,
-  "Long Dash"        ,
-  "Dot"              ,
-  "Dot Dash"         ,
-  NULL),
-  NULL), NULL, wxVERTICAL, 100));
-
-  wxDialogBox *dialog = new wxDialogBox(m_canvas->GetParent(), "Division properties", 10, 10, 500, 500);
-  if (GraphicsLabelFont)
-    dialog->SetLabelFont(GraphicsLabelFont);
-  if (GraphicsButtonFont)
-    dialog->SetButtonFont(GraphicsButtonFont);
-
-  form->AssociatePanel(dialog);
-  form->dialog = dialog;
-
-  dialog->Fit();
-  dialog->Centre(wxBOTH);
-
-  wxEndBusyCursor();
-  dialog->Show(TRUE);
-
-  int lineStyle = wxSOLID;
-  if (*pStyle)
-  {
-    if (strcmp(*pStyle, "Solid") == 0)
-      lineStyle = wxSOLID;
-    else if (strcmp(*pStyle, "Dot") == 0)
-      lineStyle = wxDOT;
-    else if (strcmp(*pStyle, "Short Dash") == 0)
-      lineStyle = wxSHORT_DASH;
-    else if (strcmp(*pStyle, "Long Dash") == 0)
-      lineStyle = wxLONG_DASH;
-    else if (strcmp(*pStyle, "Dot Dash") == 0)
-      lineStyle = wxDOT_DASH;
-  }
-
-  wxPen *newPen = wxThePenList->FindOrCreatePen(*pColour, lineWidth, lineStyle);
-  if (!pen)
-    pen = wxBLACK_PEN;
-  if (side == DIVISION_SIDE_LEFT)
-    m_leftSidePen = newPen;
-  else
-    m_topSidePen = newPen;
-
-  // Need to draw whole image again
-  wxCompositeShape *compositeParent = (wxCompositeShape *)GetParent();
-  compositeParent->Draw(dc);
-#endif
-}
-
-// Popup menu
-void wxDivisionShape::PopupMenu(double x, double y)
-{
-  wxMenu* oglPopupDivisionMenu = new OGLPopupDivisionMenu;
-
-  oglPopupDivisionMenu->SetClientData((void *)this);
-  if (m_leftSide)
-    oglPopupDivisionMenu->Enable(DIVISION_MENU_EDIT_LEFT_EDGE, TRUE);
-  else
-    oglPopupDivisionMenu->Enable(DIVISION_MENU_EDIT_LEFT_EDGE, FALSE);
-  if (m_topSide)
-    oglPopupDivisionMenu->Enable(DIVISION_MENU_EDIT_TOP_EDGE, TRUE);
-  else
-    oglPopupDivisionMenu->Enable(DIVISION_MENU_EDIT_TOP_EDGE, FALSE);
-
-  int x1, y1;
-  m_canvas->ViewStart(&x1, &y1);
-
-  int unit_x, unit_y;
-  m_canvas->GetScrollPixelsPerUnit(&unit_x, &unit_y);
-
-  wxClientDC dc(GetCanvas());
-  GetCanvas()->PrepareDC(dc);
-
-  int mouse_x = (int)(dc.LogicalToDeviceX((long)(x - x1*unit_x)));
-  int mouse_y = (int)(dc.LogicalToDeviceY((long)(y - y1*unit_y)));
-
-  m_canvas->PopupMenu(oglPopupDivisionMenu, mouse_x, mouse_y);
-  delete oglPopupDivisionMenu;
-}
-
-void wxDivisionShape::SetLeftSideColour(const wxString& colour)
-{
-  m_leftSideColour = colour;
-}
-
-void wxDivisionShape::SetTopSideColour(const wxString& colour)
-{
-  m_topSideColour = colour;
-}
-
-void wxDivisionShape::SetLeftSideStyle(const wxString& style)
-{
-  m_leftSideStyle = style;
-}
-
-void wxDivisionShape::SetTopSideStyle(const wxString& style)
-{
-  m_topSideStyle = style;
-}
-