]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/samples/ide/activegrid/tool/AbstractEditor.py 
   1  #----------------------------------------------------------------------------    2  # Name:         AbstractEditor.py    3  # Purpose:      Non-text editor for DataModel and Process    5  # Author:       Peter Yared, Morgan Hua    9  # Copyright:    (c) 2004-2005 ActiveGrid, Inc.   10  # License:      wxWindows License   11  #----------------------------------------------------------------------------   16  import  wx
. lib
. ogl 
as  ogl
  17  import  PropertyService
  21  SELECT_BRUSH 
=  wx
. Brush ( "BLUE" ,  wx
. SOLID
)   22  SHAPE_BRUSH 
=  wx
. Brush ( "WHEAT" ,  wx
. SOLID
)   23  LINE_BRUSH 
=  wx
. BLACK_BRUSH
  26  def  GetRawModel ( model
):   27      if  hasattr ( model
,  "GetRawModel" ):   28          rawModel 
=  model
. GetRawModel ()   34  class  CanvasView ( wx
. lib
. docview
. View
):   37      #----------------------------------------------------------------------------   39      #----------------------------------------------------------------------------   42      def  __init__ ( self
,  brush 
=  SHAPE_BRUSH
):   43          wx
. lib
. docview
. View
.__ init
__ ( self
)   48          self
._ needEraseLasso 
=  False   49          self
._ propShape 
=  None   52      def  OnCreate ( self
,  doc
,  flags
):   53          frame 
=  wx
. GetApp (). CreateDocumentFrame ( self
,  doc
,  flags
)   56          self
._ CreateCanvas
( frame
)   57          sizer
. Add ( self
._ canvas
,  1 ,  wx
. EXPAND
,  0 )   64      def  OnActivateView ( self
,  activate
,  activeView
,  deactiveView
):   65          if  activate 
and  self
._ canvas
:   66              # In MDI mode just calling set focus doesn't work and in SDI mode using CallAfter causes an endless loop   67              if  self
. GetDocumentManager (). GetFlags () &  wx
. lib
. docview
. DOC_SDI
:   68                  self
._ canvas
. SetFocus ()   70                  wx
. CallAfter ( self
._ canvas
. SetFocus
)   73      def  OnClose ( self
,  deleteWindow 
=  True ):   74          statusC 
=  wx
. GetApp (). CloseChildDocuments ( self
. GetDocument ())   75          statusP 
=  wx
. lib
. docview
. View
. OnClose ( self
,  deleteWindow 
=  deleteWindow
)   76          if  hasattr ( self
,  "ClearOutline" ):   77              wx
. CallAfter ( self
. ClearOutline
)   # need CallAfter because when closing the document, it is Activated and then Close, so need to match OnActivateView's CallAfter   78          if not  ( statusC 
and  statusP
):   81          if  deleteWindow 
and  self
. GetFrame ():   82              self
. GetFrame (). Destroy ()   86      def  _CreateCanvas ( self
,  parent
):   87          self
._ canvas 
=  ogl
. ShapeCanvas ( parent
)   88          wx
. EVT_LEFT_DOWN ( self
._ canvas
,  self
. OnLeftClick
)   89          wx
. EVT_LEFT_UP ( self
._ canvas
,  self
. OnLeftUp
)   90          wx
. EVT_MOTION ( self
._ canvas
,  self
. OnLeftDrag
)   91          wx
. EVT_LEFT_DCLICK ( self
._ canvas
,  self
. OnLeftDoubleClick
)   92          wx
. EVT_KEY_DOWN ( self
._ canvas
,  self
. OnKeyPressed
)   96          self
._ canvas
. SetScrollbars ( 20 ,  20 ,  maxWidth 
/  20 ,  maxHeight 
/  20 )   98          self
._ canvas
. SetBackgroundColour ( wx
. WHITE
)   99          self
._ diagram 
=  ogl
. Diagram ()  100          self
._ canvas
. SetDiagram ( self
._ diagram
)  101          self
._ diagram
. SetCanvas ( self
._ canvas
)  104      def  OnKeyPressed ( self
,  event
):  105          key 
=  event
. KeyCode ()  106          if  key 
==  wx
. WXK_DELETE
:  112      def  OnLeftClick ( self
,  event
):  113          self
. EraseRubberBand ()  115          dc 
=  wx
. ClientDC ( self
._ canvas
)  116          self
._ canvas
. PrepareDC ( dc
)  118          # keep track of mouse down for group select  119          self
._ pt
1  =  event
. GetLogicalPosition ( dc
)   # this takes into account scrollbar offset  122          shape 
=  self
._ canvas
. FindShape ( self
._ pt
1 [ 0 ],  self
._ pt
1 [ 1 ])[ 0 ]  124              self
. BringToFront ( shape
)  127              event
. Skip ()   # pass on event to shape handler to take care of selection  130          elif  event
. ControlDown ()  or  event
. ShiftDown ():     # extend select, don't deselect  133              # click on empty part of canvas, deselect everything  135              for  shape 
in  self
._ diagram
. GetShapeList ():  136                  if  hasattr ( shape
,  "GetModel" ):  139                          shape
. Select ( False ,  dc
)  141                  self
._ canvas
. Redraw ( dc
)  143              self
. SetPropertyModel ( None )  145          if  len ( self
. GetSelection ()) ==  0 :  146              self
. SetPropertyShape ( None )  150      def  OnLeftDoubleClick ( self
,  event
):  151          propertyService 
=  wx
. GetApp (). GetService ( PropertyService
. PropertyService
)  153              propertyService
. ShowWindow ()  156      def  OnLeftDrag ( self
,  event
):  157          # draw lasso for group select  158          if  self
._ pt
1  and  event
. LeftIsDown ():    # we are in middle of lasso selection  159              self
. EraseRubberBand ()  161              dc 
=  wx
. ClientDC ( self
._ canvas
)  162              self
._ canvas
. PrepareDC ( dc
)  163              self
._ pt
2  =  event
. GetLogicalPosition ( dc
)   # this takes into account scrollbar offset  164              self
. DrawRubberBand ()  169      def  OnLeftUp ( self
,  event
):  171          if  self
._ needEraseLasso
:  172              self
. EraseRubberBand ()  174              dc 
=  wx
. ClientDC ( self
._ canvas
)  175              self
._ canvas
. PrepareDC ( dc
)  177              x2
,  y2 
=  event
. GetLogicalPosition ( dc
)   # this takes into account scrollbar offset  179              tol 
=  self
._ diagram
. GetMouseTolerance ()  180              if  abs ( x1 
-  x2
) >  tol 
or  abs ( y1 
-  y2
) >  tol
:  181                  # make sure x1 < x2 and y1 < y2 to make comparison test easier  191                  for  shape 
in  self
._ diagram
. GetShapeList ():  192                      if not  shape
. GetParent ()  and  hasattr ( shape
,  "GetModel" ):   # if part of a composite, don't select it  193                          x
,  y 
=  shape
. GetX (),  shape
. GetY ()  194                          width
,  height 
=  shape
. GetBoundingBoxMax ()  195                          selected 
=  x1 
<  x 
-  width
/ 2  and  x2 
>  x 
+  width
/ 2  and  y1 
<  y 
-  height
/ 2  and  y2 
>  y 
+  height
/ 2  196                          if  event
. ControlDown ()  or  event
. ShiftDown ():     # extend select, don't deselect  198                                  shape
. Select ( selected
,  dc
)  199                          else :    # select items in lasso and deselect items out of lasso  200                              shape
. Select ( selected
,  dc
)  201                  self
._ canvas
. Redraw ( dc
)  208      def  EraseRubberBand ( self
):  209          if  self
._ needEraseLasso
:  210              self
._ needEraseLasso 
=  False  212              dc 
=  wx
. ClientDC ( self
._ canvas
)  213              self
._ canvas
. PrepareDC ( dc
)  214              dc
. SetLogicalFunction ( wx
. XOR
)  215              pen 
=  wx
. Pen ( wx
. Colour ( 200 ,  200 ,  200 ),  1 ,  wx
. SHORT_DASH
)  217              brush 
=  wx
. Brush ( wx
. Colour ( 255 ,  255 ,  255 ),  wx
. TRANSPARENT
)  219              dc
. ResetBoundingBox ()  225              # make sure x1 < x2 and y1 < y2  226              # this will make (x1, y1) = upper left corner  236              # erase previous outline  237              dc
. SetClippingRegion ( x1
,  y1
,  x2 
-  x1
,  y2 
-  y1
)  238              dc
. DrawRectangle ( x1
,  y1
,  x2 
-  x1
,  y2 
-  y1
)  242      def  DrawRubberBand ( self
):  243          self
._ needEraseLasso 
=  True  245          dc 
=  wx
. ClientDC ( self
._ canvas
)  246          self
._ canvas
. PrepareDC ( dc
)  247          dc
. SetLogicalFunction ( wx
. XOR
)  248          pen 
=  wx
. Pen ( wx
. Colour ( 200 ,  200 ,  200 ),  1 ,  wx
. SHORT_DASH
)  250          brush 
=  wx
. Brush ( wx
. Colour ( 255 ,  255 ,  255 ),  wx
. TRANSPARENT
)  252          dc
. ResetBoundingBox ()  258          # make sure x1 < x2 and y1 < y2  259          # this will make (x1, y1) = upper left corner  270          dc
. SetClippingRegion ( x1
,  y1
,  x2 
-  x1
,  y2 
-  y1
)  271          dc
. DrawRectangle ( x1
,  y1
,  x2 
-  x1
,  y2 
-  y1
)  275      def  FindParkingSpot ( self
,  width
,  height
):  276          """ given a width and height, find a upper left corner where shape can be parked without overlapping other shape """  277          offset 
=  30   # space between shapes  280          maxX 
=  700   # max distance to the right where we'll place tables  284              point 
=  self
. isSpotOccupied ( x
,  y
,  width
,  height
)  286                  x 
=  point
[ 0 ] +  offset
 289                      y 
=  point
[ 1 ] +  offset
 291                  noParkingSpot 
=  False  296      def  isSpotOccupied ( self
,  x
,  y
,  width
,  height
):  297          """ returns None if at x,y,width,height no object occupies that rectangle,  298              otherwise returns lower right corner of object that occupies given x,y position  303          for  shape 
in  self
._ diagram
. GetShapeList ():  304              if  isinstance ( shape
,  ogl
. RectangleShape
)  or  isinstance ( shape
,  ogl
. EllipseShape
):  305                  if  shape
. GetParent ()  and  isinstance ( shape
. GetParent (),  ogl
. CompositeShape
):  306                      # skip, part of a composite shape  309                  if  hasattr ( shape
,  "GetModel" ):  310                      other_x
,  other_y
,  other_width
,  other_height 
=  shape
. GetModel (). getEditorBounds ()  311                      other_x2 
=  other_x 
+  other_width
 312                      other_y2 
=  other_y 
+  other_height
 314                      # shapes x,y are at the center of the shape, need to transform to upper left coordinate  315                      other_width
,  other_height 
=  shape
. GetBoundingBoxMax ()  316                      other_x 
=  shape
. GetX () -  other_width
/ 2  317                      other_y 
=  shape
. GetY () -  other_height
/ 2  319                  other_x2 
=  other_x 
+  other_width
 320                  other_y2 
=  other_y 
+  other_height
 322                  if  (( other_x2 
<  other_x 
or  other_x2 
>  x
)  and  323                      ( other_y2 
<  other_y 
or  other_y2 
>  y
)  and  324                      ( x2 
<  x 
or  x2 
>  other_x
)  and  325                      ( y2 
<  y 
or  y2 
>  other_y
)):  326                      return  ( other_x2
,  other_y2
)  330      #----------------------------------------------------------------------------  332      #----------------------------------------------------------------------------  334      def  AddShape ( self
,  shape
,  x 
=  None ,  y 
=  None ,  pen 
=  None ,  brush 
=  None ,  text 
=  None ,  eventHandler 
=  None ):  335          if  isinstance ( shape
,  ogl
. CompositeShape
):  336              dc 
=  wx
. ClientDC ( self
._ canvas
)  337              self
._ canvas
. PrepareDC ( dc
)  340              shape
. SetDraggable ( True ,  True )  341          shape
. SetCanvas ( self
._ canvas
)  347          shape
. SetCentreResize ( False )  351              shape
. SetBrush ( brush
)  354          shape
. SetShadowMode ( ogl
. SHADOW_RIGHT
)  355          self
._ diagram
. AddShape ( shape
)  358              eventHandler 
=  EditorCanvasShapeEvtHandler ( self
)  359          eventHandler
. SetShape ( shape
)  360          eventHandler
. SetPreviousHandler ( shape
. GetEventHandler ())  361          shape
. SetEventHandler ( eventHandler
)  365      def  RemoveShape ( self
,  model 
=  None ,  shape 
=  None ):  366          if not  model 
and not  shape
:  370              shape 
=  self
. GetShape ( model
)  374              self
._ diagram
. RemoveShape ( shape
)  375              if  isinstance ( shape
,  ogl
. CompositeShape
):  376                  shape
. RemoveFromCanvas ( self
._ canvas
)  379      def  UpdateShape ( self
,  model
):  380          for  shape 
in  self
._ diagram
. GetShapeList ():  381              if  hasattr ( shape
,  "GetModel" )  and  shape
. GetModel () ==  model
:  382                  x
,  y
,  w
,  h 
=  model
. getEditorBounds ()  386                  if  isinstance ( shape
,  ogl
. CompositeShape
):  387                      if  shape
. GetX () !=  newX 
or  shape
. GetY () !=  newY
:  388                          dc 
=  wx
. ClientDC ( self
._ canvas
)  389                          self
._ canvas
. PrepareDC ( dc
)  390                          shape
. SetSize ( w
,  h
,  True )   # wxBug: SetSize must be before Move because links won't go to the right place  391                          shape
. Move ( dc
,  newX
,  newY
)   # wxBug: Move must be before SetSize because links won't go to the right place  394                      oldw
,  oldh 
=  shape
. GetBoundingBoxMax ()  397                      if  oldw 
!=  w 
or  oldh 
!=  h 
or  oldx 
!=  newX 
or  oldy 
!=  newY
:  403                      shape
. ResetControlPoints ()  404                      self
._ canvas
. Refresh ()  408      def  GetShape ( self
,  model
):  409          for  shape 
in  self
._ diagram
. GetShapeList ():  410              if  hasattr ( shape
,  "GetModel" )  and  shape
. GetModel () ==  model
:  415      def  GetSelection ( self
):  416          return  filter ( lambda  shape
:  shape
. Selected (),  self
._ diagram
. GetShapeList ())  419      def  SetSelection ( self
,  models
,  extendSelect 
=  False ):  420          dc 
=  wx
. ClientDC ( self
._ canvas
)  421          self
._ canvas
. PrepareDC ( dc
)  423          if not  isinstance ( models
,  type ([]))  and not  isinstance ( models
,  type (())):  425          for  shape 
in  self
._ diagram
. GetShapeList ():  426              if  hasattr ( shape
,  "GetModel" ):  427                  if  shape
. Selected ()  and not  shape
. GetModel ()  in  models
:   # was selected, but not in new list, so deselect, unless extend select  429                          shape
. Select ( False ,  dc
)  431                  elif not  shape
. Selected ()  and  shape
. GetModel ()  in  models
:  # was not selected and in new list, so select  432                      shape
. Select ( True ,  dc
)  434                  elif  extendSelect 
and  shape
. Selected ()  and  shape
. GetModel ()  in  models
:  # was selected, but extend select means to deselect  435                      shape
. Select ( False ,  dc
)  438              self
._ canvas
. Redraw ( dc
)  441      def  BringToFront ( self
,  shape
):  442          if  shape
. GetParent ()  and  isinstance ( shape
. GetParent (),  ogl
. CompositeShape
):  443              self
._ diagram
. RemoveShape ( shape
. GetParent ())  444              self
._ diagram
. AddShape ( shape
. GetParent ())  446              self
._ diagram
. RemoveShape ( shape
)  447              self
._ diagram
. AddShape ( shape
)  450      def  SendToBack ( self
,  shape
):  451          if  shape
. GetParent ()  and  isinstance ( shape
. GetParent (),  ogl
. CompositeShape
):  452              self
._ diagram
. RemoveShape ( shape
. GetParent ())  453              self
._ diagram
. InsertShape ( shape
. GetParent ())  455              self
._ diagram
. RemoveShape ( shape
)  456              self
._ diagram
. InsertShape ( shape
)  459      def  ScrollVisible ( self
,  shape
):  460          xUnit
,  yUnit 
=  shape
._ canvas
. GetScrollPixelsPerUnit ()  461          scrollX
,  scrollY 
=  self
._ canvas
. GetViewStart ()   # in scroll units  462          scrollW
,  scrollH 
=  self
._ canvas
. GetSize ()   # in pixels  463          w
,  h 
=  shape
. GetBoundingBoxMax ()  # in pixels  464          x 
=  shape
. GetX () -  w
/ 2   # convert to upper left coordinate from center  465          y 
=  shape
. GetY () -  h
/ 2   # convert to upper left coordinate from center  467          if  x 
>=  scrollX
* xUnit 
and  x 
<=  scrollX
* xUnit 
+  scrollW
:   # don't scroll if already visible  472          if  y 
>=  scrollY
* yUnit 
and  y 
<=  scrollY
* yUnit 
+  scrollH
:   # don't scroll if already visible  477          self
._ canvas
. Scroll ( x
,  y
)   # in scroll units  480      def  SetPropertyShape ( self
,  shape
):  481          # no need to highlight if no PropertyService is running  482          propertyService 
=  wx
. GetApp (). GetService ( PropertyService
. PropertyService
)  483          if not  propertyService
:  486          if  shape 
==  self
._ propShape
:  489          if  hasattr ( shape
,  "GetPropertyShape" ):  490              shape 
=  shape
. GetPropertyShape ()  492          dc 
=  wx
. ClientDC ( self
._ canvas
)  493          self
._ canvas
. PrepareDC ( dc
)  496          # erase old selection if it still exists  497          if  self
._ propShape 
and  self
._ propShape 
in  self
._ diagram
. GetShapeList ():  498              self
._ propShape
. SetBrush ( self
._ brush
)  499              if  ( self
._ propShape
._ textColourName 
in  [ "BLACK" ,  "WHITE" ]):   # Would use GetTextColour() but it is broken  500                  self
._ propShape
. SetTextColour ( "BLACK" ,  0 )  501              self
._ propShape
. Draw ( dc
)  504          self
._ propShape 
=  shape
 507          if  self
._ propShape 
and  self
._ propShape 
in  self
._ diagram
. GetShapeList ():  508              self
._ propShape
. SetBrush ( SELECT_BRUSH
)  509              if  ( self
._ propShape
._ textColourName 
in  [ "BLACK" ,  "WHITE" ]):   # Would use GetTextColour() but it is broken  510                  self
._ propShape
. SetTextColour ( "WHITE" ,  0 )  511              self
._ propShape
. Draw ( dc
)  516      #----------------------------------------------------------------------------  517      # Property Service methods  518      #----------------------------------------------------------------------------  520      def  GetPropertyModel ( self
):  521          if  hasattr ( self
,  "_propModel" ):  522              return  self
._ propModel
 526      def  SetPropertyModel ( self
,  model
):  527          # no need to set the model if no PropertyService is running  528          propertyService 
=  wx
. GetApp (). GetService ( PropertyService
. PropertyService
)  529          if not  propertyService
:  532          if  hasattr ( self
,  "_propModel" )  and  model 
==  self
._ propModel
:  535          self
._ propModel 
=  model
 536          propertyService
. LoadProperties ( self
._ propModel
,  self
. GetDocument ())  539  class  EditorCanvasShapeMixin
:  545      def  SetModel ( self
,  model
):  549  class  EditorCanvasShapeEvtHandler ( ogl
. ShapeEvtHandler
):  551      """ wxBug: Bug in OLG package.  With wxShape.SetShadowMode() turned on, when we set the size,  552          the width/height is larger by 6 pixels.  Need to subtract this value from width and height when we  558      def  __init__ ( self
,  view
):  559          ogl
. ShapeEvtHandler
.__ init
__ ( self
)  563      def  OnLeftClick ( self
,  x
,  y
,  keys 
=  0 ,  attachment 
=  0 ):  564          shape 
=  self
. GetShape ()  565          if  hasattr ( shape
,  "GetModel" ):   # Workaround, on drag, we should deselect all other objects and select the clicked on object  566              model 
=  shape
. GetModel ()  568              shape 
=  shape
. GetParent ()  570                  model 
=  shape
. GetModel ()  572          self
._ view
. SetSelection ( model
,  keys 
==  self
. SHIFT_KEY 
or  keys 
==  self
. CONTROL_KEY
)  573          self
._ view
. SetPropertyShape ( shape
)  574          self
._ view
. SetPropertyModel ( model
)  577      def  OnEndDragLeft ( self
,  x
,  y
,  keys 
=  0 ,  attachment 
=  0 ):  578          ogl
. ShapeEvtHandler
. OnEndDragLeft ( self
,  x
,  y
,  keys
,  attachment
)  579          shape 
=  self
. GetShape ()  580          if  hasattr ( shape
,  "GetModel" ):   # Workaround, on drag, we should deselect all other objects and select the clicked on object  581              model 
=  shape
. GetModel ()  583              parentShape 
=  shape
. GetParent ()  585                  model 
=  parentShape
. GetModel ()  586          self
._ view
. SetSelection ( model
,  keys 
==  self
. SHIFT_KEY 
or  keys 
==  self
. CONTROL_KEY
)  589      def  OnMovePost ( self
,  dc
,  x
,  y
,  oldX
,  oldY
,  display
):  590          if  x 
==  oldX 
and  y 
==  oldY
:  592          if not  self
._ view
. GetDocument ():  594          shape 
=  self
. GetShape ()  595          if  isinstance ( shape
,  EditorCanvasShapeMixin
)  and  shape
. Draggable ():  596              model 
=  shape
. GetModel ()  597              if  hasattr ( model
,  "getEditorBounds" )  and  model
. getEditorBounds ():  598                  x
,  y
,  w
,  h 
=  model
. getEditorBounds ()  599                  newX 
=  shape
. GetX () -  shape
. GetBoundingBoxMax ()[ 0 ] /  2  600                  newY 
=  shape
. GetY () -  shape
. GetBoundingBoxMax ()[ 1 ] /  2  601                  newWidth 
=  shape
. GetBoundingBoxMax ()[ 0 ]  602                  newHeight 
=  shape
. GetBoundingBoxMax ()[ 1 ]  603                  if  shape
._ shadowMode 
!=  ogl
. SHADOW_NONE
:  604                      newWidth 
-=  shape
._ shadowOffsetX
 605                      newHeight 
-=  shape
._ shadowOffsetY
 606                  newbounds 
= ( newX
,  newY
,  newWidth
,  newHeight
)  608                  if  x 
!=  newX 
or  y 
!=  newY 
or  w 
!=  newWidth 
or  h 
!=  newHeight
:  609                      self
._ view
. GetDocument (). GetCommandProcessor (). Submit ( EditorCanvasUpdateShapeBoundariesCommand ( self
._ view
. GetDocument (),  model
,  newbounds
))  616  class  EditorCanvasUpdateShapeBoundariesCommand ( wx
. lib
. docview
. Command
):  619      def  __init__ ( self
,  canvasDocument
,  model
,  newbounds
):  620          wx
. lib
. docview
. Command
.__ init
__ ( self
,  canUndo 
=  True )  621          self
._ canvasDocument 
=  canvasDocument
 623          self
._ oldbounds 
=  model
. getEditorBounds ()  624          self
._ newbounds 
=  newbounds
 628          name 
=  self
._ canvasDocument
. GetNameForObject ( self
._ model
)  631              print  "ERROR: AbstractEditor.EditorCanvasUpdateShapeBoundariesCommand.GetName: unable to get name for " ,  self
._ model
 632          return  _ ( "Move/Resize  %s " ) %  name
 636          return  self
._ canvasDocument
. UpdateEditorBoundaries ( self
._ model
,  self
._ newbounds
)  640          return  self
._ canvasDocument
. UpdateEditorBoundaries ( self
._ model
,  self
._ oldbounds
)