source: trunk/GSASIIElemGUI.py @ 2679

Last change on this file since 2679 was 2679, checked in by vondreele, 5 years ago

tidy up periodic table - better foreground/background contrast on elements

  • 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-01-31 16:06:45 +0000 (Tue, 31 Jan 2017) $
4# $Author: vondreele $
5# $Revision: 2679 $
6# $URL: trunk/GSASIIElemGUI.py $
7# $Id: GSASIIElemGUI.py 2679 2017-01-31 16:06:45Z vondreele $
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'''
16"""ElementGUI: class defn. for element GUIs
17   Copyright: 2008, Robert B. Von Dreele & Brian H. Toby (Argonne National Laboratory)
18"""
19
20import GSASIIpath
21GSASIIpath.SetVersionNumber("$Revision: 2679 $")
22import wx
23import os
24import sys
25import wx.lib.colourselect as wscs
26class PickElement(wx.Dialog):
27    '''Makes periodic table widget for picking element. Modes:
28        oneOnly if True element symbols are provided, otherwise select valence
29        ifNone if True show None button
30        ifMag if True present magnetic scatters only
31        multiple if True multiple elements can be selected
32    '''
33    Elem=None
34    def _init_ctrls(self,prnt,ifMag=False):
35        wx.Dialog.__init__(self, id=-1, name='PickElement',
36              parent=prnt, pos=wx.DefaultPosition, 
37              style=wx.DEFAULT_DIALOG_STYLE, title='Pick Element')
38        import ElementTable as ET
39        self.butWid = 60
40        if 'nt' in os.name:
41            self.butWid = 50
42        self.SetClientSize(wx.Size(50+18*self.butWid, 250))
43        self.Centre()
44        i=0
45        Elems = ET.ElTable
46        if ifMag:
47            Elems = ET.MagElTable
48        for E in Elems:
49            if E[1] < 0: continue
50            if self.oneOnly:
51                color=E[4]
52            else:
53                color=E[6]
54            self.ElButton(name=E[0],
55               pos=wx.Point(E[1]*self.butWid+25,E[2]*24+24),
56               tip=E[3],color=color)
57            i+=1
58        if self.multiple:
59            b = wx.Button(self,wx.ID_CLOSE,
60                          pos=wx.Point(16.5*self.butWid+25,7.75*24+24),
61                          label="Done")
62            b.Bind(wx.EVT_BUTTON, self.OnClose)
63
64    def __init__(self, parent,oneOnly=False,ifNone=False,ifMag=False,multiple=False):
65        'Needs a doc string'
66        self.oneOnly = oneOnly
67        self.ifNone = ifNone
68        self.multiple = multiple
69        self._init_ctrls(parent,ifMag=ifMag)
70        self.elementList = []
71       
72    def ElButton(self, name, pos, tip, color):
73        'Creates an element button widget'
74        self.color = color
75        if not self.ifNone and name[0] == 'None':
76            return
77        if self.oneOnly:
78            El = wscs.ColourSelect(label=name[0], parent=self,colour=color,
79                pos=pos, size=wx.Size(self.butWid,23), style=wx.RAISED_BORDER)
80            El.Bind(wx.EVT_BUTTON, self.OnElButton)
81        else:
82            butWid = self.butWid
83            if name[0] == 'None':
84                butWid *= 2
85            # patch for wx 2.9+ on Mac/Linux where EVT_COMBOBOX happens only on a
86            # value change. Not ideal because wx.CB_READONLY is better.
87            i,j= wx.__version__.split('.')[0:2]
88            if int(i)+int(j)/10. > 2.8:
89                El = wx.ComboBox(choices=name, parent=self, pos=pos, size=wx.Size(butWid,27),
90                    style=wx.CB_DROPDOWN, value=name[0]+' ') # add an invisible space
91                if sum(color)/3 < 150 and color[1] < 150: # background is mostly dark, use white letters
92                    El.SetForegroundColour((255,255,255))
93            else:
94                El = wx.ComboBox(choices=name, parent=self, pos=pos, size=wx.Size(butWid,23),
95                    style=wx.CB_READONLY, value=name[0])
96            El.Bind(wx.EVT_COMBOBOX,self.OnElButton)
97       
98        El.SetBackgroundColour(color)
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        El.SetToolTipString(tip)
289        El.Bind(wx.EVT_BUTTON, self.OnElButton)
290
291    def OnElButton(self, event):
292        Black = wx.Colour(0,0,0)
293        btn = event.GetEventObject()
294        El = btn.GetLabel()
295        if btn.GetColour() != Black:
296            for Elem in self.ElTable:
297                if El in Elem:
298                    ElColor = Elem[4]
299            if El in self.Elem:
300                btn.SetColour(ElColor)
301                self.Elem.remove(El)
302            else:
303                btn.SetColour(wx.Colour(255,0,0))
304                self.Elem.append(El)
305       
306class DeleteElement(wx.Dialog):
307    "Delete element from selected set widget"
308    def _init_ctrls(self, parent,choice):
309        l = len(choice)-1
310        wx.Dialog.__init__(self, id=-1, name='Delete', parent=parent, 
311              pos=wx.DefaultPosition, size=wx.Size(max(128,64+l*24), 87),
312              style=wx.DEFAULT_DIALOG_STYLE, title='Delete Element')
313        self.Show(True)
314        self.SetAutoLayout(True)
315        self.SetHelpText('Select element to delete')
316        self.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)
317
318        i = 0
319        Elem = []
320        for Elem in choice:
321            self.ElButton(id=-1,name=Elem,pos=wx.Point(16+i*24, 16))
322            i+=1
323             
324    def __init__(self, parent,choice):
325        DeleteElement.El = ' '
326        self._init_ctrls(parent,choice)
327
328    def ElButton(self, id, name, pos):
329        'Needs a doc string'
330        White = wx.Colour(255, 255, 255)
331        El = wscs.ColourSelect(label=name, parent=self, colour = White,
332            pos=pos, size=wx.Size(24, 23), style=wx.RAISED_BORDER)
333        El.Bind(wx.EVT_BUTTON, self.OnDeleteButton)
334   
335    def OnDeleteButton(self, event):
336        DeleteElement.El=event.GetEventObject().GetLabel()
337        self.EndModal(wx.ID_OK)
338       
339    def GetDeleteElement(self):
340        return DeleteElement.El
341       
342if __name__ == '__main__':
343    app = wx.PySimpleApp()
344    GSASIIpath.InvokeDebugOpts()
345    G2frame = wx.Frame(None) # create a frame
346    G2frame.Show(True)
347
348    PE = PickElement(G2frame)
349    if PE.ShowModal() == wx.ID_OK:
350        print PE.Elem
351    PE.Destroy()
352
Note: See TracBrowser for help on using the repository browser.