Source code for openalea.core.interface

# -*- python -*-
# -*- coding:utf8 -*-
#
#       OpenAlea.Core
#
#       Copyright 2006-2009 INRIA - CIRAD - INRA
#
#       File author(s): Samuel Dufour-Kowalski <samuel.dufour@sophia.inria.fr>
#                       Christophe Pradal <christophe.prada@cirad.fr>
#
#       Distributed under the Cecill-C License.
#       See accompanying file LICENSE.txt or copy at
#           http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html
#
#       OpenAlea WebSite : http://openalea.gforge.inria.fr
#
##############################################################################
"""This module defines Interface classes (I/O types)"""

__license__ = "Cecill-C"
__revision__ = " $Id$ "

from openalea.core.metaclass import make_metaclass
from openalea.core.singleton import Singleton
from openalea.core.observer import AbstractListener

from . import color_palette # used for colors of interfaces
import types
import six
# Python 3 <-> Python 3 equivalent types
try:
    from types import (StringType, SliceType, FloatType, IntType, BooleanType, TupleType,
                      ListType, DictType, InstanceType)
except ImportError:
    StringType = str #six.string_types gave a tuple
    SliceType = slice
    FloatType = float
    IntType = int
    BooleanType = bool
    TupleType = tuple
    ListType = list
    DictType = dict
    InstanceType = object


# Dictionary to map Interface with corresponding python type


[docs] class TypeInterfaceMap(six.with_metaclass(Singleton, dict)): """ Singleton class to map Interface with standard python type InterfaceWidgetMap inherits from dict class """
[docs] def declare_interface(self, type, interface): """ Declare an interface and its optional widget :param interface: IInterface class object :param type: Python type """ if type and type not in self: self[type] = interface TypeNameInterfaceMap().declare_interface(str(interface), interface)
[docs] class TypeNameInterfaceMap(six.with_metaclass(Singleton, dict)): """ Singleton class to map Interface Name with interface type InterfaceWidgetMap inherits from dict class """
[docs] def declare_interface(self, name, interface): """ Declare an interface and its optional widget :param interface: IInterface class object :param type: Python type """ if name and name not in self: self[name] = interface
[docs] class IInterfaceMetaClass(type): """ IInterface Metaclass Allow to register corresponding python type """ all = [] # all interfaces def __new__(cls, name, bases, dict): newCls = type.__new__(cls, name, bases, dict) return newCls def __init__(cls, name, bases, dic): super(IInterfaceMetaClass, cls).__init__(name, bases, dic) if(hasattr(cls, "__pytype__")): TypeInterfaceMap().declare_interface(cls.__pytype__, cls) else: TypeInterfaceMap().declare_interface(None, cls) if isinstance(cls.__color__, str): cls.__color__ = color_palette.HTMLColorToRGB(cls.__color__) if cls not in IInterfaceMetaClass.all: IInterfaceMetaClass.all.append(cls) def __repr__(cls): return cls.__name__
# Defaults interfaces
[docs] class IInterface(six.with_metaclass(IInterfaceMetaClass, object)): """ Abstract base class for all interfaces """ __pytype__ = None __color__ = None
[docs] @classmethod def default(cls): return None
def __init__(self, **kargs): """ Default init""" # # the desc should be used as a dynamic description of IInterace # # default visualisation in widget is done with tooltip # self.desc = kargs.get('desc', None) # # the label should be used to describe the default static description # # default visualisation in widget is done with label # self.label = kargs.get('label', None) def __repr__(self): return self.__class__.__name__ + '()'
[docs] class IStr(IInterface): """ String interface """ __pytype__ = StringType __color__ = color_palette.maroon __label__ = u'Short Text'
[docs] @classmethod def default(cls): return str()
[docs] class ISlice(IInterface): """ String interface """ __pytype__ = SliceType __color__ = color_palette.maroon __label__ = u'Slice'
[docs] class IFileStr(IStr): """ File Path interface """ __color__ = color_palette.maroon __label__ = u'File path' def __init__(self, filter="All (*)", save=False, **kargs): IInterface.__init__(self, **kargs) self.filter = filter self.save = save def __repr__(self): if self.filter == "All (*.*)" and not self.save: # default values return 'IFileStr' else: return 'IFileStr(filter="%s", save=%s)' % \ (self.filter, str(self.save))
[docs] class IDirStr(IStr): """ Directory Path interface """ __label__ = u'Directory path' pass
[docs] class ITextStr(IStr): """ Long String interface """ __label__ = u'Long text' pass
[docs] class ICodeStr(IStr): """ Source code interface """ __label__ = u'Code' pass
[docs] class IFloat(IInterface): """ Float interface """ __pytype__ = FloatType __color__ = color_palette.blue __label__ = u'Float' def __init__(self, min=-2. ** 24, max=2. ** 24, step=1., **kargs): IInterface.__init__(self, **kargs) self.min = min self.max = max self.step = step
[docs] @classmethod def default(cls): return 0.
def __repr__(self): default_min = -2 ** 24 default_max = 2 ** 24 default_step = 1. if (self.min == default_min and self.max == default_max and self.step == default_step): return self.__class__.__name__ else: return 'IFloat(min=%d, max=%d, step=%f)' % \ (self.min, self.max, self.step)
[docs] class IInt(IInterface): """ Int interface """ __pytype__ = IntType __color__ = color_palette.blue __label__ = u'Integer ℤ' def __init__(self, min=-2 ** 24, max=2 ** 24, step=1, **kargs): IInterface.__init__(self, **kargs) self.min = min self.max = max self.step = step
[docs] @classmethod def default(cls): return 0
[docs] def example(self): return self.min + 2
def __repr__(self): default_min = -2 ** 24 default_max = 2 ** 24 default_step = 1 if (self.min == default_min and self.max == default_max and self.step == default_step): return self.__class__.__name__ else: return 'IInt(min=%d, max=%d, step=%d)' % \ (self.min, self.max, self.step)
[docs] class IBool(IInterface): """ Bool interface """ __pytype__ = BooleanType __color__ = color_palette.aqua __label__ = 'Boolean (True/False)'
[docs] @classmethod def default(cls): return False
[docs] class IEnumStr(IStr): """ String enumeration """ __color__ = color_palette.purple __label__ = 'Predefined texts' def __init__(self, enum=[], **kargs): IInterface.__init__(self, **kargs) self.enum = enum def __repr__(self): return 'IEnumStr(enum=%s)' % (str(self.enum))
[docs] class IRGBColor(IInterface): """ RGB Color """ __color__ = color_palette.lime __label__ = 'Color (RGB)' pass
[docs] class IDateTime(IInterface): """ DateTime """ __color__ = color_palette.teal __label__ = 'Date' pass
[docs] class ITuple3(IInterface): """ Tuple3 """ __color__ = color_palette.fuchsia __label__ = 'Triple'
[docs] @classmethod def default(cls): return (None, None, None)
[docs] class ITuple(IInterface): """ Tuple """ __label__ = 'Tuple' __pytype__ = TupleType __color__ = color_palette.fuchsia
[docs] class IFunction(IInterface): """ Function interface """ __color__ = color_palette.white __pytype__ = types.FunctionType
[docs] class ISequence(IInterface): """ Sequence interface (list, tuple, ...) """ __pytype__ = ListType __color__ = color_palette.green __label__ = 'Sequence'
[docs] @classmethod def default(cls): return list()
[docs] class IDict(IInterface): """ Dictionary interface """ __pytype__ = DictType __color__ = color_palette.olive __label__ = 'Mapping key, value (dictionary)'
[docs] @classmethod def default(cls): """todo""" return dict()
[docs] class IData(IStr): """ Package data interface """ __color__ = color_palette.silver __label__ = 'Data'
# Dictionary to map Interface with corresponding widget
[docs] class InterfaceWidgetMap(six.with_metaclass(Singleton, dict)): """ Singleton class to map Interface with InterfaceWidget InterfaceWidgetMap inherits from dict class """ def __init__(self, *args): dict.__init__(self, *args)
[docs] def declare_interface(self, interface, widget=None): """ Declare an interface and its optional widget @param interface : IInterface class object @param widget : IInterfaceWidget class object """ self[interface] = widget
# Base class for interface widget
[docs] class IWidgetMetaClass(type): """ InterfaceWidget Metaclass """ def __init__(cls, name, bases, dic, **kargs): super(IWidgetMetaClass, cls).__init__(name, bases, dic) if(cls.__interface__): InterfaceWidgetMap().declare_interface(cls.__interface__, cls)
[docs] class IInterfaceWidget(six.with_metaclass(IWidgetMetaClass, AbstractListener)): """ Base class for widget associated to an interface """ __interface__ = None def __init__(self, node, parent, parameter_str, interface): """ @param parameter_str : the parameter key the widget is associated to @param interface : instance of interface object """ AbstractListener.__init__(self) self.node = node self.param_str = parameter_str
[docs] def update_state(self): """ Enable or disable widget depending of connection status """ # i = self.node.get_input_index(self.param_str) state = self.get_state() # By default, disable the entire widget try: notconnected = bool(state != "connected") if(self.internal_data().get('minimal', False)): self.setVisible(notconnected) else: self.setEnabled(notconnected) except: pass
[docs] def notify(self, sender, event): """ Notification sent by node """ pass
[docs] def set_value(self, newval): self.node.set_input(self.param_str, newval)
[docs] def get_value(self): return self.node.get_input(self.param_str)
[docs] def set_widget_value(self, newval): pass
[docs] def get_widget_value(self): return self.get_value()
[docs] def get_state(self): return self.node.get_input_state(self.param_str)
[docs] def internal_data(self): "return a dict: minimal" return self.node.internal_data
[docs] @classmethod def get_label(cls, node, parameter_str): return node.get_input_port(name=parameter_str).get_label()
[docs] def unvalidate(self): self.node.unvalidate_input(self.param_str)