bapsf-motion 0.2.3__tar.gz → 0.2.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/PKG-INFO +1 -1
  2. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/gui/configure/motion_group_widget.py +159 -78
  3. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/gui/configure/motion_space_display.py +27 -0
  4. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/gui/widgets/__init__.py +2 -0
  5. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/gui/widgets/buttons.py +33 -6
  6. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/gui/widgets/misc.py +63 -2
  7. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion.egg-info/PKG-INFO +1 -1
  8. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/.gitattributes +0 -0
  9. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/.github/dependabot.yml +0 -0
  10. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/.github/workflows/python-publish.yml +0 -0
  11. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/.github/workflows/test.yml +0 -0
  12. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/.gitignore +0 -0
  13. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/.readthedocs.yml +0 -0
  14. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/README.md +0 -0
  15. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/__init__.py +0 -0
  16. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/actors/__init__.py +0 -0
  17. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/actors/axis_.py +0 -0
  18. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/actors/base.py +0 -0
  19. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/actors/demos/__init__.py +0 -0
  20. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/actors/demos/drive_timed_run_1D.py +0 -0
  21. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/actors/demos/drive_timed_run_2D.py +0 -0
  22. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/actors/demos/mgroup_timed_run_2D.py +0 -0
  23. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/actors/drive_.py +0 -0
  24. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/actors/manager_.py +0 -0
  25. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/actors/motion_group_.py +0 -0
  26. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/actors/motor_.py +0 -0
  27. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/actors/tests/__init__.py +0 -0
  28. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/examples/20240627_2D_test_setup.toml +0 -0
  29. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/examples/20241004_2D_test_setup.toml +0 -0
  30. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/examples/bapsf_motion.toml +0 -0
  31. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/examples/benchtop_motion_group.toml +0 -0
  32. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/examples/benchtop_run.toml +0 -0
  33. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/examples/mg_1d.toml +0 -0
  34. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/examples/mg_2d_strb_test_setup.toml +0 -0
  35. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/examples/motion_group.toml +0 -0
  36. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/gui/__init__.py +0 -0
  37. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/gui/configure/__init__.py +0 -0
  38. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/gui/configure/bases.py +0 -0
  39. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/gui/configure/configure.qss +0 -0
  40. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/gui/configure/configure_.py +0 -0
  41. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/gui/configure/drive_overlay.py +0 -0
  42. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/gui/configure/helpers.py +0 -0
  43. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/gui/configure/motion_builder_overlay.py +0 -0
  44. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/gui/configure/transform_overlay.py +0 -0
  45. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/gui/helpers.py +0 -0
  46. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/gui/motor.py +0 -0
  47. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/gui/widgets/logging.py +0 -0
  48. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/motion_builder/__init__.py +0 -0
  49. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/motion_builder/core.py +0 -0
  50. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/motion_builder/exclusions/__init__.py +0 -0
  51. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/motion_builder/exclusions/base.py +0 -0
  52. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/motion_builder/exclusions/circular.py +0 -0
  53. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/motion_builder/exclusions/divider.py +0 -0
  54. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/motion_builder/exclusions/helpers.py +0 -0
  55. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/motion_builder/exclusions/lapd.py +0 -0
  56. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/motion_builder/exclusions/shadow.py +0 -0
  57. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/motion_builder/item.py +0 -0
  58. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/motion_builder/layers/__init__.py +0 -0
  59. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/motion_builder/layers/base.py +0 -0
  60. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/motion_builder/layers/helpers.py +0 -0
  61. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/motion_builder/layers/regular_grid.py +0 -0
  62. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/transform/__init__.py +0 -0
  63. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/transform/base.py +0 -0
  64. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/transform/helpers.py +0 -0
  65. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/transform/identity.py +0 -0
  66. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/transform/lapd.py +0 -0
  67. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/transform/lapd_droop.py +0 -0
  68. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/utils/__init__.py +0 -0
  69. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/utils/exceptions.py +0 -0
  70. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/utils/toml.py +0 -0
  71. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion/utils/units_.py +0 -0
  72. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion.egg-info/SOURCES.txt +0 -0
  73. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion.egg-info/dependency_links.txt +0 -0
  74. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion.egg-info/requires.txt +0 -0
  75. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/bapsf_motion.egg-info/top_level.txt +0 -0
  76. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/Makefile +0 -0
  77. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/_static/BaPSF_Logo_Color_RGB.png +0 -0
  78. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/_static/BaPSF_Logo_Color_yellow_background_RGB_32px.ico +0 -0
  79. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/_static/BaPSF_Logo_White_RGB.png +0 -0
  80. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/_static/BaPSF_Logo_White_RGB_150px.png +0 -0
  81. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/_static/css/overrides.css +0 -0
  82. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.actors.axis_.rst +0 -0
  83. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.actors.base.rst +0 -0
  84. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.actors.drive_.rst +0 -0
  85. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.actors.manager_.rst +0 -0
  86. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.actors.motion_group_.rst +0 -0
  87. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.actors.motor_.rst +0 -0
  88. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.actors.rst +0 -0
  89. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.gui.configure.rst +0 -0
  90. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.gui.motor.rst +0 -0
  91. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.gui.rst +0 -0
  92. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.gui.widgets.buttons.rst +0 -0
  93. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.gui.widgets.logging.rst +0 -0
  94. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.gui.widgets.misc.rst +0 -0
  95. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.gui.widgets.rst +0 -0
  96. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.motion_builder.core.rst +0 -0
  97. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.motion_builder.exclusions.base.rst +0 -0
  98. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.motion_builder.exclusions.circular.rst +0 -0
  99. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.motion_builder.exclusions.divider.rst +0 -0
  100. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.motion_builder.exclusions.helpers.rst +0 -0
  101. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.motion_builder.exclusions.lapd.rst +0 -0
  102. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.motion_builder.exclusions.rst +0 -0
  103. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.motion_builder.exclusions.shadow.rst +0 -0
  104. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.motion_builder.item.rst +0 -0
  105. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.motion_builder.layers.base.rst +0 -0
  106. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.motion_builder.layers.helpers.rst +0 -0
  107. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.motion_builder.layers.regular_grid.rst +0 -0
  108. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.motion_builder.layers.rst +0 -0
  109. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.motion_builder.rst +0 -0
  110. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.rst +0 -0
  111. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.transform.base.rst +0 -0
  112. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.transform.helpers.rst +0 -0
  113. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.transform.identity.rst +0 -0
  114. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.transform.lapd.rst +0 -0
  115. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.transform.lapd_droop.rst +0 -0
  116. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.transform.rst +0 -0
  117. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.utils.exceptions.rst +0 -0
  118. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.utils.rst +0 -0
  119. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.utils.toml.rst +0 -0
  120. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/api_static/bapsf_motion.utils.units_.rst +0 -0
  121. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/available_transformers.rst +0 -0
  122. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/bibliography.bib +0 -0
  123. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/bibliography.rst +0 -0
  124. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/common_links.rst +0 -0
  125. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/conf.py +0 -0
  126. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/glossary.rst +0 -0
  127. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/index.rst +0 -0
  128. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/make.bat +0 -0
  129. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/motion_builder/index.rst +0 -0
  130. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/notebooks/motion_list/CircularExclusion.ipynb +0 -0
  131. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/notebooks/motion_list/LaPDXYExclusion.ipynb +0 -0
  132. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/notebooks/motion_list/Shadow2DExclusion.ipynb +0 -0
  133. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/notebooks/motion_list/motionlist.ipynb +0 -0
  134. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/notebooks/prototypes/README.md +0 -0
  135. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/notebooks/transform/identity_transform.ipynb +0 -0
  136. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/notebooks/transform/lapd_xy_droop_correction.ipynb +0 -0
  137. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/notebooks/transform/lapd_xy_transform.ipynb +0 -0
  138. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/notebooks_.rst +0 -0
  139. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/robots.txt +0 -0
  140. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/docs/toml/index.rst +0 -0
  141. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/pyproject.toml +0 -0
  142. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/requirements/build.txt +0 -0
  143. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/requirements/docs.txt +0 -0
  144. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/requirements/extras.txt +0 -0
  145. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/requirements/gui.txt +0 -0
  146. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/requirements/install.txt +0 -0
  147. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/requirements/readthedocs.txt +0 -0
  148. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/requirements/tests.txt +0 -0
  149. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/requirements.txt +0 -0
  150. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/resources/README.md +0 -0
  151. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/resources/Remote module installation guide.pdf +0 -0
  152. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/setup.cfg +0 -0
  153. {bapsf_motion-0.2.3 → bapsf_motion-0.2.4}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: bapsf_motion
3
- Version: 0.2.3
3
+ Version: 0.2.4
4
4
  Summary: Package for controlling motion devices in a BaPSF DAQ system
5
5
  Author: Basic Plasma Science Facility
6
6
  Keywords: plasma physics,plasma,science,bapsf,motion
@@ -50,6 +50,7 @@ from bapsf_motion.gui.widgets import (
50
50
  HLinePlain,
51
51
  IconButton,
52
52
  LED,
53
+ QTAIconLabel,
53
54
  StyleButton,
54
55
  StopButton,
55
56
  ValidButton,
@@ -518,8 +519,12 @@ class AxisControlWidget(QWidget):
518
519
  return val * unit
519
520
 
520
521
  @property
521
- def target_position(self):
522
- return float(self.target_position_label.text())
522
+ def target_position(self) -> Union[float, None]:
523
+ try:
524
+ pos = float(self.target_position_label.text())
525
+ except ValueError:
526
+ pos = None
527
+ return pos
523
528
 
524
529
  @property
525
530
  def interactive_display_mode(self):
@@ -560,6 +565,9 @@ class AxisControlWidget(QWidget):
560
565
  if self._mg.terminated:
561
566
  return
562
567
 
568
+ if not self.isEnabled():
569
+ return
570
+
563
571
  pos = self.position
564
572
  self.position_label.setText(f"{pos.value:.2f} {pos.unit}")
565
573
 
@@ -577,12 +585,7 @@ class AxisControlWidget(QWidget):
577
585
  self.jog_delta_label.setText(f"{val:.2f}")
578
586
 
579
587
  def _validate_target_position_value(self):
580
- try:
581
- val = self.target_position
582
- except ValueError:
583
- val = None
584
-
585
- self.targetPositionChanged.emit(val)
588
+ self.targetPositionChanged.emit(self.target_position)
586
589
 
587
590
  def _zero_axis(self):
588
591
  self.logger.info(f"Setting zero of axis {self.axis_index}")
@@ -987,6 +990,13 @@ class DriveDesktopController(DriveBaseController):
987
990
  )
988
991
  target_pos = []
989
992
 
993
+ if any(p is None for p in target_pos):
994
+ self.logger.warning(
995
+ f"Requested target position ({target_pos}) is not valid,"
996
+ f" NOT performing move to."
997
+ )
998
+ return
999
+
990
1000
  self.moveTo.emit(target_pos)
991
1001
 
992
1002
  def set_target_position(self, target_position: List[float]):
@@ -1390,6 +1400,12 @@ class DriveControlWidget(QWidget):
1390
1400
  self.desktop_controller_widget.driveStatusChanged.connect(
1391
1401
  self.driveStatusChanged.emit
1392
1402
  )
1403
+ self.desktop_controller_widget.movementStarted.connect(
1404
+ self._drive_movement_started
1405
+ )
1406
+ self.desktop_controller_widget.movementStopped.connect(
1407
+ self._drive_movement_finished
1408
+ )
1393
1409
 
1394
1410
  self.controller_combo_box.currentTextChanged.connect(self._switch_stack)
1395
1411
 
@@ -1530,19 +1546,13 @@ class DriveControlWidget(QWidget):
1530
1546
  if self.game_controller_widget is not None:
1531
1547
  self.game_controller_widget.update_all_axis_displays()
1532
1548
 
1533
- @Slot(int)
1534
- def _drive_movement_started(self, axis_index):
1549
+ def _drive_movement_started(self):
1550
+ self.controller_combo_box.setEnabled(False)
1535
1551
  self.movementStarted.emit()
1536
1552
 
1537
- @Slot(int)
1538
- def _drive_movement_finished(self, axis_index):
1539
- if not isinstance(self.mg, MotionGroup) or not isinstance(self.mg.drive, Drive):
1540
- return
1541
-
1542
- is_moving = [ax.is_moving for ax in self.mg.drive.axes]
1543
- is_moving[axis_index] = False
1544
- if not any(is_moving):
1545
- self.movementStopped.emit()
1553
+ def _drive_movement_finished(self):
1554
+ self.controller_combo_box.setEnabled(True)
1555
+ self.movementStopped.emit()
1546
1556
 
1547
1557
  @Slot(list)
1548
1558
  def _move_to(self, target_pos):
@@ -1679,11 +1689,9 @@ class MGWidget(QWidget):
1679
1689
  _btn = DiscardButton(parent=self)
1680
1690
  self.discard_btn = _btn
1681
1691
 
1682
- _icon = QLabel(parent=self)
1683
- _icon.setPixmap(qta.icon("mdi.steering").pixmap(24, 24))
1684
- _icon.setMaximumWidth(32)
1685
- _icon.setMaximumHeight(32)
1686
- _icon.setAlignment(Qt.AlignmentFlag.AlignCenter | Qt.AlignmentFlag.AlignVCenter)
1692
+ _icon = QTAIconLabel("mdi.steering", parent=self)
1693
+ _icon.setFixedSize(32)
1694
+ _icon.setIconSize(24)
1687
1695
  self.drive_label = _icon
1688
1696
 
1689
1697
  _w = QComboBox(parent=self)
@@ -1700,11 +1708,10 @@ class MGWidget(QWidget):
1700
1708
  _btn = GearValidButton(parent=self)
1701
1709
  self.drive_btn = _btn
1702
1710
 
1703
- _icon = QLabel(parent=self)
1704
- _icon.setPixmap(qta.icon("mdi.motion").pixmap(24, 24))
1705
- _icon.setMaximumWidth(32)
1706
- _icon.setMaximumHeight(32)
1707
1711
  _icon.setAlignment(Qt.AlignmentFlag.AlignCenter | Qt.AlignmentFlag.AlignVCenter)
1712
+ _icon = QTAIconLabel("mdi.motion", parent=self)
1713
+ _icon.setFixedSize(32)
1714
+ _icon.setIconSize(24)
1708
1715
  self.mb_label = _icon
1709
1716
 
1710
1717
  _w = QComboBox(parent=self)
@@ -1722,11 +1729,9 @@ class MGWidget(QWidget):
1722
1729
  _btn.setEnabled(False)
1723
1730
  self.mb_btn = _btn
1724
1731
 
1725
- _icon = QLabel(parent=self)
1726
- _icon.setPixmap(qta.icon("fa5s.exchange-alt").pixmap(24, 24))
1727
- _icon.setMaximumWidth(32)
1728
- _icon.setMaximumHeight(32)
1729
- _icon.setAlignment(Qt.AlignmentFlag.AlignCenter | Qt.AlignmentFlag.AlignVCenter)
1732
+ _icon = QTAIconLabel("fa5s.exchange-alt", parent=self)
1733
+ _icon.setFixedSize(32)
1734
+ _icon.setIconSize(24)
1730
1735
  self.transform_label = _icon
1731
1736
 
1732
1737
  _w = QComboBox(parent=self)
@@ -1758,6 +1763,9 @@ class MGWidget(QWidget):
1758
1763
  self.drive_control_widget.setEnabled(False)
1759
1764
 
1760
1765
  self.mpl_canvas = MotionSpaceDisplay(parent=self)
1766
+ _policy = self.mpl_canvas.sizePolicy()
1767
+ _policy.setRetainSizeWhenHidden(True)
1768
+ self.mpl_canvas.setSizePolicy(_policy)
1761
1769
 
1762
1770
  self.setLayout(self._define_layout())
1763
1771
  self._connect_signals()
@@ -1851,7 +1859,10 @@ class MGWidget(QWidget):
1851
1859
  self.discard_btn.clicked.connect(self.close)
1852
1860
 
1853
1861
  def _update_position_in_plot(self):
1854
- position = self.drive_control_widget.position
1862
+ if self.drive_control_widget.isEnabled():
1863
+ position = self.drive_control_widget.position
1864
+ else:
1865
+ position = None
1855
1866
  self.mpl_canvas.update_position_plot(position)
1856
1867
 
1857
1868
  def _define_layout(self):
@@ -1877,10 +1888,11 @@ class MGWidget(QWidget):
1877
1888
 
1878
1889
  def _define_mg_builder_layout(self):
1879
1890
  layout = QHBoxLayout()
1891
+ layout.setContentsMargins(0, 0, 0, 0)
1880
1892
  layout.addLayout(self._define_toml_layout())
1881
- layout.addSpacing(12)
1882
- layout.addLayout(self._define_central_builder_layout())
1883
- layout.addSpacing(12)
1893
+ layout.addSpacing(8)
1894
+ layout.addWidget(self._define_central_builder_widget())
1895
+ layout.addSpacing(8)
1884
1896
  layout.addWidget(self.mpl_canvas)
1885
1897
 
1886
1898
  return layout
@@ -1900,12 +1912,9 @@ class MGWidget(QWidget):
1900
1912
 
1901
1913
  return layout
1902
1914
 
1903
- def _define_central_builder_layout(self):
1915
+ def _define_central_builder_widget(self):
1904
1916
 
1905
- _label = QLabel("Name: ", parent=self)
1906
- _label.setAlignment(
1907
- Qt.AlignmentFlag.AlignVCenter | Qt. AlignmentFlag.AlignLeft
1908
- )
1917
+ _label = QLabel("Name:", parent=self)
1909
1918
  _label.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
1910
1919
  font = _label.font()
1911
1920
  font.setPointSize(16)
@@ -1913,7 +1922,9 @@ class MGWidget(QWidget):
1913
1922
  name_label = _label
1914
1923
 
1915
1924
  title_sub_layout = QHBoxLayout()
1925
+ title_sub_layout.setContentsMargins(12, 0, 12, 0)
1916
1926
  title_sub_layout.addWidget(name_label)
1927
+ title_sub_layout.addSpacing(4)
1917
1928
  title_sub_layout.addWidget(self.mg_name_widget)
1918
1929
 
1919
1930
  drive_sub_layout = QHBoxLayout()
@@ -1931,19 +1942,98 @@ class MGWidget(QWidget):
1931
1942
  transform_sub_layout.addWidget(self.transform_dropdown)
1932
1943
  transform_sub_layout.addWidget(self.transform_btn)
1933
1944
 
1945
+ _legend_txt = QLabel("LEGEND", parent=self)
1946
+ font = _legend_txt.font()
1947
+ font.setBold(True)
1948
+ font.setPointSize(10)
1949
+ _legend_txt.setFont(font)
1950
+
1951
+ valid_gear_legend_layout = QHBoxLayout()
1952
+ valid_gear_legend_layout.setContentsMargins(0, 0, 0, 0)
1953
+ _btn = GearValidButton(parent=self)
1954
+ _btn.set_valid()
1955
+ _btn.setFixedSize(24)
1956
+ _btn.setIconSize(20)
1957
+ valid_gear_legend_layout.addWidget(_btn)
1958
+ valid_gear_legend_layout.addSpacing(4)
1959
+ valid_gear_legend_layout.addWidget(
1960
+ QLabel("Configuration valid. Click to edit.", parent=self)
1961
+ )
1962
+
1963
+ invalid_gear_legend_layout = QHBoxLayout()
1964
+ invalid_gear_legend_layout.setContentsMargins(0, 0, 0, 0)
1965
+ _btn = GearValidButton(parent=self)
1966
+ _btn.set_invalid()
1967
+ _btn.setFixedSize(24)
1968
+ _btn.setIconSize(20)
1969
+ invalid_gear_legend_layout.addWidget(_btn)
1970
+ invalid_gear_legend_layout.addSpacing(4)
1971
+ invalid_gear_legend_layout.addWidget(
1972
+ QLabel(
1973
+ "Configuration invalid. Click to edit.\nHover for tooltip.",
1974
+ parent=self,
1975
+ ),
1976
+ )
1977
+
1978
+ drive_legend_layout = QHBoxLayout()
1979
+ drive_legend_layout.setContentsMargins(2, 0, 0, 0)
1980
+ _icon = QTAIconLabel("mdi.steering", parent=self)
1981
+ _icon.setFixedSize(20)
1982
+ _icon.setIconSize(20)
1983
+ drive_legend_layout.addWidget(_icon)
1984
+ drive_legend_layout.addSpacing(6)
1985
+ drive_legend_layout.addWidget(
1986
+ QLabel("Drive configuration.", parent=self)
1987
+ )
1988
+
1989
+ mb_legend_layout = QHBoxLayout()
1990
+ mb_legend_layout.setContentsMargins(2, 0, 0, 0)
1991
+ _icon = QTAIconLabel("mdi.motion", parent=self)
1992
+ _icon.setFixedSize(20)
1993
+ _icon.setIconSize(20)
1994
+ mb_legend_layout.addWidget(_icon)
1995
+ mb_legend_layout.addSpacing(6)
1996
+ mb_legend_layout.addWidget(
1997
+ QLabel("Motion Builder / Space configuration.", parent=self)
1998
+ )
1999
+
2000
+ tr_legend_layout = QHBoxLayout()
2001
+ tr_legend_layout.setContentsMargins(2, 0, 0, 0)
2002
+ _icon = QTAIconLabel("fa5s.exchange-alt", parent=self)
2003
+ _icon.setFixedSize(20)
2004
+ _icon.setIconSize(20)
2005
+ tr_legend_layout.addWidget(_icon)
2006
+ tr_legend_layout.addSpacing(6)
2007
+ tr_legend_layout.addWidget(
2008
+ QLabel("Transformer configuration.", parent=self)
2009
+ )
2010
+
1934
2011
  layout = QVBoxLayout()
2012
+ layout.setContentsMargins(0, 0, 0, 0)
1935
2013
  layout.addSpacing(18)
1936
2014
  layout.addLayout(title_sub_layout)
1937
- layout.addSpacing(18)
2015
+ layout.addSpacing(12)
1938
2016
  layout.addLayout(drive_sub_layout)
1939
2017
  layout.addLayout(mb_sub_layout)
1940
2018
  layout.addLayout(transform_sub_layout)
2019
+ layout.addSpacing(8)
2020
+ layout.addWidget(HLinePlain(parent=self))
2021
+ layout.addWidget(
2022
+ _legend_txt,
2023
+ alignment=Qt.AlignmentFlag.AlignCenter,
2024
+ )
2025
+ layout.addLayout(valid_gear_legend_layout)
2026
+ layout.addLayout(invalid_gear_legend_layout)
2027
+ layout.addSpacing(4)
2028
+ layout.addLayout(drive_legend_layout)
2029
+ layout.addLayout(mb_legend_layout)
2030
+ layout.addLayout(tr_legend_layout)
1941
2031
  layout.addStretch()
1942
2032
 
1943
- return layout
1944
-
1945
- def _define_mspace_display_layout(self):
1946
- ...
2033
+ _widget = QWidget(parent=self)
2034
+ _widget.setLayout(layout)
2035
+ _widget.setFixedWidth(335)
2036
+ return _widget
1947
2037
 
1948
2038
  def _build_drive_defaults(self) -> List[Tuple[str, Dict[str, Any]]]:
1949
2039
  # Returned _drive_defaults is a List of Tuple pairs
@@ -2678,6 +2768,14 @@ class MGWidget(QWidget):
2678
2768
  vmg_name = self._validate_motion_group_name()
2679
2769
  vdrive = self._validate_drive()
2680
2770
 
2771
+ # Enable / Disable Motion Builder Config
2772
+ self.mb_dropdown.setEnabled(vdrive)
2773
+ self.mb_btn.setEnabled(vdrive)
2774
+
2775
+ # Enable / Disable Transformer Config
2776
+ self.transform_dropdown.setEnabled(vdrive)
2777
+ self.transform_btn.setEnabled(vdrive)
2778
+
2681
2779
  if not isinstance(self.mg, MotionGroup):
2682
2780
  mb = None
2683
2781
  transform = None
@@ -2689,23 +2787,25 @@ class MGWidget(QWidget):
2689
2787
  self.mb_btn.set_invalid()
2690
2788
  self.mb_btn.setToolTip("Motion space needs to be defined.")
2691
2789
  self.done_btn.setEnabled(False)
2790
+ elif "layer" not in mb.config:
2791
+ self.mb_btn.set_invalid()
2792
+ self.mb_btn.setToolTip(
2793
+ "A point layer needs to be defined to generate a motion list."
2794
+ )
2692
2795
  else:
2693
- if "layer" not in mb.config:
2694
- self.mb_btn.set_invalid()
2695
- self.mb_btn.setToolTip(
2696
- "A point layer needs to be defined to generate a motion list."
2697
- )
2698
- else:
2699
- self.mb_btn.set_valid()
2700
- self.mb_btn.setToolTip("")
2796
+ self.mb_btn.set_valid()
2797
+ self.mb_btn.setToolTip("")
2701
2798
 
2702
2799
  if not isinstance(transform, BaseTransform):
2703
2800
  self.transform_btn.set_invalid()
2704
- self.done_btn.setEnabled(False)
2801
+ self.transform_btn.setToolTip("Transformer needs to be fully configured.")
2705
2802
 
2803
+ self.done_btn.setEnabled(False)
2706
2804
  self.drive_control_widget.setEnabled(False)
2707
2805
  else:
2708
2806
  self.transform_btn.set_valid()
2807
+ self.transform_btn.setToolTip("")
2808
+
2709
2809
  self.drive_control_widget.setEnabled(True)
2710
2810
 
2711
2811
  if (
@@ -2758,26 +2858,14 @@ class MGWidget(QWidget):
2758
2858
  if not isinstance(self.mg, MotionGroup) or not isinstance(self.mg.drive, Drive):
2759
2859
  self.done_btn.setEnabled(False)
2760
2860
 
2761
- self.mb_dropdown.setEnabled(False)
2762
- self.mb_btn.setEnabled(False)
2763
- self.mb_btn.set_invalid()
2764
- self.mb_btn.setToolTip("Motion space needs to be defined.")
2765
-
2766
- self.transform_dropdown.setEnabled(False)
2767
- self.transform_btn.setEnabled(False)
2768
- self.transform_btn.set_invalid()
2769
-
2770
2861
  self.drive_btn.set_invalid()
2771
2862
  self.drive_control_widget.setEnabled(False)
2772
2863
 
2773
2864
  self.drive_btn.setToolTip("Drive is not fully configured.")
2774
2865
  return False
2775
2866
 
2776
- self.mb_dropdown.setEnabled(True)
2777
- self.mb_btn.setEnabled(True)
2778
-
2779
- self.transform_dropdown.setEnabled(True)
2780
- self.transform_btn.setEnabled(True)
2867
+ self.drive_dropdown.setEnabled(True)
2868
+ self.drive_btn.setEnabled(True)
2781
2869
 
2782
2870
  if self.mg.drive.terminated:
2783
2871
  self.drive_btn.set_invalid()
@@ -2884,14 +2972,7 @@ class MGWidget(QWidget):
2884
2972
  self.transform_btn.setEnabled(False)
2885
2973
 
2886
2974
  def enable_config_controls(self):
2887
- self.drive_dropdown.setEnabled(True)
2888
- self.drive_btn.setEnabled(True)
2889
-
2890
- self.mb_dropdown.setEnabled(True)
2891
- self.mb_btn.setEnabled(True)
2892
-
2893
- self.transform_dropdown.setEnabled(True)
2894
- self.transform_btn.setEnabled(True)
2975
+ self._validate_motion_group()
2895
2976
 
2896
2977
  def return_and_close(self):
2897
2978
  config = _deepcopy_dict(self.mg.config)
@@ -234,6 +234,31 @@ class MotionSpaceDisplay(QFrame):
234
234
  # Draw current position
235
235
  self.update_position_plot(position=position)
236
236
 
237
+ # Draw legend
238
+ self.update_legend()
239
+
240
+ self.mpl_canvas.draw()
241
+
242
+ def update_legend(self):
243
+ _names = ["motion_list", "probe", "position", "target", "insertion_point"]
244
+
245
+ # gather handles for legend
246
+ handles = []
247
+ for name in _names:
248
+ stuff = self._get_plot_axis_by_name(name)
249
+ if stuff is None:
250
+ continue
251
+
252
+ ax, handle = stuff
253
+ handles.append(handle)
254
+
255
+ if len(handles) == 0:
256
+ self.mpl_canvas.draw()
257
+ return
258
+
259
+ ax = self.mpl_canvas.figure.gca()
260
+ ax.legend(handles=handles)
261
+
237
262
  self.mpl_canvas.draw()
238
263
 
239
264
  def update_target_position_plot(self, position):
@@ -271,6 +296,7 @@ class MotionSpaceDisplay(QFrame):
271
296
  label=_label,
272
297
  )
273
298
 
299
+ self.update_legend()
274
300
  self.mpl_canvas.draw()
275
301
 
276
302
  def update_position_plot(self, position):
@@ -343,6 +369,7 @@ class MotionSpaceDisplay(QFrame):
343
369
  label=_label,
344
370
  )
345
371
 
372
+ self.update_legend()
346
373
  self.mpl_canvas.draw()
347
374
 
348
375
  def closeEvent(self, event):
@@ -16,6 +16,7 @@ __all__ = [
16
16
  "QLineEditSpecialized",
17
17
  "QLogger",
18
18
  "QLogHandler",
19
+ "QTAIconLabel",
19
20
  "StopButton",
20
21
  "StyleButton",
21
22
  "ValidButton",
@@ -41,6 +42,7 @@ from bapsf_motion.gui.widgets.misc import (
41
42
  BatteryStatusIcon,
42
43
  IPv4Validator,
43
44
  QLineEditSpecialized,
45
+ QTAIconLabel,
44
46
  HLinePlain,
45
47
  VLinePlain,
46
48
  )
@@ -399,13 +399,14 @@ class GearValidButton(ValidButton):
399
399
  action="checked",
400
400
  ) # checked state is the valid state
401
401
 
402
- self._size = 32
403
- self._icon_size = 28
404
-
405
- self.setFixedWidth(self._size)
406
- self.setFixedHeight(self._size)
407
402
  self.setIcon(self._invalid_icon)
408
- self.setIconSize(QSize(self._icon_size, self._icon_size))
403
+
404
+ self._size = None
405
+ self.setFixedSize(32)
406
+
407
+ self._icon_size = None
408
+ self.setIconSize(28)
409
+
409
410
  self.setChecked(False)
410
411
 
411
412
  def set_valid(self, state: bool = True):
@@ -417,6 +418,32 @@ class GearValidButton(ValidButton):
417
418
  self.setIcon(self._invalid_icon)
418
419
  super().set_invalid()
419
420
 
421
+ def setIconSize(self, size: int):
422
+ if not isinstance(size, int):
423
+ return
424
+ elif size <= 0:
425
+ return
426
+
427
+ self._icon_size = size
428
+ size = QSize(size, size)
429
+ super().setIconSize(size)
430
+
431
+ def setFixedSize(self, size: int):
432
+ if not isinstance(size, int):
433
+ return
434
+ elif size <= 0:
435
+ return
436
+
437
+ self._size = size
438
+ size = QSize(size, size)
439
+ super().setFixedSize(size)
440
+
441
+ def setFixedHeight(self, h):
442
+ self.setFixedSize(h)
443
+
444
+ def setFixedWidth(self, w):
445
+ self.setFixedSize(w)
446
+
420
447
  def _change_validation_icon(self):
421
448
  _icon = self._valid_icon if self.is_valid else self._invalid_icon
422
449
  self.setIcon(_icon)
@@ -3,15 +3,17 @@ __all__ = [
3
3
  "BatteryStatusIcon",
4
4
  "IPv4Validator",
5
5
  "QLineEditSpecialized",
6
+ "QTAIconLabel",
6
7
  "HLinePlain",
7
8
  "VLinePlain",
8
9
  ]
9
10
 
10
11
  import logging
11
12
 
12
- from PySide6.QtCore import Qt, Signal
13
- from PySide6.QtGui import QValidator, QColor
13
+ from PySide6.QtCore import Qt, Signal, QSize
14
+ from PySide6.QtGui import QValidator, QColor, QIcon
14
15
  from PySide6.QtWidgets import QFrame, QLabel, QLineEdit, QWidget
16
+ from typing import Union
15
17
 
16
18
  # noqa
17
19
  # import of qtawesome must happen after the PySide6 imports
@@ -20,6 +22,65 @@ import qtawesome as qta
20
22
  from bapsf_motion.utils import ipv4_pattern as _ipv4_pattern
21
23
 
22
24
 
25
+ class QTAIconLabel(QLabel):
26
+ def __init__(self, icon_name, parent=None):
27
+ super().__init__(parent=parent)
28
+
29
+ self._icon_name = None
30
+ self._icon = None
31
+ self.setIcon(icon_name)
32
+
33
+ self.setFixedSize(32)
34
+ self.setIconSize(28)
35
+ self.setAlignment(Qt.AlignmentFlag.AlignCenter | Qt.AlignmentFlag.AlignVCenter)
36
+
37
+ @property
38
+ def icon_name(self) -> str:
39
+ return self._icon_name
40
+
41
+ @property
42
+ def icon(self) -> QIcon:
43
+ return self._icon
44
+
45
+ def _get_icon(self):
46
+ return qta.icon(self._icon_name)
47
+
48
+ def setIcon(self, icon_name: str): # noqa
49
+ try:
50
+ _icon = qta.icon(icon_name)
51
+ except Exception: # noqa
52
+ return
53
+
54
+ self._icon_name = icon_name
55
+ self._icon = _icon
56
+
57
+ def setIconSize(self, size: int): # noqa
58
+ if not isinstance(size, int):
59
+ return
60
+ elif size < 1:
61
+ return
62
+
63
+ self.setPixmap(self.icon.pixmap(size, size))
64
+
65
+ def setFixedSize(self, size: Union[QSize, int]):
66
+ if isinstance(size, QSize):
67
+ pass
68
+ elif not isinstance(size, int):
69
+ return
70
+ elif size < 1:
71
+ return
72
+ else:
73
+ size = QSize(size, size)
74
+
75
+ super().setFixedSize(size)
76
+
77
+ def setFixedWidth(self, w):
78
+ self.setFixedSize(w)
79
+
80
+ def setFixedHeight(self, h):
81
+ self.setFixedSize(h)
82
+
83
+
23
84
  class BatteryStatusIcon(QLabel):
24
85
  def __init__(self, parent=None):
25
86
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: bapsf_motion
3
- Version: 0.2.3
3
+ Version: 0.2.4
4
4
  Summary: Package for controlling motion devices in a BaPSF DAQ system
5
5
  Author: Basic Plasma Science Facility
6
6
  Keywords: plasma physics,plasma,science,bapsf,motion
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes