from schrodinger.infra import util
START = 'start'
PRESTART = 'preStart'
WRITE = 'write'
PREWRITE = 'preWrite'
READ = 'read'
RESET = 'reset'
CLOSE = 'close'
SHOW = 'show'
CUSTOM = 'custom'
CUSTOM_MENU_ITEM = 'custom_menu_item'
STD_TARGETS = [START, PRESTART, WRITE, PREWRITE, READ, RESET, CLOSE, SHOW]
APPMETHODS_MAP = {
    START: '_start',
    PRESTART: '_prestart',
    WRITE: '_write',
    PREWRITE: '_prewrite',
    READ: '_read',
    RESET: '_reset',
    CLOSE: '_close'
}
#=========================================================================
# Decorators
#=========================================================================
[docs]def custom(button_text=None, order=0, tooltip=None):
    def setCustom(method):
        nonlocal button_text
        if button_text is None:
            button_text = method.__name__
        _setup_button_method(method, CUSTOM, button_text, tooltip)
        method.button_order = order
        return method
    return setCustom 
[docs]def start(button_text='Run', tooltip='Click to run panel', add_write=True):
    """
    Decorator function for the 'Start' method.
    :param button_text: Label for the start button
    :type button_text: str
    :param tooltip: Tooltip for the start button
    :type tooltip: str
    :param add_write: Whether the start method should double as a write method.
        This is possible if using af2 launch methods or if the start method respects
        the state of the start_mode member variable.
    :type add_write: bool
    """
    def decorate(method):
        method.add_write = add_write
        return _setup_button_method(method, START, button_text, tooltip)
    return decorate 
[docs]def prestart():
    def decorate(method):
        return _setup_button_method(method, PRESTART)
    return decorate 
[docs]def write(button_text='Write', tooltip=None):
    def decorate(method):
        return _setup_button_method(method, WRITE, button_text, tooltip)
    return decorate 
[docs]def prewrite():
    def decorate(method):
        return _setup_button_method(method, PREWRITE)
    return decorate 
[docs]def read(button_text='Read', tooltip=None):
    def decorate(method):
        return _setup_button_method(method, READ, button_text, tooltip)
    return decorate 
[docs]def reset(button_text='Reset', tooltip='Reset the panel'):
    def decorate(method):
        return _setup_button_method(method, RESET, button_text, tooltip)
    return decorate 
[docs]def close(button_text='Close', tooltip=None):
    def decorate(method):
        return _setup_button_method(method, CLOSE, button_text, tooltip)
    return decorate 
[docs]def show():
    """
    A decorator for methods that are called when the panel is shown (both the
    initial launch and later re-showings).
    """
    def decorate(method):
        return _setup_button_method(method, SHOW)
    return decorate 
#=========================================================================
# Decorator helpers
#=========================================================================
def _setup_button_method(method, button_target, button_text=None, tooltip=None):
    method.button_target = button_target
    if button_text is not None:
        method.button_text = button_text
    method.tooltip = tooltip
    return method
[docs]def sort_order(method):
    return method.button_order 
#=========================================================================
# MethodsDict Class
#=========================================================================
[docs]class MethodsDict(dict):
[docs]    def __init__(self, source_obj):
        dict.__init__(self)
        self.custom_methods = []
        self.custom_menu_items = []
        self.source_obj = source_obj
        self.setButtonMethods(source_obj)
        self.setSelfMethods() 
    def __nonzero__(self):  # nopy3migrate
        return self.__bool__()
    def __bool__(self):
        return bool(self.custom_methods or len(self))
[docs]    def setSelfMethods(self):
        for target in STD_TARGETS:
            setattr(self, target, self.get(target, self.emptyMethod)) 
[docs]    def emptyMethod(self):
        return