Source code for 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

import color_palette # used for colors of interfaces
import types

# Dictionary to map Interface with corresponding python type


[docs]class TypeInterfaceMap(dict): """ Singleton class to map Interface with standard python type InterfaceWidgetMap inherits from dict class """ __metaclass__ = Singleton
[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(dict): """ Singleton class to map Interface Name with interface type InterfaceWidgetMap inherits from dict class """ __metaclass__ = Singleton
[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(object): """ Abstract base class for all interfaces """ __metaclass__ = IInterfaceMetaClass __pytype__ = None __color__ = None @classmethod
[docs] 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__ = types.StringType __color__ = color_palette.maroon __label__ = u'Short Text' @classmethod
[docs] def default(cls): return str()
[docs]class ISlice(IInterface): """ String interface """ __pytype__ = types.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__ = types.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 @classmethod
[docs] 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__ = types.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 @classmethod
[docs] 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__ = types.BooleanType __color__ = color_palette.aqua __label__ = 'Boolean (True/False)' @classmethod
[docs] 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' @classmethod
[docs] def default(cls): return (None, None, None)
[docs]class ITuple(IInterface): """ Tuple """ __label__ = 'Tuple' __pytype__ = types.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__ = types.ListType __color__ = color_palette.green __label__ = 'Sequence' @classmethod
[docs] def default(cls): return list()
[docs]class IDict(IInterface): """ Dictionary interface """ __pytype__ = types.DictType __color__ = color_palette.olive __label__ = 'Mapping key, value (dictionary)' @classmethod
[docs] 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(dict): """ Singleton class to map Interface with InterfaceWidget InterfaceWidgetMap inherits from dict class """ __metaclass__ = Singleton 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(AbstractListener): """ Base class for widget associated to an interface """ __metaclass__ = IWidgetMetaClass __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()
@classmethod
[docs] 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)