source: trunk/GSASIIElemGUI.py

Last change on this file was 5586, checked in by vondreele, 4 months ago

changes to allow generalized atomic form factors (beginning)
Some fixes to spin RB stuff

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