Esempio n. 1
0
class ColorWellDialog(ModelessDialog):

    title = 'Set Backbone Color'

    #    Need to override '__init__' to initialize our extra state.
    def __init__(self, *args, **kw):

	#    Whereas in the "Colors and Color Wells" example 'coloropt'
	#    was a local variable, here the 'coloropt' variable is stored
	#    in the instance because the trigger handler (which has access
	#    to the instance) needs to update the color well contained in
	#    the ColorOption.  A new variable, 'handlerId', is created to
	#    keep track of whether a handler is currently registered.  The
	#    handler is only created when needed.  See 'map' and 'unmap'
	#    below.  (Note that the instance variables must be set before
	#    calling the base __init__ method since the dialog may be mapped
	#    during initialization, depending on which window system is used.)
	#
	#    .. "Colors and Color Wells" Main_ColorWellUI.html
	self.colorOpt = None
	self.handlerId = None

	#    Call the parent-class '__init__'.
	apply(ModelessDialog.__init__, (self,) + args, kw)

    def fillInUI(self, master):
	#    Save ColorOption in instance.
	self.coloropt = ColorOption(master, 0, 'Backbone Color', None, self._setBackboneColor, balloon='Protein backbone color')

	self._updateBackboneColor()

    def _updateBackboneColor(self):
	for m in chimera.openModels.list(modelTypes=[chimera.Molecule]):
	    for a in m.atoms:
		if ColorWellUI.MAINCHAIN.match(a.name):
		    try:
			if a.color != theColor:
			    self.coloropt.setMultiple()
			    return
		    except NameError:
			theColor = a.color

	try:
	    self.coloropt.set(theColor)
	except NameError:
	    self.coloropt.set(None)

    def _setBackboneColor(self, coloroption):
	ColorWellUI.mainchain(coloroption.get())

    #    Register a trigger handler to monitor changes in the
    #    backbone atom list when we're make visible.  We ignore
    #    the event argument.
    def map(self, *ignore):
	#    Synchronize with well color.
        self._updateBackboneColor()

	#    If no handler is currently registered, register one.
	if self.handlerId is None:
	    #    Registration occurs when the 'chimera.triggers' object
	    #    is requested to add a handler. *Registration requires
	    #    three arguments*:
	    #      - the name of the trigger,
	    #      - the handler function to be invoked when the
	    #        trigger fires, and
	    #      - an additional argument to be passed to the handler
	    #        function when it is invoked.
	    #    In this case, the trigger name is the same as the name
	    #    of the class of objects being monitored, "Atom".
	    #    The handler function is '_handler', defined below.
	    #    And the additional argument is empty (None) -- it could
	    #    have been the ColorOption instance ('coloropt') but that
	    #    is accessible via the instance.  The return value from
	    #    the registration is a unique handler identifier for
	    #    the handler/argument combination.  This identifier is
	    #    required for deregistering the handler.
	    #
	    #    *The handler function is always invoked by the trigger
	    #    with three arguments*:
	    #      - the name of the trigger,
	    #      - the additional argument passed in at registration
	    #        time, and
	    #      - an instance with three attributes
	    #	    - created: set of created objects
	    #	    - deleted: set of deleted objects
	    #	    - modified: set of modified objects
	    #    Note that with a newly opened model, objects will just
	    #    appear in both the 'created' set and not in the 'modified'
	    #    set, even though the newly created objects will normally have
	    #    various of their default attributes modified by later
	    #    code sections.
	    self.handlerId = chimera.triggers.addHandler('Atom', self._handler, None)

    #    The '_handler' function is the trigger handler invoked when
    #    attributes of 'Atom' instances change.
    def _handler(self, trigger, additional, atomChanges):
	#    Check through modified atoms for backbone atoms.
	for a in atomChanges.modified:
	    #    If any of the changed atoms is a backbone atom, call
	    #    '_updateBackboneColor' to synchronize the well color
	    #     with backbone atom colors.
	    if ColorWellUI.MAINCHAIN.match(a.name):
		self._updateBackboneColor()
		return

    #    'unmap' is called when the dialog disappears.  We ignore the
    #    event argument.
    def unmap(self, *ignore):
	#    Check whether a handler is currently registered (*i.e.*, the
	#    handler identifier, 'handlerId', is not 'None') and
	#    deregister it if necessary.
	if self.handlerId is not None:

	    #    Deregistration requires two arguments: the name of the
	    #    trigger and the unique handler identifier returned by
	    #    the registration call.
	    chimera.triggers.deleteHandler('Atom', self.handlerId)

	    #    Set the unique handler identifier to 'None' to indicate
	    #    that no handler is currently registered.
	    self.handlerId = None