Ejemplo n.º 1
0
    def test___setitem___for_child(self):
        "A child can be set (changed) with __setitem__"
        source = TreeSource(
            data={
                ('first', 111): None,
                ('second', 222): [],
                ('third', 333): [
                    ('third.one', 331),
                    ('third.two', 332)
                ]
            },
            accessors=['val1', 'val2']
        )

        self.assertEqual(len(source), 3)
        self.assertEqual(len(source[2]), 2)

        listener = Mock()
        source.add_listener(listener)

        # Re-assign the first root
        source[2][0] = ('third.one_new', -331)

        self.assertEqual(len(source), 3)
        self.assertEqual(source[2][0].val1, 'third.one_new')
        self.assertEqual(source[2][0].val2, -331)

        listener.change.assert_called_once_with(item=source[2][0])
Ejemplo n.º 2
0
    def test_prepend_child(self):
        "A new child can be prepended"
        source = TreeSource(data={
            ('first', 111):
            None,
            ('second', 222): [],
            ('third', 333): [('third.one', 331), ('third.two', 332)]
        },
                            accessors=['val1', 'val2'])

        self.assertEqual(len(source), 3)
        self.assertEqual(len(source[2]), 2)

        listener = Mock()
        source.add_listener(listener)

        # Insert the new element
        node = source.prepend(source[2], val1='new element', val2=999)

        self.assertEqual(len(source), 3)
        self.assertEqual(len(source[2]), 3)
        self.assertEqual(source[2][0], node)
        self.assertEqual(node.val1, 'new element')
        self.assertEqual(node.val2, 999)

        listener.insert.assert_called_once_with(parent=source[2],
                                                index=0,
                                                item=node)
Ejemplo n.º 3
0
    def test_remove_root(self):
        "A root can be removed"
        source = TreeSource(data={
            ('first', 111):
            None,
            ('second', 222): [],
            ('third', 333): [('third.one', 331), ('third.two', 332)]
        },
                            accessors=['val1', 'val2'])

        self.assertEqual(len(source), 3)
        self.assertEqual(len(source[2]), 2)

        listener = Mock()
        source.add_listener(listener)

        # Remove the root element
        node = source.remove(source[1])

        self.assertEqual(len(source), 2)
        self.assertEqual(len(source[1]), 2)

        listener.remove.assert_called_once_with(item=node,
                                                index=1,
                                                parent=None)
Ejemplo n.º 4
0
    def test_insert_root_kwargs(self):
        "A new root can be inserted using kwargs"
        source = TreeSource(data={
            ('first', 111):
            None,
            ('second', 222): [],
            ('third', 333): [('third.one', 331), ('third.two', 332)]
        },
                            accessors=['val1', 'val2'])

        self.assertEqual(len(source), 3)

        listener = Mock()
        source.add_listener(listener)

        # Insert the new element
        node = source.insert(None, 1, val1='new element', val2=999)

        self.assertEqual(len(source), 4)
        self.assertEqual(source[1], node)
        self.assertEqual(node.val1, 'new element')
        self.assertEqual(node.val2, 999)

        listener.insert.assert_called_once_with(parent=None,
                                                index=1,
                                                item=node)
Ejemplo n.º 5
0
    def test_insert_first_child(self):
        "If a node previously didn't allow children, inserting changes this"
        source = TreeSource(data={
            ('first', 111):
            None,
            ('second', 222): [],
            ('third', 333): [('third.one', 331), ('third.two', 332)]
        },
                            accessors=['val1', 'val2'])

        self.assertEqual(len(source), 3)
        self.assertFalse(source[0].can_have_children())
        self.assertEqual(len(source[0]), 0)

        listener = Mock()
        source.add_listener(listener)

        # Insert the new element
        node = source.insert(source[0], 0, val1='new element', val2=999)

        self.assertEqual(len(source), 3)
        self.assertTrue(source[0].can_have_children())
        self.assertEqual(len(source[0]), 1)
        self.assertEqual(source[0][0], node)
        self.assertEqual(node.val1, 'new element')
        self.assertEqual(node.val2, 999)

        listener.insert.assert_called_once_with(parent=source[0],
                                                index=0,
                                                item=node)
Ejemplo n.º 6
0
    def test_prepend_child(self):
        "A new child can be prepended"
        source = TreeSource(
            data={
                ('first', 111): None,
                ('second', 222): [],
                ('third', 333): [
                    ('third.one', 331),
                    ('third.two', 332)
                ]
            },
            accessors=['val1', 'val2']
        )

        self.assertEqual(len(source), 3)
        self.assertEqual(len(source[2]), 2)

        listener = Mock()
        source.add_listener(listener)

        # Insert the new element
        node = source.prepend(source[2], val1='new element', val2=999)

        self.assertEqual(len(source), 3)
        self.assertEqual(len(source[2]), 3)
        self.assertEqual(source[2][0], node)
        self.assertEqual(node.val1, 'new element')
        self.assertEqual(node.val2, 999)

        listener.insert.assert_called_once_with(parent=source[2], index=0, item=node)
Ejemplo n.º 7
0
    def test_init_with_list_of_tuples(self):
        "TreeSources can be instantiated from lists of tuples"
        source = TreeSource(data=[
            ('first', 111),
            ('second', 222),
            ('third', 333),
        ],
                            accessors=['val1', 'val2'])

        self.assertEqual(len(source), 3)

        self.assertEqual(source[0].val1, 'first')
        self.assertEqual(source[0].val2, 111)
        self.assertFalse(source[0].can_have_children())
        self.assertEqual(len(source[0]), 0)

        self.assertEqual(source[1].val1, 'second')
        self.assertEqual(source[1].val2, 222)
        self.assertFalse(source[1].can_have_children())
        self.assertEqual(len(source[1]), 0)

        listener = Mock()
        source.add_listener(listener)

        # Set element 1
        source[1] = ('new element', 999)

        self.assertEqual(len(source), 3)

        self.assertEqual(source[1].val1, 'new element')
        self.assertEqual(source[1].val2, 999)
        self.assertFalse(source[1].can_have_children())
        self.assertEqual(len(source[1]), 0)

        listener.change.assert_called_once_with(item=source[1])
Ejemplo n.º 8
0
    def test_remove_child(self):
        "A child can be removed"
        source = TreeSource(data={
            ('first', 111):
            None,
            ('second', 222): [],
            ('third', 333): [('third.one', 331), ('third.two', 332)]
        },
                            accessors=['val1', 'val2'])

        self.assertEqual(len(source), 3)
        self.assertEqual(len(source[2]), 2)

        listener = Mock()
        source.add_listener(listener)

        # Remove "third.two"
        node = source.remove(source[2][1])

        self.assertEqual(len(source), 3)
        self.assertEqual(len(source[2]), 1)

        listener.remove.assert_called_once_with(item=node,
                                                index=1,
                                                parent=source[2])

        # Remove "third.one"
        node = source.remove(source[2][0])

        self.assertEqual(len(source), 3)
        self.assertEqual(len(source[2]), 0)

        listener.remove.assert_any_call(item=node, index=0, parent=source[2])
Ejemplo n.º 9
0
    def test_remove_child(self):
        "A child can be removed"
        source = TreeSource(
            data={
                ('first', 111): None,
                ('second', 222): [],
                ('third', 333): [
                    ('third.one', 331),
                    ('third.two', 332)
                ]
            },
            accessors=['val1', 'val2']
        )

        self.assertEqual(len(source), 3)
        self.assertEqual(len(source[2]), 2)

        listener = Mock()
        source.add_listener(listener)

        # Remove the child element
        node = source.remove(source[2][1])

        self.assertEqual(len(source), 3)
        self.assertEqual(len(source[2]), 1)

        listener.remove.assert_called_once_with(item=node)
Ejemplo n.º 10
0
    def test_insert_first_child(self):
        "If a node previously didn't allow children, inserting changes this"
        source = TreeSource(
            data={
                ('first', 111): None,
                ('second', 222): [],
                ('third', 333): [
                    ('third.one', 331),
                    ('third.two', 332)
                ]
            },
            accessors=['val1', 'val2']
        )

        self.assertEqual(len(source), 3)
        self.assertFalse(source[0].can_have_children())
        self.assertEqual(len(source[0]), 0)

        listener = Mock()
        source.add_listener(listener)

        # Insert the new element
        node = source.insert(source[0], 0, val1='new element', val2=999)

        self.assertEqual(len(source), 3)
        self.assertTrue(source[0].can_have_children())
        self.assertEqual(len(source[0]), 1)
        self.assertEqual(source[0][0], node)
        self.assertEqual(node.val1, 'new element')
        self.assertEqual(node.val2, 999)

        listener.insert.assert_called_once_with(parent=source[0], index=0, item=node)
Ejemplo n.º 11
0
    def test_insert_root_kwargs(self):
        "A new root can be inserted using kwargs"
        source = TreeSource(
            data={
                ('first', 111): None,
                ('second', 222): [],
                ('third', 333): [
                    ('third.one', 331),
                    ('third.two', 332)
                ]
            },
            accessors=['val1', 'val2']
        )

        self.assertEqual(len(source), 3)

        listener = Mock()
        source.add_listener(listener)

        # Insert the new element
        node = source.insert(None, 1, val1='new element', val2=999)

        self.assertEqual(len(source), 4)
        self.assertEqual(source[1], node)
        self.assertEqual(node.val1, 'new element')
        self.assertEqual(node.val2, 999)

        listener.insert.assert_called_once_with(parent=None, index=1, item=node)
Ejemplo n.º 12
0
    def test_init_with_dict_of_lists(self):
        "TreeSource nodes can be instantiated from dicts of lists"
        source = TreeSource(
            data={
                ('first', 111): None,
                ('second', 222): [],
                ('third', 333): [
                    ('third.one', 331),
                    {'val1': 'third.two', 'val2': 332}
                ]
            },
            accessors=['val1', 'val2']
        )

        self.assertEqual(len(source), 3)

        self.assertEqual(source[0].val1, 'first')
        self.assertEqual(source[0].val2, 111)
        self.assertFalse(source[0].can_have_children())
        self.assertEqual(len(source[0]), 0)

        self.assertEqual(source[1].val1, 'second')
        self.assertEqual(source[1].val2, 222)
        self.assertTrue(source[1].can_have_children())
        self.assertEqual(len(source[1]), 0)

        self.assertEqual(source[2].val1, 'third')
        self.assertEqual(source[2].val2, 333)
        self.assertTrue(source[2].can_have_children())
        self.assertEqual(len(source[2]), 2)

        self.assertEqual(source[2].val1, 'third')
        self.assertEqual(source[2].val2, 333)
        self.assertTrue(source[2].can_have_children())
        self.assertEqual(len(source[2]), 2)

        self.assertEqual(source[2][0].val1, 'third.one')
        self.assertEqual(source[2][0].val2, 331)
        self.assertFalse(source[2][0].can_have_children())
        self.assertEqual(len(source[2][0]), 0)

        self.assertEqual(source[2][1].val1, 'third.two')
        self.assertEqual(source[2][1].val2, 332)
        self.assertFalse(source[2][1].can_have_children())
        self.assertEqual(len(source[2][1]), 0)

        listener = Mock()
        source.add_listener(listener)

        # Set element 2
        source[2] = {'val1': 'new element', 'val2': 999}

        self.assertEqual(len(source), 3)

        self.assertEqual(source[2].val1, 'new element')
        self.assertEqual(source[2].val2, 999)

        listener.change.assert_called_once_with(item=source[2])
Ejemplo n.º 13
0
    def test_init_with_dict_of_lists(self):
        "TreeSource nodes can be instantiated from dicts of lists"
        source = TreeSource(data={
            ('first', 111):
            None,
            ('second', 222): [],
            ('third', 333): [('third.one', 331), {
                'val1': 'third.two',
                'val2': 332
            }]
        },
                            accessors=['val1', 'val2'])

        self.assertEqual(len(source), 3)

        self.assertEqual(source[0].val1, 'first')
        self.assertEqual(source[0].val2, 111)
        self.assertFalse(source[0].can_have_children())
        self.assertEqual(len(source[0]), 0)

        self.assertEqual(source[1].val1, 'second')
        self.assertEqual(source[1].val2, 222)
        self.assertTrue(source[1].can_have_children())
        self.assertEqual(len(source[1]), 0)

        self.assertEqual(source[2].val1, 'third')
        self.assertEqual(source[2].val2, 333)
        self.assertTrue(source[2].can_have_children())
        self.assertEqual(len(source[2]), 2)

        self.assertEqual(source[2].val1, 'third')
        self.assertEqual(source[2].val2, 333)
        self.assertTrue(source[2].can_have_children())
        self.assertEqual(len(source[2]), 2)

        self.assertEqual(source[2][0].val1, 'third.one')
        self.assertEqual(source[2][0].val2, 331)
        self.assertFalse(source[2][0].can_have_children())
        self.assertEqual(len(source[2][0]), 0)

        self.assertEqual(source[2][1].val1, 'third.two')
        self.assertEqual(source[2][1].val2, 332)
        self.assertFalse(source[2][1].can_have_children())
        self.assertEqual(len(source[2][1]), 0)

        listener = Mock()
        source.add_listener(listener)

        # Set element 2
        source[2] = {'val1': 'new element', 'val2': 999}

        self.assertEqual(len(source), 3)

        self.assertEqual(source[2].val1, 'new element')
        self.assertEqual(source[2].val2, 999)

        listener.change.assert_called_once_with(item=source[2])
Ejemplo n.º 14
0
    def test_init_with_list_of_dicts(self):
        "TreeSource nodes can be instantiated from lists of dicts"
        source = TreeSource(data=[
            {
                'val1': 'first',
                'val2': 111
            },
            {
                'val1': 'second',
                'val2': 222
            },
            {
                'val1': 'third',
                'val2': 333
            },
        ],
                            accessors=['val1', 'val2'])

        self.assertEqual(len(source), 3)

        self.assertEqual(source[0].val1, 'first')
        self.assertEqual(source[0].val2, 111)
        self.assertFalse(source[0].can_have_children())
        self.assertEqual(len(source[0]), 0)

        self.assertEqual(source[1].val1, 'second')
        self.assertEqual(source[1].val2, 222)
        self.assertFalse(source[1].can_have_children())
        self.assertEqual(len(source[1]), 0)

        listener = Mock()
        source.add_listener(listener)

        # Set element 1
        source[1] = {'val1': 'new element', 'val2': 999}

        self.assertEqual(len(source), 3)

        self.assertEqual(source[1].val1, 'new element')
        self.assertEqual(source[1].val2, 999)
        self.assertFalse(source[1].can_have_children())
        self.assertEqual(len(source[1]), 0)

        listener.change.assert_called_once_with(item=source[1])
Ejemplo n.º 15
0
    def test_init_with_list_of_dicts(self):
        "TreeSource nodes can be instantiated from lists of dicts"
        source = TreeSource(
            data=[
                {'val1': 'first', 'val2': 111},
                {'val1': 'second', 'val2': 222},
                {'val1': 'third', 'val2': 333},
            ],
            accessors=['val1', 'val2']
        )

        self.assertEqual(len(source), 3)

        self.assertEqual(source[0].val1, 'first')
        self.assertEqual(source[0].val2, 111)
        self.assertFalse(source[0].can_have_children())
        self.assertEqual(len(source[0]), 0)

        self.assertEqual(source[1].val1, 'second')
        self.assertEqual(source[1].val2, 222)
        self.assertFalse(source[1].can_have_children())
        self.assertEqual(len(source[1]), 0)

        listener = Mock()
        source.add_listener(listener)

        # Set element 1
        source[1] = {'val1': 'new element', 'val2': 999}

        self.assertEqual(len(source), 3)

        self.assertEqual(source[1].val1, 'new element')
        self.assertEqual(source[1].val2, 999)
        self.assertFalse(source[1].can_have_children())
        self.assertEqual(len(source[1]), 0)

        listener.change.assert_called_once_with(item=source[1])
Ejemplo n.º 16
0
    def test_init_with_list_of_tuples(self):
        "TreeSources can be instantiated from lists of tuples"
        source = TreeSource(
            data=[
                ('first', 111),
                ('second', 222),
                ('third', 333),
            ],
            accessors=['val1', 'val2']
        )

        self.assertEqual(len(source), 3)

        self.assertEqual(source[0].val1, 'first')
        self.assertEqual(source[0].val2, 111)
        self.assertFalse(source[0].can_have_children())
        self.assertEqual(len(source[0]), 0)

        self.assertEqual(source[1].val1, 'second')
        self.assertEqual(source[1].val2, 222)
        self.assertFalse(source[1].can_have_children())
        self.assertEqual(len(source[1]), 0)

        listener = Mock()
        source.add_listener(listener)

        # Set element 1
        source[1] = ('new element', 999)

        self.assertEqual(len(source), 3)

        self.assertEqual(source[1].val1, 'new element')
        self.assertEqual(source[1].val2, 999)
        self.assertFalse(source[1].can_have_children())
        self.assertEqual(len(source[1]), 0)

        listener.change.assert_called_once_with(item=source[1])
Ejemplo n.º 17
0
    def test___setitem___for_child(self):
        "A child can be set (changed) with __setitem__"
        source = TreeSource(data={
            ('first', 111):
            None,
            ('second', 222): [],
            ('third', 333): [('third.one', 331), ('third.two', 332)]
        },
                            accessors=['val1', 'val2'])

        self.assertEqual(len(source), 3)
        self.assertEqual(len(source[2]), 2)

        listener = Mock()
        source.add_listener(listener)

        # Re-assign the first root
        source[2][0] = ('third.one_new', -331)

        self.assertEqual(len(source), 3)
        self.assertEqual(source[2][0].val1, 'third.one_new')
        self.assertEqual(source[2][0].val2, -331)

        listener.change.assert_called_once_with(item=source[2][0])
Ejemplo n.º 18
0
Archivo: tree.py Proyecto: pybee/toga
class Tree(Widget):
    """ Tree Widget

    Args:
        headings (``list`` of ``str``): The list of headings for the interface.
        id (str):  An identifier for this widget.
        style (:obj:`Style`): An optional style object. If no style is provided then
            a new one will be created for the widget.
        factory (:obj:`module`): A python module that is capable to return a
            implementation of this class with the same name. (optional & normally not needed)
    """
    MIN_WIDTH = 100
    MIN_HEIGHT = 100

    def __init__(self, headings, id=None, style=None, data=None, accessors=None,
                 multiple_select=False, on_select=None, factory=None):
        super().__init__(id=id, style=style, factory=factory)
        self.headings = headings
        self._accessors = build_accessors(headings, accessors)
        self._multiple_select = multiple_select
        self._selection = None
        self._data = None
        self._on_select = None

        self._impl = self.factory.Tree(interface=self)
        self.data = data

        self.on_select = on_select

    @property
    def data(self):
        '''
        :returns: The data source of the tree
        :rtype: ``dict``
        '''
        return self._data

    @data.setter
    def data(self, data):
        '''
        Set the data source of the data

        :param data: Data source
        :type  data: ``dict`` or ``class``
        '''
        if data is None:
            self._data = TreeSource(accessors=self._accessors, data=[])
        elif isinstance(data, (list, tuple, dict)):
            self._data = TreeSource(accessors=self._accessors, data=data)
        else:
            self._data = data

        self._data.add_listener(self._impl)
        self._impl.change_source(source=self._data)

    @property
    def multiple_select(self):
        """Does the table allow multiple rows to be selected?"""
        return self._multiple_select

    @property
    def selection(self):
        """The current selection of the table.

        A value of None indicates no selection.
        If the table allows multiple selection, returns a list of
        selected data nodes. Otherwise, returns a single data node.
        """
        return self._selection

    @property
    def on_select(self):
        """
        The callable function for when a node on the Tree is selected

        :rtype: ``callable``
        """
        return self._on_select

    @on_select.setter
    def on_select(self, handler):
        """
        Set the function to be executed on node select

        :param handler:     callback function
        :type handler:      ``callable``
        """
        self._on_select = wrapped_handler(self, handler)
        self._impl.set_on_select(self._on_select)
Ejemplo n.º 19
0
class Tree(Widget):
    """ Tree Widget

    Args:
        headings (``list`` of ``str``): The list of headings for the interface.
        id (str):  An identifier for this widget.
        style (:obj:`Style`): An optional style object. If no style is provided then
            a new one will be created for the widget.
        factory (:obj:`module`): A python module that is capable to return a
            implementation of this class with the same name. (optional & normally not needed)
    """
    MIN_WIDTH = 100
    MIN_HEIGHT = 100

    def __init__(self,
                 headings,
                 id=None,
                 style=None,
                 data=None,
                 accessors=None,
                 multiple_select=False,
                 on_select=None,
                 factory=None):
        super().__init__(id=id, style=style, factory=factory)
        self.headings = headings
        self._accessors = build_accessors(headings, accessors)
        self._multiple_select = multiple_select
        self._selection = None
        self._data = None
        self._on_select = None

        self._impl = self.factory.Tree(interface=self)
        self.data = data

        self.on_select = on_select

    @property
    def data(self):
        '''
        :returns: The data source of the tree
        :rtype: ``dict``
        '''
        return self._data

    @data.setter
    def data(self, data):
        '''
        Set the data source of the data

        :param data: Data source
        :type  data: ``dict`` or ``class``
        '''
        if data is None:
            self._data = TreeSource(accessors=self._accessors, data=[])
        elif isinstance(data, (list, tuple, dict)):
            self._data = TreeSource(accessors=self._accessors, data=data)
        else:
            self._data = data

        self._data.add_listener(self._impl)
        self._impl.change_source(source=self._data)

    @property
    def multiple_select(self):
        """Does the table allow multiple rows to be selected?"""
        return self._multiple_select

    @property
    def selection(self):
        """The current selection of the table.

        A value of None indicates no selection.
        If the table allows multiple selection, returns a list of
        selected data nodes. Otherwise, returns a single data node.
        """
        return self._selection

    @property
    def on_select(self):
        """
        The callable function for when a node on the Tree is selected

        :rtype: ``callable``
        """
        return self._on_select

    @on_select.setter
    def on_select(self, handler):
        """
        Set the function to be executed on node select

        :param handler:     callback function
        :type handler:      ``callable``
        """
        self._on_select = wrapped_handler(self, handler)
        self._impl.set_on_select(self._on_select)
Ejemplo n.º 20
0
Archivo: tree.py Proyecto: yconst/toga
class Tree(Widget):
    """ Tree Widget

    Args:
        headings (``list`` of ``str``): The list of headings for the interface.
        id (str):  An identifier for this widget.
        style (:obj:`Style`): An optional style object. If no style is provided then
            a new one will be created for the widget.
    Kwargs:
        data: The data to display in the widget. Can be an instance of
            :class:`toga.sources.TreeSource`, a list, dict or tuple with data to display
            in the tree widget, or a class instance which implements the interface of
            :class:`toga.sources.TreeSource`. Entries can be given as follows:

            - Any Python object ``value`` with a string represntation. This string will be
              shown in the widget. If ``value`` has an attribute ``icon``, instance of
              (:class:`toga.Icon`), the icon will be shown in front of the text.
            - A tuple ``(icon, value)`` where again the string represnation of ``value``
              will be used as text.
        accessors (``list`` of ``str``): Optional: a list of attributes to access the
            value in the columns. If not given, the headings will be taken.
        multiple_select (``bool``): If ``True``, allows for the selection of multiple rows.
            Defaults to ``False``.
        on_select: A function to be called when the user selects one or multiple rows.
        factory (:obj:`module`): A python module that is capable to return a
            implementation of this class with the same name. (optional & normally not needed)
    """
    MIN_WIDTH = 100
    MIN_HEIGHT = 100

    def __init__(self,
                 headings,
                 id=None,
                 style=None,
                 data=None,
                 accessors=None,
                 multiple_select=False,
                 on_select=None,
                 factory=None):
        super().__init__(id=id, style=style, factory=factory)
        self.headings = headings
        self._accessors = build_accessors(headings, accessors)
        self._multiple_select = multiple_select
        self._selection = None
        self._data = None
        self._on_select = None

        self._impl = self.factory.Tree(interface=self)
        self.data = data

        self.on_select = on_select

    @property
    def data(self):
        '''
        :returns: The data source of the tree
        :rtype: ``dict``
        '''
        return self._data

    @data.setter
    def data(self, data):
        '''
        Set the data source of the data

        :param data: Data source
        :type  data: ``dict`` or ``class``
        '''
        if data is None:
            self._data = TreeSource(accessors=self._accessors, data=[])
        elif isinstance(data, (list, tuple, dict)):
            self._data = TreeSource(accessors=self._accessors, data=data)
        else:
            self._data = data

        self._data.add_listener(self._impl)
        self._impl.change_source(source=self._data)

    @property
    def multiple_select(self):
        """Does the table allow multiple rows to be selected?"""
        return self._multiple_select

    @property
    def selection(self):
        """The current selection of the table.

        A value of None indicates no selection.
        If the table allows multiple selection, returns a list of
        selected data nodes. Otherwise, returns a single data node.
        """
        return self._selection

    @property
    def on_select(self):
        """
        The callable function for when a node on the Tree is selected

        :rtype: ``callable``
        """
        return self._on_select

    @on_select.setter
    def on_select(self, handler):
        """
        Set the function to be executed on node select

        :param handler:     callback function
        :type handler:      ``callable``
        """
        self._on_select = wrapped_handler(self, handler)
        self._impl.set_on_select(self._on_select)