]>
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
24 INACTIVE_SELECT_BRUSH
= wx
. Brush ( "LIGHT BLUE" , wx
. SOLID
)
26 NORMALFONT
= wx
. SystemSettings
. GetFont ( wx
. SYS_DEFAULT_GUI_FONT
)
27 SLANTFONT
= wx
. Font ( NORMALFONT
. GetPointSize (), NORMALFONT
. GetFamily (), wx
. SLANT
, NORMALFONT
. GetWeight ())
28 BOLDFONT
= wx
. Font ( NORMALFONT
. GetPointSize (), NORMALFONT
. GetFamily (), NORMALFONT
. GetStyle (), wx
. BOLD
)
30 DEFAULT_BACKGROUND_COLOR
= wx
. Colour ( 0xEE , 0xEE , 0xEE )
31 HEADER_BRUSH
= wx
. Brush ( wx
. Colour ( 0xDB , 0xEB , 0xFF ), wx
. SOLID
)
32 BODY_BRUSH
= wx
. Brush ( wx
. WHITE
, wx
. SOLID
)
36 PARKING_HORIZONTAL
= 2
37 PARKING_OFFSET
= 30 # space between shapes
39 FORCE_REDRAW_METHOD
= "ForceRedraw"
41 def GetRawModel ( model
):
42 if hasattr ( model
, "GetRawModel" ):
43 rawModel
= model
. GetRawModel ()
50 model
= GetRawModel ( model
)
51 if hasattr ( model
, "__xmlname__" ):
52 label
= model
.__ xmlname
__
55 label
= label
[ 0 ]. upper () + label
[ 1 :]
56 if ( hasattr ( model
, "complexType" )):
57 label
+= ': %s / %s ' % ( model
. complexType
. name
, model
. name
)
60 label
+= ': %s ' % model
. name
62 label
+= ': %s ' % model
. ref
63 except AttributeError :
70 class CanvasView ( wx
. lib
. docview
. View
):
73 #----------------------------------------------------------------------------
75 #----------------------------------------------------------------------------
78 def __init__ ( self
, brush
= SHAPE_BRUSH
, background
= DEFAULT_BACKGROUND_COLOR
):
79 wx
. lib
. docview
. View
.__ init
__ ( self
)
81 self
._ backgroundColor
= background
85 self
._ needEraseLasso
= False
86 self
._ propShape
= None
88 self
._ maxHeight
= 16000
89 self
._ valetParking
= False
93 """ for Print Preview and Print """
95 self
._ canvas
. Redraw ( dc
)
99 def OnCreate ( self
, doc
, flags
):
100 frame
= wx
. GetApp (). CreateDocumentFrame ( self
, doc
, flags
)
102 sizer
= wx
. BoxSizer ()
103 self
._ CreateCanvas
( frame
)
104 sizer
. Add ( self
._ canvas
, 1 , wx
. EXPAND
, 0 )
105 frame
. SetSizer ( sizer
)
108 wx
. EVT_RIGHT_DOWN ( self
._ canvas
, self
. OnRightClick
)
112 def OnActivateView ( self
, activate
, activeView
, deactiveView
):
113 if activate
and self
._ canvas
:
114 # In MDI mode just calling set focus doesn't work and in SDI mode using CallAfter causes an endless loop
115 if self
. GetDocumentManager (). GetFlags () & wx
. lib
. docview
. DOC_SDI
:
118 wx
. CallAfter ( self
. SetFocus
)
123 self
._ canvas
. SetFocus ()
126 def OnFocus ( self
, event
):
127 self
. FocusColorPropertyShape ( True )
131 def FocusOnClick ( self
, event
):
136 def OnKillFocus ( self
, event
):
137 self
. FocusColorPropertyShape ( False )
142 winWithFocus
= wx
. Window
. FindFocus ()
146 if winWithFocus
== self
._ canvas
:
148 winWithFocus
= winWithFocus
. GetParent ()
152 def OnClose ( self
, deleteWindow
= True ):
153 statusC
= wx
. GetApp (). CloseChildDocuments ( self
. GetDocument ())
154 statusP
= wx
. lib
. docview
. View
. OnClose ( self
, deleteWindow
= deleteWindow
)
155 if hasattr ( self
, "ClearOutline" ):
156 wx
. CallAfter ( self
. ClearOutline
) # need CallAfter because when closing the document, it is Activated and then Close, so need to match OnActivateView's CallAfter
157 if not ( statusC
and statusP
):
160 if deleteWindow
and self
. GetFrame ():
161 self
. GetFrame (). Destroy ()
165 def _CreateCanvas ( self
, parent
):
166 self
._ canvas
= ogl
. ShapeCanvas ( parent
)
167 wx
. EVT_LEFT_DOWN ( self
._ canvas
, self
. OnLeftClick
)
168 wx
. EVT_LEFT_UP ( self
._ canvas
, self
. OnLeftUp
)
169 wx
. EVT_MOTION ( self
._ canvas
, self
. OnLeftDrag
)
170 wx
. EVT_LEFT_DCLICK ( self
._ canvas
, self
. OnLeftDoubleClick
)
171 wx
. EVT_KEY_DOWN ( self
._ canvas
, self
. OnKeyPressed
)
173 # need this otherwise mouse clicks don't set focus to this view
174 wx
. EVT_LEFT_DOWN ( self
._ canvas
, self
. FocusOnClick
)
175 wx
. EVT_LEFT_DCLICK ( self
._ canvas
, self
. FocusOnClick
)
176 wx
. EVT_RIGHT_DOWN ( self
._ canvas
, self
. FocusOnClick
)
177 wx
. EVT_RIGHT_DCLICK ( self
._ canvas
, self
. FocusOnClick
)
178 wx
. EVT_MIDDLE_DOWN ( self
._ canvas
, self
. FocusOnClick
)
179 wx
. EVT_MIDDLE_DCLICK ( self
._ canvas
, self
. FocusOnClick
)
181 wx
. EVT_KILL_FOCUS ( self
._ canvas
, self
. OnKillFocus
)
182 wx
. EVT_SET_FOCUS ( self
._ canvas
, self
. OnFocus
)
184 self
._ canvas
. SetScrollbars ( 20 , 20 , self
._ maxWidth
/ 20 , self
._ maxHeight
/ 20 )
186 self
._ canvas
. SetBackgroundColour ( self
._ backgroundColor
)
187 self
._ diagram
= ogl
. Diagram ()
188 self
._ canvas
. SetDiagram ( self
._ diagram
)
189 self
._ diagram
. SetCanvas ( self
._ canvas
)
190 self
._ canvas
. SetFont ( NORMALFONT
)
193 def OnClear ( self
, event
):
194 """ Deletion of selected objects from view.
197 self
. SetPropertyModel ( None )
200 def SetLastRightClick ( self
, x
, y
):
201 self
._l astRightClick
= ( x
, y
)
204 def GetLastRightClick ( self
):
205 if hasattr ( self
, "_lastRightClick" ):
206 return self
._l astRightClick
210 def OnKeyPressed ( self
, event
):
211 key
= event
. KeyCode ()
212 if key
== wx
. WXK_DELETE
:
218 def OnRightClick ( self
, event
):
219 """ force selection underneath right click position. """
221 self
._ canvas
. SetFocus ()
223 dc
= wx
. ClientDC ( self
._ canvas
)
224 self
._ canvas
. PrepareDC ( dc
)
225 x
, y
= event
. GetLogicalPosition ( dc
) # this takes into account scrollbar offset
226 self
. SetLastRightClick ( x
, y
)
227 shape
= self
._ canvas
. FindShape ( x
, y
)[ 0 ]
231 self
. SetSelection ( None )
232 self
. SetPropertyShape ( None )
233 elif hasattr ( shape
, "GetModel" ):
234 self
. BringToFront ( shape
)
235 self
. SetPropertyShape ( shape
)
236 self
. SetSelection ( shape
)
237 shape
. Select ( True , dc
)
238 model
= shape
. GetModel ()
239 elif shape
. GetParent () and isinstance ( shape
. GetParent (), ogl
. CompositeShape
): # ComplexTypeHeader for ComplexTypeShape
240 self
. BringToFront ( shape
)
241 self
. SetPropertyShape ( shape
. GetParent ())
242 self
. SetSelection ( shape
. GetParent ())
243 shape
. GetParent (). Select ( True , dc
)
244 model
= shape
. GetParent (). GetModel ()
246 self
. SetPropertyModel ( model
)
248 return ( shape
, model
)
251 def OnLeftClick ( self
, event
):
253 self
._ canvas
. SetFocus ()
255 self
. EraseRubberBand ()
257 dc
= wx
. ClientDC ( self
._ canvas
)
258 self
._ canvas
. PrepareDC ( dc
)
260 # keep track of mouse down for group select
261 self
._ pt
1 = event
. GetLogicalPosition ( dc
) # this takes into account scrollbar offset
264 shape
= self
._ canvas
. FindShape ( self
._ pt
1 [ 0 ], self
._ pt
1 [ 1 ])[ 0 ]
266 self
. BringToFront ( shape
)
269 event
. Skip () # pass on event to shape handler to take care of selection
272 elif event
. ControlDown () or event
. ShiftDown (): # extend select, don't deselect
275 # click on empty part of canvas, deselect everything
276 forceRedrawShapes
= []
278 for shape
in self
._ diagram
. GetShapeList ():
279 if hasattr ( shape
, "GetModel" ):
282 shape
. Select ( False , dc
)
283 if hasattr ( shape
, FORCE_REDRAW_METHOD
):
284 forceRedrawShapes
. append ( shape
)
286 self
._ canvas
. Redraw ( dc
)
288 self
. SetPropertyModel ( None )
290 if len ( self
. GetSelection ()) == 0 :
291 self
. SetPropertyShape ( None )
293 for shape
in forceRedrawShapes
:
296 def OnLeftDoubleClick ( self
, event
):
297 propertyService
= wx
. GetApp (). GetService ( PropertyService
. PropertyService
)
299 propertyService
. ShowWindow ()
302 def OnLeftDrag ( self
, event
):
303 # draw lasso for group select
304 if self
._ pt
1 and event
. LeftIsDown (): # we are in middle of lasso selection
305 self
. EraseRubberBand ()
307 dc
= wx
. ClientDC ( self
._ canvas
)
308 self
._ canvas
. PrepareDC ( dc
)
309 self
._ pt
2 = event
. GetLogicalPosition ( dc
) # this takes into account scrollbar offset
310 self
. DrawRubberBand ()
315 def OnLeftUp ( self
, event
):
317 if self
._ needEraseLasso
:
318 self
. EraseRubberBand ()
320 dc
= wx
. ClientDC ( self
._ canvas
)
321 self
._ canvas
. PrepareDC ( dc
)
323 x2
, y2
= event
. GetLogicalPosition ( dc
) # this takes into account scrollbar offset
325 tol
= self
._ diagram
. GetMouseTolerance ()
326 if abs ( x1
- x2
) > tol
or abs ( y1
- y2
) > tol
:
327 # make sure x1 < x2 and y1 < y2 to make comparison test easier
337 for shape
in self
._ diagram
. GetShapeList ():
338 if not shape
. GetParent () and hasattr ( shape
, "GetModel" ): # if part of a composite, don't select it
339 x
, y
= shape
. GetX (), shape
. GetY ()
340 width
, height
= shape
. GetBoundingBoxMax ()
341 selected
= x1
< x
- width
/ 2 and x2
> x
+ width
/ 2 and y1
< y
- height
/ 2 and y2
> y
+ height
/ 2
342 if event
. ControlDown () or event
. ShiftDown (): # extend select, don't deselect
344 shape
. Select ( selected
, dc
)
345 else : # select items in lasso and deselect items out of lasso
346 shape
. Select ( selected
, dc
)
347 self
._ canvas
. Redraw ( dc
)
354 def EraseRubberBand ( self
):
355 if self
._ needEraseLasso
:
356 self
._ needEraseLasso
= False
358 dc
= wx
. ClientDC ( self
._ canvas
)
359 self
._ canvas
. PrepareDC ( dc
)
360 dc
. SetLogicalFunction ( wx
. XOR
)
361 pen
= wx
. Pen ( wx
. Colour ( 200 , 200 , 200 ), 1 , wx
. SHORT_DASH
)
363 brush
= wx
. Brush ( wx
. Colour ( 255 , 255 , 255 ), wx
. TRANSPARENT
)
365 dc
. ResetBoundingBox ()
371 # make sure x1 < x2 and y1 < y2
372 # this will make (x1, y1) = upper left corner
382 # erase previous outline
383 dc
. SetClippingRegion ( x1
, y1
, x2
- x1
, y2
- y1
)
384 dc
. DrawRectangle ( x1
, y1
, x2
- x1
, y2
- y1
)
388 def DrawRubberBand ( self
):
389 self
._ needEraseLasso
= True
391 dc
= wx
. ClientDC ( self
._ canvas
)
392 self
._ canvas
. PrepareDC ( dc
)
393 dc
. SetLogicalFunction ( wx
. XOR
)
394 pen
= wx
. Pen ( wx
. Colour ( 200 , 200 , 200 ), 1 , wx
. SHORT_DASH
)
396 brush
= wx
. Brush ( wx
. Colour ( 255 , 255 , 255 ), wx
. TRANSPARENT
)
398 dc
. ResetBoundingBox ()
404 # make sure x1 < x2 and y1 < y2
405 # this will make (x1, y1) = upper left corner
416 dc
. SetClippingRegion ( x1
, y1
, x2
- x1
, y2
- y1
)
417 dc
. DrawRectangle ( x1
, y1
, x2
- x1
, y2
- y1
)
421 def SetValetParking ( self
, enable
= True ):
422 """ If valet parking is enabled, remember last parking spot and try for a spot near it """
423 self
._ valetParking
= enable
425 self
._ valetPosition
= None
428 def FindParkingSpot ( self
, width
, height
, parking
= PARKING_HORIZONTAL
, x
= PARKING_OFFSET
, y
= PARKING_OFFSET
):
430 Given a width and height, find a upper left corner where shape can be parked without overlapping other shape
432 if self
._ valetParking
and self
._ valetPosition
:
433 x
, y
= self
._ valetPosition
435 max = 700 # max distance to the right where we'll place tables
439 point
= self
. isSpotOccupied ( x
, y
, width
, height
)
441 if parking
== PARKING_HORIZONTAL
:
442 x
= point
[ 0 ] + PARKING_OFFSET
445 y
= point
[ 1 ] + PARKING_OFFSET
446 else : # parking == PARKING_VERTICAL:
447 y
= point
[ 1 ] + PARKING_OFFSET
450 x
= point
[ 0 ] + PARKING_OFFSET
452 noParkingSpot
= False
454 if self
._ valetParking
:
455 self
._ valetPosition
= ( x
, y
)
460 def isSpotOccupied ( self
, x
, y
, width
, height
):
461 """ returns None if at x,y,width,height no object occupies that rectangle,
462 otherwise returns lower right corner of object that occupies given x,y position
467 for shape
in self
._ diagram
. GetShapeList ():
468 if isinstance ( shape
, ogl
. RectangleShape
) or isinstance ( shape
, ogl
. EllipseShape
) or isinstance ( shape
, ogl
. PolygonShape
):
469 if shape
. GetParent () and isinstance ( shape
. GetParent (), ogl
. CompositeShape
):
470 # skip, part of a composite shape
473 if hasattr ( shape
, "GetModel" ):
474 other_x
, other_y
, other_width
, other_height
= shape
. GetModel (). getEditorBounds ()
475 other_x2
= other_x
+ other_width
476 other_y2
= other_y
+ other_height
478 # shapes x,y are at the center of the shape, need to transform to upper left coordinate
479 other_width
, other_height
= shape
. GetBoundingBoxMax ()
480 other_x
= shape
. GetX () - other_width
/ 2
481 other_y
= shape
. GetY () - other_height
/ 2
483 other_x2
= other_x
+ other_width
484 other_y2
= other_y
+ other_height
486 if (( other_x2
< other_x
or other_x2
> x
) and
487 ( other_y2
< other_y
or other_y2
> y
) and
488 ( x2
< x
or x2
> other_x
) and
489 ( y2
< y
or y2
> other_y
)):
490 return ( other_x2
, other_y2
)
494 #----------------------------------------------------------------------------
496 #----------------------------------------------------------------------------
498 def AddShape ( self
, shape
, x
= None , y
= None , pen
= None , brush
= None , text
= None , eventHandler
= None , shown
= True ):
499 if isinstance ( shape
, ogl
. CompositeShape
):
500 dc
= wx
. ClientDC ( self
._ canvas
)
501 self
._ canvas
. PrepareDC ( dc
)
504 shape
. SetDraggable ( True , True )
505 shape
. SetCanvas ( self
._ canvas
)
511 shape
. SetCentreResize ( False )
515 shape
. SetBrush ( brush
)
518 shape
. SetShadowMode ( ogl
. SHADOW_NONE
)
519 self
._ diagram
. AddShape ( shape
)
522 eventHandler
= EditorCanvasShapeEvtHandler ( self
)
523 eventHandler
. SetShape ( shape
)
524 eventHandler
. SetPreviousHandler ( shape
. GetEventHandler ())
525 shape
. SetEventHandler ( eventHandler
)
529 def RemoveShape ( self
, model
= None , shape
= None ):
530 if not model
and not shape
:
534 shape
= self
. GetShape ( model
)
538 for line
in shape
. GetLines ():
539 shape
. RemoveLine ( line
)
540 self
._ diagram
. RemoveShape ( line
)
542 for obj
in self
._ diagram
. GetShapeList ():
543 for line
in obj
. GetLines ():
544 if self
. IsShapeContained ( shape
, line
. GetTo ()) or self
. IsShapeContained ( shape
, line
. GetFrom ()):
546 self
._ diagram
. RemoveShape ( line
)
550 self
._ diagram
. RemoveShape ( line
)
554 shape
. RemoveFromCanvas ( self
._ canvas
)
555 self
._ diagram
. RemoveShape ( shape
)
559 def IsShapeContained ( self
, parent
, shape
):
562 elif shape
. GetParent ():
563 return self
. IsShapeContained ( parent
, shape
. GetParent ())
568 def UpdateShape ( self
, model
):
569 for shape
in self
._ diagram
. GetShapeList ():
570 if hasattr ( shape
, "GetModel" ) and shape
. GetModel () == model
:
571 oldw
, oldh
= shape
. GetBoundingBoxMax ()
575 x
, y
, w
, h
= model
. getEditorBounds ()
579 if oldw
!= w
or oldh
!= h
or oldx
!= newX
or oldy
!= newY
:
580 dc
= wx
. ClientDC ( self
._ canvas
)
581 self
._ canvas
. PrepareDC ( dc
)
582 shape
. SetSize ( w
, h
, True ) # wxBug: SetSize must be before Move because links won't go to the right place
583 shape
. Move ( dc
, newX
, newY
) # wxBug: Move must be after SetSize because links won't go to the right place
584 shape
. ResetControlPoints ()
585 self
._ canvas
. Refresh ()
590 def GetShape ( self
, model
):
591 for shape
in self
._ diagram
. GetShapeList ():
592 if hasattr ( shape
, "GetModel" ) and shape
. GetModel () == model
:
597 def GetShapeCount ( self
):
598 return self
._ diagram
. GetCount ()
601 def GetSelection ( self
):
602 return filter ( lambda shape
: shape
. Selected (), self
._ diagram
. GetShapeList ())
605 def SetSelection ( self
, models
, extendSelect
= False ):
606 dc
= wx
. ClientDC ( self
._ canvas
)
607 self
._ canvas
. PrepareDC ( dc
)
609 if not isinstance ( models
, type ([])) and not isinstance ( models
, type (())):
611 for shape
in self
._ diagram
. GetShapeList ():
612 if hasattr ( shape
, "GetModel" ):
613 if shape
. Selected () and not shape
. GetModel () in models
: # was selected, but not in new list, so deselect, unless extend select
615 shape
. Select ( False , dc
)
617 elif not shape
. Selected () and shape
. GetModel () in models
: # was not selected and in new list, so select
618 shape
. Select ( True , dc
)
620 elif extendSelect
and shape
. Selected () and shape
. GetModel () in models
: # was selected, but extend select means to deselect
621 shape
. Select ( False , dc
)
624 self
._ canvas
. Redraw ( dc
)
627 def BringToFront ( self
, shape
):
628 if shape
. GetParent () and isinstance ( shape
. GetParent (), ogl
. CompositeShape
):
629 self
._ diagram
. RemoveShape ( shape
. GetParent ())
630 self
._ diagram
. AddShape ( shape
. GetParent ())
632 self
._ diagram
. RemoveShape ( shape
)
633 self
._ diagram
. AddShape ( shape
)
636 def SendToBack ( self
, shape
):
637 if shape
. GetParent () and isinstance ( shape
. GetParent (), ogl
. CompositeShape
):
638 self
._ diagram
. RemoveShape ( shape
. GetParent ())
639 self
._ diagram
. InsertShape ( shape
. GetParent ())
641 self
._ diagram
. RemoveShape ( shape
)
642 self
._ diagram
. InsertShape ( shape
)
645 def ScrollVisible ( self
, shape
):
649 xUnit
, yUnit
= self
._ canvas
. GetScrollPixelsPerUnit ()
650 scrollX
, scrollY
= self
._ canvas
. GetViewStart () # in scroll units
651 scrollW
, scrollH
= self
._ canvas
. GetSize () # in pixels
652 w
, h
= shape
. GetBoundingBoxMax () # in pixels
653 x
= shape
. GetX () - w
/ 2 # convert to upper left coordinate from center
654 y
= shape
. GetY () - h
/ 2 # convert to upper left coordinate from center
656 if x
>= scrollX
* xUnit
and x
<= scrollX
* xUnit
+ scrollW
: # don't scroll if already visible
661 if y
>= scrollY
* yUnit
and y
<= scrollY
* yUnit
+ scrollH
: # don't scroll if already visible
666 self
._ canvas
. Scroll ( x
, y
) # in scroll units
669 def SetPropertyShape ( self
, shape
):
670 # no need to highlight if no PropertyService is running
671 propertyService
= wx
. GetApp (). GetService ( PropertyService
. PropertyService
)
672 if not propertyService
:
675 if shape
== self
._ propShape
:
678 if hasattr ( shape
, "GetPropertyShape" ):
679 shape
= shape
. GetPropertyShape ()
681 dc
= wx
. ClientDC ( self
._ canvas
)
682 self
._ canvas
. PrepareDC ( dc
)
685 # erase old selection if it still exists
686 if self
._ propShape
and self
._ propShape
in self
._ diagram
. GetShapeList ():
687 if hasattr ( self
._ propShape
, "DEFAULT_BRUSH" ):
688 self
._ propShape
. SetBrush ( self
._ propShape
. DEFAULT_BRUSH
)
690 self
._ propShape
. SetBrush ( self
._ brush
)
691 if ( self
._ propShape
._ textColourName
in [ "BLACK" , "WHITE" ]): # Would use GetTextColour() but it is broken
692 self
._ propShape
. SetTextColour ( "BLACK" , 0 )
693 self
._ propShape
. Draw ( dc
)
696 self
._ propShape
= shape
699 if self
._ propShape
and self
._ propShape
in self
._ diagram
. GetShapeList ():
701 self
._ propShape
. SetBrush ( SELECT_BRUSH
)
703 self
._ propShape
. SetBrush ( INACTIVE_SELECT_BRUSH
)
704 if ( self
._ propShape
._ textColourName
in [ "BLACK" , "WHITE" ]): # Would use GetTextColour() but it is broken
705 self
._ propShape
. SetTextColour ( "WHITE" , 0 )
706 self
._ propShape
. Draw ( dc
)
711 def FocusColorPropertyShape ( self
, gotFocus
= False ):
712 # no need to change highlight if no PropertyService is running
713 propertyService
= wx
. GetApp (). GetService ( PropertyService
. PropertyService
)
714 if not propertyService
:
717 if not self
._ propShape
:
720 dc
= wx
. ClientDC ( self
._ canvas
)
721 self
._ canvas
. PrepareDC ( dc
)
724 # draw deactivated selection
725 if self
._ propShape
and self
._ propShape
in self
._ diagram
. GetShapeList ():
727 self
._ propShape
. SetBrush ( SELECT_BRUSH
)
729 self
._ propShape
. SetBrush ( INACTIVE_SELECT_BRUSH
)
730 if ( self
._ propShape
._ textColourName
in [ "BLACK" , "WHITE" ]): # Would use GetTextColour() but it is broken
731 self
._ propShape
. SetTextColour ( "WHITE" , 0 )
732 self
._ propShape
. Draw ( dc
)
734 if hasattr ( self
._ propShape
, FORCE_REDRAW_METHOD
):
735 self
._ propShape
. ForceRedraw ()
740 #----------------------------------------------------------------------------
741 # Property Service methods
742 #----------------------------------------------------------------------------
744 def GetPropertyModel ( self
):
745 if hasattr ( self
, "_propModel" ):
746 return self
._ propModel
750 def SetPropertyModel ( self
, model
):
751 # no need to set the model if no PropertyService is running
752 propertyService
= wx
. GetApp (). GetService ( PropertyService
. PropertyService
)
753 if not propertyService
:
756 if hasattr ( self
, "_propModel" ) and model
== self
._ propModel
:
759 self
._ propModel
= model
760 propertyService
. LoadProperties ( self
._ propModel
, self
. GetDocument ())
763 class EditorCanvasShapeMixin
:
769 def SetModel ( self
, model
):
773 class EditorCanvasShapeEvtHandler ( ogl
. ShapeEvtHandler
):
775 """ wxBug: Bug in OLG package. With wxShape.SetShadowMode() turned on, when we set the size,
776 the width/height is larger by 6 pixels. Need to subtract this value from width and height when we
782 def __init__ ( self
, view
):
783 ogl
. ShapeEvtHandler
.__ init
__ ( self
)
787 def OnLeftClick ( self
, x
, y
, keys
= 0 , attachment
= 0 ):
788 shape
= self
. GetShape ()
789 if hasattr ( shape
, "GetModel" ): # Workaround, on drag, we should deselect all other objects and select the clicked on object
790 model
= shape
. GetModel ()
792 shape
= shape
. GetParent ()
794 model
= shape
. GetModel ()
797 self
._ view
. SetSelection ( model
, keys
== self
. SHIFT_KEY
or keys
== self
. CONTROL_KEY
)
798 self
._ view
. SetPropertyShape ( shape
)
799 self
._ view
. SetPropertyModel ( model
)
802 def OnEndDragLeft ( self
, x
, y
, keys
= 0 , attachment
= 0 ):
803 ogl
. ShapeEvtHandler
. OnEndDragLeft ( self
, x
, y
, keys
, attachment
)
804 shape
= self
. GetShape ()
805 if hasattr ( shape
, "GetModel" ): # Workaround, on drag, we should deselect all other objects and select the clicked on object
806 model
= shape
. GetModel ()
808 parentShape
= shape
. GetParent ()
810 model
= parentShape
. GetModel ()
811 self
._ view
. SetSelection ( model
, keys
== self
. SHIFT_KEY
or keys
== self
. CONTROL_KEY
)
814 def OnMovePre ( self
, dc
, x
, y
, oldX
, oldY
, display
):
815 """ Prevent objects from being dragged outside of viewable area """
816 if ( x
< 0 ) or ( y
< 0 ) or ( x
> self
._ view
._ maxWidth
) or ( y
> self
._ view
._ maxHeight
):
819 return ogl
. ShapeEvtHandler
. OnMovePre ( self
, dc
, x
, y
, oldX
, oldY
, display
)
822 def OnMovePost ( self
, dc
, x
, y
, oldX
, oldY
, display
):
823 """ Update the model's record of where the shape should be. Also enable redo/undo. """
824 if x
== oldX
and y
== oldY
:
826 if not self
._ view
. GetDocument ():
828 shape
= self
. GetShape ()
829 if isinstance ( shape
, EditorCanvasShapeMixin
) and shape
. Draggable ():
830 model
= shape
. GetModel ()
831 if hasattr ( model
, "getEditorBounds" ) and model
. getEditorBounds ():
832 x
, y
, w
, h
= model
. getEditorBounds ()
833 newX
= shape
. GetX () - shape
. GetBoundingBoxMax ()[ 0 ] / 2
834 newY
= shape
. GetY () - shape
. GetBoundingBoxMax ()[ 1 ] / 2
835 newWidth
= shape
. GetBoundingBoxMax ()[ 0 ]
836 newHeight
= shape
. GetBoundingBoxMax ()[ 1 ]
837 if shape
._ shadowMode
!= ogl
. SHADOW_NONE
:
838 newWidth
-= shape
._ shadowOffsetX
839 newHeight
-= shape
._ shadowOffsetY
840 newbounds
= ( newX
, newY
, newWidth
, newHeight
)
842 if x
!= newX
or y
!= newY
or w
!= newWidth
or h
!= newHeight
:
843 self
._ view
. GetDocument (). GetCommandProcessor (). Submit ( EditorCanvasUpdateShapeBoundariesCommand ( self
._ view
. GetDocument (), model
, newbounds
))
850 class EditorCanvasUpdateShapeBoundariesCommand ( wx
. lib
. docview
. Command
):
853 def __init__ ( self
, canvasDocument
, model
, newbounds
):
854 wx
. lib
. docview
. Command
.__ init
__ ( self
, canUndo
= True )
855 self
._ canvasDocument
= canvasDocument
857 self
._ oldbounds
= model
. getEditorBounds ()
858 self
._ newbounds
= newbounds
862 name
= self
._ canvasDocument
. GetNameForObject ( self
._ model
)
865 print "ERROR: AbstractEditor.EditorCanvasUpdateShapeBoundariesCommand.GetName: unable to get name for " , self
._ model
866 return _ ( "Move/Resize %s " ) % name
870 return self
._ canvasDocument
. UpdateEditorBoundaries ( self
._ model
, self
._ newbounds
)
874 return self
._ canvasDocument
. UpdateEditorBoundaries ( self
._ model
, self
._ oldbounds
)