summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/enabled.json2
-rw-r--r--plugins/example/__pycache__/plugin.cpython-312.pycbin3549 -> 0 bytes
-rw-r--r--plugins/example/manifest.json8
-rw-r--r--plugins/example/plugin.py105
-rw-r--r--plugins/motion_capture/plugin.py11
5 files changed, 10 insertions, 116 deletions
diff --git a/plugins/enabled.json b/plugins/enabled.json
index a2216af..a33a40a 100644
--- a/plugins/enabled.json
+++ b/plugins/enabled.json
@@ -1,3 +1,3 @@
{
- "example": true
+ "motion_capture": true
} \ No newline at end of file
diff --git a/plugins/example/__pycache__/plugin.cpython-312.pyc b/plugins/example/__pycache__/plugin.cpython-312.pyc
deleted file mode 100644
index c31b466..0000000
--- a/plugins/example/__pycache__/plugin.cpython-312.pyc
+++ /dev/null
Binary files differ
diff --git a/plugins/example/manifest.json b/plugins/example/manifest.json
deleted file mode 100644
index a5af87d..0000000
--- a/plugins/example/manifest.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "plugin_id": "example",
- "name": "Example Plugin",
- "version": "1.0.0",
- "description": "Skeleton showing all plugin integration points. Safe to delete.",
- "author": "Your Name",
- "entry_point": "plugin.ExamplePlugin"
-}
diff --git a/plugins/example/plugin.py b/plugins/example/plugin.py
deleted file mode 100644
index e5fbb8e..0000000
--- a/plugins/example/plugin.py
+++ /dev/null
@@ -1,105 +0,0 @@
-"""
-plugins/example/plugin.py
-
-Skeleton plugin — shows every integration point.
-Copy this directory, rename it, update manifest.json, and fill in your logic.
-"""
-
-from __future__ import annotations
-from typing import Any, Dict, List, Optional, Type
-
-from PyQt6.QtWidgets import QLabel, QWidget
-
-# LabDAQ imports available at runtime
-from plugins.base_plugin import LabPlugin, PluginAction, PluginContext
-
-
-class ExamplePlugin(LabPlugin):
-
- # ── Metadata ──────────────────────────────────────────────────────────
-
- @property
- def plugin_id(self) -> str:
- return "example"
-
- @property
- def name(self) -> str:
- return "Example Plugin"
-
- @property
- def version(self) -> str:
- return "1.0.0"
-
- @property
- def description(self) -> str:
- return "Skeleton showing all plugin integration points."
-
- @property
- def author(self) -> str:
- return "Your Name"
-
- # ── Lifecycle ─────────────────────────────────────────────────────────
-
- def on_load(self, context: PluginContext) -> None:
- self._ctx = context
- # e.g. start a background thread, open a camera, etc.
-
- def on_unload(self) -> None:
- # Release resources — called when user disables plugin
- pass
-
- # ── Toolbar ───────────────────────────────────────────────────────────
-
- def get_toolbar_actions(self) -> List[PluginAction]:
- return [
- PluginAction(
- label = "Example",
- icon = "🔌",
- tooltip = "Open example plugin window",
- checkable = True,
- callback = self._on_toolbar_click,
- )
- ]
-
- def _on_toolbar_click(self, checked: bool):
- # Open / close your plugin window here
- pass
-
- # ── Devices ───────────────────────────────────────────────────────────
-
- def get_devices(self) -> list:
- # Return BaseDevice instances — they are auto-added to the registry
- # and AcquisitionEngine so their channels appear as normal signals.
- #
- # Example (uncomment and adapt):
- # from devices.analog_input import AnalogInputDevice
- # return [AnalogInputDevice("my_plugin_ai", num_channels=2, simulate=True)]
- return []
-
- # ── Custom filters ────────────────────────────────────────────────────
-
- def get_filter_classes(self) -> Dict[str, Type]:
- # Return {type_name: FilterBase subclass} for custom pipeline filters.
- #
- # Example:
- # from .my_filter import MyFilter
- # return {"my_filter": MyFilter}
- return {}
-
- # ── Settings widget ───────────────────────────────────────────────────
-
- def get_settings_widget(self) -> Optional[QWidget]:
- # Return a QWidget shown in Settings > Plugins when this plugin is enabled.
- lbl = QLabel("No settings for this plugin.")
- lbl.setObjectName("traceSource")
- return lbl
-
- # ── Profile persistence ───────────────────────────────────────────────
-
- def get_save_state(self) -> Dict[str, Any]:
- # Return JSON-serialisable dict saved with .labdaq profiles.
- return {}
-
- def apply_save_state(self, state: Dict[str, Any]) -> None:
- # Restore plugin state when a profile is loaded.
- pass
diff --git a/plugins/motion_capture/plugin.py b/plugins/motion_capture/plugin.py
index e5d37c7..1c655c5 100644
--- a/plugins/motion_capture/plugin.py
+++ b/plugins/motion_capture/plugin.py
@@ -166,9 +166,16 @@ class MotionCapturePlugin(LabPlugin):
self._win.set_px_per_mm(state.get("px_per_mm", 10.0))
if checked:
- geo = self._ctx.main_window.geometry()
if not self._win.isVisible():
- self._win.move(geo.right() + 8, geo.top() + 40)
+ from PyQt6.QtWidgets import QApplication
+ mw = self._ctx.main_window
+ screen = QApplication.screenAt(mw.geometry().center()) or QApplication.primaryScreen()
+ avail = screen.availableGeometry()
+ geo = mw.normalGeometry()
+ self._win.adjustSize()
+ x = max(avail.left(), min(geo.right() + 8, avail.right() - self._win.width()))
+ y = max(avail.top(), min(geo.top() + 40, avail.bottom() - self._win.height()))
+ self._win.move(x, y)
self._win.show()
self._win.raise_()
else: