bec-widgets 1.4.1__py3-none-any.whl → 1.5.1__py3-none-any.whl

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 (250) hide show
  1. CHANGELOG.md +32 -25
  2. PKG-INFO +1 -1
  3. bec_widgets/applications/alignment/alignment_1d/alignment_1d.py +7 -20
  4. bec_widgets/cli/client.py +430 -32
  5. bec_widgets/cli/generate_cli.py +2 -2
  6. bec_widgets/cli/rpc_register.py +2 -0
  7. bec_widgets/cli/rpc_wigdet_handler.py +5 -3
  8. bec_widgets/cli/server.py +2 -3
  9. bec_widgets/examples/jupyter_console/jupyter_console_window.py +10 -8
  10. bec_widgets/qt_utils/palette_viewer.py +1 -1
  11. bec_widgets/utils/crosshair.py +88 -35
  12. bec_widgets/utils/generate_designer_plugin.py +1 -1
  13. bec_widgets/utils/plugin_utils.py +14 -5
  14. bec_widgets/utils/ui_loader.py +2 -2
  15. bec_widgets/widgets/{dock → containers/dock}/dock_area.py +21 -11
  16. bec_widgets/widgets/{dock → containers/dock}/dock_area_plugin.py +1 -1
  17. bec_widgets/widgets/{dock → containers/dock}/register_dock_area.py +1 -1
  18. bec_widgets/widgets/{figure → containers/figure}/figure.py +41 -7
  19. bec_widgets/widgets/{figure → containers/figure}/plots/image/image.py +7 -4
  20. bec_widgets/widgets/{figure → containers/figure}/plots/image/image_item.py +5 -2
  21. bec_widgets/widgets/{figure → containers/figure}/plots/motor_map/motor_map.py +2 -2
  22. bec_widgets/widgets/containers/figure/plots/multi_waveform/multi_waveform.py +353 -0
  23. bec_widgets/widgets/{figure → containers/figure}/plots/waveform/waveform.py +2 -2
  24. bec_widgets/widgets/{figure → containers/figure}/plots/waveform/waveform_curve.py +2 -2
  25. bec_widgets/widgets/{button_abort → control/buttons/button_abort}/abort_button_plugin.py +1 -1
  26. bec_widgets/widgets/{button_abort → control/buttons/button_abort}/button_abort.py +1 -0
  27. bec_widgets/widgets/{button_abort → control/buttons/button_abort}/register_abort_button.py +3 -1
  28. bec_widgets/widgets/{button_reset → control/buttons/button_reset}/button_reset.py +1 -0
  29. bec_widgets/widgets/{button_reset → control/buttons/button_reset}/register_reset_button.py +3 -1
  30. bec_widgets/widgets/{button_reset → control/buttons/button_reset}/reset_button_plugin.py +1 -1
  31. bec_widgets/widgets/{button_resume → control/buttons/button_resume}/button_resume.py +1 -0
  32. bec_widgets/widgets/{button_resume → control/buttons/button_resume}/register_resume_button.py +3 -1
  33. bec_widgets/widgets/{button_resume → control/buttons/button_resume}/resume_button_plugin.py +1 -1
  34. bec_widgets/widgets/{stop_button → control/buttons/stop_button}/register_stop_button.py +1 -1
  35. bec_widgets/widgets/{stop_button → control/buttons/stop_button}/stop_button.py +1 -0
  36. bec_widgets/widgets/{stop_button → control/buttons/stop_button}/stop_button_plugin.py +1 -1
  37. bec_widgets/widgets/{position_indicator → control/device_control/position_indicator}/position_indicator.py +1 -1
  38. bec_widgets/widgets/{position_indicator → control/device_control/position_indicator}/position_indicator_plugin.py +3 -1
  39. bec_widgets/widgets/{position_indicator → control/device_control/position_indicator}/register_position_indicator.py +1 -1
  40. bec_widgets/widgets/{positioner_box → control/device_control/positioner_box}/positioner_box.py +6 -3
  41. bec_widgets/widgets/{positioner_box → control/device_control/positioner_box}/positioner_box_plugin.py +1 -1
  42. bec_widgets/widgets/{positioner_box → control/device_control/positioner_box}/positioner_control_line.py +2 -1
  43. bec_widgets/widgets/{positioner_box → control/device_control/positioner_box}/positioner_control_line_plugin.py +3 -1
  44. bec_widgets/widgets/{positioner_box → control/device_control/positioner_box}/register_positioner_box.py +3 -1
  45. bec_widgets/widgets/{positioner_box → control/device_control/positioner_box}/register_positioner_control_line.py +1 -1
  46. bec_widgets/widgets/{positioner_group → control/device_control/positioner_group}/positioner_group.py +3 -3
  47. bec_widgets/widgets/{positioner_group → control/device_control/positioner_group}/positioner_group_plugin.py +3 -1
  48. bec_widgets/widgets/{positioner_group → control/device_control/positioner_group}/register_positioner_group.py +3 -1
  49. bec_widgets/widgets/{device_combobox → control/device_input/device_combobox}/device_combo_box_plugin.py +1 -1
  50. bec_widgets/widgets/{device_combobox → control/device_input/device_combobox}/device_combobox.py +2 -1
  51. bec_widgets/widgets/{device_combobox → control/device_input/device_combobox}/register_device_combo_box.py +3 -1
  52. bec_widgets/widgets/{device_line_edit → control/device_input/device_line_edit}/device_line_edit.py +5 -2
  53. bec_widgets/widgets/{device_line_edit → control/device_input/device_line_edit}/device_line_edit_plugin.py +3 -1
  54. bec_widgets/widgets/{device_line_edit → control/device_input/device_line_edit}/register_device_line_edit.py +3 -1
  55. bec_widgets/widgets/{signal_combobox → control/device_input/signal_combobox}/register_signal_combobox.py +3 -1
  56. bec_widgets/widgets/{signal_combobox → control/device_input/signal_combobox}/signal_combobox.py +4 -1
  57. bec_widgets/widgets/{signal_combobox → control/device_input/signal_combobox}/signal_combobox_plugin.py +1 -1
  58. bec_widgets/widgets/{signal_line_edit → control/device_input/signal_line_edit}/register_signal_line_edit.py +3 -1
  59. bec_widgets/widgets/{signal_line_edit → control/device_input/signal_line_edit}/signal_line_edit.py +4 -1
  60. bec_widgets/widgets/{signal_line_edit → control/device_input/signal_line_edit}/signal_line_edit_plugin.py +3 -1
  61. bec_widgets/widgets/{scan_control → control/scan_control}/register_scan_control.py +1 -1
  62. bec_widgets/widgets/{scan_control → control/scan_control}/scan_control.py +5 -4
  63. bec_widgets/widgets/{scan_control → control/scan_control}/scan_control_plugin.py +1 -1
  64. bec_widgets/widgets/{scan_control → control/scan_control}/scan_group_box.py +4 -2
  65. bec_widgets/widgets/{dap_combo_box → dap/dap_combo_box}/dap_combo_box.py +1 -1
  66. bec_widgets/widgets/{dap_combo_box → dap/dap_combo_box}/dap_combo_box_plugin.py +1 -1
  67. bec_widgets/widgets/{dap_combo_box → dap/dap_combo_box}/register_dap_combo_box.py +1 -1
  68. bec_widgets/widgets/{lmfit_dialog → dap/lmfit_dialog}/lm_fit_dialog_plugin.py +1 -1
  69. bec_widgets/widgets/{lmfit_dialog → dap/lmfit_dialog}/lmfit_dialog.py +1 -0
  70. bec_widgets/widgets/{lmfit_dialog → dap/lmfit_dialog}/register_lm_fit_dialog.py +1 -1
  71. bec_widgets/widgets/{console → editors/console}/console.py +1 -0
  72. bec_widgets/widgets/{console → editors/console}/console_plugin.py +1 -1
  73. bec_widgets/widgets/{console → editors/console}/register_console.py +1 -1
  74. bec_widgets/widgets/{text_box → editors/text_box}/register_text_box.py +1 -1
  75. bec_widgets/widgets/{text_box → editors/text_box}/text_box.py +1 -0
  76. bec_widgets/widgets/{text_box → editors/text_box}/text_box_plugin.py +1 -1
  77. bec_widgets/widgets/{vscode → editors/vscode}/register_vs_code_editor.py +1 -1
  78. bec_widgets/widgets/{vscode → editors/vscode}/vs_code_editor_plugin.py +1 -1
  79. bec_widgets/widgets/{vscode → editors/vscode}/vscode.py +2 -2
  80. bec_widgets/widgets/{website → editors/website}/register_website_widget.py +1 -1
  81. bec_widgets/widgets/{website → editors/website}/website.py +1 -0
  82. bec_widgets/widgets/{website → editors/website}/website_widget_plugin.py +1 -1
  83. bec_widgets/widgets/{image → plots/image}/bec_image_widget_plugin.py +1 -1
  84. bec_widgets/widgets/{image → plots/image}/image_widget.py +7 -6
  85. bec_widgets/widgets/{image → plots/image}/register_bec_image_widget.py +1 -1
  86. bec_widgets/widgets/{motor_map → plots/motor_map}/bec_motor_map_widget_plugin.py +1 -1
  87. bec_widgets/widgets/{motor_map → plots/motor_map}/motor_map_widget.py +6 -6
  88. bec_widgets/widgets/{motor_map → plots/motor_map}/register_bec_motor_map_widget.py +3 -1
  89. bec_widgets/widgets/plots/multi_waveform/bec_multi_waveform_widget.pyproject +1 -0
  90. bec_widgets/widgets/plots/multi_waveform/bec_multi_waveform_widget_plugin.py +54 -0
  91. bec_widgets/widgets/plots/multi_waveform/multi_waveform_controls.ui +99 -0
  92. bec_widgets/widgets/plots/multi_waveform/multi_waveform_widget.py +535 -0
  93. bec_widgets/widgets/plots/multi_waveform/register_bec_multi_waveform_widget.py +17 -0
  94. bec_widgets/widgets/{waveform → plots/waveform}/bec_waveform_widget_plugin.py +1 -1
  95. bec_widgets/widgets/{waveform → plots/waveform}/register_bec_waveform_widget.py +3 -1
  96. bec_widgets/widgets/{waveform → plots/waveform}/waveform_popups/curve_dialog/curve_dialog.py +5 -3
  97. bec_widgets/widgets/plots/waveform/waveform_popups/dap_summary_dialog/__init__.py +0 -0
  98. bec_widgets/widgets/{waveform → plots/waveform}/waveform_popups/dap_summary_dialog/dap_summary_dialog.py +2 -6
  99. bec_widgets/widgets/{waveform → plots/waveform}/waveform_widget.py +9 -6
  100. bec_widgets/widgets/progress/__init__.py +0 -0
  101. bec_widgets/widgets/progress/bec_progressbar/__init__.py +0 -0
  102. bec_widgets/widgets/{bec_progressbar → progress/bec_progressbar}/bec_progress_bar_plugin.py +1 -1
  103. bec_widgets/widgets/{bec_progressbar → progress/bec_progressbar}/bec_progressbar.py +1 -0
  104. bec_widgets/widgets/{bec_progressbar → progress/bec_progressbar}/register_bec_progress_bar.py +3 -1
  105. bec_widgets/widgets/{ring_progress_bar → progress/ring_progress_bar}/register_ring_progress_bar.py +3 -1
  106. bec_widgets/widgets/{ring_progress_bar → progress/ring_progress_bar}/ring_progress_bar.py +2 -1
  107. bec_widgets/widgets/{ring_progress_bar → progress/ring_progress_bar}/ring_progress_bar_plugin.py +1 -1
  108. bec_widgets/widgets/services/__init__.py +0 -0
  109. bec_widgets/widgets/services/bec_queue/__init__.py +0 -0
  110. bec_widgets/widgets/{bec_queue → services/bec_queue}/bec_queue.py +5 -4
  111. bec_widgets/widgets/{bec_queue → services/bec_queue}/bec_queue_plugin.py +1 -1
  112. bec_widgets/widgets/{bec_queue → services/bec_queue}/register_bec_queue.py +1 -1
  113. bec_widgets/widgets/services/bec_status_box/__init__.py +0 -0
  114. bec_widgets/widgets/{bec_status_box → services/bec_status_box}/bec_status_box.py +3 -3
  115. bec_widgets/widgets/{bec_status_box → services/bec_status_box}/bec_status_box_plugin.py +1 -1
  116. bec_widgets/widgets/{bec_status_box → services/bec_status_box}/register_bec_status_box.py +1 -1
  117. bec_widgets/widgets/services/device_browser/__init__.py +0 -0
  118. bec_widgets/widgets/{device_browser → services/device_browser}/device_browser.py +3 -3
  119. bec_widgets/widgets/{device_browser → services/device_browser}/device_browser_plugin.py +1 -1
  120. bec_widgets/widgets/{device_browser → services/device_browser}/register_device_browser.py +3 -1
  121. bec_widgets/widgets/utility/__init__.py +0 -0
  122. bec_widgets/widgets/utility/spinner/__init__.py +0 -0
  123. bec_widgets/widgets/{spinner → utility/spinner}/register_spinner_widget.py +1 -1
  124. bec_widgets/widgets/{spinner → utility/spinner}/spinner.py +1 -0
  125. bec_widgets/widgets/{spinner → utility/spinner}/spinner_widget_plugin.py +1 -1
  126. bec_widgets/widgets/utility/toggle/__init__.py +0 -0
  127. bec_widgets/widgets/{toggle → utility/toggle}/register_toggle_switch.py +1 -1
  128. bec_widgets/widgets/{toggle → utility/toggle}/toggle.py +1 -0
  129. bec_widgets/widgets/{toggle → utility/toggle}/toggle_switch_plugin.py +1 -1
  130. bec_widgets/widgets/utility/visual/__init__.py +0 -0
  131. bec_widgets/widgets/utility/visual/color_button/__init__.py +0 -0
  132. bec_widgets/widgets/{color_button → utility/visual/color_button}/color_button.py +1 -0
  133. bec_widgets/widgets/{color_button → utility/visual/color_button}/color_button_plugin.py +1 -1
  134. bec_widgets/widgets/{color_button → utility/visual/color_button}/register_color_button.py +3 -1
  135. bec_widgets/widgets/utility/visual/colormap_selector/__init__.py +0 -0
  136. bec_widgets/widgets/{colormap_selector → utility/visual/colormap_selector}/colormap_selector.py +1 -0
  137. bec_widgets/widgets/{colormap_selector → utility/visual/colormap_selector}/colormap_selector_plugin.py +1 -1
  138. bec_widgets/widgets/{colormap_selector → utility/visual/colormap_selector}/register_colormap_selector.py +1 -1
  139. bec_widgets/widgets/utility/visual/colormap_widget/__init__.py +0 -0
  140. bec_widgets/widgets/{colormap_widget → utility/visual/colormap_widget}/bec_color_map_widget_plugin.py +1 -1
  141. bec_widgets/widgets/{colormap_widget → utility/visual/colormap_widget}/colormap_widget.py +1 -0
  142. bec_widgets/widgets/{colormap_widget → utility/visual/colormap_widget}/register_bec_color_map_widget.py +1 -1
  143. bec_widgets/widgets/utility/visual/dark_mode_button/__init__.py +0 -0
  144. bec_widgets/widgets/{dark_mode_button → utility/visual/dark_mode_button}/dark_mode_button.py +1 -0
  145. bec_widgets/widgets/{dark_mode_button → utility/visual/dark_mode_button}/dark_mode_button_plugin.py +1 -1
  146. bec_widgets/widgets/{dark_mode_button → utility/visual/dark_mode_button}/register_dark_mode_button.py +3 -1
  147. {bec_widgets-1.4.1.dist-info → bec_widgets-1.5.1.dist-info}/METADATA +1 -1
  148. bec_widgets-1.5.1.dist-info/RECORD +318 -0
  149. {bec_widgets-1.4.1.dist-info → bec_widgets-1.5.1.dist-info}/WHEEL +1 -1
  150. pyproject.toml +1 -1
  151. bec_widgets-1.4.1.dist-info/RECORD +0 -297
  152. /bec_widgets/widgets/{base_classes → containers}/__init__.py +0 -0
  153. /bec_widgets/widgets/{dock → containers/dock}/__init__.py +0 -0
  154. /bec_widgets/widgets/{dock → containers/dock}/dock.py +0 -0
  155. /bec_widgets/widgets/{dock → containers/dock}/dock_area.pyproject +0 -0
  156. /bec_widgets/widgets/{figure → containers/figure}/__init__.py +0 -0
  157. /bec_widgets/widgets/{bec_progressbar → containers/figure/plots}/__init__.py +0 -0
  158. /bec_widgets/widgets/{figure → containers/figure}/plots/axis_settings.py +0 -0
  159. /bec_widgets/widgets/{figure → containers/figure}/plots/axis_settings.ui +0 -0
  160. /bec_widgets/widgets/{bec_queue → containers/figure/plots/image}/__init__.py +0 -0
  161. /bec_widgets/widgets/{figure → containers/figure}/plots/image/image_processor.py +0 -0
  162. /bec_widgets/widgets/{bec_status_box → containers/figure/plots/motor_map}/__init__.py +0 -0
  163. /bec_widgets/widgets/{button_abort → containers/figure/plots/multi_waveform}/__init__.py +0 -0
  164. /bec_widgets/widgets/{figure → containers/figure}/plots/plot_base.py +0 -0
  165. /bec_widgets/widgets/{button_reset → containers/figure/plots/waveform}/__init__.py +0 -0
  166. /bec_widgets/widgets/{button_resume → control}/__init__.py +0 -0
  167. /bec_widgets/widgets/{color_button → control/buttons}/__init__.py +0 -0
  168. /bec_widgets/widgets/{colormap_selector → control/buttons/button_abort}/__init__.py +0 -0
  169. /bec_widgets/widgets/{button_abort → control/buttons/button_abort}/abort_button.pyproject +0 -0
  170. /bec_widgets/widgets/{colormap_widget → control/buttons/button_reset}/__init__.py +0 -0
  171. /bec_widgets/widgets/{button_reset → control/buttons/button_reset}/reset_button.pyproject +0 -0
  172. /bec_widgets/widgets/{dap_combo_box → control/buttons/button_resume}/__init__.py +0 -0
  173. /bec_widgets/widgets/{button_resume → control/buttons/button_resume}/resume_button.pyproject +0 -0
  174. /bec_widgets/widgets/{dark_mode_button → control/buttons/stop_button}/__init__.py +0 -0
  175. /bec_widgets/widgets/{stop_button → control/buttons/stop_button}/stop_button.pyproject +0 -0
  176. /bec_widgets/widgets/{device_browser → control/device_control}/__init__.py +0 -0
  177. /bec_widgets/widgets/{device_combobox → control/device_control/position_indicator}/__init__.py +0 -0
  178. /bec_widgets/widgets/{position_indicator → control/device_control/position_indicator}/position_indicator.pyproject +0 -0
  179. /bec_widgets/widgets/{device_line_edit → control/device_control/positioner_box}/__init__.py +0 -0
  180. /bec_widgets/widgets/{positioner_box → control/device_control/positioner_box}/positioner_box.pyproject +0 -0
  181. /bec_widgets/widgets/{positioner_box → control/device_control/positioner_box}/positioner_box.ui +0 -0
  182. /bec_widgets/widgets/{positioner_box → control/device_control/positioner_box}/positioner_control_line.pyproject +0 -0
  183. /bec_widgets/widgets/{positioner_box → control/device_control/positioner_box}/positioner_control_line.ui +0 -0
  184. /bec_widgets/widgets/{figure/plots → control/device_control/positioner_group}/__init__.py +0 -0
  185. /bec_widgets/widgets/{positioner_group → control/device_control/positioner_group}/positioner_group.pyproject +0 -0
  186. /bec_widgets/widgets/{figure/plots/image → control/device_input}/__init__.py +0 -0
  187. /bec_widgets/widgets/{figure/plots/motor_map → control/device_input/base_classes}/__init__.py +0 -0
  188. /bec_widgets/widgets/{base_classes → control/device_input/base_classes}/device_input_base.py +0 -0
  189. /bec_widgets/widgets/{base_classes → control/device_input/base_classes}/device_signal_input_base.py +0 -0
  190. /bec_widgets/widgets/{figure/plots/waveform → control/device_input/device_combobox}/__init__.py +0 -0
  191. /bec_widgets/widgets/{device_combobox → control/device_input/device_combobox}/device_combo_box.pyproject +0 -0
  192. /bec_widgets/widgets/{image → control/device_input/device_line_edit}/__init__.py +0 -0
  193. /bec_widgets/widgets/{device_line_edit → control/device_input/device_line_edit}/device_line_edit.pyproject +0 -0
  194. /bec_widgets/widgets/{jupyter_console → control/device_input/signal_combobox}/__init__.py +0 -0
  195. /bec_widgets/widgets/{signal_combobox → control/device_input/signal_combobox}/signal_combobox.pyproject +0 -0
  196. /bec_widgets/widgets/{lmfit_dialog → control/device_input/signal_line_edit}/__init__.py +0 -0
  197. /bec_widgets/widgets/{signal_line_edit → control/device_input/signal_line_edit}/signal_line_edit.pyproject +0 -0
  198. /bec_widgets/widgets/{scan_control → control/scan_control}/__init__.py +0 -0
  199. /bec_widgets/widgets/{scan_control → control/scan_control}/scan_control.pyproject +0 -0
  200. /bec_widgets/widgets/{motor_map → dap}/__init__.py +0 -0
  201. /bec_widgets/widgets/{motor_map/motor_map_dialog → dap/dap_combo_box}/__init__.py +0 -0
  202. /bec_widgets/widgets/{dap_combo_box → dap/dap_combo_box}/dap_combo_box.pyproject +0 -0
  203. /bec_widgets/widgets/{position_indicator → dap/lmfit_dialog}/__init__.py +0 -0
  204. /bec_widgets/widgets/{lmfit_dialog → dap/lmfit_dialog}/lm_fit_dialog.pyproject +0 -0
  205. /bec_widgets/widgets/{lmfit_dialog → dap/lmfit_dialog}/lmfit_dialog_compact.ui +0 -0
  206. /bec_widgets/widgets/{lmfit_dialog → dap/lmfit_dialog}/lmfit_dialog_vertical.ui +0 -0
  207. /bec_widgets/widgets/{positioner_box → editors}/__init__.py +0 -0
  208. /bec_widgets/widgets/{positioner_group → editors/console}/__init__.py +0 -0
  209. /bec_widgets/widgets/{console → editors/console}/console.pyproject +0 -0
  210. /bec_widgets/widgets/{signal_combobox → editors/jupyter_console}/__init__.py +0 -0
  211. /bec_widgets/widgets/{jupyter_console → editors/jupyter_console}/jupyter_console.py +0 -0
  212. /bec_widgets/widgets/{signal_line_edit → editors/text_box}/__init__.py +0 -0
  213. /bec_widgets/widgets/{text_box → editors/text_box}/text_box.pyproject +0 -0
  214. /bec_widgets/widgets/{spinner → editors/vscode}/__init__.py +0 -0
  215. /bec_widgets/widgets/{vscode → editors/vscode}/vs_code_editor.pyproject +0 -0
  216. /bec_widgets/widgets/{stop_button → editors/website}/__init__.py +0 -0
  217. /bec_widgets/widgets/{website → editors/website}/website_widget.pyproject +0 -0
  218. /bec_widgets/widgets/{text_box → plots}/__init__.py +0 -0
  219. /bec_widgets/widgets/{toggle → plots/image}/__init__.py +0 -0
  220. /bec_widgets/widgets/{image → plots/image}/bec_image_widget.pyproject +0 -0
  221. /bec_widgets/widgets/{vscode → plots/motor_map}/__init__.py +0 -0
  222. /bec_widgets/widgets/{motor_map → plots/motor_map}/bec_motor_map_widget.pyproject +0 -0
  223. /bec_widgets/widgets/{waveform → plots/motor_map/motor_map_dialog}/__init__.py +0 -0
  224. /bec_widgets/widgets/{motor_map → plots/motor_map}/motor_map_dialog/motor_map_settings.py +0 -0
  225. /bec_widgets/widgets/{motor_map → plots/motor_map}/motor_map_dialog/motor_map_settings.ui +0 -0
  226. /bec_widgets/widgets/{waveform/waveform_popups → plots/multi_waveform}/__init__.py +0 -0
  227. /bec_widgets/widgets/{waveform/waveform_popups/curve_dialog → plots/waveform}/__init__.py +0 -0
  228. /bec_widgets/widgets/{waveform → plots/waveform}/bec_waveform_widget.pyproject +0 -0
  229. /bec_widgets/widgets/{waveform/waveform_popups/dap_summary_dialog → plots/waveform/waveform_popups}/__init__.py +0 -0
  230. /bec_widgets/widgets/{website → plots/waveform/waveform_popups/curve_dialog}/__init__.py +0 -0
  231. /bec_widgets/widgets/{waveform → plots/waveform}/waveform_popups/curve_dialog/curve_dialog.ui +0 -0
  232. /bec_widgets/widgets/{bec_progressbar → progress/bec_progressbar}/bec_progress_bar.pyproject +0 -0
  233. /bec_widgets/widgets/{ring_progress_bar → progress/ring_progress_bar}/__init__.py +0 -0
  234. /bec_widgets/widgets/{ring_progress_bar → progress/ring_progress_bar}/ring.py +0 -0
  235. /bec_widgets/widgets/{ring_progress_bar → progress/ring_progress_bar}/ring_progress_bar.pyproject +0 -0
  236. /bec_widgets/widgets/{bec_queue → services/bec_queue}/bec_queue.pyproject +0 -0
  237. /bec_widgets/widgets/{bec_status_box → services/bec_status_box}/bec_status_box.pyproject +0 -0
  238. /bec_widgets/widgets/{bec_status_box → services/bec_status_box}/status_item.py +0 -0
  239. /bec_widgets/widgets/{device_browser → services/device_browser}/device_browser.pyproject +0 -0
  240. /bec_widgets/widgets/{device_browser → services/device_browser}/device_browser.ui +0 -0
  241. /bec_widgets/widgets/{device_browser → services/device_browser}/device_item/__init__.py +0 -0
  242. /bec_widgets/widgets/{device_browser → services/device_browser}/device_item/device_item.py +0 -0
  243. /bec_widgets/widgets/{spinner → utility/spinner}/spinner_widget.pyproject +0 -0
  244. /bec_widgets/widgets/{toggle → utility/toggle}/toggle_switch.pyproject +0 -0
  245. /bec_widgets/widgets/{color_button → utility/visual/color_button}/color_button.pyproject +0 -0
  246. /bec_widgets/widgets/{colormap_selector → utility/visual/colormap_selector}/colormap_selector.pyproject +0 -0
  247. /bec_widgets/widgets/{colormap_widget → utility/visual/colormap_widget}/bec_color_map_widget.pyproject +0 -0
  248. /bec_widgets/widgets/{dark_mode_button → utility/visual/dark_mode_button}/dark_mode_button.pyproject +0 -0
  249. {bec_widgets-1.4.1.dist-info → bec_widgets-1.5.1.dist-info}/entry_points.txt +0 -0
  250. {bec_widgets-1.4.1.dist-info → bec_widgets-1.5.1.dist-info}/licenses/LICENSE +0 -0
@@ -3,8 +3,6 @@ import os
3
3
  import numpy as np
4
4
  import pyqtgraph as pg
5
5
  from bec_qthemes import material_icon
6
- from qtpy.QtCore import QSize
7
- from qtpy.QtGui import QIcon
8
6
  from qtpy.QtWidgets import (
9
7
  QApplication,
10
8
  QGroupBox,
@@ -17,9 +15,9 @@ from qtpy.QtWidgets import (
17
15
 
18
16
  from bec_widgets.utils import BECDispatcher
19
17
  from bec_widgets.utils.colors import apply_theme
20
- from bec_widgets.widgets.dock.dock_area import BECDockArea
21
- from bec_widgets.widgets.figure import BECFigure
22
- from bec_widgets.widgets.jupyter_console.jupyter_console import BECJupyterConsole
18
+ from bec_widgets.widgets.containers.dock import BECDockArea
19
+ from bec_widgets.widgets.containers.figure import BECFigure
20
+ from bec_widgets.widgets.editors.jupyter_console.jupyter_console import BECJupyterConsole
23
21
 
24
22
 
25
23
  class JupyterConsoleWindow(QWidget): # pragma: no cover:
@@ -56,6 +54,7 @@ class JupyterConsoleWindow(QWidget): # pragma: no cover:
56
54
  # "cm": self.colormap,
57
55
  "im": self.im,
58
56
  "mm": self.mm,
57
+ "mw": self.mw,
59
58
  }
60
59
  )
61
60
 
@@ -167,9 +166,11 @@ class JupyterConsoleWindow(QWidget): # pragma: no cover:
167
166
  self.im.image("waveform", "1d")
168
167
 
169
168
  self.d2 = self.dock.add_dock(name="dock_2", position="bottom")
170
- self.wf = self.d2.add_widget("BECWaveformWidget", row=0, col=0)
171
- self.wf.plot(x_name="samx", y_name="bpm3a")
172
- self.wf.plot(x_name="samx", y_name="bpm4i", dap="GaussianModel")
169
+ self.wf = self.d2.add_widget("BECFigure", row=0, col=0)
170
+
171
+ self.mw = self.wf.multi_waveform(monitor="waveform") # , config=config)
172
+ # self.wf.plot(x_name="samx", y_name="bpm3a")
173
+ # self.wf.plot(x_name="samx", y_name="bpm4i", dap="GaussianModel")
173
174
  # self.bar = self.d2.add_widget("RingProgressBar", row=0, col=1)
174
175
  # self.bar.set_diameter(200)
175
176
 
@@ -210,6 +211,7 @@ if __name__ == "__main__": # pragma: no cover
210
211
 
211
212
  win = JupyterConsoleWindow()
212
213
  win.show()
214
+ win.resize(1200, 800)
213
215
 
214
216
  app.aboutToQuit.connect(win.close)
215
217
  sys.exit(app.exec_())
@@ -13,7 +13,7 @@ from qtpy.QtWidgets import (
13
13
 
14
14
  from bec_widgets.utils.bec_widget import BECWidget
15
15
  from bec_widgets.utils.colors import get_accent_colors, get_theme_palette
16
- from bec_widgets.widgets.dark_mode_button.dark_mode_button import DarkModeButton
16
+ from bec_widgets.widgets.utility.visual.dark_mode_button.dark_mode_button import DarkModeButton
17
17
 
18
18
 
19
19
  class PaletteViewer(BECWidget, QWidget):
@@ -6,13 +6,16 @@ from qtpy.QtCore import QObject, Qt, Signal, Slot
6
6
  from qtpy.QtWidgets import QApplication
7
7
 
8
8
 
9
- class NonDownsamplingScatterPlotItem(pg.ScatterPlotItem):
9
+ class CrosshairScatterItem(pg.ScatterPlotItem):
10
10
  def setDownsampling(self, ds=None, auto=None, method=None):
11
11
  pass
12
12
 
13
13
  def setClipToView(self, state):
14
14
  pass
15
15
 
16
+ def setAlpha(self, *args, **kwargs):
17
+ pass
18
+
16
19
 
17
20
  class Crosshair(QObject):
18
21
  # QT Position of mouse cursor
@@ -47,9 +50,15 @@ class Crosshair(QObject):
47
50
  self.v_line.skip_auto_range = True
48
51
  self.h_line = pg.InfiniteLine(angle=0, movable=False)
49
52
  self.h_line.skip_auto_range = True
53
+ # Add custom attribute to identify crosshair lines
54
+ self.v_line.is_crosshair = True
55
+ self.h_line.is_crosshair = True
50
56
  self.plot_item.addItem(self.v_line, ignoreBounds=True)
51
57
  self.plot_item.addItem(self.h_line, ignoreBounds=True)
52
58
 
59
+ # Initialize highlighted curve in a case of multiple curves
60
+ self.highlighted_curve_index = None
61
+
53
62
  # Add TextItem to display coordinates
54
63
  self.coord_label = pg.TextItem("", anchor=(1, 1), fill=(0, 0, 0, 100))
55
64
  self.coord_label.setVisible(False) # Hide initially
@@ -70,6 +79,7 @@ class Crosshair(QObject):
70
79
  self.plot_item.ctrl.downsampleSpin.valueChanged.connect(self.clear_markers)
71
80
 
72
81
  # Initialize markers
82
+ self.items = []
73
83
  self.marker_moved_1d = {}
74
84
  self.marker_clicked_1d = {}
75
85
  self.marker_2d = None
@@ -113,34 +123,74 @@ class Crosshair(QObject):
113
123
  self.coord_label.fill = pg.mkBrush(label_bg_color)
114
124
  self.coord_label.border = pg.mkPen(None)
115
125
 
126
+ @Slot(int)
127
+ def update_highlighted_curve(self, curve_index: int):
128
+ """
129
+ Update the highlighted curve in the case of multiple curves in a plot item.
130
+
131
+ Args:
132
+ curve_index(int): The index of curve to highlight
133
+ """
134
+ self.highlighted_curve_index = curve_index
135
+ self.clear_markers()
136
+ self.update_markers()
137
+
116
138
  def update_markers(self):
117
139
  """Update the markers for the crosshair, creating new ones if necessary."""
118
140
 
119
- # Create new markers
120
- for item in self.plot_item.items:
141
+ if self.highlighted_curve_index is not None and hasattr(self.plot_item, "visible_curves"):
142
+ # Focus on the highlighted curve only
143
+ self.items = [self.plot_item.visible_curves[self.highlighted_curve_index]]
144
+ else:
145
+ # Handle all curves
146
+ self.items = self.plot_item.items
147
+
148
+ # Create or update markers
149
+ for item in self.items:
121
150
  if isinstance(item, pg.PlotDataItem): # 1D plot
122
- if item.name() in self.marker_moved_1d:
123
- continue
124
151
  pen = item.opts["pen"]
125
152
  color = pen.color() if hasattr(pen, "color") else pg.mkColor(pen)
126
- marker_moved = NonDownsamplingScatterPlotItem(
127
- size=10, pen=pg.mkPen(color), brush=pg.mkBrush(None)
128
- )
129
- marker_moved.skip_auto_range = True
130
- self.marker_moved_1d[item.name()] = marker_moved
131
- self.plot_item.addItem(marker_moved)
132
-
133
- # Create glowing effect markers for clicked events
134
- for size, alpha in [(18, 64), (14, 128), (10, 255)]:
135
- marker_clicked = NonDownsamplingScatterPlotItem(
136
- size=size,
137
- pen=pg.mkPen(None),
138
- brush=pg.mkBrush(color.red(), color.green(), color.blue(), alpha),
153
+ name = item.name() or str(id(item))
154
+ if name in self.marker_moved_1d:
155
+ # Update existing markers
156
+ marker_moved = self.marker_moved_1d[name]
157
+ marker_moved.setPen(pg.mkPen(color))
158
+ # Update clicked markers' brushes
159
+ for marker_clicked in self.marker_clicked_1d[name]:
160
+ alpha = marker_clicked.opts["brush"].color().alpha()
161
+ marker_clicked.setBrush(
162
+ pg.mkBrush(color.red(), color.green(), color.blue(), alpha)
163
+ )
164
+ # Update z-values
165
+ marker_moved.setZValue(item.zValue() + 1)
166
+ for marker_clicked in self.marker_clicked_1d[name]:
167
+ marker_clicked.setZValue(item.zValue() + 1)
168
+ else:
169
+ # Create new markers
170
+ marker_moved = CrosshairScatterItem(
171
+ size=10, pen=pg.mkPen(color), brush=pg.mkBrush(None)
139
172
  )
140
- marker_clicked.skip_auto_range = True
141
- self.marker_clicked_1d[item.name()] = marker_clicked
142
- self.plot_item.addItem(marker_clicked)
143
-
173
+ marker_moved.skip_auto_range = True
174
+ marker_moved.is_crosshair = True
175
+ self.marker_moved_1d[name] = marker_moved
176
+ self.plot_item.addItem(marker_moved)
177
+ # Set marker z-value higher than the curve
178
+ marker_moved.setZValue(item.zValue() + 1)
179
+
180
+ # Create glowing effect markers for clicked events
181
+ marker_clicked_list = []
182
+ for size, alpha in [(18, 64), (14, 128), (10, 255)]:
183
+ marker_clicked = CrosshairScatterItem(
184
+ size=size,
185
+ pen=pg.mkPen(None),
186
+ brush=pg.mkBrush(color.red(), color.green(), color.blue(), alpha),
187
+ )
188
+ marker_clicked.skip_auto_range = True
189
+ marker_clicked.is_crosshair = True
190
+ self.plot_item.addItem(marker_clicked)
191
+ marker_clicked.setZValue(item.zValue() + 1)
192
+ marker_clicked_list.append(marker_clicked)
193
+ self.marker_clicked_1d[name] = marker_clicked_list
144
194
  elif isinstance(item, pg.ImageItem): # 2D plot
145
195
  if self.marker_2d is not None:
146
196
  continue
@@ -162,12 +212,11 @@ class Crosshair(QObject):
162
212
  """
163
213
  y_values = defaultdict(list)
164
214
  x_values = defaultdict(list)
165
- image_2d = None
166
215
 
167
216
  # Iterate through items in the plot
168
- for item in self.plot_item.items:
217
+ for item in self.items:
169
218
  if isinstance(item, pg.PlotDataItem): # 1D plot
170
- name = item.name()
219
+ name = item.name() or str(id(item))
171
220
  plot_data = item._getDisplayDataset()
172
221
  if plot_data is None:
173
222
  continue
@@ -188,7 +237,7 @@ class Crosshair(QObject):
188
237
  elif isinstance(item, pg.ImageItem): # 2D plot
189
238
  name = item.config.monitor
190
239
  image_2d = item.image
191
- # clip the x and y values to the image dimensions to avoid out of bounds errors
240
+ # Clip the x and y values to the image dimensions to avoid out of bounds errors
192
241
  y_values[name] = int(np.clip(y, 0, image_2d.shape[1] - 1))
193
242
  x_values[name] = int(np.clip(x, 0, image_2d.shape[0] - 1))
194
243
 
@@ -256,9 +305,9 @@ class Crosshair(QObject):
256
305
  # not sure how we got here, but just to be safe...
257
306
  return
258
307
 
259
- for item in self.plot_item.items:
308
+ for item in self.items:
260
309
  if isinstance(item, pg.PlotDataItem):
261
- name = item.name()
310
+ name = item.name() or str(id(item))
262
311
  x, y = x_snap_values[name], y_snap_values[name]
263
312
  if x is None or y is None:
264
313
  continue
@@ -309,13 +358,14 @@ class Crosshair(QObject):
309
358
  # not sure how we got here, but just to be safe...
310
359
  return
311
360
 
312
- for item in self.plot_item.items:
361
+ for item in self.items:
313
362
  if isinstance(item, pg.PlotDataItem):
314
- name = item.name()
363
+ name = item.name() or str(id(item))
315
364
  x, y = x_snap_values[name], y_snap_values[name]
316
365
  if x is None or y is None:
317
366
  continue
318
- self.marker_clicked_1d[name].setData([x], [y])
367
+ for marker_clicked in self.marker_clicked_1d[name]:
368
+ marker_clicked.setData([x], [y])
319
369
  x_snapped_scaled, y_snapped_scaled = self.scale_emitted_coordinates(x, y)
320
370
  coordinate_to_emit = (
321
371
  name,
@@ -337,9 +387,12 @@ class Crosshair(QObject):
337
387
  def clear_markers(self):
338
388
  """Clears the markers from the plot."""
339
389
  for marker in self.marker_moved_1d.values():
340
- marker.clear()
341
- for marker in self.marker_clicked_1d.values():
342
- marker.clear()
390
+ self.plot_item.removeItem(marker)
391
+ for markers in self.marker_clicked_1d.values():
392
+ for marker in markers:
393
+ self.plot_item.removeItem(marker)
394
+ self.marker_moved_1d.clear()
395
+ self.marker_clicked_1d.clear()
343
396
 
344
397
  def scale_emitted_coordinates(self, x, y):
345
398
  """Scales the emitted coordinates if the axes are in log scale.
@@ -366,7 +419,7 @@ class Crosshair(QObject):
366
419
  x, y = pos
367
420
  x_scaled, y_scaled = self.scale_emitted_coordinates(x, y)
368
421
 
369
- # # Update coordinate label
422
+ # Update coordinate label
370
423
  self.coord_label.setText(f"({x_scaled:.{self.precision}g}, {y_scaled:.{self.precision}g})")
371
424
  self.coord_label.setPos(x, y)
372
425
  self.coord_label.setVisible(True)
@@ -143,7 +143,7 @@ class DesignerPluginGenerator:
143
143
 
144
144
  if __name__ == "__main__": # pragma: no cover
145
145
  # from bec_widgets.widgets.bec_queue.bec_queue import BECQueue
146
- from bec_widgets.widgets.spinner.spinner import SpinnerWidget
146
+ from bec_widgets.widgets.utility.spinner import SpinnerWidget
147
147
 
148
148
  generator = DesignerPluginGenerator(SpinnerWidget)
149
149
  generator.run(validate=False)
@@ -53,7 +53,7 @@ class BECClassInfo:
53
53
  obj: type
54
54
  is_connector: bool = False
55
55
  is_widget: bool = False
56
- is_top_level: bool = False
56
+ is_plugin: bool = False
57
57
 
58
58
 
59
59
  class BECClassContainer:
@@ -88,14 +88,14 @@ class BECClassContainer:
88
88
  """
89
89
  Get all top-level classes.
90
90
  """
91
- return [info.obj for info in self.collection if info.is_top_level]
91
+ return [info.obj for info in self.collection if info.is_plugin]
92
92
 
93
93
  @property
94
94
  def plugins(self):
95
95
  """
96
96
  Get all plugins. These are all classes that are on the top level and are widgets.
97
97
  """
98
- return [info.obj for info in self.collection if info.is_widget and info.is_top_level]
98
+ return [info.obj for info in self.collection if info.is_widget and info.is_plugin]
99
99
 
100
100
  @property
101
101
  def widgets(self):
@@ -109,10 +109,17 @@ class BECClassContainer:
109
109
  """
110
110
  Get all top-level classes that are RPC-enabled. These are all classes that users can choose from.
111
111
  """
112
- return [info.obj for info in self.collection if info.is_top_level and info.is_connector]
112
+ return [info.obj for info in self.collection if info.is_plugin and info.is_connector]
113
+
114
+ @property
115
+ def classes(self):
116
+ """
117
+ Get all classes.
118
+ """
119
+ return [info.obj for info in self.collection]
113
120
 
114
121
 
115
- def get_rpc_classes(repo_name: str) -> BECClassContainer:
122
+ def get_custom_classes(repo_name: str) -> BECClassContainer:
116
123
  """
117
124
  Get all RPC-enabled classes in the specified repository.
118
125
 
@@ -153,6 +160,8 @@ def get_rpc_classes(repo_name: str) -> BECClassContainer:
153
160
  issubclass(obj, QWidget) or issubclass(obj, QGraphicsWidget)
154
161
  ):
155
162
  class_info.is_top_level = True
163
+ if hasattr(obj, "PLUGIN") and obj.PLUGIN:
164
+ class_info.is_plugin = True
156
165
  collection.add_class(class_info)
157
166
 
158
167
  return collection
@@ -4,7 +4,7 @@ from qtpy import PYQT6, PYSIDE6, QT_VERSION
4
4
  from qtpy.QtCore import QFile, QIODevice
5
5
 
6
6
  from bec_widgets.utils.generate_designer_plugin import DesignerPluginInfo
7
- from bec_widgets.utils.plugin_utils import get_rpc_classes
7
+ from bec_widgets.utils.plugin_utils import get_custom_classes
8
8
 
9
9
  if PYSIDE6:
10
10
  from PySide6.QtUiTools import QUiLoader
@@ -30,7 +30,7 @@ class UILoader:
30
30
  def __init__(self, parent=None):
31
31
  self.parent = parent
32
32
 
33
- widgets = get_rpc_classes("bec_widgets").top_level_classes
33
+ widgets = get_custom_classes("bec_widgets").classes
34
34
 
35
35
  self.custom_widgets = {widget.__name__: widget for widget in widgets}
36
36
 
@@ -18,17 +18,18 @@ from bec_widgets.qt_utils.toolbar import (
18
18
  )
19
19
  from bec_widgets.utils import ConnectionConfig, WidgetContainerUtils
20
20
  from bec_widgets.utils.bec_widget import BECWidget
21
- from bec_widgets.widgets.bec_queue.bec_queue import BECQueue
22
- from bec_widgets.widgets.bec_status_box.bec_status_box import BECStatusBox
23
- from bec_widgets.widgets.dark_mode_button.dark_mode_button import DarkModeButton
24
- from bec_widgets.widgets.dock.dock import BECDock, DockConfig
25
- from bec_widgets.widgets.image.image_widget import BECImageWidget
26
- from bec_widgets.widgets.motor_map.motor_map_widget import BECMotorMapWidget
27
- from bec_widgets.widgets.positioner_box.positioner_box import PositionerBox
28
- from bec_widgets.widgets.ring_progress_bar.ring_progress_bar import RingProgressBar
29
- from bec_widgets.widgets.scan_control.scan_control import ScanControl
30
- from bec_widgets.widgets.vscode.vscode import VSCodeEditor
31
- from bec_widgets.widgets.waveform.waveform_widget import BECWaveformWidget
21
+ from bec_widgets.widgets.containers.dock.dock import BECDock, DockConfig
22
+ from bec_widgets.widgets.control.device_control.positioner_box.positioner_box import PositionerBox
23
+ from bec_widgets.widgets.control.scan_control.scan_control import ScanControl
24
+ from bec_widgets.widgets.editors.vscode.vscode import VSCodeEditor
25
+ from bec_widgets.widgets.plots.image.image_widget import BECImageWidget
26
+ from bec_widgets.widgets.plots.motor_map.motor_map_widget import BECMotorMapWidget
27
+ from bec_widgets.widgets.plots.multi_waveform.multi_waveform_widget import BECMultiWaveformWidget
28
+ from bec_widgets.widgets.plots.waveform.waveform_widget import BECWaveformWidget
29
+ from bec_widgets.widgets.progress.ring_progress_bar.ring_progress_bar import RingProgressBar
30
+ from bec_widgets.widgets.services.bec_queue.bec_queue import BECQueue
31
+ from bec_widgets.widgets.services.bec_status_box.bec_status_box import BECStatusBox
32
+ from bec_widgets.widgets.utility.visual.dark_mode_button.dark_mode_button import DarkModeButton
32
33
 
33
34
 
34
35
  class DockAreaConfig(ConnectionConfig):
@@ -39,6 +40,7 @@ class DockAreaConfig(ConnectionConfig):
39
40
 
40
41
 
41
42
  class BECDockArea(BECWidget, QWidget):
43
+ PLUGIN = True
42
44
  USER_ACCESS = [
43
45
  "_config_dict",
44
46
  "panels",
@@ -85,6 +87,11 @@ class BECDockArea(BECWidget, QWidget):
85
87
  tooltip="Add Waveform",
86
88
  filled=True,
87
89
  ),
90
+ "multi_waveform": MaterialIconAction(
91
+ icon_name=BECMultiWaveformWidget.ICON_NAME,
92
+ tooltip="Add Multi Waveform",
93
+ filled=True,
94
+ ),
88
95
  "image": MaterialIconAction(
89
96
  icon_name=BECImageWidget.ICON_NAME, tooltip="Add Image", filled=True
90
97
  ),
@@ -154,6 +161,9 @@ class BECDockArea(BECWidget, QWidget):
154
161
  self.toolbar.widgets["menu_plots"].widgets["waveform"].triggered.connect(
155
162
  lambda: self.add_dock(widget="BECWaveformWidget", prefix="waveform")
156
163
  )
164
+ self.toolbar.widgets["menu_plots"].widgets["multi_waveform"].triggered.connect(
165
+ lambda: self.add_dock(widget="BECMultiWaveformWidget", prefix="multi_waveform")
166
+ )
157
167
  self.toolbar.widgets["menu_plots"].widgets["image"].triggered.connect(
158
168
  lambda: self.add_dock(widget="BECImageWidget", prefix="image")
159
169
  )
@@ -6,7 +6,7 @@ from qtpy.QtDesigner import QDesignerCustomWidgetInterface
6
6
 
7
7
  import bec_widgets
8
8
  from bec_widgets.utils.bec_designer import designer_material_icon
9
- from bec_widgets.widgets.dock import BECDockArea
9
+ from bec_widgets.widgets.containers.dock import BECDockArea
10
10
 
11
11
  DOM_XML = """
12
12
  <ui language='c++'>
@@ -6,7 +6,7 @@ def main(): # pragma: no cover
6
6
  return
7
7
  from PySide6.QtDesigner import QPyDesignerCustomWidgetCollection
8
8
 
9
- from bec_widgets.widgets.dock.dock_area_plugin import BECDockAreaPlugin
9
+ from bec_widgets.widgets.containers.dock.dock_area_plugin import BECDockAreaPlugin
10
10
 
11
11
  QPyDesignerCustomWidgetCollection.addCustomWidget(BECDockAreaPlugin())
12
12
 
@@ -16,10 +16,20 @@ from typeguard import typechecked
16
16
  from bec_widgets.utils import ConnectionConfig, WidgetContainerUtils
17
17
  from bec_widgets.utils.bec_widget import BECWidget
18
18
  from bec_widgets.utils.colors import apply_theme
19
- from bec_widgets.widgets.figure.plots.image.image import BECImageShow, ImageConfig
20
- from bec_widgets.widgets.figure.plots.motor_map.motor_map import BECMotorMap, MotorMapConfig
21
- from bec_widgets.widgets.figure.plots.plot_base import BECPlotBase, SubplotConfig
22
- from bec_widgets.widgets.figure.plots.waveform.waveform import BECWaveform, Waveform1DConfig
19
+ from bec_widgets.widgets.containers.figure.plots.image.image import BECImageShow, ImageConfig
20
+ from bec_widgets.widgets.containers.figure.plots.motor_map.motor_map import (
21
+ BECMotorMap,
22
+ MotorMapConfig,
23
+ )
24
+ from bec_widgets.widgets.containers.figure.plots.multi_waveform.multi_waveform import (
25
+ BECMultiWaveform,
26
+ BECMultiWaveformConfig,
27
+ )
28
+ from bec_widgets.widgets.containers.figure.plots.plot_base import BECPlotBase, SubplotConfig
29
+ from bec_widgets.widgets.containers.figure.plots.waveform.waveform import (
30
+ BECWaveform,
31
+ Waveform1DConfig,
32
+ )
23
33
 
24
34
  logger = bec_logger.logger
25
35
 
@@ -64,6 +74,7 @@ class WidgetHandler:
64
74
  "BECWaveform": (BECWaveform, Waveform1DConfig),
65
75
  "BECImageShow": (BECImageShow, ImageConfig),
66
76
  "BECMotorMap": (BECMotorMap, MotorMapConfig),
77
+ "BECMultiWaveform": (BECMultiWaveform, BECMultiWaveformConfig),
67
78
  }
68
79
 
69
80
  def create_widget(
@@ -134,8 +145,14 @@ class BECFigure(BECWidget, pg.GraphicsLayoutWidget):
134
145
  "BECWaveform": BECWaveform,
135
146
  "BECImageShow": BECImageShow,
136
147
  "BECMotorMap": BECMotorMap,
148
+ "BECMultiWaveform": BECMultiWaveform,
149
+ }
150
+ widget_method_map = {
151
+ "BECWaveform": "plot",
152
+ "BECImageShow": "image",
153
+ "BECMotorMap": "motor_map",
154
+ "BECMultiWaveform": "multi_waveform",
137
155
  }
138
- widget_method_map = {"BECWaveform": "plot", "BECImageShow": "image", "BECMotorMap": "motor_map"}
139
156
 
140
157
  clean_signal = pyqtSignal()
141
158
 
@@ -445,10 +462,27 @@ class BECFigure(BECWidget, pg.GraphicsLayoutWidget):
445
462
 
446
463
  return motor_map
447
464
 
465
+ def multi_waveform(
466
+ self,
467
+ monitor: str = None,
468
+ new: bool = False,
469
+ row: int | None = None,
470
+ col: int | None = None,
471
+ config: dict | None = None,
472
+ **axis_kwargs,
473
+ ):
474
+ multi_waveform = self.subplot_factory(
475
+ widget_type="BECMultiWaveform", config=config, row=row, col=col, new=new, **axis_kwargs
476
+ )
477
+ if config is not None:
478
+ return multi_waveform
479
+ multi_waveform.set_monitor(monitor)
480
+ return multi_waveform
481
+
448
482
  def subplot_factory(
449
483
  self,
450
484
  widget_type: Literal[
451
- "BECPlotBase", "BECWaveform", "BECImageShow", "BECMotorMap"
485
+ "BECPlotBase", "BECWaveform", "BECImageShow", "BECMotorMap", "BECMultiWaveform"
452
486
  ] = "BECPlotBase",
453
487
  row: int = None,
454
488
  col: int = None,
@@ -500,7 +534,7 @@ class BECFigure(BECWidget, pg.GraphicsLayoutWidget):
500
534
  def add_widget(
501
535
  self,
502
536
  widget_type: Literal[
503
- "BECPlotBase", "BECWaveform", "BECImageShow", "BECMotorMap"
537
+ "BECPlotBase", "BECWaveform", "BECImageShow", "BECMotorMap", "BECMultiWaveform"
504
538
  ] = "BECPlotBase",
505
539
  widget_id: str = None,
506
540
  row: int = None,
@@ -6,19 +6,22 @@ from typing import Any, Literal, Optional
6
6
  import numpy as np
7
7
  from bec_lib.endpoints import MessageEndpoints
8
8
  from bec_lib.logger import bec_logger
9
- from pydantic import BaseModel, Field, ValidationError
9
+ from pydantic import Field, ValidationError
10
10
  from qtpy.QtCore import QThread, Slot
11
11
  from qtpy.QtWidgets import QWidget
12
12
 
13
13
  # from bec_widgets.qt_utils.error_popups import SafeSlot as Slot
14
14
  from bec_widgets.utils import EntryValidator
15
- from bec_widgets.widgets.figure.plots.image.image_item import BECImageItem, ImageItemConfig
16
- from bec_widgets.widgets.figure.plots.image.image_processor import (
15
+ from bec_widgets.widgets.containers.figure.plots.image.image_item import (
16
+ BECImageItem,
17
+ ImageItemConfig,
18
+ )
19
+ from bec_widgets.widgets.containers.figure.plots.image.image_processor import (
17
20
  ImageProcessor,
18
21
  ImageStats,
19
22
  ProcessorWorker,
20
23
  )
21
- from bec_widgets.widgets.figure.plots.plot_base import BECPlotBase, SubplotConfig
24
+ from bec_widgets.widgets.containers.figure.plots.plot_base import BECPlotBase, SubplotConfig
22
25
 
23
26
  logger = bec_logger.logger
24
27
 
@@ -8,10 +8,13 @@ from bec_lib.logger import bec_logger
8
8
  from pydantic import Field
9
9
 
10
10
  from bec_widgets.utils import BECConnector, ConnectionConfig
11
- from bec_widgets.widgets.figure.plots.image.image_processor import ImageStats, ProcessingConfig
11
+ from bec_widgets.widgets.containers.figure.plots.image.image_processor import (
12
+ ImageStats,
13
+ ProcessingConfig,
14
+ )
12
15
 
13
16
  if TYPE_CHECKING:
14
- from bec_widgets.widgets.figure.plots.image.image import BECImageShow
17
+ from bec_widgets.widgets.containers.figure.plots.image.image import BECImageShow
15
18
 
16
19
  logger = bec_logger.logger
17
20
 
@@ -15,8 +15,8 @@ from qtpy.QtWidgets import QWidget
15
15
 
16
16
  from bec_widgets.qt_utils.error_popups import SafeSlot as Slot
17
17
  from bec_widgets.utils import Colors, EntryValidator
18
- from bec_widgets.widgets.figure.plots.plot_base import BECPlotBase, SubplotConfig
19
- from bec_widgets.widgets.figure.plots.waveform.waveform import Signal, SignalData
18
+ from bec_widgets.widgets.containers.figure.plots.plot_base import BECPlotBase, SubplotConfig
19
+ from bec_widgets.widgets.containers.figure.plots.waveform.waveform import Signal, SignalData
20
20
 
21
21
  logger = bec_logger.logger
22
22