Added a Python port of the OGL library, deprecated the C++ wrapped version.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@27447 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
		@@ -12,7 +12,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
%define DOCSTRING
 | 
					%define DOCSTRING
 | 
				
			||||||
"The Object Graphics Library provides for simple drawing and manipulation
 | 
					"The Object Graphics Library provides for simple drawing and manipulation
 | 
				
			||||||
of 2D objects."
 | 
					of 2D objects.  (This version is deprecated, please use wx.lib.ogl instead.)"
 | 
				
			||||||
%enddef
 | 
					%enddef
 | 
				
			||||||
%module(docstring=DOCSTRING) ogl
 | 
					%module(docstring=DOCSTRING) ogl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -29,6 +29,12 @@ of 2D objects."
 | 
				
			|||||||
%pythoncode { wx = _core }
 | 
					%pythoncode { wx = _core }
 | 
				
			||||||
%pythoncode { __docfilter__ = wx.__DocFilter(globals()) }
 | 
					%pythoncode { __docfilter__ = wx.__DocFilter(globals()) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%pythoncode {
 | 
				
			||||||
 | 
					    import warnings
 | 
				
			||||||
 | 
					    warnings.warn("This module is deprecated.  Please use the wx.lib.ogl pacakge instead.",    
 | 
				
			||||||
 | 
					                  DeprecationWarning, stacklevel=2)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MAKE_CONST_WXSTRING_NOSWIG(EmptyString);
 | 
					MAKE_CONST_WXSTRING_NOSWIG(EmptyString);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,7 @@ import images
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
_treeList = [
 | 
					_treeList = [
 | 
				
			||||||
    # new stuff
 | 
					    # new stuff
 | 
				
			||||||
    ('Recent Additions', [
 | 
					    ('Recent Additions and Updates', [
 | 
				
			||||||
        'VListBox',
 | 
					        'VListBox',
 | 
				
			||||||
        'Listbook',
 | 
					        'Listbook',
 | 
				
			||||||
        'MaskedNumCtrl',
 | 
					        'MaskedNumCtrl',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,15 +1,19 @@
 | 
				
			|||||||
 | 
					# -*- coding: iso-8859-1 -*-
 | 
				
			||||||
# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
 | 
					# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# o Updated for wx namespace
 | 
					# o Updated for wx namespace
 | 
				
			||||||
# 
 | 
					# 
 | 
				
			||||||
 | 
					# 20040508 - Pierre Hj<48>lm
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# o Changed to use the python version of OGL
 | 
				
			||||||
 | 
					# o Added TextShape, CompositeShape and CompositeShape with divisions
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import wx
 | 
					import wx
 | 
				
			||||||
import  wx.ogl  as  ogl
 | 
					import wx.lib.ogl as ogl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import  images
 | 
					import  images
 | 
				
			||||||
 | 
					
 | 
				
			||||||
##wx.Trap()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#----------------------------------------------------------------------
 | 
					#----------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DiamondShape(ogl.PolygonShape):
 | 
					class DiamondShape(ogl.PolygonShape):
 | 
				
			||||||
@@ -20,13 +24,6 @@ class DiamondShape(ogl.PolygonShape):
 | 
				
			|||||||
        if h == 0.0:
 | 
					        if h == 0.0:
 | 
				
			||||||
            h = 60.0
 | 
					            h = 60.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Either ogl.RealPoints or 2-tuples of floats  works.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #points = [ ogl.RealPoint(0.0,    -h/2.0),
 | 
					 | 
				
			||||||
        #          ogl.RealPoint(w/2.0,  0.0),
 | 
					 | 
				
			||||||
        #          ogl.RealPoint(0.0,    h/2.0),
 | 
					 | 
				
			||||||
        #          ogl.RealPoint(-w/2.0, 0.0),
 | 
					 | 
				
			||||||
        #          ]
 | 
					 | 
				
			||||||
        points = [ (0.0,    -h/2.0),
 | 
					        points = [ (0.0,    -h/2.0),
 | 
				
			||||||
                   (w/2.0,  0.0),
 | 
					                   (w/2.0,  0.0),
 | 
				
			||||||
                   (0.0,    h/2.0),
 | 
					                   (0.0,    h/2.0),
 | 
				
			||||||
@@ -44,6 +41,67 @@ class RoundedRectangleShape(ogl.RectangleShape):
 | 
				
			|||||||
        self.SetCornerRadius(-0.3)
 | 
					        self.SetCornerRadius(-0.3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#----------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CompositeDivisionShape(ogl.CompositeShape):
 | 
				
			||||||
 | 
					    def __init__(self, canvas):
 | 
				
			||||||
 | 
					        ogl.CompositeShape.__init__(self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.SetCanvas(canvas)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # create a division in the composite
 | 
				
			||||||
 | 
					        self.MakeContainer()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # add a shape to the original division
 | 
				
			||||||
 | 
					        shape2 = ogl.RectangleShape(40, 60)
 | 
				
			||||||
 | 
					        self.GetDivisions()[0].AddChild(shape2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # now divide the division so we get 2
 | 
				
			||||||
 | 
					        self.GetDivisions()[0].Divide(wx.HORIZONTAL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # and add a shape to the second division (and move it to the
 | 
				
			||||||
 | 
					        # centre of the division)
 | 
				
			||||||
 | 
					        shape3 = ogl.CircleShape(40)
 | 
				
			||||||
 | 
					        shape3.SetBrush(wx.CYAN_BRUSH)
 | 
				
			||||||
 | 
					        self.GetDivisions()[1].AddChild(shape3)
 | 
				
			||||||
 | 
					        shape3.SetX(self.GetDivisions()[1].GetX())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for division in self.GetDivisions():
 | 
				
			||||||
 | 
					            division.SetSensitivityFilter(0)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					#----------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CompositeShape(ogl.CompositeShape):
 | 
				
			||||||
 | 
					    def __init__(self, canvas):
 | 
				
			||||||
 | 
					        ogl.CompositeShape.__init__(self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.SetCanvas(canvas)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        constraining_shape = ogl.RectangleShape(120, 100)
 | 
				
			||||||
 | 
					        constrained_shape1 = ogl.CircleShape(50)
 | 
				
			||||||
 | 
					        constrained_shape2 = ogl.RectangleShape(80, 20)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        constraining_shape.SetBrush(wx.BLUE_BRUSH)
 | 
				
			||||||
 | 
					        constrained_shape2.SetBrush(wx.RED_BRUSH)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        self.AddChild(constraining_shape)
 | 
				
			||||||
 | 
					        self.AddChild(constrained_shape1)
 | 
				
			||||||
 | 
					        self.AddChild(constrained_shape2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        constraint = ogl.Constraint(ogl.CONSTRAINT_MIDALIGNED_BOTTOM, constraining_shape, [constrained_shape1, constrained_shape2])
 | 
				
			||||||
 | 
					        self.AddConstraint(constraint)
 | 
				
			||||||
 | 
					        self.Recompute()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # If we don't do this, the shapes will be able to move on their
 | 
				
			||||||
 | 
					        # own, instead of moving the composite
 | 
				
			||||||
 | 
					        constraining_shape.SetDraggable(False)
 | 
				
			||||||
 | 
					        constrained_shape1.SetDraggable(False)
 | 
				
			||||||
 | 
					        constrained_shape2.SetDraggable(False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # If we don't do this the shape will take all left-clicks for itself
 | 
				
			||||||
 | 
					        constraining_shape.SetSensitivityFilter(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
#----------------------------------------------------------------------
 | 
					#----------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DividedShape(ogl.DividedShape):
 | 
					class DividedShape(ogl.DividedShape):
 | 
				
			||||||
@@ -88,7 +146,7 @@ class DividedShape(ogl.DividedShape):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def OnSizingEndDragLeft(self, pt, x, y, keys, attch):
 | 
					    def OnSizingEndDragLeft(self, pt, x, y, keys, attch):
 | 
				
			||||||
        print "***", self
 | 
					        print "***", self
 | 
				
			||||||
        self.base_OnSizingEndDragLeft(pt, x, y, keys, attch)
 | 
					        ogl.DividedShape.OnSizingEndDragLeft(self, pt, x, y, keys, attch)
 | 
				
			||||||
        self.SetRegionSizes()
 | 
					        self.SetRegionSizes()
 | 
				
			||||||
        self.ReformatRegions()
 | 
					        self.ReformatRegions()
 | 
				
			||||||
        self.GetCanvas().Refresh()
 | 
					        self.GetCanvas().Refresh()
 | 
				
			||||||
@@ -103,15 +161,14 @@ class MyEvtHandler(ogl.ShapeEvtHandler):
 | 
				
			|||||||
        self.statbarFrame = frame
 | 
					        self.statbarFrame = frame
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def UpdateStatusBar(self, shape):
 | 
					    def UpdateStatusBar(self, shape):
 | 
				
			||||||
        x,y = shape.GetX(), shape.GetY()
 | 
					        x, y = shape.GetX(), shape.GetY()
 | 
				
			||||||
        width, height = shape.GetBoundingBoxMax()
 | 
					        width, height = shape.GetBoundingBoxMax()
 | 
				
			||||||
        self.statbarFrame.SetStatusText("Pos: (%d,%d)  Size: (%d, %d)" %
 | 
					        self.statbarFrame.SetStatusText("Pos: (%d, %d)  Size: (%d, %d)" %
 | 
				
			||||||
                                        (x, y, width, height))
 | 
					                                        (x, y, width, height))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def OnLeftClick(self, x, y, keys = 0, attachment = 0):
 | 
					    def OnLeftClick(self, x, y, keys=0, attachment=0):
 | 
				
			||||||
        shape = self.GetShape()
 | 
					        shape = self.GetShape()
 | 
				
			||||||
        print shape.__class__, shape.GetClassName()
 | 
					 | 
				
			||||||
        canvas = shape.GetCanvas()
 | 
					        canvas = shape.GetCanvas()
 | 
				
			||||||
        dc = wx.ClientDC(canvas)
 | 
					        dc = wx.ClientDC(canvas)
 | 
				
			||||||
        canvas.PrepareDC(dc)
 | 
					        canvas.PrepareDC(dc)
 | 
				
			||||||
@@ -142,9 +199,9 @@ class MyEvtHandler(ogl.ShapeEvtHandler):
 | 
				
			|||||||
        self.UpdateStatusBar(shape)
 | 
					        self.UpdateStatusBar(shape)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
 | 
					    def OnEndDragLeft(self, x, y, keys=0, attachment=0):
 | 
				
			||||||
        shape = self.GetShape()
 | 
					        shape = self.GetShape()
 | 
				
			||||||
        self.base_OnEndDragLeft(x, y, keys, attachment)
 | 
					        ogl.ShapeEvtHandler.OnEndDragLeft(self, x, y, keys, attachment)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not shape.Selected():
 | 
					        if not shape.Selected():
 | 
				
			||||||
            self.OnLeftClick(x, y, keys, attachment)
 | 
					            self.OnLeftClick(x, y, keys, attachment)
 | 
				
			||||||
@@ -153,12 +210,12 @@ class MyEvtHandler(ogl.ShapeEvtHandler):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def OnSizingEndDragLeft(self, pt, x, y, keys, attch):
 | 
					    def OnSizingEndDragLeft(self, pt, x, y, keys, attch):
 | 
				
			||||||
        self.base_OnSizingEndDragLeft(pt, x, y, keys, attch)
 | 
					        ogl.ShapeEvtHandler.OnSizingEndDragLeft(self, pt, x, y, keys, attch)
 | 
				
			||||||
        self.UpdateStatusBar(self.GetShape())
 | 
					        self.UpdateStatusBar(self.GetShape())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def OnMovePost(self, dc, x, y, oldX, oldY, display):
 | 
					    def OnMovePost(self, dc, x, y, oldX, oldY, display):
 | 
				
			||||||
        self.base_OnMovePost(dc, x, y, oldX, oldY, display)
 | 
					        ogl.ShapeEvtHandler.OnMovePost(self, dc, x, y, oldX, oldY, display)
 | 
				
			||||||
        self.UpdateStatusBar(self.GetShape())
 | 
					        self.UpdateStatusBar(self.GetShape())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -188,11 +245,26 @@ class TestWindow(ogl.ShapeCanvas):
 | 
				
			|||||||
        rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID)
 | 
					        rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID)
 | 
				
			||||||
        dsBrush = wx.Brush("WHEAT", wx.SOLID)
 | 
					        dsBrush = wx.Brush("WHEAT", wx.SOLID)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.MyAddShape(
 | 
				
			||||||
 | 
					            CompositeDivisionShape(self), 
 | 
				
			||||||
 | 
					            310, 310, wx.BLACK_PEN, wx.BLUE_BRUSH, "Division"
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        self.MyAddShape(
 | 
				
			||||||
 | 
					            CompositeShape(self), 
 | 
				
			||||||
 | 
					            100, 260, wx.BLACK_PEN, wx.RED_BRUSH, "Composite"
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        self.MyAddShape(
 | 
					        self.MyAddShape(
 | 
				
			||||||
            ogl.CircleShape(80), 
 | 
					            ogl.CircleShape(80), 
 | 
				
			||||||
            100, 100, wx.Pen(wx.BLUE, 3), wx.GREEN_BRUSH, "Circle"
 | 
					            100, 100, wx.Pen(wx.BLUE, 3), wx.GREEN_BRUSH, "Circle"
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
 | 
					        self.MyAddShape(
 | 
				
			||||||
 | 
					            ogl.TextShape(45, 30), 
 | 
				
			||||||
 | 
					            205, 60, wx.GREEN_PEN, wx.LIGHT_GREY_BRUSH, "Text"
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.MyAddShape(
 | 
					        self.MyAddShape(
 | 
				
			||||||
            ogl.RectangleShape(85, 50), 
 | 
					            ogl.RectangleShape(85, 50), 
 | 
				
			||||||
            305, 60, wx.BLACK_PEN, wx.LIGHT_GREY_BRUSH, "Rectangle"
 | 
					            305, 60, wx.BLACK_PEN, wx.LIGHT_GREY_BRUSH, "Rectangle"
 | 
				
			||||||
@@ -200,17 +272,17 @@ class TestWindow(ogl.ShapeCanvas):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        ds = self.MyAddShape(
 | 
					        ds = self.MyAddShape(
 | 
				
			||||||
            DividedShape(140, 150, self), 
 | 
					            DividedShape(140, 150, self), 
 | 
				
			||||||
                    495, 145, wx.BLACK_PEN, dsBrush, ''
 | 
					            515, 145, wx.BLACK_PEN, dsBrush, ''
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.MyAddShape(
 | 
					        self.MyAddShape(
 | 
				
			||||||
            DiamondShape(90, 90), 
 | 
					            DiamondShape(90, 90), 
 | 
				
			||||||
            345, 235, wx.Pen(wx.BLUE, 3, wx.DOT), wx.RED_BRUSH, "Polygon"
 | 
					            445, 305, wx.Pen(wx.BLUE, 3, wx.DOT), wx.RED_BRUSH, "Polygon"
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
        self.MyAddShape(
 | 
					        self.MyAddShape(
 | 
				
			||||||
            RoundedRectangleShape(95,70), 
 | 
					            RoundedRectangleShape(95, 70), 
 | 
				
			||||||
            140, 255, wx.Pen(wx.RED, 2), rRectBrush, "Rounded Rect"
 | 
					            345, 145, wx.Pen(wx.RED, 2), rRectBrush, "Rounded Rect"
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        bmp = images.getTest2Bitmap()
 | 
					        bmp = images.getTest2Bitmap()
 | 
				
			||||||
@@ -219,7 +291,7 @@ class TestWindow(ogl.ShapeCanvas):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        s = ogl.BitmapShape()
 | 
					        s = ogl.BitmapShape()
 | 
				
			||||||
        s.SetBitmap(bmp)
 | 
					        s.SetBitmap(bmp)
 | 
				
			||||||
        self.MyAddShape(s, 225, 150, None, None, "Bitmap")
 | 
					        self.MyAddShape(s, 225, 130, None, None, "Bitmap")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        dc = wx.ClientDC(self)
 | 
					        dc = wx.ClientDC(self)
 | 
				
			||||||
        self.PrepareDC(dc)
 | 
					        self.PrepareDC(dc)
 | 
				
			||||||
@@ -241,13 +313,14 @@ class TestWindow(ogl.ShapeCanvas):
 | 
				
			|||||||
            self.diagram.AddShape(line)
 | 
					            self.diagram.AddShape(line)
 | 
				
			||||||
            line.Show(True)
 | 
					            line.Show(True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # for some reason, the shapes have to be moved for the line to show up...
 | 
					 | 
				
			||||||
            fromShape.Move(dc, fromShape.GetX(), fromShape.GetY())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def MyAddShape(self, shape, x, y, pen, brush, text):
 | 
					    def MyAddShape(self, shape, x, y, pen, brush, text):
 | 
				
			||||||
 | 
					        # Composites have to be moved for all children to get in place
 | 
				
			||||||
 | 
					        if isinstance(shape, ogl.CompositeShape):
 | 
				
			||||||
 | 
					            dc = wx.ClientDC(self)
 | 
				
			||||||
 | 
					            self.PrepareDC(dc)
 | 
				
			||||||
 | 
					            shape.Move(dc, x, y)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
            shape.SetDraggable(True, True)
 | 
					            shape.SetDraggable(True, True)
 | 
				
			||||||
        shape.SetCanvas(self)
 | 
					        shape.SetCanvas(self)
 | 
				
			||||||
        shape.SetX(x)
 | 
					        shape.SetX(x)
 | 
				
			||||||
@@ -268,16 +341,6 @@ class TestWindow(ogl.ShapeCanvas):
 | 
				
			|||||||
        return shape
 | 
					        return shape
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def OnDestroy(self, evt):
 | 
					 | 
				
			||||||
        # Do some cleanup
 | 
					 | 
				
			||||||
        for shape in self.diagram.GetShapeList():
 | 
					 | 
				
			||||||
            if shape.GetParent() == None:
 | 
					 | 
				
			||||||
                shape.SetCanvas(None)
 | 
					 | 
				
			||||||
                shape.Destroy()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.diagram.Destroy()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def OnBeginDragLeft(self, x, y, keys):
 | 
					    def OnBeginDragLeft(self, x, y, keys):
 | 
				
			||||||
        self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys))
 | 
					        self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -298,25 +361,32 @@ def runTest(frame, nb, log):
 | 
				
			|||||||
    
 | 
					    
 | 
				
			||||||
#----------------------------------------------------------------------
 | 
					#----------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# The OGL library holds some resources that need to be freed before
 | 
					 | 
				
			||||||
# the app shuts down.
 | 
					 | 
				
			||||||
class __Cleanup:
 | 
					 | 
				
			||||||
    def __del__(self, cleanup=ogl.OGLCleanUp):
 | 
					 | 
				
			||||||
        cleanup()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# When this module gets cleaned up by Python then __cu will be cleaned
 | 
					overview = """<html><body>
 | 
				
			||||||
# up and it's __dell__ is called, which will then call ogl.OGLCleanUp.
 | 
					<h2>Object Graphics Library</h2>
 | 
				
			||||||
__cu = __Cleanup()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
overview = """\
 | 
					 | 
				
			||||||
The Object Graphics Library is a library supporting the creation and
 | 
					The Object Graphics Library is a library supporting the creation and
 | 
				
			||||||
manipulation of simple and complex graphic images on a canvas.
 | 
					manipulation of simple and complex graphic images on a canvas.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<p>The OGL library was originally written in C++ and provided to
 | 
				
			||||||
 | 
					wxPython via an extension module wrapper as is most of the rest of
 | 
				
			||||||
 | 
					wxPython.  The code has now been ported to Python (with many thanks to
 | 
				
			||||||
 | 
					Pierre Hj<48>lm!) in order to make it be more easily maintainable and
 | 
				
			||||||
 | 
					less likely to get rusty because nobody cares about the C++ lib any
 | 
				
			||||||
 | 
					more.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<p>The Python version should be mostly drop-in compatible with the
 | 
				
			||||||
 | 
					wrapped C++ version, except for the location of the package
 | 
				
			||||||
 | 
					(wx.lib.ogl instead of wx.ogl) and that the base class methods are
 | 
				
			||||||
 | 
					called the normal Python way (superclass.Method(self, ...)) instead of the
 | 
				
			||||||
 | 
					hacky way that had to be done to support overloaded methods with the
 | 
				
			||||||
 | 
					old SWIG (self.base_Method(...))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == '__main__':
 | 
					if __name__ == '__main__':
 | 
				
			||||||
    import sys,os
 | 
					    import sys, os
 | 
				
			||||||
    import run
 | 
					    import run
 | 
				
			||||||
    run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
 | 
					    run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -71,6 +71,7 @@ wxPython/wx/lib/colourchooser
 | 
				
			|||||||
wxPython/wx/lib/editor
 | 
					wxPython/wx/lib/editor
 | 
				
			||||||
wxPython/wx/lib/masked
 | 
					wxPython/wx/lib/masked
 | 
				
			||||||
wxPython/wx/lib/mixins
 | 
					wxPython/wx/lib/mixins
 | 
				
			||||||
 | 
					wxPython/wx/lib/ogl
 | 
				
			||||||
wxPython/wx/py
 | 
					wxPython/wx/py
 | 
				
			||||||
wxPython/wx/py/tests
 | 
					wxPython/wx/py/tests
 | 
				
			||||||
wxPython/wxPython
 | 
					wxPython/wxPython
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -106,6 +106,8 @@ Source: "wx\lib\colourchooser\*.py";           DestDir: "{app}\wx\lib\colourchoo
 | 
				
			|||||||
Source: "wx\lib\editor\*.py";                  DestDir: "{app}\wx\lib\editor"; Components: core
 | 
					Source: "wx\lib\editor\*.py";                  DestDir: "{app}\wx\lib\editor"; Components: core
 | 
				
			||||||
Source: "wx\lib\editor\*.txt";                 DestDir: "{app}\wx\lib\editor"; Components: core
 | 
					Source: "wx\lib\editor\*.txt";                 DestDir: "{app}\wx\lib\editor"; Components: core
 | 
				
			||||||
Source: "wx\lib\mixins\*.py";                  DestDir: "{app}\wx\lib\mixins"; Components: core
 | 
					Source: "wx\lib\mixins\*.py";                  DestDir: "{app}\wx\lib\mixins"; Components: core
 | 
				
			||||||
 | 
					Source: "wx\lib\masked\*.py";                  DestDir: "{app}\wx\lib\masked"; Components: core
 | 
				
			||||||
 | 
					Source: "wx\lib\ogl\*.py";                     DestDir: "{app}\wx\lib\ogl"; Components: core
 | 
				
			||||||
Source: "wx\py\*.py";                          DestDir: "{app}\wx\py"; Components: core
 | 
					Source: "wx\py\*.py";                          DestDir: "{app}\wx\py"; Components: core
 | 
				
			||||||
Source: "wx\py\*.txt";                         DestDir: "{app}\wx\py"; Components: core
 | 
					Source: "wx\py\*.txt";                         DestDir: "{app}\wx\py"; Components: core
 | 
				
			||||||
Source: "wx\py\*.ico";                         DestDir: "{app}\wx\py"; Components: core
 | 
					Source: "wx\py\*.ico";                         DestDir: "{app}\wx\py"; Components: core
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -80,6 +80,17 @@ remaining compatible with "C".
 | 
				
			|||||||
Switched gizmos.TreeListCtrl to the newer version of the code from the
 | 
					Switched gizmos.TreeListCtrl to the newer version of the code from the
 | 
				
			||||||
wxCode project.
 | 
					wxCode project.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OGL is dead! LONG LIVE OGL!  (Oops, sorry.  A bit of my dramatic side
 | 
				
			||||||
 | 
					leaked out there...)  The wx.ogl module has been deprecated in favor
 | 
				
			||||||
 | 
					of the new Python port of the OGL library located at wx.lib.ogl
 | 
				
			||||||
 | 
					contributed by Pierre Hj<48>lm.  This will hopefully greatly extend the
 | 
				
			||||||
 | 
					life of OGL within wxPython by making it more easily maintainable and
 | 
				
			||||||
 | 
					less prone to getting rusty as there seems to be less and less
 | 
				
			||||||
 | 
					interest in maintaining the C++ version.  At this point there are just
 | 
				
			||||||
 | 
					a couple minor known compatibility differences, please see the
 | 
				
			||||||
 | 
					MigrationGuide_ file for details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. _MigrationGuide: MigrationGuide.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,10 +3,10 @@ wxPython 2.5 Migration Guide
 | 
				
			|||||||
============================
 | 
					============================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This document will help explain some of the major changes in wxPython
 | 
					This document will help explain some of the major changes in wxPython
 | 
				
			||||||
2.5 and let you know what you need to do to adapt your programs to
 | 
					2.5 since the 2.4 series and let you know what you need to do to adapt
 | 
				
			||||||
those changes.  Be sure to also check in the CHANGES_ file like
 | 
					your programs to those changes.  Be sure to also check in the CHANGES_
 | 
				
			||||||
usual to see info about the not so major changes and other things that
 | 
					file like usual to see info about the not so major changes and other
 | 
				
			||||||
have been added to wxPython.
 | 
					things that have been added to wxPython.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. _CHANGES: CHANGES.html
 | 
					.. _CHANGES: CHANGES.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -20,8 +20,8 @@ The **wxWindows** project and library is now known as
 | 
				
			|||||||
.. _here: http://www.wxwidgets.org/name.htm
 | 
					.. _here: http://www.wxwidgets.org/name.htm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This won't really affect wxPython all that much, other than the fact
 | 
					This won't really affect wxPython all that much, other than the fact
 | 
				
			||||||
that the wxwindows.org domain name will be changing to wxwidgets.org,
 | 
					that the wxwindows.org domain name has changed to wxwidgets.org,
 | 
				
			||||||
so mail list, CVS, and etc. addresses will be changing.  We're going
 | 
					so mail list, CVS, and etc. addresses have also changed.  We're going
 | 
				
			||||||
to try and smooth the transition as much as possible, but I wanted you
 | 
					to try and smooth the transition as much as possible, but I wanted you
 | 
				
			||||||
all to be aware of this change if you run into any issues.
 | 
					all to be aware of this change if you run into any issues.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -585,6 +585,34 @@ provided by the makers of the ActiveX control that you are using.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OGL is dead! LONG LIVE OGL!
 | 
				
			||||||
 | 
					---------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The wx.ogl module has been deprecated in favor of the new Python port
 | 
				
			||||||
 | 
					of the OGL library located at wx.lib.ogl contributed by Pierre Hj<48>lm.
 | 
				
			||||||
 | 
					This will hopefully greatly extend the life of OGL within wxPython by
 | 
				
			||||||
 | 
					making it more easily maintainable and less prone to getting rusty as
 | 
				
			||||||
 | 
					there seems to be less and less interest in maintaining the C++
 | 
				
			||||||
 | 
					version.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					There are only a few known compatibility issues at this time.  First
 | 
				
			||||||
 | 
					is the location of OGL.  The deprecated version is located in the
 | 
				
			||||||
 | 
					wx.ogl module, and the new version is in the wx.lib.ogl package.  So
 | 
				
			||||||
 | 
					this just means that to start using the new version you need to adjust
 | 
				
			||||||
 | 
					your imports.  So if your code currently has something like this::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     import wx
 | 
				
			||||||
 | 
					     import wx.ogl as ogl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Then just change it to this::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     import wx
 | 
				
			||||||
 | 
					     import wx.lib.ogl as ogl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Obsolete Modules
 | 
					Obsolete Modules
 | 
				
			||||||
----------------
 | 
					----------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -707,6 +707,7 @@ if __name__ == "__main__":
 | 
				
			|||||||
                          'wx.lib.editor',
 | 
					                          'wx.lib.editor',
 | 
				
			||||||
                          'wx.lib.masked',
 | 
					                          'wx.lib.masked',
 | 
				
			||||||
                          'wx.lib.mixins',
 | 
					                          'wx.lib.mixins',
 | 
				
			||||||
 | 
					                          'wx.lib.ogl',
 | 
				
			||||||
                          'wx.py',
 | 
					                          'wx.py',
 | 
				
			||||||
                          'wx.tools',
 | 
					                          'wx.tools',
 | 
				
			||||||
                          'wx.tools.XRCed',
 | 
					                          'wx.tools.XRCed',
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								wxPython/wx/lib/ogl/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								wxPython/wx/lib/ogl/__init__.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					"""
 | 
				
			||||||
 | 
					The Object Graphics Library provides for simple drawing and manipulation
 | 
				
			||||||
 | 
					of 2D objects.
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					__all__ = ["basic", "diagram", "canvas", "lines", "bmpshape", "divided", "composit"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from basic import *
 | 
				
			||||||
 | 
					from diagram import *
 | 
				
			||||||
 | 
					from canvas import *
 | 
				
			||||||
 | 
					from lines import *
 | 
				
			||||||
 | 
					from bmpshape import *
 | 
				
			||||||
 | 
					from divided import *
 | 
				
			||||||
 | 
					from composit import *
 | 
				
			||||||
							
								
								
									
										3173
									
								
								wxPython/wx/lib/ogl/basic.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3173
									
								
								wxPython/wx/lib/ogl/basic.py
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										66
									
								
								wxPython/wx/lib/ogl/bmpshape.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								wxPython/wx/lib/ogl/bmpshape.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
				
			|||||||
 | 
					# -*- coding: iso-8859-1 -*-
 | 
				
			||||||
 | 
					#----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					# Name:         bmpshape.py
 | 
				
			||||||
 | 
					# Purpose:      Bitmap shape
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Author:       Pierre Hj<48>lm (from C++ original by Julian Smart)
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Created:      20040508
 | 
				
			||||||
 | 
					# RCS-ID:       
 | 
				
			||||||
 | 
					# Copyright:    (c) 2004 Pierre Hj<48>lm - 1998 Julian Smart
 | 
				
			||||||
 | 
					# Licence:      wxWindows license
 | 
				
			||||||
 | 
					#----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from __future__ import division
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from basic import RectangleShape
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BitmapShape(RectangleShape):
 | 
				
			||||||
 | 
					    """Draws a bitmap (non-resizable)."""
 | 
				
			||||||
 | 
					    def __init__(self):
 | 
				
			||||||
 | 
					        RectangleShape.__init__(self, 100, 50)
 | 
				
			||||||
 | 
					        self._filename=""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def OnDraw(self, dc):
 | 
				
			||||||
 | 
					        if not self._bitmap.Ok():
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        x = self._xpos-self._bitmap.GetWidth() / 2
 | 
				
			||||||
 | 
					        y = self._ypos-self._bitmap.GetHeight() / 2
 | 
				
			||||||
 | 
					        dc.DrawBitmap(self._bitmap, x, y, True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def SetSize(self, w, h, recursive = True):
 | 
				
			||||||
 | 
					        if self._bitmap.Ok():
 | 
				
			||||||
 | 
					            w = self._bitmap.GetWidth()
 | 
				
			||||||
 | 
					            h = self._bitmap.GetHeight()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.SetAttachmentSize(w, h)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self._width = w
 | 
				
			||||||
 | 
					        self._height = h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.SetDefaultRegionSize()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def GetBitmap(self):
 | 
				
			||||||
 | 
					        """Return a the bitmap associated with this shape."""
 | 
				
			||||||
 | 
					        return self._bitmap
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def SetBitmap(self, bitmap):
 | 
				
			||||||
 | 
					        """Set the bitmap associated with this shape.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        You can delete the bitmap from the calling application, since
 | 
				
			||||||
 | 
					        reference counting will take care of holding on to the internal bitmap
 | 
				
			||||||
 | 
					        data.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self._bitmap = bitmap
 | 
				
			||||||
 | 
					        if self._bitmap.Ok():
 | 
				
			||||||
 | 
					            self.SetSize(self._bitmap.GetWidth(), self._bitmap.GetHeight())
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					    def SetFilename(self, f):
 | 
				
			||||||
 | 
					        """Set the bitmap filename."""
 | 
				
			||||||
 | 
					        self._filename = f
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def GetFilename(self):
 | 
				
			||||||
 | 
					        """Return the bitmap filename."""
 | 
				
			||||||
 | 
					        return self._filename
 | 
				
			||||||
							
								
								
									
										360
									
								
								wxPython/wx/lib/ogl/canvas.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										360
									
								
								wxPython/wx/lib/ogl/canvas.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,360 @@
 | 
				
			|||||||
 | 
					# -*- coding: iso-8859-1 -*-
 | 
				
			||||||
 | 
					#----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					# Name:         canvas.py
 | 
				
			||||||
 | 
					# Purpose:      The canvas class
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Author:       Pierre Hj<48>lm (from C++ original by Julian Smart)
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Created:      20040508
 | 
				
			||||||
 | 
					# RCS-ID:       
 | 
				
			||||||
 | 
					# Copyright:    (c) 2004 Pierre Hj<48>lm - 1998 Julian Smart
 | 
				
			||||||
 | 
					# Licence:      wxWindows license
 | 
				
			||||||
 | 
					#----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from __future__ import division
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import wx
 | 
				
			||||||
 | 
					from lines import LineShape
 | 
				
			||||||
 | 
					from composit import *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NoDragging, StartDraggingLeft, ContinueDraggingLeft, StartDraggingRight, ContinueDraggingRight = 0, 1, 2, 3, 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					KEY_SHIFT, KEY_CTRL = 1, 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Helper function: True if 'contains' wholly contains 'contained'.
 | 
				
			||||||
 | 
					def WhollyContains(contains, contained):
 | 
				
			||||||
 | 
					    xp1, yp1 = contains.GetX(), contains.GetY()
 | 
				
			||||||
 | 
					    xp2, yp2 = contained.GetX(), contained.GetY()
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    w1, h1 = contains.GetBoundingBoxMax()
 | 
				
			||||||
 | 
					    w2, h2 = contained.GetBoundingBoxMax()
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    left1 = xp1-w1 / 2.0
 | 
				
			||||||
 | 
					    top1 = yp1-h1 / 2.0
 | 
				
			||||||
 | 
					    right1 = xp1 + w1 / 2.0
 | 
				
			||||||
 | 
					    bottom1 = yp1 + h1 / 2.0
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    left2 = xp2-w2 / 2.0
 | 
				
			||||||
 | 
					    top2 = yp2-h2 / 2.0
 | 
				
			||||||
 | 
					    right2 = xp2 + w2 / 2.0
 | 
				
			||||||
 | 
					    bottom2 = yp2 + h2 / 2.0
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return ((left1 <= left2) and (top1 <= top2) and (right1 >= right2) and (bottom1 >= bottom2))
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ShapeCanvas(wx.ScrolledWindow):
 | 
				
			||||||
 | 
					    def __init__(self, parent = None, id=-1, pos = wx.DefaultPosition, size = wx.DefaultSize, style = wx.BORDER, name="ShapeCanvas"):
 | 
				
			||||||
 | 
					        wx.ScrolledWindow.__init__(self, parent, id, pos, size, style, name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self._shapeDiagram = None
 | 
				
			||||||
 | 
					        self._dragState = NoDragging
 | 
				
			||||||
 | 
					        self._draggedShape = None
 | 
				
			||||||
 | 
					        self._oldDragX = 0
 | 
				
			||||||
 | 
					        self._oldDragY = 0
 | 
				
			||||||
 | 
					        self._firstDragX = 0
 | 
				
			||||||
 | 
					        self._firstDragY = 0
 | 
				
			||||||
 | 
					        self._checkTolerance = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        wx.EVT_PAINT(self, self.OnPaint)
 | 
				
			||||||
 | 
					        wx.EVT_MOUSE_EVENTS(self, self.OnMouseEvent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def SetDiagram(self, diag):
 | 
				
			||||||
 | 
					        self._shapeDiagram = diag
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def GetDiagram(self):
 | 
				
			||||||
 | 
					        return self._shapeDiagram
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def OnPaint(self, evt):
 | 
				
			||||||
 | 
					        dc = wx.PaintDC(self)
 | 
				
			||||||
 | 
					        self.PrepareDC(dc)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        dc.SetBackground(wx.Brush(self.GetBackgroundColour(), wx.SOLID))
 | 
				
			||||||
 | 
					        dc.Clear()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if self.GetDiagram():
 | 
				
			||||||
 | 
					            self.GetDiagram().Redraw(dc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def OnMouseEvent(self, evt):
 | 
				
			||||||
 | 
					        dc = wx.ClientDC(self)
 | 
				
			||||||
 | 
					        self.PrepareDC(dc)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        x, y = evt.GetLogicalPosition(dc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        keys = 0
 | 
				
			||||||
 | 
					        if evt.ShiftDown():
 | 
				
			||||||
 | 
					            keys |= KEY_SHIFT
 | 
				
			||||||
 | 
					        if evt.ControlDown():
 | 
				
			||||||
 | 
					            keys |= KEY_CTRL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        dragging = evt.Dragging()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Check if we're within the tolerance for mouse movements.
 | 
				
			||||||
 | 
					        # If we're very close to the position we started dragging
 | 
				
			||||||
 | 
					        # from, this may not be an intentional drag at all.
 | 
				
			||||||
 | 
					        if dragging:
 | 
				
			||||||
 | 
					            dx = abs(dc.LogicalToDeviceX(x-self._firstDragX))
 | 
				
			||||||
 | 
					            dy = abs(dc.LogicalToDeviceY(y-self._firstDragY))
 | 
				
			||||||
 | 
					            if self._checkTolerance and (dx <= self.GetDiagram().GetMouseTolerance()) and (dy <= self.GetDiagram().GetMouseTolerance()):
 | 
				
			||||||
 | 
					                return
 | 
				
			||||||
 | 
					            # If we've ignored the tolerance once, then ALWAYS ignore
 | 
				
			||||||
 | 
					            # tolerance in this drag, even if we come back within
 | 
				
			||||||
 | 
					            # the tolerance range.
 | 
				
			||||||
 | 
					            self._checkTolerance = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Dragging - note that the effect of dragging is left entirely up
 | 
				
			||||||
 | 
					        # to the object, so no movement is done unless explicitly done by
 | 
				
			||||||
 | 
					        # object.
 | 
				
			||||||
 | 
					        if dragging and self._draggedShape and self._dragState == StartDraggingLeft:
 | 
				
			||||||
 | 
					            self._dragState = ContinueDraggingLeft
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # If the object isn't m_draggable, transfer message to canvas
 | 
				
			||||||
 | 
					            if self._draggedShape.Draggable():
 | 
				
			||||||
 | 
					                self._draggedShape.GetEventHandler().OnBeginDragLeft(x, y, keys, self._draggedAttachment)
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                self._draggedShape = None
 | 
				
			||||||
 | 
					                self.OnBeginDragLeft(x, y, keys)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            self._oldDragX, self._oldDragY = x, y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        elif dragging and self._draggedShape and self._dragState == ContinueDraggingLeft:
 | 
				
			||||||
 | 
					            # Continue dragging
 | 
				
			||||||
 | 
					            self._draggedShape.GetEventHandler().OnDragLeft(False, self._oldDragX, self._oldDragY, keys, self._draggedAttachment)
 | 
				
			||||||
 | 
					            self._draggedShape.GetEventHandler().OnDragLeft(True, x, y, keys, self._draggedAttachment)
 | 
				
			||||||
 | 
					            self._oldDragX, self._oldDragY = x, y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        elif evt.LeftUp and self._draggedShape and self._dragState == ContinueDraggingLeft:
 | 
				
			||||||
 | 
					            self._dragState = NoDragging
 | 
				
			||||||
 | 
					            self._checkTolerance = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            self._draggedShape.GetEventHandler().OnDragLeft(False, self._oldDragX, self._oldDragY, keys, self._draggedAttachment)
 | 
				
			||||||
 | 
					            self._draggedShape.GetEventHandler().OnEndDragLeft(x, y, keys, self._draggedAttachment)
 | 
				
			||||||
 | 
					            self._draggedShape = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        elif dragging and self._draggedShape and self._dragState == StartDraggingRight:
 | 
				
			||||||
 | 
					            self._dragState = ContinueDraggingRight
 | 
				
			||||||
 | 
					            if self._draggedShape.Draggable:
 | 
				
			||||||
 | 
					                self._draggedShape.GetEventHandler().OnBeginDragRight(x, y, keys, self._draggedAttachment)
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                self._draggedShape = None
 | 
				
			||||||
 | 
					                self.OnBeginDragRight(x, y, keys)
 | 
				
			||||||
 | 
					            self._oldDragX, self._oldDragY = x, y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        elif dragging and self._draggedShape and self._dragState == ContinueDraggingRight:
 | 
				
			||||||
 | 
					            # Continue dragging
 | 
				
			||||||
 | 
					            self._draggedShape.GetEventHandler().OnDragRight(False, self._oldDragX, self._oldDragY, keys, self._draggedAttachment)
 | 
				
			||||||
 | 
					            self._draggedShape.GetEventHandler().OnDragRight(True, x, y, keys, self._draggedAttachment)
 | 
				
			||||||
 | 
					            self._oldDragX, self._oldDragY = x, y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        elif evt.RightUp() and self._draggedShape and self._dragState == ContinueDraggingRight:
 | 
				
			||||||
 | 
					            self._dragState = NoDragging
 | 
				
			||||||
 | 
					            self._checkTolerance = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            self._draggedShape.GetEventHandler().OnDragRight(False, self._oldDragX, self._oldDragY, keys, self._draggedAttachment)
 | 
				
			||||||
 | 
					            self._draggedShape.GetEventHandler().OnEndDragRight(x, y, keys, self._draggedAttachment)
 | 
				
			||||||
 | 
					            self._draggedShape = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # All following events sent to canvas, not object
 | 
				
			||||||
 | 
					        elif dragging and not self._draggedShape and self._dragState == StartDraggingLeft:
 | 
				
			||||||
 | 
					            self._dragState = ContinueDraggingLeft
 | 
				
			||||||
 | 
					            self.OnBeginDragLeft(x, y, keys)
 | 
				
			||||||
 | 
					            self._oldDragX, self._oldDragY = x, y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        elif dragging and not self._draggedShape and self._dragState == ContinueDraggingLeft:
 | 
				
			||||||
 | 
					            # Continue dragging
 | 
				
			||||||
 | 
					            self.OnDragLeft(False, self._oldDragX, self._oldDragY, keys)
 | 
				
			||||||
 | 
					            self.OnDragLeft(True, x, y, keys)
 | 
				
			||||||
 | 
					            self._oldDragX, self._oldDragY = x, y                
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        elif evt.LeftUp() and not self._draggedShape and self._dragState == ContinueDraggingLeft:
 | 
				
			||||||
 | 
					            self._dragState = NoDragging
 | 
				
			||||||
 | 
					            self._checkTolerance = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            self.OnDragLeft(False, self._oldDragX, self._oldDragY, keys)
 | 
				
			||||||
 | 
					            self.OnEndDragLeft(x, y, keys)
 | 
				
			||||||
 | 
					            self._draggedShape = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        elif dragging and not self._draggedShape and self._dragState == StartDraggingRight:
 | 
				
			||||||
 | 
					            self._dragState = ContinueDraggingRight
 | 
				
			||||||
 | 
					            self.OnBeginDragRight(x, y, keys)
 | 
				
			||||||
 | 
					            self._oldDragX, self._oldDragY = x, y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        elif dragging and not self._draggedShape and self._dragState == ContinueDraggingRight:
 | 
				
			||||||
 | 
					            # Continue dragging
 | 
				
			||||||
 | 
					            self.OnDragRight(False, self._oldDragX, self._oldDragY, keys)
 | 
				
			||||||
 | 
					            self.OnDragRight(True, x, y, keys)
 | 
				
			||||||
 | 
					            self._oldDragX, self._oldDragY = x, y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        elif evt.RightUp() and not self._draggedShape and self._dragState == ContinueDraggingRight:
 | 
				
			||||||
 | 
					            self._dragState = NoDragging
 | 
				
			||||||
 | 
					            self._checkTolerance = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            self.OnDragRight(False, self._oldDragX, self._oldDragY, keys)
 | 
				
			||||||
 | 
					            self.OnEndDragRight(x, y, keys)
 | 
				
			||||||
 | 
					            self._draggedShape = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Non-dragging events
 | 
				
			||||||
 | 
					        elif evt.IsButton():
 | 
				
			||||||
 | 
					            self._checkTolerance = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # Find the nearest object
 | 
				
			||||||
 | 
					            attachment = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            nearest_object, attachment = self.FindShape(x, y)
 | 
				
			||||||
 | 
					            if nearest_object: # Object event
 | 
				
			||||||
 | 
					                if evt.LeftDown():
 | 
				
			||||||
 | 
					                    self._draggedShape = nearest_object
 | 
				
			||||||
 | 
					                    self._draggedAttachment = attachment
 | 
				
			||||||
 | 
					                    self._dragState = StartDraggingLeft
 | 
				
			||||||
 | 
					                    self._firstDragX = x
 | 
				
			||||||
 | 
					                    self._firstDragY = y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                elif evt.LeftUp():
 | 
				
			||||||
 | 
					                    # N.B. Only register a click if the same object was
 | 
				
			||||||
 | 
					                    # identified for down *and* up.
 | 
				
			||||||
 | 
					                    if nearest_object == self._draggedShape:
 | 
				
			||||||
 | 
					                        nearest_object.GetEventHandler().OnLeftClick(x, y, keys, attachment)
 | 
				
			||||||
 | 
					                    self._draggedShape = None
 | 
				
			||||||
 | 
					                    self._dragState = NoDragging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                elif evt.LeftDClick():
 | 
				
			||||||
 | 
					                    nearest_object.GetEventHandler().OnLeftDoubleClick(x, y, keys, attachment)
 | 
				
			||||||
 | 
					                    self._draggedShape = None
 | 
				
			||||||
 | 
					                    self._dragState = NoDragging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                elif evt.RightDown():
 | 
				
			||||||
 | 
					                    self._draggedShape = nearest_object
 | 
				
			||||||
 | 
					                    self._draggedAttachment = attachment
 | 
				
			||||||
 | 
					                    self._dragState = StartDraggingRight
 | 
				
			||||||
 | 
					                    self._firstDragX = x
 | 
				
			||||||
 | 
					                    self._firstDragY = y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                elif evt.RightUp():
 | 
				
			||||||
 | 
					                    if nearest_object == self._draggedShape:
 | 
				
			||||||
 | 
					                        nearest_object.GetEventHandler().OnRightClick(x, y, keys, attachment)
 | 
				
			||||||
 | 
					                    self._draggedShape = None
 | 
				
			||||||
 | 
					                    self._dragState = NoDragging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            else: # Canvas event
 | 
				
			||||||
 | 
					                if evt.LeftDown():
 | 
				
			||||||
 | 
					                    self._draggedShape = None
 | 
				
			||||||
 | 
					                    self._dragState = StartDraggingLeft
 | 
				
			||||||
 | 
					                    self._firstDragX = x
 | 
				
			||||||
 | 
					                    self._firstDragY = y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                elif evt.LeftUp():
 | 
				
			||||||
 | 
					                    self.OnLeftClick(x, y, keys)
 | 
				
			||||||
 | 
					                    self._draggedShape = None
 | 
				
			||||||
 | 
					                    self._dragState = NoDragging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                elif evt.RightDown():
 | 
				
			||||||
 | 
					                    self._draggedShape = None
 | 
				
			||||||
 | 
					                    self._dragState = StartDraggingRight
 | 
				
			||||||
 | 
					                    self._firstDragX = x
 | 
				
			||||||
 | 
					                    self._firstDragY = y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                elif evt.RightUp():
 | 
				
			||||||
 | 
					                    self.OnRightClick(x, y, keys)
 | 
				
			||||||
 | 
					                    self._draggedShape = None
 | 
				
			||||||
 | 
					                    self._dragState = NoDragging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def FindShape(self, x, y, info = None, notObject = None):
 | 
				
			||||||
 | 
					        nearest = 100000.0
 | 
				
			||||||
 | 
					        nearest_attachment = 0
 | 
				
			||||||
 | 
					        nearest_object = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Go backward through the object list, since we want:
 | 
				
			||||||
 | 
					        # (a) to have the control points drawn LAST to overlay
 | 
				
			||||||
 | 
					        #     the other objects
 | 
				
			||||||
 | 
					        # (b) to find the control points FIRST if they exist
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for object in self.GetDiagram().GetShapeList()[::-1]:
 | 
				
			||||||
 | 
					            # First pass for lines, which might be inside a container, so we
 | 
				
			||||||
 | 
					            # want lines to take priority over containers. This first loop
 | 
				
			||||||
 | 
					            # could fail if we clickout side a line, so then we'll
 | 
				
			||||||
 | 
					            # try other shapes.
 | 
				
			||||||
 | 
					            if object.IsShown() and \
 | 
				
			||||||
 | 
					               isinstance(object, LineShape) and \
 | 
				
			||||||
 | 
					               object.HitTest(x, y) and \
 | 
				
			||||||
 | 
					               ((info == None) or isinstance(object, info)) and \
 | 
				
			||||||
 | 
					               (not notObject or not notObject.HasDescendant(object)):
 | 
				
			||||||
 | 
					                temp_attachment, dist = object.HitTest(x, y)
 | 
				
			||||||
 | 
					                # A line is trickier to spot than a normal object.
 | 
				
			||||||
 | 
					                # For a line, since it's the diagonal of the box
 | 
				
			||||||
 | 
					                # we use for the hit test, we may have several
 | 
				
			||||||
 | 
					                # lines in the box and therefore we need to be able
 | 
				
			||||||
 | 
					                # to specify the nearest point to the centre of the line
 | 
				
			||||||
 | 
					                # as our hit criterion, to give the user some room for
 | 
				
			||||||
 | 
					                # manouevre.
 | 
				
			||||||
 | 
					                if dist<nearest:
 | 
				
			||||||
 | 
					                    nearest = dist
 | 
				
			||||||
 | 
					                    nearest_object = object
 | 
				
			||||||
 | 
					                    nearest_attachment = temp_attachment
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for object in self.GetDiagram().GetShapeList()[::-1]:
 | 
				
			||||||
 | 
					            # On second pass, only ever consider non-composites or
 | 
				
			||||||
 | 
					            # divisions. If children want to pass up control to
 | 
				
			||||||
 | 
					            # the composite, that's up to them.
 | 
				
			||||||
 | 
					            if (object.IsShown() and 
 | 
				
			||||||
 | 
					                   (isinstance(object, DivisionShape) or 
 | 
				
			||||||
 | 
					                    not isinstance(object, CompositeShape)) and 
 | 
				
			||||||
 | 
					                    object.HitTest(x, y) and 
 | 
				
			||||||
 | 
					                    (info == None or isinstance(object, info)) and 
 | 
				
			||||||
 | 
					                    (not notObject or not notObject.HasDescendant(object))):
 | 
				
			||||||
 | 
					                temp_attachment, dist = object.HitTest(x, y)
 | 
				
			||||||
 | 
					                if not isinstance(object, LineShape):
 | 
				
			||||||
 | 
					                    # If we've hit a container, and we have already
 | 
				
			||||||
 | 
					                    # found a line in the first pass, then ignore
 | 
				
			||||||
 | 
					                    # the container in case the line is in the container.
 | 
				
			||||||
 | 
					                    # Check for division in case line straddles divisions
 | 
				
			||||||
 | 
					                    # (i.e. is not wholly contained).
 | 
				
			||||||
 | 
					                    if not nearest_object or not (isinstance(object, DivisionShape) or WhollyContains(object, nearest_object)):
 | 
				
			||||||
 | 
					                        nearest_object = object
 | 
				
			||||||
 | 
					                        nearest_attachment = temp_attachment
 | 
				
			||||||
 | 
					                        break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return nearest_object, nearest_attachment
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def AddShape(self, object, addAfter = None):
 | 
				
			||||||
 | 
					        self.GetDiagram().AddShape(object, addAfter)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def InsertShape(self, object):
 | 
				
			||||||
 | 
					        self.GetDiagram().InsertShape(object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def RemoveShape(self, object):
 | 
				
			||||||
 | 
					        self.GetDiagram().RemoveShape(object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def GetQuickEditMode(self):
 | 
				
			||||||
 | 
					        return self.GetDiagram().GetQuickEditMode()
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def Redraw(self, dc):
 | 
				
			||||||
 | 
					        self.GetDiagram().Redraw(dc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def Snap(self, x, y):
 | 
				
			||||||
 | 
					        return self.GetDiagram().Snap(x, y)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def OnLeftClick(self, x, y, keys = 0):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def OnRightClick(self, x, y, keys = 0):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def OnDragLeft(self, draw, x, y, keys = 0):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def OnBeginDragLeft(self, x, y, keys = 0):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def OnEndDragLeft(self, x, y, keys = 0):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def OnDragRight(self, draw, x, y, keys = 0):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def OnBeginDragRight(self, x, y, keys = 0):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def OnEndDragRight(self, x, y, keys = 0):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
							
								
								
									
										1410
									
								
								wxPython/wx/lib/ogl/composit.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1410
									
								
								wxPython/wx/lib/ogl/composit.py
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										160
									
								
								wxPython/wx/lib/ogl/diagram.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								wxPython/wx/lib/ogl/diagram.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,160 @@
 | 
				
			|||||||
 | 
					# -*- coding: iso-8859-1 -*-
 | 
				
			||||||
 | 
					#----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					# Name:         diagram.py
 | 
				
			||||||
 | 
					# Purpose:      Diagram class
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Author:       Pierre Hj<48>lm (from C++ original by Julian Smart)
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Created:      20040508
 | 
				
			||||||
 | 
					# RCS-ID:       
 | 
				
			||||||
 | 
					# Copyright:    (c) 2004 Pierre Hj<48>lm - 1998 Julian Smart
 | 
				
			||||||
 | 
					# Licence:      wxWindows license
 | 
				
			||||||
 | 
					#----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from __future__ import division
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import wx
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DEFAULT_MOUSE_TOLERANCE = 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Diagram(object):
 | 
				
			||||||
 | 
					    """Encapsulates an entire diagram, with methods for drawing. A diagram has
 | 
				
			||||||
 | 
					    an associated ShapeCanvas.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Derived from:
 | 
				
			||||||
 | 
					      Object
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    def __init__(self):
 | 
				
			||||||
 | 
					        self._diagramCanvas = None
 | 
				
			||||||
 | 
					        self._quickEditMode = False
 | 
				
			||||||
 | 
					        self._snapToGrid = True
 | 
				
			||||||
 | 
					        self._gridSpacing = 5.0
 | 
				
			||||||
 | 
					        self._shapeList = []
 | 
				
			||||||
 | 
					        self._mouseTolerance = DEFAULT_MOUSE_TOLERANCE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def Redraw(self, dc):
 | 
				
			||||||
 | 
					        """Draw the shapes in the diagram on the specified device context."""
 | 
				
			||||||
 | 
					        if self._shapeList:
 | 
				
			||||||
 | 
					            if self.GetCanvas():
 | 
				
			||||||
 | 
					                self.GetCanvas().SetCursor(wx.HOURGLASS_CURSOR)
 | 
				
			||||||
 | 
					            for object in self._shapeList:
 | 
				
			||||||
 | 
					                object.Draw(dc)
 | 
				
			||||||
 | 
					            if self.GetCanvas():
 | 
				
			||||||
 | 
					                self.GetCanvas().SetCursor(wx.STANDARD_CURSOR)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def Clear(self, dc):
 | 
				
			||||||
 | 
					        """Clear the specified device context."""
 | 
				
			||||||
 | 
					        dc.Clear()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def AddShape(self, object, addAfter = None):
 | 
				
			||||||
 | 
					        """Adds a shape to the diagram. If addAfter is not None, the shape
 | 
				
			||||||
 | 
					        will be added after addAfter.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        if not object in self._shapeList:
 | 
				
			||||||
 | 
					            if addAfter:
 | 
				
			||||||
 | 
					                self._shapeList.insert(self._shapeList.index(addAfter) + 1, object)
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                self._shapeList.append(object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            object.SetCanvas(self.GetCanvas())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def InsertShape(self, object):
 | 
				
			||||||
 | 
					        """Insert a shape at the front of the shape list."""
 | 
				
			||||||
 | 
					        self._shapeList.insert(0, object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def RemoveShape(self, object):
 | 
				
			||||||
 | 
					        """Remove the shape from the diagram (non-recursively) but do not
 | 
				
			||||||
 | 
					        delete it.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        if object in self._shapeList:
 | 
				
			||||||
 | 
					            self._shapeList.remove(object)
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					    def RemoveAllShapes(self):
 | 
				
			||||||
 | 
					        """Remove all shapes from the diagram but do not delete the shapes."""
 | 
				
			||||||
 | 
					        self._shapeList = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def DeleteAllShapes(self):
 | 
				
			||||||
 | 
					        """Remove and delete all shapes in the diagram."""
 | 
				
			||||||
 | 
					        for shape in self._shapeList[:]:
 | 
				
			||||||
 | 
					            if not shape.GetParent():
 | 
				
			||||||
 | 
					                self.RemoveShape(shape)
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					    def ShowAll(self, show):
 | 
				
			||||||
 | 
					        """Call Show for each shape in the diagram."""
 | 
				
			||||||
 | 
					        for shape in self._shapeList:
 | 
				
			||||||
 | 
					            shape.Show()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def DrawOutLine(self, dc, x1, y1, x2, y2):
 | 
				
			||||||
 | 
					        """Draw an outline rectangle on the current device context."""
 | 
				
			||||||
 | 
					        dc.SetPen(wx.Pen(wx.Color(0, 0, 0), 1, wx.DOT))
 | 
				
			||||||
 | 
					        dc.SetBrush(wx.TRANSPARENT_BRUSH)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        dc.DrawLines([[x1, y1], [x2, y1], [x2, y2], [x1, y2], [x1, y1]])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def RecentreAll(self, dc):
 | 
				
			||||||
 | 
					        """Make sure all text that should be centred, is centred."""
 | 
				
			||||||
 | 
					        for shape in self._shapeList:
 | 
				
			||||||
 | 
					            shape.Recentre(dc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def SetCanvas(self, canvas):
 | 
				
			||||||
 | 
					        """Set the canvas associated with this diagram."""
 | 
				
			||||||
 | 
					        self._diagramCanvas = canvas
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def GetCanvas(self):
 | 
				
			||||||
 | 
					        """Return the shape canvas associated with this diagram."""
 | 
				
			||||||
 | 
					        return self._diagramCanvas
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    def FindShape(self, id):
 | 
				
			||||||
 | 
					        """Return the shape for the given identifier."""
 | 
				
			||||||
 | 
					        for shape in self._shapeList:
 | 
				
			||||||
 | 
					            if shape.GetId() == id:
 | 
				
			||||||
 | 
					                return shape
 | 
				
			||||||
 | 
					        return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def Snap(self, x, y):
 | 
				
			||||||
 | 
					        """'Snaps' the coordinate to the nearest grid position, if
 | 
				
			||||||
 | 
					        snap-to-grid is on."""
 | 
				
			||||||
 | 
					        if self._snapToGrid:
 | 
				
			||||||
 | 
					            return self._gridSpacing * int(x / self._gridSpacing + 0.5), self._gridSpacing * int(y / self._gridSpacing + 0.5)
 | 
				
			||||||
 | 
					        return x, y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def GetGridSpacing(self):
 | 
				
			||||||
 | 
					        """Return the grid spacing."""
 | 
				
			||||||
 | 
					        return self._gridSpacing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def GetSnapToGrid(self):
 | 
				
			||||||
 | 
					        """Return snap-to-grid mode."""
 | 
				
			||||||
 | 
					        return self._snapToGrid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def SetQuickEditMode(self, mode):
 | 
				
			||||||
 | 
					        """Set quick-edit-mode on of off.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        In this mode, refreshes are minimized, but the diagram may need
 | 
				
			||||||
 | 
					        manual refreshing occasionally.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self._quickEditMode = mode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def GetQuickEditMode(self):
 | 
				
			||||||
 | 
					        """Return quick edit mode."""
 | 
				
			||||||
 | 
					        return self._quickEditMode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def SetMouseTolerance(self, tolerance):
 | 
				
			||||||
 | 
					        """Set the tolerance within which a mouse move is ignored.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        The default is 3 pixels.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self._mouseTolerance = tolerance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def GetMouseTolerance(self):
 | 
				
			||||||
 | 
					        """Return the tolerance within which a mouse move is ignored."""
 | 
				
			||||||
 | 
					        return self._mouseTolerance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def GetShapeList(self):
 | 
				
			||||||
 | 
					        """Return the internal shape list."""
 | 
				
			||||||
 | 
					        return self._shapeList
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def GetCount(self):
 | 
				
			||||||
 | 
					        """Return the number of shapes in the diagram."""
 | 
				
			||||||
 | 
					        return len(self._shapeList)
 | 
				
			||||||
							
								
								
									
										404
									
								
								wxPython/wx/lib/ogl/divided.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										404
									
								
								wxPython/wx/lib/ogl/divided.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,404 @@
 | 
				
			|||||||
 | 
					# -*- coding: iso-8859-1 -*-
 | 
				
			||||||
 | 
					#----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					# Name:         divided.py
 | 
				
			||||||
 | 
					# Purpose:      DividedShape class
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Author:       Pierre Hj<48>lm (from C++ original by Julian Smart)
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Created:      20040508
 | 
				
			||||||
 | 
					# RCS-ID:       
 | 
				
			||||||
 | 
					# Copyright:    (c) 2004 Pierre Hj<48>lm - 1998 Julian Smart
 | 
				
			||||||
 | 
					# Licence:      wxWindows license
 | 
				
			||||||
 | 
					#----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from __future__ import division
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					import wx
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from basic import ControlPoint, RectangleShape, Shape
 | 
				
			||||||
 | 
					from oglmisc import *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DividedShapeControlPoint(ControlPoint):
 | 
				
			||||||
 | 
					    def __init__(self, the_canvas, object, region, size, the_m_xoffset, the_m_yoffset, the_type):
 | 
				
			||||||
 | 
					        ControlPoint.__init__(self, the_canvas, object, size, the_m_xoffset, the_m_yoffset, the_type)
 | 
				
			||||||
 | 
					        self.regionId = region
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Implement resizing of divided object division
 | 
				
			||||||
 | 
					    def OnDragLeft(self, draw, x, y, keys = 0, attachment = 0):
 | 
				
			||||||
 | 
					        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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        dividedObject = self._shape
 | 
				
			||||||
 | 
					        x1 = dividedObject.GetX()-dividedObject.GetWidth() / 2
 | 
				
			||||||
 | 
					        y1 = y
 | 
				
			||||||
 | 
					        x2 = dividedObject.GetX() + dividedObject.GetWidth() / 2
 | 
				
			||||||
 | 
					        y2 = y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        dc.DrawLine(x1, y1, x2, y2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def OnBeginDragLeft(self, x, y, keys = 0, attachment = 0):
 | 
				
			||||||
 | 
					        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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        dividedObject = self._shape
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        x1 = dividedObject.GetX()-dividedObject.GetWidth() / 2
 | 
				
			||||||
 | 
					        y1 = y
 | 
				
			||||||
 | 
					        x2 = dividedObject.GetX() + dividedObject.GetWidth() / 2
 | 
				
			||||||
 | 
					        y2 = y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        dc.DrawLine(x1, y1, x2, y2)
 | 
				
			||||||
 | 
					        self._canvas.CaptureMouse()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
 | 
				
			||||||
 | 
					        dc = wx.ClientDC(self.GetCanvas())
 | 
				
			||||||
 | 
					        self.GetCanvas().PrepareDC(dc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        dividedObject = self._shape
 | 
				
			||||||
 | 
					        if not dividedObject.GetRegions()[self.regionId]:
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        thisRegion = dividedObject.GetRegions()[self.regionId]
 | 
				
			||||||
 | 
					        nextRegion = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        dc.SetLogicalFunction(wx.COPY)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if self._canvas.HasCapture():
 | 
				
			||||||
 | 
					            self._canvas.ReleaseMouse()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Find the old top and bottom of this region,
 | 
				
			||||||
 | 
					        # and calculate the new proportion for this region
 | 
				
			||||||
 | 
					        # if legal.
 | 
				
			||||||
 | 
					        currentY = dividedObject.GetY()-dividedObject.GetHeight() / 2
 | 
				
			||||||
 | 
					        maxY = dividedObject.GetY() + dividedObject.GetHeight() / 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Save values
 | 
				
			||||||
 | 
					        theRegionTop = 0
 | 
				
			||||||
 | 
					        nextRegionBottom = 0
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        for i in range(len(dividedObject.GetRegions())):
 | 
				
			||||||
 | 
					            region = dividedObject.GetRegions()[i]
 | 
				
			||||||
 | 
					            proportion = region._regionProportionY
 | 
				
			||||||
 | 
					            yy = currentY + dividedObject.GetHeight() * proportion
 | 
				
			||||||
 | 
					            actualY = min(maxY, yy)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if region == thisRegion:
 | 
				
			||||||
 | 
					                thisRegionTop = currentY
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                if i + 1<len(dividedObject.GetRegions()):
 | 
				
			||||||
 | 
					                    nextRegion = dividedObject.GetRegions()[i + 1]
 | 
				
			||||||
 | 
					            if region == nextRegion:
 | 
				
			||||||
 | 
					                nextRegionBottom = actualY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            currentY = actualY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if not nextRegion:
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Check that we haven't gone above this region or below
 | 
				
			||||||
 | 
					        # next region.
 | 
				
			||||||
 | 
					        if y <= thisRegionTop or y >= nextRegionBottom:
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        dividedObject.EraseLinks(dc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Now calculate the new proportions of this region and the next region
 | 
				
			||||||
 | 
					        thisProportion = (y-thisRegionTop) / dividedObject.GetHeight()
 | 
				
			||||||
 | 
					        nextProportion = (nextRegionBottom-y) / dividedObject.GetHeight()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        thisRegion.SetProportions(0, thisProportion)
 | 
				
			||||||
 | 
					        nextRegion.SetProportions(0, nextProportion)
 | 
				
			||||||
 | 
					        self._yoffset = y-dividedObject.GetY()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Now reformat text
 | 
				
			||||||
 | 
					        for i, region in enumerate(dividedObject.GetRegions()):
 | 
				
			||||||
 | 
					            if region.GetText():
 | 
				
			||||||
 | 
					                s = region.GetText()
 | 
				
			||||||
 | 
					                dividedObject.FormatText(dc, s, i)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        dividedObject.SetRegionSizes()
 | 
				
			||||||
 | 
					        dividedObject.Draw(dc)
 | 
				
			||||||
 | 
					        dividedObject.GetEventHandler().OnMoveLinks(dc)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DividedShape(RectangleShape):
 | 
				
			||||||
 | 
					    """A DividedShape is a rectangle with a number of vertical divisions.
 | 
				
			||||||
 | 
					    Each division may have its text formatted with independent characteristics,
 | 
				
			||||||
 | 
					    and the size of each division relative to the whole image may be specified.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Derived from:
 | 
				
			||||||
 | 
					      RectangleShape
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    def __init__(self, w, h):
 | 
				
			||||||
 | 
					        RectangleShape.__init__(self, w, h)
 | 
				
			||||||
 | 
					        self.ClearRegions()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def OnDraw(self, dc):
 | 
				
			||||||
 | 
					        RectangleShape.OnDraw(self, dc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def OnDrawContents(self, dc):
 | 
				
			||||||
 | 
					        if self.GetRegions():
 | 
				
			||||||
 | 
					            defaultProportion = 1 / len(self.GetRegions())
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            defaultProportion = 0
 | 
				
			||||||
 | 
					        currentY = self._ypos-self._height / 2
 | 
				
			||||||
 | 
					        maxY = self._ypos + self._height / 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        leftX = self._xpos-self._width / 2
 | 
				
			||||||
 | 
					        rightX = self._xpos + self._width / 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if self._pen:
 | 
				
			||||||
 | 
					            dc.SetPen(self._pen)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        dc.SetTextForeground(self._textColour)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # For efficiency, don't do this under X - doesn't make
 | 
				
			||||||
 | 
					        # any visible difference for our purposes.
 | 
				
			||||||
 | 
					        if sys.platform[:3]=="win":
 | 
				
			||||||
 | 
					            dc.SetTextBackground(self._brush.GetColour())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if self.GetDisableLabel():
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        xMargin = 2
 | 
				
			||||||
 | 
					        yMargin = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        dc.SetBackgroundMode(wx.TRANSPARENT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for region in self.GetRegions():
 | 
				
			||||||
 | 
					            dc.SetFont(region.GetFont())
 | 
				
			||||||
 | 
					            dc.SetTextForeground(region.GetActualColourObject())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if region._regionProportionY<0:
 | 
				
			||||||
 | 
					                proportion = defaultProportion
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                proportion = region._regionProportionY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            y = currentY + self._height * proportion
 | 
				
			||||||
 | 
					            actualY = min(maxY, y)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            centreX = self._xpos
 | 
				
			||||||
 | 
					            centreY = currentY + (actualY-currentY) / 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            DrawFormattedText(dc, region._formattedText, centreX, centreY, self._width-2 * xMargin, actualY-currentY-2 * yMargin, region._formatMode)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if y <= maxY and region != self.GetRegions()[-1]:
 | 
				
			||||||
 | 
					                regionPen = region.GetActualPen()
 | 
				
			||||||
 | 
					                if regionPen:
 | 
				
			||||||
 | 
					                    dc.SetPen(regionPen)
 | 
				
			||||||
 | 
					                    dc.DrawLine(leftX, y, rightX, y)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            currentY = actualY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def SetSize(self, w, h, recursive = True):
 | 
				
			||||||
 | 
					        self.SetAttachmentSize(w, h)
 | 
				
			||||||
 | 
					        self._width = w
 | 
				
			||||||
 | 
					        self._height = h
 | 
				
			||||||
 | 
					        self.SetRegionSizes()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def SetRegionSizes(self):
 | 
				
			||||||
 | 
					        """Set all region sizes according to proportions and this object
 | 
				
			||||||
 | 
					        total size.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        if not self.GetRegions():
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if self.GetRegions():
 | 
				
			||||||
 | 
					            defaultProportion = 1 / len(self.GetRegions())
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            defaultProportion = 0
 | 
				
			||||||
 | 
					        currentY = self._ypos-self._height / 2
 | 
				
			||||||
 | 
					        maxY = self._ypos + self._height / 2
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        for region in self.GetRegions():
 | 
				
			||||||
 | 
					            if region._regionProportionY <= 0:
 | 
				
			||||||
 | 
					                proportion = defaultProportion
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                proportion = region._regionProportionY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            sizeY = proportion * self._height
 | 
				
			||||||
 | 
					            y = currentY + sizeY
 | 
				
			||||||
 | 
					            actualY = min(maxY, y)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            centreY = currentY + (actualY-currentY) / 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            region.SetSize(self._width, sizeY)
 | 
				
			||||||
 | 
					            region.SetPosition(0, centreY-self._ypos)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            currentY = actualY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Attachment points correspond to regions in the divided box
 | 
				
			||||||
 | 
					    def GetAttachmentPosition(self, attachment, nth = 0, no_arcs = 1, line = None):
 | 
				
			||||||
 | 
					        totalNumberAttachments = len(self.GetRegions()) * 2 + 2
 | 
				
			||||||
 | 
					        if self.GetAttachmentMode() == ATTACHMENT_MODE_NONE or attachment >= totalNumberAttachments:
 | 
				
			||||||
 | 
					            return Shape.GetAttachmentPosition(self, attachment, nth, no_arcs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        n = len(self.GetRegions())
 | 
				
			||||||
 | 
					        isEnd = line and line.IsEnd(self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        left = self._xpos-self._width / 2
 | 
				
			||||||
 | 
					        right = self._xpos + self._width / 2
 | 
				
			||||||
 | 
					        top = self._ypos-self._height / 2
 | 
				
			||||||
 | 
					        bottom = self._ypos + self._height / 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Zero is top, n + 1 is bottom
 | 
				
			||||||
 | 
					        if attachment == 0:
 | 
				
			||||||
 | 
					            y = top
 | 
				
			||||||
 | 
					            if self._spaceAttachments:
 | 
				
			||||||
 | 
					                if line and line.GetAlignmentType(isEnd) == LINE_ALIGNMENT_TO_NEXT_HANDLE:
 | 
				
			||||||
 | 
					                    # Align line according to the next handle along
 | 
				
			||||||
 | 
					                    point = line.GetNextControlPoint(self)
 | 
				
			||||||
 | 
					                    if point.x<left:
 | 
				
			||||||
 | 
					                        x = left
 | 
				
			||||||
 | 
					                    elif point.x>right:
 | 
				
			||||||
 | 
					                        x = right
 | 
				
			||||||
 | 
					                    else:
 | 
				
			||||||
 | 
					                        x = point.x
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    x = left + (nth + 1) * self._width / (no_arcs + 1)
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                x = self._xpos
 | 
				
			||||||
 | 
					        elif attachment == n + 1:
 | 
				
			||||||
 | 
					            y = bottom
 | 
				
			||||||
 | 
					            if self._spaceAttachments:
 | 
				
			||||||
 | 
					                if line and line.GetAlignmentType(isEnd) == LINE_ALIGNMENT_TO_NEXT_HANDLE:
 | 
				
			||||||
 | 
					                    # Align line according to the next handle along
 | 
				
			||||||
 | 
					                    point = line.GetNextControlPoint(self)
 | 
				
			||||||
 | 
					                    if point.x<left:
 | 
				
			||||||
 | 
					                        x = left
 | 
				
			||||||
 | 
					                    elif point.x>right:
 | 
				
			||||||
 | 
					                        x = right
 | 
				
			||||||
 | 
					                    else:
 | 
				
			||||||
 | 
					                        x = point.x
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    x = left + (nth + 1) * self._width / (no_arcs + 1)
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                x = self._xpos
 | 
				
			||||||
 | 
					        else: # Left or right
 | 
				
			||||||
 | 
					            isLeft = not attachment<(n + 1)
 | 
				
			||||||
 | 
					            if isLeft:
 | 
				
			||||||
 | 
					                i = totalNumberAttachments-attachment-1
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                i = attachment-1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            region = self.GetRegions()[i]
 | 
				
			||||||
 | 
					            if region:
 | 
				
			||||||
 | 
					                if isLeft:
 | 
				
			||||||
 | 
					                    x = left
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    x = right
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                # Calculate top and bottom of region
 | 
				
			||||||
 | 
					                top = self._ypos + region._y-region._height / 2
 | 
				
			||||||
 | 
					                bottom = self._ypos + region._y + region._height / 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                # Assuming we can trust the absolute size and
 | 
				
			||||||
 | 
					                # position of these regions
 | 
				
			||||||
 | 
					                if self._spaceAttachments:
 | 
				
			||||||
 | 
					                    if line and line.GetAlignmentType(isEnd) == LINE_ALIGNMENT_TO_NEXT_HANDLE:
 | 
				
			||||||
 | 
					                        # Align line according to the next handle along
 | 
				
			||||||
 | 
					                        point = line.GetNextControlPoint(self)
 | 
				
			||||||
 | 
					                        if point.y<bottom:
 | 
				
			||||||
 | 
					                            y = bottom
 | 
				
			||||||
 | 
					                        elif point.y>top:
 | 
				
			||||||
 | 
					                            y = top
 | 
				
			||||||
 | 
					                        else:
 | 
				
			||||||
 | 
					                            y = point.y
 | 
				
			||||||
 | 
					                    else:
 | 
				
			||||||
 | 
					                        y = top + (nth + 1) * region._height / (no_arcs + 1)
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    y = self._ypos + region._y
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                return False
 | 
				
			||||||
 | 
					        return x, y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def GetNumberOfAttachments(self):
 | 
				
			||||||
 | 
					        # There are two attachments for each region (left and right),
 | 
				
			||||||
 | 
					        # plus one on the top and one on the bottom.
 | 
				
			||||||
 | 
					        n = len(self.GetRegions()) * 2 + 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        maxN = n-1
 | 
				
			||||||
 | 
					        for point in self._attachmentPoints:
 | 
				
			||||||
 | 
					            if point._id>maxN:
 | 
				
			||||||
 | 
					                maxN = point._id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return maxN + 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def AttachmentIsValid(self, attachment):
 | 
				
			||||||
 | 
					        totalNumberAttachments = len(self.GetRegions()) * 2 + 2
 | 
				
			||||||
 | 
					        if attachment >= totalNumberAttachments:
 | 
				
			||||||
 | 
					            return Shape.AttachmentIsValid(self, attachment)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            return attachment >= 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def MakeControlPoints(self):
 | 
				
			||||||
 | 
					        RectangleShape.MakeControlPoints(self)
 | 
				
			||||||
 | 
					        self.MakeMandatoryControlPoints()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def MakeMandatoryControlPoints(self):
 | 
				
			||||||
 | 
					        currentY = self.GetY()-self._height / 2
 | 
				
			||||||
 | 
					        maxY = self.GetY() + self._height / 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for i, region in enumerate(self.GetRegions()):
 | 
				
			||||||
 | 
					            proportion = region._regionProportionY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            y = currentY + self._height * proportion
 | 
				
			||||||
 | 
					            actualY = min(maxY, y)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if region != self.GetRegions()[-1]:
 | 
				
			||||||
 | 
					                controlPoint = DividedShapeControlPoint(self._canvas, self, i, CONTROL_POINT_SIZE, 0, actualY-self.GetY(), 0)
 | 
				
			||||||
 | 
					                self._canvas.AddShape(controlPoint)
 | 
				
			||||||
 | 
					                self._controlPoints.append(controlPoint)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            currentY = actualY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def ResetControlPoints(self):
 | 
				
			||||||
 | 
					        # May only have the region handles, (n - 1) of them
 | 
				
			||||||
 | 
					        if len(self._controlPoints)>len(self.GetRegions())-1:
 | 
				
			||||||
 | 
					            RectangleShape.ResetControlPoints(self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.ResetMandatoryControlPoints()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def ResetMandatoryControlPoints(self):
 | 
				
			||||||
 | 
					        currentY = self.GetY()-self._height / 2
 | 
				
			||||||
 | 
					        maxY = self.GetY() + self._height / 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        i = 0
 | 
				
			||||||
 | 
					        for controlPoint in self._controlPoints:
 | 
				
			||||||
 | 
					            if isinstance(controlPoint, DividedShapeControlPoint):
 | 
				
			||||||
 | 
					                region = self.GetRegions()[i]
 | 
				
			||||||
 | 
					                proportion = region._regionProportionY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                y = currentY + self._height * proportion
 | 
				
			||||||
 | 
					                actualY = min(maxY, y)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                controlPoint._xoffset = 0
 | 
				
			||||||
 | 
					                controlPoint._yoffset = actualY-self.GetY()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                currentY = actualY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                i += 1
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					    def EditRegions(self):
 | 
				
			||||||
 | 
					        """Edit the region colours and styles. Not implemented."""
 | 
				
			||||||
 | 
					        print "EditRegions() is unimplemented"
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    def OnRightClick(self, x, y, keys = 0, attachment = 0):
 | 
				
			||||||
 | 
					        if keys & KEY_CTRL:
 | 
				
			||||||
 | 
					            self.EditRegions()
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            RectangleShape.OnRightClick(self, x, y, keys, attachment)
 | 
				
			||||||
							
								
								
									
										1533
									
								
								wxPython/wx/lib/ogl/lines.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1533
									
								
								wxPython/wx/lib/ogl/lines.py
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										416
									
								
								wxPython/wx/lib/ogl/oglmisc.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										416
									
								
								wxPython/wx/lib/ogl/oglmisc.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,416 @@
 | 
				
			|||||||
 | 
					# -*- coding: iso-8859-1 -*-
 | 
				
			||||||
 | 
					#----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					# Name:         oglmisc.py
 | 
				
			||||||
 | 
					# Purpose:      Miscellaneous OGL support functions
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Author:       Pierre Hj<48>lm (from C++ original by Julian Smart)
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Created:      20040508
 | 
				
			||||||
 | 
					# RCS-ID:       
 | 
				
			||||||
 | 
					# Copyright:    (c) 2004 Pierre Hj<48>lm - 1998 Julian Smart
 | 
				
			||||||
 | 
					# Licence:      wxWindows license
 | 
				
			||||||
 | 
					#----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from __future__ import division
 | 
				
			||||||
 | 
					from math import *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import wx
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Control point types
 | 
				
			||||||
 | 
					# Rectangle and most other shapes
 | 
				
			||||||
 | 
					CONTROL_POINT_VERTICAL = 1
 | 
				
			||||||
 | 
					CONTROL_POINT_HORIZONTAL = 2
 | 
				
			||||||
 | 
					CONTROL_POINT_DIAGONAL = 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Line
 | 
				
			||||||
 | 
					CONTROL_POINT_ENDPOINT_TO = 4
 | 
				
			||||||
 | 
					CONTROL_POINT_ENDPOINT_FROM = 5
 | 
				
			||||||
 | 
					CONTROL_POINT_LINE = 6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Types of formatting: can be combined in a bit list
 | 
				
			||||||
 | 
					FORMAT_NONE = 0             # Left justification
 | 
				
			||||||
 | 
					FORMAT_CENTRE_HORIZ = 1     # Centre horizontally
 | 
				
			||||||
 | 
					FORMAT_CENTRE_VERT = 2      # Centre vertically
 | 
				
			||||||
 | 
					FORMAT_SIZE_TO_CONTENTS = 4 # Resize shape to contents
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Attachment modes
 | 
				
			||||||
 | 
					ATTACHMENT_MODE_NONE, ATTACHMENT_MODE_EDGE, ATTACHMENT_MODE_BRANCHING = 0, 1, 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Shadow mode
 | 
				
			||||||
 | 
					SHADOW_NONE, SHADOW_LEFT, SHADOW_RIGHT = 0, 1, 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OP_CLICK_LEFT, OP_CLICK_RIGHT, OP_DRAG_LEFT, OP_DRAG_RIGHT = 1, 2, 4, 8
 | 
				
			||||||
 | 
					OP_ALL = OP_CLICK_LEFT | OP_CLICK_RIGHT | OP_DRAG_LEFT | OP_DRAG_RIGHT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Sub-modes for branching attachment mode
 | 
				
			||||||
 | 
					BRANCHING_ATTACHMENT_NORMAL = 1
 | 
				
			||||||
 | 
					BRANCHING_ATTACHMENT_BLOB = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# logical function to use when drawing rubberband boxes, etc.
 | 
				
			||||||
 | 
					OGLRBLF = wx.INVERT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CONTROL_POINT_SIZE = 6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Types of arrowhead
 | 
				
			||||||
 | 
					# (i) Built-in
 | 
				
			||||||
 | 
					ARROW_HOLLOW_CIRCLE   = 1
 | 
				
			||||||
 | 
					ARROW_FILLED_CIRCLE   = 2
 | 
				
			||||||
 | 
					ARROW_ARROW           = 3
 | 
				
			||||||
 | 
					ARROW_SINGLE_OBLIQUE  = 4
 | 
				
			||||||
 | 
					ARROW_DOUBLE_OBLIQUE  = 5
 | 
				
			||||||
 | 
					# (ii) Custom
 | 
				
			||||||
 | 
					ARROW_METAFILE        = 20
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Position of arrow on line
 | 
				
			||||||
 | 
					ARROW_POSITION_START  = 0
 | 
				
			||||||
 | 
					ARROW_POSITION_END    = 1
 | 
				
			||||||
 | 
					ARROW_POSITION_MIDDLE = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Line alignment flags
 | 
				
			||||||
 | 
					# Vertical by default
 | 
				
			||||||
 | 
					LINE_ALIGNMENT_HORIZ              = 1
 | 
				
			||||||
 | 
					LINE_ALIGNMENT_VERT               = 0
 | 
				
			||||||
 | 
					LINE_ALIGNMENT_TO_NEXT_HANDLE     = 2
 | 
				
			||||||
 | 
					LINE_ALIGNMENT_NONE               = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Format a string to a list of strings that fit in the given box.
 | 
				
			||||||
 | 
					# Interpret %n and 10 or 13 as a new line.
 | 
				
			||||||
 | 
					def FormatText(dc, text, width, height, formatMode):
 | 
				
			||||||
 | 
					    i = 0
 | 
				
			||||||
 | 
					    word=""
 | 
				
			||||||
 | 
					    word_list = []
 | 
				
			||||||
 | 
					    end_word = False
 | 
				
			||||||
 | 
					    new_line = False
 | 
				
			||||||
 | 
					    while i<len(text):
 | 
				
			||||||
 | 
					        if text[i]=="%":
 | 
				
			||||||
 | 
					            i += 1
 | 
				
			||||||
 | 
					            if i == len(text):
 | 
				
			||||||
 | 
					                word+="%"
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                if text[i]=="n":
 | 
				
			||||||
 | 
					                    new_line = True
 | 
				
			||||||
 | 
					                    end_word = True
 | 
				
			||||||
 | 
					                    i += 1
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    word+="%"+text[i]
 | 
				
			||||||
 | 
					                    i += 1
 | 
				
			||||||
 | 
					        elif text[i] in ["\012","\015"]:
 | 
				
			||||||
 | 
					            new_line = True
 | 
				
			||||||
 | 
					            end_word = True
 | 
				
			||||||
 | 
					            i += 1
 | 
				
			||||||
 | 
					        elif text[i]==" ":
 | 
				
			||||||
 | 
					            end_word = True
 | 
				
			||||||
 | 
					            i += 1
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            word += text[i]
 | 
				
			||||||
 | 
					            i += 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if i == len(text):
 | 
				
			||||||
 | 
					            end_word = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if end_word:
 | 
				
			||||||
 | 
					            word_list.append(word)
 | 
				
			||||||
 | 
					            word=""
 | 
				
			||||||
 | 
					            end_word = False
 | 
				
			||||||
 | 
					        if new_line:
 | 
				
			||||||
 | 
					            word_list.append(None)
 | 
				
			||||||
 | 
					            new_line = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Now, make a list of strings which can fit in the box
 | 
				
			||||||
 | 
					    string_list = []
 | 
				
			||||||
 | 
					    buffer=""
 | 
				
			||||||
 | 
					    for s in word_list:
 | 
				
			||||||
 | 
					        oldBuffer = buffer
 | 
				
			||||||
 | 
					        if s is None:
 | 
				
			||||||
 | 
					            # FORCE NEW LINE
 | 
				
			||||||
 | 
					            if len(buffer)>0:
 | 
				
			||||||
 | 
					                string_list.append(buffer)
 | 
				
			||||||
 | 
					            buffer=""
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            if len(buffer):
 | 
				
			||||||
 | 
					                buffer+=" "
 | 
				
			||||||
 | 
					            buffer += s
 | 
				
			||||||
 | 
					            x, y = dc.GetTextExtent(buffer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # Don't fit within the bounding box if we're fitting
 | 
				
			||||||
 | 
					            # shape to contents
 | 
				
			||||||
 | 
					            if (x>width) and not (formatMode & FORMAT_SIZE_TO_CONTENTS):
 | 
				
			||||||
 | 
					                # Deal with first word being wider than box
 | 
				
			||||||
 | 
					                if len(oldBuffer):
 | 
				
			||||||
 | 
					                    string_list.append(oldBuffer)
 | 
				
			||||||
 | 
					                buffer = s
 | 
				
			||||||
 | 
					    if len(buffer):
 | 
				
			||||||
 | 
					        string_list.append(buffer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return string_list
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def GetCentredTextExtent(dc, text_list, xpos = 0, ypos = 0, width = 0, height = 0):
 | 
				
			||||||
 | 
					    if not text_list:
 | 
				
			||||||
 | 
					        return 0, 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    max_width = 0
 | 
				
			||||||
 | 
					    for line in text_list:
 | 
				
			||||||
 | 
					        current_width, char_height = dc.GetTextExtent(line)
 | 
				
			||||||
 | 
					        if current_width>max_width:
 | 
				
			||||||
 | 
					            max_width = current_width
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return max_width, len(text_list) * char_height
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def CentreText(dc, text_list, xpos, ypos, width, height, formatMode):
 | 
				
			||||||
 | 
					    if not text_list:
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # First, get maximum dimensions of box enclosing text
 | 
				
			||||||
 | 
					    char_height = 0
 | 
				
			||||||
 | 
					    max_width = 0
 | 
				
			||||||
 | 
					    current_width = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Store text extents for speed
 | 
				
			||||||
 | 
					    widths = []
 | 
				
			||||||
 | 
					    for line in text_list:
 | 
				
			||||||
 | 
					        current_width, char_height = dc.GetTextExtent(line.GetText())
 | 
				
			||||||
 | 
					        widths.append(current_width)
 | 
				
			||||||
 | 
					        if current_width>max_width:
 | 
				
			||||||
 | 
					            max_width = current_width
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    max_height = len(text_list) * char_height
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if formatMode & FORMAT_CENTRE_VERT:
 | 
				
			||||||
 | 
					        if max_height<height:
 | 
				
			||||||
 | 
					            yoffset = ypos - height / 2 + (height - max_height) / 2
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            yoffset = ypos - height / 2
 | 
				
			||||||
 | 
					        yOffset = ypos
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        yoffset = 0.0
 | 
				
			||||||
 | 
					        yOffset = 0.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if formatMode & FORMAT_CENTRE_HORIZ:
 | 
				
			||||||
 | 
					        xoffset = xpos - width / 2
 | 
				
			||||||
 | 
					        xOffset = xpos
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        xoffset = 0.0
 | 
				
			||||||
 | 
					        xOffset = 0.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for i, line in enumerate(text_list):
 | 
				
			||||||
 | 
					        if formatMode & FORMAT_CENTRE_HORIZ and widths[i]<width:
 | 
				
			||||||
 | 
					            x = (width - widths[i]) / 2 + xoffset
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            x = xoffset
 | 
				
			||||||
 | 
					        y = i * char_height + yoffset
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        line.SetX(x - xOffset)
 | 
				
			||||||
 | 
					        line.SetY(y - yOffset)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def DrawFormattedText(dc, text_list, xpos, ypos, width, height, formatMode):
 | 
				
			||||||
 | 
					    if formatMode & FORMAT_CENTRE_HORIZ:
 | 
				
			||||||
 | 
					        xoffset = xpos
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        xoffset = xpos - width / 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if formatMode & FORMAT_CENTRE_VERT:
 | 
				
			||||||
 | 
					        yoffset = ypos
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        yoffset = ypos - height / 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # +1 to allow for rounding errors
 | 
				
			||||||
 | 
					    dc.SetClippingRegion(xpos - width / 2, ypos - height / 2, width + 1, height + 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for line in text_list:
 | 
				
			||||||
 | 
					        dc.DrawText(line.GetText(), xoffset + line.GetX(), yoffset + line.GetY())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dc.DestroyClippingRegion()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def RoughlyEqual(val1, val2, tol = 0.00001):
 | 
				
			||||||
 | 
					    return val1<(val2 + tol) and val1>(val2 - tol) and \
 | 
				
			||||||
 | 
					           val2<(val1 + tol) and val2>(val1 - tol)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def FindEndForBox(width, height, x1, y1, x2, y2):
 | 
				
			||||||
 | 
					    xvec = [x1 - width / 2, x1 - width / 2, x1 + width / 2, x1 + width / 2, x1 - width / 2]
 | 
				
			||||||
 | 
					    yvec = [y1 - height / 2, y1 + height / 2, y1 + height / 2, y1 - height / 2, y1 - height / 2]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return FindEndForPolyline(xvec, yvec, x2, y2, x1, y1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def CheckLineIntersection(x1, y1, x2, y2, x3, y3, x4, y4):
 | 
				
			||||||
 | 
					    denominator_term = (y4 - y3) * (x2 - x1) - (y2 - y1) * (x4 - x3)
 | 
				
			||||||
 | 
					    numerator_term = (x3 - x1) * (y4 - y3) + (x4 - x3) * (y1 - y3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    length_ratio = 1.0
 | 
				
			||||||
 | 
					    k_line = 1.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Check for parallel lines
 | 
				
			||||||
 | 
					    if denominator_term<0.005 and denominator_term>-0.005:
 | 
				
			||||||
 | 
					        line_constant=-1.0
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        line_constant = float(numerator_term) / denominator_term
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Check for intersection
 | 
				
			||||||
 | 
					    if line_constant<1.0 and line_constant>0.0:
 | 
				
			||||||
 | 
					        # Now must check that other line hits
 | 
				
			||||||
 | 
					        if (y4 - y3)<0.005 and (y4 - y3)>-0.005:
 | 
				
			||||||
 | 
					            k_line = (x1 - x3 + line_constant * (x2 - x1)) / (x4 - x3)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            k_line = (y1 - y3 + line_constant * (y2 - y1)) / (y4 - y3)
 | 
				
			||||||
 | 
					        if k_line >= 0 and k_line<1:
 | 
				
			||||||
 | 
					            length_ratio = line_constant
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            k_line = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return length_ratio, k_line
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def FindEndForPolyline(xvec, yvec, x1, y1, x2, y2):
 | 
				
			||||||
 | 
					    lastx = xvec[0]
 | 
				
			||||||
 | 
					    lasty = yvec[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    min_ratio = 1.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for i in range(1, len(xvec)):
 | 
				
			||||||
 | 
					        line_ratio, other_ratio = CheckLineIntersection(x1, y1, x2, y2, lastx, lasty, xvec[i], yvec[i])
 | 
				
			||||||
 | 
					        lastx = xvec[i]
 | 
				
			||||||
 | 
					        lasty = yvec[i]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if line_ratio<min_ratio:
 | 
				
			||||||
 | 
					            min_ratio = line_ratio
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Do last (implicit) line if last and first doubles are not identical
 | 
				
			||||||
 | 
					    if not (xvec[0] == lastx and yvec[0] == lasty):
 | 
				
			||||||
 | 
					        line_ratio, other_ratio = CheckLineIntersection(x1, y1, x2, y2, lastx, lasty, xvec[0], yvec[0])
 | 
				
			||||||
 | 
					        if line_ratio<min_ratio:
 | 
				
			||||||
 | 
					            min_ratio = line_ratio
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return x1 + (x2 - x1) * min_ratio, y1 + (y2 - y1) * min_ratio
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def PolylineHitTest(xvec, yvec, x1, y1, x2, y2):
 | 
				
			||||||
 | 
					    isAHit = False
 | 
				
			||||||
 | 
					    lastx = xvec[0]
 | 
				
			||||||
 | 
					    lasty = yvec[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    min_ratio = 1.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for i in range(1, len(xvec)):
 | 
				
			||||||
 | 
					        line_ratio, other_ratio = CheckLineIntersection(x1, y1, x2, y2, lastx, lasty, xvec[i], yvec[i])
 | 
				
			||||||
 | 
					        if line_ratio != 1.0:
 | 
				
			||||||
 | 
					            isAHit = True
 | 
				
			||||||
 | 
					        lastx = xvec[i]
 | 
				
			||||||
 | 
					        lasty = yvec[i]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if line_ratio<min_ratio:
 | 
				
			||||||
 | 
					            min_ratio = line_ratio
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Do last (implicit) line if last and first doubles are not identical
 | 
				
			||||||
 | 
					    if not (xvec[0] == lastx and yvec[0] == lasty):
 | 
				
			||||||
 | 
					        line_ratio, other_ratio = CheckLineIntersection(x1, y1, x2, y2, lastx, lasty, xvec[0], yvec[0])
 | 
				
			||||||
 | 
					        if line_ratio != 1.0:
 | 
				
			||||||
 | 
					            isAHit = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return isAHit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def GraphicsStraightenLine(point1, point2):
 | 
				
			||||||
 | 
					    dx = point2[0] - point1[0]
 | 
				
			||||||
 | 
					    dy = point2[1] - point1[1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if dx == 0:
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					    elif abs(dy / dx)>1:
 | 
				
			||||||
 | 
					        point2[0] = point1[0]
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        point2[1] = point1[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def GetPointOnLine(x1, y1, x2, y2, length):
 | 
				
			||||||
 | 
					    l = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1))
 | 
				
			||||||
 | 
					    if l<0.01:
 | 
				
			||||||
 | 
					        l = 0.01
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    i_bar = (x2 - x1) / l
 | 
				
			||||||
 | 
					    j_bar = (y2 - y1) / l
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return -length * i_bar + x2,-length * j_bar + y2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def GetArrowPoints(x1, y1, x2, y2, length, width):
 | 
				
			||||||
 | 
					    l = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if l<0.01:
 | 
				
			||||||
 | 
					        l = 0.01
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    i_bar = (x2 - x1) / l
 | 
				
			||||||
 | 
					    j_bar = (y2 - y1) / l
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    x3=-length * i_bar + x2
 | 
				
			||||||
 | 
					    y3=-length * j_bar + y2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return x2, y2, width*-j_bar + x3, width * i_bar + y3,-width*-j_bar + x3,-width * i_bar + y3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def DrawArcToEllipse(x1, y1, width1, height1, x2, y2, x3, y3):
 | 
				
			||||||
 | 
					    a1 = width1 / 2
 | 
				
			||||||
 | 
					    b1 = height1 / 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Check that x2 != x3
 | 
				
			||||||
 | 
					    if abs(x2 - x3)<0.05:
 | 
				
			||||||
 | 
					        x4 = x2
 | 
				
			||||||
 | 
					        if y3>y2:
 | 
				
			||||||
 | 
					            y4 = y1 - sqrt((b1 * b1 - (((x2 - x1) * (x2 - x1)) * (b1 * b1) / (a1 * a1))))
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            y4 = y1 + sqrt((b1 * b1 - (((x2 - x1) * (x2 - x1)) * (b1 * b1) / (a1 * a1))))
 | 
				
			||||||
 | 
					        return x4, y4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Calculate the x and y coordinates of the point where arc intersects ellipse
 | 
				
			||||||
 | 
					    A = (1 / (a1 * a1))
 | 
				
			||||||
 | 
					    B = ((y3 - y2) * (y3 - y2)) / ((x3 - x2) * (x3 - x2) * b1 * b1)
 | 
				
			||||||
 | 
					    C = (2 * (y3 - y2) * (y2 - y1)) / ((x3 - x2) * b1 * b1)
 | 
				
			||||||
 | 
					    D = ((y2 - y1) * (y2 - y1)) / (b1 * b1)
 | 
				
			||||||
 | 
					    E = (A + B)
 | 
				
			||||||
 | 
					    F = (C - (2 * A * x1) - (2 * B * x2))
 | 
				
			||||||
 | 
					    G = ((A * x1 * x1) + (B * x2 * x2) - (C * x2) + D - 1)
 | 
				
			||||||
 | 
					    H = ((y3 - y2) / (x32 - x2))
 | 
				
			||||||
 | 
					    K = ((F * F) - (4 * E * G))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if K >= 0:
 | 
				
			||||||
 | 
					        # In this case the line intersects the ellipse, so calculate intersection
 | 
				
			||||||
 | 
					        if x2 >= x1:
 | 
				
			||||||
 | 
					            ellipse1_x = ((F*-1) + sqrt(K)) / (2 * E)
 | 
				
			||||||
 | 
					            ellipse1_y = ((H * (ellipse1_x - x2)) + y2)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            ellipse1_x = (((F*-1) - sqrt(K)) / (2 * E))
 | 
				
			||||||
 | 
					            ellipse1_y = ((H * (ellipse1_x - x2)) + y2)
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        # in this case, arc does not intersect ellipse, so just draw arc
 | 
				
			||||||
 | 
					        ellipse1_x = x3
 | 
				
			||||||
 | 
					        ellipse1_y = y3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ellipse1_x, ellipse1_y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def FindEndForCircle(radius, x1, y1, x2, y2):
 | 
				
			||||||
 | 
					    H = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if H == 0:
 | 
				
			||||||
 | 
					        return x1, y1
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        return radius * (x2 - x1) / H + x1, radius * (y2 - y1) / H + y1
 | 
				
			||||||
		Reference in New Issue
	
	Block a user