source: trunk/GSASIIElemGUI.py @ 4203

Last change on this file since 4203 was 4203, checked in by toby, 22 months ago

Add close and composition to G2scriptable; more doc updates

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