source: sasview/src/sas/sasgui/plottools/toolbar.py @ d620d03c

Last change on this file since d620d03c was 34f23c8, checked in by Paul Kienzle <pkienzle@…>, 6 years ago

py3/wx4 compatibility changes for gui. Refs #1249

  • Property mode set to 100644
File size: 6.5 KB
Line 
1"""
2    This module overwrites matplotlib toolbar
3"""
4import wx
5from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg
6from matplotlib.backends.backend_wx import _load_bitmap
7import logging
8
9logger = logging.getLogger(__name__)
10
11# Event binding code changed after version 2.5
12if wx.VERSION_STRING >= '2.5':
13    def bind(actor, event, action, **kw):
14        actor.Bind(event, action, **kw)
15else:
16    def bind(actor, event, action, id=None):
17        if id is not None:
18            event(actor, id, action)
19        else:
20            event(actor, action)
21
22class NavigationToolBar(NavigationToolbar2WxAgg):
23    _NTB2_HOME = wx.NewId()
24    _NTB2_BACK = wx.NewId()
25    _NTB2_FORWARD = wx.NewId()
26    _NTB2_PAN = wx.NewId()
27    _NTB2_ZOOM = wx.NewId()
28    _NTB2_SAVE = wx.NewId()
29    _NTB2_PRINT = wx.NewId()
30    _NTB2_RESET = wx.NewId()
31    _NTB2_COPY = wx.NewId()
32    """
33    Overwrite matplotlib toolbar
34    """
35    def __init__(self, canvas, parent=None):
36        NavigationToolbar2WxAgg.__init__(self, canvas)
37
38    # CRUFT: mpl 1.1 uses save rather than save_figure
39    try: save_figure = NavigationToolbar2WxAgg.save
40    except AttributeError: pass
41
42    def _init_toolbar(self):
43        self._parent = self.canvas.GetParent()
44
45        # for mpl 1.2+ compatibility
46        self.wx_ids = {}
47        self.wx_ids['Back'] = self._NTB2_BACK
48        self.wx_ids['Forward'] = self._NTB2_FORWARD
49        self.wx_ids['Pan'] = self._NTB2_PAN
50        self.wx_ids['Zoom'] = self._NTB2_ZOOM
51
52        self.SetToolBitmapSize(wx.Size(24, 24))
53
54        context_tip = 'Graph Menu: \n'
55        context_tip += '    For more menu options, \n'
56        context_tip += '    right-click the data symbols.'
57        context = wx.ArtProvider.GetBitmap(wx.ART_LIST_VIEW, wx.ART_TOOLBAR)
58        self.AddSimpleTool(self._NTB2_HOME, context, context_tip, context_tip)
59
60        self.InsertSeparator(1)
61
62        self.AddSimpleTool(self._NTB2_BACK, _load_bitmap('back.png'),
63                           'Back', 'Back navigation view')
64        self.AddSimpleTool(self._NTB2_FORWARD, _load_bitmap('forward.png'),
65                           'Forward', 'Forward navigation view')
66        # todo: get new bitmap
67        # todo: update with code from matplotlib/backends/backend_wx.py
68        if 'phoenix' in wx.PlatformInfo: # wx phoenix >= 4.0.0b2
69            self.AddCheckTool(self._NTB2_PAN, "Pan", _load_bitmap('move.png'),
70                              shortHelp='Pan',
71                              longHelp='Pan with left, zoom with right')
72            self.AddCheckTool(self._NTB2_ZOOM, "Zoom", _load_bitmap('zoom_to_rect.png'),
73                              shortHelp='Zoom', longHelp='Zoom to rectangle')
74        else:
75            self.AddCheckTool(self._NTB2_PAN, _load_bitmap('move.png'),
76                              shortHelp='Pan',
77                              longHelp='Pan with left, zoom with right')
78            self.AddCheckTool(self._NTB2_ZOOM, _load_bitmap('zoom_to_rect.png'),
79                              shortHelp='Zoom', longHelp='Zoom to rectangle')
80
81        self.AddSeparator()
82        self.AddSimpleTool(self._NTB2_SAVE, _load_bitmap('filesave.png'),
83                           'Save', 'Save plot contents to file')
84
85        print_bmp = wx.ArtProvider.GetBitmap(wx.ART_PRINT, wx.ART_TOOLBAR)
86        self.AddSimpleTool(self._NTB2_PRINT, print_bmp, 'Print', 'Print plot')
87
88        reset_bmp = wx.ArtProvider.GetBitmap(wx.ART_GO_HOME, wx.ART_TOOLBAR)
89        self.AddSimpleTool(self._NTB2_RESET, reset_bmp, 'Reset', 'Reset graph range')
90
91        bind(self, wx.EVT_TOOL, self.context_menu, id=self._NTB2_HOME)
92        bind(self, wx.EVT_TOOL, self.forward, id=self._NTB2_FORWARD)
93        bind(self, wx.EVT_TOOL, self.back, id=self._NTB2_BACK)
94        bind(self, wx.EVT_TOOL, self.zoom, id=self._NTB2_ZOOM)
95        bind(self, wx.EVT_TOOL, self.pan, id=self._NTB2_PAN)
96        bind(self, wx.EVT_TOOL, self.save_figure, id=self._NTB2_SAVE)
97        bind(self, wx.EVT_TOOL, self.print_figure, id=self._NTB2_PRINT)
98        bind(self, wx.EVT_TOOL, self.home, id=self._NTB2_RESET)
99
100        self.Realize()
101
102    def on_menu(self, event):
103        try:
104            self._parent.onToolContextMenu(event=event)
105        except:
106            logger.error("Plot toolbar could not show menu")
107
108    def context_menu(self, event):
109        """
110        Default context menu for a plot panel
111
112        """
113        # Slicer plot popup menu
114        popup = wx.Menu()
115        popup.Append(self._NTB2_SAVE, '&Save image', 'Save image as PNG')
116        wx.EVT_MENU(self, self._NTB2_SAVE, self.save_figure)
117
118        popup.Append(self._NTB2_PRINT, '&Print image', 'Print image ')
119        wx.EVT_MENU(self, self._NTB2_PRINT, self.print_figure)
120
121        popup.Append(self._NTB2_COPY, '&Copy to Clipboard', 'Copy image to the clipboard')
122        wx.EVT_MENU(self, self._NTB2_COPY, self.copy_figure)
123
124        # Show the popup menu relative to the location of the toolbar
125        self.PopupMenu(popup, (0,0))
126
127
128    def print_figure(self, event):
129        try:
130            _printer = wx.Printer()
131            _printer.Print(self.canvas, PlotPrintout(self.canvas), True)
132        except:
133            import traceback
134            logger.error(traceback.format_exc())
135
136    def copy_figure(self, event):
137        copy_image_to_clipboard(self.canvas)
138
139class PlotPrintout(wx.Printout):
140    """
141    Create the wx.Printout object for matplotlib figure from the PlotPanel.
142    Provides the required OnPrintPage and HasPage overrides.  Other methods
143    may be added/overriden in the future.
144    :TODO: this needs LOTS of TLC .. but fixes immediate problem
145    """
146    def __init__(self, canvas):
147        """
148        Initialize wx.Printout and get passed figure object
149        """
150        wx.Printout.__init__(self)
151        self.canvas = canvas
152
153    def OnPrintPage(self, page):
154        """
155        Most rudimentry OnPrintPage override.  instatiates a dc object, gets
156        its size, gets the size of the figure object, scales it to the dc
157        canvas size keeping the aspect ratio intact, then prints as bitmap
158        """
159        _dc = self.GetDC()
160        _dcX, _dcY = _dc.GetSize()
161        _bmpX, _bmpY = self.canvas.GetSize()
162        _scale = min(_dcX/_bmpX, _dcY/_bmpY)
163        _dc.SetUserScale(_scale, _scale)
164        _dc.DrawBitmap(self.canvas.bitmap, 0, 0, False,)
165        return True
166
167    def GetPageInfo(self):
168        """
169        just sets the page to 1 - no flexibility for now
170        """
171        return (1, 1, 1, 1)
172
173
174def copy_image_to_clipboard(canvas):
175    bmp = wx.BitmapDataObject()
176    bmp.SetBitmap(canvas.bitmap)
177
178    wx.TheClipboard.Open()
179    wx.TheClipboard.SetData(bmp)
180    wx.TheClipboard.Close()
181
182
Note: See TracBrowser for help on using the repository browser.