# Espacio de trabajo

> La disposición de una ventana estilo editor: barra de título, docks, centro y barra de estado. Componente de Pyzed para GUIs en Python.

Source: https://albakore.github.io/pyzed/es/library/workspace/

:::tip[En pocas palabras]
Toda la disposición de una ventana tipo editor: barra arriba, paneles laterales, la zona principal y una barra abajo.
:::

Construye el marco de una ventana estilo editor: la barra de título arriba, docks a la izquierda, a la derecha y abajo, el centro y la barra de estado. Pasa `None` para ocultar un dock (así funciona Ctrl+B); `left_width`, `right_width` y `bottom_height` fijan su tamaño y `on_resize` avisa al arrastrar.

`ui.workspace` · Categoría: [Espacio de trabajo](https://albakore.github.io/pyzed/es/library/#espacio-de-trabajo) · [Referencia completa →](https://albakore.github.io/pyzed/es/reference/ui/#workspace-1)

**Código:**

```python
files = ui.TreeNode.from_paths(["src/main.py", "src/ui.py", "README.md"], status={"src/ui.py": "modified"})
ui.workspace(
    pz.column([
        ui.tab_bar([ui.Tab.for_file("src/main.py")], "src/main.py", on_close=on_close),
        ui.editor("ws-main", "import pyzed as pz\n\n\ndef main():\n    pz.run(App)\n", path="main.py"),
    ]),
    title_bar=ui.title_bar([ui.title_button("pyzed", chevron=True),
                            ui.title_button("main", icon="git-branch", muted=True)],
                           [ui.icon_button("bell", on_bell, size="sm"), ui.avatar("KV")]),
    left=pz.column([ui.panel_header("Project", [ui.icon_button("plus", on_new, size="xs")]),
                    ui.tree(files, expanded={"src"}, selected="src/main.py")]),
    bottom=pz.column([ui.panel_header("Terminal", icon="terminal"),
                      ui.terminal("$ python main.py\n\x1b[32m✓\x1b[0m done")]),
    status_bar=ui.status_bar([ui.status_item("0", icon="circle-x"), ui.status_item("1", icon="triangle-alert")],
                             [ui.status_item("Ln 4, Col 8"), ui.status_item("Python")]),
    left_width=200, bottom_height=110,
)
```

## Cuándo usarlo

- Como raíz de apps tipo editor: IDEs, apps de notas, clientes de bases de datos, gestores de archivos.

## Uso

```python
import pyzed as pz
from pyzed import ui

class Ide(pz.App):
    def __init__(self):
        self.show_left = True

    def on_key(self, combo):
        if combo == "ctrl-b":
            self.show_left = not self.show_left

    def view(self):
        return ui.workspace(
            self.editor_area(),
            title_bar=ui.title_bar([ui.title_button("my-project", chevron=True)]),
            left=self.project_panel() if self.show_left else None,
            status_bar=ui.status_bar([], [ui.status_item("Python")]),
        )
```

## Variantes

:::note[Sobre estas capturas]
Cada captura la graba pyzed mismo, fuera de pantalla a 2x, en One Dark o One Light según el tema de este sitio, y recortada al componente para que se vea a su tamaño real. El puntero pasa por encima, pulsa o escribe en él; un componente que no reacciona al puntero recorre algunos temas. Con movimiento reducido ves el primer fotograma. Abre **Código** bajo una captura para ver el fragmento que la dibuja; los nombres libres como `on_save` son tus propios callbacks.
:::

### Docks

```python
ui.workspace(main_view(), status_bar=ui.status_bar([], [ui.status_item("Python")]))
```

```python
ui.workspace(main_view(), left=pz.column([ui.panel_header("Project"),
             ui.list_item("main.py", icon="file-code", selected=True, inset=True)]), left_width=150)
```

```python
ui.workspace(main_view(), bottom=pz.column([ui.panel_header("Terminal", icon="terminal"),
             ui.terminal("$ python main.py")]), bottom_height=90)
```

```python
ui.workspace(main_view(), right=pz.column([ui.panel_header("Outline"), ui.list_item("class Notes", icon="box")]),
             right_width=150)
```

```python
ui.workspace(main_view(), title_bar=ui.title_bar([ui.title_button("pyzed", chevron=True)],
                                                  [ui.avatar("KV")]))
```

## Eventos

Espacio de trabajo tiene **1 evento propios**, en la tabla de abajo. Como todo widget, también tiene los **18 eventos comunes** (`click`, `double_click`, `right_click`, `mouse_enter`, `drag`, `key_down`, `resize`…), que se conectan con `.on(...)`: mira [Eventos](https://albakore.github.io/pyzed/es/guides/events/) y [Eventos de cada componente](https://albakore.github.io/pyzed/es/library/events/).

| Evento | El handler recibe | Cuándo |
| --- | --- | --- |
| `on_resize` | `(side, size)` | Se llama con `(side, size)` cuando el usuario termina de cambiar el tamaño de un panel arrastrando su borde interior. |

**El handler recibe** es lo que Pyzed le pasa a tu función: `()` es nada. Cualquier handler también puede ser un mensaje (un valor que no se puede llamar), que va a `update()`.

### Manejar los eventos

Los mismos eventos escritos de tres formas. **Imperativa**: métodos de la app que cambian `self`. **Declarativa**: los handlers producen mensajes y un único `update()` decide. **Funcional**: una función pura dibuja un estado inmutable y pide cambios con `set_state(...)`. Mira [Imperativo, declarativo y funcional](https://albakore.github.io/pyzed/es/guides/code-styles/).

**Imperativo:**

```python
class Ide(pz.App):
    def __init__(self):
        self.left_width, self.bottom_height = 220, 160

    def resized(self, side, size):       # on_resize: which dock and its new size
        if side == "left":
            self.left_width = size
        elif side == "bottom":
            self.bottom_height = size

    def view(self):
        return ui.workspace(main_view(), left=ui.panel_header("Project"), bottom=ui.panel_header("Terminal"),
                            left_width=self.left_width, bottom_height=self.bottom_height,
                            on_resize=self.resized)
```

**Declarativo:**

```python
from dataclasses import dataclass

@dataclass
class Resized:
    side: str
    size: float

class Ide(pz.App):
    sizes = {"left": 220, "bottom": 160}

    def update(self, message):
        match message:
            case Resized(side, size):
                self.sizes = {**self.sizes, side: size}

    def view(self):
        return ui.workspace(main_view(), left=ui.panel_header("Project"), bottom=ui.panel_header("Terminal"),
                            left_width=self.sizes["left"], bottom_height=self.sizes["bottom"],
                            on_resize=Resized)
```

**Funcional:**

```python
from dataclasses import dataclass

@dataclass(frozen=True)
class State:
    left: float = 220
    bottom: float = 160

def view(state, set_state):
    return ui.workspace(main_view(), left=ui.panel_header("Project"), bottom=ui.panel_header("Terminal"),
                        left_width=state.left, bottom_height=state.bottom,
                        on_resize=lambda side, size: set_state(**{side: size}))
```

## Propiedades y API

### `ui.workspace`

```python
workspace(
    center,
    *,
    title_bar=None,
    left=None,
    right=None,
    bottom=None,
    status_bar=None,
    left_width=240,
    right_width=320,
    bottom_height=220,
    on_resize=None,
    theme=None,
)
```

El layout de una ventana estilo editor: barra de título, docks izquierdo, derecho e inferior, centro y barra de estado. Pasa `None` para ocultar un dock.

| Propiedad | Por defecto | Descripción |
| --- | --- | --- |
| `center` | *obligatorio* | Contenido central (normalmente pestañas + editor). |
| `title_bar` | `None` | Barra de título (`ui.title_bar`). |
| `left` | `None` | Dock izquierdo. |
| `right` | `None` | Dock derecho. |
| `bottom` | `None` | Dock inferior. |
| `status_bar` | `None` | Barra de estado (`ui.status_bar`). |
| `left_width` | `240` | Ancho del dock izquierdo. |
| `right_width` | `320` | Ancho del dock derecho. |
| `bottom_height` | `220` | Alto del dock inferior. |
| `theme` | `None` | Tema a usar en lugar del actual (`pyzed.theme.current()`). |

Eventos: `on_resize` ([eventos](#eventos)).

[Referencia completa →](https://albakore.github.io/pyzed/es/reference/ui/#workspace-1)

## Relacionados

- [Barra de título](https://albakore.github.io/pyzed/es/library/title-bar/): La barra superior con los selectores de proyecto y rama.
- [Barra de estado](https://albakore.github.io/pyzed/es/library/status-bar/): La barra inferior: diagnósticos, posición del cursor, lenguaje.
- [Panel](https://albakore.github.io/pyzed/es/library/panel/): Un panel lateral acoplable y redimensionable.
- [División](https://albakore.github.io/pyzed/es/library/split/): Dos paneles con un divisor que se arrastra.
