Package gui :: Package spin_viewer :: Module containers
[hide private]
[frames] | no frames]

Source Code for Module gui.spin_viewer.containers

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2010-2012 Edward d'Auvergne                                   # 
  4  #                                                                             # 
  5  # This file is part of the program relax (http://www.nmr-relax.com).          # 
  6  #                                                                             # 
  7  # This program is free software: you can redistribute it and/or modify        # 
  8  # it under the terms of the GNU General Public License as published by        # 
  9  # the Free Software Foundation, either version 3 of the License, or           # 
 10  # (at your option) any later version.                                         # 
 11  #                                                                             # 
 12  # This program is distributed in the hope that it will be useful,             # 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 15  # GNU General Public License for more details.                                # 
 16  #                                                                             # 
 17  # You should have received a copy of the GNU General Public License           # 
 18  # along with this program.  If not, see <http://www.gnu.org/licenses/>.       # 
 19  #                                                                             # 
 20  ############################################################################### 
 21   
 22  # Module docstring. 
 23  """The molecule, residue, and spin containers for the spin viewer.""" 
 24   
 25   
 26  # Python module imports. 
 27  from re import search 
 28  import wx 
 29   
 30  # relax module imports. 
 31  from generic_fns.mol_res_spin import return_spin 
 32   
 33  # GUI module imports. 
 34  from gui import paths 
 35  from gui.misc import bitmap_setup 
 36  from gui.string_conv import str_to_gui 
 37   
 38   
 39   
40 -class Container(wx.Window):
41 """The molecule, residue, and spin container window.""" 42
43 - def __init__(self, gui, parent=None, id=None):
44 """Set up the container GUI element. 45 46 @param gui: The gui object. 47 @type gui: wx object 48 @keyword parent: The parent GUI element that this is to be attached to. 49 @type parent: wx object 50 @keyword id: The ID number. 51 @type id: int 52 """ 53 54 # Store the args. 55 self.gui = gui 56 57 # Execute the base class method. 58 wx.Window.__init__(self, parent, id, style=wx.BORDER_SUNKEN) 59 60 # Set a minimum size for the window. 61 self.SetMinSize((500, 500)) 62 63 # Add a sizer. 64 self.main_sizer = wx.BoxSizer(wx.VERTICAL) 65 self.SetSizer(self.main_sizer) 66 67 # Display the root panel. 68 self.container = Root(self.main_sizer, self) 69 70 # Resizing. 71 self.Bind(wx.EVT_SIZE, self._resize)
72 73
74 - def _resize(self, event):
75 """Resize the tree element. 76 77 @param event: The wx event. 78 @type event: wx event 79 """ 80 81 # Re-perform the window layout. 82 self.Layout() 83 self.Refresh()
84 85
86 - def display(self, info):
87 """Display the info for the selected container. 88 89 @param info: The information list consisting of the container type ('root', 'mol', 'res', or 'spin'), the molecule name, the residue number, the residue name, the spin number, and the spin name. The name and number information is dropped when not needed. 90 @type info: list of str and int 91 """ 92 93 # Destroy all the original contents. 94 self.main_sizer.Clear(deleteWindows=True) 95 96 # The root window display. 97 if info == 'root' or info == None: 98 self.container = Root(self.main_sizer, self) 99 100 # The molecule container display. 101 elif info['type'] == 'mol': 102 self.container = Molecule(self.main_sizer, self, mol_name=info['mol_name'], mol_id=info['id'], select=info['select']) 103 104 # The residue container display. 105 elif info['type'] == 'res': 106 self.container = Residue(self.main_sizer, self, mol_name=info['mol_name'], res_num=info['res_num'], res_name=info['res_name'], res_id=info['id'], select=info['select']) 107 108 # The spin container display. 109 elif info['type'] == 'spin': 110 self.container = Spin(self.main_sizer, self, mol_name=info['mol_name'], res_num=info['res_num'], res_name=info['res_name'], spin_num=info['spin_num'], spin_name=info['spin_name'], spin_id=info['id'], select=info['select']) 111 112 # Re-perform the window layout. 113 self.Layout() 114 self.Refresh()
115 116 117
118 -class Container_base:
119 """The base class for the molecule, residue, and spin containers.""" 120 121 # Some class variables. 122 border = 10 123
124 - def create_head_text(self, text):
125 """Generate the wx.StaticText object for header text. 126 127 @param text: The text of the subtitle. 128 @type text: str 129 @return: The subtitle object. 130 @rtype: wx.StaticText instance 131 """ 132 133 # Unicode. 134 text = unicode(text) 135 136 # Fix for the '&' character. 137 text = text.replace('&', '&&') 138 139 # The object. 140 obj = wx.StaticText(self.parent, -1, text) 141 142 # Formatting. 143 obj.SetFont(wx.Font(pointSize=12, family=wx.FONTFAMILY_ROMAN, style=wx.ITALIC, weight=wx.NORMAL, face='Times')) 144 145 # Return the object. 146 return obj
147 148
149 - def create_subtitle(self, text):
150 """Generate the subtitle wx.StaticText object. 151 152 @param text: The text of the subtitle. 153 @type text: str 154 @return: The subtitle object. 155 @rtype: wx.StaticText instance 156 """ 157 158 # Unicode. 159 text = unicode(text) 160 161 # Fix for the '&' character. 162 text = text.replace('&', '&&') 163 164 # The object. 165 obj = wx.StaticText(self.parent, -1, text) 166 167 # Formatting. 168 obj.SetFont(wx.Font(pointSize=16, family=wx.FONTFAMILY_ROMAN, style=wx.ITALIC, weight=wx.NORMAL, face='Times')) 169 170 # Return the object. 171 return obj
172 173
174 - def create_title(self, text):
175 """Generate the title wx.StaticText object. 176 177 @param text: The text of the subtitle. 178 @type text: str 179 @return: The subtitle object. 180 @rtype: wx.StaticText instance 181 """ 182 183 # The object. 184 title = wx.StaticText(self.parent, -1, text) 185 186 # Formatting. 187 title.SetFont(wx.Font(pointSize=32, family=wx.FONTFAMILY_ROMAN, style=wx.ITALIC, weight=wx.NORMAL, face='Times')) 188 189 # Return the object. 190 return title
191 192 193
194 -class Molecule(Container_base):
195 """The molecule container.""" 196
197 - def __init__(self, box, parent, mol_name=None, mol_id=None, select=True):
198 """Set up the molecule container. 199 200 @param box: The box sizer element to pack the contents into. 201 @type box: wx object 202 @param parent: The parent GUI element. 203 @type parent: wx object 204 @keyword mol_name: The name of the molecule. 205 @type mol_name: str 206 @keyword mol_id: The molecule ID string. 207 @type mol_id: str 208 @keyword select: The selection state. 209 @type select: bool 210 """ 211 212 # Store the args. 213 self.parent = parent 214 self.mol_name = mol_name 215 self.mol_id = mol_id 216 self.select = select 217 218 # Create the header. 219 sizer = self.header_molecule() 220 221 # Add to the sizer. 222 box.Add(sizer, 0, wx.ALL|wx.EXPAND, border=self.border) 223 224 # A divider. 225 line = wx.StaticLine(self.parent, -1, (25, 50)) 226 box.Add(line, 0, wx.EXPAND|wx.ALL, border=self.border)
227 228
229 - def header_molecule(self):
230 """Create the header for the molecule container. 231 232 @return: The sizer containing the header. 233 @rtype: wx.Sizer instance 234 """ 235 236 # A sizer for the header. 237 sizer = wx.BoxSizer(wx.HORIZONTAL) 238 239 # A sizer for the text component of the header. 240 text_sizer = wx.BoxSizer(wx.VERTICAL) 241 242 # The title 243 title = self.create_title("Molecule container") 244 text_sizer.Add(title, 0, wx.LEFT, 0) 245 246 # Spacer. 247 text_sizer.AddSpacer(30) 248 249 # The info grid. 250 grid_sizer = wx.FlexGridSizer(2, 2, 5, 50) 251 grid_sizer.Add(self.create_head_text("Molecule:"), 0, wx.ADJUST_MINSIZE, 0) 252 grid_sizer.Add(self.create_head_text(self.mol_name), 0, wx.ADJUST_MINSIZE, 0) 253 grid_sizer.Add(self.create_head_text("Molecule ID string:"), 0, wx.ADJUST_MINSIZE, 0) 254 grid_sizer.Add(self.create_head_text("'%s'" % self.mol_id), 0, wx.ADJUST_MINSIZE, 0) 255 text_sizer.Add(grid_sizer, 0, wx.LEFT, 0) 256 257 # Add the text sizer to the main header sizer. 258 sizer.Add(text_sizer, 1, wx.ALL|wx.EXPAND, 0) 259 260 # Stretch spacer. 261 sizer.AddStretchSpacer() 262 263 # The graphic. 264 if self.select: 265 path = paths.WIZARD_IMAGE_PATH + 'molecule.png' 266 else: 267 path = paths.WIZARD_IMAGE_PATH + 'molecule_grey.png' 268 image = wx.StaticBitmap(self.parent, -1, bitmap_setup(path)) 269 sizer.Add(image, 0, wx.RIGHT, 0) 270 271 # Return the sizer. 272 return sizer
273 274 275
276 -class Residue(Container_base):
277 """The residue container.""" 278
279 - def __init__(self, box, parent, mol_name=None, res_num=None, res_name=None, res_id=None, select=True):
280 """Set up the residue container. 281 282 @param box: The box sizer element to pack the contents into. 283 @type box: wx object 284 @param parent: The parent GUI element. 285 @type parent: wx object 286 @keyword mol_name: The molecule name. 287 @type mol_name: str 288 @keyword res_num: The residue number. 289 @type res_num: str 290 @keyword res_name: The residue name. 291 @type res_name: str 292 @keyword res_id: The residue ID string. 293 @type res_id: str 294 @keyword select: The selection state. 295 @type select: bool 296 """ 297 298 # Store the args. 299 self.parent = parent 300 self.mol_name = mol_name 301 self.res_num = res_num 302 self.res_name = res_name 303 self.res_id = res_id 304 self.select = select 305 306 # Create the header. 307 sizer = self.header_residue() 308 309 # Add to the main sizer. 310 box.Add(sizer, 0, wx.ALL|wx.EXPAND, border=self.border) 311 312 # A divider. 313 line = wx.StaticLine(self.parent, -1, (25, 50)) 314 box.Add(line, 0, wx.EXPAND|wx.ALL, border=self.border)
315 316
317 - def header_residue(self):
318 """Create the header for the residue container. 319 320 @return: The sizer containing the header. 321 @rtype: wx.Sizer instance 322 """ 323 324 # A sizer for the header. 325 sizer = wx.BoxSizer(wx.HORIZONTAL) 326 327 # A sizer for the text component of the header. 328 text_sizer = wx.BoxSizer(wx.VERTICAL) 329 330 # The title 331 title = self.create_title("Residue container") 332 text_sizer.Add(title, 0, wx.LEFT, 0) 333 334 # Spacer. 335 text_sizer.AddSpacer(30) 336 337 # The info grid. 338 grid_sizer = wx.FlexGridSizer(4, 2, 5, 50) 339 grid_sizer.Add(self.create_head_text("Molecule:"), 0, wx.ADJUST_MINSIZE, 0) 340 grid_sizer.Add(self.create_head_text(self.mol_name), 0, wx.ADJUST_MINSIZE, 0) 341 grid_sizer.Add(self.create_head_text("Residue number:"), 0, wx.ADJUST_MINSIZE, 0) 342 grid_sizer.Add(self.create_head_text(self.res_num), 0, wx.ADJUST_MINSIZE, 0) 343 grid_sizer.Add(self.create_head_text("Residue name:"), 0, wx.ADJUST_MINSIZE, 0) 344 grid_sizer.Add(self.create_head_text(self.res_name), 0, wx.ADJUST_MINSIZE, 0) 345 grid_sizer.Add(self.create_head_text("Residue ID string:"), 0, wx.ADJUST_MINSIZE, 0) 346 grid_sizer.Add(self.create_head_text("'%s'" % self.res_id), 0, wx.ADJUST_MINSIZE, 0) 347 text_sizer.Add(grid_sizer, 0, wx.LEFT, 0) 348 349 # Add the text sizer to the main header sizer. 350 sizer.Add(text_sizer, 1, wx.ALL|wx.EXPAND, 0) 351 352 # Stretch spacer. 353 sizer.AddStretchSpacer() 354 355 # The graphic. 356 if self.select: 357 path = paths.WIZARD_IMAGE_PATH + 'residue.png' 358 else: 359 path = paths.WIZARD_IMAGE_PATH + 'residue_grey.png' 360 image = wx.StaticBitmap(self.parent, -1, bitmap_setup(path)) 361 sizer.Add(image, 0, wx.RIGHT, 0) 362 363 # Return the sizer. 364 return sizer
365 366 367
368 -class Spin(Container_base):
369 """The spin container.""" 370
371 - def __init__(self, box, parent, mol_name=None, res_num=None, res_name=None, spin_num=None, spin_name=None, spin_id=None, select=True):
372 """Set up the spin container. 373 374 @param box: The box sizer element to pack the contents into. 375 @type box: wx object 376 @param parent: The parent GUI element. 377 @type parent: wx object 378 @keyword mol_name: The molecule name. 379 @type mol_name: str 380 @keyword res_num: The residue number. 381 @type res_num: str 382 @keyword res_name: The residue name. 383 @type res_name: str 384 @keyword spin_num: The spin number. 385 @type spin_num: str 386 @keyword spin_name: The spin name. 387 @type spin_name: str 388 @keyword spin_id: The spin ID string. 389 @type spin_id: str 390 @keyword select: The selection state. 391 @type select: bool 392 """ 393 394 # Store the args. 395 self.parent = parent 396 self.mol_name = mol_name 397 self.res_num = res_num 398 self.res_name = res_name 399 self.spin_num = spin_num 400 self.spin_name = spin_name 401 self.spin_id = spin_id 402 self.select = select 403 404 # Create the header. 405 sizer = self.header_spin() 406 407 # Add to the main sizer. 408 box.Add(sizer, 0, wx.ALL|wx.EXPAND, border=self.border) 409 410 # A divider. 411 line = wx.StaticLine(self.parent, -1, (25, 50)) 412 box.Add(line, 0, wx.EXPAND|wx.ALL, border=self.border) 413 414 # The spin container variables. 415 sizer2 = self.spin_vars() 416 box.Add(sizer2, 1, wx.ALL|wx.EXPAND, border=self.border)
417 418
419 - def header_spin(self):
420 """Create the header for the spin container. 421 422 @return: The sizer containing the header. 423 @rtype: wx.Sizer instance 424 """ 425 426 # A sizer for the header. 427 sizer = wx.BoxSizer(wx.HORIZONTAL) 428 429 # A sizer for the text component of the header. 430 text_sizer = wx.BoxSizer(wx.VERTICAL) 431 432 # The title 433 title = self.create_title("Spin container") 434 text_sizer.Add(title, 0, wx.LEFT, 0) 435 436 # Spacer. 437 text_sizer.AddSpacer(30) 438 439 # The info grid. 440 grid_sizer = wx.FlexGridSizer(6, 2, 5, 50) 441 grid_sizer.Add(self.create_head_text("Molecule:"), 0, wx.ADJUST_MINSIZE, 0) 442 grid_sizer.Add(self.create_head_text(self.mol_name), 0, wx.ADJUST_MINSIZE, 0) 443 grid_sizer.Add(self.create_head_text("Residue number:"), 0, wx.ADJUST_MINSIZE, 0) 444 grid_sizer.Add(self.create_head_text(self.res_num), 0, wx.ADJUST_MINSIZE, 0) 445 grid_sizer.Add(self.create_head_text("Residue name:"), 0, wx.ADJUST_MINSIZE, 0) 446 grid_sizer.Add(self.create_head_text(self.res_name), 0, wx.ADJUST_MINSIZE, 0) 447 grid_sizer.Add(self.create_head_text("Spin number:"), 0, wx.ADJUST_MINSIZE, 0) 448 grid_sizer.Add(self.create_head_text(self.spin_num), 0, wx.ADJUST_MINSIZE, 0) 449 grid_sizer.Add(self.create_head_text("Spin name:"), 0, wx.ADJUST_MINSIZE, 0) 450 grid_sizer.Add(self.create_head_text(self.spin_name), 0, wx.ADJUST_MINSIZE, 0) 451 grid_sizer.Add(self.create_head_text("Spin ID string:"), 0, wx.ADJUST_MINSIZE, 0) 452 grid_sizer.Add(self.create_head_text("'%s'" % self.spin_id), 0, wx.ADJUST_MINSIZE, 0) 453 text_sizer.Add(grid_sizer, 0, wx.LEFT, 0) 454 455 # Add the text sizer to the main header sizer. 456 sizer.Add(text_sizer, 1, wx.ALL|wx.EXPAND, 0) 457 458 # Stretch spacer. 459 sizer.AddStretchSpacer() 460 461 # The graphic. 462 if self.select: 463 path = paths.WIZARD_IMAGE_PATH + 'spin.png' 464 else: 465 path = paths.WIZARD_IMAGE_PATH + 'spin_grey.png' 466 image = wx.StaticBitmap(self.parent, -1, bitmap_setup(path)) 467 sizer.Add(image, 0, wx.RIGHT, 0) 468 469 # Return the sizer. 470 return sizer
471 472
473 - def spin_vars(self, blacklist=[]):
474 """Create the variable table for the spin container. 475 476 @keyword blacklist: A list of spin container objects to blacklist from the variable display table. 477 @type blacklist: list of str 478 @return: The sizer containing the table. 479 @rtype: wx.Sizer instance 480 """ 481 482 # A sizer for the table. 483 sizer = wx.BoxSizer(wx.VERTICAL) 484 485 # The title 486 title = self.create_subtitle("Spin container contents") 487 sizer.Add(title, 0, wx.LEFT, 0) 488 489 # Add a spacer. 490 sizer.AddSpacer(20) 491 492 # The table. 493 table = wx.ListCtrl(self.parent, -1, style=wx.BORDER_SUNKEN|wx.LC_REPORT) 494 495 # The headers. 496 table.InsertColumn(0, "Variable") 497 table.InsertColumn(1, "Value") 498 table.InsertColumn(2, "Type") 499 500 # The widths. 501 table.SetColumnWidth(0, 300) 502 table.SetColumnWidth(1, 200) 503 table.SetColumnWidth(2, 200) 504 505 # The spin container. 506 spin = return_spin(self.spin_id) 507 508 # Add some names to the blacklist. 509 blacklist += ['is_empty'] 510 511 # Loop over the contents of the spin container. 512 for name in dir(spin): 513 # Skip special objects. 514 if search('^_', name): 515 continue 516 517 # Blacklisted names. 518 if name in blacklist: 519 continue 520 521 # Get the object. 522 obj = getattr(spin, name) 523 524 # The type. 525 obj_type = str(type(obj)).split("'")[1] 526 527 # List types. 528 if obj_type in ['list', 'numpy.ndarray'] and len(obj) > 1: 529 # The first row. 530 table.Append((str_to_gui(name), str_to_gui("[%s," % obj[0]), str_to_gui(obj_type))) 531 532 # The rest of the rows. 533 for i in range(1, len(obj)-1): 534 table.Append((str_to_gui(''), str_to_gui(" %s," % obj[i]), str_to_gui(''))) 535 536 # The last row. 537 table.Append((str_to_gui(''), str_to_gui(" %s]" % obj[-1]), str_to_gui(''))) 538 539 # Dictionary types. 540 elif obj_type == 'dict': 541 # The keys. 542 keys = sorted(obj.keys()) 543 544 # Single entry (or None). 545 if len(keys) < 2: 546 table.Append((str_to_gui(name), str_to_gui(obj), str_to_gui(obj_type))) 547 continue 548 549 # The first row. 550 table.Append((str_to_gui(name), str_to_gui("{'%s': %s," % (keys[0], obj[keys[0]])), str_to_gui(obj_type))) 551 552 # The rest of the rows. 553 for i in range(1, len(keys)-1): 554 table.Append((str_to_gui(''), str_to_gui(" '%s': %s," % (keys[i], obj[keys[i]])), str_to_gui(''))) 555 556 # The last row. 557 table.Append((str_to_gui(''), str_to_gui(" '%s': %s}" % (keys[-1], obj[keys[-1]])), str_to_gui(''))) 558 559 # All other data types. 560 else: 561 table.Append((str_to_gui(name), str_to_gui(obj), str_to_gui(obj_type))) 562 563 # Add the table to the sizer. 564 sizer.Add(table, 1, wx.ALL|wx.EXPAND, 0) 565 566 # Return the sizer. 567 return sizer
568 569 570
571 -class Root(Container_base):
572 """The root container.""" 573
574 - def __init__(self, box, parent):
575 """Set up the root container. 576 577 @param box: The box sizer element to pack the contents into. 578 @type box: wx object 579 @param parent: The parent GUI element. 580 @type parent: wx object 581 """ 582 583 # Store the arg. 584 self.parent = parent 585 586 # A sizer for the header. 587 sizer = wx.BoxSizer(wx.VERTICAL) 588 589 # The title 590 title = self.create_title("The spin view window") 591 sizer.Add(title, 0, wx.LEFT, 0) 592 593 # Add to the sizer. 594 box.Add(sizer, 0, wx.ALL|wx.EXPAND, border=self.border)
595