Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 84b14c7

Browse filesBrowse files
authored
Merge pull request #18599 from anntzer/wxrub
Simplify wx rubberband drawing.
2 parents 7ce2f67 + 7465670 commit 84b14c7
Copy full SHA for 84b14c7

File tree

Expand file treeCollapse file tree

1 file changed

+29
-149
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+29
-149
lines changed

‎lib/matplotlib/backends/backend_wx.py

Copy file name to clipboardExpand all lines: lib/matplotlib/backends/backend_wx.py
+29-149Lines changed: 29 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -525,8 +525,8 @@ def __init__(self, parent, id, figure):
525525
# Create the drawing bitmap
526526
self.bitmap = wx.Bitmap(w, h)
527527
_log.debug("%s - __init__() - bitmap w:%d h:%d", type(self), w, h)
528-
# TODO: Add support for 'point' inspection and plot navigation.
529528
self._isDrawn = False
529+
self._rubberband_rect = None
530530

531531
self.Bind(wx.EVT_SIZE, self._onSize)
532532
self.Bind(wx.EVT_PAINT, self._onPaint)
@@ -625,20 +625,22 @@ def gui_repaint(self, drawDC=None, origin='WX'):
625625
_log.debug("%s - gui_repaint()", type(self))
626626
# The "if self" check avoids a "wrapped C/C++ object has been deleted"
627627
# RuntimeError if doing things after window is closed.
628-
if self and self.IsShownOnScreen():
629-
if not drawDC:
630-
# not called from OnPaint use a ClientDC
631-
drawDC = wx.ClientDC(self)
632-
633-
# following is for 'WX' backend on Windows
634-
# the bitmap can not be in use by another DC,
635-
# see GraphicsContextWx._cache
636-
if wx.Platform == '__WXMSW__' and origin == 'WX':
637-
img = self.bitmap.ConvertToImage()
638-
bmp = img.ConvertToBitmap()
639-
drawDC.DrawBitmap(bmp, 0, 0)
640-
else:
641-
drawDC.DrawBitmap(self.bitmap, 0, 0)
628+
if not (self and self.IsShownOnScreen()):
629+
return
630+
if not drawDC: # not called from OnPaint use a ClientDC
631+
drawDC = wx.ClientDC(self)
632+
# For 'WX' backend on Windows, the bitmap can not be in use by another
633+
# DC (see GraphicsContextWx._cache).
634+
bmp = (self.bitmap.ConvertToImage().ConvertToBitmap()
635+
if wx.Platform == '__WXMSW__' and origin == 'WX'
636+
else self.bitmap)
637+
drawDC.DrawBitmap(bmp, 0, 0)
638+
if self._rubberband_rect is not None:
639+
x0, y0, x1, y1 = self._rubberband_rect
640+
drawDC.DrawLineList(
641+
[(x0, y0, x1, y0), (x1, y0, x1, y1),
642+
(x0, y0, x0, y1), (x0, y1, x1, y1)],
643+
wx.Pen('BLACK', 1, wx.PENSTYLE_SHORT_DASH))
642644

643645
filetypes = {
644646
**FigureCanvasBase.filetypes,
@@ -1249,58 +1251,13 @@ def release_zoom(self, event):
12491251
self._zoomAxes = None
12501252

12511253
def draw_rubberband(self, event, x0, y0, x1, y1):
1252-
if self._retinaFix: # On Macs, use the following code
1253-
# wx.DCOverlay does not work properly on Retina displays.
1254-
rubberBandColor = '#C0C0FF'
1255-
if self._prevZoomRect:
1256-
self._prevZoomRect.pop(0).remove()
1257-
self.canvas.restore_region(self._savedRetinaImage)
1258-
X0, X1 = self._zoomStartX, event.xdata
1259-
Y0, Y1 = self._zoomStartY, event.ydata
1260-
lineX = (X0, X0, X1, X1, X0)
1261-
lineY = (Y0, Y1, Y1, Y0, Y0)
1262-
self._prevZoomRect = self._zoomAxes.plot(
1263-
lineX, lineY, '-', color=rubberBandColor)
1264-
self._zoomAxes.draw_artist(self._prevZoomRect[0])
1265-
self.canvas.blit(self._zoomAxes.bbox)
1266-
return
1267-
1268-
# Use an Overlay to draw a rubberband-like bounding box.
1269-
1270-
dc = wx.ClientDC(self.canvas)
1271-
odc = wx.DCOverlay(self._wxoverlay, dc)
1272-
odc.Clear()
1273-
1274-
# Mac's DC is already the same as a GCDC, and it causes
1275-
# problems with the overlay if we try to use an actual
1276-
# wx.GCDC so don't try it.
1277-
if 'wxMac' not in wx.PlatformInfo:
1278-
dc = wx.GCDC(dc)
1279-
12801254
height = self.canvas.figure.bbox.height
1281-
y1 = height - y1
1282-
y0 = height - y0
1283-
1284-
if y1 < y0:
1285-
y0, y1 = y1, y0
1286-
if x1 < x0:
1287-
x0, x1 = x1, x0
1288-
1289-
w = x1 - x0
1290-
h = y1 - y0
1291-
rect = wx.Rect(x0, y0, w, h)
1255+
self.canvas._rubberband_rect = (x0, height - y0, x1, height - y1)
1256+
self.canvas.Refresh()
12921257

1293-
rubberBandColor = '#C0C0FF' # or load from config?
1294-
1295-
# Set a pen for the border
1296-
color = wx.Colour(rubberBandColor)
1297-
dc.SetPen(wx.Pen(color, 1))
1298-
1299-
# use the same color, plus alpha for the brush
1300-
r, g, b, a = color.Get(True)
1301-
color.Set(r, g, b, 0x60)
1302-
dc.SetBrush(wx.Brush(color))
1303-
dc.DrawRectangle(rect)
1258+
def remove_rubberband(self):
1259+
self.canvas._rubberband_rect = None
1260+
self.canvas.Refresh()
13041261

13051262
def set_message(self, s):
13061263
if self._coordinates:
@@ -1448,91 +1405,14 @@ def set_cursor(self, cursor):
14481405
self._make_classic_style_pseudo_toolbar(), cursor)
14491406

14501407

1451-
if 'wxMac' not in wx.PlatformInfo:
1452-
# on most platforms, use overlay
1453-
class RubberbandWx(backend_tools.RubberbandBase):
1454-
def __init__(self, *args, **kwargs):
1455-
super().__init__(*args, **kwargs)
1456-
self._wxoverlay = None
1408+
class RubberbandWx(backend_tools.RubberbandBase):
1409+
def draw_rubberband(self, x0, y0, x1, y1):
1410+
NavigationToolbar2Wx.draw_rubberband(
1411+
self._make_classic_style_pseudo_toolbar(), None, x0, y0, x1, y1)
14571412

1458-
def draw_rubberband(self, x0, y0, x1, y1):
1459-
# Use an Overlay to draw a rubberband-like bounding box.
1460-
if self._wxoverlay is None:
1461-
self._wxoverlay = wx.Overlay()
1462-
dc = wx.ClientDC(self.canvas)
1463-
odc = wx.DCOverlay(self._wxoverlay, dc)
1464-
odc.Clear()
1465-
1466-
dc = wx.GCDC(dc)
1467-
1468-
height = self.canvas.figure.bbox.height
1469-
y1 = height - y1
1470-
y0 = height - y0
1471-
1472-
if y1 < y0:
1473-
y0, y1 = y1, y0
1474-
if x1 < x0:
1475-
x0, x1 = x1, x0
1476-
1477-
w = x1 - x0
1478-
h = y1 - y0
1479-
rect = wx.Rect(x0, y0, w, h)
1480-
1481-
rubberBandColor = '#C0C0FF' # or load from config?
1482-
1483-
# Set a pen for the border
1484-
color = wx.Colour(rubberBandColor)
1485-
dc.SetPen(wx.Pen(color, 1))
1486-
1487-
# use the same color, plus alpha for the brush
1488-
r, g, b, a = color.Get(True)
1489-
color.Set(r, g, b, 0x60)
1490-
dc.SetBrush(wx.Brush(color))
1491-
dc.DrawRectangle(rect)
1492-
1493-
def remove_rubberband(self):
1494-
if self._wxoverlay is None:
1495-
return
1496-
self._wxoverlay.Reset()
1497-
self._wxoverlay = None
1498-
1499-
else:
1500-
# on Mac OS retina displays DCOverlay does not work
1501-
# and dc.SetLogicalFunction does not have an effect on any display
1502-
# the workaround is to blit the full image for remove_rubberband
1503-
class RubberbandWx(backend_tools.RubberbandBase):
1504-
def __init__(self, *args, **kwargs):
1505-
super().__init__(*args, **kwargs)
1506-
self._rect = None
1507-
1508-
def draw_rubberband(self, x0, y0, x1, y1):
1509-
dc = wx.ClientDC(self.canvas)
1510-
# this would be required if the Canvas is a ScrolledWindow,
1511-
# which is not the case for now
1512-
# self.PrepareDC(dc)
1513-
1514-
# delete old rubberband
1515-
if self._rect:
1516-
self.remove_rubberband(dc)
1517-
1518-
# draw new rubberband
1519-
dc.SetPen(wx.Pen(wx.BLACK, 1, wx.SOLID))
1520-
dc.SetBrush(wx.TRANSPARENT_BRUSH)
1521-
self._rect = (x0, self.canvas._height-y0, x1-x0, -y1+y0)
1522-
dc.DrawRectangle(self._rect)
1523-
1524-
def remove_rubberband(self, dc=None):
1525-
if not self._rect:
1526-
return
1527-
if self.canvas.bitmap:
1528-
if dc is None:
1529-
dc = wx.ClientDC(self.canvas)
1530-
dc.DrawBitmap(self.canvas.bitmap, 0, 0)
1531-
# for testing the method on Windows, use this code instead:
1532-
# img = self.canvas.bitmap.ConvertToImage()
1533-
# bmp = img.ConvertToBitmap()
1534-
# dc.DrawBitmap(bmp, 0, 0)
1535-
self._rect = None
1413+
def remove_rubberband(self):
1414+
NavigationToolbar2Wx.remove_rubberband(
1415+
self._make_classic_style_pseudo_toolbar())
15361416

15371417

15381418
class _HelpDialog(wx.Dialog):

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.