source: trunk/GSASIIElemGUI.py @ 3553

Last change on this file since 3553 was 3136, checked in by vondreele, 8 years ago

make GSAS-II python 3.6 compliant & preserve python 2.7 use;changes:
do from future import division, print_function for all GSAS-II py sources
all menu items revised to be py 2.7/3.6 compliant
all wx.OPEN --> wx.FD_OPEN in file dialogs
all integer divides (typically for image pixel math) made explicit with ; ambiguous ones made floats as appropriate
all print "stuff" --> print (stuff)
all print >> pFile,'stuff' --> pFile.writeCIFtemplate('stuff')
all read file opens made explicit 'r' or 'rb'
all cPickle imports made for py2.7 or 3.6 as cPickle or _pickle; test for '2' platform.version_tuple[0] for py 2.7
define cPickleload to select load(fp) or load(fp,encoding='latin-1') for loading gpx files; provides cross compatibility between py 2.7/3.6 gpx files
make dict.keys() as explicit list(dict.keys()) as needed (NB: possible source of remaining py3.6 bugs)
make zip(a,b) as explicit list(zip(a,b)) as needed (NB: possible source of remaining py3.6 bugs)
select unichr/chr according test for '2' platform.version_tuple[0] for py 2.7 (G2pwdGUI * G2plot) for special characters
select wg.EVT_GRID_CELL_CHANGE (classic) or wg.EVT_GRID_CELL_CHANGED (phoenix) in grid Bind
maxint --> maxsize; used in random number stuff
raise Exception,"stuff" --> raise Exception("stuff")
wx 'classic' sizer.DeleteWindows?() or 'phoenix' sizer.Clear(True)
wx 'classic' SetToolTipString?(text) or 'phoenix' SetToolTip?(wx.ToolTip?(text)); define SetToolTipString?(self,text) to handle the choice in plots
status.SetFields? --> status.SetStatusText?
'classic' AddSimpleTool? or 'phoenix' self.AddTool? for plot toolbar; Bind different as well
define GetItemPydata? as it doesn't exist in wx 'phoenix'
allow python versions 2.7 & 3.6 to run GSAS-II
Bind override commented out - no logging capability (NB: remove all logging code?)
all import ContentsValidator? open filename & test if valid then close; filepointer removed from Reader
binary importers (mostly images) test for 'byte' type & convert as needed to satisfy py 3.6 str/byte rules

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 15.3 KB
Line 
1# -*- coding: utf-8 -*-
2########### SVN repository information ###################
3# $Date: 2017-10-23 16:39:16 +0000 (Mon, 23 Oct 2017) $
4# $Author: toby $
5# $Revision: 3136 $
6# $URL: trunk/GSASIIElemGUI.py $
7# $Id: GSASIIElemGUI.py 3136 2017-10-23 16:39:16Z toby $
8########### SVN repository information ###################
9'''
10*GSASIIElemGUI: GUI to select and delete element lists*
11-------------------------------------------------------
12
13Module to select elements from a periodic table and
14to delete an element from a list of selected elements.
15'''
16from __future__ import division, print_function
17import GSASIIpath
18GSASIIpath.SetVersionNumber("$Revision: 3136 $")
19import wx
20import os
21import wx.lib.colourselect as wscs
22class PickElement(wx.Dialog):
23    '''Makes periodic table widget for picking element. Modes:
24        oneOnly if True element symbols are provided, otherwise select valence
25        ifNone if True show None button
26        ifMag if True present magnetic scatters only
27        multiple if True multiple elements can be selected
28    '''
29    Elem=None
30    def _init_ctrls(self,prnt,ifMag=False):
31        wx.Dialog.__init__(self, id=-1, name='PickElement',
32              parent=prnt, pos=wx.DefaultPosition, 
33              style=wx.DEFAULT_DIALOG_STYLE, title='Pick Element')
34        import ElementTable as ET
35        self.butWid = 60
36        if 'nt' in os.name:
37            self.butWid = 50
38        self.SetClientSize(wx.Size(50+18*self.butWid, 250))
39        self.Centre()
40        i=0
41        Elems = ET.ElTable
42        if ifMag:
43            Elems = ET.MagElTable
44        for E in Elems:
45            if E[1] < 0: continue
46            if self.oneOnly:
47                color=E[4]
48            else:
49                color=E[6]
50            self.ElButton(name=E[0],
51               pos=wx.Point(E[1]*self.butWid+25,E[2]*24+24),
52               tip=E[3],color=color)
53            i+=1
54        if self.multiple:
55            b = wx.Button(self,wx.ID_CLOSE,
56                          pos=wx.Point(16.5*self.butWid+25,7.75*24+24),
57                          label="Done")
58            b.Bind(wx.EVT_BUTTON, self.OnClose)
59
60    def __init__(self, parent,oneOnly=False,ifNone=False,ifMag=False,multiple=False):
61        'Needs a doc string'
62        self.oneOnly = oneOnly
63        self.ifNone = ifNone
64        self.multiple = multiple
65        self._init_ctrls(parent,ifMag=ifMag)
66        self.elementList = []
67       
68    def ElButton(self, name, pos, tip, color):
69        'Creates an element button widget'
70        self.color = color
71        if not self.ifNone and name[0] == 'None':
72            return
73        if self.oneOnly:
74            El = wscs.ColourSelect(label=name[0], parent=self,colour=color,
75                pos=pos, size=wx.Size(self.butWid,23), style=wx.RAISED_BORDER)
76            El.Bind(wx.EVT_BUTTON, self.OnElButton)
77        else:
78            butWid = self.butWid
79            if name[0] == 'None':
80                butWid *= 2
81            # patch for wx 2.9+ where EVT_COMBOBOX happens only on a value change.
82            i,j= wx.__version__.split('.')[0:2]
83            if int(i)+int(j)/10. > 2.8:
84                startname = name[0]+' '  # add an invisible space
85            else:
86                startname = name[0]
87            # Not ideal because wx.CB_READONLY is better.
88            El = wx.ComboBox(choices=name, parent=self, pos=pos, size=wx.Size(butWid,27),
89                    style=wx.CB_DROPDOWN, value=startname)
90            #El = wx.ComboBox(choices=name, parent=self, pos=pos, size=wx.Size(butWid,23),
91            #        style=wx.CB_READONLY, value=name[0])
92            if sum(color)/3 < 150 and color[1] < 150: # background is mostly dark, use white letters
93                El.SetForegroundColour((255,255,255))
94            El.Bind(wx.EVT_COMBOBOX,self.OnElButton)
95       
96        El.SetBackgroundColour(color)
97        El.SetToolTipString(tip)
98
99    def OnElButton(self, event):
100        if self.oneOnly:
101            El = event.GetEventObject().GetLabel()
102        else:
103            El = event.GetEventObject().GetValue()
104        self.Elem = El
105        if self.multiple:
106            if El in self.elementList:
107                self.elementList.remove(El)
108                event.GetEventObject().SetBackgroundColour(self.color) # Shows on Mac
109            else:
110                self.elementList.append(El)
111                event.GetEventObject().SetBackgroundColour('black') # Shows on Mac
112            event.GetEventObject().SetColour(
113                wx.Colour(*[int(i/2) for i in event.GetEventObject().GetColour()]))
114        else:
115            self.EndModal(wx.ID_OK)
116
117    def OnClose(self,event):
118        self.EndModal(wx.ID_OK)
119               
120class PickElements(wx.Dialog):
121    """Makes periodic table widget for picking elements - caller maintains element list"""
122    Elem = []
123    def _init_ctrls(self, prnt,list):
124        wx.Dialog.__init__(self, id=-1, name='PickElements',
125              parent=prnt, pos=wx.DefaultPosition, size=wx.Size(580, 360),
126              style=wx.DEFAULT_DIALOG_STYLE, title='Pick Elements')
127        panel = wx.Panel(self)
128       
129        REcolor = wx.Colour(128, 128, 255)
130        Metcolor = wx.Colour(192, 192, 192)
131        Noblecolor = wx.Colour(255, 128, 255)
132        Alkcolor = wx.Colour(255, 255, 128)
133        AlkEcolor = wx.Colour(255, 128, 0)
134        SemMetcolor = wx.Colour(128, 255, 0)
135        NonMetcolor = wx.Colour(0, 255, 255)
136        White = wx.Colour(255, 255, 255)
137        self.Elem = []
138        for El in list:
139            self.Elem.append(El.lower().capitalize())
140       
141        self.ElTable = [
142            ("H",   0,0, "Hydrogen",    White,           0.0000),
143            ("He", 17,0, "Helium",      Noblecolor,      0.0000),
144            ("Li",  0,1, "Lithium",     Alkcolor,        0.0004),
145            ("Be",  1,1, "Beryllium",   AlkEcolor,       0.0006),
146            ("B",  12,1, "Boron",       NonMetcolor,     0.0012),
147            ("C",  13,1, "Carbon",      NonMetcolor,     0.0018),
148            ("N",  14,1, "Nitrogen",    NonMetcolor,     0.0030),
149            ("O",  15,1, "Oxygen",      NonMetcolor,     0.0042),
150            ("F",  16,1, "Fluorine",    NonMetcolor,     0.0054),
151            ("Ne", 17,1, "Neon",        Noblecolor,      0.0066),
152            ("Na",  0,2, "Sodium",      Alkcolor,        0.0084),
153            ("Mg",  1,2, "Magnesium",   AlkEcolor,       0.0110),
154            ("Al", 12,2, "Aluminum",    SemMetcolor,     0.0125),
155            ("Si", 13,2, "Silicon",     NonMetcolor,     0.0158),
156            ("P",  14,2, "Phosphorus",  NonMetcolor,     0.0180),
157            ("S",  15,2, "Sulphur",     NonMetcolor,     0.0210),
158            ("Cl", 16,2, "Chlorine",    NonMetcolor,     0.0250),
159            ("Ar", 17,2, "Argon",       Noblecolor,      0.0285),
160            ("K",   0,3, "Potassium",   Alkcolor,        0.0320),
161            ("Ca",  1,3, "Calcium",     AlkEcolor,       0.0362),
162            ("Sc",  2,3, "Scandium",    Metcolor,        0.0410),
163            ("Ti",  3,3, "Titanium",    Metcolor,        0.0460),
164            ("V",   4,3, "Vanadium",    Metcolor,        0.0510),
165            ("Cr",  5,3, "Chromium",    Metcolor,        0.0560),
166            ("Mn",  6,3, "Manganese",   Metcolor,        0.0616),
167            ("Fe",  7,3, "Iron",        Metcolor,        0.0680),
168            ("Co",  8,3, "Cobalt",      Metcolor,        0.0740),
169            ("Ni",  9,3, "Nickel",      Metcolor,        0.0815),
170            ("Cu", 10,3, "Copper",      Metcolor,        0.0878),
171            ("Zn", 11,3, "Zinc",        Metcolor,        0.0960),
172            ("Ga", 12,3, "Gallium",     SemMetcolor,      0.104),
173            ("Ge", 13,3, "Germanium",   SemMetcolor,      0.114),
174            ("As", 14,3, "Arsenic",     NonMetcolor,      0.120),
175            ("Se", 15,3, "Selenium",    NonMetcolor,      0.132),
176            ("Br", 16,3, "Bromine",     NonMetcolor,      0.141),
177            ("Kr", 17,3, "Krypton",     Noblecolor,       0.150),
178            ("Rb",  0,4, "Rubidium",    Alkcolor,         0.159),
179            ("Sr",  1,4, "Strontium",   AlkEcolor,        0.171),
180            ("Y",   2,4, "Yittrium",    Metcolor,         0.180),
181            ("Zr",  3,4, "Zirconium",   Metcolor,         0.192),
182            ("Nb",  4,4, "Niobium",     Metcolor,         0.204),
183            ("Mo",  5,4, "Molybdenium", Metcolor,         0.216),
184            ("Tc",  6,4, "Technetium",  Metcolor,         0.228),
185            ("Ru",  7,4, "Ruthenium",   Metcolor,         0.246),
186            ("Rh",  8,4, "Rhodium",     Metcolor,         0.258),
187            ("Pd",  9,4, "Palladium",   Metcolor,         0.270),
188            ("Ag", 10,4, "Silver",      Metcolor,         0.285),
189            ("Cd", 11,4, "Cadmium",     Metcolor,         0.300),
190            ("In", 12,4, "Indium",      SemMetcolor,      0.318),
191            ("Sn", 13,4, "Tin",         SemMetcolor,      0.330),
192            ("Sb", 14,4, "Antimony",    SemMetcolor,      0.348),
193            ("Te", 15,4, "Tellurium",   NonMetcolor,      0.363),
194            ("I",  16,4, "Iodine",      NonMetcolor,      0.384),
195            ("Xe", 17,4, "Xenon",       Noblecolor,       0.396),
196            ("Cs",  0,5, "Caesium",     Alkcolor,         0.414),
197            ("Ba",  1,5, "Barium",      AlkEcolor,        0.438),
198            ("La",  2,5, "Lanthanium",  Metcolor,         0.456),
199            ("Ce",  3.5,6.5, "Cerium",      REcolor,      0.474),
200            ("Pr",  4.5,6.5, "Praseodymium",REcolor,      0.492),
201            ("Nd",  5.5,6.5, "Neodymium",   REcolor,      0.516),
202            ("Pm",  6.5,6.5, "Promethium",  REcolor,      0.534),
203            ("Sm",  7.5,6.5, "Samarium",    REcolor,      0.558),
204            ("Eu",  8.5,6.5, "Europium",    REcolor,      0.582),
205            ("Gd",  9.5,6.5, "Gadolinium",  REcolor,      0.610),
206            ("Tb", 10.5,6.5, "Terbium",     REcolor,      0.624),
207            ("Dy", 11.5,6.5, "Dysprosium",  REcolor,      0.648),
208            ("Ho", 12.5,6.5, "Holmium",     REcolor,      0.672),
209            ("Er", 13.5,6.5, "Erbium",      REcolor,      0.696),
210            ("Tm", 14.5,6.5, "Thulium",     REcolor,      0.723),
211            ("Yb", 15.5,6.5, "Ytterbium",   REcolor,      0.750),
212            ("Lu", 16.5,6.5, "Lutetium",    REcolor,      0.780),
213            ("Hf",  3,5, "Hafnium",     Metcolor,         0.804),
214            ("Ta",  4,5, "Tantalum",    Metcolor,         0.834),
215            ("W",   5,5, "Tungsten",    Metcolor,         0.864),
216            ("Re",  6,5, "Rhenium",     Metcolor,         0.900),
217            ("Os",  7,5, "Osmium",      Metcolor,         0.919),
218            ("Ir",  8,5, "Iridium",     Metcolor,         0.948),
219            ("Pt",  9,5, "Platinium",   Metcolor,         0.984),
220            ("Au", 10,5, "Gold",        Metcolor,         1.014),
221            ("Hg", 11,5, "Mercury",     Metcolor,         1.046),
222            ("Tl", 12,5, "Thallium",    SemMetcolor,      1.080),
223            ("Pb", 13,5, "Lead",        SemMetcolor,      1.116),
224            ("Bi", 14,5, "Bismuth",     SemMetcolor,      1.149),
225            ("Po", 15,5, "Polonium",    SemMetcolor,      1.189),
226            ("At", 16,5, "Astatine",    NonMetcolor,      1.224),
227            ("Rn", 17,5, "Radon",       Noblecolor,       1.260),
228            ("Fr",  0,6, "Francium",    Alkcolor,         1.296),
229            ("Ra",  1,6, "Radium",      AlkEcolor,        1.332),
230            ("Ac",  2,6, "Actinium",    Metcolor,         1.374),
231            ("Th",  3.5,7.5, "Thorium",     REcolor,      1.416),
232            ("Pa",  4.5,7.5, "Protactinium",REcolor,      1.458),
233            ("U",   5.5,7.5, "Uranium",     REcolor,      1.470),
234            ("Np",  6.5,7.5, "Neptunium",   REcolor,      1.536),
235            ("Pu",  7.5,7.5, "Plutonium",   REcolor,      1.584),
236            ("Am",  8.5,7.5, "Americium",   REcolor,      1.626),
237            ("Cm",  9.5,7.5, "Curium",      REcolor,      1.669),
238            ("Bk", 10.5,7.5, "Berkelium",   REcolor,      1.716),
239            ("Cf", 11.5,7.5, "Californium", REcolor,      1.764)]
240           
241        mainSizer = wx.BoxSizer(wx.VERTICAL)
242        elPanel = wx.Panel(panel)
243           
244        i=0
245        for E in self.ElTable:
246            PickElements.ElButton(self,parent=elPanel,name=E[0],
247                pos=wx.Point(E[1]*30+20,E[2]*30+25),tip=E[3],color=E[4])
248            i+=1
249        mainSizer.Add(elPanel,0,wx.EXPAND)
250        mainSizer.Add((10,10),0)
251       
252        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
253        OkBtn = wx.Button(panel,-1,"Ok")
254        OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
255        cancelBtn = wx.Button(panel,-1,"Cancel")
256        cancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel)
257        btnSizer.Add((20,20),1)
258        btnSizer.Add(OkBtn)
259        btnSizer.Add((20,20),1)
260        btnSizer.Add(cancelBtn)
261        btnSizer.Add((20,20),1)
262        mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM, 10)
263        panel.SetSizer(mainSizer)
264        panel.Fit()
265                 
266    def OnOk(self,event):
267        if self.Elem:
268            self.EndModal(wx.ID_OK)
269        else:       
270            self.EndModal(wx.ID_CANCEL)       
271       
272    def OnCancel(self,event):
273        self.EndModal(wx.ID_CANCEL)       
274
275    def __init__(self, parent,list):
276        self._init_ctrls(parent,list)
277       
278    def ElButton(self, parent, name, pos, tip, color):
279        Black = wx.Colour(0,0,0)
280        if name in self.Elem:
281            color = Black
282        El = wscs.ColourSelect(label=name, parent=parent,colour=color,
283            pos=pos, size=wx.Size(32, 32), style=wx.RAISED_BORDER)
284        El.SetBackgroundColour(color)
285        El.SetLabel(name)
286        El.SetToolTipString(tip)
287        El.Bind(wx.EVT_BUTTON, self.OnElButton)
288
289    def OnElButton(self, event):
290        Black = wx.Colour(0,0,0)
291        btn = event.GetEventObject()
292        El = btn.GetLabel()
293        if btn.GetColour() != Black:
294            for Elem in self.ElTable:
295                if El in Elem:
296                    ElColor = Elem[4]
297            if El in self.Elem:
298                btn.SetColour(ElColor)
299                self.Elem.remove(El)
300            else:
301                btn.SetColour(wx.Colour(255,0,0))
302                self.Elem.append(El)
303       
304class DeleteElement(wx.Dialog):
305    "Delete element from selected set widget"
306    def _init_ctrls(self, parent,choice):
307        l = len(choice)-1
308        wx.Dialog.__init__(self, id=-1, name='Delete', parent=parent, 
309              pos=wx.DefaultPosition, size=wx.Size(max(128,64+l*24), 87),
310              style=wx.DEFAULT_DIALOG_STYLE, title='Delete Element')
311        self.Show(True)
312        self.SetAutoLayout(True)
313        self.SetHelpText('Select element to delete')
314        self.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)
315
316        i = 0
317        Elem = []
318        for Elem in choice:
319            self.ElButton(id=-1,name=Elem,pos=wx.Point(16+i*24, 16))
320            i+=1
321             
322    def __init__(self, parent,choice):
323        DeleteElement.El = ' '
324        self._init_ctrls(parent,choice)
325
326    def ElButton(self, id, name, pos):
327        'Needs a doc string'
328        White = wx.Colour(255, 255, 255)
329        El = wscs.ColourSelect(label=name, parent=self, colour = White,
330            pos=pos, size=wx.Size(24, 23), style=wx.RAISED_BORDER)
331        El.Bind(wx.EVT_BUTTON, self.OnDeleteButton)
332   
333    def OnDeleteButton(self, event):
334        DeleteElement.El=event.GetEventObject().GetLabel()
335        self.EndModal(wx.ID_OK)
336       
337    def GetDeleteElement(self):
338        return DeleteElement.El
339       
340if __name__ == '__main__':
341    app = wx.PySimpleApp()
342    GSASIIpath.InvokeDebugOpts()
343    G2frame = wx.Frame(None) # create a frame
344    G2frame.Show(True)
345
346    PE = PickElement(G2frame)
347    if PE.ShowModal() == wx.ID_OK:
348        print (PE.Elem)
349    PE.Destroy()
350
Note: See TracBrowser for help on using the repository browser.