Changeset 1619
- Timestamp:
- Dec 26, 2014 9:58:22 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/GSASII.py
r1618 r1619 68 68 import GSASIIIO as G2IO 69 69 import GSASIIgrid as G2gd 70 import GSASIIctrls as G2G 70 71 import GSASIIplot as G2plt 71 72 import GSASIIpwd as G2pwd … … 1455 1456 else: 1456 1457 inp = [rd.idstring, 10.,80.,0.01] # see names for what's what 1457 dlg = G2 gd.ScrolledMultiEditor(1458 dlg = G2G.ScrolledMultiEditor( 1458 1459 self,[inp] * len(inp),range(len(inp)),names, 1459 1460 header='Enter simulation name and range', … … 2037 2038 wxID_PATTERNTREE = wx.NewId() 2038 2039 #self.PatternTree = wx.TreeCtrl(id=wxID_PATTERNTREE, # replaced for logging 2039 self.PatternTree = G2 gd.G2TreeCtrl(id=wxID_PATTERNTREE,2040 self.PatternTree = G2G.G2TreeCtrl(id=wxID_PATTERNTREE, 2040 2041 parent=self.mainPanel, pos=wx.Point(0, 0),style=wx.TR_DEFAULT_STYLE ) 2041 2042 self.PatternTree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnPatternTreeSelChanged) -
trunk/GSASIIIO.py
r1603 r1619 38 38 import GSASIIstrIO as G2stIO 39 39 import GSASIImapvars as G2mv 40 import GSASIIctrls as G2G 40 41 import os 41 42 import os.path as ospath … … 206 207 vsizer.Add(wx.StaticText(dlg,wx.ID_ANY,u'Wavelength (\xC5) '), 207 208 0,wx.ALIGN_LEFT|wx.ALL, 2) 208 wdgt = G2 gd.ValidatedTxtCtrl(dlg,Data,'wavelength')209 wdgt = G2G.ValidatedTxtCtrl(dlg,Data,'wavelength') 209 210 vsizer.Add(wdgt) 210 211 mainsizer.Add(vsizer,0,wx.ALIGN_LEFT|wx.ALL, 2) … … 213 214 vsizer.Add(wx.StaticText(dlg,wx.ID_ANY,u'Pixel size (\xb5m). Width '), 214 215 0,wx.ALIGN_LEFT|wx.ALL, 2) 215 wdgt = G2 gd.ValidatedTxtCtrl(dlg,Data['pixelSize'],0,216 wdgt = G2G.ValidatedTxtCtrl(dlg,Data['pixelSize'],0, 216 217 size=(50,-1)) 217 218 vsizer.Add(wdgt) 218 219 vsizer.Add(wx.StaticText(dlg,wx.ID_ANY,u' Height '), 219 220 wx.ALIGN_LEFT|wx.ALL, 2) 220 wdgt = G2 gd.ValidatedTxtCtrl(dlg,Data['pixelSize'],1,221 wdgt = G2G.ValidatedTxtCtrl(dlg,Data['pixelSize'],1, 221 222 size=(50,-1)) 222 223 vsizer.Add(wdgt) … … 226 227 vsizer.Add(wx.StaticText(dlg,wx.ID_ANY,u'Sample to detector (mm) '), 227 228 0,wx.ALIGN_LEFT|wx.ALL, 2) 228 wdgt = G2 gd.ValidatedTxtCtrl(dlg,Data,'distance')229 wdgt = G2G.ValidatedTxtCtrl(dlg,Data,'distance') 229 230 vsizer.Add(wdgt) 230 231 mainsizer.Add(vsizer,0,wx.ALIGN_LEFT|wx.ALL, 2) … … 233 234 vsizer.Add(wx.StaticText(dlg,wx.ID_ANY,u'Beam center (pixels). X = '), 234 235 0,wx.ALIGN_LEFT|wx.ALL, 2) 235 wdgt = G2 gd.ValidatedTxtCtrl(dlg,Data['center'],0,236 wdgt = G2G.ValidatedTxtCtrl(dlg,Data['center'],0, 236 237 size=(75,-1)) 237 238 vsizer.Add(wdgt) 238 239 vsizer.Add(wx.StaticText(dlg,wx.ID_ANY,u' Y = '), 239 240 wx.ALIGN_LEFT|wx.ALL, 2) 240 wdgt = G2 gd.ValidatedTxtCtrl(dlg,Data['center'],1,241 wdgt = G2G.ValidatedTxtCtrl(dlg,Data['center'],1, 241 242 size=(75,-1)) 242 243 vsizer.Add(wdgt) … … 246 247 vsizer.Add(wx.StaticText(dlg,wx.ID_ANY,u'Comments '), 247 248 0,wx.ALIGN_LEFT|wx.ALL, 2) 248 wdgt = G2 gd.ValidatedTxtCtrl(dlg,Comments,0,size=(250,-1))249 wdgt = G2G.ValidatedTxtCtrl(dlg,Comments,0,size=(250,-1)) 249 250 vsizer.Add(wdgt) 250 251 mainsizer.Add(vsizer,0,wx.ALIGN_LEFT|wx.ALL, 2) -
trunk/GSASIIconstrGUI.py
r1545 r1619 31 31 import GSASIImapvars as G2mv 32 32 import GSASIIgrid as G2gd 33 import GSASIIctrls as G2G 33 34 import GSASIIplot as G2plt 34 35 import GSASIIobj as G2obj … … 119 120 name = wx.StaticText(panel,wx.ID_ANY,lbl1, 120 121 style=wx.ALIGN_RIGHT) 121 scale = G2 gd.ValidatedTxtCtrl(panel,self.data[id],0,122 scale = G2G.ValidatedTxtCtrl(panel,self.data[id],0, 122 123 typeHint=float, 123 124 OKcontrol=self.DisableOK) … … 133 134 name = wx.StaticText(panel,wx.ID_ANY,"New variable's\nname (optional)", 134 135 style=wx.ALIGN_CENTER) 135 scale = G2 gd.ValidatedTxtCtrl(panel,self.newvar,0,136 scale = G2G.ValidatedTxtCtrl(panel,self.newvar,0, 136 137 typeHint=str,notBlank=False) 137 138 dataGridSizer.Add(name,0,wx.LEFT|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL,5) … … 839 840 constSizer.Add((-1,-1)) 840 841 if refineflag: 841 ch = G2 gd.G2CheckBox(pageDisplay,'',item,-2)842 ch = G2G.G2CheckBox(pageDisplay,'',item,-2) 842 843 constSizer.Add(ch,0,wx.LEFT|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER,1) 843 844 else: -
trunk/GSASIIexprGUI.py
r1413 r1619 32 32 GSASIIpath.SetVersionNumber("$Revision$") 33 33 import GSASIIgrid as G2gd 34 import GSASIIctrls as G2G 34 35 import GSASIIpy3 as G2py3 35 36 import GSASIIobj as G2obj … … 458 459 GridSiz.Add((-1,-1),0,wx.ALIGN_LEFT|wx.EXPAND,0) 459 460 elif self.varSelect.get(v) == 0: 460 wid = G2 gd.ValidatedTxtCtrl(self.varbox,self.varName,v,461 wid = G2G.ValidatedTxtCtrl(self.varbox,self.varName,v, 461 462 #OnLeave=self.OnTxtLeave, 462 463 size=(50,-1)) … … 470 471 GridSiz.Add((-1,-1),0,wx.ALIGN_RIGHT|wx.EXPAND,0) 471 472 elif self.varSelect.get(v) == 0: 472 wid = G2 gd.ValidatedTxtCtrl(self.varbox,self.varValue,v,473 wid = G2G.ValidatedTxtCtrl(self.varbox,self.varValue,v, 473 474 #OnLeave=self.OnTxtLeave, 474 475 size=(75,-1)) … … 493 494 if self.varSelect.get(v) == 0 and self.fit: 494 495 self.varRefflag[v] = self.varRefflag.get(v,True) 495 wid = G2 gd.G2CheckBox(self.varbox,'',self.varRefflag,v)496 wid = G2G.G2CheckBox(self.varbox,'',self.varRefflag,v) 496 497 GridSiz.Add(wid,0,wx.ALIGN_LEFT|wx.EXPAND,0) 497 498 else: … … 517 518 sel = self.depChoices[event.GetEventObject().GetSelection()] 518 519 var = self.SelectG2var(sel,'Dependent variable',self.depParmLists[sel]) 519 if not var:520 if var is None: 520 521 self.dependentVar = None 521 522 self.OnValidate(None) … … 538 539 v = event.GetEventObject().label 539 540 sel = self.AllowedChoices[event.GetEventObject().GetSelection()] 540 self.varSelect[v] = sel541 541 if sel == 0: 542 542 sv = G2obj.MakeUniqueLabel(v,self.usedVars) 543 self.varSelect[v] = sel 543 544 self.varName[v] = sv 544 545 self.varValue[v] = self.varValue.get(v,0.0) 545 546 else: 546 547 var = self.SelectG2var(sel,v,self.parmLists[sel]) 547 if not var: 548 del self.varSelect[v] 548 if var is None: 549 549 self.OnValidate(None) 550 550 return 551 self.varSelect[v] = sel 551 552 self.varName[v] = var 552 553 self.OnValidate(None) -
trunk/GSASIIgrid.py
r1618 r1619 46 46 import GSASIIexprGUI as G2exG 47 47 import GSASIIlog as log 48 import GSASIIctrls as G2G 48 49 49 50 # trig functions in degrees … … 137 138 ] = [wx.NewId() for item in range(10)] 138 139 139 [ wxID_RENAMESEQSEL,wxID_SAVESEQSEL,wxID_SAVESEQSELCSV,wxID_PLOTSEQSEL, 140 [ wxID_RENAMESEQSEL,wxID_SAVESEQSEL,wxID_SAVESEQSELCSV,wxID_PLOTSEQSEL,wxID_ORGSEQSEL, 140 141 wxADDSEQVAR,wxDELSEQVAR,wxEDITSEQVAR,wxCOPYPARFIT, 141 142 wxADDPARFIT,wxDELPARFIT,wxEDITPARFIT,wxDOPARFIT, 142 ] = [wx.NewId() for item in range(1 2)]143 ] = [wx.NewId() for item in range(13)] 143 144 144 145 [ wxID_MODELCOPY,wxID_MODELFIT,wxID_MODELADD,wxID_ELEMENTADD,wxID_ELEMENTDELETE, … … 211 212 212 213 213 class G2TreeCtrl(wx.TreeCtrl):214 '''Create a wrapper around the standard TreeCtrl so we can "wrap"215 various events.216 217 This logs when a tree item is selected (in :meth:`onSelectionChanged`)218 219 This also wraps lists and dicts pulled out of the tree to track where220 they were retrieved from.221 '''222 def __init__(self,parent=None,*args,**kwargs):223 super(self.__class__,self).__init__(parent=parent,*args,**kwargs)224 self.G2frame = parent.GetParent()225 self.root = self.AddRoot('Loaded Data: ')226 self.SelectionChanged = None227 log.LogInfo['Tree'] = self228 229 def _getTreeItemsList(self,item):230 '''Get the full tree hierarchy from a reference to a tree item.231 Note that this effectively hard-codes phase and histogram names in the232 returned list. We may want to make these names relative in the future.233 '''234 textlist = [self.GetItemText(item)]235 parent = self.GetItemParent(item)236 while parent:237 if parent == self.root: break238 textlist.insert(0,self.GetItemText(parent))239 parent = self.GetItemParent(parent)240 return textlist241 242 def onSelectionChanged(self,event):243 '''Log each press on a tree item here.244 '''245 if self.SelectionChanged:246 textlist = self._getTreeItemsList(event.GetItem())247 if log.LogInfo['Logging'] and event.GetItem() != self.root:248 textlist[0] = self.GetRelativeHistNum(textlist[0])249 if textlist[0] == "Phases" and len(textlist) > 1:250 textlist[1] = self.GetRelativePhaseNum(textlist[1])251 log.MakeTreeLog(textlist)252 self.SelectionChanged(event)253 254 def Bind(self,eventtype,handler,*args,**kwargs):255 '''Override the Bind() function so that page change events can be trapped256 '''257 if eventtype == wx.EVT_TREE_SEL_CHANGED:258 self.SelectionChanged = handler259 wx.TreeCtrl.Bind(self,eventtype,self.onSelectionChanged)260 return261 wx.TreeCtrl.Bind(self,eventtype,handler,*args,**kwargs)262 263 # commented out, disables Logging264 # def GetItemPyData(self,*args,**kwargs):265 # '''Override the standard method to wrap the contents266 # so that the source can be logged when changed267 # '''268 # data = super(self.__class__,self).GetItemPyData(*args,**kwargs)269 # textlist = self._getTreeItemsList(args[0])270 # if type(data) is dict:271 # return log.dictLogged(data,textlist)272 # if type(data) is list:273 # return log.listLogged(data,textlist)274 # if type(data) is tuple: #N.B. tuples get converted to lists275 # return log.listLogged(list(data),textlist)276 # return data277 278 def GetRelativeHistNum(self,histname):279 '''Returns list with a histogram type and a relative number for that280 histogram, or the original string if not a histogram281 '''282 histtype = histname.split()[0]283 if histtype != histtype.upper(): # histograms (only) have a keyword all in caps284 return histname285 item, cookie = self.GetFirstChild(self.root)286 i = 0287 while item:288 itemtext = self.GetItemText(item)289 if itemtext == histname:290 return histtype,i291 elif itemtext.split()[0] == histtype:292 i += 1293 item, cookie = self.GetNextChild(self.root, cookie)294 else:295 raise Exception("Histogram not found: "+histname)296 297 def ConvertRelativeHistNum(self,histtype,histnum):298 '''Converts a histogram type and relative histogram number to a299 histogram name in the current project300 '''301 item, cookie = self.GetFirstChild(self.root)302 i = 0303 while item:304 itemtext = self.GetItemText(item)305 if itemtext.split()[0] == histtype:306 if i == histnum: return itemtext307 i += 1308 item, cookie = self.GetNextChild(self.root, cookie)309 else:310 raise Exception("Histogram #'+str(histnum)+' of type "+histtype+' not found')311 312 def GetRelativePhaseNum(self,phasename):313 '''Returns a phase number if the string matches a phase name314 or else returns the original string315 '''316 item, cookie = self.GetFirstChild(self.root)317 while item:318 itemtext = self.GetItemText(item)319 if itemtext == "Phases":320 parent = item321 item, cookie = self.GetFirstChild(parent)322 i = 0323 while item:324 itemtext = self.GetItemText(item)325 if itemtext == phasename:326 return i327 item, cookie = self.GetNextChild(parent, cookie)328 i += 1329 else:330 return phasename # not a phase name331 item, cookie = self.GetNextChild(self.root, cookie)332 else:333 raise Exception("No phases found ")334 335 def ConvertRelativePhaseNum(self,phasenum):336 '''Converts relative phase number to a phase name in337 the current project338 '''339 item, cookie = self.GetFirstChild(self.root)340 while item:341 itemtext = self.GetItemText(item)342 if itemtext == "Phases":343 parent = item344 item, cookie = self.GetFirstChild(parent)345 i = 0346 while item:347 if i == phasenum:348 return self.GetItemText(item)349 item, cookie = self.GetNextChild(parent, cookie)350 i += 1351 else:352 raise Exception("Phase "+str(phasenum)+" not found")353 item, cookie = self.GetNextChild(self.root, cookie)354 else:355 raise Exception("No phases found ")356 #===========================================================================357 214 class G2LoggedButton(wx.Button): 358 215 '''A version of wx.Button that creates logging events. Bindings are saved … … 378 235 log.MakeButtonLog(self.locationcode,self.label) 379 236 self.handler(event) 380 #===========================================================================381 class ValidatedTxtCtrl(wx.TextCtrl):382 '''Create a TextCtrl widget that uses a validator to prevent the383 entry of inappropriate characters and changes color to highlight384 when invalid input is supplied. As valid values are typed,385 they are placed into the dict or list where the initial value386 came from. The type of the initial value must be int,387 float or str or None (see :obj:`key` and :obj:`typeHint`);388 this type (or the one in :obj:`typeHint`) is preserved.389 390 Float values can be entered in the TextCtrl as numbers or also391 as algebraic expressions using operators + - / \* () and \*\*,392 in addition pi, sind(), cosd(), tand(), and sqrt() can be used,393 as well as appreviations s, sin, c, cos, t, tan and sq.394 395 :param wx.Panel parent: name of panel or frame that will be396 the parent to the TextCtrl. Can be None.397 398 :param dict/list loc: the dict or list with the initial value to be399 placed in the TextCtrl.400 401 :param int/str key: the dict key or the list index for the value to be402 edited by the TextCtrl. The ``loc[key]`` element must exist, but may403 have value None. If None, the type for the element is taken from404 :obj:`typeHint` and the value for the control is set initially405 blank (and thus invalid.) This is a way to specify a field without a406 default value: a user must set a valid value.407 If the value is not None, it must have a base408 type of int, float, str or unicode; the TextCrtl will be initialized409 from this value.410 411 :param list nDig: number of digits & places ([nDig,nPlc]) after decimal to use412 for display of float. Alternately, None can be specified which causes413 numbers to be displayed with approximately 5 significant figures414 (Default=None).415 416 :param bool notBlank: if True (default) blank values are invalid417 for str inputs.418 419 :param number min: minimum allowed valid value. If None (default) the420 lower limit is unbounded.421 422 :param number max: maximum allowed valid value. If None (default) the423 upper limit is unbounded424 425 :param function OKcontrol: specifies a function or method that will be426 called when the input is validated. The called function is supplied427 with one argument which is False if the TextCtrl contains an invalid428 value and True if the value is valid.429 Note that this function should check all values430 in the dialog when True, since other entries might be invalid.431 The default for this is None, which indicates no function should432 be called.433 434 :param function OnLeave: specifies a function or method that will be435 called when the focus for the control is lost.436 The called function is supplied with (at present) three keyword arguments:437 438 * invalid: (*bool*) True if the value for the TextCtrl is invalid439 * value: (*int/float/str*) the value contained in the TextCtrl440 * tc: (*wx.TextCtrl*) the TextCtrl name441 442 The number of keyword arguments may be increased in the future should needs arise,443 so it is best to code these functions with a \*\*kwargs argument so they will444 continue to run without errors445 446 The default for OnLeave is None, which indicates no function should447 be called.448 449 :param type typeHint: the value of typeHint is overrides the initial value450 for the dict/list element ``loc[key]``, if set to451 int or float, which specifies the type for input to the TextCtrl.452 Defaults as None, which is ignored.453 454 :param bool CIFinput: for str input, indicates that only printable455 ASCII characters may be entered into the TextCtrl. Forces output456 to be ASCII rather than Unicode. For float and int input, allows457 use of a single '?' or '.' character as valid input.458 459 :param dict OnLeaveArgs: a dict with keyword args that are passed to460 the :attr:`OnLeave` function. Defaults to ``{}``461 462 :param (other): other optional keyword parameters for the463 wx.TextCtrl widget such as size or style may be specified.464 465 '''466 def __init__(self,parent,loc,key,nDig=None,notBlank=True,min=None,max=None,467 OKcontrol=None,OnLeave=None,typeHint=None,468 CIFinput=False, OnLeaveArgs={}, **kw):469 # save passed values needed outside __init__470 self.result = loc471 self.key = key472 self.nDig = nDig473 self.OKcontrol=OKcontrol474 self.OnLeave = OnLeave475 self.OnLeaveArgs = OnLeaveArgs476 self.CIFinput = CIFinput477 self.type = str478 # initialization479 self.invalid = False # indicates if the control has invalid contents480 self.evaluated = False # set to True when the validator recognizes an expression481 val = loc[key]482 if isinstance(val,int) or typeHint is int:483 self.type = int484 wx.TextCtrl.__init__(485 self,parent,wx.ID_ANY,486 validator=NumberValidator(int,result=loc,key=key,487 min=min,max=max,488 OKcontrol=OKcontrol,489 CIFinput=CIFinput),490 **kw)491 if val is not None:492 self._setValue(val)493 else: # no default is invalid for a number494 self.invalid = True495 self._IndicateValidity()496 497 elif isinstance(val,float) or typeHint is float:498 self.type = float499 wx.TextCtrl.__init__(500 self,parent,wx.ID_ANY,501 validator=NumberValidator(float,result=loc,key=key,502 min=min,max=max,503 OKcontrol=OKcontrol,504 CIFinput=CIFinput),505 **kw)506 if val is not None:507 self._setValue(val)508 else:509 self.invalid = True510 self._IndicateValidity()511 512 elif isinstance(val,str) or isinstance(val,unicode):513 if self.CIFinput:514 wx.TextCtrl.__init__(515 self,parent,wx.ID_ANY,val,516 validator=ASCIIValidator(result=loc,key=key),517 **kw)518 else:519 wx.TextCtrl.__init__(self,parent,wx.ID_ANY,val,**kw)520 if notBlank:521 self.Bind(wx.EVT_CHAR,self._onStringKey)522 self.ShowStringValidity() # test if valid input523 else:524 self.invalid = False525 self.Bind(wx.EVT_CHAR,self._GetStringValue)526 elif val is None:527 raise Exception,("ValidatedTxtCtrl error: value of "+str(key)+528 " element is None and typeHint not defined as int or float")529 else:530 raise Exception,("ValidatedTxtCtrl error: Unknown element ("+str(key)+531 ") type: "+str(type(val)))532 # When the mouse is moved away or the widget loses focus,533 # display the last saved value, if an expression534 #self.Bind(wx.EVT_LEAVE_WINDOW, self._onLeaveWindow)535 self.Bind(wx.EVT_TEXT_ENTER, self._onLoseFocus)536 self.Bind(wx.EVT_KILL_FOCUS, self._onLoseFocus)537 # patch for wx 2.9 on Mac538 i,j= wx.__version__.split('.')[0:2]539 if int(i)+int(j)/10. > 2.8 and 'wxOSX' in wx.PlatformInfo:540 self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)541 542 def SetValue(self,val):543 if self.result is not None: # note that this bypasses formatting544 self.result[self.key] = val545 log.LogVarChange(self.result,self.key)546 self._setValue(val)547 548 def _setValue(self,val):549 self.invalid = False550 if self.type is int:551 try:552 if int(val) != val:553 self.invalid = True554 else:555 val = int(val)556 except:557 if self.CIFinput and (val == '?' or val == '.'):558 pass559 else:560 self.invalid = True561 wx.TextCtrl.SetValue(self,str(val))562 elif self.type is float:563 try:564 val = float(val) # convert strings, if needed565 except:566 if self.CIFinput and (val == '?' or val == '.'):567 pass568 else:569 self.invalid = True570 if self.nDig:571 wx.TextCtrl.SetValue(self,str(G2py3.FormatValue(val,self.nDig)))572 else:573 wx.TextCtrl.SetValue(self,str(G2py3.FormatSigFigs(val)).rstrip('0'))574 else:575 wx.TextCtrl.SetValue(self,str(val))576 self.ShowStringValidity() # test if valid input577 return578 579 self._IndicateValidity()580 if self.OKcontrol:581 self.OKcontrol(not self.invalid)582 583 def OnKeyDown(self,event):584 'Special callback for wx 2.9+ on Mac where backspace is not processed by validator'585 key = event.GetKeyCode()586 if key in [wx.WXK_BACK, wx.WXK_DELETE]:587 if self.Validator: wx.CallAfter(self.Validator.TestValid,self)588 if key == wx.WXK_RETURN:589 self._onLoseFocus(None)590 event.Skip()591 592 def _onStringKey(self,event):593 event.Skip()594 if self.invalid: # check for validity after processing the keystroke595 wx.CallAfter(self.ShowStringValidity,True) # was invalid596 else:597 wx.CallAfter(self.ShowStringValidity,False) # was valid598 599 def _IndicateValidity(self):600 'Set the control colors to show invalid input'601 if self.invalid:602 self.SetForegroundColour("red")603 self.SetBackgroundColour("yellow")604 self.SetFocus()605 self.Refresh()606 else: # valid input607 self.SetBackgroundColour(608 wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))609 self.SetForegroundColour("black")610 self.Refresh()611 612 def ShowStringValidity(self,previousInvalid=True):613 '''Check if input is valid. Anytime the input is614 invalid, call self.OKcontrol (if defined) because it is fast.615 If valid, check for any other invalid entries only when616 changing from invalid to valid, since that is slower.617 618 :param bool previousInvalid: True if the TextCtrl contents were619 invalid prior to the current change.620 621 '''622 val = self.GetValue().strip()623 self.invalid = not val624 self._IndicateValidity()625 if self.invalid:626 if self.OKcontrol:627 self.OKcontrol(False)628 elif self.OKcontrol and previousInvalid:629 self.OKcontrol(True)630 # always store the result631 if self.CIFinput: # for CIF make results ASCII632 self.result[self.key] = val.encode('ascii','replace')633 else:634 self.result[self.key] = val635 log.LogVarChange(self.result,self.key)636 637 def _GetStringValue(self,event):638 '''Get string input and store.639 '''640 event.Skip() # process keystroke641 wx.CallAfter(self._SaveStringValue)642 643 def _SaveStringValue(self):644 val = self.GetValue().strip()645 # always store the result646 if self.CIFinput: # for CIF make results ASCII647 self.result[self.key] = val.encode('ascii','replace')648 else:649 self.result[self.key] = val650 log.LogVarChange(self.result,self.key)651 652 def _onLoseFocus(self,event):653 if self.evaluated:654 self.EvaluateExpression()655 elif self.result is not None: # show formatted result, as Bob wants656 self._setValue(self.result[self.key])657 if self.OnLeave: self.OnLeave(invalid=self.invalid,658 value=self.result[self.key],659 tc=self,660 **self.OnLeaveArgs)661 if event: event.Skip()662 663 def EvaluateExpression(self):664 '''Show the computed value when an expression is entered to the TextCtrl665 Make sure that the number fits by truncating decimal places and switching666 to scientific notation, as needed.667 Called on loss of focus, enter, etc..668 '''669 if self.invalid: return # don't substitute for an invalid expression670 if not self.evaluated: return # true when an expression is evaluated671 if self.result is not None: # retrieve the stored result672 self._setValue(self.result[self.key])673 self.evaluated = False # expression has been recast as value, reset flag674 675 class NumberValidator(wx.PyValidator):676 '''A validator to be used with a TextCtrl to prevent677 entering characters other than digits, signs, and for float678 input, a period and exponents.679 680 The value is checked for validity after every keystroke681 If an invalid number is entered, the box is highlighted.682 If the number is valid, it is saved in result[key]683 684 :param type typ: the base data type. Must be int or float.685 686 :param bool positiveonly: If True, negative integers are not allowed687 (default False). This prevents the + or - keys from being pressed.688 Used with typ=int; ignored for typ=float.689 690 :param number min: Minimum allowed value. If None (default) the691 lower limit is unbounded692 693 :param number max: Maximum allowed value. If None (default) the694 upper limit is unbounded695 696 :param dict/list result: List or dict where value should be placed when valid697 698 :param any key: key to use for result (int for list)699 700 :param function OKcontrol: function or class method to control701 an OK button for a window.702 Ignored if None (default)703 704 :param bool CIFinput: allows use of a single '?' or '.' character705 as valid input.706 707 '''708 def __init__(self, typ, positiveonly=False, min=None, max=None,709 result=None, key=None, OKcontrol=None, CIFinput=False):710 'Create the validator'711 wx.PyValidator.__init__(self)712 # save passed parameters713 self.typ = typ714 self.positiveonly = positiveonly715 self.min = min716 self.max = max717 self.result = result718 self.key = key719 self.OKcontrol = OKcontrol720 self.CIFinput = CIFinput721 # set allowed keys by data type722 self.Bind(wx.EVT_CHAR, self.OnChar)723 if self.typ == int and self.positiveonly:724 self.validchars = '0123456789'725 elif self.typ == int:726 self.validchars = '0123456789+-'727 elif self.typ == float:728 # allow for above and sind, cosd, sqrt, tand, pi, and abbreviations729 # also addition, subtraction, division, multiplication, exponentiation730 self.validchars = '0123456789.-+eE/cosindcqrtap()*'731 else:732 self.validchars = None733 return734 if self.CIFinput:735 self.validchars += '?.'736 def Clone(self):737 'Create a copy of the validator, a strange, but required component'738 return NumberValidator(typ=self.typ,739 positiveonly=self.positiveonly,740 min=self.min, max=self.max,741 result=self.result, key=self.key,742 OKcontrol=self.OKcontrol,743 CIFinput=self.CIFinput)744 def TransferToWindow(self):745 'Needed by validator, strange, but required component'746 return True # Prevent wxDialog from complaining.747 def TransferFromWindow(self):748 'Needed by validator, strange, but required component'749 return True # Prevent wxDialog from complaining.750 def TestValid(self,tc):751 '''Check if the value is valid by casting the input string752 into the current type.753 754 Set the invalid variable in the TextCtrl object accordingly.755 756 If the value is valid, save it in the dict/list where757 the initial value was stored, if appropriate.758 759 :param wx.TextCtrl tc: A reference to the TextCtrl that the validator760 is associated with.761 '''762 tc.invalid = False # assume valid763 if self.CIFinput:764 val = tc.GetValue().strip()765 if val == '?' or val == '.':766 self.result[self.key] = val767 log.LogVarChange(self.result,self.key)768 return769 try:770 val = self.typ(tc.GetValue())771 except (ValueError, SyntaxError) as e:772 if self.typ is float: # for float values, see if an expression can be evaluated773 val = G2py3.FormulaEval(tc.GetValue())774 if val is None:775 tc.invalid = True776 return777 else:778 tc.evaluated = True779 else:780 tc.invalid = True781 return782 # if self.max != None and self.typ == int:783 # if val > self.max:784 # tc.invalid = True785 # if self.min != None and self.typ == int:786 # if val < self.min:787 # tc.invalid = True # invalid788 if self.max != None:789 if val > self.max:790 tc.invalid = True791 if self.min != None:792 if val < self.min:793 tc.invalid = True # invalid794 if self.key is not None and self.result is not None and not tc.invalid:795 self.result[self.key] = val796 log.LogVarChange(self.result,self.key)797 798 def ShowValidity(self,tc):799 '''Set the control colors to show invalid input800 801 :param wx.TextCtrl tc: A reference to the TextCtrl that the validator802 is associated with.803 804 '''805 if tc.invalid:806 tc.SetForegroundColour("red")807 tc.SetBackgroundColour("yellow")808 tc.SetFocus()809 tc.Refresh()810 return False811 else: # valid input812 tc.SetBackgroundColour(813 wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))814 tc.SetForegroundColour("black")815 tc.Refresh()816 return True817 818 def CheckInput(self,previousInvalid):819 '''called to test every change to the TextCtrl for validity and820 to change the appearance of the TextCtrl821 822 Anytime the input is invalid, call self.OKcontrol823 (if defined) because it is fast.824 If valid, check for any other invalid entries only when825 changing from invalid to valid, since that is slower.826 827 :param bool previousInvalid: True if the TextCtrl contents were828 invalid prior to the current change.829 '''830 tc = self.GetWindow()831 self.TestValid(tc)832 self.ShowValidity(tc)833 # if invalid834 if tc.invalid and self.OKcontrol:835 self.OKcontrol(False)836 if not tc.invalid and self.OKcontrol and previousInvalid:837 self.OKcontrol(True)838 839 def OnChar(self, event):840 '''Called each type a key is pressed841 ignores keys that are not allowed for int and float types842 '''843 key = event.GetKeyCode()844 tc = self.GetWindow()845 if key == wx.WXK_RETURN:846 if tc.invalid:847 self.CheckInput(True)848 else:849 self.CheckInput(False)850 return851 if key < wx.WXK_SPACE or key == wx.WXK_DELETE or key > 255: # control characters get processed852 event.Skip()853 if tc.invalid:854 wx.CallAfter(self.CheckInput,True)855 else:856 wx.CallAfter(self.CheckInput,False)857 return858 elif chr(key) in self.validchars: # valid char pressed?859 event.Skip()860 if tc.invalid:861 wx.CallAfter(self.CheckInput,True)862 else:863 wx.CallAfter(self.CheckInput,False)864 return865 if not wx.Validator_IsSilent(): wx.Bell()866 return # Returning without calling event.Skip, which eats the keystroke867 868 ################################################################################869 class ASCIIValidator(wx.PyValidator):870 '''A validator to be used with a TextCtrl to prevent871 entering characters other than ASCII characters.872 873 The value is checked for validity after every keystroke874 If an invalid number is entered, the box is highlighted.875 If the number is valid, it is saved in result[key]876 877 :param dict/list result: List or dict where value should be placed when valid878 879 :param any key: key to use for result (int for list)880 881 '''882 def __init__(self, result=None, key=None):883 'Create the validator'884 import string885 wx.PyValidator.__init__(self)886 # save passed parameters887 self.result = result888 self.key = key889 self.validchars = string.ascii_letters + string.digits + string.punctuation + string.whitespace890 self.Bind(wx.EVT_CHAR, self.OnChar)891 def Clone(self):892 'Create a copy of the validator, a strange, but required component'893 return ASCIIValidator(result=self.result, key=self.key)894 tc = self.GetWindow()895 tc.invalid = False # make sure the validity flag is defined in parent896 def TransferToWindow(self):897 'Needed by validator, strange, but required component'898 return True # Prevent wxDialog from complaining.899 def TransferFromWindow(self):900 'Needed by validator, strange, but required component'901 return True # Prevent wxDialog from complaining.902 def TestValid(self,tc):903 '''Check if the value is valid by casting the input string904 into ASCII.905 906 Save it in the dict/list where the initial value was stored907 908 :param wx.TextCtrl tc: A reference to the TextCtrl that the validator909 is associated with.910 '''911 self.result[self.key] = tc.GetValue().encode('ascii','replace')912 log.LogVarChange(self.result,self.key)913 914 def OnChar(self, event):915 '''Called each type a key is pressed916 ignores keys that are not allowed for int and float types917 '''918 key = event.GetKeyCode()919 tc = self.GetWindow()920 if key == wx.WXK_RETURN:921 self.TestValid(tc)922 return923 if key < wx.WXK_SPACE or key == wx.WXK_DELETE or key > 255: # control characters get processed924 event.Skip()925 self.TestValid(tc)926 return927 elif chr(key) in self.validchars: # valid char pressed?928 event.Skip()929 self.TestValid(tc)930 return931 if not wx.Validator_IsSilent():932 wx.Bell()933 return # Returning without calling event.Skip, which eats the keystroke934 ################################################################################935 237 class EnumSelector(wx.ComboBox): 936 238 '''A customized :class:`wxpython.ComboBox` that selects items from a list … … 992 294 993 295 ################################################################################ 994 class G2CheckBox(wx.CheckBox):995 '''A customized version of a CheckBox that automatically initializes996 the control to a supplied list or dict entry and updates that997 entry as the widget is used.998 999 :param wx.Panel parent: name of panel or frame that will be1000 the parent to the widget. Can be None.1001 :param str label: text to put on check button1002 :param dict/list loc: the dict or list with the initial value to be1003 placed in the CheckBox.1004 :param int/str key: the dict key or the list index for the value to be1005 edited by the CheckBox. The ``loc[key]`` element must exist.1006 The CheckBox will be initialized from this value.1007 If the value is anything other that True (or 1), it will be taken as1008 False.1009 '''1010 def __init__(self,parent,label,loc,key):1011 wx.CheckBox.__init__(self,parent,id=wx.ID_ANY,label=label)1012 self.loc = loc1013 self.key = key1014 self.SetValue(self.loc[self.key]==True)1015 self.Bind(wx.EVT_CHECKBOX, self._OnCheckBox)1016 def _OnCheckBox(self,event):1017 self.loc[self.key] = self.GetValue()1018 log.LogVarChange(self.loc,self.key)1019 296 ################################################################################ 1020 297 class G2ChoiceButton(wx.Choice): … … 1080 357 if self.onChoice: 1081 358 self.onChoice() 1082 ################################################################################1083 def CallScrolledMultiEditor(parent,dictlst,elemlst,prelbl=[],postlbl=[],1084 title='Edit items',header='',size=(300,250),1085 CopyButton=False, **kw):1086 '''Shell routine to call a ScrolledMultiEditor dialog. See1087 :class:`ScrolledMultiEditor` for parameter definitions.1088 1089 :returns: True if the OK button is pressed; False if the window is closed1090 with the system menu or the Cancel button.1091 1092 '''1093 dlg = ScrolledMultiEditor(parent,dictlst,elemlst,prelbl,postlbl,1094 title,header,size,1095 CopyButton, **kw)1096 if dlg.ShowModal() == wx.ID_OK:1097 dlg.Destroy()1098 return True1099 else:1100 dlg.Destroy()1101 return False1102 1103 class ScrolledMultiEditor(wx.Dialog):1104 '''Define a window for editing a potentially large number of dict- or1105 list-contained values with validation for each item. Edited values are1106 automatically placed in their source location. If invalid entries1107 are provided, the TextCtrl is turned yellow and the OK button is disabled.1108 1109 The type for each TextCtrl validation is determined by the1110 initial value of the entry (int, float or string).1111 Float values can be entered in the TextCtrl as numbers or also1112 as algebraic expressions using operators + - / \* () and \*\*,1113 in addition pi, sind(), cosd(), tand(), and sqrt() can be used,1114 as well as appreviations s(), sin(), c(), cos(), t(), tan() and sq().1115 1116 :param wx.Frame parent: name of parent window, or may be None1117 1118 :param tuple dictlst: a list of dicts or lists containing values to edit1119 1120 :param tuple elemlst: a list of keys for each item in a dictlst. Must have the1121 same length as dictlst.1122 1123 :param wx.Frame parent: name of parent window, or may be None1124 1125 :param tuple prelbl: a list of labels placed before the TextCtrl for each1126 item (optional)1127 1128 :param tuple postlbl: a list of labels placed after the TextCtrl for each1129 item (optional)1130 1131 :param str title: a title to place in the frame of the dialog1132 1133 :param str header: text to place at the top of the window. May contain1134 new line characters.1135 1136 :param wx.Size size: a size parameter that dictates the1137 size for the scrolled region of the dialog. The default is1138 (300,250).1139 1140 :param bool CopyButton: if True adds a small button that copies the1141 value for the current row to all fields below (default is False)1142 1143 :param list minvals: optional list of minimum values for validation1144 of float or int values. Ignored if value is None.1145 :param list maxvals: optional list of maximum values for validation1146 of float or int values. Ignored if value is None.1147 :param list sizevals: optional list of wx.Size values for each input1148 widget. Ignored if value is None.1149 1150 :param tuple checkdictlst: an optional list of dicts or lists containing bool1151 values (similar to dictlst).1152 :param tuple checkelemlst: an optional list of dicts or lists containing bool1153 key values (similar to elemlst). Must be used with checkdictlst.1154 :param string checklabel: a string to use for each checkbutton1155 1156 :returns: the wx.Dialog created here. Use method .ShowModal() to display it.1157 1158 *Example for use of ScrolledMultiEditor:*1159 1160 ::1161 1162 dlg = <pkg>.ScrolledMultiEditor(frame,dictlst,elemlst,prelbl,postlbl,1163 header=header)1164 if dlg.ShowModal() == wx.ID_OK:1165 for d,k in zip(dictlst,elemlst):1166 print d[k]1167 1168 *Example definitions for dictlst and elemlst:*1169 1170 ::1171 1172 dictlst = (dict1,list1,dict1,list1)1173 elemlst = ('a', 1, 2, 3)1174 1175 This causes items dict1['a'], list1[1], dict1[2] and list1[3] to be edited.1176 1177 Note that these items must have int, float or str values assigned to1178 them. The dialog will force these types to be retained. String values1179 that are blank are marked as invalid.1180 '''1181 1182 def __init__(self,parent,dictlst,elemlst,prelbl=[],postlbl=[],1183 title='Edit items',header='',size=(300,250),1184 CopyButton=False,1185 minvals=[],maxvals=[],sizevals=[],1186 checkdictlst=[], checkelemlst=[], checklabel=""):1187 if len(dictlst) != len(elemlst):1188 raise Exception,"ScrolledMultiEditor error: len(dictlst) != len(elemlst) "+str(len(dictlst))+" != "+str(len(elemlst))1189 if len(checkdictlst) != len(checkelemlst):1190 raise Exception,"ScrolledMultiEditor error: len(checkdictlst) != len(checkelemlst) "+str(len(checkdictlst))+" != "+str(len(checkelemlst))1191 wx.Dialog.__init__( # create dialog & sizer1192 self,parent,wx.ID_ANY,title,1193 style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)1194 mainSizer = wx.BoxSizer(wx.VERTICAL)1195 self.orig = []1196 self.dictlst = dictlst1197 self.elemlst = elemlst1198 self.checkdictlst = checkdictlst1199 self.checkelemlst = checkelemlst1200 self.StartCheckValues = [checkdictlst[i][checkelemlst[i]] for i in range(len(checkdictlst))]1201 self.ButtonIndex = {}1202 for d,i in zip(dictlst,elemlst):1203 self.orig.append(d[i])1204 # add a header if supplied1205 if header:1206 subSizer = wx.BoxSizer(wx.HORIZONTAL)1207 subSizer.Add((-1,-1),1,wx.EXPAND)1208 subSizer.Add(wx.StaticText(self,wx.ID_ANY,header))1209 subSizer.Add((-1,-1),1,wx.EXPAND)1210 mainSizer.Add(subSizer,0,wx.EXPAND,0)1211 # make OK button now, because we will need it for validation1212 self.OKbtn = wx.Button(self, wx.ID_OK)1213 self.OKbtn.SetDefault()1214 # create scrolled panel and sizer1215 panel = wxscroll.ScrolledPanel(self, wx.ID_ANY,size=size,1216 style = wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER)1217 cols = 41218 if CopyButton: cols += 11219 subSizer = wx.FlexGridSizer(cols=cols,hgap=2,vgap=2)1220 self.ValidatedControlsList = [] # make list of TextCtrls1221 self.CheckControlsList = [] # make list of CheckBoxes1222 for i,(d,k) in enumerate(zip(dictlst,elemlst)):1223 if i >= len(prelbl): # label before TextCtrl, or put in a blank1224 subSizer.Add((-1,-1))1225 else:1226 subSizer.Add(wx.StaticText(panel,wx.ID_ANY,str(prelbl[i])))1227 kargs = {}1228 if i < len(minvals):1229 if minvals[i] is not None: kargs['min']=minvals[i]1230 if i < len(maxvals):1231 if maxvals[i] is not None: kargs['max']=maxvals[i]1232 if i < len(sizevals):1233 if sizevals[i]: kargs['size']=sizevals[i]1234 if CopyButton:1235 import wx.lib.colourselect as wscs1236 but = wscs.ColourSelect(label='v', # would like to use u'\u2193' or u'\u25BC' but not in WinXP1237 # is there a way to test?1238 parent=panel,1239 colour=(255,255,200),1240 size=wx.Size(30,23),1241 style=wx.RAISED_BORDER)1242 but.Bind(wx.EVT_BUTTON, self._OnCopyButton)1243 but.SetToolTipString('Press to copy adjacent value to all rows below')1244 self.ButtonIndex[but] = i1245 subSizer.Add(but)1246 # create the validated TextCrtl, store it and add it to the sizer1247 ctrl = ValidatedTxtCtrl(panel,d,k,OKcontrol=self.ControlOKButton,1248 **kargs)1249 self.ValidatedControlsList.append(ctrl)1250 subSizer.Add(ctrl)1251 if i < len(postlbl): # label after TextCtrl, or put in a blank1252 subSizer.Add(wx.StaticText(panel,wx.ID_ANY,str(postlbl[i])))1253 else:1254 subSizer.Add((-1,-1))1255 if i < len(checkdictlst):1256 ch = G2CheckBox(panel,checklabel,checkdictlst[i],checkelemlst[i])1257 self.CheckControlsList.append(ch)1258 subSizer.Add(ch)1259 else:1260 subSizer.Add((-1,-1))1261 # finish up ScrolledPanel1262 panel.SetSizer(subSizer)1263 panel.SetAutoLayout(1)1264 panel.SetupScrolling()1265 # patch for wx 2.9 on Mac1266 i,j= wx.__version__.split('.')[0:2]1267 if int(i)+int(j)/10. > 2.8 and 'wxOSX' in wx.PlatformInfo:1268 panel.SetMinSize((subSizer.GetSize()[0]+30,panel.GetSize()[1]))1269 mainSizer.Add(panel,1, wx.ALL|wx.EXPAND,1)1270 1271 # Sizer for OK/Close buttons. N.B. on Close changes are discarded1272 # by restoring the initial values1273 btnsizer = wx.BoxSizer(wx.HORIZONTAL)1274 btnsizer.Add(self.OKbtn)1275 btn = wx.Button(self, wx.ID_CLOSE,"Cancel")1276 btn.Bind(wx.EVT_BUTTON,self._onClose)1277 btnsizer.Add(btn)1278 mainSizer.Add(btnsizer, 0, wx.ALIGN_CENTER|wx.ALL, 5)1279 # size out the window. Set it to be enlarged but not made smaller1280 self.SetSizer(mainSizer)1281 mainSizer.Fit(self)1282 self.SetMinSize(self.GetSize())1283 1284 def _OnCopyButton(self,event):1285 'Implements the copy down functionality'1286 but = event.GetEventObject()1287 n = self.ButtonIndex.get(but)1288 if n is None: return1289 for i,(d,k,ctrl) in enumerate(zip(self.dictlst,self.elemlst,self.ValidatedControlsList)):1290 if i < n: continue1291 if i == n:1292 val = d[k]1293 continue1294 d[k] = val1295 ctrl.SetValue(val)1296 for i in range(len(self.checkdictlst)):1297 if i < n: continue1298 self.checkdictlst[i][self.checkelemlst[i]] = self.checkdictlst[n][self.checkelemlst[n]]1299 self.CheckControlsList[i].SetValue(self.checkdictlst[i][self.checkelemlst[i]])1300 def _onClose(self,event):1301 'Used on Cancel: Restore original values & close the window'1302 for d,i,v in zip(self.dictlst,self.elemlst,self.orig):1303 d[i] = v1304 for i in range(len(self.checkdictlst)):1305 self.checkdictlst[i][self.checkelemlst[i]] = self.StartCheckValues[i]1306 self.EndModal(wx.ID_CANCEL)1307 1308 def ControlOKButton(self,setvalue):1309 '''Enable or Disable the OK button for the dialog. Note that this is1310 passed into the ValidatedTxtCtrl for use by validators.1311 1312 :param bool setvalue: if True, all entries in the dialog are1313 checked for validity. if False then the OK button is disabled.1314 1315 '''1316 if setvalue: # turn button on, do only if all controls show as valid1317 for ctrl in self.ValidatedControlsList:1318 if ctrl.invalid:1319 self.OKbtn.Disable()1320 return1321 else:1322 self.OKbtn.Enable()1323 else:1324 self.OKbtn.Disable()1325 359 1326 360 ################################################################################ … … 1544 578 self._default(data,self.default) 1545 579 self.Draw(self.data) 1546 1547 class PickTwoDialog(wx.Dialog): 1548 '''This does not seem to be in use 1549 ''' 1550 def __init__(self,parent,title,prompt,names,choices): 1551 wx.Dialog.__init__(self,parent,-1,title, 1552 pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE) 1553 self.panel = wx.Panel(self) #just a dummy - gets destroyed in Draw! 1554 self.prompt = prompt 1555 self.choices = choices 1556 self.names = names 1557 self.Draw() 1558 1559 def Draw(self): 1560 Indx = {} 1561 1562 def OnSelection(event): 1563 Obj = event.GetEventObject() 1564 id = Indx[Obj.GetId()] 1565 self.choices[id] = Obj.GetValue().encode() #to avoid Unicode versions 1566 self.Draw() 1567 1568 self.panel.DestroyChildren() 1569 self.panel.Destroy() 1570 self.panel = wx.Panel(self) 1571 mainSizer = wx.BoxSizer(wx.VERTICAL) 1572 mainSizer.Add(wx.StaticText(self.panel,-1,self.prompt),0,wx.ALIGN_CENTER) 1573 for isel,name in enumerate(self.choices): 1574 lineSizer = wx.BoxSizer(wx.HORIZONTAL) 1575 lineSizer.Add(wx.StaticText(self.panel,-1,'Reference atom '+str(isel+1)),0,wx.ALIGN_CENTER) 1576 nameList = self.names[:] 1577 if isel: 1578 if self.choices[0] in nameList: 1579 nameList.remove(self.choices[0]) 1580 choice = wx.ComboBox(self.panel,-1,value=name,choices=nameList, 1581 style=wx.CB_READONLY|wx.CB_DROPDOWN) 1582 Indx[choice.GetId()] = isel 1583 choice.Bind(wx.EVT_COMBOBOX, OnSelection) 1584 lineSizer.Add(choice,0,WACV) 1585 mainSizer.Add(lineSizer) 1586 OkBtn = wx.Button(self.panel,-1,"Ok") 1587 OkBtn.Bind(wx.EVT_BUTTON, self.OnOk) 1588 CancelBtn = wx.Button(self.panel,-1,'Cancel') 1589 CancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel) 1590 btnSizer = wx.BoxSizer(wx.HORIZONTAL) 1591 btnSizer.Add((20,20),1) 1592 btnSizer.Add(OkBtn) 1593 btnSizer.Add(CancelBtn) 1594 btnSizer.Add((20,20),1) 1595 mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10) 1596 self.panel.SetSizer(mainSizer) 1597 self.panel.Fit() 1598 self.Fit() 1599 1600 def GetSelection(self): 1601 return self.choices 1602 1603 def OnOk(self,event): 1604 parent = self.GetParent() 1605 parent.Raise() 1606 self.EndModal(wx.ID_OK) 1607 1608 def OnCancel(self,event): 1609 parent = self.GetParent() 1610 parent.Raise() 1611 self.EndModal(wx.ID_CANCEL) 1612 580 1613 581 class SingleFloatDialog(wx.Dialog): 1614 582 'Dialog to obtain a single float value from user' … … 2356 1324 2357 1325 ################################################################################ 2358 def SelectEdit1Var(G2frame,array,labelLst,elemKeysLst,dspLst,refFlgElem):2359 '''Select a variable from a list, then edit it and select histograms2360 to copy it to.2361 2362 :param wx.Frame G2frame: main GSAS-II frame2363 :param dict array: the array (dict or list) where values to be edited are kept2364 :param list labelLst: labels for each data item2365 :param list elemKeysLst: a list of lists of keys needed to be applied (see below)2366 to obtain the value of each parameter2367 :param list dspLst: list list of digits to be displayed (10,4) is 10 digits2368 with 4 decimal places. Can be None.2369 :param list refFlgElem: a list of lists of keys needed to be applied (see below)2370 to obtain the refine flag for each parameter or None if the parameter2371 does not have refine flag.2372 2373 Example::2374 array = data2375 labelLst = ['v1','v2']2376 elemKeysLst = [['v1'], ['v2',0]]2377 refFlgElem = [None, ['v2',1]]2378 2379 * The value for v1 will be in data['v1'] and this cannot be refined while,2380 * The value for v2 will be in data['v2'][0] and its refinement flag is data['v2'][1]2381 '''2382 def unkey(dct,keylist):2383 '''dive into a nested set of dicts/lists applying keys in keylist2384 consecutively2385 '''2386 d = dct2387 for k in keylist:2388 d = d[k]2389 return d2390 2391 def OnChoice(event):2392 'Respond when a parameter is selected in the Choice box'2393 valSizer.DeleteWindows()2394 lbl = event.GetString()2395 copyopts['currentsel'] = lbl2396 i = labelLst.index(lbl)2397 OKbtn.Enable(True)2398 ch.SetLabel(lbl)2399 args = {}2400 if dspLst[i]:2401 args = {'nDig':dspLst[i]}2402 Val = ValidatedTxtCtrl(2403 dlg,2404 unkey(array,elemKeysLst[i][:-1]),2405 elemKeysLst[i][-1],2406 **args)2407 copyopts['startvalue'] = unkey(array,elemKeysLst[i])2408 #unkey(array,elemKeysLst[i][:-1])[elemKeysLst[i][-1]] =2409 valSizer.Add(Val,0,wx.LEFT,5)2410 dlg.SendSizeEvent()2411 2412 # SelectEdit1Var execution begins here2413 saveArray = copy.deepcopy(array) # keep original values2414 TreeItemType = G2frame.PatternTree.GetItemText(G2frame.PickId)2415 copyopts = {'InTable':False,"startvalue":None,'currentsel':None}2416 hst = G2frame.PatternTree.GetItemText(G2frame.PatternId)2417 histList = G2pdG.GetHistsLikeSelected(G2frame)2418 if not histList:2419 G2frame.ErrorDialog('No match','No histograms match '+hst,G2frame.dataFrame)2420 return2421 dlg = wx.Dialog(G2frame.dataDisplay,wx.ID_ANY,'Set a parameter value',2422 style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)2423 mainSizer = wx.BoxSizer(wx.VERTICAL)2424 mainSizer.Add((5,5))2425 subSizer = wx.BoxSizer(wx.HORIZONTAL)2426 subSizer.Add((-1,-1),1,wx.EXPAND)2427 subSizer.Add(wx.StaticText(dlg,wx.ID_ANY,'Select a parameter and set a new value'))2428 subSizer.Add((-1,-1),1,wx.EXPAND)2429 mainSizer.Add(subSizer,0,wx.EXPAND,0)2430 mainSizer.Add((0,10))2431 2432 subSizer = wx.FlexGridSizer(0,2,5,0)2433 subSizer.Add(wx.StaticText(dlg,wx.ID_ANY,'Parameter: '))2434 ch = wx.Choice(dlg, wx.ID_ANY, choices = sorted(labelLst))2435 ch.SetSelection(-1)2436 ch.Bind(wx.EVT_CHOICE, OnChoice)2437 subSizer.Add(ch)2438 subSizer.Add(wx.StaticText(dlg,wx.ID_ANY,'Value: '))2439 valSizer = wx.BoxSizer(wx.HORIZONTAL)2440 subSizer.Add(valSizer)2441 mainSizer.Add(subSizer)2442 2443 mainSizer.Add((-1,20))2444 subSizer = wx.BoxSizer(wx.HORIZONTAL)2445 subSizer.Add(G2CheckBox(dlg, 'Edit in table ', copyopts, 'InTable'))2446 mainSizer.Add(subSizer)2447 2448 btnsizer = wx.StdDialogButtonSizer()2449 OKbtn = wx.Button(dlg, wx.ID_OK,'Continue')2450 OKbtn.Enable(False)2451 OKbtn.SetDefault()2452 OKbtn.Bind(wx.EVT_BUTTON,lambda event: dlg.EndModal(wx.ID_OK))2453 btnsizer.AddButton(OKbtn)2454 btn = wx.Button(dlg, wx.ID_CANCEL)2455 btnsizer.AddButton(btn)2456 btnsizer.Realize()2457 mainSizer.Add((-1,5),1,wx.EXPAND,1)2458 mainSizer.Add(btnsizer,0,wx.ALIGN_CENTER,0)2459 mainSizer.Add((-1,10))2460 2461 dlg.SetSizer(mainSizer)2462 dlg.CenterOnParent()2463 if dlg.ShowModal() != wx.ID_OK:2464 array.update(saveArray)2465 dlg.Destroy()2466 return2467 dlg.Destroy()2468 2469 copyList = []2470 lbl = copyopts['currentsel']2471 dlg = G2MultiChoiceDialog(2472 G2frame.dataFrame,2473 'Copy parameter '+lbl+' from\n'+hst,2474 'Copy parameters', histList)2475 dlg.CenterOnParent()2476 try:2477 if dlg.ShowModal() == wx.ID_OK:2478 for i in dlg.GetSelections():2479 copyList.append(histList[i])2480 else:2481 # reset the parameter since cancel was pressed2482 array.update(saveArray)2483 return2484 finally:2485 dlg.Destroy()2486 2487 prelbl = [hst]2488 i = labelLst.index(lbl)2489 keyLst = elemKeysLst[i]2490 refkeys = refFlgElem[i]2491 dictlst = [unkey(array,keyLst[:-1])]2492 if refkeys is not None:2493 refdictlst = [unkey(array,refkeys[:-1])]2494 else:2495 refdictlst = None2496 Id = GetPatternTreeItemId(G2frame,G2frame.root,hst)2497 hstData = G2frame.PatternTree.GetItemPyData(GetPatternTreeItemId(G2frame,Id,'Instrument Parameters'))[0]2498 for h in copyList:2499 Id = GetPatternTreeItemId(G2frame,G2frame.root,h)2500 instData = G2frame.PatternTree.GetItemPyData(GetPatternTreeItemId(G2frame,Id,'Instrument Parameters'))[0]2501 if len(hstData) != len(instData) or hstData['Type'][0] != instData['Type'][0]: #don't mix data types or lam & lam1/lam2 parms!2502 print h+' not copied - instrument parameters not commensurate'2503 continue2504 hData = G2frame.PatternTree.GetItemPyData(GetPatternTreeItemId(G2frame,Id,TreeItemType))2505 if TreeItemType == 'Instrument Parameters':2506 hData = hData[0]2507 #copy the value if it is changed or we will not edit in a table2508 valNow = unkey(array,keyLst)2509 if copyopts['startvalue'] != valNow or not copyopts['InTable']:2510 unkey(hData,keyLst[:-1])[keyLst[-1]] = valNow2511 prelbl += [h]2512 dictlst += [unkey(hData,keyLst[:-1])]2513 if refdictlst is not None:2514 refdictlst += [unkey(hData,refkeys[:-1])]2515 if refdictlst is None:2516 args = {}2517 else:2518 args = {'checkdictlst':refdictlst,2519 'checkelemlst':len(dictlst)*[refkeys[-1]],2520 'checklabel':'Refine?'}2521 if copyopts['InTable']:2522 dlg = ScrolledMultiEditor(2523 G2frame.dataDisplay,dictlst,2524 len(dictlst)*[keyLst[-1]],prelbl,2525 header='Editing parameter '+lbl,2526 CopyButton=True,**args)2527 dlg.CenterOnParent()2528 if dlg.ShowModal() != wx.ID_OK:2529 array.update(saveArray)2530 dlg.Destroy()2531 2532 ################################################################################2533 1326 class ShowLSParms(wx.Dialog): 2534 1327 '''Create frame to show least-squares parameters … … 3213 2006 self.PrefillDataMenu(self.SequentialMenu,helpType='Sequential',helpLbl='Sequential Refinement') 3214 2007 self.SequentialFile = wx.Menu(title='') 3215 self.SequentialMenu.Append(menu=self.SequentialFile, title=' Selected Cols')3216 self.SequentialFile.Append(id=wxID_RENAMESEQSEL, kind=wx.ITEM_NORMAL,text='Rename ',2008 self.SequentialMenu.Append(menu=self.SequentialFile, title='Columns') 2009 self.SequentialFile.Append(id=wxID_RENAMESEQSEL, kind=wx.ITEM_NORMAL,text='Rename selected', 3217 2010 help='Rename selected sequential refinement columns') 3218 self.SequentialFile.Append(id=wxID_SAVESEQSEL, kind=wx.ITEM_NORMAL,text='Save as text',2011 self.SequentialFile.Append(id=wxID_SAVESEQSEL, kind=wx.ITEM_NORMAL,text='Save selected as text', 3219 2012 help='Save selected sequential refinement results as a text file') 3220 self.SequentialFile.Append(id=wxID_SAVESEQSELCSV, kind=wx.ITEM_NORMAL,text='Save as CSV',2013 self.SequentialFile.Append(id=wxID_SAVESEQSELCSV, kind=wx.ITEM_NORMAL,text='Save selected as CSV', 3221 2014 help='Save selected sequential refinement results as a CSV spreadsheet file') 3222 2015 self.SequentialFile.Append(id=wxID_PLOTSEQSEL, kind=wx.ITEM_NORMAL,text='Plot selected', 3223 2016 help='Plot selected sequential refinement results') 2017 self.SequentialFile.Append(id=wxID_ORGSEQSEL, kind=wx.ITEM_NORMAL,text='Reorganize', 2018 help='Reorganize variables where variables change') 3224 2019 self.SequentialPvars = wx.Menu(title='') 3225 2020 self.SequentialMenu.Append(menu=self.SequentialPvars, title='Pseudo Vars') … … 4534 3329 G2plt.PlotSelectedSequence(G2frame,cols,GetColumnInfo,SelectXaxis) 4535 3330 3331 def OnReOrgSelSeq(event): 3332 'Reorder the columns' 3333 G2G.GetItemOrder(G2frame,VaryListChanges,vallookup,posdict) 3334 UpdateSeqResults(G2frame,data,G2frame.dataDisplay.GetSize()) # redisplay variables 3335 4536 3336 def OnSaveSelSeqCSV(event): 4537 3337 'export the selected columns to a .csv file from menu command' … … 5041 3841 lbl = variableLabels.get(var,G2obj.fmtVarDescr(var)) 5042 3842 dlg = SingleStringDialog(G2frame.dataFrame,'Set variable label', 5043 'Set a n ame for variable '+var,lbl,size=(400,-1))3843 'Set a new name for variable '+var,lbl,size=(400,-1)) 5044 3844 if dlg.Show(): 5045 3845 variableLabels[var] = dlg.GetValue() … … 5141 3941 G2frame.dataFrame.Bind(wx.EVT_MENU, OnSaveSelSeqCSV, id=wxID_SAVESEQSELCSV) 5142 3942 G2frame.dataFrame.Bind(wx.EVT_MENU, OnPlotSelSeq, id=wxID_PLOTSEQSEL) 3943 G2frame.dataFrame.Bind(wx.EVT_MENU, OnReOrgSelSeq, id=wxID_ORGSEQSEL) 5143 3944 G2frame.dataFrame.Bind(wx.EVT_MENU, AddNewPseudoVar, id=wxADDSEQVAR) 5144 3945 G2frame.dataFrame.Bind(wx.EVT_MENU, DelPseudoVar, id=wxDELSEQVAR) … … 5152 3953 EnableParFitEqMenus() 5153 3954 5154 VaryListChanges = [] 3955 # scan for locations where the variables change 3956 VaryListChanges = [] # histograms where there is a change 5155 3957 prevVaryList = [] 5156 3958 combinedVaryList = [] 5157 3959 firstValueList = [] 3960 vallookup = {} 3961 posdict = {} 5158 3962 for i,name in enumerate(histNames): 5159 3963 if i == 0 or prevVaryList != sorted(data[name]['varyList']): 5160 if GSASIIpath.GetConfigValue('debug'):5161 print 'VaryList changes at',name5162 print data[name]['varyList']5163 print data[name]['variables']5164 3964 # add variables to list as they appear 5165 3965 for j,var in enumerate(data[name]['varyList']): … … 5167 3967 combinedVaryList.append(data[name]['varyList'][j]) 5168 3968 firstValueList.append(data[name]['variables'][j]) 3969 vallookup[name] = dict(zip(data[name]['varyList'],data[name]['variables'])) 3970 posdict[name] = {} 3971 for lbl in data[name]['varyList']: 3972 posdict[name][combinedVaryList.index(lbl)] = lbl 5169 3973 prevVaryList = sorted(data[name]['varyList']) 5170 VaryListChanges += [name] 3974 VaryListChanges.append(name) 3975 if len(VaryListChanges) > 1: 3976 G2frame.dataFrame.SequentialFile.Enable(wxID_ORGSEQSEL,True) 3977 else: 3978 G2frame.dataFrame.SequentialFile.Enable(wxID_ORGSEQSEL,False) 5171 3979 #----------------------------------------------------------------------------------- 5172 3980 # build up the data table by columns ----------------------------------------------- … … 5231 4039 colList += zip(*cells) 5232 4040 colSigs += zip(*cellESDs) 4041 # sort out the variables in their selected order 4042 varcols = 0 4043 for d in posdict.itervalues(): 4044 varcols = max(varcols,max(d.keys())+1) 4045 # get labels for each column 4046 for i in range(varcols): 4047 lbl = '' 4048 for h in VaryListChanges: 4049 if posdict[h].get(i): 4050 if posdict[h].get(i) in lbl: continue 4051 if lbl != "": lbl += '/' 4052 lbl += posdict[h].get(i) 4053 colLabels.append(lbl) 4054 Types += varcols*[wg.GRID_VALUE_FLOAT] 4055 vals = [] 4056 esds = [] 4057 varsellist = None # will be a list of variable names in the order they are selected to appear 4058 # tabulate values for each hist, leaving None for blank columns 4059 for name in histNames: 4060 if name in posdict: 4061 varsellist = [posdict[name].get(i) for i in range(varcols)] 4062 sellist = [data[name]['varyList'].index(v) if v is not None else None for v in varsellist] 4063 if not varsellist: raise Exception() 4064 vals.append([data[name]['variables'][s] if s is not None else None for s in sellist]) 4065 esds.append([data[name]['sig'][s] if s is not None else None for s in sellist]) 4066 colList += zip(*vals) 4067 colSigs += zip(*esds) 5233 4068 # add the variables that were refined; change from rows to columns 5234 4069 #colList += zip(*[data[name]['variables'] for name in histNames]) … … 5236 4071 #Types += len(data[histNames[0]]['varyList'])*[wg.GRID_VALUE_FLOAT] 5237 4072 #colSigs += zip(*[data[name]['sig'] for name in histNames]) 5238 for var in combinedVaryList: 5239 colLabels += [var] 5240 Types += [wg.GRID_VALUE_FLOAT] 5241 vals = [] 5242 sigs = [] 5243 for name in histNames: 5244 try: 5245 i = data[name]['varyList'].index(var) 5246 vals.append(data[name]['variables'][i]) 5247 sigs.append(data[name]['sig'][i]) 5248 except ValueError: # var not in list 5249 vals.append(None) 5250 sigs.append(None) 5251 colList += [vals] 5252 colSigs += [sigs] 4073 4074 # for var in combinedVaryList: 4075 # colLabels += [var] 4076 # Types += [wg.GRID_VALUE_FLOAT] 4077 # vals = [] 4078 # sigs = [] 4079 # for name in histNames: 4080 # try: 4081 # i = data[name]['varyList'].index(var) 4082 # vals.append(data[name]['variables'][i]) 4083 # sigs.append(data[name]['sig'][i]) 4084 # except ValueError: # var not in list 4085 # vals.append(None) 4086 # sigs.append(None) 4087 # colList += [vals] 4088 # colSigs += [sigs] 5253 4089 5254 4090 # tabulate constrained variables, removing histogram numbers if needed … … 5398 4234 dictlst = [inp] * len(inp) 5399 4235 elemlst = range(len(inp)) 5400 dlg = ScrolledMultiEditor(4236 dlg = G2G.ScrolledMultiEditor( 5401 4237 G2frame,[inp] * len(inp), range(len(inp)), names, 5402 4238 header='Edit simulation range', … … 5907 4743 print 70*'*' 5908 4744 5909 if __name__ == '__main__':5910 app = wx.PySimpleApp()5911 frm = wx.Frame(None) # create a frame5912 frm.Show(True)5913 5914 #======================================================================5915 # test ScrolledMultiEditor5916 #======================================================================5917 # Data1 = {5918 # 'Order':1,5919 # 'omega':'string',5920 # 'chi':2.0,5921 # 'phi':'',5922 # }5923 # elemlst = sorted(Data1.keys())5924 # prelbl = sorted(Data1.keys())5925 # dictlst = len(elemlst)*[Data1,]5926 #Data2 = [True,False,False,True]5927 #Checkdictlst = len(Data2)*[Data2,]5928 #Checkelemlst = range(len(Checkdictlst))5929 # print 'before',Data1,'\n',Data25930 # dlg = ScrolledMultiEditor(5931 # frm,dictlst,elemlst,prelbl,5932 # checkdictlst=Checkdictlst,checkelemlst=Checkelemlst,5933 # checklabel="Refine?",5934 # header="test")5935 # if dlg.ShowModal() == wx.ID_OK:5936 # print "OK"5937 # else:5938 # print "Cancel"5939 # print 'after',Data1,'\n',Data25940 # dlg.Destroy()5941 Data3 = {5942 'Order':1.0,5943 'omega':1.1,5944 'chi':2.0,5945 'phi':2.3,5946 'Order1':1.0,5947 'omega1':1.1,5948 'chi1':2.0,5949 'phi1':2.3,5950 'Order2':1.0,5951 'omega2':1.1,5952 'chi2':2.0,5953 'phi2':2.3,5954 }5955 elemlst = sorted(Data3.keys())5956 dictlst = len(elemlst)*[Data3,]5957 prelbl = elemlst[:]5958 prelbl[0]="this is a much longer label to stretch things out"5959 Data2 = len(elemlst)*[False,]5960 Data2[1] = Data2[3] = True5961 Checkdictlst = len(elemlst)*[Data2,]5962 Checkelemlst = range(len(Checkdictlst))5963 #print 'before',Data3,'\n',Data25964 #print dictlst,"\n",elemlst5965 #print Checkdictlst,"\n",Checkelemlst5966 dlg = ScrolledMultiEditor(5967 frm,dictlst,elemlst,prelbl,5968 checkdictlst=Checkdictlst,checkelemlst=Checkelemlst,5969 checklabel="Refine?",5970 header="test",CopyButton=True)5971 if dlg.ShowModal() == wx.ID_OK:5972 print "OK"5973 else:5974 print "Cancel"5975 #print 'after',Data3,'\n',Data25976 5977 # Data2 = list(range(100))5978 # elemlst += range(2,6)5979 # postlbl += range(2,6)5980 # dictlst += len(range(2,6))*[Data2,]5981 5982 # prelbl = range(len(elemlst))5983 # postlbl[1] = "a very long label for the 2nd item to force a horiz. scrollbar"5984 # header="""This is a longer\nmultiline and perhaps silly header"""5985 # dlg = ScrolledMultiEditor(frm,dictlst,elemlst,prelbl,postlbl,5986 # header=header,CopyButton=True)5987 # print Data15988 # if dlg.ShowModal() == wx.ID_OK:5989 # for d,k in zip(dictlst,elemlst):5990 # print k,d[k]5991 # dlg.Destroy()5992 # if CallScrolledMultiEditor(frm,dictlst,elemlst,prelbl,postlbl,5993 # header=header):5994 # for d,k in zip(dictlst,elemlst):5995 # print k,d[k]5996 5997 #======================================================================5998 # test G2MultiChoiceDialog5999 #======================================================================6000 # choices = []6001 # for i in range(21):6002 # choices.append("option_"+str(i))6003 # dlg = G2MultiChoiceDialog(frm, 'Sequential refinement',6004 # 'Select dataset to include',6005 # choices)6006 # sel = range(2,11,2)6007 # dlg.SetSelections(sel)6008 # dlg.SetSelections((1,5))6009 # if dlg.ShowModal() == wx.ID_OK:6010 # for sel in dlg.GetSelections():6011 # print sel,choices[sel]6012 6013 #======================================================================6014 # test wx.MultiChoiceDialog6015 #======================================================================6016 # dlg = wx.MultiChoiceDialog(frm, 'Sequential refinement',6017 # 'Select dataset to include',6018 # choices)6019 # sel = range(2,11,2)6020 # dlg.SetSelections(sel)6021 # dlg.SetSelections((1,5))6022 # if dlg.ShowModal() == wx.ID_OK:6023 # for sel in dlg.GetSelections():6024 # print sel,choices[sel]6025 6026 pnl = wx.Panel(frm)6027 siz = wx.BoxSizer(wx.VERTICAL)6028 6029 td = {'Goni':200.,'a':1.,'calc':1./3.,'string':'s'}6030 for key in sorted(td):6031 txt = ValidatedTxtCtrl(pnl,td,key)6032 siz.Add(txt)6033 pnl.SetSizer(siz)6034 siz.Fit(frm)6035 app.MainLoop()6036 print td -
trunk/GSASIIimgGUI.py
r1583 r1619 29 29 import GSASIIIO as G2IO 30 30 import GSASIIgrid as G2gd 31 import GSASIIctrls as G2G 31 32 import numpy as np 32 33 … … 1227 1228 Text.SetBackgroundColour(VERY_LIGHT_GREY) 1228 1229 littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Lower/Upper thresholds '),0,WACV) 1229 lowerThreshold = G2 gd.ValidatedTxtCtrl(G2frame.dataDisplay,loc=thresh[1],key=0,1230 lowerThreshold = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,loc=thresh[1],key=0, 1230 1231 min=thresh[0][0],OnLeave=Replot,typeHint=int) 1231 1232 littleSizer.Add(lowerThreshold,0,WACV) 1232 upperThreshold = G2 gd.ValidatedTxtCtrl(G2frame.dataDisplay,loc=thresh[1],key=1,1233 upperThreshold = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,loc=thresh[1],key=1, 1233 1234 max=thresh[0][1],OnLeave=Replot,typeHint=int) 1234 1235 littleSizer.Add(upperThreshold,0,WACV) … … 1250 1251 littleSizer.Add(spotText,0,WACV) 1251 1252 spotText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg) 1252 spotDiameter = G2 gd.ValidatedTxtCtrl(G2frame.dataDisplay,loc=Spots[i],key=2,1253 spotDiameter = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,loc=Spots[i],key=2, 1253 1254 max=100.,OnLeave=Replot,nDig=[8,2]) 1254 1255 littleSizer.Add(spotDiameter,0,WACV) … … 1273 1274 ringText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg) 1274 1275 littleSizer.Add(ringText,0,WACV) 1275 ringThick = G2 gd.ValidatedTxtCtrl(G2frame.dataDisplay,loc=Rings[i],key=1,1276 ringThick = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,loc=Rings[i],key=1, 1276 1277 min=0.001,max=1.,OnLeave=Replot,nDig=[8,3]) 1277 1278 littleSizer.Add(ringThick,0,WACV) … … 1303 1304 azmText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg) 1304 1305 littleSizer.Add(azmText,0,WACV) 1305 arcThick = G2 gd.ValidatedTxtCtrl(G2frame.dataDisplay,loc=Arcs[i],key=2,1306 arcThick = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,loc=Arcs[i],key=2, 1306 1307 min=0.001,max=20.,OnLeave=Replot,nDig=[8,3]) 1307 1308 littleSizer.Add(arcThick,0,WACV) … … 1658 1659 samZ.Bind(wx.EVT_KILL_FOCUS,OnSamZ) 1659 1660 samSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=' Sample load(MPa): '),0,WACV) 1660 samLoad = G2 gd.ValidatedTxtCtrl(G2frame.dataDisplay,data,'Sample load',1661 samLoad = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,data,'Sample load', 1661 1662 nDig=[8,3],typeHint=float,) 1662 1663 samSizer.Add(samLoad,0,WACV) -
trunk/GSASIIplot.py
r1618 r1619 3135 3135 Xnew.append(X[i]) 3136 3136 Ynew.append(Y[i]) 3137 Ysnew.append(sig[i])3137 if sig: Ysnew.append(sig[i]) 3138 3138 if Ysnew: 3139 3139 if G2frame.seqReverse and not G2frame.seqXaxis: -
trunk/GSASIIpwdGUI.py
r1618 r1619 38 38 import GSASIIplot as G2plt 39 39 import GSASIIgrid as G2gd 40 import GSASIIctrls as G2G 40 41 import GSASIIElemGUI as G2elemGUI 41 42 import GSASIIElem as G2elem … … 1239 1240 ''' 1240 1241 updateData(insVal,insRef) 1241 G2 gd.SelectEdit1Var(G2frame,data,labelLst,elemKeysLst,dspLst,refFlgElem)1242 G2G.SelectEdit1Var(G2frame,data,labelLst,elemKeysLst,dspLst,refFlgElem) 1242 1243 insVal.update({key:data[key][1] for key in instkeys}) 1243 1244 insRef.update({key:data[key][2] for key in instkeys}) … … 1315 1316 dspLst.append([10,4]) 1316 1317 refFlgElem.append([key,2]) 1317 ratVal = G2 gd.ValidatedTxtCtrl(G2frame.dataDisplay,insVal,key,nDig=(10,4),typeHint=float,OnLeave=AfterChange)1318 ratVal = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,insVal,key,nDig=(10,4),typeHint=float,OnLeave=AfterChange) 1318 1319 instSizer.Add(ratVal,0) 1319 1320 instSizer.Add(RefineBox(key),0,WACV) … … 1329 1330 instSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,u' Lam (\xc5): (%10.6f)'%(insDef[key])), 1330 1331 0,WACV) 1331 waveVal = G2 gd.ValidatedTxtCtrl(G2frame.dataDisplay,insVal,key,nDig=(10,6),typeHint=float,OnLeave=AfterChange)1332 waveVal = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,insVal,key,nDig=(10,6),typeHint=float,OnLeave=AfterChange) 1332 1333 labelLst.append(u'Lam (\xc5)') 1333 1334 elemKeysLst.append([key,1]) … … 1350 1351 wx.StaticText(G2frame.dataDisplay,-1,lblWdef(item,4,insDef[item])), 1351 1352 0,WACV) 1352 itemVal = G2 gd.ValidatedTxtCtrl(G2frame.dataDisplay,insVal,item,nDig=(10,4),typeHint=float,OnLeave=AfterChange)1353 itemVal = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,insVal,item,nDig=(10,4),typeHint=float,OnLeave=AfterChange) 1353 1354 instSizer.Add(itemVal,0,WACV) 1354 1355 refFlgElem.append([item,2]) … … 1380 1381 wx.StaticText(G2frame.dataDisplay,-1,lblWdef(item,nDig[1],insDef[item])), 1381 1382 0,WACV) 1382 itemVal = G2 gd.ValidatedTxtCtrl(G2frame.dataDisplay,insVal,item,nDig=nDig,typeHint=float,OnLeave=AfterChange)1383 itemVal = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,insVal,item,nDig=nDig,typeHint=float,OnLeave=AfterChange) 1383 1384 instSizer.Add(itemVal,0,WACV) 1384 1385 instSizer.Add(RefineBox(item),0,WACV) … … 1429 1430 wx.StaticText(G2frame.dataDisplay,-1,lblWdef(item,nDig[1],insDef[item])), 1430 1431 0,WACV) 1431 itemVal = G2 gd.ValidatedTxtCtrl(G2frame.dataDisplay,insVal,item,nDig=nDig,typeHint=float,OnLeave=AfterChange)1432 itemVal = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,insVal,item,nDig=nDig,typeHint=float,OnLeave=AfterChange) 1432 1433 instSizer.Add(itemVal,0,WACV) 1433 1434 labelLst.append(item) … … 1440 1441 instSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,u' Lam (\xc5): (%10.6f)'%(insDef['Lam'])), 1441 1442 0,WACV) 1442 waveVal = G2 gd.ValidatedTxtCtrl(G2frame.dataDisplay,insVal,'Lam',nDig=(10,6),typeHint=float,OnLeave=AfterChange)1443 waveVal = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,insVal,'Lam',nDig=(10,6),typeHint=float,OnLeave=AfterChange) 1443 1444 instSizer.Add(waveVal,0,WACV) 1444 1445 labelLst.append(u'Lam (\xc5)') … … 1452 1453 instSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,u' Lam (\xc5): (%10.6f)'%(insDef['Lam'])), 1453 1454 0,WACV) 1454 waveVal = G2 gd.ValidatedTxtCtrl(G2frame.dataDisplay,insVal,'Lam',nDig=(10,6),typeHint=float,OnLeave=AfterChange)1455 waveVal = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,insVal,'Lam',nDig=(10,6),typeHint=float,OnLeave=AfterChange) 1455 1456 instSizer.Add(waveVal,0,WACV) 1456 1457 labelLst.append(u'Lam (\xc5)') … … 1847 1848 def OnCopy1Val(event): 1848 1849 'Select one value to copy to many histograms and optionally allow values to be edited in a table' 1849 G2 gd.SelectEdit1Var(G2frame,data,labelLst,elemKeysLst,dspLst,refFlgElem)1850 G2G.SelectEdit1Var(G2frame,data,labelLst,elemKeysLst,dspLst,refFlgElem) 1850 1851 wx.CallAfter(UpdateSampleGrid,G2frame,data) 1851 1852 … … 1956 1957 dspLst.append(nDig) 1957 1958 if 'list' in str(type(data[key])): 1958 parmRef = G2 gd.G2CheckBox(G2frame.dataDisplay,' '+lbl,data[key],1)1959 parmRef = G2G.G2CheckBox(G2frame.dataDisplay,' '+lbl,data[key],1) 1959 1960 parmSizer.Add(parmRef,0,WACV|wx.EXPAND) 1960 parmVal = G2 gd.ValidatedTxtCtrl(G2frame.dataDisplay,data[key],0,1961 parmVal = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,data[key],0, 1961 1962 nDig=nDig,typeHint=float,OnLeave=AfterChange) 1962 1963 elemKeysLst.append([key,0]) … … 1965 1966 parmSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' '+lbl), 1966 1967 0,WACV|wx.EXPAND) 1967 parmVal = G2 gd.ValidatedTxtCtrl(G2frame.dataDisplay,data,key,1968 parmVal = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,data,key, 1968 1969 typeHint=float,OnLeave=AfterChange) 1969 1970 elemKeysLst.append([key]) … … 1973 1974 1974 1975 for key in ('FreePrm1','FreePrm2','FreePrm3'): 1975 parmVal = G2 gd.ValidatedTxtCtrl(G2frame.dataDisplay,Controls,key,typeHint=str,1976 parmVal = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,Controls,key,typeHint=str, 1976 1977 notBlank=False) 1977 1978 parmSizer.Add(parmVal,1,wx.EXPAND) 1978 parmVal = G2 gd.ValidatedTxtCtrl(G2frame.dataDisplay,data,key,typeHint=float)1979 parmVal = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,data,key,typeHint=float) 1979 1980 parmSizer.Add(parmVal,1,wx.EXPAND) 1980 1981 labelLst.append(Controls[key]) … … 3787 3788 sizeSizer.Add(nRadii,0,WACV) 3788 3789 sizeSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' R dist. cutoff: '),0,WACV) 3789 rCutoff = G2 gd.ValidatedTxtCtrl(G2frame.dataDisplay,level['Controls'],'Cutoff',3790 rCutoff = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,level['Controls'],'Cutoff', 3790 3791 min=0.001,max=0.1,typeHint=float) 3791 3792 sizeSizer.Add(rCutoff,0,WACV) … … 3883 3884 topSizer.Add(matsel,0,WACV) 3884 3885 topSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Volume fraction: '),0,WACV) 3885 volfrac = G2 gd.ValidatedTxtCtrl(G2frame.dataDisplay,data['Particle']['Matrix']['VolFrac'],0,3886 volfrac = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,data['Particle']['Matrix']['VolFrac'],0, 3886 3887 typeHint=float) 3887 3888 topSizer.Add(volfrac,0,WACV)
Note: See TracChangeset
for help on using the changeset viewer.