{ "cells": [ { "cell_type": "markdown", "id": "t2-header", "metadata": {}, "source": [ "# Tutorial 2: Open a Multiview of Panels\n", "\n", "This tutorial shows how to display multiple panels simultaneously using scivianna's layout system." ] }, { "cell_type": "markdown", "id": "t2-intro", "metadata": {}, "source": [ "## Introduction to Layouts\n", "\n", "Scivianna provides two layout classes for displaying multiple panels:\n", "\n", "| Layout | Description |\n", "|--------|-------------|\n", "| `SplitLayout` | Two panels split vertically or horizontally with a draggable divider |\n", "| `GridStackLayout` | Multiple panels in a grid with drag-and-drop rearrangement |\n", "\n", "## Step 1: SplitLayout - Two Panels Side by Side\n", "\n", "`SplitLayout` divides the screen into two areas. You can split vertically (side by side) or horizontally (top and bottom)." ] }, { "cell_type": "code", "execution_count": null, "id": "t2-split-imports", "metadata": {}, "outputs": [], "source": [ "from pathlib import Path\n", "from scivianna.slave import ComputeSlave\n", "from scivianna.interface.med_interface import MEDInterface\n", "from scivianna.panel.panel_2d import Panel2D\n", "from scivianna.layout.split import SplitLayout, SplitItem, SplitDirection\n", "from scivianna.constants import GEOMETRY\n", "import scivianna.input_file\n", "\n", "# Path to a built-in example MED file\n", "med_file_path = Path(scivianna.input_file.__file__).parent / \"power.med\"" ] }, { "cell_type": "markdown", "id": "t2-split-vertical", "metadata": {}, "source": [ "### Vertical Split (Side by Side)\n", "\n", "Creates two panels displayed left and right with a vertical divider." ] }, { "cell_type": "code", "execution_count": null, "id": "t2-split-vertical-code", "metadata": {}, "outputs": [], "source": [ "# Create two ComputeSlaves\n", "slave1 = ComputeSlave(MEDInterface)\n", "slave2 = ComputeSlave(MEDInterface)\n", "\n", "# Load the same file in both slaves (or different files)\n", "slave1.read_file(med_file_path, GEOMETRY)\n", "slave2.read_file(med_file_path, GEOMETRY)\n", "\n", "# Create two Panel2D instances\n", "panel_left = Panel2D(slave=slave1, name=\"Left Panel\")\n", "panel_right = Panel2D(slave=slave2, name=\"Right Panel\")\n", "\n", "# Create a SplitItem defining the layout\n", "split_item = SplitItem(\n", " panel_1=panel_left,\n", " panel_2=panel_right,\n", " direction=SplitDirection.VERTICAL, # Side by side\n", ")\n", "\n", "# Create the SplitLayout\n", "split_layout = SplitLayout(split_item)\n", "\n", "# Display\n", "# split_layout" ] }, { "cell_type": "markdown", "id": "t2-split-horizontal", "metadata": {}, "source": [ "### Horizontal Split (Top and Bottom)\n", "\n", "Creates two panels displayed one above the other with a horizontal divider." ] }, { "cell_type": "code", "execution_count": null, "id": "t2-split-horizontal-code", "metadata": {}, "outputs": [], "source": [ "# Create the split item with horizontal direction\n", "split_item_h = SplitItem(\n", " panel_1=panel_left,\n", " panel_2=panel_right,\n", " direction=SplitDirection.HORIZONTAL, # Top and bottom\n", ")\n", "\n", "# Create the SplitLayout\n", "split_layout_h = SplitLayout(split_item_h)\n", "\n", "# Display\n", "# split_layout_h" ] }, { "cell_type": "markdown", "id": "t2-split-features", "metadata": {}, "source": [ "### SplitLayout Features\n", "\n", "- **Draggable divider**: Click and drag the divider to resize panels\n", "- **Panel switching**: Click on panel icons in the sidebar to switch between panels\n", "- **Duplication**: Use the duplicate button to split a panel further (creating nested splits)\n", "- **Save/Restore**: Layouts can be saved to and restored from zip files" ] }, { "cell_type": "markdown", "id": "t2-nested-split", "metadata": {}, "source": [ "## Step 2: Nested Splits - Multiple Panels\n", "\n", "`SplitItem` can be nested to create more complex layouts with multiple panels." ] }, { "cell_type": "code", "execution_count": null, "id": "t2-nested-code", "metadata": {}, "outputs": [], "source": [ "# Create three slaves and panels\n", "slave_a = ComputeSlave(MEDInterface)\n", "slave_b = ComputeSlave(MEDInterface)\n", "slave_c = ComputeSlave(MEDInterface)\n", "\n", "slave_a.read_file(med_file_path, GEOMETRY)\n", "slave_b.read_file(med_file_path, GEOMETRY)\n", "slave_c.read_file(med_file_path, GEOMETRY)\n", "\n", "panel_a = Panel2D(slave=slave_a, name=\"Panel A\")\n", "panel_b = Panel2D(slave=slave_b, name=\"Panel B\")\n", "panel_c = Panel2D(slave=slave_c, name=\"Panel C\")\n", "\n", "# Create nested split item:\n", "# +----------+----------+\n", "# | | |\n", "# | Panel A | Panel B |\n", "# | | |\n", "# +----------+----------+\n", "# | |\n", "# | Panel C │\n", "# | |\n", "# +----------+----------+\n", "\n", "inner_split = SplitItem(\n", " panel_1=panel_a,\n", " panel_2=panel_b,\n", " direction=SplitDirection.VERTICAL, # A | B\n", ")\n", "\n", "# Actually for 3 panels we need a different approach:\n", "# Left: Panel A (top/bottom split with Panel C)\n", "# Right: Panel B\n", "\n", "nested_split = SplitItem(\n", " panel_1=inner_split,\n", " panel_2=panel_c,\n", " direction=SplitDirection.HORIZONTAL, # A over C\n", ")\n", "\n", "nested_layout = SplitLayout(nested_split)\n", "# nested_layout/" ] }, { "cell_type": "markdown", "id": "t2-gridstack", "metadata": {}, "source": [ "## Step 3: GridStackLayout - Multiple Panels in a Grid\n", "\n", "`GridStackLayout` provides a more flexible grid-based layout with drag-and-drop rearrangement." ] }, { "cell_type": "code", "execution_count": null, "id": "t2-gridstack-code", "metadata": {}, "outputs": [], "source": [ "from scivianna.layout.gridstack import GridStackLayout\n", "\n", "# Create four slaves and panels\n", "slaves = [\n", " ComputeSlave(MEDInterface) for _ in range(4)\n", "]\n", "panels = {}\n", "\n", "for i, slave in enumerate(slaves):\n", " slave.read_file(med_file_path, GEOMETRY)\n", " panels[f\"Grid Panel {i}\"] = Panel2D(slave=slave, name=f\"Grid Panel {i}\")\n", "\n", "# Defining the panels bounds:\n", "\n", "# +----------+----------+\n", "# | | |\n", "# | 0 | 1 |\n", "# | | |\n", "# +----------+----------+\n", "# | | |\n", "# | 2 | 3 |\n", "# | | |\n", "# +----------+----------+\n", "bounds_x = {\n", " \"Grid Panel 0\": [0, 4],\n", " \"Grid Panel 1\": [5, 9],\n", " \"Grid Panel 2\": [0, 4],\n", " \"Grid Panel 3\": [5, 9]\n", "}\n", "bounds_y = {\n", " \"Grid Panel 0\": [0, 4],\n", " \"Grid Panel 1\": [0, 4],\n", " \"Grid Panel 2\": [5, 9],\n", " \"Grid Panel 3\": [5, 9]\n", "}\n", "\n", "# Create a GridStackLayout with the panels\n", "grid_layout = GridStackLayout(\n", " visualisation_panels = panels,\n", " bounds_x = bounds_x,\n", " bounds_y = bounds_y\n", ")\n", "\n", "# Display\n", "# grid_layout" ] }, { "cell_type": "markdown", "id": "t2-gridstack-features", "metadata": {}, "source": [ "### GridStackLayout Features\n", "\n", "- **Drag-and-drop**: Drag panel borders to resize cells\n", "- **Resizable grid**: Right-click on a cell to adjust rows/columns\n", "- **Panel switching**: Click on panel icons in the sidebar to switch between panels\n", "- **Save/Restore**: Layouts can be saved to and restored from zip files" ] }, { "cell_type": "markdown", "id": "t2-save-restore", "metadata": {}, "source": [ "## Step 4: Save and Restore Layouts\n", "\n", "Layouts can be saved to zip files and restored later." ] }, { "cell_type": "code", "execution_count": null, "id": "t2-save-restore-code", "metadata": {}, "outputs": [], "source": [ "# Save the layout to a zip file\n", "# split_layout.save_to_zip(\"my_layout.zip\", include_files=True)\n", "\n", "# Restore the layout from a zip file\n", "# restored_layout = SplitLayout.restore_from_zip(\n", "# \"my_layout.zip\",\n", "# include_files=True,\n", "# )" ] }, { "cell_type": "markdown", "id": "t2-sync-fields", "metadata": {}, "source": [ "## Step 5: Synchronized Fields\n", "\n", "Multiple panels can synchronize their displayed field when the sync_field argument is set at True." ] }, { "cell_type": "code", "execution_count": null, "id": "t2-sync-fields-code", "metadata": {}, "outputs": [], "source": [ "# Create two panels sharing the same slave\n", "shared_slave = ComputeSlave(MEDInterface)\n", "shared_slave.read_file(med_file_path, GEOMETRY)\n", "\n", "panel_sync1 = Panel2D(slave=shared_slave, name=\"Sync Panel 1\")\n", "panel_sync2 = Panel2D(slave=shared_slave, name=\"Sync Panel 2\")\n", "\n", "panel_sync1.sync_field = True\n", "panel_sync2.sync_field = True\n", "\n", "# When you change the field in one panel, both update\n", "sync_split = SplitItem(\n", " panel_1=panel_sync1,\n", " panel_2=panel_sync2,\n", " direction=SplitDirection.VERTICAL,\n", ")\n", "\n", "sync_layout = SplitLayout(sync_split)\n", "# sync_layout" ] }, { "cell_type": "markdown", "id": "t2-summary", "metadata": {}, "source": [ "## Summary\n", "\n", "In this tutorial, you learned:\n", "1. **SplitLayout**: Two-panel layouts with draggable dividers — vertical (side by side) and horizontal (stacked)\n", "2. **Nested splits**: Building complex multi-panel layouts by nesting `SplitItem` instances\n", "3. **GridStackLayout**: Flexible multi-panel grids with drag-and-drop resizing and configurable cell bounds\n", "4. **Save/Restore**: Persisting layout configurations to zip files with `save_to_zip()` and `restore_from_zip()`\n", "5. **Field synchronization**: Linking field selections across panels using `sync_field=True`\n", "\n", "## Next Steps\n", "\n", "- [Tutorial 3: 2D-1D Panel Interactions](./3_panel_2d_1d_interactions.ipynb) — Link 2D geometry views with 1D line plots\n", "- [Tutorial 4: Developing an Interface (Dev)](./4_develop_interface.ipynb) — Create custom data interfaces" ] } ], "metadata": { "kernelspec": { "display_name": "venv_t4", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.12" } }, "nbformat": 4, "nbformat_minor": 5 }