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