source: sasview/src/sas/sasgui/perspectives/simulation/ShapeParameters.py @ f370ea07

Last change on this file since f370ea07 was d85c194, checked in by Piotr Rozyczko <piotr.rozyczko@…>, 9 years ago

Remaining modules refactored

  • Property mode set to 100644
File size: 20.9 KB
RevLine 
[eaeb13e]1"""
2This software was developed by the University of Tennessee as part of the
3Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
4project funded by the US National Science Foundation.
5
6See the license text in license.txt
7
8copyright 2009, University of Tennessee
9"""
10import wx
11import sys
12import wx.lib.newevent
13from copy import deepcopy
14import SimCanvas
15
16(CreateShapeEvent, EVT_ADD_SHAPE) = wx.lib.newevent.NewEvent()
17(EditShapeEvent, EVT_EDIT_SHAPE)  = wx.lib.newevent.NewEvent()
[6ef7ac5a]18(DelShapeEvent, EVT_DEL_SHAPE)    = wx.lib.newevent.NewEvent()
19(QRangeEvent, EVT_Q_RANGE)        = wx.lib.newevent.NewEvent() 
20(PtDensityEvent, EVT_PT_DENSITY)  = wx.lib.newevent.NewEvent() 
[eaeb13e]21
22class ShapeParameterPanel(wx.Panel):
23    #TODO: show units
24    #TODO: order parameters properly
25    CENTER_PANE = True
26   
[6ef7ac5a]27    def __init__(self, parent, q_min=0.001, q_max=0.5, q_npts=10, pt_density=0.1, *args, **kwargs):
[eaeb13e]28        wx.Panel.__init__(self, parent, *args, **kwargs)
29       
30        self.window_name = "ShapeParams"
31        self.window_caption = "Shape parameter"
32       
33     
34        self.params = {}
35        self.parent = parent
36        self.type = None
37        self.listeners = []
38        self.parameters = []
39        self.bck = wx.GridBagSizer(5,5)
40        self.SetSizer(self.bck)
41       
42        # position and orientation ctrl
43        self.xctrl = None
44        self.yctrl = None
45        self.zctrl = None
46        self.actrl = None
47        self.bctrl = None
48        self.cctrl = None
49               
50        # Sizer to hold the shape parameters
51        self.shape_sizer = wx.GridBagSizer(5,5)
52       
[cb78690]53        ny = 0       
[eaeb13e]54        title = wx.StaticText(self, -1, "[Temporary form]", style=wx.ALIGN_LEFT)
[cb78690]55        self.bck.Add(title, (ny,0), (1,2), flag=wx.LEFT|wx.ALIGN_CENTER_VERTICAL, border=15)
56       
57        # Shape list
58        shape_text = wx.StaticText(self, -1, "Geometric shape", style=wx.ALIGN_LEFT)
59        self.shape_list = SimCanvas.getShapes()
60        value_list = []
61        for item in self.shape_list:
62            value_list.append(item['name'])
63           
64        self.model_combo = wx.ComboBox(self, -1, value=value_list[0], choices=value_list, style=wx.CB_READONLY)
[6ef7ac5a]65        self.model_combo.SetToolTip(wx.ToolTip("Select a geometric shape from the drop-down list"))
[eaeb13e]66       
[cb78690]67        ny+=1
68        self.bck.Add(shape_text, (ny,0), flag=wx.LEFT|wx.ALIGN_CENTER_VERTICAL, border=15)
69        self.bck.Add(self.model_combo, (ny,1), flag=wx.LEFT|wx.ALIGN_CENTER_VERTICAL, border=15)
70        wx.EVT_COMBOBOX(self.model_combo,-1, self._on_select_shape)
71   
72        # Placeholder for parameter form
73        ny+=1
74        self.bck.Add(self.shape_sizer, (ny,0), (1,2), flag=wx.LEFT|wx.ALIGN_CENTER_VERTICAL, border=0)   
[eaeb13e]75       
76        # Point density control
77        point_density_text = wx.StaticText(self, -1, "Point density", style=wx.ALIGN_LEFT)
[cb78690]78        ny+=1
79        self.bck.Add(point_density_text, (ny,0), flag = wx.LEFT|wx.ALIGN_CENTER_VERTICAL, border = 15)
[eaeb13e]80        self.point_density_ctrl = wx.TextCtrl(self, -1, size=(40,20), style=wx.TE_PROCESS_ENTER)
[6ef7ac5a]81        self.point_density_ctrl.SetValue(str(pt_density))
82        self.point_density_ctrl.SetToolTip(wx.ToolTip("Enter the number of real-space points per Angstrom cube"))
83        self.point_density_ctrl.Bind(wx.EVT_TEXT_ENTER, self._on_density_changed)
84        self.point_density_ctrl.Bind(wx.EVT_KILL_FOCUS, self._on_density_changed)
[cb78690]85        self.bck.Add(self.point_density_ctrl, (ny,1), flag = wx.LEFT|wx.ALIGN_CENTER_VERTICAL, border = 15)
[eaeb13e]86       
[cb78690]87        # Q range
88        q_min_text = wx.StaticText(self, -1, "Q min", style=wx.ALIGN_LEFT)
89        ny+=1
90        self.bck.Add(q_min_text, (ny,0), flag = wx.LEFT|wx.ALIGN_CENTER_VERTICAL, border = 15)
91        self.q_min_ctrl = wx.TextCtrl(self, -1, size=(40,20), style=wx.TE_PROCESS_ENTER)
[6ef7ac5a]92        self.q_min_ctrl.SetValue(str(q_min))
93        self.q_min_ctrl.SetToolTip(wx.ToolTip("Enter the minimum Q value to be simulated"))
94        self.q_min_ctrl.Bind(wx.EVT_TEXT_ENTER, self._on_q_range_changed)
95        self.q_min_ctrl.Bind(wx.EVT_KILL_FOCUS, self._on_q_range_changed)
[cb78690]96        self.bck.Add(self.q_min_ctrl, (ny,1), flag = wx.LEFT|wx.ALIGN_CENTER_VERTICAL, border = 15)
[eaeb13e]97       
[cb78690]98        q_max_text = wx.StaticText(self, -1, "Q max", style=wx.ALIGN_LEFT)
99        self.bck.Add(q_max_text, (ny,2), flag = wx.LEFT|wx.ALIGN_CENTER_VERTICAL, border = 15)
100        self.q_max_ctrl = wx.TextCtrl(self, -1, size=(40,20), style=wx.TE_PROCESS_ENTER)
[6ef7ac5a]101        self.q_max_ctrl.SetValue(str(q_max))
102        self.q_min_ctrl.SetToolTip(wx.ToolTip("Enter the maximum Q value to be simulated"))
103        self.q_max_ctrl.Bind(wx.EVT_TEXT_ENTER, self._on_q_range_changed)
104        self.q_max_ctrl.Bind(wx.EVT_KILL_FOCUS, self._on_q_range_changed)
[cb78690]105        self.bck.Add(self.q_max_ctrl, (ny,3), flag = wx.LEFT|wx.ALIGN_CENTER_VERTICAL, border = 15)
106       
[6ef7ac5a]107        q_npts_text = wx.StaticText(self, -1, "No. of Q pts", style=wx.ALIGN_LEFT)
108        self.bck.Add(q_npts_text, (ny,4), flag = wx.LEFT|wx.ALIGN_CENTER_VERTICAL, border = 15)
109        self.q_npts_ctrl = wx.TextCtrl(self, -1, size=(40,20), style=wx.TE_PROCESS_ENTER)
110        self.q_npts_ctrl.SetValue(str(q_npts))
111        self.q_min_ctrl.SetToolTip(wx.ToolTip("Enter the number of Q points to be simulated"))
112        self.q_npts_ctrl.Bind(wx.EVT_TEXT_ENTER, self._on_q_range_changed)
113        self.q_npts_ctrl.Bind(wx.EVT_KILL_FOCUS, self._on_q_range_changed)
114        self.bck.Add(self.q_npts_ctrl, (ny,5), flag = wx.LEFT|wx.ALIGN_CENTER_VERTICAL, border = 15)
115       
[cb78690]116        # Shape List
117        # Internal counter of shapes in the listbox
118        self.counter = 0
119        # Buffer filled flag
120        self.buffer_filled = False
121        # Save current flag
122        self.current_saved = False       
123         
124        id = wx.NewId()
125        shape_listbox_text = wx.StaticText(self, -1, "List of shapes on 3D canvas", style=wx.ALIGN_LEFT)
126        self.shape_listbox = wx.ListBox(self, id, wx.DefaultPosition, (295, 200), 
127                                   [], wx.LB_SINGLE | wx.LB_HSCROLL)
128       
129        # Listen to history events
130        self.parent.Bind(EVT_ADD_SHAPE, self._on_add_shape_to_listbox)
131        self.shape_listbox.Bind(wx.EVT_LISTBOX, self._on_select_from_listbox, id=id)
132        self.shape_listbox.Bind(wx.EVT_CONTEXT_MENU, self._on_listbox_context_menu, id=id)
133       
134        ny+=1
135        self.bck.Add(shape_listbox_text, (ny,0), (1,2), flag = wx.LEFT|wx.ALIGN_CENTER_VERTICAL, border = 15)
136        ny+=1
137        self.bck.Add(self.shape_listbox, (ny,0), (1,5), flag = wx.LEFT|wx.ALIGN_CENTER_VERTICAL, border = 15)
[eaeb13e]138       
139        self.current_shape = None
140       
[cb78690]141        # Default shape
142        if type(self.shape_list)==list and len(self.shape_list)>0:
143            shape = SimCanvas.getShapeClassByName(self.shape_list[0]['name'])()
144            self.editShape(shape)                       
145
146    def _on_select_shape(self, event):
147        shape = SimCanvas.getShapeClassByName(self.shape_list[event.GetEventObject().GetSelection()]['name'])()
148        self.editShape(shape)   
[eaeb13e]149
[6ef7ac5a]150    def _on_density_changed(self, event):
[eaeb13e]151        """
152            Process event that might mean a change of the simulation point density
153        """
[6ef7ac5a]154        npts  = self._readCtrlFloat(self.point_density_ctrl)
155        if npts is not None:
156            event = PtDensityEvent(npts=npts)
157            wx.PostEvent(self.parent, event)
[eaeb13e]158           
[6ef7ac5a]159    def _on_q_range_changed(self, event):
[eaeb13e]160        """
[6ef7ac5a]161            Process event that might mean a change in Q range
162            @param event: EVT_Q_RANGE event
[eaeb13e]163        """
[6ef7ac5a]164        q_min = self._readCtrlFloat(self.q_min_ctrl)
165        q_max = self._readCtrlFloat(self.q_max_ctrl)
166        npts  = self._readCtrlInt(self.q_npts_ctrl)
167        if q_min is not None or q_max is not None or npts is not None:
168            event = QRangeEvent(q_min=q_min, q_max=q_max, npts=npts)
169            wx.PostEvent(self.parent, event)
170           
[eaeb13e]171    def _onEditShape(self, evt):
172        """
173            Process an EVT_EDIT_SHAPE event
174            @param evt: EVT_EDIT_SHAPE object
175        """
176        evt.Skip()
177        self.editShape(evt.shape, False)
178       
179    def editShape(self, shape=None, new=True):
180        """
181            Rebuild the panel
182        """
183        self.current_shape = shape
184        self.shape_sizer.Clear(True) 
185        #self.type = type 
186       
187        if shape==None:
188            title = wx.StaticText(self, -1, "Use menu to add a shapes", style=wx.ALIGN_LEFT)
189            self.shape_sizer.Add(title, (0,0), (1,2), flag=wx.LEFT|wx.ALIGN_CENTER_VERTICAL, border=15)
190
191        else:
192            if new==False:
193                title = wx.StaticText(self, -1, "Edit shape parameters", style=wx.ALIGN_LEFT)
194            else:
195                title = wx.StaticText(self, -1, "Create shape from parameters", style=wx.ALIGN_LEFT)
196               
197            self.shape_sizer.Add(title, (0,0), (1,2), flag=wx.LEFT|wx.ALIGN_CENTER_VERTICAL, border=15)
198           
199            n = 1
200            self.parameters = []
201            keys = shape.params.keys()
202            keys.sort()
203           
204            for item in keys:
205                if item in ['contrast', 'order']:
206                    continue
207                n += 1
208                text = wx.StaticText(self, -1, item, style=wx.ALIGN_LEFT)
209                self.shape_sizer.Add(text, (n-1,0), flag = wx.LEFT|wx.ALIGN_CENTER_VERTICAL, border = 15)
210                ctl = wx.TextCtrl(self, -1, size=(40,20), style=wx.TE_PROCESS_ENTER)
211               
212               
213                ctl.SetValue(str(shape.params[item]))
214                self.Bind(wx.EVT_TEXT_ENTER, self.onTextEnter)
215                ctl.Bind(wx.EVT_KILL_FOCUS, self.onTextEnter)
216                self.parameters.append([item, ctl])
217                self.shape_sizer.Add(ctl, (n-1,1), flag=wx.TOP|wx.BOTTOM, border = 0)
218               
219                # Units
220                units = wx.StaticText(self, -1, shape.details[item], style=wx.ALIGN_LEFT)
221                self.shape_sizer.Add(units, (n-1,2), flag=wx.LEFT|wx.ALIGN_CENTER_VERTICAL, border = 15)
222
223            for item in ['contrast', 'order']:
224                n += 1
225                text = wx.StaticText(self, -1, item, style=wx.ALIGN_LEFT)
226                self.shape_sizer.Add(text, (n-1,0), flag = wx.LEFT|wx.ALIGN_CENTER_VERTICAL, border = 15)
227                ctl = wx.TextCtrl(self, -1, size=(40,20), style=wx.TE_PROCESS_ENTER)
228               
229               
230                ctl.SetValue(str(shape.params[item]))
231                self.Bind(wx.EVT_TEXT_ENTER, self.onTextEnter)
232                ctl.Bind(wx.EVT_KILL_FOCUS, self.onTextEnter)
233                self.parameters.append([item, ctl])
234                self.shape_sizer.Add(ctl, (n-1,1), flag=wx.TOP|wx.BOTTOM, border = 0)
235               
236                # Units
237                units = wx.StaticText(self, -1, shape.details[item], style=wx.ALIGN_LEFT)
238                self.shape_sizer.Add(units, (n-1,2), flag=wx.LEFT|wx.ALIGN_CENTER_VERTICAL, border = 15)
239               
240               
241            # Add position
242            n += 1
243           
244            pos_sizer = wx.GridBagSizer(0,0)
245           
246            text = wx.StaticText(self, -1, 'x', style=wx.ALIGN_LEFT)
247            pos_sizer.Add(text, (0,0), (1,1), flag = wx.LEFT|wx.ALIGN_CENTER, border = 15)
248            text = wx.StaticText(self, -1, 'y', style=wx.ALIGN_LEFT)
249            pos_sizer.Add(text, (0,1), (1,1), flag = wx.LEFT|wx.ALIGN_CENTER, border = 15)
250            text = wx.StaticText(self, -1, 'z', style=wx.ALIGN_LEFT)
251            pos_sizer.Add(text, (0,2), (1,1), flag = wx.LEFT|wx.ALIGN_CENTER, border = 15)
252           
253            self.xctrl = wx.TextCtrl(self, -1, size=(40,20), style=wx.TE_PROCESS_ENTER)
254            self.xctrl.SetValue(str(shape.x))
255            self.xctrl.Bind(wx.EVT_KILL_FOCUS, self.onTextEnter)
256            pos_sizer.Add(self.xctrl, (1,0), (1,1), flag = wx.LEFT|wx.ALIGN_CENTER, border = 15)
257            self.yctrl = wx.TextCtrl(self, -1, size=(40,20), style=wx.TE_PROCESS_ENTER)
258            self.yctrl.SetValue(str(shape.y))
259            self.yctrl.Bind(wx.EVT_KILL_FOCUS, self.onTextEnter)
260            pos_sizer.Add(self.yctrl, (1,1), (1,1), flag = wx.LEFT|wx.ALIGN_CENTER, border = 15)
261            self.zctrl = wx.TextCtrl(self, -1, size=(40,20), style=wx.TE_PROCESS_ENTER)
262            self.zctrl.SetValue(str(shape.z))
263            self.zctrl.Bind(wx.EVT_KILL_FOCUS, self.onTextEnter)
264            pos_sizer.Add(self.zctrl, (1,2), (1,1), flag = wx.LEFT|wx.ALIGN_CENTER, border = 15)
265           
266            self.shape_sizer.Add(pos_sizer, (n-1, 0), (1,3), flag=wx.LEFT|wx.ALIGN_CENTER)
267           
268            # Add orientation
269            n += 1
270           
271            pos_sizer = wx.GridBagSizer(0,0)
272           
273            text = wx.StaticText(self, -1, 'theta_x', style=wx.ALIGN_LEFT)
274            pos_sizer.Add(text, (0,0), (1,1), flag = wx.LEFT|wx.ALIGN_CENTER, border = 15)
275            text = wx.StaticText(self, -1, 'theta_y', style=wx.ALIGN_LEFT)
276            pos_sizer.Add(text, (0,1), (1,1), flag = wx.LEFT|wx.ALIGN_CENTER, border = 15)
277            text = wx.StaticText(self, -1, 'theta_z', style=wx.ALIGN_LEFT)
278            pos_sizer.Add(text, (0,2), (1,1), flag = wx.LEFT|wx.ALIGN_CENTER, border = 15)
279           
280            self.actrl = wx.TextCtrl(self, -1, size=(40,20), style=wx.TE_PROCESS_ENTER)
281            self.actrl.SetValue(str(shape.theta_x))
282            self.actrl.Bind(wx.EVT_KILL_FOCUS, self.onTextEnter)
283            pos_sizer.Add(self.actrl, (1,0), (1,1), flag = wx.LEFT|wx.ALIGN_CENTER, border = 15)
284            self.bctrl = wx.TextCtrl(self, -1, size=(40,20), style=wx.TE_PROCESS_ENTER)
285            self.bctrl.SetValue(str(shape.theta_y))
286            self.bctrl.Bind(wx.EVT_KILL_FOCUS, self.onTextEnter)
287            pos_sizer.Add(self.bctrl, (1,1), (1,1), flag = wx.LEFT|wx.ALIGN_CENTER, border = 15)
288            self.cctrl = wx.TextCtrl(self, -1, size=(40,20), style=wx.TE_PROCESS_ENTER)
289            self.cctrl.SetValue(str(shape.theta_z))
290            self.cctrl.Bind(wx.EVT_KILL_FOCUS, self.onTextEnter)
291            pos_sizer.Add(self.cctrl, (1,2), (1,1), flag = wx.LEFT|wx.ALIGN_CENTER, border = 15)
292           
293            self.shape_sizer.Add(pos_sizer, (n-1, 0), (1,3), flag=wx.LEFT|wx.ALIGN_CENTER)
294           
295           
296            # Add a button to create the new shape on the canvas
297            n += 1
298            if new==True:
299                create = wx.Button(self, 1,"Create")
300                self.shape_sizer.Add(create, (n-1,1), (1,2), flag=wx.ALIGN_RIGHT|wx.ALL, border = 15)
301                self.Bind(wx.EVT_BUTTON, self._onCreate, id = 1)       
302            else:
303                create = wx.Button(self, 1,"Apply")
304                self.shape_sizer.Add(create, (n-1,1), (1,2), flag=wx.ALIGN_RIGHT|wx.ALL, border = 15)
305                self.Bind(wx.EVT_BUTTON, self._onEdited, id = 1)       
306               
307
308
309        self.shape_sizer.Layout()
310        self.shape_sizer.Fit(self)
[cb78690]311        try:
312            self.parent.GetSizer().Layout()
313        except:
314            print "TODO: move the Layout call of editShape up to the caller"
[eaeb13e]315
316    def _readCtrlFloat(self, ctrl):
[6ef7ac5a]317        """
318            Parses a TextCtrl for a float value.
319            Returns None is the value hasn't changed or the value is not a float.
320            The control background turns pink if the value is not a float.
321           
322            @param ctrl: TextCtrl object
323        """
[eaeb13e]324        if ctrl.IsModified():
[6ef7ac5a]325            ctrl.SetModified(False)
[eaeb13e]326            str_value = ctrl.GetValue().lstrip().rstrip()
327            try:
328                flt_value = float(str_value)
329                ctrl.SetBackgroundColour(
330                        wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
331                ctrl.Refresh()
332                return flt_value
333            except:
334                ctrl.SetBackgroundColour("pink")
335                ctrl.Refresh()
336        return None
337
[6ef7ac5a]338    def _readCtrlInt(self, ctrl):
339        """
340            Parses a TextCtrl for a float value.
341            Returns None is the value hasn't changed or the value is not a float.
342            The control background turns pink if the value is not a float.
343           
344            @param ctrl: TextCtrl object
345        """
346        if ctrl.IsModified():
347            ctrl.SetModified(False)
348            str_value = ctrl.GetValue().lstrip().rstrip()
349            try:
350                int_value = int(str_value)
351                ctrl.SetBackgroundColour(
352                        wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
353                ctrl.Refresh()
354                return int_value
355            except:
356                ctrl.SetBackgroundColour("pink")
357                ctrl.Refresh()
358        return None
359
[eaeb13e]360    def _parseCtrl(self):
361        try:
362            # Position
363            tmp = self._readCtrlFloat(self.xctrl)
364            if not tmp==None:
365                self.current_shape.x = tmp
366               
367            tmp = self._readCtrlFloat(self.yctrl)
368            if not tmp==None:
369                self.current_shape.y = tmp
370               
371            tmp = self._readCtrlFloat(self.zctrl)
372            if not tmp==None:
373                self.current_shape.z = tmp
374               
375            # Orientation
376            tmp = self._readCtrlFloat(self.actrl)
377            if not tmp==None:
378                self.current_shape.theta_x = tmp
379               
380            tmp = self._readCtrlFloat(self.bctrl)
381            if not tmp==None:
382                self.current_shape.theta_y = tmp
383               
384            tmp = self._readCtrlFloat(self.cctrl)
385            if not tmp==None:
386                self.current_shape.theta_z = tmp
387               
388            # Parameters
389            for item in self.parameters:
390                tmp = self._readCtrlFloat(item[1])
391                if not tmp==None:
392                    self.current_shape.params[item[0]] = tmp
393        except:
394            print "Could not create"
395            print sys.exc_value
396               
397    def _onCreate(self, evt):
398        """
399            Create a new shape with the parameters given by the user
400        """
401        self._parseCtrl()
402        event = CreateShapeEvent(shape=self.current_shape, new=True)
403        wx.PostEvent(self.parent, event)
404        self.editShape(self.current_shape, False)
405           
406       
407    def _onEdited(self, evt):
408        self._parseCtrl()
409        event = CreateShapeEvent(shape=self.current_shape, new=False)
410        wx.PostEvent(self.parent, event)
411        self.editShape(self.current_shape, False)
412
413    def onTextEnter(self, evt): 
414        """
415            Read text field to check values
416        """ 
417        self._readCtrlFloat(self.xctrl)
418        self._readCtrlFloat(self.yctrl)
419        self._readCtrlFloat(self.zctrl)
420        self._readCtrlFloat(self.actrl)
421        self._readCtrlFloat(self.bctrl)
422        self._readCtrlFloat(self.cctrl)
423        for item in self.parameters:
424            self._readCtrlFloat(item[1])
425 
[cb78690]426    #-- Methods to support list of shapes --
427    def _on_add_shape_to_listbox(self, event):
[eaeb13e]428        """
[cb78690]429            Process a new shape           
430            @param event: EVT_ADD_SHAPE event
[eaeb13e]431        """
[cb78690]432        event.Skip()
433        if event.new:
434            self.counter += 1
435            self.shape_listbox.Insert("%d: %s" % (self.counter, event.shape.name), 
436                                 self.shape_listbox.GetCount(), event.shape)
[eaeb13e]437
[cb78690]438    def _on_select_from_listbox(self, event):
[eaeb13e]439        """
[cb78690]440            Process item selection events
[eaeb13e]441        """
[cb78690]442        index = event.GetSelection()
443        view_name = self.shape_listbox.GetString(index)
444        self.editShape(shape=event.GetClientData(), new=False)
445        # The following event is bound to the SimPanel to highlight the shape in blue
446        #TODO: how come it doesn't work?
447        wx.PostEvent(self.parent, EditShapeEvent(shape=event.GetClientData()))
448        #TODO: select the shape from the drop down
[eaeb13e]449       
[cb78690]450    def _on_listbox_context_menu(self, event):
[eaeb13e]451        """
452            Popup context menu event
453        """
[cb78690]454        # Create context menu
[eaeb13e]455        popupmenu = wx.Menu()
[cb78690]456       
457        # Create an item to delete the selected shape from the canvas
458        id = wx.NewId()
459        popupmenu.Append(id, "&Remove Selected")
460        wx.EVT_MENU(self, id, self._on_remove_shape_from_listbox)
461       
462        # Create an item to rename a shape to a more user friendly name
463        #id = wx.NewId()
[eaeb13e]464        #popupmenu.Append(102, "&Rename Selected")
465        #wx.EVT_MENU(self, 102, self.onRename)
466
467        pos = event.GetPosition()
468        pos = self.ScreenToClient(pos)
[cb78690]469        self.PopupMenu(popupmenu, pos)       
470       
471    def _on_remove_shape_from_listbox(self, ev):
[eaeb13e]472        """
[cb78690]473            Remove an item
[eaeb13e]474        """
[cb78690]475        indices = self.shape_listbox.GetSelections()
476        if len(indices)>0:
477            name =  self.shape_listbox.GetClientData(indices[0]).name
478            self.shape_listbox.Delete(indices[0])
479            wx.PostEvent(self.parent, DelShapeEvent(id = name))
480       
481    def _on_rename_shape_from_listbox(self, ev):
[eaeb13e]482        """
[cb78690]483            Rename an item
[eaeb13e]484        """
[cb78690]485        indices = self.shape_listbox.GetSelections()
486        if len(indices)>0:
487            print "NOT YET IMPLMENTED"
488            print "renaming", self.shape_listbox.GetString(indices[0])
[eaeb13e]489               
Note: See TracBrowser for help on using the repository browser.