source: trunk/GSASIIElemGUI.py @ 3715

Last change on this file since 3715 was 3715, checked in by vondreele, 3 years ago

fix element tool tip problem vs wx classic/phoenix

  • 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: 2018-11-03 13:17:57 +0000 (Sat, 03 Nov 2018) $
4# $Author: vondreele $
5# $Revision: 3715 $
6# $URL: trunk/GSASIIElemGUI.py $
7# $Id: GSASIIElemGUI.py 3715 2018-11-03 13:17:57Z 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'''
16from __future__ import division, print_function
17import GSASIIpath
18GSASIIpath.SetVersionNumber("$Revision: 3715 $")
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        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=wx.Point(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(id=-1,name=Elem,pos=wx.Point(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, id, 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.