]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/samples/ide/activegrid/tool/AbstractEditor.py
removed code inside USE_SIZABLE_CALENDAR, we should allow making the main calendar...
[wxWidgets.git] / wxPython / samples / ide / activegrid / tool / AbstractEditor.py
index 8369738428b2469d4decdf5227b7e32d6784bbb4..8a2e9c5232fac8ac742e774344fb87151f1adb62 100644 (file)
@@ -23,6 +23,20 @@ SHAPE_BRUSH = wx.Brush("WHEAT", wx.SOLID)
 LINE_BRUSH = wx.BLACK_BRUSH
 INACTIVE_SELECT_BRUSH = wx.Brush("LIGHT BLUE", wx.SOLID)
 
 LINE_BRUSH = wx.BLACK_BRUSH
 INACTIVE_SELECT_BRUSH = wx.Brush("LIGHT BLUE", wx.SOLID)
 
+NORMALFONT = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
+SLANTFONT = wx.Font(NORMALFONT.GetPointSize(), NORMALFONT.GetFamily(), wx.SLANT, NORMALFONT.GetWeight())
+BOLDFONT = wx.Font(NORMALFONT.GetPointSize(), NORMALFONT.GetFamily(), NORMALFONT.GetStyle(), wx.BOLD)
+
+DEFAULT_BACKGROUND_COLOR = wx.Colour(0xEE, 0xEE, 0xEE)
+HEADER_BRUSH = wx.Brush(wx.Colour(0xDB, 0xEB, 0xFF), wx.SOLID)
+BODY_BRUSH = wx.Brush(wx.WHITE, wx.SOLID)
+
+
+PARKING_VERTICAL = 1
+PARKING_HORIZONTAL = 2
+PARKING_OFFSET = 30    # space between shapes
+
+FORCE_REDRAW_METHOD = "ForceRedraw"
 
 def GetRawModel(model):
     if hasattr(model, "GetRawModel"):
 
 def GetRawModel(model):
     if hasattr(model, "GetRawModel"):
@@ -32,6 +46,27 @@ def GetRawModel(model):
     return rawModel
 
 
     return rawModel
 
 
+def GetLabel(model):
+    model = GetRawModel(model)
+    if hasattr(model, "__xmlname__"):
+        label = model.__xmlname__
+        try:
+            if (len(label) > 0):
+                label = label[0].upper() + label[1:]
+            if (hasattr(model, "complexType")):
+                label += ': %s/%s' % (model.complexType.name, model.name)
+            else:
+                if model.name:
+                    label += ': %s' % model.name
+                elif model.ref:
+                    label += ': %s' % model.ref
+        except AttributeError:
+            pass
+    else:
+        label = str(model)
+    return label
+
+
 class CanvasView(wx.lib.docview.View):
 
 
 class CanvasView(wx.lib.docview.View):
 
 
@@ -40,16 +75,27 @@ class CanvasView(wx.lib.docview.View):
     #----------------------------------------------------------------------------
 
 
     #----------------------------------------------------------------------------
 
 
-    def __init__(self, brush = SHAPE_BRUSH):
+    def __init__(self, brush=SHAPE_BRUSH, background=DEFAULT_BACKGROUND_COLOR):
         wx.lib.docview.View.__init__(self)
         self._brush = brush
         wx.lib.docview.View.__init__(self)
         self._brush = brush
+        self._backgroundColor = background
         self._canvas = None
         self._pt1 = None
         self._pt2 = None
         self._needEraseLasso = False
         self._propShape = None
         self._canvas = None
         self._pt1 = None
         self._pt2 = None
         self._needEraseLasso = False
         self._propShape = None
+        self._maxWidth = 2000
+        self._maxHeight = 16000
+        self._valetParking = False
 
 
 
 
+    def OnDraw(self, dc):
+        """ for Print Preview and Print """
+        dc.BeginDrawing()
+        self._canvas.Redraw(dc)
+        dc.EndDrawing()
+        
+
     def OnCreate(self, doc, flags):
         frame = wx.GetApp().CreateDocumentFrame(self, doc, flags)
         frame.Show()
     def OnCreate(self, doc, flags):
         frame = wx.GetApp().CreateDocumentFrame(self, doc, flags)
         frame.Show()
@@ -59,6 +105,7 @@ class CanvasView(wx.lib.docview.View):
         frame.SetSizer(sizer)
         frame.Layout()        
         self.Activate()
         frame.SetSizer(sizer)
         frame.Layout()        
         self.Activate()
+        wx.EVT_RIGHT_DOWN(self._canvas, self.OnRightClick)
         return True
         
 
         return True
         
 
@@ -77,11 +124,15 @@ class CanvasView(wx.lib.docview.View):
 
 
     def OnFocus(self, event):
 
 
     def OnFocus(self, event):
-        self.SetFocus()
         self.FocusColorPropertyShape(True)
         event.Skip()
 
 
         self.FocusColorPropertyShape(True)
         event.Skip()
 
 
+    def FocusOnClick(self, event):
+        self.SetFocus()
+        event.Skip()
+
+
     def OnKillFocus(self, event):
         self.FocusColorPropertyShape(False)
         event.Skip()
     def OnKillFocus(self, event):
         self.FocusColorPropertyShape(False)
         event.Skip()
@@ -120,25 +171,41 @@ class CanvasView(wx.lib.docview.View):
         wx.EVT_KEY_DOWN(self._canvas, self.OnKeyPressed)
         
         # need this otherwise mouse clicks don't set focus to this view
         wx.EVT_KEY_DOWN(self._canvas, self.OnKeyPressed)
         
         # need this otherwise mouse clicks don't set focus to this view
-        wx.EVT_LEFT_DOWN(self._canvas, self.OnFocus)
-        wx.EVT_LEFT_DCLICK(self._canvas, self.OnFocus)
-        wx.EVT_RIGHT_DOWN(self._canvas, self.OnFocus)
-        wx.EVT_RIGHT_DCLICK(self._canvas, self.OnFocus)
-        wx.EVT_MIDDLE_DOWN(self._canvas, self.OnFocus)
-        wx.EVT_MIDDLE_DCLICK(self._canvas, self.OnFocus)
+        wx.EVT_LEFT_DOWN(self._canvas, self.FocusOnClick)
+        wx.EVT_LEFT_DCLICK(self._canvas, self.FocusOnClick)
+        wx.EVT_RIGHT_DOWN(self._canvas, self.FocusOnClick)
+        wx.EVT_RIGHT_DCLICK(self._canvas, self.FocusOnClick)
+        wx.EVT_MIDDLE_DOWN(self._canvas, self.FocusOnClick)
+        wx.EVT_MIDDLE_DCLICK(self._canvas, self.FocusOnClick)
         
         wx.EVT_KILL_FOCUS(self._canvas, self.OnKillFocus)
         wx.EVT_SET_FOCUS(self._canvas, self.OnFocus)
 
         
         wx.EVT_KILL_FOCUS(self._canvas, self.OnKillFocus)
         wx.EVT_SET_FOCUS(self._canvas, self.OnFocus)
 
-        maxWidth = 2000
-        maxHeight = 16000
-        self._canvas.SetScrollbars(20, 20, maxWidth / 20, maxHeight / 20)
+        self._canvas.SetScrollbars(20, 20, self._maxWidth / 20, self._maxHeight / 20)
         
         
-        self._canvas.SetBackgroundColour(wx.WHITE)
+        self._canvas.SetBackgroundColour(self._backgroundColor)
         self._diagram = ogl.Diagram()
         self._canvas.SetDiagram(self._diagram)
         self._diagram.SetCanvas(self._canvas)
         self._diagram = ogl.Diagram()
         self._canvas.SetDiagram(self._diagram)
         self._diagram.SetCanvas(self._canvas)
+        self._canvas.SetFont(NORMALFONT)
+
 
 
+    def OnClear(self, event):
+        """ Deletion of selected objects from view.
+        *Must Override*
+        """
+        self.SetPropertyModel(None)
+                  
+
+    def SetLastRightClick(self, x, y):
+        self._lastRightClick = (x,y)
+        
+
+    def GetLastRightClick(self):
+        if hasattr(self, "_lastRightClick"):
+            return self._lastRightClick
+        return (-1,-1)
+        
 
     def OnKeyPressed(self, event):
         key = event.KeyCode()
 
     def OnKeyPressed(self, event):
         key = event.KeyCode()
@@ -148,7 +215,43 @@ class CanvasView(wx.lib.docview.View):
             event.Skip()
 
 
             event.Skip()
 
 
+    def OnRightClick(self, event):
+        """ force selection underneath right click position. """
+        self.Activate()
+        self._canvas.SetFocus()
+
+        dc = wx.ClientDC(self._canvas)
+        self._canvas.PrepareDC(dc)
+        x, y = event.GetLogicalPosition(dc)  # this takes into account scrollbar offset
+        self.SetLastRightClick(x, y)
+        shape = self._canvas.FindShape(x, y)[0]
+        
+        model = None
+        if not shape:
+            self.SetSelection(None)
+            self.SetPropertyShape(None)
+        elif hasattr(shape, "GetModel"):
+            self.BringToFront(shape)
+            self.SetPropertyShape(shape)
+            self.SetSelection(shape)
+            shape.Select(True, dc)
+            model = shape.GetModel()
+        elif shape.GetParent() and isinstance(shape.GetParent(), ogl.CompositeShape):  # ComplexTypeHeader for ComplexTypeShape
+            self.BringToFront(shape)
+            self.SetPropertyShape(shape.GetParent())
+            self.SetSelection(shape.GetParent())
+            shape.GetParent().Select(True, dc)
+            model = shape.GetParent().GetModel()
+
+        self.SetPropertyModel(model)
+        
+        return (shape, model)
+
+
     def OnLeftClick(self, event):
     def OnLeftClick(self, event):
+        self.Activate()
+        self._canvas.SetFocus()
+        
         self.EraseRubberBand()
 
         dc = wx.ClientDC(self._canvas)
         self.EraseRubberBand()
 
         dc = wx.ClientDC(self._canvas)
@@ -170,12 +273,15 @@ class CanvasView(wx.lib.docview.View):
             pass
         else:
             # click on empty part of canvas, deselect everything
             pass
         else:
             # click on empty part of canvas, deselect everything
+            forceRedrawShapes = []
             needRefresh = False
             for shape in self._diagram.GetShapeList():
                 if hasattr(shape, "GetModel"):
                     if shape.Selected():
                         needRefresh = True
                         shape.Select(False, dc)
             needRefresh = False
             for shape in self._diagram.GetShapeList():
                 if hasattr(shape, "GetModel"):
                     if shape.Selected():
                         needRefresh = True
                         shape.Select(False, dc)
+                        if hasattr(shape, FORCE_REDRAW_METHOD):
+                            forceRedrawShapes.append(shape)
             if needRefresh:
                 self._canvas.Redraw(dc)
 
             if needRefresh:
                 self._canvas.Redraw(dc)
 
@@ -184,7 +290,8 @@ class CanvasView(wx.lib.docview.View):
         if len(self.GetSelection()) == 0:
             self.SetPropertyShape(None)
 
         if len(self.GetSelection()) == 0:
             self.SetPropertyShape(None)
 
-
+        for shape in forceRedrawShapes:
+            shape.ForceRedraw()
 
     def OnLeftDoubleClick(self, event):
         propertyService = wx.GetApp().GetService(PropertyService.PropertyService)
 
     def OnLeftDoubleClick(self, event):
         propertyService = wx.GetApp().GetService(PropertyService.PropertyService)
@@ -311,24 +418,42 @@ class CanvasView(wx.lib.docview.View):
         dc.EndDrawing()
 
 
         dc.EndDrawing()
 
 
-    def FindParkingSpot(self, width, height):
-        """ given a width and height, find a upper left corner where shape can be parked without overlapping other shape """
-        offset = 30  # space between shapes
-        x = offset
-        y = offset
-        maxX = 700  # max distance to the right where we'll place tables
+    def SetValetParking(self, enable=True):
+        """ If valet parking is enabled, remember last parking spot and try for a spot near it """
+        self._valetParking = enable
+        if enable:
+            self._valetPosition = None
+        
+
+    def FindParkingSpot(self, width, height, parking=PARKING_HORIZONTAL, x=PARKING_OFFSET, y=PARKING_OFFSET):
+        """
+            Given a width and height, find a upper left corner where shape can be parked without overlapping other shape
+        """
+        if self._valetParking and self._valetPosition:
+            x, y = self._valetPosition
+        
+        max = 700  # max distance to the right where we'll place tables
         noParkingSpot = True
 
         while noParkingSpot:
             point = self.isSpotOccupied(x, y, width, height)
             if point:
         noParkingSpot = True
 
         while noParkingSpot:
             point = self.isSpotOccupied(x, y, width, height)
             if point:
-                x = point[0] + offset
-                if x > maxX:
-                    x = offset
-                    y = point[1] + offset
+                if parking == PARKING_HORIZONTAL:
+                    x = point[0] + PARKING_OFFSET
+                    if x > max:
+                        x = PARKING_OFFSET
+                        y = point[1] + PARKING_OFFSET
+                else:  # parking == PARKING_VERTICAL:
+                    y = point[1] + PARKING_OFFSET
+                    if y > max:
+                        y = PARKING_OFFSET
+                        x = point[0] + PARKING_OFFSET
             else:
                 noParkingSpot = False
 
             else:
                 noParkingSpot = False
 
+        if self._valetParking:
+            self._valetPosition = (x, y)
+            
         return x, y
 
 
         return x, y
 
 
@@ -340,7 +465,7 @@ class CanvasView(wx.lib.docview.View):
         y2 = y + height
 
         for shape in self._diagram.GetShapeList():
         y2 = y + height
 
         for shape in self._diagram.GetShapeList():
-            if isinstance(shape, ogl.RectangleShape) or isinstance(shape, ogl.EllipseShape):
+            if isinstance(shape, ogl.RectangleShape) or isinstance(shape, ogl.EllipseShape) or isinstance(shape, ogl.PolygonShape):
                 if shape.GetParent() and isinstance(shape.GetParent(), ogl.CompositeShape):
                     # skip, part of a composite shape
                     continue
                 if shape.GetParent() and isinstance(shape.GetParent(), ogl.CompositeShape):
                     # skip, part of a composite shape
                     continue
@@ -370,7 +495,7 @@ class CanvasView(wx.lib.docview.View):
     # Canvas methods
     #----------------------------------------------------------------------------
 
     # Canvas methods
     #----------------------------------------------------------------------------
 
-    def AddShape(self, shape, x = None, y = None, pen = None, brush = None, text = None, eventHandler = None):
+    def AddShape(self, shape, x = None, y = None, pen = None, brush = None, text = None, eventHandler = None, shown=True):
         if isinstance(shape, ogl.CompositeShape):
             dc = wx.ClientDC(self._canvas)
             self._canvas.PrepareDC(dc)
         if isinstance(shape, ogl.CompositeShape):
             dc = wx.ClientDC(self._canvas)
             self._canvas.PrepareDC(dc)
@@ -390,9 +515,9 @@ class CanvasView(wx.lib.docview.View):
             shape.SetBrush(brush)
         if text:
             shape.AddText(text)
             shape.SetBrush(brush)
         if text:
             shape.AddText(text)
-        shape.SetShadowMode(ogl.SHADOW_RIGHT)
+        shape.SetShadowMode(ogl.SHADOW_NONE)
         self._diagram.AddShape(shape)
         self._diagram.AddShape(shape)
-        shape.Show(True)
+        shape.Show(shown)
         if not eventHandler:
             eventHandler = EditorCanvasShapeEvtHandler(self)
         eventHandler.SetShape(shape)
         if not eventHandler:
             eventHandler = EditorCanvasShapeEvtHandler(self)
         eventHandler.SetShape(shape)
@@ -410,37 +535,55 @@ class CanvasView(wx.lib.docview.View):
 
         if shape:
             shape.Select(False)
 
         if shape:
             shape.Select(False)
-            self._diagram.RemoveShape(shape)
-            if isinstance(shape, ogl.CompositeShape):
+            for line in shape.GetLines():
+                shape.RemoveLine(line)
+                self._diagram.RemoveShape(line)
+                line.Delete()
+            for obj in self._diagram.GetShapeList():
+                for line in obj.GetLines():
+                    if self.IsShapeContained(shape, line.GetTo()) or self.IsShapeContained(shape, line.GetFrom()):
+                        obj.RemoveLine(line)
+                        self._diagram.RemoveShape(line)
+                        line.Delete()
+                    if line == shape:
+                        obj.RemoveLine(line)
+                        self._diagram.RemoveShape(line)
+                        line.Delete()
+                    
+            if self._canvas:
                 shape.RemoveFromCanvas(self._canvas)
                 shape.RemoveFromCanvas(self._canvas)
+            self._diagram.RemoveShape(shape)
+            shape.Delete()
+
+
+    def IsShapeContained(self, parent, shape):
+        if parent == shape:
+            return True
+        elif shape.GetParent():
+            return self.IsShapeContained(parent, shape.GetParent())
+            
+        return False
 
 
     def UpdateShape(self, model):
         for shape in self._diagram.GetShapeList():
             if hasattr(shape, "GetModel") and shape.GetModel() == model:
 
 
     def UpdateShape(self, model):
         for shape in self._diagram.GetShapeList():
             if hasattr(shape, "GetModel") and shape.GetModel() == model:
+                oldw, oldh = shape.GetBoundingBoxMax()
+                oldx = shape.GetX()
+                oldy = shape.GetY()
+
                 x, y, w, h = model.getEditorBounds()
                 newX = x + w / 2
                 newY = y + h / 2
                 x, y, w, h = model.getEditorBounds()
                 newX = x + w / 2
                 newY = y + h / 2
-                changed = False
-                if isinstance(shape, ogl.CompositeShape):
-                    if shape.GetX() != newX or shape.GetY() != newY:
-                        dc = wx.ClientDC(self._canvas)
-                        self._canvas.PrepareDC(dc)
-                        shape.SetSize(w, h, True)  # wxBug: SetSize must be before Move because links won't go to the right place
-                        shape.Move(dc, newX, newY)  # wxBug: Move must be before SetSize because links won't go to the right place
-                        changed = True
-                else:
-                    oldw, oldh = shape.GetBoundingBoxMax()
-                    oldx = shape.GetX()
-                    oldy = shape.GetY()
-                    if oldw != w or oldh != h or oldx != newX or oldy != newY:
-                        shape.SetSize(w, h)
-                        shape.SetX(newX)
-                        shape.SetY(newY)
-                        changed = True
-                if changed:
+                
+                if oldw != w or oldh != h or oldx != newX or oldy != newY:
+                    dc = wx.ClientDC(self._canvas)
+                    self._canvas.PrepareDC(dc)
+                    shape.SetSize(w, h, True)   # wxBug: SetSize must be before Move because links won't go to the right place
+                    shape.Move(dc, newX, newY)  # wxBug: Move must be after SetSize because links won't go to the right place
                     shape.ResetControlPoints()
                     self._canvas.Refresh()
                     shape.ResetControlPoints()
                     self._canvas.Refresh()
+                    
                 break
 
 
                 break
 
 
@@ -451,6 +594,10 @@ class CanvasView(wx.lib.docview.View):
         return None
 
 
         return None
 
 
+    def GetShapeCount(self):
+        return self._diagram.GetCount()
+
+
     def GetSelection(self):
         return filter(lambda shape: shape.Selected(), self._diagram.GetShapeList())
 
     def GetSelection(self):
         return filter(lambda shape: shape.Selected(), self._diagram.GetShapeList())
 
@@ -496,7 +643,10 @@ class CanvasView(wx.lib.docview.View):
 
 
     def ScrollVisible(self, shape):
 
 
     def ScrollVisible(self, shape):
-        xUnit, yUnit = shape._canvas.GetScrollPixelsPerUnit()
+        if not shape:
+            return
+            
+        xUnit, yUnit = self._canvas.GetScrollPixelsPerUnit()
         scrollX, scrollY = self._canvas.GetViewStart()  # in scroll units
         scrollW, scrollH = self._canvas.GetSize()  # in pixels
         w, h = shape.GetBoundingBoxMax() # in pixels
         scrollX, scrollY = self._canvas.GetViewStart()  # in scroll units
         scrollW, scrollH = self._canvas.GetSize()  # in pixels
         w, h = shape.GetBoundingBoxMax() # in pixels
@@ -534,7 +684,10 @@ class CanvasView(wx.lib.docview.View):
 
         # erase old selection if it still exists
         if self._propShape and self._propShape in self._diagram.GetShapeList():
 
         # erase old selection if it still exists
         if self._propShape and self._propShape in self._diagram.GetShapeList():
-            self._propShape.SetBrush(self._brush)
+            if hasattr(self._propShape, "DEFAULT_BRUSH"):
+                self._propShape.SetBrush(self._propShape.DEFAULT_BRUSH)
+            else:
+                self._propShape.SetBrush(self._brush)
             if (self._propShape._textColourName in ["BLACK", "WHITE"]):  # Would use GetTextColour() but it is broken
                 self._propShape.SetTextColour("BLACK", 0)
             self._propShape.Draw(dc)
             if (self._propShape._textColourName in ["BLACK", "WHITE"]):  # Would use GetTextColour() but it is broken
                 self._propShape.SetTextColour("BLACK", 0)
             self._propShape.Draw(dc)
@@ -578,6 +731,9 @@ class CanvasView(wx.lib.docview.View):
                 self._propShape.SetTextColour("WHITE", 0)
             self._propShape.Draw(dc)
 
                 self._propShape.SetTextColour("WHITE", 0)
             self._propShape.Draw(dc)
 
+            if hasattr(self._propShape, FORCE_REDRAW_METHOD):
+                self._propShape.ForceRedraw()
+
         dc.EndDrawing()
 
 
         dc.EndDrawing()
 
 
@@ -637,9 +793,10 @@ class EditorCanvasShapeEvtHandler(ogl.ShapeEvtHandler):
             if shape:
                 model = shape.GetModel()
 
             if shape:
                 model = shape.GetModel()
 
-        self._view.SetSelection(model, keys == self.SHIFT_KEY or keys == self.CONTROL_KEY)
-        self._view.SetPropertyShape(shape)
-        self._view.SetPropertyModel(model)
+        if model:
+            self._view.SetSelection(model, keys == self.SHIFT_KEY or keys == self.CONTROL_KEY)
+            self._view.SetPropertyShape(shape)
+            self._view.SetPropertyModel(model)
 
 
     def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
 
 
     def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
@@ -654,7 +811,16 @@ class EditorCanvasShapeEvtHandler(ogl.ShapeEvtHandler):
         self._view.SetSelection(model, keys == self.SHIFT_KEY or keys == self.CONTROL_KEY)
 
 
         self._view.SetSelection(model, keys == self.SHIFT_KEY or keys == self.CONTROL_KEY)
 
 
+    def OnMovePre(self, dc, x, y, oldX, oldY, display):
+        """ Prevent objects from being dragged outside of viewable area """
+        if (x < 0) or (y < 0) or (x > self._view._maxWidth) or (y > self._view._maxHeight):
+            return False
+
+        return ogl.ShapeEvtHandler.OnMovePre(self, dc, x, y, oldX, oldY, display)
+
+
     def OnMovePost(self, dc, x, y, oldX, oldY, display):
     def OnMovePost(self, dc, x, y, oldX, oldY, display):
+        """ Update the model's record of where the shape should be.  Also enable redo/undo.  """
         if x == oldX and y == oldY:
             return
         if not self._view.GetDocument():
         if x == oldX and y == oldY:
             return
         if not self._view.GetDocument():