@@ -528,8 +528,8 @@ def __init__(self, parent, id, figure):
528528 # Create the drawing bitmap
529529 self .bitmap = wx .Bitmap (w , h )
530530 _log .debug ("%s - __init__() - bitmap w:%d h:%d" , type (self ), w , h )
531- # TODO: Add support for 'point' inspection and plot navigation.
532531 self ._isDrawn = False
532+ self ._rubberband_rect = None
533533
534534 self .Bind (wx .EVT_SIZE , self ._onSize )
535535 self .Bind (wx .EVT_PAINT , self ._onPaint )
@@ -628,20 +628,22 @@ def gui_repaint(self, drawDC=None, origin='WX'):
628628 _log .debug ("%s - gui_repaint()" , type (self ))
629629 # The "if self" check avoids a "wrapped C/C++ object has been deleted"
630630 # RuntimeError if doing things after window is closed.
631- if self and self .IsShownOnScreen ():
632- if not drawDC :
633- # not called from OnPaint use a ClientDC
634- drawDC = wx .ClientDC (self )
635-
636- # following is for 'WX' backend on Windows
637- # the bitmap can not be in use by another DC,
638- # see GraphicsContextWx._cache
639- if wx .Platform == '__WXMSW__' and origin == 'WX' :
640- img = self .bitmap .ConvertToImage ()
641- bmp = img .ConvertToBitmap ()
642- drawDC .DrawBitmap (bmp , 0 , 0 )
643- else :
644- drawDC .DrawBitmap (self .bitmap , 0 , 0 )
631+ if not (self and self .IsShownOnScreen ()):
632+ return
633+ if not drawDC : # not called from OnPaint use a ClientDC
634+ drawDC = wx .ClientDC (self )
635+ # For 'WX' backend on Windows, the bitmap can not be in use by another
636+ # DC (see GraphicsContextWx._cache).
637+ bmp = (self .bitmap .ConvertToImage ().ConvertToBitmap ()
638+ if wx .Platform == '__WXMSW__' and origin == 'WX'
639+ else self .bitmap )
640+ drawDC .DrawBitmap (bmp , 0 , 0 )
641+ if self ._rubberband_rect is not None :
642+ x0 , y0 , x1 , y1 = self ._rubberband_rect
643+ drawDC .DrawLineList (
644+ [(x0 , y0 , x1 , y0 ), (x1 , y0 , x1 , y1 ),
645+ (x0 , y0 , x0 , y1 ), (x0 , y1 , x1 , y1 )],
646+ wx .Pen ('BLACK' , 1 , wx .PENSTYLE_SHORT_DASH ))
645647
646648 filetypes = {
647649 ** FigureCanvasBase .filetypes ,
@@ -1250,58 +1252,13 @@ def release_zoom(self, event):
12501252 self ._zoomAxes = None
12511253
12521254 def draw_rubberband (self , event , x0 , y0 , x1 , y1 ):
1253- if self ._retinaFix : # On Macs, use the following code
1254- # wx.DCOverlay does not work properly on Retina displays.
1255- rubberBandColor = '#C0C0FF'
1256- if self ._prevZoomRect :
1257- self ._prevZoomRect .pop (0 ).remove ()
1258- self .canvas .restore_region (self ._savedRetinaImage )
1259- X0 , X1 = self ._zoomStartX , event .xdata
1260- Y0 , Y1 = self ._zoomStartY , event .ydata
1261- lineX = (X0 , X0 , X1 , X1 , X0 )
1262- lineY = (Y0 , Y1 , Y1 , Y0 , Y0 )
1263- self ._prevZoomRect = self ._zoomAxes .plot (
1264- lineX , lineY , '-' , color = rubberBandColor )
1265- self ._zoomAxes .draw_artist (self ._prevZoomRect [0 ])
1266- self .canvas .blit (self ._zoomAxes .bbox )
1267- return
1268-
1269- # Use an Overlay to draw a rubberband-like bounding box.
1270-
1271- dc = wx .ClientDC (self .canvas )
1272- odc = wx .DCOverlay (self ._wxoverlay , dc )
1273- odc .Clear ()
1274-
1275- # Mac's DC is already the same as a GCDC, and it causes
1276- # problems with the overlay if we try to use an actual
1277- # wx.GCDC so don't try it.
1278- if 'wxMac' not in wx .PlatformInfo :
1279- dc = wx .GCDC (dc )
1280-
12811255 height = self .canvas .figure .bbox .height
1282- y1 = height - y1
1283- y0 = height - y0
1284-
1285- if y1 < y0 :
1286- y0 , y1 = y1 , y0
1287- if x1 < x0 :
1288- x0 , x1 = x1 , x0
1289-
1290- w = x1 - x0
1291- h = y1 - y0
1292- rect = wx .Rect (x0 , y0 , w , h )
1256+ self .canvas ._rubberband_rect = (x0 , height - y0 , x1 , height - y1 )
1257+ self .canvas .Refresh ()
12931258
1294- rubberBandColor = '#C0C0FF' # or load from config?
1295-
1296- # Set a pen for the border
1297- color = wx .Colour (rubberBandColor )
1298- dc .SetPen (wx .Pen (color , 1 ))
1299-
1300- # use the same color, plus alpha for the brush
1301- r , g , b , a = color .Get (True )
1302- color .Set (r , g , b , 0x60 )
1303- dc .SetBrush (wx .Brush (color ))
1304- dc .DrawRectangle (rect )
1259+ def remove_rubberband (self ):
1260+ self .canvas ._rubberband_rect = None
1261+ self .canvas .Refresh ()
13051262
13061263 def set_message (self , s ):
13071264 if self ._coordinates :
@@ -1449,91 +1406,14 @@ def set_cursor(self, cursor):
14491406 self ._make_classic_style_pseudo_toolbar (), cursor )
14501407
14511408
1452- if 'wxMac' not in wx .PlatformInfo :
1453- # on most platforms, use overlay
1454- class RubberbandWx (backend_tools .RubberbandBase ):
1455- def __init__ (self , * args , ** kwargs ):
1456- super ().__init__ (* args , ** kwargs )
1457- self ._wxoverlay = None
1409+ class RubberbandWx (backend_tools .RubberbandBase ):
1410+ def draw_rubberband (self , x0 , y0 , x1 , y1 ):
1411+ NavigationToolbar2Wx .draw_rubberband (
1412+ self ._make_classic_style_pseudo_toolbar (), None , x0 , y0 , x1 , y1 )
14581413
1459- def draw_rubberband (self , x0 , y0 , x1 , y1 ):
1460- # Use an Overlay to draw a rubberband-like bounding box.
1461- if self ._wxoverlay is None :
1462- self ._wxoverlay = wx .Overlay ()
1463- dc = wx .ClientDC (self .canvas )
1464- odc = wx .DCOverlay (self ._wxoverlay , dc )
1465- odc .Clear ()
1466-
1467- dc = wx .GCDC (dc )
1468-
1469- height = self .canvas .figure .bbox .height
1470- y1 = height - y1
1471- y0 = height - y0
1472-
1473- if y1 < y0 :
1474- y0 , y1 = y1 , y0
1475- if x1 < x0 :
1476- x0 , x1 = x1 , x0
1477-
1478- w = x1 - x0
1479- h = y1 - y0
1480- rect = wx .Rect (x0 , y0 , w , h )
1481-
1482- rubberBandColor = '#C0C0FF' # or load from config?
1483-
1484- # Set a pen for the border
1485- color = wx .Colour (rubberBandColor )
1486- dc .SetPen (wx .Pen (color , 1 ))
1487-
1488- # use the same color, plus alpha for the brush
1489- r , g , b , a = color .Get (True )
1490- color .Set (r , g , b , 0x60 )
1491- dc .SetBrush (wx .Brush (color ))
1492- dc .DrawRectangle (rect )
1493-
1494- def remove_rubberband (self ):
1495- if self ._wxoverlay is None :
1496- return
1497- self ._wxoverlay .Reset ()
1498- self ._wxoverlay = None
1499-
1500- else :
1501- # on Mac OS retina displays DCOverlay does not work
1502- # and dc.SetLogicalFunction does not have an effect on any display
1503- # the workaround is to blit the full image for remove_rubberband
1504- class RubberbandWx (backend_tools .RubberbandBase ):
1505- def __init__ (self , * args , ** kwargs ):
1506- super ().__init__ (* args , ** kwargs )
1507- self ._rect = None
1508-
1509- def draw_rubberband (self , x0 , y0 , x1 , y1 ):
1510- dc = wx .ClientDC (self .canvas )
1511- # this would be required if the Canvas is a ScrolledWindow,
1512- # which is not the case for now
1513- # self.PrepareDC(dc)
1514-
1515- # delete old rubberband
1516- if self ._rect :
1517- self .remove_rubberband (dc )
1518-
1519- # draw new rubberband
1520- dc .SetPen (wx .Pen (wx .BLACK , 1 , wx .SOLID ))
1521- dc .SetBrush (wx .TRANSPARENT_BRUSH )
1522- self ._rect = (x0 , self .canvas ._height - y0 , x1 - x0 , - y1 + y0 )
1523- dc .DrawRectangle (self ._rect )
1524-
1525- def remove_rubberband (self , dc = None ):
1526- if not self ._rect :
1527- return
1528- if self .canvas .bitmap :
1529- if dc is None :
1530- dc = wx .ClientDC (self .canvas )
1531- dc .DrawBitmap (self .canvas .bitmap , 0 , 0 )
1532- # for testing the method on Windows, use this code instead:
1533- # img = self.canvas.bitmap.ConvertToImage()
1534- # bmp = img.ConvertToBitmap()
1535- # dc.DrawBitmap(bmp, 0, 0)
1536- self ._rect = None
1414+ def remove_rubberband (self ):
1415+ NavigationToolbar2Wx .remove_rubberband (
1416+ self ._make_classic_style_pseudo_toolbar ())
15371417
15381418
15391419class _HelpDialog (wx .Dialog ):
0 commit comments