IPlugin.py 5.3 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#MDANSE : Molecular Dynamics Analysis for Neutron Scattering Experiments
#------------------------------------------------------------------------------------------
#Copyright (C)
#2015- Eric C. Pellegrini Institut Laue-Langevin
#BP 156
#6, rue Jules Horowitz
#38042 Grenoble Cedex 9
#France
#pellegrini[at]ill.fr
#goret[at]ill.fr
#aoun[at]ill.fr
#
#This library is free software; you can redistribute it and/or
#modify it under the terms of the GNU Lesser General Public
#License as published by the Free Software Foundation; either
#version 2.1 of the License, or (at your option) any later version.
#
#This library is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#Lesser General Public License for more details.
#
#You should have received a copy of the GNU Lesser General Public
#License along with this library; if not, write to the Free Software
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

''' 
Created on Mar 30, 2015

:author: Gael Goret, Eric C. Pellegrini
'''

import abc
import cPickle

import wx
import wx.aui as aui

from MDANSE import REGISTRY
40
41

from MDANSE.GUI import PUBLISHER
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

def plugin_parent(window):
                          
    if window == window.TopLevelParent:
        return None
     
    if isinstance(window,IPlugin):
        return window
     
    else:
        return plugin_parent(window.Parent)

class PluginDropTarget(wx.DropTarget):

    def __init__(self, targetPanel):

        wx.DropTarget.__init__(self)
        self._targetPanel = targetPanel
        
        self._data = wx.CustomDataObject("Plugin")
        self.SetDataObject(self._data)
        
    @property
    def target_panel(self):
        return self._targetPanel

    def OnDrop(self, x, y):
        return True

    def OnDragOver(self, x, y, d):
        return wx.DragCopy

    def OnData(self, x, y, d):

        if self.GetData():
            pluginName = cPickle.loads(self._data.GetData())
            self._targetPanel.drop(pluginName)

        return d

class IPlugin(wx.Panel):
    
    __metaclass__ = REGISTRY
    
    type = "plugin"
        
88
    ancestor = []
89
90
91
92
93
94
    
    def __init__(self, parent, *args, **kwargs):
        
        wx.Panel.__init__(self, parent, *args, **kwargs)
        
        self._parent = parent
95
96

        self._currentWindow = self
97
98
99
100
101
        
        self.SetDropTarget(PluginDropTarget(self))
        
        self.build_dialog()
        
102
103
        self._mgr.Bind(wx.EVT_CHILD_FOCUS, self.on_changing_pane)
                
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
        self._mgr.Bind(aui.EVT_AUI_PANE_CLOSE, self.on_close_pane)
                                                        
    @abc.abstractmethod
    def build_panel(self):
        pass
    
    @abc.abstractmethod
    def plug(self, standalone=False):
        pass
    
    @property
    def mgr(self):
        return self._mgr
    
    @property
    def parent(self):
        return self._parent
    
    def is_parent(self,window):
123
                        
124
125
        if window == self:
            return True
126
127
128

        if window is None:
            return False
129
130
    
        return self.is_parent(window.Parent)    
131
132
133

    @property
    def currentWindow(self):
134
        
135
        return self._currentWindow
136
137
138
139
    
    def close(self):
        
        pass
140
                
141
    def on_close_pane(self, event):
142
143
144

        d = wx.MessageDialog(None, 'Closing this plugin will also close all the other ones you plugged in in so far. Do you really want to close ?', 'Question', wx.YES_NO|wx.YES_DEFAULT|wx.ICON_QUESTION)
        if d.ShowModal() == wx.ID_NO:
145
            event.Veto()
146
            return
147
                
148
        window = event.GetPane().window
149
                
150
151
152
        # Call the 'close' method the plugin to be closed
        window.close()
        
153
154
155
        self._mgr.DetachPane(window)
        window.Destroy()
        self._mgr.Update()
156
            
157
158
        self.SetFocus()
        
159
160
        self._currentWindow = self
        
161
        PUBLISHER.sendMessage('msg_set_plugins_tree', data=self)
162
                                            
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
    def build_dialog(self):

        self.Freeze()

        self._mgr = aui.AuiManager(self)

        self.build_panel()  
         
        self._mgr.Update()
        
        self.Thaw()
        
    def drop(self, pluginName):
                                        
        # If no plugin match the name of the dropped plugin, do nothing.
178
        plugin = REGISTRY["plugin"].get(pluginName,None)  
179
180
        if plugin is None:
            return
181
                                                               
182
183
184
185
186
187
188
189
        plugin = plugin(self)

        self._mgr.AddPane(plugin, aui.AuiPaneInfo().Caption(getattr(plugin, "label", pluginName)))

        self._mgr.Update()
        
        plugin.plug()
        
190
191
        plugin.SetFocus()
        
192
    def on_changing_pane(self, event):
193
        
194
195
196
197
        window = plugin_parent(event.GetWindow())
                
        if window is None:
            return
198
        
199
200
        self._currentWindow = window

201
        PUBLISHER.sendMessage('msg_set_plugins_tree', data=window)
202
203