source: sasview/calculatorview/src/sans/perspectives/calculator/data_operator.py @ 5a5bb29

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 5a5bb29 was 5a5bb29, checked in by Jae Cho <jhjcho@…>, 12 years ago

better layout for MAC

  • Property mode set to 100644
File size: 28.5 KB
Line 
1"""
2GUI for the data operation
3"""
4import wx
5import sys
6import time
7import numpy
8from sans.dataloader.data_info import Data2D
9from sans.dataloader.data_info import Data1D
10from danse.common.plottools.PlotPanel import PlotPanel
11from danse.common.plottools.plottables import Graph
12from danse.common.plottools.canvas import FigureCanvas
13from matplotlib.font_manager import FontProperties
14from matplotlib.figure import Figure
15from sans.guiframe.events import StatusEvent
16       
17#Control panel width
18if sys.platform.count("win32") > 0:
19    PANEL_WIDTH = 790
20    PANEL_HEIGTH = 370
21    FONT_VARIANT = 0
22    _BOX_WIDTH = 200
23    ON_MAC = False
24else:
25    _BOX_WIDTH = 230
26    PANEL_WIDTH = 900
27    PANEL_HEIGTH = 430
28    FONT_VARIANT = 1
29    ON_MAC = True
30     
31class DataOperPanel(wx.ScrolledWindow):
32    """
33    :param data: when not empty the class can
34                same information into a data object
35        and post event containing the changed data object to some other frame
36    """
37    def __init__(self, parent, *args, **kwds):
38        kwds['name'] = "Data Operation"
39        kwds["size"] = (PANEL_WIDTH, PANEL_HEIGTH)
40        wx.ScrolledWindow.__init__(self, parent, *args, **kwds)
41        self.parent = parent
42        #sizers etc.
43        self.main_sizer = None
44        self.name_sizer = None
45        self.button_sizer = None
46        self.data_namectr = None
47        self.numberctr = None
48        self.data1_cbox = None
49        self.operator_cbox = None
50        self.data2_cbox = None
51        self.data_title_tcl = None
52        self.out_pic = None
53        self.equal_pic = None
54        self.data1_pic = None
55        self.operator_pic = None
56        self.data2_pic = None
57        self.output = None
58        self._notes = None
59        #data
60        self._data = self.get_datalist()
61        self._do_layout()
62        self.fill_data_combox()
63        self.fill_oprator_combox()
64        self.Bind(wx.EVT_PAINT, self.set_panel_on_focus)
65             
66    def _define_structure(self):
67        """
68        define initial sizer
69        """
70        self.main_sizer = wx.BoxSizer(wx.VERTICAL)
71        title = "Data Operation "
72        title += "[ + (add); - (subtract); "
73        title += "* (multiply); / (divide); "
74        title += "| (append) ]"
75        name_box = wx.StaticBox(self, -1, title)
76        self.name_sizer = wx.StaticBoxSizer(name_box, wx.HORIZONTAL)
77        self.button_sizer = wx.BoxSizer(wx.HORIZONTAL)
78     
79    def _layout_name(self):
80        """
81        Do the layout for data name related widgets
82        """
83        new_data_sizer = wx.BoxSizer(wx.VERTICAL)
84        equal_sizer =  wx.BoxSizer(wx.VERTICAL)
85        old_data1_sizer = wx.BoxSizer(wx.VERTICAL)
86        operator_sizer = wx.BoxSizer(wx.VERTICAL)
87        old_data2_sizer = wx.BoxSizer(wx.VERTICAL)
88        data2_hori_sizer = wx.BoxSizer(wx.HORIZONTAL)
89        data_name = wx.StaticText(self, -1, 'Output Data Name') 
90        equal_name = wx.StaticText(self, -1, ' =', size=(50, 25)) 
91        data1_name = wx.StaticText(self, -1, 'Data1')
92        operator_name = wx.StaticText(self, -1, 'Operator')
93        data2_name = wx.StaticText(self, -1, 'Data2 (or Number)')
94        self.data_namectr = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 25))
95        self.data_namectr.SetToolTipString("Hit 'Enter' key after typing.")
96        self.data_namectr.SetValue(str('MyNewDataName'))
97        self.numberctr = wx.TextCtrl(self, -1, size=(_BOX_WIDTH/3, 25)) 
98        self.numberctr.SetToolTipString("Hit 'Enter' key after typing.")
99        self.numberctr.SetValue(str(1.0))
100        self.data1_cbox = wx.ComboBox(self, -1, size=(_BOX_WIDTH, 25), 
101                                      style=wx.CB_READONLY)
102        self.operator_cbox = wx.ComboBox(self, -1, size=(70, 25), 
103                                         style=wx.CB_READONLY)
104        operation_tip = "Add: +, Subtract: -, "
105        operation_tip += "Multiply: *, Divide: /, "
106        operation_tip += "Append(Combine): | "
107        self.operator_cbox.SetToolTipString(operation_tip)
108        self.data2_cbox = wx.ComboBox(self, -1, size=(_BOX_WIDTH*2/3, 25),
109                                       style=wx.CB_READONLY)
110
111        self.out_pic = SmallPanel(self, -1, True, 
112                                    size=(_BOX_WIDTH, _BOX_WIDTH), 
113                                    style=wx.NO_BORDER)
114        self.equal_pic = SmallPanel(self, -1, True, '=', 
115                                    size=(50, _BOX_WIDTH), 
116                                    style=wx.NO_BORDER)
117        self.data1_pic = SmallPanel(self, -1, True, 
118                                    size=(_BOX_WIDTH, _BOX_WIDTH), 
119                                    style=wx.NO_BORDER)
120        self.operator_pic = SmallPanel(self, -1, True, '+',
121                                    size=(70, _BOX_WIDTH), 
122                                    style=wx.NO_BORDER)
123        self.data2_pic = SmallPanel(self, -1, True, 
124                                    size=(_BOX_WIDTH, _BOX_WIDTH), 
125                                    style=wx.NO_BORDER)
126        for ax in self.equal_pic.axes:
127            ax.set_frame_on(False)
128        for ax in self.operator_pic.axes:
129            ax.set_frame_on(False)
130
131        new_data_sizer.AddMany([(data_name, 0, wx.LEFT, 3),
132                                       (self.data_namectr, 0, wx.LEFT, 3),
133                                       (self.out_pic, 0, wx.LEFT, 3)])
134        equal_sizer.AddMany([(13, 13), (equal_name, 0, wx.LEFT, 3),
135                                       (self.equal_pic, 0, wx.LEFT, 3)])
136        old_data1_sizer.AddMany([(data1_name, 0, wx.LEFT, 3),
137                                       (self.data1_cbox, 0, wx.LEFT, 3),
138                                       (self.data1_pic, 0, wx.LEFT, 3)])
139        operator_sizer.AddMany([(operator_name, 0, wx.LEFT, 3),
140                                 (self.operator_cbox, 0, wx.LEFT, 3),
141                                 (self.operator_pic, 0, wx.LEFT, 3)])
142        data2_hori_sizer.AddMany([(self.data2_cbox, 0, wx.LEFT, 0),
143                                       (self.numberctr, 0, wx.RIGHT, 0)])
144        old_data2_sizer.AddMany([(data2_name, 0, wx.LEFT, 3),
145                                       (data2_hori_sizer, 0, wx.LEFT, 3),
146                                       (self.data2_pic, 0, wx.LEFT, 3)])
147        self.name_sizer.AddMany([(new_data_sizer, 0, wx.LEFT|wx.TOP, 5),
148                                       (equal_sizer, 0, wx.TOP, 5),
149                                       (old_data1_sizer, 0, wx.TOP, 5),
150                                       (operator_sizer, 0, wx.TOP, 5),
151                                       (old_data2_sizer, 0, wx.TOP, 5)])
152        self.data2_cbox.Show(True)
153
154        self._show_numctrl(self.numberctr, False)
155       
156        wx.EVT_TEXT_ENTER(self.data_namectr, -1, self.on_name)
157        wx.EVT_TEXT_ENTER(self.numberctr, -1, self.on_number) 
158        wx.EVT_COMBOBOX(self.data1_cbox, -1, self.on_select_data1) 
159        wx.EVT_COMBOBOX(self.operator_cbox, -1, self.on_select_operator) 
160        wx.EVT_COMBOBOX(self.data2_cbox, -1, self.on_select_data2)
161   
162    def _show_numctrl(self, ctrl, enable=True): 
163        """
164        Show/Hide on Win
165        Enable/Disable on MAC
166        """
167        if ON_MAC:
168            ctrl.Enable(enable)
169            chidren = ctrl.GetChildren()
170            if len(children) > 0:
171                ctrl.GetChildren()[0].SetBackGroundColour(\
172                                                self.GetBackGroundColour())
173        else:
174            if not ctrl.IsEnabled():
175                ctrl.Enable(True)
176            ctrl.Show(enable)
177           
178    def on_name(self, event=None):
179        """
180        On data name typing
181        """
182        if event != None:
183            event.Skip()
184        item = event.GetEventObject()
185        if item.IsEnabled():
186            self._set_textctrl_color(item, 'white')
187        else:
188            self._set_textctrl_color(item, self.GetBackgroundColour())
189        text = item.GetValue().strip()
190        self._check_newname(text)
191   
192    def _check_newname(self, name=None):
193        """
194        Check name ctr strings
195        """
196        self.send_warnings('')
197        msg = ''
198        if name == None:
199            text = self.data_namectr.GetValue().strip()
200        else:
201            text = name
202        state_list = self.get_datalist().values()
203        if text in [str(state.data.name) for state in state_list]:
204            self._set_textctrl_color(self.data_namectr, 'pink')
205            msg = "DataOperation: The name already exists."
206        if len(text) == 0:
207            self._set_textctrl_color(self.data_namectr, 'pink')
208            msg = "DataOperation: Type the data name first."
209        if self._notes:
210            self.send_warnings(msg, 'error')
211       
212        self.Refresh()
213   
214    def _set_textctrl_color(self, ctrl, color): 
215        """
216        Set TextCtrl color
217        """
218        if ON_MAC:
219            chidren = ctrl.GetChildren()
220            if len(children) > 0:
221                ctrl.GetChildren()[0].SetBackgroundColour(color) 
222        else:
223            ctrl.SetBackgroundColour(color) 
224        self.name_sizer.Layout()
225                     
226    def on_number(self, event=None):
227        """
228        On selecting Number for Data2
229        """
230        if event != None:
231            event.Skip()
232        self.send_warnings('')
233        if self.numberctr.IsEnabled():
234            self._set_textctrl_color(self.numberctr, 'white')
235        else:
236            self._set_textctrl_color(self.numberctr, self.GetBackgroundColour())
237
238        item = event.GetEventObject()
239        text = item.GetValue().strip()
240        try:
241            val = float(text)
242            pos = self.data2_cbox.GetSelection()
243            self.data2_cbox.SetClientData(pos, val)
244        except:
245            self._set_textctrl_color(self.numberctr, 'pink')
246            msg = "DataOperation: Number requires a float number."
247            self.send_warnings(msg, 'error')
248            return
249        self.put_text_pic(self.data2_pic, content=str(val)) 
250        self.check_data_inputs()
251        if self.output != None:
252            self.output.name = str(self.data_namectr.GetValue())
253        self.draw_output(self.output)
254       
255    def on_select_data1(self, event=None):
256        """
257        On select data1
258        """
259        if event != None:
260            event.Skip()
261        self.send_warnings('')
262        item = event.GetEventObject()
263        pos = item.GetSelection()
264        data = item.GetClientData(pos)
265        if data == None:
266            content = "?"
267            self.put_text_pic(self.data1_pic, content) 
268        else:
269            self.data1_pic.add_image(data)
270        self.check_data_inputs()
271        if self.output != None:
272            self.output.name = str(self.data_namectr.GetValue())
273        self.draw_output(self.output)
274       
275    def on_select_operator(self, event=None):
276        """
277        On Select an Operator
278        """
279        if event != None:
280            event.Skip()
281        self.send_warnings('')
282        item = event.GetEventObject()
283        text = item.GetValue().strip()
284        self.put_text_pic(self.operator_pic, content=text) 
285        self.check_data_inputs()
286        if self.output != None:
287            self.output.name = str(self.data_namectr.GetValue())
288        self.draw_output(self.output)
289       
290    def on_select_data2(self, event=None):
291        """
292        On Selecting Data2
293        """
294        if event != None:
295            event.Skip()
296        self.send_warnings('')
297        item = event.GetEventObject()
298        text = item.GetValue().strip().lower()
299        self._show_numctrl(self.numberctr, text=='number')
300       
301        pos = item.GetSelection()
302        data = item.GetClientData(pos)
303        content = "?"
304        if not (self.numberctr.IsShown() and self.numberctr.IsEnabled()):
305            if data == None:
306                content = "?"
307                self.put_text_pic(self.data2_pic, content) 
308            else:
309                self.data2_pic.add_image(data)
310        else:
311            if data == None:
312                content = str(self.numberctr.GetValue().strip())
313                try:
314                    content = float(content)
315                    data = content
316                except:
317                    self._set_textctrl_color(self.numberctr, 'pink')
318                    content = "?"
319                    data = None
320                item.SetClientData(pos, content)
321            self.put_text_pic(self.data2_pic, content)   
322        self.check_data_inputs()
323
324        if self.output != None:
325            self.output.name = str(self.data_namectr.GetValue())
326        self.draw_output(self.output)
327       
328    def put_text_pic(self, pic=None, content=''): 
329        """
330        Put text to the pic
331        """
332        pic.set_content(content) 
333        pic.add_text()
334        pic.draw()
335                 
336    def check_data_inputs(self):
337        """
338        Check data1 and data2 whether or not they are ready for operation
339        """
340        self._set_textctrl_color(self.data1_cbox, 'white')
341        self._set_textctrl_color(self.data2_cbox, 'white')
342        flag = False
343        pos1 = self.data1_cbox.GetCurrentSelection()
344        data1 = self.data1_cbox.GetClientData(pos1)
345        if data1 == None:
346            self.output = None
347            return flag
348        pos2 = self.data2_cbox.GetCurrentSelection()
349        data2 = self.data2_cbox.GetClientData(pos2)
350        if data2 == None:
351            self.output = None
352            return flag
353        if self.numberctr.IsShown():
354            if self.numberctr.IsEnabled():
355                self._set_textctrl_color(self.numberctr, 'white')
356            else:
357                self._set_textctrl_color(self.numberctr, 
358                                         self.GetBackgroundColour())
359            try:
360                float(data2)
361                if self.operator_cbox.GetValue().strip() == '|':
362                    msg = "DataOperation: This operation can not accept "
363                    msg += "a float number."
364                    self.send_warnings(msg, 'error')
365                    self._set_textctrl_color(self.numberctr, 'pink')
366                    self.output = None
367                    return flag
368            except:
369                msg = "DataOperation: Number requires a float number."
370                self.send_warnings(msg, 'error')
371                self._set_textctrl_color(self.numberctr, 'pink')
372                self.output = None
373                return flag
374        elif data1.__class__.__name__ != data2.__class__.__name__:
375            self._set_textctrl_color(self.data1_cbox, 'pink')
376            self._set_textctrl_color(self.data1_cbox, 'pink')
377            msg = "DataOperation: Data types must be same."
378            self.send_warnings(msg, 'error')
379            self.output = None
380            return flag
381        try:
382            self.output = self.make_data_out(data1, data2)
383        except:
384            self._check_newname()
385            self._set_textctrl_color(self.data1_cbox, 'pink')
386            self._set_textctrl_color(self.data2_cbox, 'pink')
387            msg = "DataOperation: Data types must be same."
388            self.send_warnings(msg, 'error')
389            self.output = None
390            return flag
391        return True
392   
393    def make_data_out(self, data1, data2):
394        """
395        Make a temp. data output set
396        """
397        output = None
398        pos = self.operator_cbox.GetCurrentSelection()
399        operator = self.operator_cbox.GetClientData(pos)
400        exec "output = data1 %s data2"% operator
401        return output
402   
403   
404    def draw_output(self, output):
405        """
406        Draw output data(temp)
407        """
408        out = self.out_pic
409        if output == None:
410            content = "?"
411            self.put_text_pic(out, content) 
412        else:
413            out.add_image(output)
414        self.name_sizer.Layout()
415        self.Refresh()
416                   
417    def _layout_button(self): 
418        """
419            Do the layout for the button widgets
420        """ 
421        self.bt_apply = wx.Button(self, -1, "Apply", size=(_BOX_WIDTH/2, -1))
422        app_tip = "Generate the Data and send to Data Explorer."
423        self.bt_apply.SetToolTipString(app_tip)
424        self.bt_apply.Bind(wx.EVT_BUTTON, self.on_click_apply)
425       
426        self.bt_close = wx.Button(self, -1, 'Close', size=(_BOX_WIDTH/2, -1))
427        self.bt_close.Bind(wx.EVT_BUTTON, self.on_close)
428        self.bt_close.SetToolTipString("Close this panel.")
429       
430        self.button_sizer.AddMany([(PANEL_WIDTH/2, 25),
431                                   (self.bt_apply, 0, wx.RIGHT, 10),
432                                   (self.bt_close, 0, wx.RIGHT, 10)])
433       
434    def _do_layout(self):
435        """
436        Draw the current panel
437        """
438        self._define_structure()
439        self._layout_name()
440        self._layout_button()
441        self.main_sizer.AddMany([(self.name_sizer, 0, wx.EXPAND|wx.ALL, 10),
442                                (self.button_sizer, 0,
443                                          wx.EXPAND|wx.TOP|wx.BOTTOM, 5)])
444        self.SetSizer(self.main_sizer)
445        self.SetScrollbars(20, 20, 25, 65)
446        self.SetAutoLayout(True)
447   
448    def set_panel_on_focus(self, event):
449        """
450        On Focus at this window
451        """
452        if event != None:
453            event.Skip()
454        self._data = self.get_datalist()
455        children = self.GetChildren()
456        # update the list only when it is on the top
457        if self.FindFocus() in children:
458            self.fill_data_combox()
459         
460    def fill_oprator_combox(self):
461        """
462        fill the current combobox with the operator
463        """   
464        operator_list = [' +', ' -', ' *', " /", " |"]
465        for oper in operator_list:
466            pos = self.operator_cbox.Append(str(oper))
467            self.operator_cbox.SetClientData(pos, str(oper.strip()))
468        self.operator_cbox.SetSelection(0)
469       
470       
471    def fill_data_combox(self):
472        """
473        fill the current combobox with the available data
474        """
475        pos_pre1 = self.data1_cbox.GetCurrentSelection()
476        pos_pre2 = self.data2_cbox.GetCurrentSelection()
477        current1 = self.data1_cbox.GetValue()
478        current2 = self.data2_cbox.GetValue()
479        if pos_pre1 < 0:
480            pos_pre1 = 0
481        if pos_pre2 < 0:
482            pos_pre2 = 0
483        self.data1_cbox.Clear()
484        self.data2_cbox.Clear()
485        if not self._data:
486            pos = self.data1_cbox.Append('No Data Available')
487            self.data1_cbox.SetSelection(pos)
488            self.data1_cbox.SetClientData(pos, None)
489            pos2 = self.data2_cbox.Append('No Data Available')
490            self.data2_cbox.SetSelection(pos2)
491            self.data2_cbox.SetClientData(pos2, None)
492            pos3 = self.data2_cbox.Append("Number")
493            val = None
494            if (self.numberctr.IsShown() and self.numberctr.IsEnabled()):
495                try:
496                    val = float(self.numberctr.GetValue())
497                except:
498                    val = None
499            self.data2_cbox.SetClientData(pos3, val)
500            return
501        pos1 = self.data1_cbox.Append('Select Data')
502        self.data1_cbox.SetSelection(pos1)
503        self.data1_cbox.SetClientData(pos1, None)
504        pos2 = self.data2_cbox.Append('Select Data')
505        self.data2_cbox.SetSelection(pos2)
506        self.data2_cbox.SetClientData(pos2, None)
507        pos3 = self.data2_cbox.Append('Number')
508        val = None
509        if (self.numberctr.IsShown() and self.numberctr.IsEnabled()):
510            try:
511                val = float(self.numberctr.GetValue())
512            except:
513                val = None
514        self.data2_cbox.SetClientData(pos3, val)
515        dnames = []
516        for dstate in self._data.values():
517            if dstate != None:
518                if dstate.data != None:
519                    dnames.append(dstate.data.name)
520        if len(dnames) > 0:
521            ind = numpy.argsort(dnames)
522            for datastate in numpy.array(self._data.values())[ind]:
523                data = datastate.data
524                if data != None:
525                    name = data.name
526                    pos1 = self.data1_cbox.Append(str(name))
527                    self.data1_cbox.SetClientData(pos1, data)
528                    pos2 = self.data2_cbox.Append(str(name))
529                    self.data2_cbox.SetClientData(pos2, data)
530                    if str(current1) == str(name):
531                      pos_pre1 = pos1
532                    if str(current2) == str(name):
533                      pos_pre2 = pos2
534                try:
535                    theory_list = datastate.get_theory()
536                    for theory, _ in theory_list.values():
537                        th_name = theory.name
538                        posth1 = self.data1_cbox.Append(str(th_name))
539                        self.data1_cbox.SetClientData(posth1, theory)
540                        posth2 = self.data2_cbox.Append(str(th_name))
541                        self.data2_cbox.SetClientData(posth2, theory)
542                        if str(current1) == str(th_name):
543                            pos_pre1 = posth1
544                        if str(current2) == str(th_name):
545                            pos_pre2 = posth2
546                except:
547                    continue 
548        self.data1_cbox.SetSelection(pos_pre1)
549        self.data2_cbox.SetSelection(pos_pre2)
550   
551    def get_datalist(self):
552        """
553        """
554        data_manager = self.parent.parent.get_data_manager()
555        if data_manager != None:
556            return  data_manager.get_all_data()
557        else:
558            return {}
559           
560    def on_click_apply(self, event):
561        """   
562        changes are saved in data object imported to edit
563        """
564        self.send_warnings('')
565        self.data_namectr.SetBackgroundColour('white')
566        state_list = self.get_datalist().values()
567        name = self.data_namectr.GetValue().strip()
568        if name in [str(state.data.name) for state in state_list]:
569            self._set_textctrl_color(self.data_namectr, 'pink')
570            msg = "The Output Data Name already exists...   "
571            wx.MessageBox(msg, 'Error')
572            return
573        if name == '':
574            sself._set_textctrl_color(self.data_namectr, 'pink')
575            msg = "Please type the output data name first...   "
576            wx.MessageBox(msg, 'Error')
577            return
578        if self.output == None:
579            msg = "No Output Data has been generated...   "
580            wx.MessageBox(msg, 'Error')
581            return
582        # send data to data manager
583        self.output.name = name
584        self.output.run = "Data Operation"
585        self.output.instrument = "SansView"
586        self.output.id = str(name) + str(time.time())
587        data = {self.output.id :self.output}
588        self.parent.parent.add_data(data)
589        self.name_sizer.Layout()
590        self.Refresh()
591        #must post event here
592        event.Skip()
593   
594    def on_close(self, event):
595        """
596        leave data as it is and close
597        """
598        self.parent.OnClose()
599       
600    def set_plot_unfocus(self):
601        """
602        Unfocus on right click
603        """
604   
605    def send_warnings(self, msg='', info='info'):
606        """
607        Send warning to status bar
608        """
609        wx.PostEvent(self.parent.parent, StatusEvent(status=msg, info=info))
610         
611class SmallPanel(PlotPanel):
612    """
613    PlotPanel for Quick plot and masking plot
614    """
615    def __init__(self, parent, id=-1, is_number=False, content='?', **kwargs):
616        """
617        """ 
618        PlotPanel.__init__(self, parent, id=id, **kwargs)
619        self.is_number = is_number
620        self.content = content
621        self.position = (0.4, 0.5)
622        self.scale = 'linear'
623        self.subplot.set_xticks([])
624        self.subplot.set_yticks([])
625        self.add_text()
626        self.figure.subplots_adjust(left=0.1, bottom=0.1)
627       
628    def set_content(self, content=''):
629        """
630        Set text content
631        """
632        self.content = str(content)
633         
634    def add_toolbar(self):
635        """
636        Add toolbar
637        """
638        # Not implemented
639        pass
640   
641    def on_set_focus(self, event):
642        """
643        send to the parenet the current panel on focus
644        """
645        pass
646
647    def add_image(self, plot):
648        """
649        Add Image
650        """
651        self.content = ''
652        self.textList = []
653        self.plots = {}
654        self.clear()
655        try:
656            self.figure.delaxes(self.figure.axes[0])
657            self.subplot = self.figure.add_subplot(111)
658            #self.figure.delaxes(self.figure.axes[1])
659        except:
660            pass
661        try:
662            name = plot.name
663        except:
664            name = plot.filename
665        self.plots[name] = plot
666
667        #init graph
668        self.graph = Graph()
669
670        #add plot
671        self.graph.add(plot)
672        #draw       
673        self.graph.render(self)
674       
675        try:
676            self.figure.delaxes(self.figure.axes[1])
677        except:
678            pass
679        self.subplot.figure.canvas.resizing = False
680        self.subplot.set_xticks([])
681        self.subplot.set_yticks([])
682        # Draw zero axis lines
683        self.subplot.axhline(linewidth = 1, color='r') 
684        self.subplot.axvline(linewidth = 1, color='r')       
685
686        self.erase_legend()
687        try:
688            # mpl >= 1.1.0
689            self.figure.tight_layout()
690        except:
691            self.figure.subplots_adjust(left=0.1, bottom=0.1)
692        self.subplot.figure.canvas.draw()
693
694    def add_text(self):
695        """
696        Text in the plot
697        """
698        if not self.is_number:
699            return
700
701        self.clear()
702        try:
703            self.figure.delaxes(self.figure.axes[0])
704            self.subplot = self.figure.add_subplot(111)
705            self.figure.delaxes(self.figure.axes[1])
706        except:
707            pass
708        self.subplot.set_xticks([])
709        self.subplot.set_yticks([])
710        label = self.content
711        FONT = FontProperties()
712        xpos, ypos = (0.4, 0.5)
713        font = FONT.copy()
714        font.set_size(14)
715
716        self.textList = []
717        self.subplot.set_xlim((0, 1))
718        self.subplot.set_ylim((0, 1))
719       
720        try:
721            if self.content != '?':
722                float(label)
723        except:
724            self.subplot.set_frame_on(False)
725        try:
726            # mpl >= 1.1.0
727            self.figure.tight_layout()
728        except:
729            self.figure.subplots_adjust(left=0.1, bottom=0.1)
730        if len(label) > 0 and xpos > 0 and ypos > 0:
731            new_text = self.subplot.text(str(xpos), str(ypos), str(label),
732                                           fontproperties=font)
733            self.textList.append(new_text) 
734       
735    def erase_legend(self):
736        """
737        Remove Legend
738        """
739        #for ax in self.axes:
740        self.remove_legend(self.subplot)
741                     
742    def onMouseMotion(self, event):
743        """
744        Disable dragging 2D image
745        """
746   
747    def onWheel(self, event):
748        """
749        """
750     
751    def onLeftDown(self, event):
752        """
753        Disables LeftDown
754        """
755   
756    def onPick(self, event):
757        """
758        Remove Legend
759        """
760        for ax in self.axes:
761            self.remove_legend(ax)
762                       
763   
764    def draw(self):
765        """
766        Draw
767        """
768        if self.dimension == 3:
769            pass
770        else:
771            self.subplot.figure.canvas.draw_idle() 
772       
773    def onContextMenu(self, event):
774        """
775        Default context menu for a plot panel
776        """
777               
778class DataOperatorWindow(wx.Frame):
779    def __init__(self, parent, *args, **kwds):
780        kwds["size"] = (PANEL_WIDTH, PANEL_HEIGTH)
781        wx.Frame.__init__(self, parent, *args, **kwds)
782        self.parent = parent
783        self.panel = DataOperPanel(parent=self)
784        wx.EVT_CLOSE(self, self.OnClose)
785        self.CenterOnParent()
786        self.Show()
787   
788    def OnClose(self, event=None): 
789        """
790        On close event
791        """
792        self.Show(False)
793
794       
795if __name__ == "__main__":
796   
797    app  = wx.App()
798    window = DataOperatorWindow(parent=None, data=[], title="Data Editor")
799    app.MainLoop()
800 
Note: See TracBrowser for help on using the repository browser.