# Delegate

Delegate is the representation layer. Delegate is called by the view to create a
specific piece of the user interface. TreeView calls the delegate to create the
widgets for the header and per item in the column.

To 

## Item

![](../data/mdv-delegate-items.png)

Each row in TreeView is the representation of the model's item.

## Column

![](../data/mdv-delegate-columns.png)

Each model's item can have multiple data fields. To display them, TreeView uses
columns.

## Level

![](../data/mdv-delegate-level.png)

The level is the number of parent items for the given item.

## Branch Widget Header

![](../data/mdv-delegate-widget.png)

The branch is the widget that makes TreeView expand or collapse the current
item.

## Example

To reimplement a delegate, it's necessary to reimplement the following methods
of `ui.AbstractItemDelegate`:

```
def build_branch(self, model, item, column_id, level, expanded):
```

```
def build_widget(self, model, item, column_id, level, expanded):
```

```
def build_header(self, column_id):
```

```execute 200
##
class Item(ui.AbstractItem):
    """Single item of the model"""

    def __init__(self, text):
        super().__init__()
        self.name_model = ui.SimpleStringModel(text)
        self.children = None

class Model(ui.AbstractItemModel):
    def __init__(self, *args):
        super().__init__()
        self._children = [Item(t) for t in args]

    def get_item_children(self, item):
        """Returns all the children when the widget asks it."""
        if item is not None:
            if not item.children:
                item.children = [Item(f"Child #{i}") for i in range(5)]
            return item.children

        return self._children

    def get_item_value_model_count(self, item):
        """The number of columns"""
        return 1

    def get_item_value_model(self, item, column_id):
        """
        Return value model.
        It's the object that tracks the specific value.
        In our case we use ui.SimpleStringModel.
        """
        return item.name_model

##
class Delegate(ui.AbstractItemDelegate):
    """
    Delegate is the representation layer. TreeView calls the methods
    of the delegate to create custom widgets for each item.
    """

    def build_branch(self, model, item, column_id, level, expanded):
        """Create a branch widget that opens or closes subtree"""
        # Offset depents on level
        text = "     " * (level + 1)
        # > and v symbols depending on the expanded state
        if expanded:
            text += "v    "
        else:
            text += ">    "
        ui.Label(text, height=22, alignment=ui.Alignment.CENTER, tooltip="Branch")

    def build_widget(self, model, item, column_id, level, expanded):
        """Create a widget per column per item"""
        ui.Label(
            model.get_item_value_model(item, column_id).as_string,
            tooltip="Widget"
        )

    def build_header(self, column_id):
        """Build the header"""
        ui.Label("Header", tooltip="Header", height=25)

with ui.ScrollingFrame(
    height=200,
    horizontal_scrollbar_policy=ui.ScrollBarPolicy.SCROLLBAR_ALWAYS_OFF,
    vertical_scrollbar_policy=ui.ScrollBarPolicy.SCROLLBAR_ALWAYS_ON,
    style_type_name_override="TreeView",
):
    self._model = Model("Root", "Items")
    self._delegate = Delegate()
    ui.TreeView(
        self._model, delegate=self._delegate, root_visible=False, header_visible=True
    )

```
