-/////////////////////////////////////////////////////////////////////////////
-// 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;
-}
-