source: trunk/GSASIIElemGUI.py @ 2668

Last change on this file since 2668 was 2668, checked in by toby, 5 years ago

white letters for dark element colors (Mac/Linux?)

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