Skip to content

Commit

Permalink
add pygfx stub
Browse files Browse the repository at this point in the history
  • Loading branch information
tlambert03 committed Jan 21, 2025
1 parent 4a34909 commit a900665
Show file tree
Hide file tree
Showing 16 changed files with 471 additions and 38 deletions.
4 changes: 1 addition & 3 deletions src/ndv/models/_scene/_transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@

import numpy as np
from numpy.typing import ArrayLike, DTypeLike, NDArray
from pydantic import ConfigDict, RootModel
from pydantic import ConfigDict, Field, RootModel
from pydantic_core import core_schema

Check warning on line 11 in src/ndv/models/_scene/_transform.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/_transform.py#L8-L11

Added lines #L8 - L11 were not covered by tests

from ._vis_model import Field

if TYPE_CHECKING:
from collections.abc import Iterable, Sized

Expand Down
36 changes: 31 additions & 5 deletions src/ndv/models/_scene/_vis_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,22 @@
from abc import abstractmethod
from contextlib import suppress
from importlib import import_module
from typing import TYPE_CHECKING, Any, ClassVar, Generic, Protocol, TypeVar, cast
from typing import (

Check warning on line 8 in src/ndv/models/_scene/_vis_model.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/_vis_model.py#L3-L8

Added lines #L3 - L8 were not covered by tests
TYPE_CHECKING,
Any,
ClassVar,
Generic,
Protocol,
TypeVar,
cast,
)

from psygnal import EmissionInfo, SignalGroupDescriptor
from pydantic import BaseModel, ConfigDict
from pydantic.fields import Field

Check warning on line 20 in src/ndv/models/_scene/_vis_model.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/_vis_model.py#L18-L20

Added lines #L18 - L20 were not covered by tests

if TYPE_CHECKING:
from collections.abc import Iterable
from collections.abc import Iterable, Iterator

__all__ = ["Field", "ModelBase", "SupportsVisibility", "VisModel"]

Check warning on line 25 in src/ndv/models/_scene/_vis_model.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/_vis_model.py#L25

Added line #L25 was not covered by tests

Expand Down Expand Up @@ -252,13 +260,31 @@ def _get_default_backend() -> str:
This will likely be context dependent.
"""
return "vispy"
from ndv.views._app import canvas_backend

Check warning on line 263 in src/ndv/models/_scene/_vis_model.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/_vis_model.py#L263

Added line #L263 was not covered by tests

return canvas_backend(None).value

Check warning on line 265 in src/ndv/models/_scene/_vis_model.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/_vis_model.py#L265

Added line #L265 was not covered by tests


def _update_blocker(adaptor: BackendAdaptor) -> contextlib.AbstractContextManager:
from ndv.models._scene.nodes.node import NodeAdaptorProtocol

Check warning on line 269 in src/ndv/models/_scene/_vis_model.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/_vis_model.py#L268-L269

Added lines #L268 - L269 were not covered by tests

if isinstance(adaptor, NodeAdaptorProtocol):

Check warning on line 271 in src/ndv/models/_scene/_vis_model.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/_vis_model.py#L271

Added line #L271 was not covered by tests

@contextlib.contextmanager
def blocker() -> Iterator[None]:
adaptor._vis_block_updates()
try:
yield

Check warning on line 277 in src/ndv/models/_scene/_vis_model.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/_vis_model.py#L273-L277

Added lines #L273 - L277 were not covered by tests
finally:
adaptor._vis_unblock_updates()

Check warning on line 279 in src/ndv/models/_scene/_vis_model.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/_vis_model.py#L279

Added line #L279 was not covered by tests

return blocker()
return contextlib.nullcontext()

Check warning on line 282 in src/ndv/models/_scene/_vis_model.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/_vis_model.py#L281-L282

Added lines #L281 - L282 were not covered by tests


def sync_adaptor(adaptor: BackendAdaptor, model: VisModel) -> None:

Check warning on line 285 in src/ndv/models/_scene/_vis_model.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/_vis_model.py#L285

Added line #L285 was not covered by tests
"""Decorator to validate and cache adaptor classes."""
blocker = getattr(adaptor, "_vis_updates_blocked", contextlib.nullcontext)
with blocker():
with _update_blocker(adaptor):
for field_name in model.model_fields:
method_name = SETTER_METHOD.format(name=field_name)
value = getattr(model, field_name)
Expand Down
11 changes: 5 additions & 6 deletions src/ndv/models/_scene/canvas.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@

from cmap import Color # noqa: TC002
from psygnal.containers import EventedList
from pydantic import Field

Check warning on line 9 in src/ndv/models/_scene/canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/canvas.py#L7-L9

Added lines #L7 - L9 were not covered by tests

from ._vis_model import Field, SupportsVisibility, VisModel
from ._vis_model import SupportsVisibility, VisModel
from .view import View

Check warning on line 12 in src/ndv/models/_scene/canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/canvas.py#L11-L12

Added lines #L11 - L12 were not covered by tests

if TYPE_CHECKING:
Expand Down Expand Up @@ -58,10 +59,8 @@ class Canvas(VisModel[CanvasAdaptorProtocol]):
an orthoviewer might be a single canvas with three views, one for each axis.
"""

width: float = Field(default=500, description="The width of the canvas in pixels.")
height: float = Field(
default=500, description="The height of the canvas in pixels."
)
width: int = Field(default=500, description="The width of the canvas in pixels.")
height: int = Field(default=500, description="The height of the canvas in pixels.")
background_color: Color | None = Field(

Check warning on line 64 in src/ndv/models/_scene/canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/canvas.py#L62-L64

Added lines #L62 - L64 were not covered by tests
default=None,
description="The background color. None implies transparent "
Expand All @@ -72,7 +71,7 @@ class Canvas(VisModel[CanvasAdaptorProtocol]):
views: ViewList[View] = Field(default_factory=lambda: ViewList(), frozen=True)

Check warning on line 71 in src/ndv/models/_scene/canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/canvas.py#L69-L71

Added lines #L69 - L71 were not covered by tests

@property
def size(self) -> tuple[float, float]:
def size(self) -> tuple[int, int]:

Check warning on line 74 in src/ndv/models/_scene/canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/canvas.py#L73-L74

Added lines #L73 - L74 were not covered by tests
"""Return the size of the canvas."""
return self.width, self.height

Check warning on line 76 in src/ndv/models/_scene/canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/canvas.py#L76

Added line #L76 was not covered by tests

Expand Down
3 changes: 2 additions & 1 deletion src/ndv/models/_scene/nodes/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
from abc import abstractmethod
from typing import Literal, Protocol

Check warning on line 4 in src/ndv/models/_scene/nodes/camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/nodes/camera.py#L3-L4

Added lines #L3 - L4 were not covered by tests

from pydantic import Field

Check warning on line 6 in src/ndv/models/_scene/nodes/camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/nodes/camera.py#L6

Added line #L6 was not covered by tests

from ndv._types import CameraType

Check warning on line 8 in src/ndv/models/_scene/nodes/camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/nodes/camera.py#L8

Added line #L8 was not covered by tests
from ndv.models._scene._vis_model import Field

from .node import Node, NodeAdaptorProtocol

Check warning on line 10 in src/ndv/models/_scene/nodes/camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/nodes/camera.py#L10

Added line #L10 was not covered by tests

Expand Down
14 changes: 10 additions & 4 deletions src/ndv/models/_scene/nodes/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,22 @@
TypeVar,
Union,
cast,
runtime_checkable,
)

from pydantic import (

Check warning on line 17 in src/ndv/models/_scene/nodes/node.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/nodes/node.py#L17

Added line #L17 was not covered by tests
Field,
SerializerFunctionWrapHandler,
field_validator,
model_serializer,
)

from ndv.models._scene._transform import Transform
from ndv.models._scene._vis_model import Field, SupportsVisibility, VisModel
from ndv.models._scene._vis_model import SupportsVisibility, VisModel
from ndv.models._sequence import ValidatedEventedList

Check warning on line 26 in src/ndv/models/_scene/nodes/node.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/nodes/node.py#L24-L26

Added lines #L24 - L26 were not covered by tests

if TYPE_CHECKING:
from collections.abc import Iterator
from contextlib import AbstractContextManager

logger = logging.getLogger(__name__)
NodeTypeCoV = TypeVar("NodeTypeCoV", bound="Node", covariant=True)
Expand All @@ -34,6 +35,7 @@
)


@runtime_checkable
class NodeAdaptorProtocol(SupportsVisibility[NodeTypeCoV], Protocol):

Check warning on line 39 in src/ndv/models/_scene/nodes/node.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/nodes/node.py#L38-L39

Added lines #L38 - L39 were not covered by tests
"""Backend interface for a Node."""

Expand All @@ -58,8 +60,12 @@ def _vis_set_node_type(self, arg: str) -> None:
pass

@abstractmethod
def _vis_updates_blocked(self) -> AbstractContextManager:
"""Return a context manager that blocks updates to the node."""
def _vis_block_updates(self) -> None:

Check warning on line 63 in src/ndv/models/_scene/nodes/node.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/nodes/node.py#L62-L63

Added lines #L62 - L63 were not covered by tests
"""Block future updates until `unblock_updates` is called."""

@abstractmethod
def _vis_unblock_updates(self) -> None:

Check warning on line 67 in src/ndv/models/_scene/nodes/node.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/nodes/node.py#L66-L67

Added lines #L66 - L67 were not covered by tests
"""Unblock updates after `block_updates` was called."""

@abstractmethod
def _vis_force_update(self) -> None:

Check warning on line 71 in src/ndv/models/_scene/nodes/node.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_scene/nodes/node.py#L70-L71

Added lines #L70 - L71 were not covered by tests
Expand Down
5 changes: 4 additions & 1 deletion src/ndv/models/_sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,10 @@ def __len__(self) -> int:
return len(self._list)

Check warning on line 91 in src/ndv/models/_sequence.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_sequence.py#L90-L91

Added lines #L90 - L91 were not covered by tests

def __eq__(self, value: object) -> bool:

Check warning on line 93 in src/ndv/models/_sequence.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_sequence.py#L93

Added line #L93 was not covered by tests
return self._list == value
# TODO: this can cause recursion errors for recursive models
if isinstance(value, ValidatedEventedList):
return self._list == value._list
return NotImplemented

Check warning on line 97 in src/ndv/models/_sequence.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/models/_sequence.py#L95-L97

Added lines #L95 - L97 were not covered by tests

# -----------------------------------------------------

Expand Down
8 changes: 8 additions & 0 deletions src/ndv/views/_scene/pygfx/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from ._camera import Camera
from ._canvas import Canvas
from ._image import Image
from ._node import Node
from ._scene import Scene
from ._view import View

Check warning on line 6 in src/ndv/views/_scene/pygfx/__init__.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/__init__.py#L1-L6

Added lines #L1 - L6 were not covered by tests

__all__ = ["Camera", "Canvas", "Image", "Node", "Scene", "View"]

Check warning on line 8 in src/ndv/views/_scene/pygfx/__init__.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/__init__.py#L8

Added line #L8 was not covered by tests
57 changes: 57 additions & 0 deletions src/ndv/views/_scene/pygfx/_camera.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from __future__ import annotations

Check warning on line 1 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L1

Added line #L1 was not covered by tests

import warnings
from typing import Any

Check warning on line 4 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L3-L4

Added lines #L3 - L4 were not covered by tests

import pygfx

Check warning on line 6 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L6

Added line #L6 was not covered by tests

from ndv._types import CameraType
from ndv.models._scene.nodes import camera

Check warning on line 9 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L8-L9

Added lines #L8 - L9 were not covered by tests

from ._node import Node

Check warning on line 11 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L11

Added line #L11 was not covered by tests


class Camera(Node, camera.CameraAdaptorProtocol):

Check warning on line 14 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L14

Added line #L14 was not covered by tests
"""Adaptor for pygfx camera."""

_pygfx_node: pygfx.Camera

Check warning on line 17 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L17

Added line #L17 was not covered by tests

def __init__(self, camera: camera.Camera, **backend_kwargs: Any) -> None:
if camera.type == CameraType.PANZOOM:
self._pygfx_node = pygfx.OrthographicCamera(**backend_kwargs)
self.controller = pygfx.PanZoomController(self._pygfx_node)
elif camera.type == CameraType.ARCBALL:
self._pygfx_node = pygfx.PerspectiveCamera(**backend_kwargs)
self.controller = pygfx.OrbitOrthoController(self._pygfx_node)

Check warning on line 25 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L19-L25

Added lines #L19 - L25 were not covered by tests

# FIXME: hardcoded
# self._pygfx_cam.scale.y = -1

def _vis_set_zoom(self, zoom: float) -> None:

Check warning on line 30 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L30

Added line #L30 was not covered by tests
raise NotImplementedError

def _vis_set_center(self, arg: tuple[float, ...]) -> None:
raise NotImplementedError

def _vis_set_type(self, arg: CameraType) -> None:

Check warning on line 36 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L36

Added line #L36 was not covered by tests
raise NotImplementedError

def _view_size(self) -> tuple[float, float] | None:

Check warning on line 39 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L39

Added line #L39 was not covered by tests
"""Return the size of first parent viewbox in pixels."""
raise NotImplementedError

def update_controller(self) -> None:

Check warning on line 43 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L43

Added line #L43 was not covered by tests
# This is called by the View Adaptor in the `_visit` method
# ... which is in turn called by the Canvas backend adaptor's `_animate` method
# i.e. the main render loop.
self.controller.update_camera(self._pygfx_node)

Check warning on line 47 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L47

Added line #L47 was not covered by tests

def set_viewport(self, viewport: pygfx.Viewport) -> None:

Check warning on line 49 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L49

Added line #L49 was not covered by tests
# This is used by the Canvas backend adaptor...
# and should perhaps be moved to the View Adaptor
self.controller.add_default_event_handlers(viewport, self._pygfx_node)

Check warning on line 52 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L52

Added line #L52 was not covered by tests

def _vis_set_range(self, margin: float) -> None:
warnings.warn(

Check warning on line 55 in src/ndv/views/_scene/pygfx/_camera.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_camera.py#L54-L55

Added lines #L54 - L55 were not covered by tests
"set_range not implemented for pygfx", RuntimeWarning, stacklevel=2
)
117 changes: 117 additions & 0 deletions src/ndv/views/_scene/pygfx/_canvas.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
from __future__ import annotations

Check warning on line 1 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L1

Added line #L1 was not covered by tests

from contextlib import suppress
from typing import TYPE_CHECKING, Any, Union, cast

Check warning on line 4 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L3-L4

Added lines #L3 - L4 were not covered by tests

import pygfx

Check warning on line 6 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L6

Added line #L6 was not covered by tests

from ndv.models import _scene as core

Check warning on line 8 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L8

Added line #L8 was not covered by tests

if TYPE_CHECKING:
import numpy as np
from cmap import Color
from typing_extensions import TypeAlias
from wgpu.gui import glfw, jupyter, offscreen, qt

from ._view import View

# from wgpu.gui.auto import WgpuCanvas
# ... will result in one of the following canvas classes
TypeWgpuCanvasType: TypeAlias = Union[
type[offscreen.WgpuCanvas], # if WGPU_FORCE_OFFSCREEN=1
type[jupyter.WgpuCanvas], # if is_jupyter()
type[glfw.WgpuCanvas], # if glfw is installed
type[qt.WgpuCanvas], # if any pyqt backend is installed
]
# TODO: lol... there's probably a better way to do this :)
WgpuCanvasType: TypeAlias = Union[
offscreen.WgpuCanvas, # if WGPU_FORCE_OFFSCREEN=1
jupyter.WgpuCanvas, # if is_jupyter()
glfw.WgpuCanvas, # if glfw is installed
qt.WgpuCanvas, # if any pyqt backend is installed
]


class Canvas(core.canvas.CanvasAdaptorProtocol):

Check warning on line 35 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L35

Added line #L35 was not covered by tests
"""Canvas interface for pygfx Backend."""

def __init__(self, canvas: core.Canvas, **backend_kwargs: Any) -> None:

Check warning on line 38 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L38

Added line #L38 was not covered by tests
# wgpu.gui.auto.WgpuCanvas is a "magic" import that itself is context sensitive
# see TYPE_CHECKING section above for details
from wgpu.gui.auto import WgpuCanvas

Check warning on line 41 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L41

Added line #L41 was not covered by tests

WgpuCanvas = cast("TypeWgpuCanvasType", WgpuCanvas)

Check warning on line 43 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L43

Added line #L43 was not covered by tests

canvas = WgpuCanvas(size=canvas.size, title=canvas.title, **backend_kwargs)
self._wgpu_canvas = cast("WgpuCanvasType", canvas)

Check warning on line 46 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L45-L46

Added lines #L45 - L46 were not covered by tests
# TODO: background_color
# the qt backend, this shows by default...
# if we need to prevent it, we could potentially monkeypatch during init.
if hasattr(self._wgpu_canvas, "hide"):
self._wgpu_canvas.hide()

Check warning on line 51 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L50-L51

Added lines #L50 - L51 were not covered by tests

self._renderer = pygfx.renderers.WgpuRenderer(self._wgpu_canvas)
self._viewport: pygfx.Viewport = pygfx.Viewport(self._renderer)
self._views: list[View] = []

Check warning on line 55 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L53-L55

Added lines #L53 - L55 were not covered by tests
# self._grid: dict[tuple[int, int], View] = {}

def _vis_get_native(self) -> WgpuCanvasType:
return self._wgpu_canvas

Check warning on line 59 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L58-L59

Added lines #L58 - L59 were not covered by tests

def _vis_set_visible(self, arg: bool) -> None:
if hasattr(self._wgpu_canvas, "show"):
self._wgpu_canvas.show()
self._wgpu_canvas.request_draw(self._animate)

Check warning on line 64 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L61-L64

Added lines #L61 - L64 were not covered by tests

def _animate(self, viewport: pygfx.Viewport | None = None) -> None:
vp = viewport or self._viewport
for view in self._views:
view._visit(vp)
if hasattr(vp.renderer, "flush"):

Check warning on line 70 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L66-L70

Added lines #L66 - L70 were not covered by tests
# an attribute error can occur if flush() is called before render()
# https://github.com/pygfx/pygfx/issues/946
with suppress(AttributeError):
vp.renderer.flush()
if viewport is None:
self._wgpu_canvas.request_draw()

Check warning on line 76 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L73-L76

Added lines #L73 - L76 were not covered by tests

def _vis_add_view(self, view: core.View) -> None:
adaptor = cast("View", view.backend_adaptor())

Check warning on line 79 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L78-L79

Added lines #L78 - L79 were not covered by tests
# adaptor._pygfx_cam.set_viewport(self._viewport)
self._views.append(adaptor)

Check warning on line 81 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L81

Added line #L81 was not covered by tests

def _vis_set_width(self, arg: int) -> None:
_, height = self._wgpu_canvas.get_logical_size()
self._wgpu_canvas.set_logical_size(arg, height)

Check warning on line 85 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L83-L85

Added lines #L83 - L85 were not covered by tests

def _vis_set_height(self, arg: int) -> None:
width, _ = self._wgpu_canvas.get_logical_size()
self._wgpu_canvas.set_logical_size(width, arg)

Check warning on line 89 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L87-L89

Added lines #L87 - L89 were not covered by tests

def _vis_set_background_color(self, arg: Color | None) -> None:

Check warning on line 91 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L91

Added line #L91 was not covered by tests
raise NotImplementedError()

def _vis_set_title(self, arg: str) -> None:

Check warning on line 94 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L94

Added line #L94 was not covered by tests
raise NotImplementedError()

def _vis_close(self) -> None:

Check warning on line 97 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L97

Added line #L97 was not covered by tests
"""Close canvas."""
self._wgpu_canvas.close()

Check warning on line 99 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L99

Added line #L99 was not covered by tests

def _vis_render(

Check warning on line 101 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L101

Added line #L101 was not covered by tests
self,
region: tuple[int, int, int, int] | None = None,
size: tuple[int, int] | None = None,
bgcolor: Color | None = None,
crop: np.ndarray | tuple[int, int, int, int] | None = None,
alpha: bool = True,
) -> np.ndarray:
"""Render to screenshot."""
from wgpu.gui.offscreen import WgpuCanvas

Check warning on line 110 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L110

Added line #L110 was not covered by tests

w, h = self._wgpu_canvas.get_logical_size()
canvas = WgpuCanvas(width=w, height=h, pixel_ratio=1)
renderer = pygfx.renderers.WgpuRenderer(canvas)
viewport = pygfx.Viewport(renderer)
canvas.request_draw(lambda: self._animate(viewport))
return cast("np.ndarray", canvas.draw())

Check warning on line 117 in src/ndv/views/_scene/pygfx/_canvas.py

View check run for this annotation

Codecov / codecov/patch

src/ndv/views/_scene/pygfx/_canvas.py#L112-L117

Added lines #L112 - L117 were not covered by tests
Loading

0 comments on commit a900665

Please sign in to comment.