From c04c42c04a8616e22a61a762e1b2cf312bfcb8ea Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Wed, 6 Nov 2024 11:05:19 +0100 Subject: [PATCH] Rename (#7) --- README.md | 6 +-- docs/api.rst | 8 ++-- docs/conf.py | 2 +- docs/gui.rst | 44 +++++++++---------- docs/guide.rst | 4 +- docs/start.rst | 10 ++--- examples/{gui_auto.py => cube_auto.py} | 6 +-- examples/{gui_glfw.py => cube_glfw.py} | 4 +- examples/{gui_qt.py => cube_qt.py} | 4 +- examples/{gui_wx.py => cube_wx.py} | 4 +- examples/{gui_demo.py => demo.py} | 4 +- examples/{gui_events.py => events.py} | 4 +- examples/{gui_multiple.py => multiple.py} | 6 +-- ...{gui_threading.py => offsceen_threaded.py} | 4 +- examples/{gui_qt_embed.py => qt_app.py} | 4 +- .../{gui_qt_asyncio.py => qt_app_asyncio.py} | 6 +-- examples/{gui_wx_embed.py => wx_app.py} | 6 +-- rendercanvas/__init__.py | 14 +++--- rendercanvas/_events.py | 12 ++--- rendercanvas/_gui_utils.py | 8 ++-- rendercanvas/_loop.py | 20 ++++----- rendercanvas/asyncio.py | 12 ++--- rendercanvas/auto.py | 30 ++++++------- rendercanvas/base.py | 22 +++++----- rendercanvas/glfw.py | 26 +++++------ rendercanvas/jupyter.py | 22 +++++----- rendercanvas/offscreen.py | 14 +++--- rendercanvas/qt.py | 40 ++++++++--------- rendercanvas/utils/cube.py | 4 +- rendercanvas/wx.py | 34 +++++++------- tests/{test_gui_base.py => test_base.py} | 14 +++--- tests/{test_gui_events.py => test_events.py} | 4 +- tests/{test_gui_glfw.py => test_glfw.py} | 18 ++++---- ...est_gui_offscreen.py => test_offscreen.py} | 10 ++--- ...t_gui_scheduling.py => test_scheduling.py} | 26 +++++------ tests/{test_gui_utils.py => test_utils.py} | 0 36 files changed, 228 insertions(+), 228 deletions(-) rename examples/{gui_auto.py => cube_auto.py} (65%) rename examples/{gui_glfw.py => cube_glfw.py} (67%) rename examples/{gui_qt.py => cube_qt.py} (84%) rename examples/{gui_wx.py => cube_wx.py} (68%) rename examples/{gui_demo.py => demo.py} (95%) rename examples/{gui_events.py => events.py} (65%) rename examples/{gui_multiple.py => multiple.py} (69%) rename examples/{gui_threading.py => offsceen_threaded.py} (94%) rename examples/{gui_qt_embed.py => qt_app.py} (95%) rename examples/{gui_qt_asyncio.py => qt_app_asyncio.py} (94%) rename examples/{gui_wx_embed.py => wx_app.py} (87%) rename tests/{test_gui_base.py => test_base.py} (93%) rename tests/{test_gui_events.py => test_events.py} (98%) rename tests/{test_gui_glfw.py => test_glfw.py} (93%) rename tests/{test_gui_offscreen.py => test_offscreen.py} (83%) rename tests/{test_gui_scheduling.py => test_scheduling.py} (90%) rename tests/{test_gui_utils.py => test_utils.py} (100%) diff --git a/README.md b/README.md index 3deb784..3ed79b7 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ by producing rgba images. pip install rendercanvas ``` -To have at least one GUI backend, we recommend: +To have at least one backend, we recommend: ``` pip install rendercanvas glfw ``` @@ -53,11 +53,11 @@ Also see the [online documentation](https://rendercanvas.readthedocs.io) and the ```py # Select either the glfw, qt or jupyter backend -from rendercanvas.auto import WgpuCanvas, loop +from rendercanvas.auto import RenderCanvas, loop # Visualizations can be embedded as a widget in a Qt application. # Supported qt libs are PySide6, PyQt6, PySide2 or PyQt5. -from rendercanvas.pyside6 import QWgpuWidget +from rendercanvas.pyside6 import QRenderWidget # Now specify what the canvas should do on a draw diff --git a/docs/api.rst b/docs/api.rst index 1929774..b62fbed 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -1,14 +1,14 @@ rendercanvas base classes ========================= -.. autoclass:: rendercanvas.base.WgpuCanvasInterface +.. autoclass:: rendercanvas.base.RenderCanvasInterface :members: -.. autoclass:: rendercanvas.base.WgpuCanvasBase +.. autoclass:: rendercanvas.base.BaseRenderCanvas :members: -.. .. autoclass:: rendercanvas.base.WgpuLoop +.. .. autoclass:: rendercanvas.base.BaseLoop .. :members: -.. .. autoclass:: rendercanvas.base.WgpuTimer +.. .. autoclass:: rendercanvas.base.BaseTimer .. :members: diff --git a/docs/conf.py b/docs/conf.py index aad2807..f751318 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -47,7 +47,7 @@ intersphinx_mapping = { "python": ("https://docs.python.org/3", None), "numpy": ("https://numpy.org/doc/stable", None), - "wgpu": ("https://wgpu-py.readthedocs.io/en/latest", None), + "wgpu": ("https://wgpu-py.readthedocs.io/en/stable", None), } # Add any paths that contain templates here, relative to this directory. diff --git a/docs/gui.rst b/docs/gui.rst index fa55c02..1513274 100644 --- a/docs/gui.rst +++ b/docs/gui.rst @@ -13,8 +13,8 @@ moment these include GLFW, Jupyter, Qt, and wx. The Canvas base classes ----------------------- -For each supported GUI toolkit there is a module that implements a ``WgpuCanvas`` class, -which inherits from :class:`WgpuCanvasBase`, providing a common API. +For each supported GUI toolkit there is a module that implements a ``RenderCanvas`` class, +which inherits from :class:`BaseRenderCanvas`, providing a common API. The GLFW, Qt, and Jupyter backends also inherit from :class:`WgpuAutoGui` to include support for events (interactivity). In the next sections we demonstrates the different canvas classes that you can use. @@ -23,10 +23,10 @@ canvas classes that you can use. Events ------ -To implement interaction with a ``WgpuCanvas``, use the :func:`WgpuCanvasBase.add_event_handler()` method. +To implement interaction with a ``RenderCanvas``, use the :func:`BaseRenderCanvas.add_event_handler()` method. Events come in the following flavours: -.. autoclass:: WgpuEventType +.. autoclass:: EventType :members: @@ -47,9 +47,9 @@ for details about the event objects. .. code-block:: py - from wgpu.gui.auto import WgpuCanvas, run, call_later + from wgpu.gui.auto import RenderCanvas, run, call_later - canvas = WgpuCanvas(title="Example") + canvas = RenderCanvas(title="Example") canvas.request_draw(your_draw_function) run() @@ -64,9 +64,9 @@ but you can replace ``from rendercanvas.auto`` with ``from rendercanvas.glfw`` t .. code-block:: py - from wgpu.gui.glfw import WgpuCanvas, run, call_later + from wgpu.gui.glfw import RenderCanvas, run, call_later - canvas = WgpuCanvas(title="Example") + canvas = RenderCanvas(title="Example") canvas.request_draw(your_draw_function) run() @@ -77,23 +77,23 @@ Support for Qt There is support for PyQt5, PyQt6, PySide2 and PySide6. The rendercanvas library detects what library you are using by looking what module has been imported. -For a toplevel widget, the ``rendercanvas.qt.WgpuCanvas`` class can be imported. If you want to -embed the canvas as a subwidget, use ``rendercanvas.qt.WgpuWidget`` instead. +For a toplevel widget, the ``rendercanvas.qt.RenderCanvas`` class can be imported. If you want to +embed the canvas as a subwidget, use ``rendercanvas.qt.QRenderWidget`` instead. Also see the `Qt triangle example `_ and `Qt triangle embed example `_. .. code-block:: py - # Import any of the Qt libraries before importing the WgpuCanvas. + # Import any of the Qt libraries before importing the RenderCanvas. # This way wgpu knows which Qt library to use. from PySide6 import QtWidgets - from wgpu.gui.qt import WgpuCanvas + from wgpu.gui.qt import RenderCanvas app = QtWidgets.QApplication([]) # Instantiate the canvas - canvas = WgpuCanvas(title="Example") + canvas = RenderCanvas(title="Example") # Tell the canvas what drawing function to call canvas.request_draw(your_draw_function) @@ -105,8 +105,8 @@ Support for wx -------------- There is support for embedding a wgpu visualization in wxPython. -For a toplevel widget, the ``gui.wx.WgpuCanvas`` class can be imported. If you want to -embed the canvas as a subwidget, use ``gui.wx.WgpuWidget`` instead. +For a toplevel widget, the ``gui.wx.RenderCanvas`` class can be imported. If you want to +embed the canvas as a subwidget, use ``gui.wx.RenderWidget`` instead. Also see the `wx triangle example `_ and `wx triangle embed example `_. @@ -114,12 +114,12 @@ and `wx triangle embed example ` for details: +Multiple backends are supported, including multiple GUI libraries, see :doc:`the GUI API ` for details: -* `glfw `_: a lightweight GUI for the desktop -* `jupyter_rfb `_: only needed if you plan on using wgpu in Jupyter +* `glfw `_: a lightweight canvas for the desktop +* `jupyter_rfb `_: only needed if you plan on using Jupyter * qt (PySide6, PyQt6, PySide2, PyQt5) * wx diff --git a/examples/gui_auto.py b/examples/cube_auto.py similarity index 65% rename from examples/gui_auto.py rename to examples/cube_auto.py index 668c7ad..cb6c156 100644 --- a/examples/gui_auto.py +++ b/examples/cube_auto.py @@ -2,13 +2,13 @@ Run a wgpu example on an automatically selected backend. """ -from rendercanvas.auto import WgpuCanvas, run +from rendercanvas.auto import RenderCanvas, run from rendercanvas.utils.cube import setup_drawing_sync -canvas = WgpuCanvas( - size=(640, 480), title=f"The wgpu cube example on a {WgpuCanvas.__name__}" +canvas = RenderCanvas( + size=(640, 480), title=f"The wgpu cube example on a {RenderCanvas.__name__}" ) draw_frame = setup_drawing_sync(canvas) diff --git a/examples/gui_glfw.py b/examples/cube_glfw.py similarity index 67% rename from examples/gui_glfw.py rename to examples/cube_glfw.py index bb8fbc3..e1a5529 100644 --- a/examples/gui_glfw.py +++ b/examples/cube_glfw.py @@ -2,12 +2,12 @@ Run a wgpu example on the glfw backend. """ -from rendercanvas.glfw import WgpuCanvas, run +from rendercanvas.glfw import RenderCanvas, run from rendercanvas.utils.cube import setup_drawing_sync -canvas = WgpuCanvas(size=(640, 480), title="The wgpu cube example on glfw") +canvas = RenderCanvas(size=(640, 480), title="The wgpu cube example on glfw") draw_frame = setup_drawing_sync(canvas) diff --git a/examples/gui_qt.py b/examples/cube_qt.py similarity index 84% rename from examples/gui_qt.py rename to examples/cube_qt.py index 4289027..09be663 100644 --- a/examples/gui_qt.py +++ b/examples/cube_qt.py @@ -18,12 +18,12 @@ pass -from rendercanvas.qt import WgpuCanvas, run +from rendercanvas.qt import RenderCanvas, run from rendercanvas.utils.cube import setup_drawing_sync -canvas = WgpuCanvas(size=(640, 480), title=f"The wgpu cube example on {lib}") +canvas = RenderCanvas(size=(640, 480), title=f"The wgpu cube example on {lib}") draw_frame = setup_drawing_sync(canvas) diff --git a/examples/gui_wx.py b/examples/cube_wx.py similarity index 68% rename from examples/gui_wx.py rename to examples/cube_wx.py index b1fce04..22441b6 100644 --- a/examples/gui_wx.py +++ b/examples/cube_wx.py @@ -2,12 +2,12 @@ Run a wgpu example on the wx backend. """ -from rendercanvas.wx import WgpuCanvas, run +from rendercanvas.wx import RenderCanvas, run from rendercanvas.utils.cube import setup_drawing_sync -canvas = WgpuCanvas(size=(640, 480), title="The wgpu cube example on wx") +canvas = RenderCanvas(size=(640, 480), title="The wgpu cube example on wx") draw_frame = setup_drawing_sync(canvas) diff --git a/examples/gui_demo.py b/examples/demo.py similarity index 95% rename from examples/gui_demo.py rename to examples/demo.py index d99ccdf..07692b3 100644 --- a/examples/gui_demo.py +++ b/examples/demo.py @@ -11,12 +11,12 @@ import time -from rendercanvas.auto import WgpuCanvas, loop +from rendercanvas.auto import RenderCanvas, loop from cube import setup_drawing_sync -canvas = WgpuCanvas( +canvas = RenderCanvas( size=(640, 480), title="Canvas events on $backend - $fps fps", max_fps=10, diff --git a/examples/gui_events.py b/examples/events.py similarity index 65% rename from examples/gui_events.py rename to examples/events.py index 42d7a98..61f80b2 100644 --- a/examples/gui_events.py +++ b/examples/events.py @@ -2,10 +2,10 @@ A simple example to demonstrate events. """ -from rendercanvas.auto import WgpuCanvas, run +from rendercanvas.auto import RenderCanvas, run -canvas = WgpuCanvas(size=(640, 480), title="wgpu events") +canvas = RenderCanvas(size=(640, 480), title="RenderCanvas events") @canvas.add_event_handler("*") diff --git a/examples/gui_multiple.py b/examples/multiple.py similarity index 69% rename from examples/gui_multiple.py rename to examples/multiple.py index 53294f0..ad26338 100644 --- a/examples/gui_multiple.py +++ b/examples/multiple.py @@ -4,17 +4,17 @@ # test_example = true -from rendercanvas.auto import WgpuCanvas, loop +from rendercanvas.auto import RenderCanvas, loop from triangle import setup_drawing_sync as setup_drawing_sync_triangle from cube import setup_drawing_sync as setup_drawing_sync_cube -canvas1 = WgpuCanvas(title=f"Triangle example on {WgpuCanvas.__name__}") +canvas1 = RenderCanvas(title=f"Triangle example on {RenderCanvas.__name__}") draw_frame1 = setup_drawing_sync_triangle(canvas1) canvas1.request_draw(draw_frame1) -canvas2 = WgpuCanvas(title=f"Cube example on {WgpuCanvas.__name__}") +canvas2 = RenderCanvas(title=f"Cube example on {RenderCanvas.__name__}") draw_frame2 = setup_drawing_sync_cube(canvas2) canvas2.request_draw(draw_frame2) diff --git a/examples/gui_threading.py b/examples/offsceen_threaded.py similarity index 94% rename from examples/gui_threading.py rename to examples/offsceen_threaded.py index d929382..24954ef 100644 --- a/examples/gui_threading.py +++ b/examples/offsceen_threaded.py @@ -17,13 +17,13 @@ import time import threading -from rendercanvas.offscreen import WgpuCanvas +from rendercanvas.offscreen import RenderCanvas from cube import setup_drawing_sync # create canvas -canvas = WgpuCanvas() +canvas = RenderCanvas() draw_frame = setup_drawing_sync(canvas) diff --git a/examples/gui_qt_embed.py b/examples/qt_app.py similarity index 95% rename from examples/gui_qt_embed.py rename to examples/qt_app.py index 5e531af..a109a48 100644 --- a/examples/gui_qt_embed.py +++ b/examples/qt_app.py @@ -18,7 +18,7 @@ except ModuleNotFoundError: pass -from rendercanvas.qt import QWgpuWidget +from rendercanvas.qt import QRenderWidget from rendercanvas.utils.cube import setup_drawing_sync @@ -31,7 +31,7 @@ def __init__(self): splitter = QtWidgets.QSplitter() self.button = QtWidgets.QPushButton("Hello world", self) - self.canvas = QWgpuWidget(splitter) + self.canvas = QRenderWidget(splitter) self.output = QtWidgets.QTextEdit(splitter) self.button.clicked.connect(self.whenButtonClicked) diff --git a/examples/gui_qt_asyncio.py b/examples/qt_app_asyncio.py similarity index 94% rename from examples/gui_qt_asyncio.py rename to examples/qt_app_asyncio.py index 059f800..f7af902 100644 --- a/examples/gui_qt_asyncio.py +++ b/examples/qt_app_asyncio.py @@ -1,7 +1,7 @@ """ An example demonstrating a qt app with a wgpu viz inside. -This is the same as the ``gui_qt_embed.py`` example, except this uses +This is the same as the ``qt_app.py`` example, except this uses the asyncio compatible mode that was introduced in Pyside 6.6. For more info see: @@ -17,7 +17,7 @@ import asyncio from PySide6 import QtWidgets, QtAsyncio -from rendercanvas.qt import QWgpuWidget +from rendercanvas.qt import QRenderWidget from rendercanvas.utils.cube import setup_drawing_sync @@ -49,7 +49,7 @@ def __init__(self): # todo: use update_mode = 'continuous' when that feature has arrived self.button = QtWidgets.QPushButton("Hello world", self) - self.canvas = QWgpuWidget(splitter) + self.canvas = QRenderWidget(splitter) self.output = QtWidgets.QTextEdit(splitter) # self.button.clicked.connect(self.whenButtonClicked) # see above :( diff --git a/examples/gui_wx_embed.py b/examples/wx_app.py similarity index 87% rename from examples/gui_wx_embed.py rename to examples/wx_app.py index a3232f9..8916de3 100644 --- a/examples/gui_wx_embed.py +++ b/examples/wx_app.py @@ -3,7 +3,7 @@ """ import wx -from rendercanvas.wx import WgpuWidget +from rendercanvas.wx import RenderWidget from rendercanvas.utils.cube import setup_drawing_sync @@ -16,8 +16,8 @@ def __init__(self): splitter = wx.SplitterWindow(self) self.button = wx.Button(self, -1, "Hello world") - self.canvas1 = WgpuWidget(splitter) - self.canvas2 = WgpuWidget(splitter) + self.canvas1 = RenderWidget(splitter) + self.canvas2 = RenderWidget(splitter) splitter.SplitVertically(self.canvas1, self.canvas2) splitter.SetSashGravity(0.5) diff --git a/rendercanvas/__init__.py b/rendercanvas/__init__.py index 3bc61e4..059d713 100644 --- a/rendercanvas/__init__.py +++ b/rendercanvas/__init__.py @@ -6,13 +6,13 @@ from ._version import __version__, version_info from . import _gui_utils -from ._events import WgpuEventType -from .base import WgpuCanvasInterface, WgpuCanvasBase, WgpuLoop, WgpuTimer +from ._events import EventType +from .base import RenderCanvasInterface, BaseRenderCanvas, BaseLoop, BaseTimer __all__ = [ - "WgpuCanvasInterface", - "WgpuCanvasBase", - "WgpuEventType", - "WgpuLoop", - "WgpuTimer", + "RenderCanvasInterface", + "BaseRenderCanvas", + "EventType", + "BaseLoop", + "BaseTimer", ] diff --git a/rendercanvas/_events.py b/rendercanvas/_events.py index 31ef567..6355bf3 100644 --- a/rendercanvas/_events.py +++ b/rendercanvas/_events.py @@ -5,12 +5,12 @@ from ._coreutils import BaseEnum -class WgpuEventType(BaseEnum): - """The WgpuEventType enum specifies the possible events for a WgpuCanvas. +class EventType(BaseEnum): + """The EventType enum specifies the possible events for a RenderCanvas. This includes the events from the jupyter_rfb event spec (see https://jupyter-rfb.readthedocs.io/en/stable/events.html) plus some - wgpu-specific events. + rendercanvas-specific events. """ # Jupter_rfb spec @@ -116,7 +116,7 @@ def my_handler(event): for type in types: if not isinstance(type, str): raise TypeError(f"Event types must be str, but got {type}") - if not (type == "*" or type in WgpuEventType): + if not (type == "*" or type in EventType): raise ValueError(f"Adding handler with invalid event_type: '{type}'") def decorator(_callback): @@ -153,7 +153,7 @@ def submit(self, event): Events are emitted later by the scheduler. """ event_type = event["event_type"] - if event_type not in WgpuEventType: + if event_type not in EventType: raise ValueError(f"Submitting with invalid event_type: '{event_type}'") if event_type == "close": self._closed = True @@ -207,7 +207,7 @@ def emit(self, event): with log_exception(f"Error during handling {event_type} event"): callback(event) - def _wgpu_close(self): + def _rc_close(self): """Wrap up when the scheduler detects the canvas is closed/dead.""" # This is a little feature because detecting a widget from closing can be tricky. if not self._closed: diff --git a/rendercanvas/_gui_utils.py b/rendercanvas/_gui_utils.py index 601c917..f4cf5e5 100644 --- a/rendercanvas/_gui_utils.py +++ b/rendercanvas/_gui_utils.py @@ -1,4 +1,4 @@ -"""Private gui utilities.""" +"""Private utilities.""" import os import sys @@ -13,7 +13,7 @@ logger = logging.getLogger("rendercanvas") -# ===== GUI lib support +# ===== lib support QT_MODULE_NAMES = ["PySide6", "PyQt6", "PySide2", "PyQt5"] @@ -130,7 +130,7 @@ def proxy(*args, **kwargs): def get_alt_x11_display(): """Get (the pointer to) a process-global x11 display instance.""" - # Ideally we'd get the real display object used by the GUI toolkit. + # Ideally we'd get the real display object used by the backend. # But this is not always possible. In that case, using an alt display # object can be used. global _x11_display @@ -147,7 +147,7 @@ def get_alt_x11_display(): def get_alt_wayland_display(): """Get (the pointer to) a process-global Wayland display instance.""" - # Ideally we'd get the real display object used by the GUI toolkit. + # Ideally we'd get the real display object used by the backend. # This creates a global object, similar to what we do for X11. # Unfortunately, this segfaults, so it looks like the real display object # is needed? Leaving this here for reference. diff --git a/rendercanvas/_loop.py b/rendercanvas/_loop.py index adffa36..1e17e41 100644 --- a/rendercanvas/_loop.py +++ b/rendercanvas/_loop.py @@ -12,7 +12,7 @@ # That would e.g. allow using glfw with qt together. Probably a too weird use-case for the added complexity. -class WgpuTimer: +class BaseTimer: """Base class for a timer objects.""" _running_timers = set() @@ -43,7 +43,7 @@ def start(self, interval): self._init() if self.is_running: self._stop() - WgpuTimer._running_timers.add(self) + BaseTimer._running_timers.add(self) self._interval = max(0.0, float(interval)) self._expect_tick_at = time.perf_counter() + self._interval self._start() @@ -55,7 +55,7 @@ def stop(self): callback is *not* called. If the timer is currently not running, this method does nothing. """ - WgpuTimer._running_timers.discard(self) + BaseTimer._running_timers.discard(self) self._expect_tick_at = None self._stop() @@ -63,7 +63,7 @@ def _tick(self): """The implementations must call this method.""" # Stop or restart if self._one_shot: - WgpuTimer._running_timers.discard(self) + BaseTimer._running_timers.discard(self) self._expect_tick_at = None else: self._expect_tick_at = time.perf_counter() + self._interval @@ -120,7 +120,7 @@ def _stop(self): raise NotImplementedError() -class WgpuLoop: +class BaseLoop: """Base class for event-loop objects.""" _TimerClass = None # subclases must set this @@ -135,7 +135,7 @@ def __init__(self): # loop usually stops when the last window is closed, so the close event may # not be fired. # * Keep the GUI going even when the canvas loop is on pause e.g. because its - # minimized (applies to backends that implement _wgpu_gui_poll). + # minimized (applies to backends that implement _rc_gui_poll). self._gui_timer = self._TimerClass(self, self._tick, one_shot=False) def _register_scheduler(self, scheduler): @@ -145,7 +145,7 @@ def _register_scheduler(self, scheduler): def _tick(self): # Keep the GUI alive on every tick - self._wgpu_gui_poll() + self._rc_gui_poll() # Check all schedulers schedulers_to_close = [] @@ -235,7 +235,7 @@ def _call_soon(self, callback, *args): """ self.call_later(0, callback, *args) - def _wgpu_gui_poll(self): + def _rc_gui_poll(self): """For the subclass to implement: Some event loops (e.g. asyncio) are just that and dont have a GUI to update. @@ -332,7 +332,7 @@ def __init__(self, canvas, loop, *, mode="ondemand", min_fps=1, max_fps=30): assert loop is not None # Initialise the timer that runs our scheduling loop. - # Note that the gui may do a first draw earlier, starting the loop, and that's fine. + # Note that the backend may do a first draw earlier, starting the loop, and that's fine. self._last_tick_time = -0.1 self._timer = loop.call_later(0.1, self._tick) @@ -343,7 +343,7 @@ def _get_canvas(self): canvas = self._canvas_ref() if canvas is None or canvas.is_closed(): # Pretty nice, we can send a close event, even if the canvas no longer exists - self._events._wgpu_close() + self._events._rc_close() return None else: return canvas diff --git a/rendercanvas/asyncio.py b/rendercanvas/asyncio.py index 808040f..161db1f 100644 --- a/rendercanvas/asyncio.py +++ b/rendercanvas/asyncio.py @@ -1,16 +1,16 @@ """Implements an asyncio event loop.""" -# This is used for GUI backends that don't have an event loop by themselves, like glfw. +# This is used for backends that don't have an event loop by themselves, like glfw. # Would be nice to also allow a loop based on e.g. Trio. But we can likely fit that in # when the time comes. import asyncio -from .base import WgpuLoop, WgpuTimer +from .base import BaseLoop, BaseTimer -class AsyncioWgpuTimer(WgpuTimer): - """Wgpu timer based on asyncio.""" +class AsyncioTimer(BaseTimer): + """Timer based on asyncio.""" _handle = None @@ -30,8 +30,8 @@ def _stop(self): self._handle = None -class AsyncioWgpuLoop(WgpuLoop): - _TimerClass = AsyncioWgpuTimer +class AsyncioLoop(BaseLoop): + _TimerClass = AsyncioTimer _the_loop = None _is_interactive = False diff --git a/rendercanvas/auto.py b/rendercanvas/auto.py index dfb107f..88ca771 100644 --- a/rendercanvas/auto.py +++ b/rendercanvas/auto.py @@ -1,11 +1,11 @@ """ -Automatic GUI backend selection. +Automatic backend selection. Right now we only chose between GLFW, Qt and Jupyter. We might add support for e.g. wx later. Or we might decide to stick with these three. """ -__all__ = ["WgpuCanvas", "loop", "run"] +__all__ = ["RenderCanvas", "loop", "run"] import os import sys @@ -13,12 +13,12 @@ from ._gui_utils import logger, QT_MODULE_NAMES, get_imported_qt_lib, asyncio_is_running -# Note that wx is not in here, because it does not (yet) fully implement base.WgpuCanvasBase -WGPU_GUI_BACKEND_NAMES = ["glfw", "qt", "jupyter", "offscreen"] +# Note that wx is not in here, because it does not (yet) fully implement base.BaseRenderCanvas +BACKEND_NAMES = ["glfw", "qt", "jupyter", "offscreen"] def _load_backend(backend_name): - """Load a gui backend by name.""" + """Load a backend by name.""" if backend_name == "glfw": from . import glfw as module elif backend_name == "qt": @@ -30,7 +30,7 @@ def _load_backend(backend_name): elif backend_name == "offscreen": from . import offscreen as module else: # no-cover - raise ImportError("Unknown wgpu gui backend: '{backend_name}'") + raise ImportError("Unknown rendercanvas backend: '{backend_name}'") return module @@ -53,7 +53,7 @@ def select_backend(): # Always report failed backends, because we only try them when it looks like we can. if failed_backends: - msg = "WGPU could not load some backends:" + msg = "rendercanvas could not load some backends:" for key, val in failed_backends.items(): msg += f"\n{key}: {val}" logger.warning(msg) @@ -61,10 +61,10 @@ def select_backend(): # Return or raise if module is not None: log = logger.warning if failed_backends else logger.info - log(f"WGPU selected {backend_name} gui because {reason}.") + log(f"Rendercanvas selected {backend_name} backend because {reason}.") return module else: - msg = "WGPU Could not load any of the supported GUI backends." + msg = "Rendercanvas could not load any of the supported backends." if "jupyter" in failed_backends: msg += "\n You may need to ``pip install -U jupyter_rfb``." else: @@ -94,9 +94,9 @@ def backends_by_env_vars(): # Env var to force a backend for general use backend_name = os.getenv("WGPU_GUI_BACKEND", "").lower().strip() or None if backend_name: - if backend_name not in WGPU_GUI_BACKEND_NAMES: + if backend_name not in BACKEND_NAMES: logger.warning( - f"Ignoring invalid WGPU_GUI_BACKEND '{backend_name}', must be one of {WGPU_GUI_BACKEND_NAMES}" + f"Ignoring invalid WGPU_GUI_BACKEND '{backend_name}', must be one of {BACKEND_NAMES}" ) backend_name = None if backend_name: @@ -167,9 +167,9 @@ def backends_by_imported_modules(): def backends_by_trying_in_order(): - """Generate backend names by trying to import the GUI lib in order. This is the final fallback.""" + """Generate backend names by trying to import the corresponding lib in order. This is the final fallback.""" - gui_lib_to_backend = { + lib_to_backend = { "glfw": "glfw", "PySide6": "qt", "PyQt6": "qt", @@ -178,7 +178,7 @@ def backends_by_trying_in_order(): # "wx": "wx", } - for libname, backend_name in gui_lib_to_backend.items(): + for libname, backend_name in lib_to_backend.items(): try: importlib.import_module(libname) except ModuleNotFoundError: @@ -188,5 +188,5 @@ def backends_by_trying_in_order(): # Load! module = select_backend() -WgpuCanvas, loop = module.WgpuCanvas, module.loop +RenderCanvas, loop = module.RenderCanvas, module.loop run = loop.run # backwards compat diff --git a/rendercanvas/base.py b/rendercanvas/base.py index 8fddf5d..bd63072 100644 --- a/rendercanvas/base.py +++ b/rendercanvas/base.py @@ -1,17 +1,17 @@ import sys -from ._events import EventEmitter, WgpuEventType # noqa: F401 -from ._loop import Scheduler, WgpuLoop, WgpuTimer # noqa: F401 +from ._events import EventEmitter, EventType # noqa: F401 +from ._loop import Scheduler, BaseLoop, BaseTimer # noqa: F401 from ._gui_utils import log_exception -class WgpuCanvasInterface: +class RenderCanvasInterface: """The minimal interface to be a valid canvas. Any object that implements these methods is a canvas that wgpu can work with. The object does not even have to derive from this class. - In most cases it's more convenient to subclass :class:`WgpuCanvasBase `. + In most cases it's more convenient to subclass :class:`BaseRenderCanvas `. """ _canvas_context = None # set in get_context() @@ -83,14 +83,14 @@ def present_image(self, image, **kwargs): raise NotImplementedError() -class WgpuCanvasBase(WgpuCanvasInterface): +class BaseRenderCanvas(RenderCanvasInterface): """The base canvas class. - This class provides a uniform canvas API so render systems can be use + This class provides a uniform canvas API so render systems can use code that is portable accross multiple GUI libraries and canvas targets. Arguments: - update_mode (WgpuEventType): The mode for scheduling draws and events. Default 'ondemand'. + update_mode (EventType): The mode for scheduling draws and events. Default 'ondemand'. min_fps (float): A minimal frames-per-second to use when the ``update_mode`` is 'ondemand'. The default is 1: even without draws requested, it still draws every second. max_fps (float): A maximal frames-per-second to use when the ``update_mode`` is 'ondemand' or 'continuous'. @@ -173,7 +173,7 @@ def _process_events(self): # Get events from the GUI into our event mechanism. loop = self._get_loop() if loop: - loop._wgpu_gui_poll() + loop._rc_gui_poll() # Flush our events, so downstream code can update stuff. # Maybe that downstream code request a new draw. @@ -245,7 +245,7 @@ def force_draw(self): def _draw_frame_and_present(self): """Draw the frame and present the result. - Errors are logged to the "wgpu" logger. Should be called by the + Errors are logged to the "rendercanvas" logger. Should be called by the subclass at its draw event. """ @@ -294,7 +294,7 @@ def _draw_frame_and_present(self): def _get_loop(self): """For the subclass to implement: - Must return the global loop instance (WgpuLoop) for the canvas subclass, + Must return the global loop instance (a BaseLoop subclass) for the canvas subclass, or None for a canvas without scheduled draws. """ return None @@ -371,7 +371,7 @@ def _set_title(self, title): def pop_kwargs_for_base_canvas(kwargs_dict): """Convenience functions for wrapper canvases like in Qt and wx.""" - code = WgpuCanvasBase.__init__.__code__ + code = BaseRenderCanvas.__init__.__code__ base_kwarg_names = code.co_varnames[: code.co_argcount + code.co_kwonlyargcount] d = {} for key in base_kwarg_names: diff --git a/rendercanvas/glfw.py b/rendercanvas/glfw.py index d116c51..0b11737 100644 --- a/rendercanvas/glfw.py +++ b/rendercanvas/glfw.py @@ -14,21 +14,21 @@ import glfw -from .base import WgpuCanvasBase -from .asyncio import AsyncioWgpuLoop +from .base import BaseRenderCanvas +from .asyncio import AsyncioLoop from ._gui_utils import SYSTEM_IS_WAYLAND, weakbind, logger # Make sure that glfw is new enough glfw_version_info = tuple(int(i) for i in glfw.__version__.split(".")[:2]) if glfw_version_info < (1, 9): - raise ImportError("wgpu-py requires glfw 1.9 or higher.") + raise ImportError("rendercanvas requires glfw 1.9 or higher.") # Do checks to prevent pitfalls on hybrid Xorg/Wayland systems is_wayland = False if sys.platform.startswith("linux") and SYSTEM_IS_WAYLAND: if not hasattr(glfw, "get_x11_window"): - # Probably glfw was imported before we wgpu was, so we missed our chance + # Probably glfw was imported before this module, so we missed our chance # to set the env var to make glfw use x11. is_wayland = True logger.warning("Using GLFW with Wayland, which is experimental.") @@ -141,8 +141,8 @@ def get_physical_size(window): return int(psize[0]), int(psize[1]) -class GlfwWgpuCanvas(WgpuCanvasBase): - """A glfw window providing a wgpu canvas.""" +class GlfwRenderCanvas(BaseRenderCanvas): + """A glfw window providing a render canvas.""" # See https://www.glfw.org/docs/latest/group__window.html @@ -201,7 +201,7 @@ def __init__(self, *, size=None, title=None, **kwargs): self.set_logical_size(*size) self.set_title(title) - # Callbacks to provide a minimal working canvas for wgpu + # Callbacks to provide a minimal working canvas def _on_pixelratio_change(self, *args): if self._changing_pixel_ratio: @@ -518,15 +518,15 @@ def _on_char(self, window, char): def present_image(self, image, **kwargs): raise NotImplementedError() # AFAIK glfw does not have a builtin way to blit an image. It also does - # not really need one, since it's the most reliable GUI backend to + # not really need one, since it's the most reliable backend to # render to the screen. -# Make available under a name that is the same for all gui backends -WgpuCanvas = GlfwWgpuCanvas +# Make available under a name that is the same for all backends +RenderCanvas = GlfwRenderCanvas -class GlfwAsyncioWgpuLoop(AsyncioWgpuLoop): +class GlfwAsyncioLoop(AsyncioLoop): def __init__(self): super().__init__() self.all_glfw_canvases = weakref.WeakSet() @@ -539,7 +539,7 @@ def init_glfw(self): self._glfw_initialized = True atexit.register(glfw.terminate) - def _wgpu_gui_poll(self): + def _rc_gui_poll(self): glfw.post_empty_event() # Awake the event loop, if it's in wait-mode glfw.poll_events() if self.stop_if_no_more_canvases and not tuple(self.all_glfw_canvases): @@ -551,7 +551,7 @@ def _run(self): poll_glfw_briefly() -loop = GlfwAsyncioWgpuLoop() +loop = GlfwAsyncioLoop() run = loop.run # backwards compat diff --git a/rendercanvas/jupyter.py b/rendercanvas/jupyter.py index 5f22762..81b5718 100644 --- a/rendercanvas/jupyter.py +++ b/rendercanvas/jupyter.py @@ -6,16 +6,16 @@ import time import weakref -from .base import WgpuCanvasBase -from .asyncio import AsyncioWgpuLoop +from .base import BaseRenderCanvas +from .asyncio import AsyncioLoop import numpy as np from jupyter_rfb import RemoteFrameBuffer from IPython.display import display -class JupyterWgpuCanvas(WgpuCanvasBase, RemoteFrameBuffer): - """An ipywidgets widget providing a wgpu canvas. Needs the jupyter_rfb library.""" +class JupyterRenderCanvas(BaseRenderCanvas, RemoteFrameBuffer): + """An ipywidgets widget providing a render canvas. Needs the jupyter_rfb library.""" def __init__(self, *, size=None, title=None, **kwargs): super().__init__(**kwargs) @@ -62,7 +62,7 @@ def get_frame(self): self._draw_frame_and_present() return self._last_image - # Implementation needed for WgpuCanvasBase + # Implementation needed for BaseRenderCanvas def _get_loop(self): return loop @@ -105,7 +105,7 @@ def _force_draw(self): if array is not None: self._rfb_send_frame(array) - # Implementation needed for WgpuCanvasInterface + # Implementation needed for RenderCanvasInterface def get_present_info(self): # Use a format that maps well to PNG: rgba8norm. Use srgb for @@ -122,16 +122,16 @@ def present_image(self, image, **kwargs): self._last_image = np.frombuffer(image, np.uint8).reshape(image.shape) -# Make available under a name that is the same for all gui backends -WgpuCanvas = JupyterWgpuCanvas +# Make available under a name that is the same for all backends +RenderCanvas = JupyterRenderCanvas -class JupyterAsyncioWgpuLoop(AsyncioWgpuLoop): +class JupyterAsyncioLoop(AsyncioLoop): def __init__(self): super().__init__() self._pending_jupyter_canvases = [] - def _wgpu_gui_poll(self): + def _rc_gui_poll(self): pass # Jupyter is running in a separate process :) def run(self): @@ -144,4 +144,4 @@ def run(self): display(w) -loop = JupyterAsyncioWgpuLoop() +loop = JupyterAsyncioLoop() diff --git a/rendercanvas/offscreen.py b/rendercanvas/offscreen.py index 16c2d05..522faf7 100644 --- a/rendercanvas/offscreen.py +++ b/rendercanvas/offscreen.py @@ -1,7 +1,7 @@ -from .base import WgpuCanvasBase, WgpuLoop, WgpuTimer +from .base import BaseRenderCanvas, BaseLoop, BaseTimer -class WgpuManualOffscreenCanvas(WgpuCanvasBase): +class ManualOffscreenRenderCanvas(BaseRenderCanvas): """An offscreen canvas intended for manual use. Call the ``.draw()`` method to perform a draw and get the result. @@ -69,10 +69,10 @@ def draw(self): return self._last_image -WgpuCanvas = WgpuManualOffscreenCanvas +RenderCanvas = ManualOffscreenRenderCanvas -class StubWgpuTimer(WgpuTimer): +class StubTimer(BaseTimer): def _start(self): pass @@ -80,7 +80,7 @@ def _stop(self): pass -class StubLoop(WgpuLoop): +class StubLoop(BaseLoop): # If we consider the use-cases for using this offscreen canvas: # # * Using rendercanvas.auto in test-mode: in this case run() should not hang, @@ -94,11 +94,11 @@ class StubLoop(WgpuLoop): # In summary, we provide a call_later() and run() that behave pretty # well for the first case. - _TimerClass = StubWgpuTimer # subclases must set this + _TimerClass = StubTimer # subclases must set this def _process_timers(self): # Running this loop processes any timers - for timer in list(WgpuTimer._running_timers): + for timer in list(BaseTimer._running_timers): if timer.time_left <= 0: timer._tick() diff --git a/rendercanvas/qt.py b/rendercanvas/qt.py index b079862..1dfbf9a 100644 --- a/rendercanvas/qt.py +++ b/rendercanvas/qt.py @@ -7,7 +7,7 @@ import ctypes import importlib -from .base import WgpuCanvasBase, WgpuLoop, WgpuTimer, pop_kwargs_for_base_canvas +from .base import BaseRenderCanvas, BaseLoop, BaseTimer, pop_kwargs_for_base_canvas from ._gui_utils import ( logger, SYSTEM_IS_WAYLAND, @@ -128,10 +128,10 @@ def enable_hidpi(): pass # fail on older Qt's -# If you import this module, you want to use wgpu in a way that does not suck +# If you import this module, you want to render in a way that does not suck # on high-res monitors. So we apply the minimal configuration to make this so. # Most apps probably should also set AA_UseHighDpiPixmaps, but it's not -# needed for wgpu, so not our responsibility (some users may NOT want it set). +# needed, so not our responsibility (some users may NOT want it set). enable_hidpi() _show_image_method_warning = ( @@ -139,8 +139,8 @@ def enable_hidpi(): ) -class QWgpuWidget(WgpuCanvasBase, QtWidgets.QWidget): - """A QWidget representing a wgpu canvas that can be embedded in a Qt application.""" +class QRenderWidget(BaseRenderCanvas, QtWidgets.QWidget): + """A QWidget representing a render canvas that can be embedded in a Qt application.""" def __init__(self, *args, present_method=None, **kwargs): super().__init__(*args, **kwargs) @@ -182,7 +182,7 @@ def paintEngine(self): # noqa: N802 - this is a Qt method def paintEvent(self, event): # noqa: N802 - this is a Qt method self._draw_frame_and_present() - # Methods that we add from wgpu (snake_case) + # Methods that we add for BaseRenderCanvas (snake_case) def _request_draw(self): # Ask Qt to do a paint event @@ -267,7 +267,7 @@ def set_logical_size(self, width, height): if width < 0 or height < 0: raise ValueError("Window width and height must not be negative") parent = self.parent() - if isinstance(parent, QWgpuCanvas): + if isinstance(parent, QRenderCanvas): parent.resize(width, height) else: self.resize(width, height) # See comment on pixel ratio @@ -276,7 +276,7 @@ def _set_title(self, title): # A QWidgets title can actually be shown when the widget is shown in a dock. # But the application should probably determine that title, not us. parent = self.parent() - if isinstance(parent, QWgpuCanvas): + if isinstance(parent, QRenderCanvas): parent.setWindowTitle(title) def close(self): @@ -446,8 +446,8 @@ def present_image(self, image_data, **kwargs): # backingstore.flush(rect2) -class QWgpuCanvas(WgpuCanvasBase, QtWidgets.QWidget): - """A toplevel Qt widget providing a wgpu canvas.""" +class QRenderCanvas(BaseRenderCanvas, QtWidgets.QWidget): + """A toplevel Qt widget providing a render canvas.""" # Most of this is proxying stuff to the inner widget. # We cannot use a toplevel widget directly, otherwise the window @@ -471,7 +471,7 @@ def __init__(self, *, size=None, title=None, **kwargs): self.setAttribute(WA_DeleteOnClose, True) self.setMouseTracking(True) - self._subwidget = QWgpuWidget(self, **sub_kwargs) + self._subwidget = QRenderWidget(self, **sub_kwargs) self._events = self._subwidget._events # Note: At some point we called `self._subwidget.winId()` here. For some @@ -494,7 +494,7 @@ def closeEvent(self, event): # noqa: N802 self._subwidget._is_closed = True self.submit_event({"event_type": "close"}) - # Methods that we add from wgpu (snake_case) + # Methods that we add from BaseRenderCanvas (snake_case) def _request_draw(self): self._subwidget._request_draw() @@ -544,12 +544,12 @@ def present_image(self, image, **kwargs): # Make available under a name that is the same for all gui backends -WgpuWidget = QWgpuWidget -WgpuCanvas = QWgpuCanvas +RenderWidget = QRenderWidget +RenderCanvas = QRenderCanvas -class QtWgpuTimer(WgpuTimer): - """Wgpu timer basef on Qt.""" +class QtTimer(BaseTimer): + """Timer basef on Qt.""" def _init(self): self._qt_timer = QtCore.QTimer() @@ -564,8 +564,8 @@ def _stop(self): self._qt_timer.stop() -class QtWgpuLoop(WgpuLoop): - _TimerClass = QtWgpuTimer +class QtLoop(BaseLoop): + _TimerClass = QtTimer def init_qt(self): _ = self._app @@ -603,9 +603,9 @@ def _stop(self): if not already_had_app_on_import: self._app.quit() - def _wgpu_gui_poll(self): + def _rc_gui_poll(self): pass # we assume the Qt event loop is running. Calling processEvents() will cause recursive repaints. -loop = QtWgpuLoop() +loop = QtLoop() run = loop.run # backwards compat diff --git a/rendercanvas/utils/cube.py b/rendercanvas/utils/cube.py index 0a66c19..0ed7ac6 100644 --- a/rendercanvas/utils/cube.py +++ b/rendercanvas/utils/cube.py @@ -15,7 +15,7 @@ def setup_drawing_sync(canvas, power_preference="high-performance", limits=None): """Setup to draw a rotating cube on the given canvas. - The given canvas must implement WgpuCanvasInterface, but nothing more. + The given canvas must implement RenderCanvasInterface, but nothing more. Returns the draw function. """ @@ -35,7 +35,7 @@ def setup_drawing_sync(canvas, power_preference="high-performance", limits=None) async def setup_drawing_async(canvas, limits=None): """Setup to async-draw a rotating cube on the given canvas. - The given canvas must implement WgpuCanvasInterface, but nothing more. + The given canvas must implement RenderCanvasInterface, but nothing more. Returns the draw function. """ diff --git a/rendercanvas/wx.py b/rendercanvas/wx.py index 091222b..8fa5787 100644 --- a/rendercanvas/wx.py +++ b/rendercanvas/wx.py @@ -16,7 +16,7 @@ get_alt_x11_display, get_alt_wayland_display, ) -from .base import WgpuCanvasBase, WgpuLoop, WgpuTimer, pop_kwargs_for_base_canvas +from .base import BaseRenderCanvas, BaseLoop, BaseTimer, pop_kwargs_for_base_canvas BUTTON_MAP = { @@ -120,8 +120,8 @@ def enable_hidpi(): ) -class WxWgpuWindow(WgpuCanvasBase, wx.Window): - """A wx Window representing a wgpu canvas that can be embedded in a wx application.""" +class WxRenderWidget(BaseRenderCanvas, wx.Window): + """A wx Window representing a render canvas that can be embedded in a wx application.""" def __init__(self, *args, present_method=None, **kwargs): super().__init__(*args, **kwargs) @@ -310,7 +310,7 @@ def _on_mouse_events(self, event: wx.MouseEvent): def _on_mouse_move(self, event: wx.MouseEvent): self._mouse_event("pointer_move", event) - # Methods that we add from wgpu + # Methods that we add from BaseRenderCanvas def _get_surface_ids(self): if sys.platform.startswith("win") or sys.platform.startswith("darwin"): @@ -371,7 +371,7 @@ def set_logical_size(self, width, height): if width < 0 or height < 0: raise ValueError("Window width and height must not be negative") parent = self.Parent - if isinstance(parent, WxWgpuCanvas): + if isinstance(parent, WxRenderCanvas): parent.SetSize(width, height) else: self.SetSize(width, height) @@ -379,7 +379,7 @@ def set_logical_size(self, width, height): def _set_title(self, title): # Set title only on frame parent = self.Parent - if isinstance(parent, WxWgpuCanvas): + if isinstance(parent, WxRenderCanvas): parent.SetTitle(title) def _request_draw(self): @@ -417,8 +417,8 @@ def present_image(self, image_data, **kwargs): dc.DrawBitmap(bitmap, 0, 0, False) -class WxWgpuCanvas(WgpuCanvasBase, wx.Frame): - """A toplevel wx Frame providing a wgpu canvas.""" +class WxRenderCanvas(BaseRenderCanvas, wx.Frame): + """A toplevel wx Frame providing a render canvas.""" # Most of this is proxying stuff to the inner widget. @@ -440,7 +440,7 @@ def __init__( if not size: size = 640, 480 - self._subwidget = WxWgpuWindow(parent=self, **sub_kwargs) + self._subwidget = WxRenderWidget(parent=self, **sub_kwargs) self._events = self._subwidget._events self.Bind(wx.EVT_CLOSE, lambda e: self.Destroy()) @@ -511,8 +511,8 @@ def present_image(self, image, **kwargs): # Make available under a name that is the same for all gui backends -WgpuWidget = WxWgpuWindow -WgpuCanvas = WxWgpuCanvas +RenderWidget = WxRenderWidget +RenderCanvas = WxRenderCanvas class TimerWithCallback(wx.Timer): @@ -524,10 +524,10 @@ def Notify(self, *args): # noqa: N802 try: self._callback() except RuntimeError: - pass # wrapped C/C++ object of type WxWgpuWindow has been deleted + pass # wrapped C/C++ object of type WxRenderWidget has been deleted -class WxWgpuTimer(WgpuTimer): +class WxTimer(BaseTimer): def _init(self): self._wx_timer = TimerWithCallback(self._tick) @@ -538,8 +538,8 @@ def _stop(self): self._wx_timer.Stop() -class WxWgpuLoop(WgpuLoop): - _TimerClass = WxWgpuTimer +class WxLoop(BaseLoop): + _TimerClass = WxTimer _the_app = None _frame_to_keep_loop_alive = None @@ -565,7 +565,7 @@ def _stop(self): self._frame_to_keep_loop_alive.Destroy() _frame_to_keep_loop_alive = None - def _wgpu_gui_poll(self): + def _rc_gui_poll(self): pass # We can assume the wx loop is running. def process_wx_events(self): @@ -577,5 +577,5 @@ def process_wx_events(self): wx.GUIEventLoop.SetActive(old) -loop = WxWgpuLoop() +loop = WxLoop() run = loop.run # backwards compat diff --git a/tests/test_gui_base.py b/tests/test_base.py similarity index 93% rename from tests/test_gui_base.py rename to tests/test_base.py index ed439d7..18aa716 100644 --- a/tests/test_gui_base.py +++ b/tests/test_base.py @@ -12,11 +12,11 @@ def test_base_canvas_context(): - assert hasattr(rendercanvas.WgpuCanvasInterface, "get_context") + assert hasattr(rendercanvas.RenderCanvasInterface, "get_context") def test_canvas_get_context_needs_backend_to_be_selected(): - code = "from rendercanvas import WgpuCanvasBase; canvas = WgpuCanvasBase(); canvas.get_context()" + code = "from rendercanvas import BaseRenderCanvas; canvas = BaseRenderCanvas(); canvas.get_context()" result = subprocess.run( [sys.executable, "-c", code], @@ -31,7 +31,7 @@ def test_canvas_get_context_needs_backend_to_be_selected(): assert "canvas.get_context" in out.lower() -class CanvasThatRaisesErrorsDuringDrawing(rendercanvas.WgpuCanvasBase): +class CanvasThatRaisesErrorsDuringDrawing(rendercanvas.BaseRenderCanvas): def __init__(self): super().__init__() self._count = 0 @@ -91,7 +91,7 @@ def test_canvas_logging(caplog): assert text.count("intended-fail") == 4 -class MyOffscreenCanvas(rendercanvas.WgpuCanvasBase): +class MyOffscreenCanvas(rendercanvas.BaseRenderCanvas): def __init__(self): super().__init__() self.frame_count = 0 @@ -123,8 +123,8 @@ def test_run_bare_canvas(): # This is (more or less) the equivalent of: # - # from rendercanvas.auto import WgpuCanvas, loop - # canvas = WgpuCanvas() + # from rendercanvas.auto import RenderCanvas, loop + # canvas = RenderCanvas() # loop.run() # # Note: loop.run() calls _draw_frame_and_present() in event loop. @@ -202,7 +202,7 @@ def draw_frame(): def test_canvas_base_events(): - c = rendercanvas.WgpuCanvasBase() + c = rendercanvas.BaseRenderCanvas() # We test events extensively in another test module. This is just # to make sure that events are working for the base canvas. diff --git a/tests/test_gui_events.py b/tests/test_events.py similarity index 98% rename from tests/test_gui_events.py rename to tests/test_events.py index 461f991..f8e7788 100644 --- a/tests/test_gui_events.py +++ b/tests/test_events.py @@ -4,7 +4,7 @@ import time -from rendercanvas._events import EventEmitter, WgpuEventType +from rendercanvas._events import EventEmitter, EventType from testutils import run_tests import pytest @@ -16,7 +16,7 @@ def handler(event): pass # All these are valid - valid_types = list(WgpuEventType) + valid_types = list(EventType) ee.add_handler(handler, *valid_types) # This is not diff --git a/tests/test_gui_glfw.py b/tests/test_glfw.py similarity index 93% rename from tests/test_gui_glfw.py rename to tests/test_glfw.py index a1aa0b8..0f683e1 100644 --- a/tests/test_gui_glfw.py +++ b/tests/test_glfw.py @@ -31,19 +31,19 @@ def teardown_module(): def test_is_canvas_base(): - from rendercanvas import WgpuCanvasBase - from rendercanvas.glfw import WgpuCanvas + from rendercanvas import BaseRenderCanvas + from rendercanvas.glfw import RenderCanvas - assert issubclass(WgpuCanvas, WgpuCanvasBase) + assert issubclass(RenderCanvas, BaseRenderCanvas) def test_glfw_canvas_basics(): """Create a window and check some of its behavior. No wgpu calls here.""" import glfw - from rendercanvas.glfw import WgpuCanvas + from rendercanvas.glfw import RenderCanvas - canvas = WgpuCanvas() + canvas = RenderCanvas() canvas.set_logical_size(300, 200) etime = time.time() + 0.1 @@ -65,14 +65,14 @@ def test_glfw_canvas_basics(): def test_glfw_canvas_del(): - from rendercanvas.glfw import WgpuCanvas, loop + from rendercanvas.glfw import RenderCanvas, loop def run_briefly(): asyncio_loop = loop._loop asyncio_loop.run_until_complete(asyncio.sleep(0.5)) # poll_glfw_briefly() - canvas = WgpuCanvas() + canvas = RenderCanvas() ref = weakref.ref(canvas) assert ref() is not None @@ -104,14 +104,14 @@ def test_glfw_canvas_render(): import wgpu import glfw - from rendercanvas.glfw import WgpuCanvas, loop + from rendercanvas.glfw import RenderCanvas, loop def run_briefly(): asyncio_loop = loop._loop asyncio_loop.run_until_complete(asyncio.sleep(0.5)) # poll_glfw_briefly() - canvas = WgpuCanvas(max_fps=9999, update_mode="ondemand") + canvas = RenderCanvas(max_fps=9999, update_mode="ondemand") device = wgpu.gpu.request_adapter_sync().request_device_sync() draw_frame1 = _get_draw_function(device, canvas) diff --git a/tests/test_gui_offscreen.py b/tests/test_offscreen.py similarity index 83% rename from tests/test_gui_offscreen.py rename to tests/test_offscreen.py index 0b83d96..75df1c8 100644 --- a/tests/test_gui_offscreen.py +++ b/tests/test_offscreen.py @@ -10,7 +10,7 @@ def test_offscreen_selection_using_env_var(): - from rendercanvas.offscreen import WgpuManualOffscreenCanvas + from rendercanvas.offscreen import ManualOffscreenRenderCanvas ori = os.environ.get("WGPU_FORCE_OFFSCREEN", "") os.environ["WGPU_FORCE_OFFSCREEN"] = "1" @@ -23,12 +23,12 @@ def test_offscreen_selection_using_env_var(): for value in ["", "0", "false", "False", "wut"]: os.environ["WGPU_FORCE_OFFSCREEN"] = value module = select_backend() - assert module.WgpuCanvas is not WgpuManualOffscreenCanvas + assert module.RenderCanvas is not ManualOffscreenRenderCanvas for value in ["1", "true", "True"]: os.environ["WGPU_FORCE_OFFSCREEN"] = value module = select_backend() - assert module.WgpuCanvas is WgpuManualOffscreenCanvas + assert module.RenderCanvas is ManualOffscreenRenderCanvas finally: os.environ["WGPU_FORCE_OFFSCREEN"] = ori @@ -53,9 +53,9 @@ def check(): def test_offscreen_canvas_del(): - from rendercanvas.offscreen import WgpuCanvas + from rendercanvas.offscreen import RenderCanvas - canvas = WgpuCanvas() + canvas = RenderCanvas() ref = weakref.ref(canvas) assert ref() is not None diff --git a/tests/test_gui_scheduling.py b/tests/test_scheduling.py similarity index 90% rename from tests/test_gui_scheduling.py rename to tests/test_scheduling.py index 5938684..3db0d0f 100644 --- a/tests/test_gui_scheduling.py +++ b/tests/test_scheduling.py @@ -6,10 +6,10 @@ import time from testutils import run_tests -from rendercanvas import WgpuCanvasBase, WgpuLoop, WgpuTimer +from rendercanvas import BaseRenderCanvas, BaseLoop, BaseTimer -class MyTimer(WgpuTimer): +class MyTimer(BaseTimer): def _start(self): pass @@ -17,7 +17,7 @@ def _stop(self): pass -class MyLoop(WgpuLoop): +class MyLoop(BaseLoop): _TimerClass = MyTimer def __init__(self): @@ -25,7 +25,7 @@ def __init__(self): self.__stopped = False def process_timers(self): - for timer in list(WgpuTimer._running_timers): + for timer in list(BaseTimer._running_timers): if timer.time_left <= 0: timer._tick() @@ -36,7 +36,7 @@ def _stop(self): self.__stopped = True -class MyCanvas(WgpuCanvasBase): +class MyCanvas(BaseRenderCanvas): _loop = MyLoop() _gui_draw_requested = False @@ -80,7 +80,7 @@ def active_sleep(self, delay): self.draw_if_necessary() -def test_gui_scheduling_manual(): +def test_scheduling_manual(): canvas = MyCanvas(min_fps=0.000001, max_fps=100, update_mode="manual") # Booting ... @@ -104,7 +104,7 @@ def test_gui_scheduling_manual(): assert canvas.draw_count == 1 -def test_gui_scheduling_ondemand(): +def test_scheduling_ondemand(): canvas = MyCanvas(min_fps=0.000001, max_fps=100, update_mode="ondemand") # There's a small startup time, so no activity at first @@ -135,7 +135,7 @@ def test_gui_scheduling_ondemand(): assert canvas.events_count == 0 -def test_gui_scheduling_ondemand_always_request_draw(): +def test_scheduling_ondemand_always_request_draw(): # Test that using ondemand mode with a request_draw() in the # draw function, is equivalent to continuous mode. @@ -145,15 +145,15 @@ def test_gui_scheduling_ondemand_always_request_draw(): def draw_func(): canvas.request_draw() - _test_gui_scheduling_continuous(canvas) + _test_scheduling_continuous(canvas) -def test_gui_scheduling_continuous(): +def test_scheduling_continuous(): canvas = MyCanvas(max_fps=10, update_mode="continuous") - _test_gui_scheduling_continuous(canvas) + _test_scheduling_continuous(canvas) -def _test_gui_scheduling_continuous(canvas): +def _test_scheduling_continuous(canvas): # There's a small startup time, so no activity at first canvas.active_sleep(0.001) assert canvas.draw_count == 0 @@ -182,7 +182,7 @@ def _test_gui_scheduling_continuous(canvas): assert canvas.events_count == 0 -def test_gui_scheduling_fastest(): +def test_scheduling_fastest(): canvas = MyCanvas(max_fps=10, update_mode="fastest") # There's a small startup time, so no activity at first diff --git a/tests/test_gui_utils.py b/tests/test_utils.py similarity index 100% rename from tests/test_gui_utils.py rename to tests/test_utils.py