From 7c874b598cc39c5477a883dd45a7147021ddec32 Mon Sep 17 00:00:00 2001 From: Lachlan Grose Date: Mon, 30 Sep 2024 09:17:08 +1000 Subject: [PATCH] vue template and initialisation --- .../_register_loop_ui.py | 5 ++ loopstructuralvisualisation/trame/__init__.py | 40 ++++++++++ .../trame/ui/vuetify3.py | 80 +++++++++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 loopstructuralvisualisation/_register_loop_ui.py create mode 100644 loopstructuralvisualisation/trame/__init__.py create mode 100644 loopstructuralvisualisation/trame/ui/vuetify3.py diff --git a/loopstructuralvisualisation/_register_loop_ui.py b/loopstructuralvisualisation/_register_loop_ui.py new file mode 100644 index 0000000..8ec129b --- /dev/null +++ b/loopstructuralvisualisation/_register_loop_ui.py @@ -0,0 +1,5 @@ +import pyvista +from .trame import initialize + + +pyvista.trame.jupyter.initialize = initialize diff --git a/loopstructuralvisualisation/trame/__init__.py b/loopstructuralvisualisation/trame/__init__.py new file mode 100644 index 0000000..8cf5647 --- /dev/null +++ b/loopstructuralvisualisation/trame/__init__.py @@ -0,0 +1,40 @@ +from pyvista.trame.ui import UI_TITLE +from pyvista.trame.ui import get_viewer +from .ui.vuetify3 import LoopViewer as Viewer +from .. import Loop3DView + + +def initialize( + server, + plotter, + mode=None, + default_server_rendering=True, + collapse_menu=False, + **kwargs, +): # numpydoc ignore=PR01,RT01 + """Generate the UI for a given plotter.""" + state = server.state + state.trame__title = UI_TITLE + if issubclass(type(plotter), Loop3DView): + # only use the loopviewer if the plotter is a Loop3DView + viewer = Viewer(plotter, server=server) + + else: + # if pyvista use trame.ui.Viewer + viewer = get_viewer( + plotter, + server=server, + suppress_rendering=mode == "client", + ) + with viewer.make_layout(server, template_name=plotter._id_name) as layout: + viewer.layout = layout + viewer.ui( + mode=mode, + default_server_rendering=default_server_rendering, + collapse_menu=collapse_menu, + **kwargs, + ) + if issubclass(type(plotter), Loop3DView): + viewer.object_menu() + + return viewer diff --git a/loopstructuralvisualisation/trame/ui/vuetify3.py b/loopstructuralvisualisation/trame/ui/vuetify3.py new file mode 100644 index 0000000..00e919a --- /dev/null +++ b/loopstructuralvisualisation/trame/ui/vuetify3.py @@ -0,0 +1,80 @@ +# ruff: noqa: D102,D103,D107 +"""PyVista Trame Viewer class for a Vue 3 client. + +This class, derived from `pyvista.trame.ui.base_viewer`, +is intended for use with a trame application where the client type is "vue3". +Therefore, the `ui` method implemented by this class utilizes the API of Vuetify 3. +""" + +from __future__ import annotations + +from turtle import onclick +from typing import TYPE_CHECKING + +from cycler import V +from trame.ui.vuetify3 import VAppLayout, SinglePageWithDrawerLayout +from trame.widgets import html +from trame.widgets import vuetify3 as vuetify +from trame.widgets import trame +from pyvista.trame.views import PyVistaLocalView +from pyvista.trame.views import PyVistaRemoteLocalView +from pyvista.trame.views import PyVistaRemoteView + +from pyvista.trame.ui.base_viewer import BaseViewer +from pyvista.trame.ui.vuetify3 import Viewer +from trame.widgets.vuetify3 import VTreeview + + +if TYPE_CHECKING: # pragma: no cover + from trame_client.ui.core import AbstractLayout + +test = {} + + +class LoopViewer(Viewer): + def __init__(self, *args, **kwargs): + """Overwrite the pyvista trame layout to use a singlepage layout + and add an object visibility menu to the drawer + """ + super().__init__(*args, **kwargs) + + def make_layout(self, *args, **kwargs): + + return SinglePageWithDrawerLayout(*args, **kwargs) + + def ui(self, *args, **kwargs): + with self.layout.content: + return super().ui(*args, **kwargs) + + def toggle_visibility(self, **kwargs): + """Toggle the visibility of an object in the plotter. + this is a slot called by the state change, the kwargs are the current state + so we need to check the keys and update accordingly + """ + for k in kwargs.keys(): + object_name = k.split("__")[0] + test[object_name] = kwargs[k] + if object_name in self.plotter.objects: + self.plotter.objects[object_name]["actor"].visibility = kwargs[k] + self.update() + # self.actors[k].visibility = not self.actors[k].visibility + + def object_menu(self): + with self.layout.drawer as drawer: + with vuetify.VCard(): + + for k, a in self.plotter.objects.items(): + drawer.server.state[f"{k}__visibility"] = True + drawer.server.state.change(f"{k}__visibility")(self.toggle_visibility) + + with vuetify.VRow(): + with vuetify.VCol(): + + vuetify.VCheckbox( + label=k, + v_model=(f"{k}__visibility"), + # click=(self.toggle_visibility("test")), + ) + # vuetify.VCheckbox(label="Test") + # vuetify.VCheckbox(label="Test") + # vuetify.VCheckbox(label="Test")