+++ /dev/null
-# -*- coding: iso-8859-1 -*-
-#----------------------------------------------------------------------------
-# Name: composit.py
-# Purpose: Composite class
-#
-# Author: Pierre Hjälm (from C++ original by Julian Smart)
-#
-# Created: 2004-05-08
-# RCS-ID: $Id$
-# Copyright: (c) 2004 Pierre Hjälm - 1998 Julian Smart
-# Licence: wxWindows license
-#----------------------------------------------------------------------------
-
-from __future__ import division
-
-import sys
-import wx
-
-from basic import RectangleShape, Shape, ControlPoint
-from oglmisc import *
-
-KEY_SHIFT, KEY_CTRL = 1, 2
-
-_objectStartX = 0.0
-_objectStartY = 0.0
-
-CONSTRAINT_CENTRED_VERTICALLY = 1
-CONSTRAINT_CENTRED_HORIZONTALLY = 2
-CONSTRAINT_CENTRED_BOTH = 3
-CONSTRAINT_LEFT_OF = 4
-CONSTRAINT_RIGHT_OF = 5
-CONSTRAINT_ABOVE = 6
-CONSTRAINT_BELOW = 7
-CONSTRAINT_ALIGNED_TOP = 8
-CONSTRAINT_ALIGNED_BOTTOM = 9
-CONSTRAINT_ALIGNED_LEFT = 10
-CONSTRAINT_ALIGNED_RIGHT = 11
-
-# Like aligned, but with the objects centred on the respective edge
-# of the reference object.
-CONSTRAINT_MIDALIGNED_TOP = 12
-CONSTRAINT_MIDALIGNED_BOTTOM = 13
-CONSTRAINT_MIDALIGNED_LEFT = 14
-CONSTRAINT_MIDALIGNED_RIGHT = 15
-
-
-# Backwards compatibility names. These should be removed eventually.
-gyCONSTRAINT_CENTRED_VERTICALLY = CONSTRAINT_CENTRED_VERTICALLY
-gyCONSTRAINT_CENTRED_HORIZONTALLY = CONSTRAINT_CENTRED_HORIZONTALLY
-gyCONSTRAINT_CENTRED_BOTH = CONSTRAINT_CENTRED_BOTH
-gyCONSTRAINT_LEFT_OF = CONSTRAINT_LEFT_OF
-gyCONSTRAINT_RIGHT_OF = CONSTRAINT_RIGHT_OF
-gyCONSTRAINT_ABOVE = CONSTRAINT_ABOVE
-gyCONSTRAINT_BELOW = CONSTRAINT_BELOW
-gyCONSTRAINT_ALIGNED_TOP = CONSTRAINT_ALIGNED_TOP
-gyCONSTRAINT_ALIGNED_BOTTOM = CONSTRAINT_ALIGNED_BOTTOM
-gyCONSTRAINT_ALIGNED_LEFT = CONSTRAINT_ALIGNED_LEFT
-gyCONSTRAINT_ALIGNED_RIGHT = CONSTRAINT_ALIGNED_RIGHT
-gyCONSTRAINT_MIDALIGNED_TOP = CONSTRAINT_MIDALIGNED_TOP
-gyCONSTRAINT_MIDALIGNED_BOTTOM = CONSTRAINT_MIDALIGNED_BOTTOM
-gyCONSTRAINT_MIDALIGNED_LEFT = CONSTRAINT_MIDALIGNED_LEFT
-gyCONSTRAINT_MIDALIGNED_RIGHT = CONSTRAINT_MIDALIGNED_RIGHT
-
-
-
-class ConstraintType(object):
- def __init__(self, theType, theName, thePhrase):
- self._type = theType
- self._name = theName
- self._phrase = thePhrase
-
-
-
-ConstraintTypes = [
- [CONSTRAINT_CENTRED_VERTICALLY,
- ConstraintType(CONSTRAINT_CENTRED_VERTICALLY, "Centre vertically", "centred vertically w.r.t.")],
-
- [CONSTRAINT_CENTRED_HORIZONTALLY,
- ConstraintType(CONSTRAINT_CENTRED_HORIZONTALLY, "Centre horizontally", "centred horizontally w.r.t.")],
-
- [CONSTRAINT_CENTRED_BOTH,
- ConstraintType(CONSTRAINT_CENTRED_BOTH, "Centre", "centred w.r.t.")],
-
- [CONSTRAINT_LEFT_OF,
- ConstraintType(CONSTRAINT_LEFT_OF, "Left of", "left of")],
-
- [CONSTRAINT_RIGHT_OF,
- ConstraintType(CONSTRAINT_RIGHT_OF, "Right of", "right of")],
-
- [CONSTRAINT_ABOVE,
- ConstraintType(CONSTRAINT_ABOVE, "Above", "above")],
-
- [CONSTRAINT_BELOW,
- ConstraintType(CONSTRAINT_BELOW, "Below", "below")],
-
- # Alignment
- [CONSTRAINT_ALIGNED_TOP,
- ConstraintType(CONSTRAINT_ALIGNED_TOP, "Top-aligned", "aligned to the top of")],
-
- [CONSTRAINT_ALIGNED_BOTTOM,
- ConstraintType(CONSTRAINT_ALIGNED_BOTTOM, "Bottom-aligned", "aligned to the bottom of")],
-
- [CONSTRAINT_ALIGNED_LEFT,
- ConstraintType(CONSTRAINT_ALIGNED_LEFT, "Left-aligned", "aligned to the left of")],
-
- [CONSTRAINT_ALIGNED_RIGHT,
- ConstraintType(CONSTRAINT_ALIGNED_RIGHT, "Right-aligned", "aligned to the right of")],
-
- # Mid-alignment
- [CONSTRAINT_MIDALIGNED_TOP,
- ConstraintType(CONSTRAINT_MIDALIGNED_TOP, "Top-midaligned", "centred on the top of")],
-
- [CONSTRAINT_MIDALIGNED_BOTTOM,
- ConstraintType(CONSTRAINT_MIDALIGNED_BOTTOM, "Bottom-midaligned", "centred on the bottom of")],
-
- [CONSTRAINT_MIDALIGNED_LEFT,
- ConstraintType(CONSTRAINT_MIDALIGNED_LEFT, "Left-midaligned", "centred on the left of")],
-
- [CONSTRAINT_MIDALIGNED_RIGHT,
- ConstraintType(CONSTRAINT_MIDALIGNED_RIGHT, "Right-midaligned", "centred on the right of")]
- ]
-
-
-
-
-class Constraint(object):
- """A Constraint object helps specify how child shapes are laid out with
- respect to siblings and parents.
-
- Derived from:
- wxObject
- """
- def __init__(self, type, constraining, constrained):
- self._xSpacing = 0.0
- self._ySpacing = 0.0
-
- self._constraintType = type
- self._constraintingObject = constraining
-
- self._constraintId = 0
- self._constraintName="noname"
-
- self._constrainedObjects = constrained[:]
-
- def __repr__(self):
- return "<%s.%s>" % (self.__class__.__module__, self.__class__.__name__)
-
- def SetSpacing(self, x, y):
- """Sets the horizontal and vertical spacing for the constraint."""
- self._xSpacing = x
- self._ySpacing = y
-
- def Equals(self, a, b):
- """Return TRUE if x and y are approximately equal (for the purposes
- of evaluating the constraint).
- """
- marg = 0.5
-
- return b <= a + marg and b >= a-marg
-
- def Evaluate(self):
- """Evaluate this constraint and return TRUE if anything changed."""
- maxWidth, maxHeight = self._constraintingObject.GetBoundingBoxMax()
- minWidth, minHeight = self._constraintingObject.GetBoundingBoxMin()
- x = self._constraintingObject.GetX()
- y = self._constraintingObject.GetY()
-
- dc = wx.ClientDC(self._constraintingObject.GetCanvas())
- self._constraintingObject.GetCanvas().PrepareDC(dc)
-
- if self._constraintType == CONSTRAINT_CENTRED_VERTICALLY:
- n = len(self._constrainedObjects)
- totalObjectHeight = 0.0
- for constrainedObject in self._constrainedObjects:
- width2, height2 = constrainedObject.GetBoundingBoxMax()
- totalObjectHeight += height2
-
- # Check if within the constraining object...
- if totalObjectHeight + (n + 1) * self._ySpacing <= minHeight:
- spacingY = (minHeight-totalObjectHeight) / (n + 1)
- startY = y-minHeight / 2
- else: # Otherwise, use default spacing
- spacingY = self._ySpacing
- startY = y-(totalObjectHeight + (n + 1) * spacingY) / 2
-
- # Now position the objects
- changed = False
- for constrainedObject in self._constrainedObjects:
- width2, height2 = constrainedObject.GetBoundingBoxMax()
- startY += spacingY + height2 / 2
- if not self.Equals(startY, constrainedObject.GetY()):
- constrainedObject.Move(dc, constrainedObject.GetX(), startY, False)
- changed = True
- startY += height2 / 2
- return changed
- elif self._constraintType == CONSTRAINT_CENTRED_HORIZONTALLY:
- n = len(self._constrainedObjects)
- totalObjectWidth = 0.0
- for constrainedObject in self._constrainedObjects:
- width2, height2 = constrainedObject.GetBoundingBoxMax()
- totalObjectWidth += width2
-
- # Check if within the constraining object...
- if totalObjectWidth + (n + 1) * self._xSpacing<minWidth:
- spacingX = (minWidth-totalObjectWidth) / (n + 1)
- startX = x-minWidth / 2
- else: # Otherwise, use default spacing
- spacingX = self._xSpacing
- startX = x-(totalObjectWidth + (n + 1) * spacingX) / 2
-
- # Now position the objects
- changed = False
- for constrainedObject in self._constrainedObjects:
- width2, height2 = constrainedObject.GetBoundingBoxMax()
- startX += spacingX + width2 / 2
- if not self.Equals(startX, constrainedObject.GetX()):
- constrainedObject.Move(dc, startX, constrainedObject.GetY(), False)
- changed = True
- startX += width2 / 2
- return changed
- elif self._constraintType == CONSTRAINT_CENTRED_BOTH:
- n = len(self._constrainedObjects)
- totalObjectWidth = 0.0
- totalObjectHeight = 0.0
-
- for constrainedObject in self._constrainedObjects:
- width2, height2 = constrainedObject.GetBoundingBoxMax()
- totalObjectWidth += width2
- totalObjectHeight += height2
-
- # Check if within the constraining object...
- if totalObjectHeight + (n + 1) * self._xSpacing <= minWidth:
- spacingX = (minWidth-totalObjectWidth) / (n + 1)
- startX = x-minWidth / 2
- else: # Otherwise, use default spacing
- spacingX = self._xSpacing
- startX = x-(totalObjectWidth + (n + 1) * spacingX) / 2
-
- # Check if within the constraining object...
- if totalObjectHeight + (n + 1) * self._ySpacing <= minHeight:
- spacingY = (minHeight-totalObjectHeight) / (n + 1)
- startY = y-minHeight / 2
- else: # Otherwise, use default spacing
- spacingY = self._ySpacing
- startY = y-(totalObjectHeight + (n + 1) * spacingY) / 2
-
- # Now position the objects
- changed = False
- for constrainedObject in self._constrainedObjects:
- width2, height2 = constrainedObject.GetBoundingBoxMax()
- startX += spacingX + width2 / 2
- startY += spacingY + height2 / 2
-
- if not self.Equals(startX, constrainedObject.GetX()) or not self.Equals(startY, constrainedObject.GetY()):
- constrainedObject.Move(dc, startX, startY, False)
- changed = True
-
- startX += width2 / 2
- startY += height2 / 2
- return changed
- elif self._constraintType == CONSTRAINT_LEFT_OF:
- changed = False
- for constrainedObject in self._constrainedObjects:
- width2, height2 = constrainedObject.GetBoundingBoxMax()
-
- x3 = x-minWidth / 2-width2 / 2-self._xSpacing
- if not self.Equals(x3, constrainedObject.GetX()):
- changed = True
- constrainedObject.Move(dc, x3, constrainedObject.GetY(), False)
- return changed
- elif self._constraintType == CONSTRAINT_RIGHT_OF:
- changed = False
-
- for constrainedObject in self._constrainedObjects:
- width2, height2 = constrainedObject.GetBoundingBoxMax()
- x3 = x + minWidth / 2 + width2 / 2 + self._xSpacing
- if not self.Equals(x3, constrainedObject.GetX()):
- constrainedObject.Move(dc, x3, constrainedObject.GetY(), False)
- changed = True
- return changed
- elif self._constraintType == CONSTRAINT_ABOVE:
- changed = False
-
- for constrainedObject in self._constrainedObjects:
- width2, height2 = constrainedObject.GetBoundingBoxMax()
-
- y3 = y-minHeight / 2-height2 / 2-self._ySpacing
- if not self.Equals(y3, constrainedObject.GetY()):
- changed = True
- constrainedObject.Move(dc, constrainedObject.GetX(), y3, False)
- return changed
- elif self._constraintType == CONSTRAINT_BELOW:
- changed = False
-
- for constrainedObject in self._constrainedObjects:
- width2, height2 = constrainedObject.GetBoundingBoxMax()
-
- y3 = y + minHeight / 2 + height2 / 2 + self._ySpacing
- if not self.Equals(y3, constrainedObject.GetY()):
- changed = True
- constrainedObject.Move(dc, constrainedObject.GetX(), y3, False)
- return changed
- elif self._constraintType == CONSTRAINT_ALIGNED_LEFT:
- changed = False
- for constrainedObject in self._constrainedObjects:
- width2, height2 = constrainedObject.GetBoundingBoxMax()
- x3 = x-minWidth / 2 + width2 / 2 + self._xSpacing
- if not self.Equals(x3, constrainedObject.GetX()):
- changed = True
- constrainedObject.Move(dc, x3, constrainedObject.GetY(), False)
- return changed
- elif self._constraintType == CONSTRAINT_ALIGNED_RIGHT:
- changed = False
- for constrainedObject in self._constrainedObjects:
- width2, height2 = constrainedObject.GetBoundingBoxMax()
- x3 = x + minWidth / 2-width2 / 2-self._xSpacing
- if not self.Equals(x3, constrainedObject.GetX()):
- changed = True
- constrainedObject.Move(dc, x3, constrainedObject.GetY(), False)
- return changed
- elif self._constraintType == CONSTRAINT_ALIGNED_TOP:
- changed = False
- for constrainedObject in self._constrainedObjects:
- width2, height2 = constrainedObject.GetBoundingBoxMax()
- y3 = y-minHeight / 2 + height2 / 2 + self._ySpacing
- if not self.Equals(y3, constrainedObject.GetY()):
- changed = True
- constrainedObject.Move(dc, constrainedObject.GetX(), y3, False)
- return changed
- elif self._constraintType == CONSTRAINT_ALIGNED_BOTTOM:
- changed = False
- for constrainedObject in self._constrainedObjects:
- width2, height2 = constrainedObject.GetBoundingBoxMax()
- y3 = y + minHeight / 2-height2 / 2-self._ySpacing
- if not self.Equals(y3, constrainedObject.GetY()):
- changed = True
- constrainedObject.Move(dc, constrainedObject.GetX(), y3, False)
- return changed
- elif self._constraintType == CONSTRAINT_MIDALIGNED_LEFT:
- changed = False
- for constrainedObject in self._constrainedObjects:
- x3 = x-minWidth / 2
- if not self.Equals(x3, constrainedObject.GetX()):
- changed = True
- constrainedObject.Move(dc, x3, constrainedObject.GetY(), False)
- return changed
- elif self._constraintType == CONSTRAINT_MIDALIGNED_RIGHT:
- changed = False
- for constrainedObject in self._constrainedObjects:
- x3 = x + minWidth / 2
- if not self.Equals(x3, constrainedObject.GetX()):
- changed = True
- constrainedObject.Move(dc, x3, constrainedObject.GetY(), False)
- return changed
- elif self._constraintType == CONSTRAINT_MIDALIGNED_TOP:
- changed = False
- for constrainedObject in self._constrainedObjects:
- y3 = y-minHeight / 2
- if not self.Equals(y3, constrainedObject.GetY()):
- changed = True
- constrainedObject.Move(dc, constrainedObject.GetX(), y3, False)
- return changed
- elif self._constraintType == CONSTRAINT_MIDALIGNED_BOTTOM:
- changed = False
- for constrainedObject in self._constrainedObjects:
- y3 = y + minHeight / 2
- if not self.Equals(y3, constrainedObject.GetY()):
- changed = True
- constrainedObject.Move(dc, constrainedObject.GetX(), y3, False)
- return changed
-
- return False
-
-OGLConstraint = wx._core._deprecated(Constraint,
- "The OGLConstraint name is deprecated, use `ogl.Constraint` instead.")
-
-
-class CompositeShape(RectangleShape):
- """This is an object with a list of child objects, and a list of size
- and positioning constraints between the children.
-
- Derived from:
- wxRectangleShape
- """
- def __init__(self):
- RectangleShape.__init__(self, 100.0, 100.0)
-
- self._oldX = self._xpos
- self._oldY = self._ypos
-
- self._constraints = []
- self._divisions = [] # In case it's a container
-
- def OnDraw(self, dc):
- x1 = self._xpos-self._width / 2
- y1 = self._ypos-self._height / 2
-
- if self._shadowMode != SHADOW_NONE:
- if self._shadowBrush:
- dc.SetBrush(self._shadowBrush)
- dc.SetPen(wx.Pen(wx.WHITE, 1, wx.TRANSPARENT))
-
- if self._cornerRadius:
- dc.DrawRoundedRectangle(x1 + self._shadowOffsetX, y1 + self._shadowOffsetY, self._width, self._height, self._cornerRadius)
- else:
- dc.DrawRectangle(x1 + self._shadowOffsetX, y1 + self._shadowOffsetY, self._width, self._height)
-
- # For debug purposes /pi
- #dc.DrawRectangle(x1, y1, self._width, self._height)
-
- def OnDrawContents(self, dc):
- for object in self._children:
- object.Draw(dc)
- object.DrawLinks(dc)
-
- Shape.OnDrawContents(self, dc)
-
- def OnMovePre(self, dc, x, y, old_x, old_y, display = True):
- diffX = x-old_x
- diffY = y-old_y
-
- for object in self._children:
- object.Erase(dc)
- object.Move(dc, object.GetX() + diffX, object.GetY() + diffY, display)
-
- return True
-
- def OnErase(self, dc):
- RectangleShape.OnErase(self, dc)
- for object in self._children:
- object.Erase(dc)
-
- def OnDragLeft(self, draw, x, y, keys = 0, attachment = 0):
- xx, yy = self._canvas.Snap(x, y)
- offsetX = xx - _objectStartX
- offsetY = yy - _objectStartY
-
- dc = wx.ClientDC(self.GetCanvas())
- self.GetCanvas().PrepareDC(dc)
-
- dc.SetLogicalFunction(OGLRBLF)
- dottedPen = wx.Pen(wx.Colour(0, 0, 0), 1, wx.DOT)
- dc.SetPen(dottedPen)
- dc.SetBrush(wx.TRANSPARENT_BRUSH)
-
- self.GetEventHandler().OnDrawOutline(dc, self.GetX() + offsetX, self.GetY() + offsetY, self.GetWidth(), self.GetHeight())
-
- def OnBeginDragLeft(self, x, y, keys = 0, attachment = 0):
- global _objectStartX, _objectStartY
-
- _objectStartX = x
- _objectStartY = y
-
- dc = wx.ClientDC(self.GetCanvas())
- self.GetCanvas().PrepareDC(dc)
-
- #self.Erase(dc)
-
- dc.SetLogicalFunction(OGLRBLF)
- dottedPen = wx.Pen(wx.Colour(0, 0, 0), 1, wx.DOT)
- dc.SetPen(dottedPen)
- dc.SetBrush(wx.TRANSPARENT_BRUSH)
- self._canvas.CaptureMouse()
-
- xx, yy = self._canvas.Snap(x, y)
- offsetX = xx - _objectStartX
- offsetY = yy - _objectStartY
-
- self.GetEventHandler().OnDrawOutline(dc, self.GetX() + offsetX, self.GetY() + offsetY, self.GetWidth(), self.GetHeight())
-
- def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
- dc = wx.ClientDC(self.GetCanvas())
- self.GetCanvas().PrepareDC(dc)
-
- if self._canvas.HasCapture():
- self._canvas.ReleaseMouse()
-
- if not self._draggable:
- if self._parent:
- self._parent.GetEventHandler().OnEndDragLeft(x, y, keys, 0)
- return
-
- self.Erase(dc)
-
- dc.SetLogicalFunction(wx.COPY)
-
- xx, yy = self._canvas.Snap(x, y)
- offsetX = xx - _objectStartX
- offsetY = yy - _objectStartY
-
- self.Move(dc, self.GetX() + offsetX, self.GetY() + offsetY)
-
- if self._canvas and not self._canvas.GetQuickEditMode():
- self._canvas.Redraw(dc)
-
- def OnRightClick(self, x, y, keys = 0, attachment = 0):
- # 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:
- for division in self._divisions:
- hit = division.HitTest(x, y)
- if hit:
- division.GetEventHandler().OnRightClick(x, y, keys, hit[0])
- break
-
- def SetSize(self, w, h, recursive = True):
- self.SetAttachmentSize(w, h)
-
- xScale = w / max(1, self.GetWidth())
- yScale = h / max(1, self.GetHeight())
-
- self._width = w
- self._height = h
-
- if not recursive:
- return
-
- dc = wx.ClientDC(self.GetCanvas())
- self.GetCanvas().PrepareDC(dc)
-
- for object in self._children:
- # Scale the position first
- newX = (object.GetX()-self.GetX()) * xScale + self.GetX()
- newY = (object.GetY()-self.GetY()) * yScale + self.GetY()
- object.Show(False)
- object.Move(dc, newX, newY)
- object.Show(True)
-
- # Now set the scaled size
- xbound, ybound = object.GetBoundingBoxMax()
- if not object.GetFixedWidth():
- xbound *= xScale
- if not object.GetFixedHeight():
- ybound *= yScale
- object.SetSize(xbound, ybound)
-
- self.SetDefaultRegionSize()
-
- def AddChild(self, child, addAfter = None):
- """Adds a child shape to the composite.
-
- If addAfter is not None, the shape will be added after this shape.
- """
- self._children.append(child)
- child.SetParent(self)
- if self._canvas:
- # Ensure we add at the right position
- if addAfter:
- child.RemoveFromCanvas(self._canvas)
- child.AddToCanvas(self._canvas, addAfter)
-
- def RemoveChild(self, child):
- """Removes the child from the composite and any constraint
- relationships, but does not delete the child.
- """
- self._children.remove(child)
- self._divisions.remove(child)
- self.RemoveChildFromConstraints(child)
- child.SetParent(None)
-
- def DeleteConstraintsInvolvingChild(self, child):
- """This function deletes constraints which mention the given child.
-
- Used when deleting a child from the composite.
- """
- for constraint in self._constraints:
- if constraint._constrainingObject == child or child in constraint._constrainedObjects:
- self._constraints.remove(constraint)
-
- def RemoveChildFromConstraints(self, child):
- for constraint in self._constraints:
- if child in constraint._constrainedObjects:
- constraint._constrainedObjects.remove(child)
- if constraint._constrainingObject == child:
- constraint._constrainingObject = None
-
- # Delete the constraint if no participants left
- if not constraint._constrainingObject:
- self._constraints.remove(constraint)
-
- def AddConstraint(self, constraint):
- """Adds a constraint to the composite."""
- self._constraints.append(constraint)
- if constraint._constraintId == 0:
- constraint._constraintId = wx.NewId()
- return constraint
-
- def AddSimpleConstraint(self, type, constraining, constrained):
- """Add a constraint of the given type to the composite.
-
- constraining is the shape doing the constraining
- constrained is a list of shapes being constrained
- """
- constraint = Constraint(type, constraining, constrained)
- if constraint._constraintId == 0:
- constraint._constraintId = wx.NewId()
- self._constraints.append(constraint)
- return constraint
-
- def FindConstraint(self, cId):
- """Finds the constraint with the given id.
-
- Returns a tuple of the constraint and the actual composite the
- constraint was in, in case that composite was a descendant of
- this composit.
-
- Returns None if not found.
- """
- for constraint in self._constraints:
- if constraint._constraintId == cId:
- return constraint, self
-
- # If not found, try children
- for child in self._children:
- if isinstance(child, CompositeShape):
- constraint = child.FindConstraint(cId)
- if constraint:
- return constraint[0], child
-
- return None
-
- def DeleteConstraint(self, constraint):
- """Deletes constraint from composite."""
- self._constraints.remove(constraint)
-
- def CalculateSize(self):
- """Calculates the size and position of the composite based on
- child sizes and positions.
- """
- maxX=-999999.9
- maxY=-999999.9
- minX = 999999.9
- minY = 999999.9
-
- for child in self._children:
- # Recalculate size of composite objects because may not conform
- # to size it was set to - depends on the children.
- if isinstance(child, CompositeShape):
- child.CalculateSize()
-
- w, h = child.GetBoundingBoxMax()
- if child.GetX() + w / 2>maxX:
- maxX = child.GetX() + w / 2
- if child.GetX()-w / 2<minX:
- minX = child.GetX()-w / 2
- if child.GetY() + h / 2>maxY:
- maxY = child.GetY() + h / 2
- if child.GetY()-h / 2<minY:
- minY = child.GetY()-h / 2
-
- self._width = maxX-minX
- self._height = maxY-minY
- self._xpos = self._width / 2 + minX
- self._ypos = self._height / 2 + minY
-
- def Recompute(self):
- """Recomputes any constraints associated with the object. If FALSE is
- returned, the constraints could not be satisfied (there was an
- inconsistency).
- """
- noIterations = 0
- changed = True
- while changed and noIterations<500:
- changed = self.Constrain()
- noIterations += 1
-
- return not changed
-
- def Constrain(self):
- self.CalculateSize()
-
- changed = False
- for child in self._children:
- if isinstance(child, CompositeShape) and child.Constrain():
- changed = True
-
- for constraint in self._constraints:
- if constraint.Evaluate():
- changed = True
-
- return changed
-
- def MakeContainer(self):
- """Makes this composite into a container by creating one child
- DivisionShape.
- """
- division = self.OnCreateDivision()
- self._divisions.append(division)
- self.AddChild(division)
-
- division.SetSize(self._width, self._height)
-
- dc = wx.ClientDC(self.GetCanvas())
- self.GetCanvas().PrepareDC(dc)
-
- division.Move(dc, self.GetX(), self.GetY())
- self.Recompute()
- division.Show(True)
-
- def OnCreateDivision(self):
- return DivisionShape()
-
- def FindContainerImage(self):
- """Finds the image used to visualize a container. This is any child of
- the composite that is not in the divisions list.
- """
- for child in self._children:
- if child in self._divisions:
- return child
-
- return None
-
- def ContainsDivision(self, division):
- """Returns TRUE if division is a descendant of this container."""
- if division in self._divisions:
- return True
-
- for child in self._children:
- if isinstance(child, CompositeShape):
- return child.ContainsDivision(division)
-
- return False
-
- def GetDivisions(self):
- """Return the list of divisions."""
- return self._divisions
-
- def GetConstraints(self):
- """Return the list of constraints."""
- return self._constraints
-
-
-# A division object is a composite with special properties,
-# to be used for containment. It's a subdivision of a container.
-# A containing node image consists of a composite with a main child shape
-# such as rounded rectangle, plus a list of division objects.
-# It needs to be a composite because a division contains pieces
-# of diagram.
-# NOTE a container has at least one wxDivisionShape for consistency.
-# This can be subdivided, so it turns into two objects, then each of
-# these can be subdivided, etc.
-
-DIVISION_SIDE_NONE =0
-DIVISION_SIDE_LEFT =1
-DIVISION_SIDE_TOP =2
-DIVISION_SIDE_RIGHT =3
-DIVISION_SIDE_BOTTOM =4
-
-originalX = 0.0
-originalY = 0.0
-originalW = 0.0
-originalH = 0.0
-
-
-
-class DivisionControlPoint(ControlPoint):
- def __init__(self, the_canvas, object, size, the_xoffset, the_yoffset, the_type):
- ControlPoint.__init__(self, the_canvas, object, size, the_xoffset, the_yoffset, the_type)
- self.SetEraseObject(False)
-
- # Implement resizing of canvas object
- def OnDragLeft(self, draw, x, y, keys = 0, attachment = 0):
- ControlPoint.OnDragLeft(self, draw, x, y, keys, attachment)
-
- def OnBeginDragLeft(self, x, y, keys = 0, attachment = 0):
- global originalX, originalY, originalW, originalH
-
- originalX = self._shape.GetX()
- originalY = self._shape.GetY()
- originalW = self._shape.GetWidth()
- originalH = self._shape.GetHeight()
-
- ControlPoint.OnBeginDragLeft(self, x, y, keys, attachment)
-
- def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
- ControlPoint.OnEndDragLeft(self, x, y, keys, attachment)
-
- dc = wx.ClientDC(self.GetCanvas())
- self.GetCanvas().PrepareDC(dc)
-
- division = self._shape
- divisionParent = division.GetParent()
-
- # Need to check it's within the bounds of the parent composite
- x1 = divisionParent.GetX()-divisionParent.GetWidth() / 2
- y1 = divisionParent.GetY()-divisionParent.GetHeight() / 2
- x2 = divisionParent.GetX() + divisionParent.GetWidth() / 2
- y2 = divisionParent.GetY() + divisionParent.GetHeight() / 2
-
- # Need to check it has not made the division zero or negative
- # width / height
- dx1 = division.GetX()-division.GetWidth() / 2
- dy1 = division.GetY()-division.GetHeight() / 2
- dx2 = division.GetX() + division.GetWidth() / 2
- dy2 = division.GetY() + division.GetHeight() / 2
-
- success = True
- if division.GetHandleSide() == DIVISION_SIDE_LEFT:
- if x <= x1 or x >= x2 or x >= dx2:
- success = False
- # Try it out first...
- elif not division.ResizeAdjoining(DIVISION_SIDE_LEFT, x, True):
- success = False
- else:
- division.ResizeAdjoining(DIVISION_SIDE_LEFT, x, False)
- elif division.GetHandleSide() == DIVISION_SIDE_TOP:
- if y <= y1 or y >= y2 or y >= dy2:
- success = False
- elif not division.ResizeAdjoining(DIVISION_SIDE_TOP, y, True):
- success = False
- else:
- division.ResizingAdjoining(DIVISION_SIDE_TOP, y, False)
- elif division.GetHandleSide() == DIVISION_SIDE_RIGHT:
- if x <= x1 or x >= x2 or x <= dx1:
- success = False
- elif not division.ResizeAdjoining(DIVISION_SIDE_RIGHT, x, True):
- success = False
- else:
- division.ResizeAdjoining(DIVISION_SIDE_RIGHT, x, False)
- elif division.GetHandleSide() == DIVISION_SIDE_BOTTOM:
- if y <= y1 or y >= y2 or y <= dy1:
- success = False
- elif not division.ResizeAdjoining(DIVISION_SIDE_BOTTOM, y, True):
- success = False
- else:
- division.ResizeAdjoining(DIVISION_SIDE_BOTTOM, y, False)
-
- if not success:
- division.SetSize(originalW, originalH)
- division.Move(dc, originalX, originalY)
-
- divisionParent.Draw(dc)
- division.GetEventHandler().OnDrawControlPoints(dc)
-
-
-
-DIVISION_MENU_SPLIT_HORIZONTALLY =1
-DIVISION_MENU_SPLIT_VERTICALLY =2
-DIVISION_MENU_EDIT_LEFT_EDGE =3
-DIVISION_MENU_EDIT_TOP_EDGE =4
-DIVISION_MENU_EDIT_RIGHT_EDGE =5
-DIVISION_MENU_EDIT_BOTTOM_EDGE =6
-DIVISION_MENU_DELETE_ALL =7
-
-
-
-class PopupDivisionMenu(wx.Menu):
- def __init__(self):
- wx.Menu.__init__(self)
- self.Append(DIVISION_MENU_SPLIT_HORIZONTALLY,"Split horizontally")
- self.Append(DIVISION_MENU_SPLIT_VERTICALLY,"Split vertically")
- self.AppendSeparator()
- self.Append(DIVISION_MENU_EDIT_LEFT_EDGE,"Edit left edge")
- self.Append(DIVISION_MENU_EDIT_TOP_EDGE,"Edit top edge")
-
- wx.EVT_MENU_RANGE(self, DIVISION_MENU_SPLIT_HORIZONTALLY, DIVISION_MENU_EDIT_BOTTOM_EDGE, self.OnMenu)
-
- def SetClientData(self, data):
- self._clientData = data
-
- def GetClientData(self):
- return self._clientData
-
- def OnMenu(self, event):
- division = self.GetClientData()
- if event.GetId() == DIVISION_MENU_SPLIT_HORIZONTALLY:
- division.Divide(wx.HORIZONTAL)
- elif event.GetId() == DIVISION_MENU_SPLIT_VERTICALLY:
- division.Divide(wx.VERTICAL)
- elif event.GetId() == DIVISION_MENU_EDIT_LEFT_EDGE:
- division.EditEdge(DIVISION_SIDE_LEFT)
- elif event.GetId() == DIVISION_MENU_EDIT_TOP_EDGE:
- division.EditEdge(DIVISION_SIDE_TOP)
-
-
-
-class DivisionShape(CompositeShape):
- """A division shape is like a composite in that it can contain further
- objects, but is used exclusively to divide another shape into regions,
- or divisions. A wxDivisionShape is never free-standing.
-
- Derived from:
- wxCompositeShape
- """
- def __init__(self):
- CompositeShape.__init__(self)
- self.SetSensitivityFilter(OP_CLICK_LEFT | OP_CLICK_RIGHT | OP_DRAG_RIGHT)
- self.SetCentreResize(False)
- self.SetAttachmentMode(True)
- self._leftSide = None
- self._rightSide = None
- self._topSide = None
- self._bottomSide = None
- self._handleSide = DIVISION_SIDE_NONE
- self._leftSidePen = wx.BLACK_PEN
- self._topSidePen = wx.BLACK_PEN
- self._leftSideColour="BLACK"
- self._topSideColour="BLACK"
- self._leftSideStyle="Solid"
- self._topSideStyle="Solid"
- self.ClearRegions()
-
- def SetLeftSide(self, shape):
- """Set the the division on the left side of this division."""
- self._leftSide = shape
-
- def SetTopSide(self, shape):
- """Set the the division on the top side of this division."""
- self._topSide = shape
-
- def SetRightSide(self, shape):
- """Set the the division on the right side of this division."""
- self._rightSide = shape
-
- def SetBottomSide(self, shape):
- """Set the the division on the bottom side of this division."""
- self._bottomSide = shape
-
- def GetLeftSide(self):
- """Return the division on the left side of this division."""
- return self._leftSide
-
- def GetTopSide(self):
- """Return the division on the top side of this division."""
- return self._topSide
-
- def GetRightSide(self):
- """Return the division on the right side of this division."""
- return self._rightSide
-
- def GetBottomSide(self):
- """Return the division on the bottom side of this division."""
- return self._bottomSide
-
- def SetHandleSide(self, side):
- """Sets the side which the handle appears on.
-
- Either DIVISION_SIDE_LEFT or DIVISION_SIDE_TOP.
- """
- self._handleSide = side
-
- def GetHandleSide(self):
- """Return the side which the handle appears on."""
- return self._handleSide
-
- def SetLeftSidePen(self, pen):
- """Set the colour for drawing the left side of the division."""
- self._leftSidePen = pen
-
- def SetTopSidePen(self, pen):
- """Set the colour for drawing the top side of the division."""
- self._topSidePen = pen
-
- def GetLeftSidePen(self):
- """Return the pen used for drawing the left side of the division."""
- return self._leftSidePen
-
- def GetTopSidePen(self):
- """Return the pen used for drawing the top side of the division."""
- return self._topSidePen
-
- def GetLeftSideColour(self):
- """Return the colour used for drawing the left side of the division."""
- return self._leftSideColour
-
- def GetTopSideColour(self):
- """Return the colour used for drawing the top side of the division."""
- return self._topSideColour
-
- def SetLeftSideColour(self, colour):
- """Set the colour for drawing the left side of the division."""
- self._leftSideColour = colour
-
- def SetTopSideColour(self, colour):
- """Set the colour for drawing the top side of the division."""
- self._topSideColour = colour
-
- def GetLeftSideStyle(self):
- """Return the style used for the left side of the division."""
- return self._leftSideStyle
-
- def GetTopSideStyle(self):
- """Return the style used for the top side of the division."""
- return self._topSideStyle
-
- def SetLeftSideStyle(self, style):
- self._leftSideStyle = style
-
- def SetTopSideStyle(self, style):
- self._lefttopStyle = style
-
- def OnDraw(self, dc):
- dc.SetBrush(wx.TRANSPARENT_BRUSH)
- dc.SetBackgroundMode(wx.TRANSPARENT)
-
- x1 = self.GetX()-self.GetWidth() / 2
- y1 = self.GetY()-self.GetHeight() / 2
- x2 = self.GetX() + self.GetWidth() / 2
- y2 = self.GetY() + self.GetHeight() / 2
-
- # Should subtract 1 pixel if drawing under Windows
- if sys.platform[:3]=="win":
- y2 -= 1
-
- if self._leftSide:
- dc.SetPen(self._leftSidePen)
- dc.DrawLine(x1, y2, x1, y1)
-
- if self._topSide:
- dc.SetPen(self._topSidePen)
- dc.DrawLine(x1, y1, x2, y1)
-
- # For testing purposes, draw a rectangle so we know
- # how big the division is.
- #dc.SetBrush(wx.RED_BRUSH)
- #dc.DrawRectangle(x1, y1, self.GetWidth(), self.GetHeight())
-
- def OnDrawContents(self, dc):
- CompositeShape.OnDrawContents(self, dc)
-
- def OnMovePre(self, dc, x, y, oldx, oldy, display = True):
- diffX = x-oldx
- diffY = y-oldy
- for object in self._children:
- object.Erase(dc)
- object.Move(dc, object.GetX() + diffX, object.GetY() + diffY, display)
- return True
-
- def OnDragLeft(self, draw, x, y, keys = 0, attachment = 0):
- if self._sensitivity & OP_DRAG_LEFT != OP_DRAG_LEFT:
- if self._parent:
- hit = self._parent.HitTest(x, y)
- if hit:
- attachment, dist = hit
- self._parent.GetEventHandler().OnDragLeft(draw, x, y, keys, attachment)
- return
- Shape.OnDragLeft(self, draw, x, y, keys, attachment)
-
- def OnBeginDragLeft(self, x, y, keys = 0, attachment = 0):
- if self._sensitivity & OP_DRAG_LEFT != OP_DRAG_LEFT:
- if self._parent:
- hit = self._parent.HitTest(x, y)
- if hit:
- attachment, dist = hit
- self._parent.GetEventHandler().OnBeginDragLeft(x, y, keys, attachment)
- return
- Shape.OnBeginDragLeft(x, y, keys, attachment)
-
- def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
- if self._canvas.HasCapture():
- self._canvas.ReleaseMouse()
- if self._sensitivity & OP_DRAG_LEFT != OP_DRAG_LEFT:
- if self._parent:
- hit = self._parent.HitTest(x, y)
- if hit:
- attachment, dist = hit
- self._parent.GetEventHandler().OnEndDragLeft(x, y, keys, attachment)
- return
-
- dc = wx.ClientDC(self.GetCanvas())
- self.GetCanvas().PrepareDC(dc)
-
- dc.SetLogicalFunction(wx.COPY)
-
- self._xpos, self._ypos = self._canvas.Snap(self._xpos, self._ypos)
- self.GetEventHandler().OnMovePre(dc, x, y, self._oldX, self._oldY)
-
- self.ResetControlPoints()
- self.Draw(dc)
- self.MoveLinks(dc)
- self.GetEventHandler().OnDrawControlPoints(dc)
-
- if self._canvas and not self._canvas.GetQuickEditMode():
- self._canvas.Redraw(dc)
-
- def SetSize(self, w, h, recursive = True):
- self._width = w
- self._height = h
- RectangleShape.SetSize(self, w, h, recursive)
-
- def CalculateSize(self):
- pass
-
- # Experimental
- def OnRightClick(self, x, y, keys = 0, attachment = 0):
- if keys & KEY_CTRL:
- self.PopupMenu(x, y)
- else:
- if self._parent:
- hit = self._parent.HitTest(x, y)
- if hit:
- attachment, dist = hit
- self._parent.GetEventHandler().OnRightClick(x, y, keys, attachment)
-
- # Divide wx.HORIZONTALly or wx.VERTICALly
- def Divide(self, direction):
- """Divide this division into two further divisions,
- horizontally (direction is wxHORIZONTAL) or
- vertically (direction is wxVERTICAL).
- """
- # Calculate existing top-left, bottom-right
- x1 = self.GetX()-self.GetWidth() / 2
- y1 = self.GetY()-self.GetHeight() / 2
-
- compositeParent = self.GetParent()
- oldWidth = self.GetWidth()
- oldHeight = self.GetHeight()
- if self.Selected():
- self.Select(False)
-
- dc = wx.ClientDC(self.GetCanvas())
- self.GetCanvas().PrepareDC(dc)
-
- if direction == wx.VERTICAL:
- # Dividing vertically means notionally putting a horizontal
- # line through it.
- # Break existing piece into two.
- newXPos1 = self.GetX()
- newYPos1 = y1 + self.GetHeight() / 4
- newXPos2 = self.GetX()
- newYPos2 = y1 + 3 * self.GetHeight() / 4
- newDivision = compositeParent.OnCreateDivision()
- newDivision.Show(True)
-
- self.Erase(dc)
-
- # Anything adjoining the bottom of this division now adjoins the
- # bottom of the new division.
- for obj in compositeParent.GetDivisions():
- if obj.GetTopSide() == self:
- obj.SetTopSide(newDivision)
-
- newDivision.SetTopSide(self)
- newDivision.SetBottomSide(self._bottomSide)
- newDivision.SetLeftSide(self._leftSide)
- newDivision.SetRightSide(self._rightSide)
- self._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())
-
- self._handleSide = DIVISION_SIDE_BOTTOM
- newDivision.SetHandleSide(DIVISION_SIDE_TOP)
-
- self.SetSize(oldWidth, oldHeight / 2)
- self.Move(dc, newXPos1, newYPos1)
-
- newDivision.SetSize(oldWidth, oldHeight / 2)
- newDivision.Move(dc, newXPos2, newYPos2)
- else:
- # Dividing horizontally means notionally putting a vertical line
- # through it.
- # Break existing piece into two.
- newXPos1 = x1 + self.GetWidth() / 4
- newYPos1 = self.GetY()
- newXPos2 = x1 + 3 * self.GetWidth() / 4
- newYPos2 = self.GetY()
- newDivision = compositeParent.OnCreateDivision()
- newDivision.Show(True)
-
- self.Erase(dc)
-
- # Anything adjoining the left of this division now adjoins the
- # left of the new division.
- for obj in compositeParent.GetDivisions():
- if obj.GetLeftSide() == self:
- obj.SetLeftSide(newDivision)
-
- newDivision.SetTopSide(self._topSide)
- newDivision.SetBottomSide(self._bottomSide)
- newDivision.SetLeftSide(self)
- newDivision.SetRightSide(self._rightSide)
- self._rightSide = newDivision
-
- compositeParent.GetDivisions().append(newDivision)
- compositeParent.AddChild(newDivision, compositeParent.FindContainerImage())
-
- self._handleSide = DIVISION_SIDE_RIGHT
- newDivision.SetHandleSide(DIVISION_SIDE_LEFT)
-
- self.SetSize(oldWidth / 2, oldHeight)
- self.Move(dc, newXPos1, newYPos1)
-
- newDivision.SetSize(oldWidth / 2, oldHeight)
- newDivision.Move(dc, newXPos2, newYPos2)
-
- if compositeParent.Selected():
- compositeParent.DeleteControlPoints(dc)
- compositeParent.MakeControlPoints()
- compositeParent.MakeMandatoryControlPoints()
-
- compositeParent.Draw(dc)
- return True
-
- def MakeControlPoints(self):
- self.MakeMandatoryControlPoints()
-
- def MakeMandatoryControlPoints(self):
- maxX, maxY = self.GetBoundingBoxMax()
- x = y = 0.0
- direction = 0
-
- if self._handleSide == DIVISION_SIDE_LEFT:
- x=-maxX / 2
- direction = CONTROL_POINT_HORIZONTAL
- elif self._handleSide == DIVISION_SIDE_TOP:
- y=-maxY / 2
- direction = CONTROL_POINT_VERTICAL
- elif self._handleSide == DIVISION_SIDE_RIGHT:
- x = maxX / 2
- direction = CONTROL_POINT_HORIZONTAL
- elif self._handleSide == DIVISION_SIDE_BOTTOM:
- y = maxY / 2
- direction = CONTROL_POINT_VERTICAL
-
- if self._handleSide != DIVISION_SIDE_NONE:
- control = DivisionControlPoint(self._canvas, self, CONTROL_POINT_SIZE, x, y, direction)
- self._canvas.AddShape(control)
- self._controlPoints.append(control)
-
- def ResetControlPoints(self):
- self.ResetMandatoryControlPoints()
-
- def ResetMandatoryControlPoints(self):
- if not self._controlPoints:
- return
-
- maxX, maxY = self.GetBoundingBoxMax()
-
- node = self._controlPoints[0]
-
- if self._handleSide == DIVISION_SIDE_LEFT and node:
- node._xoffset=-maxX / 2
- node._yoffset = 0.0
-
- if self._handleSide == DIVISION_SIDE_TOP and node:
- node._xoffset = 0.0
- node._yoffset=-maxY / 2
-
- if self._handleSide == DIVISION_SIDE_RIGHT and node:
- node._xoffset = maxX / 2
- node._yoffset = 0.0
-
- if self._handleSide == DIVISION_SIDE_BOTTOM and node:
- node._xoffset = 0.0
- node._yoffset = maxY / 2
-
- def AdjustLeft(self, left, test):
- """Adjust a side.
-
- Returns FALSE if it's not physically possible to adjust it to
- this point.
- """
- x2 = self.GetX() + self.GetWidth() / 2
-
- if left >= x2:
- return False
-
- if test:
- return True
-
- newW = x2-left
- newX = left + newW / 2
- self.SetSize(newW, self.GetHeight())
-
- dc = wx.ClientDC(self.GetCanvas())
- self.GetCanvas().PrepareDC(dc)
-
- self.Move(dc, newX, self.GetY())
- return True
-
- def AdjustTop(self, top, test):
- """Adjust a side.
-
- Returns FALSE if it's not physically possible to adjust it to
- this point.
- """
- y2 = self.GetY() + self.GetHeight() / 2
-
- if top >= y2:
- return False
-
- if test:
- return True
-
- newH = y2-top
- newY = top + newH / 2
- self.SetSize(self.GetWidth(), newH)
-
- dc = wx.ClientDC(self.GetCanvas())
- self.GetCanvas().PrepareDC(dc)
-
- self.Move(dc, self.GetX(), newY)
- return True
-
- def AdjustRight(self, right, test):
- """Adjust a side.
-
- Returns FALSE if it's not physically possible to adjust it to
- this point.
- """
- x1 = self.GetX()-self.GetWidth() / 2
-
- if right <= x1:
- return False
-
- if test:
- return True
-
- newW = right-x1
- newX = x1 + newW / 2
- self.SetSize(newW, self.GetHeight())
-
- dc = wx.ClientDC(self.GetCanvas())
- self.GetCanvas().PrepareDC(dc)
-
- self.Move(dc, newX, self.GetY())
- return True
-
- def AdjustTop(self, top, test):
- """Adjust a side.
-
- Returns FALSE if it's not physically possible to adjust it to
- this point.
- """
- y1 = self.GetY()-self.GetHeight() / 2
-
- if bottom <= y1:
- return False
-
- if test:
- return True
-
- newH = bottom-y1
- newY = y1 + newH / 2
- self.SetSize(self.GetWidth(), newH)
-
- dc = wx.ClientDC(self.GetCanvas())
- self.GetCanvas().PrepareDC(dc)
-
- self.Move(dc, self.GetX(), newY)
- return True
-
- # 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.
- #
- def ResizeAdjoining(self, side, newPos, test):
- """Resize adjoining divisions at the given side.
-
- If test is TRUE, just see whether it's possible for each adjoining
- region, returning FALSE if it's not.
-
- side can be one of:
-
- * DIVISION_SIDE_NONE
- * DIVISION_SIDE_LEFT
- * DIVISION_SIDE_TOP
- * DIVISION_SIDE_RIGHT
- * DIVISION_SIDE_BOTTOM
- """
- divisionParent = self.GetParent()
- for division in divisionParent.GetDivisions():
- if side == DIVISION_SIDE_LEFT:
- if division._rightSide == self:
- success = division.AdjustRight(newPos, test)
- if not success and test:
- return false
- elif side == DIVISION_SIDE_TOP:
- if division._bottomSide == self:
- success = division.AdjustBottom(newPos, test)
- if not success and test:
- return False
- elif side == DIVISION_SIDE_RIGHT:
- if division._leftSide == self:
- success = division.AdjustLeft(newPos, test)
- if not success and test:
- return False
- elif side == DIVISION_SIDE_BOTTOM:
- if division._topSide == self:
- success = division.AdjustTop(newPos, test)
- if not success and test:
- return False
- return True
-
- def EditEdge(self, side):
- print "EditEdge() not implemented."
-
- def PopupMenu(self, x, y):
- menu = PopupDivisionMenu()
- menu.SetClientData(self)
- if self._leftSide:
- menu.Enable(DIVISION_MENU_EDIT_LEFT_EDGE, True)
- else:
- menu.Enable(DIVISION_MENU_EDIT_LEFT_EDGE, False)
- if self._topSide:
- menu.Enable(DIVISION_MENU_EDIT_TOP_EDGE, True)
- else:
- menu.Enable(DIVISION_MENU_EDIT_TOP_EDGE, False)
-
- x1, y1 = self._canvas.GetViewStart()
- unit_x, unit_y = self._canvas.GetScrollPixelsPerUnit()
-
- dc = wx.ClientDC(self.GetCanvas())
- self.GetCanvas().PrepareDC(dc)
-
- mouse_x = dc.LogicalToDeviceX(x-x1 * unit_x)
- mouse_y = dc.LogicalToDeviceY(y-y1 * unit_y)
-
- self._canvas.PopupMenu(menu, (mouse_x, mouse_y))
-
-