commit-gnue
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnue] r8299 - trunk/gnue-designer/src/uidrivers/wx/uihelpers/documentca


From: jcater
Subject: [gnue] r8299 - trunk/gnue-designer/src/uidrivers/wx/uihelpers/documentcanvas
Date: Mon, 3 Apr 2006 18:22:57 -0500 (CDT)

Author: jcater
Date: 2006-03-30 18:28:05 -0600 (Thu, 30 Mar 2006)
New Revision: 8299

Added:
   trunk/gnue-designer/src/uidrivers/wx/uihelpers/documentcanvas/canvas.py
   trunk/gnue-designer/src/uidrivers/wx/uihelpers/documentcanvas/dnd.py
   trunk/gnue-designer/src/uidrivers/wx/uihelpers/documentcanvas/widget.py
Removed:
   
trunk/gnue-designer/src/uidrivers/wx/uihelpers/documentcanvas/DocumentCanvas.py
Log:
split document canvas into separate classes (BREAKS PagePainter)

Deleted: 
trunk/gnue-designer/src/uidrivers/wx/uihelpers/documentcanvas/DocumentCanvas.py
===================================================================
--- 
trunk/gnue-designer/src/uidrivers/wx/uihelpers/documentcanvas/DocumentCanvas.py 
    2006-03-31 00:21:28 UTC (rev 8298)
+++ 
trunk/gnue-designer/src/uidrivers/wx/uihelpers/documentcanvas/DocumentCanvas.py 
    2006-03-31 00:28:05 UTC (rev 8299)
@@ -1,601 +0,0 @@
-#
-# Copyright 2001-2006 Free Software Foundation
-#
-# This file is part of GNU Enterprise
-#
-# GNU Enterprise is free software; you can redistribute it
-# and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation; either
-# version 2, or(at your option) any later version.
-#
-# GNU Enterprise is distributed in the hope that it will be
-# useful, but WITHOUT ANY WARRANTY; without even the implied
-# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-# PURPOSE. See the GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public
-# License along with program; see the file COPYING. If not,
-# write to the Free Software Foundation, Inc., 59 Temple Place
-# - Suite 330, Boston, MA 02111-1307, USA.
-#
-# $Id: TriggerEditor.py 8210 2006-03-07 00:04:31Z jcater $
-
-#
-# These classes were based on SimpleCanvas from OSA's Chandler
-# application, but heavily commented, debugged, and extended.
-#
-
-import wx
-import time
-
-
-# ===================================================================
-# A Drawable canvas widget
-# ===================================================================
-class wxSimpleDrawableObject(wx.EvtHandler):
-    def __init__(self, canvas):
-      super(wxSimpleDrawableObject, self).__init__()
-
-      self.bounds = wx.Rect()
-      self.canvas = canvas
-      self.visible = True
-      self.selected = False
-      self.dragStartPos = None
-
-      self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseEvent)
-
-    def MoveTo(self, x, y):
-      self.canvas.RefreshScrolledRect(self.bounds);
-      self.bounds.SetLeft(x)
-      self.bounds.SetTop(y)
-      self.canvas.RefreshScrolledRect(self.bounds);
-
-    def SetSize(self, width, height):
-      self.canvas.RefreshScrolledRect(self.bounds);
-      self.bounds.SetWidth(width)
-      self.bounds.SetHeight(height)
-      self.canvas.RefreshScrolledRect(self.bounds);
-
-    def OnMouseEvent(self, event):
-      x, y = event.GetPositionTuple()
-      if event.ButtonDown(1):
-        if self.SelectedHitTest(x, y) :
-          self.canvas.DeSelectAll()
-          self.SetSelected()
-          self.canvas.Update()
-          if self.DragHitTest(x, y):
-            self.dragStartPos =(x, y)
-        else:
-          self.dragStartPos =(x,y)
-      elif event.ButtonUp(1):
-        self.dragStartPos = None
-      elif event.Dragging() and event.LeftIsDown():
-        tolerance = 2
-        if abs(x - self.dragStartPos[0]) > tolerance or abs(y - 
self.dragStartPos[1]) > tolerance:
-          self.DoDrag(x, y)
-          return True
-      event.Skip()
-      return False
-
-    def SetBounds(self, bounds):
-      self.canvas.RefreshScrolledRect(self.bounds);
-      self.bounds = bounds
-      self.canvas.RefreshScrolledRect(self.bounds);
-
-    def Show(self, show):
-
-      # Make sure show is a Boolean
-      show = bool(show)
-
-      if(show ^ self.visible):
-        self.visible = show
-        self.canvas.RefreshScrolledRect(self.bounds);
-        self.canvas.Update()
-
-    def ConvertToCanvasDeviceCoordinates(self, x, y):
-      return self.canvas.CalcScrolledPosition(self.bounds.GetLeft() + x,
-                                                self.bounds.GetTop() + y)
-
-    def DoDrag(self, x, y):
-      """
-        Implement all the drag and drop functionality:
-      """
-
-      """
-        Create the dragImage and begin dragging over the full screen
-      """
-      offscreenBuffer = wx.EmptyBitmap(self.bounds.GetWidth(), 
self.bounds.GetHeight())
-      memoryDC = wx.MemoryDC()
-      memoryDC.SelectObject(offscreenBuffer)
-
-      memoryDC.BeginDrawing()
-      memoryDC.Clear()
-      self.Draw(memoryDC)
-
-      maskBitmap = wx.EmptyBitmap(self.bounds.GetWidth(), 
self.bounds.GetHeight(), 1)
-      memoryDC.SelectObject(maskBitmap)
-
-      memoryDC.SetBackground(wx.BLACK_BRUSH)
-      memoryDC.Clear()
-
-      self.DrawMask(memoryDC)
-      memoryDC.EndDrawing()
-
-      memoryDC.SelectObject(wx.NullBitmap)
-
-      if "__WXMAC__" in wx.PlatformInfo:  # workaround for wxMac bug
-          offscreenBuffer.SetMask(wx.Mask(maskBitmap, wx.BLACK))
-      else:
-          offscreenBuffer.SetMask(wx.Mask(maskBitmap))
-
-      """
-        Create the dragImage and begin dragging
-      """
-      if "__WXGTK__" in wx.PlatformInfo:
-          # The "hole punching" trick dosen't work on wxGTK, move the hostspot
-          # to be just outside the image
-          x, y = -1, -1
-      self.dragImage = wxCanvasDragImage(offscreenBuffer)
-
-      self.dragImage.BeginDrag(wx.Point(x,y), self.canvas, True)
-      self.dragImage.Move(self.ConvertToCanvasDeviceCoordinates(x, y))
-      self.dragImage.Show()
-
-      """
-        We need to keep a reference to the dataObject, rather than create
-      it in the construction because wxCanvasDropSource doesn't own the
-      data so the garbage collector will delete it.
-      """
-      dataObject = self.ConvertDrawableObjectToDataObject(x, y)
-      dropSource = wxCanvasDropSource(self, dataObject)
-
-      self.canvas.internalDnDItem = self
-      result = dropSource.DoDragDrop(wx.Drag_AllowMove)
-      self.canvas.internalDnDItem = None
-      self.dragImage.Hide()
-      self.dragImage.EndDrag()
-      del self.dragImage
-
-  def DrawMask(self, dc):
-    """
-      optionally implement this routine to draw a mask
-    """
-    pass
-
-  def SizeDrag(self, dragRect, startDrag, endDrag):
-    self.canvas.RefreshScrolledRect(self.bounds)
-    self.bounds = dragRect
-    self.canvas.RefreshScrolledRect(self.bounds)
-
-  """
-    You must implement the following functions
-  """
-  def Draw(self, dc):
-    """
-      You must implement this routine to do draw
-    """
-    assert(False)
-
-  def DragHitTest(self, x, y):
-    """
-      You must implement this routine to do hit testing for dragable region
-    of drawable object
-    """
-    assert(False)
-
-  def ConvertDrawableObjectToDataObject(self, x, y):
-    """
-      You must implement this routine to create data object for drag and drop
-    """
-    assert(False)
-
-  def SelectedHitTest(self, x, y):
-    """
-    You must implement this routine to do hit testing to identify the region
-    for selecting the object.
-    """
-    assert(False)
-
-  def SetSelected(self, selected=True):
-    """
-    Sets the selected bit for this object. Does a canvas refresh on the object
-    if it has changed state. Does not call Update on the canvas.
-    """
-    # Use the same trick as Show()
-    selected = bool(selected)
-
-    # Only do a refresh if we've changed state.
-    if(selected ^ self.selected):
-      self.selected = selected
-      self.canvas.RefreshScrolledRect(self.bounds);
-
-
-# ===================================================================
-# The canvas to draw on
-# ===================================================================
-class wxSimpleCanvas(wx.ScrolledWindow):
-    def __init__(self, *arguments, **keywords):
-      super(wxSimpleCanvas, self).__init__(*arguments, **keywords)
-
-      self.autoCreateDistance = 0
-      self.zOrderedDrawableObjects = []
-      self.internalDnDItem = None
-      self.Bind(wx.EVT_PAINT, self.OnPaint)
-      self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
-      self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseEvent)
-
-
-    def __del__(self):
-      for item in self.zOrderedDrawableObjects:
-        item.Destroy()
-
-    def RefreshScrolledRect(self, rect):
-      position = rect.GetPosition()
-      x, y = self.CalcScrolledPosition(position.x, position.y)
-      self.RefreshRect(wx.Rect(x, y, rect.GetWidth(), rect.GetHeight()));
-
-    def OnPaint(self, event):
-      """
-        wx.BufferedDC doesn't work here since it doesn't handle scrolled 
windows
-      and always allocates a buffer the size of the client area. So instead 
we'll
-      allocate a wx.MemoryDC, draw into it then blit it to our paintDC.
-        Eventually, if we're printing, we should bypass the wx.MemoryDC.
-        The updateRegion is not in scrolled coordinates.
-      """
-      scrollWindowOriginX, scrollWindowOriginY = 
self.CalcUnscrolledPosition(0, 0)
-
-      paintDC = wx.PaintDC(self)
-      self.PrepareDC(paintDC)
-
-      """
-        Calculate the rectangle that needs updating in scrolled coordinates
-      """
-      updateRect = self.GetUpdateRegion().GetBox()
-      bufferX = updateRect.GetLeft() + scrollWindowOriginX
-      bufferY = updateRect.GetTop() + scrollWindowOriginY
-      bufferWidth = updateRect.GetWidth()
-      bufferHeight = updateRect.GetHeight()
-
-      memoryDC = wx.MemoryDC()
-      offscreenBuffer = wx.EmptyBitmap(bufferWidth, bufferHeight)
-      memoryDC.SelectObject(offscreenBuffer)
-      memoryDC.SetDeviceOrigin(-bufferX, -bufferY)
-
-      """
-        Debugging code that makes it easy to see which areas are updating.
-      """
-      if 0:
-        success = paintDC.Blit(bufferX, bufferY,
-                                bufferWidth, bufferHeight,
-                                paintDC,
-                                bufferX, bufferY,
-                                wx.SRC_INVERT)
-        time.sleep(1)
-        success = paintDC.Blit(bufferX, bufferY,
-                                bufferWidth, bufferHeight,
-                                paintDC,
-                                bufferX, bufferY,
-                                wx.SRC_INVERT)
-
-
-      memoryDC.BeginDrawing()
-
-      self.DrawBackground(memoryDC)
-      self.Draw(memoryDC)
-
-      paintDC.Blit(bufferX, bufferY,
-                    bufferWidth, bufferHeight,
-                    memoryDC,
-                    bufferX, bufferY)
-
-      memoryDC.EndDrawing()
-
-    def Draw(self, dc):
-      updateRegion = self.GetUpdateRegion()
-      scrollWindowOriginX, scrollWindowOriginY = 
self.CalcUnscrolledPosition(0, 0)
-      dcOriginX, dcOriginY = dc.GetDeviceOrigin()
-      index = len(self.zOrderedDrawableObjects) - 1
-      while index >= 0:
-        drawableObject = self.zOrderedDrawableObjects [index]
-        objectX = drawableObject.bounds.GetLeft()
-        objectY = drawableObject.bounds.GetTop()
-        objectWidth = drawableObject.bounds.GetWidth()
-        objectHeight = drawableObject.bounds.GetHeight()
-
-        bounds = wx.Rect(objectX - scrollWindowOriginX,
-                          objectY - scrollWindowOriginY,
-                          objectWidth,
-                          objectHeight)
-
-        if updateRegion.ContainsRect(bounds) != wx.OutRegion and 
drawableObject.visible:
-          dc.SetDeviceOrigin(objectX + dcOriginX, objectY + dcOriginY)
-          drawableObject.Draw(dc)
-          dc.SetDeviceOrigin(dcOriginX, dcOriginY)
-        index -= 1
-
-    def OnEraseBackground(self, event):
-      """
-        Override OnEraseBackground to avoid erasing background. Instead
-      implement OnDrawBackground to draw/erase the background. This
-      design alternative will eliminate flicker
-      """
-      pass
-
-    def OnMouseEvent(self, event):
-      x, y = event.GetPositionTuple()
-      x, y = self.CalcUnscrolledPosition(x, y)
-      for drawableObject in self.zOrderedDrawableObjects:
-        if drawableObject.bounds.Inside((x, y)):
-          event.m_x = x - drawableObject.bounds.GetX()
-          event.m_y = y - drawableObject.bounds.GetY()
-          if drawableObject.ProcessEvent(event):
-            return True
-
-      if self.autoCreateDistance != 0:
-        if event.ButtonDown() and self.CreateHitTest(x, y):
-            self.dragStart = wx.Point(x, y)
-            self.CaptureMouse()
-            return True
-        elif hasattr(self, 'dragStart'):
-          if event.Dragging():
-            """
-              Clip mouse position to the scrolling window's bounds
-            """
-            boundsX, boundsY = self.GetVirtualSizeTuple()
-            if x < 0:
-              x = 0
-            if x > boundsX:
-              x = boundsX
-            if y < 0:
-              y = 0
-            if y > boundsY:
-              y = boundsY
-
-            deltaX =  x - self.dragStart.x
-            deltaY =  y - self.dragStart.y
-
-            if deltaX >= 0:
-              left = self.dragStart.x
-              width = deltaX
-            else:
-              left = x
-              width = -deltaX
-
-            if deltaY >= 0:
-              top = self.dragStart.y
-              height = deltaY
-            else:
-              top = y
-              height = -deltaY
-            dragRect = wx.Rect(left, top, width, height)
-
-            if not hasattr(self, 'dragCreateDrawableObject'):
-              if(deltaX * deltaX) +(deltaY * deltaY) >(self.autoCreateDistance 
* self.autoCreateDistance):
-                """
-                Create a new drawable object if we've dragged 
autoCreateDistance
-                pixels
-                """
-                object = self.dragCreateDrawableObject = 
self.CreateNewDrawableObject(dragRect,
-                                                                              
self.dragStart,
-                                                                              
wx.Point(x, y))
-                # if we weren't allowed to create one, give up
-                if object is None:
-                    return True
-
-                self.DeSelectAll()
-                object.selected = True
-
-
-                #self.zOrderedDrawableObjects.insert(0, 
self.dragCreateDrawableObject)
-                
#self.RefreshScrolledRect(self.dragCreateDrawableObject.bounds);
-                self.Add(object)
-
-              return True
-            else:
-              if self.dragCreateDrawableObject != None:
-                self.dragCreateDrawableObject.SizeDrag(dragRect,
-                                                        self.dragStart,
-                                                        wx.Point(x, y))
-
-          elif event.ButtonUp():
-            del self.dragStart
-            if hasattr(self, 'dragCreateDrawableObject'):
-                del self.dragCreateDrawableObject
-            self.ReleaseMouse()
-            return True
-      return False
-
-    def OnData(self, dataObject, x, y, result):
-      """
-        Handle default behavior of copy and move
-      """
-      if result == wx.DragMove or result == wx.DragCopy:
-          if(self.internalDnDItem != None) and(result == wx.DragMove):
-              assert(self.zOrderedDrawableObjects.count(self.internalDnDItem) 
== 1)
-
-              drawableObject = 
self.ConvertDataObjectToDrawableObject(dataObject, x, y, True)
-              x = drawableObject.bounds.GetLeft()
-              y = drawableObject.bounds.GetTop()
-
-              self.zOrderedDrawableObjects.remove(self.internalDnDItem)
-              self.zOrderedDrawableObjects.insert(0, self.internalDnDItem)
-              self.internalDnDItem.MoveTo(x, y)
-              self.internalDnDItem.Show(True)
-          else:
-
-              drawableObject = 
self.ConvertDataObjectToDrawableObject(dataObject, x, y, False)
-              x = drawableObject.bounds.GetLeft()
-              y = drawableObject.bounds.GetTop()
-
-              self.zOrderedDrawableObjects.insert(0, drawableObject)
-              self.RefreshScrolledRect(drawableObject.bounds);
-      return result
-
-    def CreateHitTest(self, x, y):
-      """
-        Set self.autoCreateDistance to some value other than zero to enable
-      dragging autoCreateDistance pixels to automatically create new drawable
-      objects.
-        By default, drawable objects are created if you click and drag in the
-      canvas anwhere there isn't a drawable object. You can restrict this 
location
-      that drawable objects are created by overriding this routine
-      """
-      return True
-    """
-      You must implement the following functions
-    """
-    def ConvertDataObjectToDrawableObject(self, dataObject, x, y, move):
-      """
-        You must implement this routine to convert a dataobject, used in
-      drag and drop into a drawable object.
-      """
-      assert(False)
-
-    def CreateNewDrawableObject(self, dragRect, startDrag, endDrag):
-      """
-        You must implement this routine to create new drawable objects by
-      dragging on the blank canvas.
-      """
-      assert(False)
-
-    def DeSelectAll(self):
-      """
-      Mark all selected objects as not selected. Only Refresh the objects
-      that change, don't call Update.
-      """
-      for drawableObject in self.zOrderedDrawableObjects:
-          if(drawableObject.selected):
-              drawableObject.selected = False
-              self.RefreshScrolledRect(drawableObject.bounds)
-
-    # -----------------------------------------------------------------
-    # Additions by GNUe
-    # -----------------------------------------------------------------
-    def Add(self, object):
-      """
-      Add a DrawableObject to the canvas
-      """
-      self.zOrderedDrawableObjects.insert(0, object)
-      self.RefreshScrolledRect(object.bounds);
-
-    def Remove(self, object):
-      self.zOrderedDrawableObjects.remove(object)
-      bounds = object.bounds
-      self.RefreshScrolledRect(bounds)
-      object.Destroy()
-
-
-# ===================================================================
-# A draggable image frame
-# ===================================================================
-class wxCanvasDragImage(wx.Frame):
-  """
-  A class similar to wx.DragImage except that it uses a shaped frame
-  to display the image, and that it is always full screen.
-  """
-  def __init__(self, bitmap):
-    super(wxCanvasDragImage, self).__init__(
-            None, -1, "",
-            style = wx.FRAME_SHAPED
-                  | wx.SIMPLE_BORDER
-                  | wx.FRAME_NO_TASKBAR
-                  | wx.STAY_ON_TOP)
-    self.bmp = bitmap
-    w, h = self.bmp.GetWidth(), self.bmp.GetHeight()
-    self.SetClientSize((w, h) )
-    self.hotspot = None
-    self.window = None
-
-    self.Bind(wx.EVT_PAINT, self.OnPaint)
-
-    if "__WXGTK__" in wx.PlatformInfo:
-      # wxGTK requires that the window be created before you can
-      # set its shape, so delay the call to SetWindowShape until
-      # this event.
-      self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
-    else:
-      # On wxMSW and wxMac the window has already been created, so go for it.
-      self.SetWindowShape()
-
-  def SetWindowShape(self, evt=None, hotspot=None):
-    # Use the bitmap's mask to determine the region
-    rgn = wx.RegionFromBitmap(self.bmp)
-    if hotspot is not None:
-      # punch a hole in the region at the hotspot to allow mouse events
-      # through to the window below
-      rect = wx.Rect(hotspot.x-1, hotspot.y-1, 3, 3)
-      rgn.SubtractRect(rect)
-    self.SetShape(rgn)
-
-  def BeginDrag(self, hotspot, window, *ignoreOthers):
-    self.hotspot = wx.Point(hotspot[0], hotspot[1])
-    if "__WXGTK__" not in wx.PlatformInfo:
-      self.SetWindowShape(hotspot = self.hotspot)
-    self.window = window
-    if self.window:
-      self.window.CaptureMouse()
-
-  def EndDrag(self, doDestroy=True):
-    if self.window and self.window.HasCapture():
-      self.window.ReleaseMouse()
-    self.Hide()
-    if doDestroy:
-      self.Destroy()
-
-  def Move(self, pt):
-    """
-    Move the image to a new location on screen.  The pt parameter
-    is a point in client coordinants relative to the window
-    specifed in BeginDrag. (Only for compatibility with
-    wx.DragImage, otherwise I would just use screen coordinants...)
-    """
-    pt2 = pt
-    if self.window:
-      pt2 = self.window.ClientToScreen(pt)
-    self.SetPosition(pt2 - self.hotspot)
-
-  def Show(self):
-    wx.Frame.Show(self)
-    self.Update()
-
-  def OnPaint(self, evt):
-    dc = wx.PaintDC(self)
-    dc.DrawBitmap(self.bmp, 0, 0, True)
-
-
-# ===================================================================
-# A draggable drop source
-# ===================================================================
-class wxCanvasDropSource(wx.DropSource):
-  def __init__(self, drawableObject, dataObject):
-    super(wxCanvasDropSource, self).__init__(drawableObject.canvas)
-    self.drawableObject = drawableObject
-    self.SetData(dataObject)
-
-  def GiveFeedback(self, effect):
-    windowX, windowY = wx.GetMousePosition()
-    self.drawableObject.Show(effect != wx.DragMove)
-    x, y = self.drawableObject.canvas.ScreenToClientXY(windowX, windowY)
-    self.drawableObject.dragImage.Move((x, y))
-    return False
-
-
-# ===================================================================
-# A draggable drop target
-# ===================================================================
-class wxCanvasDropTarget(wx.PyDropTarget):
-  def __init__(self, canvas, dropTargetDataObject):
-    super(wxCanvasDropTarget, self).__init__()
-    self.canvas = canvas
-    self.dataObject = dropTargetDataObject
-    self.SetDataObject(dropTargetDataObject)
-
-  def OnData(self, x, y, result):
-    """
-      Delegate functionality to the canvas
-    """
-    if(self.GetData()):
-      x, y = self.canvas.CalcUnscrolledPosition(x, y)
-      result = self.canvas.OnData(self.dataObject, x, y, result)
-    return result
-

Copied: trunk/gnue-designer/src/uidrivers/wx/uihelpers/documentcanvas/canvas.py 
(from rev 8298, 
trunk/gnue-designer/src/uidrivers/wx/uihelpers/documentcanvas/DocumentCanvas.py)
===================================================================
--- 
trunk/gnue-designer/src/uidrivers/wx/uihelpers/documentcanvas/DocumentCanvas.py 
    2006-03-31 00:21:28 UTC (rev 8298)
+++ trunk/gnue-designer/src/uidrivers/wx/uihelpers/documentcanvas/canvas.py     
2006-03-31 00:28:05 UTC (rev 8299)
@@ -0,0 +1,305 @@
+#
+# Copyright 2001-2006 Free Software Foundation
+#
+# This file is part of GNU Enterprise
+#
+# GNU Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2, or(at your option) any later version.
+#
+# GNU Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied
+# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+# PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with program; see the file COPYING. If not,
+# write to the Free Software Foundation, Inc., 59 Temple Place
+# - Suite 330, Boston, MA 02111-1307, USA.
+#
+# $Id: TriggerEditor.py 8210 2006-03-07 00:04:31Z jcater $
+
+#
+# These classes were based on SimpleCanvas from OSA's Chandler
+# application, but heavily commented, debugged, and extended.
+#
+
+import time
+
+import wx
+
+
+# ===================================================================
+# The canvas to draw on
+# ===================================================================
+class DocumentCanvas(wx.ScrolledWindow):
+    def __init__(self, *arguments, **keywords):
+        super(wxSimpleCanvas, self).__init__(*arguments, **keywords)
+
+        self.autoCreateDistance = 0
+        self.zOrderedDrawableObjects = []
+        self.internalDnDItem = None
+        self.Bind(wx.EVT_PAINT, self.OnPaint)
+        self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
+        self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseEvent)
+
+
+    def __del__(self):
+        for item in self.zOrderedDrawableObjects:
+            item.Destroy()
+
+    def RefreshScrolledRect(self, rect):
+        position = rect.GetPosition()
+        x, y = self.CalcScrolledPosition(position.x, position.y)
+        self.RefreshRect(wx.Rect(x, y, rect.GetWidth(), rect.GetHeight()));
+
+    def OnPaint(self, event):
+        """
+          wx.BufferedDC doesn't work here since it doesn't handle scrolled 
windows
+        and always allocates a buffer the size of the client area. So instead 
we'll
+        allocate a wx.MemoryDC, draw into it then blit it to our paintDC.
+          Eventually, if we're printing, we should bypass the wx.MemoryDC.
+          The updateRegion is not in scrolled coordinates.
+        """
+        scrollWindowOriginX, scrollWindowOriginY = 
self.CalcUnscrolledPosition(0, 0)
+
+        paintDC = wx.PaintDC(self)
+        self.PrepareDC(paintDC)
+
+        """
+          Calculate the rectangle that needs updating in scrolled coordinates
+        """
+        updateRect = self.GetUpdateRegion().GetBox()
+        bufferX = updateRect.GetLeft() + scrollWindowOriginX
+        bufferY = updateRect.GetTop() + scrollWindowOriginY
+        bufferWidth = updateRect.GetWidth()
+        bufferHeight = updateRect.GetHeight()
+
+        memoryDC = wx.MemoryDC()
+        offscreenBuffer = wx.EmptyBitmap(bufferWidth, bufferHeight)
+        memoryDC.SelectObject(offscreenBuffer)
+        memoryDC.SetDeviceOrigin(-bufferX, -bufferY)
+
+        """
+          Debugging code that makes it easy to see which areas are updating.
+        """
+        if 0:
+          success = paintDC.Blit(bufferX, bufferY,
+                                  bufferWidth, bufferHeight,
+                                  paintDC,
+                                  bufferX, bufferY,
+                                  wx.SRC_INVERT)
+          time.sleep(1)
+          success = paintDC.Blit(bufferX, bufferY,
+                                  bufferWidth, bufferHeight,
+                                  paintDC,
+                                  bufferX, bufferY,
+                                  wx.SRC_INVERT)
+
+
+        memoryDC.BeginDrawing()
+
+        self.DrawBackground(memoryDC)
+        self.Draw(memoryDC)
+
+        paintDC.Blit(bufferX, bufferY,
+                      bufferWidth, bufferHeight,
+                      memoryDC,
+                      bufferX, bufferY)
+
+        memoryDC.EndDrawing()
+
+    def Draw(self, dc):
+      updateRegion = self.GetUpdateRegion()
+      scrollWindowOriginX, scrollWindowOriginY = 
self.CalcUnscrolledPosition(0, 0)
+      dcOriginX, dcOriginY = dc.GetDeviceOrigin()
+      index = len(self.zOrderedDrawableObjects) - 1
+      while index >= 0:
+        drawableObject = self.zOrderedDrawableObjects [index]
+        objectX = drawableObject.bounds.GetLeft()
+        objectY = drawableObject.bounds.GetTop()
+        objectWidth = drawableObject.bounds.GetWidth()
+        objectHeight = drawableObject.bounds.GetHeight()
+
+        bounds = wx.Rect(objectX - scrollWindowOriginX,
+                          objectY - scrollWindowOriginY,
+                          objectWidth,
+                          objectHeight)
+
+        if updateRegion.ContainsRect(bounds) != wx.OutRegion and 
drawableObject.visible:
+          dc.SetDeviceOrigin(objectX + dcOriginX, objectY + dcOriginY)
+          drawableObject.Draw(dc)
+          dc.SetDeviceOrigin(dcOriginX, dcOriginY)
+        index -= 1
+
+    def OnEraseBackground(self, event):
+      """
+        Override OnEraseBackground to avoid erasing background. Instead
+      implement OnDrawBackground to draw/erase the background. This
+      design alternative will eliminate flicker
+      """
+      pass
+
+    def OnMouseEvent(self, event):
+      x, y = event.GetPositionTuple()
+      x, y = self.CalcUnscrolledPosition(x, y)
+      for drawableObject in self.zOrderedDrawableObjects:
+        if drawableObject.bounds.Inside((x, y)):
+          event.m_x = x - drawableObject.bounds.GetX()
+          event.m_y = y - drawableObject.bounds.GetY()
+          if drawableObject.ProcessEvent(event):
+            return True
+
+      if self.autoCreateDistance != 0:
+        if event.ButtonDown() and self.CreateHitTest(x, y):
+            self.dragStart = wx.Point(x, y)
+            self.CaptureMouse()
+            return True
+        elif hasattr(self, 'dragStart'):
+          if event.Dragging():
+            """
+              Clip mouse position to the scrolling window's bounds
+            """
+            boundsX, boundsY = self.GetVirtualSizeTuple()
+            if x < 0:
+              x = 0
+            if x > boundsX:
+              x = boundsX
+            if y < 0:
+              y = 0
+            if y > boundsY:
+              y = boundsY
+
+            deltaX =  x - self.dragStart.x
+            deltaY =  y - self.dragStart.y
+
+            if deltaX >= 0:
+              left = self.dragStart.x
+              width = deltaX
+            else:
+              left = x
+              width = -deltaX
+
+            if deltaY >= 0:
+              top = self.dragStart.y
+              height = deltaY
+            else:
+              top = y
+              height = -deltaY
+            dragRect = wx.Rect(left, top, width, height)
+
+            if not hasattr(self, 'dragCreateDrawableObject'):
+              if(deltaX * deltaX) +(deltaY * deltaY) >(self.autoCreateDistance 
* self.autoCreateDistance):
+                """
+                Create a new drawable object if we've dragged 
autoCreateDistance
+                pixels
+                """
+                object = self.dragCreateDrawableObject = 
self.CreateNewDrawableObject(dragRect,
+                                                                              
self.dragStart,
+                                                                              
wx.Point(x, y))
+                # if we weren't allowed to create one, give up
+                if object is None:
+                    return True
+
+                self.DeSelectAll()
+                object.selected = True
+
+
+                #self.zOrderedDrawableObjects.insert(0, 
self.dragCreateDrawableObject)
+                
#self.RefreshScrolledRect(self.dragCreateDrawableObject.bounds);
+                self.Add(object)
+
+              return True
+            else:
+              if self.dragCreateDrawableObject != None:
+                self.dragCreateDrawableObject.SizeDrag(dragRect,
+                                                        self.dragStart,
+                                                        wx.Point(x, y))
+
+          elif event.ButtonUp():
+            del self.dragStart
+            if hasattr(self, 'dragCreateDrawableObject'):
+                del self.dragCreateDrawableObject
+            self.ReleaseMouse()
+            return True
+      return False
+
+    def OnData(self, dataObject, x, y, result):
+      """
+        Handle default behavior of copy and move
+      """
+      if result == wx.DragMove or result == wx.DragCopy:
+          if(self.internalDnDItem != None) and(result == wx.DragMove):
+              assert(self.zOrderedDrawableObjects.count(self.internalDnDItem) 
== 1)
+
+              drawableObject = 
self.ConvertDataObjectToDrawableObject(dataObject, x, y, True)
+              x = drawableObject.bounds.GetLeft()
+              y = drawableObject.bounds.GetTop()
+
+              self.zOrderedDrawableObjects.remove(self.internalDnDItem)
+              self.zOrderedDrawableObjects.insert(0, self.internalDnDItem)
+              self.internalDnDItem.MoveTo(x, y)
+              self.internalDnDItem.Show(True)
+          else:
+
+              drawableObject = 
self.ConvertDataObjectToDrawableObject(dataObject, x, y, False)
+              x = drawableObject.bounds.GetLeft()
+              y = drawableObject.bounds.GetTop()
+
+              self.zOrderedDrawableObjects.insert(0, drawableObject)
+              self.RefreshScrolledRect(drawableObject.bounds);
+      return result
+
+    def CreateHitTest(self, x, y):
+      """
+        Set self.autoCreateDistance to some value other than zero to enable
+      dragging autoCreateDistance pixels to automatically create new drawable
+      objects.
+        By default, drawable objects are created if you click and drag in the
+      canvas anwhere there isn't a drawable object. You can restrict this 
location
+      that drawable objects are created by overriding this routine
+      """
+      return True
+    """
+      You must implement the following functions
+    """
+    def ConvertDataObjectToDrawableObject(self, dataObject, x, y, move):
+      """
+        You must implement this routine to convert a dataobject, used in
+      drag and drop into a drawable object.
+      """
+      assert(False)
+
+    def CreateNewDrawableObject(self, dragRect, startDrag, endDrag):
+      """
+        You must implement this routine to create new drawable objects by
+      dragging on the blank canvas.
+      """
+      assert(False)
+
+    def DeSelectAll(self):
+      """
+      Mark all selected objects as not selected. Only Refresh the objects
+      that change, don't call Update.
+      """
+      for drawableObject in self.zOrderedDrawableObjects:
+          if(drawableObject.selected):
+              drawableObject.selected = False
+              self.RefreshScrolledRect(drawableObject.bounds)
+
+    # -----------------------------------------------------------------
+    # Additions by GNUe
+    # -----------------------------------------------------------------
+    def Add(self, object):
+      """
+      Add a DrawableObject to the canvas
+      """
+      self.zOrderedDrawableObjects.insert(0, object)
+      self.RefreshScrolledRect(object.bounds);
+
+    def Remove(self, object):
+      self.zOrderedDrawableObjects.remove(object)
+      bounds = object.bounds
+      self.RefreshScrolledRect(bounds)
+      object.Destroy()

Added: trunk/gnue-designer/src/uidrivers/wx/uihelpers/documentcanvas/dnd.py
===================================================================
--- trunk/gnue-designer/src/uidrivers/wx/uihelpers/documentcanvas/dnd.py        
2006-03-31 00:21:28 UTC (rev 8298)
+++ trunk/gnue-designer/src/uidrivers/wx/uihelpers/documentcanvas/dnd.py        
2006-03-31 00:28:05 UTC (rev 8299)
@@ -0,0 +1,143 @@
+#
+# Copyright 2001-2006 Free Software Foundation
+#
+# This file is part of GNU Enterprise
+#
+# GNU Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2, or(at your option) any later version.
+#
+# GNU Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied
+# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+# PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with program; see the file COPYING. If not,
+# write to the Free Software Foundation, Inc., 59 Temple Place
+# - Suite 330, Boston, MA 02111-1307, USA.
+#
+# $Id: TriggerEditor.py 8210 2006-03-07 00:04:31Z jcater $
+
+"""
+Drag and Drop helper classes
+"""
+
+import wx
+
+
+# ===================================================================
+# A draggable image frame
+# ===================================================================
+class wxCanvasDragImage(wx.Frame):
+  """
+  A class similar to wx.DragImage except that it uses a shaped frame
+  to display the image, and that it is always full screen.
+  """
+  def __init__(self, bitmap):
+    super(wxCanvasDragImage, self).__init__(
+            None, -1, "",
+            style = wx.FRAME_SHAPED
+                  | wx.SIMPLE_BORDER
+                  | wx.FRAME_NO_TASKBAR
+                  | wx.STAY_ON_TOP)
+    self.bmp = bitmap
+    w, h = self.bmp.GetWidth(), self.bmp.GetHeight()
+    self.SetClientSize((w, h) )
+    self.hotspot = None
+    self.window = None
+
+    self.Bind(wx.EVT_PAINT, self.OnPaint)
+
+    if "__WXGTK__" in wx.PlatformInfo:
+      # wxGTK requires that the window be created before you can
+      # set its shape, so delay the call to SetWindowShape until
+      # this event.
+      self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
+    else:
+      # On wxMSW and wxMac the window has already been created, so go for it.
+      self.SetWindowShape()
+
+  def SetWindowShape(self, evt=None, hotspot=None):
+    # Use the bitmap's mask to determine the region
+    rgn = wx.RegionFromBitmap(self.bmp)
+    if hotspot is not None:
+      # punch a hole in the region at the hotspot to allow mouse events
+      # through to the window below
+      rect = wx.Rect(hotspot.x-1, hotspot.y-1, 3, 3)
+      rgn.SubtractRect(rect)
+    self.SetShape(rgn)
+
+  def BeginDrag(self, hotspot, window, *ignoreOthers):
+    self.hotspot = wx.Point(hotspot[0], hotspot[1])
+    if "__WXGTK__" not in wx.PlatformInfo:
+      self.SetWindowShape(hotspot = self.hotspot)
+    self.window = window
+    if self.window:
+      self.window.CaptureMouse()
+
+  def EndDrag(self, doDestroy=True):
+    if self.window and self.window.HasCapture():
+      self.window.ReleaseMouse()
+    self.Hide()
+    if doDestroy:
+      self.Destroy()
+
+  def Move(self, pt):
+    """
+    Move the image to a new location on screen.  The pt parameter
+    is a point in client coordinants relative to the window
+    specifed in BeginDrag. (Only for compatibility with
+    wx.DragImage, otherwise I would just use screen coordinants...)
+    """
+    pt2 = pt
+    if self.window:
+      pt2 = self.window.ClientToScreen(pt)
+    self.SetPosition(pt2 - self.hotspot)
+
+  def Show(self):
+    wx.Frame.Show(self)
+    self.Update()
+
+  def OnPaint(self, evt):
+    dc = wx.PaintDC(self)
+    dc.DrawBitmap(self.bmp, 0, 0, True)
+
+
+# ===================================================================
+# A draggable drop source
+# ===================================================================
+class wxCanvasDropSource(wx.DropSource):
+  def __init__(self, drawableObject, dataObject):
+    super(wxCanvasDropSource, self).__init__(drawableObject.canvas)
+    self.drawableObject = drawableObject
+    self.SetData(dataObject)
+
+  def GiveFeedback(self, effect):
+    windowX, windowY = wx.GetMousePosition()
+    self.drawableObject.Show(effect != wx.DragMove)
+    x, y = self.drawableObject.canvas.ScreenToClientXY(windowX, windowY)
+    self.drawableObject.dragImage.Move((x, y))
+    return False
+
+
+# ===================================================================
+# A draggable drop target
+# ===================================================================
+class wxCanvasDropTarget(wx.PyDropTarget):
+  def __init__(self, canvas, dropTargetDataObject):
+    super(wxCanvasDropTarget, self).__init__()
+    self.canvas = canvas
+    self.dataObject = dropTargetDataObject
+    self.SetDataObject(dropTargetDataObject)
+
+  def OnData(self, x, y, result):
+    """
+      Delegate functionality to the canvas
+    """
+    if(self.GetData()):
+      x, y = self.canvas.CalcUnscrolledPosition(x, y)
+      result = self.canvas.OnData(self.dataObject, x, y, result)
+    return result
+

Added: trunk/gnue-designer/src/uidrivers/wx/uihelpers/documentcanvas/widget.py
===================================================================
--- trunk/gnue-designer/src/uidrivers/wx/uihelpers/documentcanvas/widget.py     
2006-03-31 00:21:28 UTC (rev 8298)
+++ trunk/gnue-designer/src/uidrivers/wx/uihelpers/documentcanvas/widget.py     
2006-03-31 00:28:05 UTC (rev 8299)
@@ -0,0 +1,209 @@
+#
+# Copyright 2001-2006 Free Software Foundation
+#
+# This file is part of GNU Enterprise
+#
+# GNU Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2, or(at your option) any later version.
+#
+# GNU Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied
+# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+# PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with program; see the file COPYING. If not,
+# write to the Free Software Foundation, Inc., 59 Temple Place
+# - Suite 330, Boston, MA 02111-1307, USA.
+#
+# $Id: TriggerEditor.py 8210 2006-03-07 00:04:31Z jcater $
+
+#
+# These classes were based on SimpleCanvas from OSA's Chandler
+# application, but heavily commented, debugged, and extended.
+#
+
+import wx
+
+# ===================================================================
+# A Drawable canvas widget
+# ===================================================================
+class DocumentWidget(wx.EvtHandler):
+    def __init__(self, canvas):
+      super(wxSimpleDrawableObject, self).__init__()
+
+      self.bounds = wx.Rect()
+      self.canvas = canvas
+      self.visible = True
+      self.selected = False
+      self.dragStartPos = None
+
+      self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseEvent)
+
+    def MoveTo(self, x, y):
+      self.canvas.RefreshScrolledRect(self.bounds);
+      self.bounds.SetLeft(x)
+      self.bounds.SetTop(y)
+      self.canvas.RefreshScrolledRect(self.bounds);
+
+    def SetSize(self, width, height):
+      self.canvas.RefreshScrolledRect(self.bounds);
+      self.bounds.SetWidth(width)
+      self.bounds.SetHeight(height)
+      self.canvas.RefreshScrolledRect(self.bounds);
+
+    def OnMouseEvent(self, event):
+      x, y = event.GetPositionTuple()
+      if event.ButtonDown(1):
+        if self.SelectedHitTest(x, y) :
+          self.canvas.DeSelectAll()
+          self.SetSelected()
+          self.canvas.Update()
+          if self.DragHitTest(x, y):
+            self.dragStartPos =(x, y)
+        else:
+          self.dragStartPos =(x,y)
+      elif event.ButtonUp(1):
+        self.dragStartPos = None
+      elif event.Dragging() and event.LeftIsDown():
+        tolerance = 2
+        if abs(x - self.dragStartPos[0]) > tolerance or abs(y - 
self.dragStartPos[1]) > tolerance:
+          self.DoDrag(x, y)
+          return True
+      event.Skip()
+      return False
+
+    def SetBounds(self, bounds):
+      self.canvas.RefreshScrolledRect(self.bounds);
+      self.bounds = bounds
+      self.canvas.RefreshScrolledRect(self.bounds);
+
+    def Show(self, show):
+
+      # Make sure show is a Boolean
+      show = bool(show)
+
+      if(show ^ self.visible):
+        self.visible = show
+        self.canvas.RefreshScrolledRect(self.bounds);
+        self.canvas.Update()
+
+    def ConvertToCanvasDeviceCoordinates(self, x, y):
+      return self.canvas.CalcScrolledPosition(self.bounds.GetLeft() + x,
+                                                self.bounds.GetTop() + y)
+
+    def DoDrag(self, x, y):
+      """
+        Implement all the drag and drop functionality:
+      """
+
+      """
+        Create the dragImage and begin dragging over the full screen
+      """
+      offscreenBuffer = wx.EmptyBitmap(self.bounds.GetWidth(), 
self.bounds.GetHeight())
+      memoryDC = wx.MemoryDC()
+      memoryDC.SelectObject(offscreenBuffer)
+
+      memoryDC.BeginDrawing()
+      memoryDC.Clear()
+      self.Draw(memoryDC)
+
+      maskBitmap = wx.EmptyBitmap(self.bounds.GetWidth(), 
self.bounds.GetHeight(), 1)
+      memoryDC.SelectObject(maskBitmap)
+
+      memoryDC.SetBackground(wx.BLACK_BRUSH)
+      memoryDC.Clear()
+
+      self.DrawMask(memoryDC)
+      memoryDC.EndDrawing()
+
+      memoryDC.SelectObject(wx.NullBitmap)
+
+      if "__WXMAC__" in wx.PlatformInfo:  # workaround for wxMac bug
+          offscreenBuffer.SetMask(wx.Mask(maskBitmap, wx.BLACK))
+      else:
+          offscreenBuffer.SetMask(wx.Mask(maskBitmap))
+
+      """
+        Create the dragImage and begin dragging
+      """
+      if "__WXGTK__" in wx.PlatformInfo:
+          # The "hole punching" trick dosen't work on wxGTK, move the hostspot
+          # to be just outside the image
+          x, y = -1, -1
+      self.dragImage = wxCanvasDragImage(offscreenBuffer)
+
+      self.dragImage.BeginDrag(wx.Point(x,y), self.canvas, True)
+      self.dragImage.Move(self.ConvertToCanvasDeviceCoordinates(x, y))
+      self.dragImage.Show()
+
+      """
+        We need to keep a reference to the dataObject, rather than create
+      it in the construction because wxCanvasDropSource doesn't own the
+      data so the garbage collector will delete it.
+      """
+      dataObject = self.ConvertDrawableObjectToDataObject(x, y)
+      dropSource = wxCanvasDropSource(self, dataObject)
+
+      self.canvas.internalDnDItem = self
+      result = dropSource.DoDragDrop(wx.Drag_AllowMove)
+      self.canvas.internalDnDItem = None
+      self.dragImage.Hide()
+      self.dragImage.EndDrag()
+      del self.dragImage
+
+  def DrawMask(self, dc):
+    """
+      optionally implement this routine to draw a mask
+    """
+    pass
+
+  def SizeDrag(self, dragRect, startDrag, endDrag):
+    self.canvas.RefreshScrolledRect(self.bounds)
+    self.bounds = dragRect
+    self.canvas.RefreshScrolledRect(self.bounds)
+
+  """
+    You must implement the following functions
+  """
+  def Draw(self, dc):
+    """
+      You must implement this routine to do draw
+    """
+    assert(False)
+
+  def DragHitTest(self, x, y):
+    """
+      You must implement this routine to do hit testing for dragable region
+    of drawable object
+    """
+    assert(False)
+
+  def ConvertDrawableObjectToDataObject(self, x, y):
+    """
+      You must implement this routine to create data object for drag and drop
+    """
+    assert(False)
+
+  def SelectedHitTest(self, x, y):
+    """
+    You must implement this routine to do hit testing to identify the region
+    for selecting the object.
+    """
+    assert(False)
+
+  def SetSelected(self, selected=True):
+    """
+    Sets the selected bit for this object. Does a canvas refresh on the object
+    if it has changed state. Does not call Update on the canvas.
+    """
+    # Use the same trick as Show()
+    selected = bool(selected)
+
+    # Only do a refresh if we've changed state.
+    if(selected ^ self.selected):
+      self.selected = selected
+      self.canvas.RefreshScrolledRect(self.bounds);
+





reply via email to

[Prev in Thread] Current Thread [Next in Thread]