Again OGL and line control points

I tried adding an optional argument to wxLineShape::InsertLineControlPoint()
which allowed the programmer to specify the position of the control point.
This would allow you to create control points where you need them when
restoring from a file, but with wxLineShape::GetLineControlPoints() broken in
wxPython, you would not be able to get the control point positions in order to
save them :frowning: I think this is why I ended up giving up on this approach.

I ended up writing my own MultiSegmentLineShape() class which maintains a list
of vertex shapes and wxLineShapes that connect them. Below is the source. I've
hacked out unrelated code, so consider it an untested example which may be useful.

  Matthew

### MultiSegmentLineShape and related classes ###

class LineSegmentShape(wxLineShape):
  def __init__(self, rootSegment, *_args, **_kwargs):
    self.RootSegmentGet = weakref.ref(rootSegment)
    
    wxLineShape.__init__(self, *_args, **_kwargs)
  
  def LeftClick(self, eventHandler, x, y, keys, attachment):
    rootSegment = self.RootSegmentGet()
    if rootSegment is not None:
      pass

  def LeftDoubleClick(self, eventHandler, x, y, keys, attachment):
    rootSegment = self.RootSegmentGet()
    if rootSegment is not None:
      pass
  
class LineVertexShape(wxRectangleShape):
  def __init__(self, rootSegment, *_args, **_kwargs):
    self.RootSegmentGet = weakref.ref(rootSegment)
    wxRectangleShape.__init__(self, *_args, **_kwargs)
  
  def DragLeft(self, eventHandler, arg1, x, y, keys, attachment):
    eventHandler.base_OnDragLeft(arg1, x, y, keys, attachment)
  
  def DragLeftBegin(self, eventHandler, x, y, keys, attachment):
    eventHandler.base_OnBeginDragLeft(x, y, keys,attachment)
  
  def DragLeftEnd(self, eventHandler, x, y, keys, attachment):
    eventHandler.base_OnEndDragLeft(x, y, keys, attachment)
  
  def LeftClick(self, eventHandler, x, y, keys, attachment):
    rootSegment = self.RootSegmentGet()
    if rootSegment is not None:
      pass

  def LeftDoubleClick(self, eventHandler, x, y, keys, attachment):
    rootSegment = self.RootSegmentGet()
    if rootSegment is not None:
      pass

class MultiSegmentLineShape(wxLineShape):
  size = 6
  
  def __init__(self, *_args, **_kwargs):
    self.vertexList =
    self.lineList =
    self.selected = False
    wxLineShape.__init__(self, *_args, **_kwargs)
  
  def IsLine(self):
    return 1
  
  def PreDestroy(self):
    canvas = self.GetCanvas()
    for shape in self.vertexList:
      canvas.ShapeRemove(shape)
    self.vertexList =
    
    for shape in self.lineList:
      canvas.ShapeRemove(shape)
    self.lineList =
  
  def SegmentDelete(self, bRedraw = True):
    lenVertexList = len(self.vertexList)
    if lenVertexList:
      canvas = self.GetCanvas()
      vertex = self.vertexList.pop(-1)
      line = self.lineList.pop(-1)
      shapeTo = self.GetTo()
      if lenVertexList > 1:
        shapeFrom = self.vertexList[-1]
      else:
        shapeFrom = self.FromShapeGet()
      
      vertex.RemoveLine(line)
      shapeFrom.RemoveLine(line)
      canvas.ShapeRemove(vertex)
      canvas.ShapeRemove(line)
      shapeFrom.AddLine(self, shapeTo, AttachmentRIGHT, AttachmentLEFT)
      
      if bRedraw:
        shapeTo.ForceMove()
  
  def SegmentInsert(self, position = None, bShow = True):
    lenVertexList = len(self.vertexList)
    if lenVertexList:
      shapeFrom = self.vertexList[lenVertexList - 1]
    else:
      shapeFrom = self.GetFrom()
      self.FromShapeGet = weakref.ref(shapeFrom)
      if wxLineShape.Selected(self):
        wxLineShape.Select(self, False)
    
    shapeTo = self.GetTo()
    
    # Create a new vertex shape at the given position
    canvas = self.GetCanvas()
    dc = canvas.DcGet()
    size = self.size
    vertex = LineVertexShape(self, size, size)
    pen = self.GetPen()
    brush = self.GetBrush()
    if position is not None:
      x = position.x
      y = position.y
    else:
      ends = self.GetEnds()
      xLastPoint, yLastPoint, xSecondLastPoint, ySecondLastPoint = ends
      x = (xLastPoint + xSecondLastPoint) / 2
      y = (yLastPoint + ySecondLastPoint) / 2
    
    canvas.ShapeAdd(vertex, x, y, pen, brush, None, (size, size), bShow)
    self.vertexList.append(vertex)
    
    # Move the "from" end of the existing line to the new vertex
    shapeFrom.RemoveLine(self)
    vertex.AddLine(self, shapeTo, AttachmentRIGHT, AttachmentLEFT)
    
    line = LineSegmentShape(self)
    attachments = (AttachmentRIGHT, AttachmentLEFT)
    canvas.LineAdd(line, pen, brush, shapeFrom, vertex, None, attachments, dc, bShow)
    if bShow:
      shapeTo.ForceMove(dc)
    
    self.lineList.append(line)
    return vertex, line
  
  def Select(self, selected, dc):
    self.selected = selected
    if len(self.vertexList):
      if selected:
        size = self.size
      else:
        size = 0
      for vertex in self.vertexList:
        vertex.SetSize(size, size)
      
      if wxLineShape.Selected(self):
        wxLineShape.Select(self, False)
    else:
      wxLineShape.Select(self, selected)
  
  def Selected(self):
    return self.selected
  
  def Show(self, bShow):
    shapeTo = self.GetTo()
    if shapeTo is not None:
      canvas = self.GetCanvas()
      dc = canvas.DcGet()
      shapeTo.ForceMove(dc)
    
    wxLineShape.Show(self, bShow)
    for shape in self.vertexList:
      shape.Show(bShow)
    
    for shape in self.lineList:
      shape.Show(bShow)
  
  def VertexListGet(self):
    return self.vertexList
  
  def VertexListMoveRelative(self, offsetX, offsetY, dc = None, bRedraw = True):
    for vertex in self.vertexList:
      vertex.MoveRelative(offsetX, offsetY, dc, bRedraw)
  
### ###

···

-----Original Message-----
From: Robin Dunn [mailto:robin@alldunn.com]
Sent: Monday, July 07, 2003 5:01 PM
To: wxPython-users@lists.wxwindows.org
Subject: Re: [wxPython-users] Again OGL and line control points

Davide Salomoni wrote:

Hello,

the application I am writing uses OGL to create various shapes connected
with lines. Everything works fine, but I am now wondering how to properly
save the thing. The wxWindows docs mention the methods wxDiagram::SaveFile
and LoadFile but these do not seem implemented in wxPython (nor it is clear
to what they would save and how).

They use some very old components of the library that have been
deprecated for a long time. With 2.4 they now have bee turned off by
default, so I had to disable the wxDiagram::[Load|Save]File methods too.

So I wrote a few routines to save the
shapes and their attributes in XML format, but the question is now the
following: the graphs handled by my app can be relatively complex, so it is
very useful to use multiple control points for wxLineShapes (and possibly
make them splines). But is it possible to save and restore the position of
the line control points of a (splined) wxLineShape? If not (I couldn't find
how), is there any other possibility?

Unfortunatly I don't know and don't have time to dive into the code
right now. Has anybody else tried this?

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwindows.org
For additional commands, e-mail: wxPython-users-help@lists.wxwindows.org