techui-builder 0.6.7a1__tar.gz → 0.6.8a2__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 (178) hide show
  1. {techui_builder-0.6.7a1/src/techui_builder.egg-info → techui_builder-0.6.8a2}/PKG-INFO +1 -1
  2. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/src/techui_builder/_version.py +3 -3
  3. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/src/techui_builder/builder.py +129 -29
  4. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2/src/techui_builder.egg-info}/PKG-INFO +1 -1
  5. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/src/techui_builder.egg-info/SOURCES.txt +1 -0
  6. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/tests/conftest.py +51 -4
  7. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/tests/test_builder.py +41 -1
  8. techui_builder-0.6.8a2/tests/test_files/test_bob_navtabs.bob +46 -0
  9. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/.copier-answers.yml +0 -0
  10. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/.devcontainer/devcontainer.json +0 -0
  11. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/.devcontainer/install_lazygit.sh +0 -0
  12. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/.github/CONTRIBUTING.md +0 -0
  13. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  14. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/.github/ISSUE_TEMPLATE/issue.md +0 -0
  15. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +0 -0
  16. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/.github/dependabot.yml +0 -0
  17. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/.github/pages/index.html +0 -0
  18. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/.github/pages/make_switcher.py +0 -0
  19. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/.github/workflows/_dist.yml +0 -0
  20. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/.github/workflows/_docs.yml +0 -0
  21. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/.github/workflows/_pypi.yml +0 -0
  22. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/.github/workflows/_release.yml +0 -0
  23. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/.github/workflows/_test.yml +0 -0
  24. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/.github/workflows/_tox.yml +0 -0
  25. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/.github/workflows/ci.yml +0 -0
  26. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/.github/workflows/periodic.yml +0 -0
  27. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/.gitignore +0 -0
  28. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/.gitleaks.toml +0 -0
  29. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/.pre-commit-config.yaml +0 -0
  30. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/.python-version +0 -0
  31. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/.vscode/extensions.json +0 -0
  32. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/.vscode/launch.json +0 -0
  33. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/.vscode/settings.json +0 -0
  34. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/.vscode/tasks.json +0 -0
  35. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/Dockerfile +0 -0
  36. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/LICENSE +0 -0
  37. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/README.md +0 -0
  38. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/catalog-info.yaml +0 -0
  39. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/docs/conf.py +0 -0
  40. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example/t01-services/services/bl01t-mo-ioc-01/config/ioc.yaml +0 -0
  41. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example/t01-services/synoptic/index.bob +0 -0
  42. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example/t01-services/synoptic/techui.yaml +0 -0
  43. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/config/devsta.db +0 -0
  44. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/services/bl23b-di-mod-01/config/ioc.yaml +0 -0
  45. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/services/bl23b-di-mod-02/config/ioc.yaml +0 -0
  46. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/services/bl23b-di-uvcam-01/config/ioc.yaml +0 -0
  47. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/services/bl23b-di-uvcam-02/config/ioc.yaml +0 -0
  48. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/services/bl23b-mo-ioc-01/config/ioc.yaml +0 -0
  49. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/services/bl23b-va-ioc-01/config/ioc.yaml +0 -0
  50. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/IMG1.bob +0 -0
  51. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/IMG11.bob +0 -0
  52. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/IMG12.bob +0 -0
  53. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/IONP1.bob +0 -0
  54. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/IONP11.bob +0 -0
  55. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/IONP12.bob +0 -0
  56. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/IONP21.bob +0 -0
  57. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/JsonMap.json +0 -0
  58. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/M3.bob +0 -0
  59. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/MOD1.bob +0 -0
  60. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/MOD2.bob +0 -0
  61. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/PIRG1.bob +0 -0
  62. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/PIRG11.bob +0 -0
  63. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/PIRG12.bob +0 -0
  64. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/SPACE11.bob +0 -0
  65. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/index.bob +0 -0
  66. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/LICENSE +0 -0
  67. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/bob/ADAravis/ADAravis_detail.bob +0 -0
  68. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/bob/ADAravis/ADAravis_summary.bob +0 -0
  69. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/bob/ADAravis/NDFileHDF5.pvi.bob +0 -0
  70. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/bob/ADAravis/NDPluginPva.pvi.bob +0 -0
  71. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/bob/ADAravis/NDPluginROI.pvi.bob +0 -0
  72. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/bob/ADAravis/NDPluginROIStat.pvi.bob +0 -0
  73. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/bob/ADAravis/NDPluginStats.pvi.bob +0 -0
  74. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/bob/ADAravis/ProfileCursorGraphs.bob +0 -0
  75. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/bob/colour.def +0 -0
  76. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/bob/digitelMpc/digitelMpcIonp.bob +0 -0
  77. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/bob/dls_class.bcf +0 -0
  78. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/bob/mks937a/mks937a.bob +0 -0
  79. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/bob/mks937a/mks937aGauge.bob +0 -0
  80. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/bob/mks937a/mks937aImg.bob +0 -0
  81. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/bob/mks937a/mks937aPirg.bob +0 -0
  82. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/bob/pmac/MOTOR.bob +0 -0
  83. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/bob/pmac/motor_embed.bob +0 -0
  84. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/bob/pmac/pmacController.bob +0 -0
  85. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/bob/pmac/ppmacController.bob +0 -0
  86. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/bob/rga/rga.bob +0 -0
  87. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/bob/settings.ini +0 -0
  88. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/bob/vacuumValve/vacuumValve.bob +0 -0
  89. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/bob/vacuumValve/vacuumValveInterlocks.bob +0 -0
  90. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/3DCM_diag_3.gif +0 -0
  91. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/Beamline_Image.png +0 -0
  92. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/Beamline_Image_Colour.png +0 -0
  93. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/Panda.jpg +0 -0
  94. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/WoodenArch.jpg +0 -0
  95. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/absorber 1 (copy).svg +0 -0
  96. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/absorber 1.svg +0 -0
  97. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/aperture.svg +0 -0
  98. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/camera +0 -0
  99. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/camera-1.svg +0 -0
  100. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/dcm.svg +0 -0
  101. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/diag-stick-camera.svg +0 -0
  102. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/diag-stick-camera_flipped.png +0 -0
  103. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/diag-stick.svg +0 -0
  104. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/fastValve 1 (copy).svg +0 -0
  105. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/fastValve 1.svg +0 -0
  106. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/floodgate.jpg +0 -0
  107. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/fm.png +0 -0
  108. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/fm.svg +0 -0
  109. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/fvg 0.svg +0 -0
  110. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/hfm.svg +0 -0
  111. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/img 0 (copy).svg +0 -0
  112. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/img 0.svg +0 -0
  113. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/ionp 4 (another copy).svg +0 -0
  114. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/ionp 4 (copy).svg +0 -0
  115. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/ionp 4.svg +0 -0
  116. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/manualValve 1 (copy).svg +0 -0
  117. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/manualValve 1.svg +0 -0
  118. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/motors +0 -0
  119. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/pirg 0 (copy).svg +0 -0
  120. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/pirg 0.svg +0 -0
  121. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/rga 0.svg +0 -0
  122. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/ring 0.svg +0 -0
  123. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/ring 1.png +0 -0
  124. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/ring 1.svg +0 -0
  125. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/shutter 1 (copy).svg +0 -0
  126. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/shutter 1.svg +0 -0
  127. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/shutter 2.svg +0 -0
  128. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/shutter 3.svg +0 -0
  129. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/slits.svg +0 -0
  130. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/space 0.svg +0 -0
  131. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/spacenew 0.svg +0 -0
  132. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/table.png +0 -0
  133. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/valve 1 (copy).svg +0 -0
  134. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/valve 1.svg +0 -0
  135. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/vfm-up.svg +0 -0
  136. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/webcam.png +0 -0
  137. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/symbols/webcam.svg +0 -0
  138. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui-support/techui-support.yaml +0 -0
  139. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/example-synoptic/b23-services/synoptic/techui.yaml +0 -0
  140. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/pyproject.toml +0 -0
  141. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/setup.cfg +0 -0
  142. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/src/techui_builder/__init__.py +0 -0
  143. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/src/techui_builder/__main__.py +0 -0
  144. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/src/techui_builder/_logger.py +0 -0
  145. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/src/techui_builder/autofill.py +0 -0
  146. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/src/techui_builder/generate.py +0 -0
  147. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/src/techui_builder/models.py +0 -0
  148. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/src/techui_builder/schema_generator.py +0 -0
  149. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/src/techui_builder/utils.py +0 -0
  150. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/src/techui_builder/validator.py +0 -0
  151. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/src/techui_builder.egg-info/dependency_links.txt +0 -0
  152. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/src/techui_builder.egg-info/entry_points.txt +0 -0
  153. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/src/techui_builder.egg-info/requires.txt +0 -0
  154. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/src/techui_builder.egg-info/top_level.txt +0 -0
  155. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/tests/__init__.py +0 -0
  156. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/tests/test_autofiller.py +0 -0
  157. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/tests/test_cli.py +0 -0
  158. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/tests/test_files/group.xml +0 -0
  159. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/tests/test_files/index.bob +0 -0
  160. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/tests/test_files/motor-edited.bob +0 -0
  161. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/tests/test_files/motor.bob +0 -0
  162. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/tests/test_files/motor_bad.bob +0 -0
  163. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/tests/test_files/motor_embed.bob +0 -0
  164. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/tests/test_files/test_bob.bob +0 -0
  165. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/tests/test_files/test_bob_bad.bob +0 -0
  166. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/tests/test_files/test_bob_embedded.bob +0 -0
  167. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/tests/test_files/widget.xml +0 -0
  168. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/tests/test_files/widget_bad.xml +0 -0
  169. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/tests/test_files/widget_bad_2.xml +0 -0
  170. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/tests/test_files/widget_related.xml +0 -0
  171. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/tests/test_files/widget_related_no_suffix.xml +0 -0
  172. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/tests/test_files/widget_url_screen.xml +0 -0
  173. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/tests/test_generate.py +0 -0
  174. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/tests/test_logger.py +0 -0
  175. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/tests/test_models.py +0 -0
  176. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/tests/test_utils.py +0 -0
  177. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/tests/test_validator.py +0 -0
  178. {techui_builder-0.6.7a1 → techui_builder-0.6.8a2}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: techui-builder
3
- Version: 0.6.7a1
3
+ Version: 0.6.8a2
4
4
  Summary: A package for building Phoebus GUIs
5
5
  Author-email: Oliver Copping <oliver.copping@diamond.ac.uk>, Adedamola Sode <adedamola.sode@diamond.ac.uk>, Niamh Dougan <niamh.dougan@diamond.ac.uk>
6
6
  Project-URL: GitHub, https://github.com/DiamondLightSource/techui-builder
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.6.7a1'
22
- __version_tuple__ = version_tuple = (0, 6, 7, 'a1')
21
+ __version__ = version = '0.6.8a2'
22
+ __version_tuple__ = version_tuple = (0, 6, 8, 'a2')
23
23
 
24
- __commit_id__ = commit_id = 'gc414caca5'
24
+ __commit_id__ = commit_id = 'gd10e2d23d'
@@ -266,6 +266,55 @@ class Builder:
266
266
  ) -> JsonMap:
267
267
  """Recursively generate JSON map from .bob file tree"""
268
268
 
269
+ # ------------ USEFUL FUNCTIONS ------------
270
+
271
+ def _get_display_name(
272
+ name_element: str | None, component_name: str | None, file_path: Path
273
+ ):
274
+ # Validated screen names don't get renegerated
275
+ name = name_element
276
+ display_name = self._get_component_label(
277
+ name_element,
278
+ component_name,
279
+ name,
280
+ )
281
+ # Create valid displayName
282
+ display_name = self._parse_display_name(display_name, file_path)
283
+ return display_name
284
+
285
+ def _next_file_crawl(
286
+ file_path_text: str,
287
+ destination_path: Path,
288
+ name_element: str | None,
289
+ component_name: str | None,
290
+ display_name: str | None,
291
+ macro_dictionary: dict[str, Any],
292
+ ):
293
+ # TODO: misleading var name?
294
+ next_file_path = destination_path.joinpath(file_path_text)
295
+
296
+ # Crawl the next file
297
+ if next_file_path.is_file():
298
+ # TODO: investigate non-recursive approaches?
299
+ child_node = self._generate_json_map(
300
+ next_file_path,
301
+ destination_path,
302
+ current_component_name=component_name,
303
+ name_elem=name_element,
304
+ )
305
+ else:
306
+ child_node = JsonMap(
307
+ file_path_text,
308
+ display_name,
309
+ exists=(
310
+ "IOC" in macro_dictionary or ("https://" in file_path_text)
311
+ ),
312
+ )
313
+
314
+ return child_node
315
+
316
+ # ------------------------------------------
317
+
269
318
  # Create initial node at top of .bob file
270
319
  current_node = JsonMap(
271
320
  str(screen_path.resolve().relative_to(self._write_directory.resolve())),
@@ -298,7 +347,7 @@ class Builder:
298
347
  for w in root.findall(".//widget")
299
348
  if w.get("type", default=None)
300
349
  # in ["symbol", "embedded", "action_button"]
301
- in ["symbol", "action_button", "embedded"]
350
+ in ["symbol", "action_button", "embedded", "navtabs"]
302
351
  ]
303
352
 
304
353
  for widget_elem in widgets:
@@ -322,16 +371,49 @@ class Builder:
322
371
  name_elem = widget_elem.name.text
323
372
  macro_dict = self._get_macros(widget_elem)
324
373
 
325
- case _:
374
+ case "navtabs":
375
+ tabs = _get_nav_tabs(widget_elem)
376
+ if tabs is None:
377
+ continue
378
+
379
+ for tab in tabs:
380
+ name_elem = tab.name.text
381
+ file_elem = tab.file
382
+ macro_dict = self._get_macros(tab)
383
+
384
+ # Extract file path from file_elem
385
+ # Keep raw string to preserve urls
386
+ file_text = file_elem.text.strip() if file_elem.text else ""
387
+ file_path = Path(file_text)
388
+
389
+ # If file is already a .bob file, skip it
390
+ if not file_path.suffix == ".bob":
391
+ continue
392
+
393
+ display_name = _get_display_name(
394
+ name_elem, current_component_name, file_path
395
+ )
396
+
397
+ child_node = _next_file_crawl(
398
+ file_text,
399
+ dest_path,
400
+ name_elem,
401
+ current_component_name,
402
+ display_name,
403
+ macro_dict,
404
+ )
405
+
406
+ child_node.macros = macro_dict
407
+ # TODO: make this work for only list[JsonMap]
408
+ assert isinstance(current_node.children, list)
409
+ # TODO: fix typing
410
+ current_node.children.append(child_node)
411
+
412
+ # We have already done the logic, so skip to the next widget
326
413
  continue
327
414
 
328
- # Validated screen names don't get renegerated
329
- display_name = name_elem
330
- display_name = self._get_component_label(
331
- name_elem,
332
- current_component_name,
333
- display_name,
334
- )
415
+ case _:
416
+ continue
335
417
 
336
418
  # Extract file path from file_elem
337
419
  # Keep raw string to preserve urls
@@ -342,27 +424,18 @@ class Builder:
342
424
  if not file_path.suffix == ".bob":
343
425
  continue
344
426
 
345
- # Create valid displayName
346
- display_name = self._parse_display_name(display_name, file_path)
347
-
348
- # TODO: misleading var name?
349
- next_file_path = dest_path.joinpath(file_path)
427
+ display_name = _get_display_name(
428
+ name_elem, current_component_name, file_path
429
+ )
350
430
 
351
- # Crawl the next file
352
- if next_file_path.is_file():
353
- # TODO: investigate non-recursive approaches?
354
- child_node = self._generate_json_map(
355
- next_file_path,
356
- dest_path,
357
- current_component_name=current_component_name,
358
- name_elem=name_elem,
359
- )
360
- else:
361
- child_node = JsonMap(
362
- file_text,
363
- display_name,
364
- exists=("IOC" in macro_dict or ("https://" in file_text)),
365
- )
431
+ child_node = _next_file_crawl(
432
+ file_text,
433
+ dest_path,
434
+ name_elem,
435
+ current_component_name,
436
+ display_name,
437
+ macro_dict,
438
+ )
366
439
 
367
440
  if widget_type == "embedded":
368
441
  for embedded_child in child_node.children:
@@ -499,6 +572,11 @@ class Builder:
499
572
  json.dumps(map, indent=4, default=lambda o: _serialise_json_map(o))
500
573
  + "\n"
501
574
  )
575
+ # f.writelines(
576
+ # self.conf.model_dump_json(
577
+ # indent=4, exclude_defaults=True, exclude_none=True
578
+ # )
579
+ # )
502
580
 
503
581
 
504
582
  # Function to convert the JsonMap objects into dictionaries,
@@ -558,3 +636,25 @@ def _get_action_group(element: ObjectifiedElement) -> ObjectifiedElement | None:
558
636
  f"Actions group not found in component [bold]{name}[/bold] on "
559
637
  f"[bold]{parent_name}[/bold]"
560
638
  )
639
+
640
+
641
+ def _get_nav_tabs(element: ObjectifiedElement) -> list[ObjectifiedElement] | None:
642
+ try:
643
+ element_tabs = element.tabs
644
+ assert element_tabs is not None
645
+
646
+ tabs = list(element_tabs.iterchildren("tab"))
647
+
648
+ return tabs
649
+
650
+ except AttributeError:
651
+ # TODO: Find better way of handling there being no "tabs" group
652
+ # TODO: Do widgets always have a name attr, or _can_ it be empty??
653
+ name = element.name
654
+
655
+ parent_name = p.name if (p := element.getparent()) is not None else None
656
+
657
+ logger_.error(
658
+ f"Tabs group not found in component [bold]{name}[/bold] on "
659
+ f"[bold]{parent_name}[/bold]"
660
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: techui-builder
3
- Version: 0.6.7a1
3
+ Version: 0.6.8a2
4
4
  Summary: A package for building Phoebus GUIs
5
5
  Author-email: Oliver Copping <oliver.copping@diamond.ac.uk>, Adedamola Sode <adedamola.sode@diamond.ac.uk>, Niamh Dougan <niamh.dougan@diamond.ac.uk>
6
6
  Project-URL: GitHub, https://github.com/DiamondLightSource/techui-builder
@@ -169,6 +169,7 @@ tests/test_files/motor_embed.bob
169
169
  tests/test_files/test_bob.bob
170
170
  tests/test_files/test_bob_bad.bob
171
171
  tests/test_files/test_bob_embedded.bob
172
+ tests/test_files/test_bob_navtabs.bob
172
173
  tests/test_files/widget.xml
173
174
  tests/test_files/widget_bad.xml
174
175
  tests/test_files/widget_bad_2.xml
@@ -53,13 +53,20 @@ def test_files():
53
53
 
54
54
 
55
55
  @pytest.fixture
56
- def example_json_map():
56
+ def example_json_map_root():
57
+ test_map_base = JsonMap("test_bob.bob", "Display")
58
+
59
+ return test_map_base
60
+
61
+
62
+ @pytest.fixture
63
+ def example_json_map(example_json_map_root):
57
64
  # Create test json map with child json map
58
65
  test_map_child = JsonMap("test_child_bob.bob", "Detector", exists=False)
59
- test_map = JsonMap("test_bob.bob", "Display")
60
- test_map.children.append(test_map_child)
61
66
 
62
- return test_map
67
+ example_json_map_root.children.append(test_map_child)
68
+
69
+ return example_json_map_root
63
70
 
64
71
 
65
72
  @pytest.fixture
@@ -217,3 +224,43 @@ def example_symbol_widget():
217
224
  widget_element = fromstring(tostring(widget_element))
218
225
 
219
226
  return widget_element
227
+
228
+
229
+ @pytest.fixture
230
+ def example_navtabs_widget():
231
+ # You cannot set a text tag of an ObjectifiedElement,
232
+ # so we need to make an etree.Element and convert it ...
233
+
234
+ widget_element = Element("widget")
235
+ widget_element.set("type", "navtabs")
236
+ widget_element.set("version", "2.0.0")
237
+ name_element = SubElement(widget_element, "name")
238
+ name_element.text = "navtab"
239
+ width_element = SubElement(widget_element, "width")
240
+ width_element.text = "205"
241
+ height_element = SubElement(widget_element, "height")
242
+ height_element.text = "120"
243
+ tabs_element = SubElement(widget_element, "tabs")
244
+ tab_element_1 = SubElement(tabs_element, "tab")
245
+ tab_element_2 = SubElement(tabs_element, "tab")
246
+
247
+ name_element_1 = SubElement(tab_element_1, "name")
248
+ name_element_1.text = "tab1"
249
+ file_element_1 = SubElement(tab_element_1, "file")
250
+ file_element_1.text = "tests/test-files/motor_embed.bob"
251
+ macros_element_1 = SubElement(tab_element_1, "macros")
252
+ macro_element_1 = SubElement(macros_element_1, "macro1")
253
+ macro_element_1.text = "test_macro_1"
254
+
255
+ name_element_2 = SubElement(tab_element_2, "name")
256
+ name_element_2.text = "tab2"
257
+ file_element_2 = SubElement(tab_element_2, "file")
258
+ file_element_2.text = "tests/test-files/motor_embed.bob"
259
+ macros_element_2 = SubElement(tab_element_2, "macros")
260
+ macro_element_2 = SubElement(macros_element_2, "macro2")
261
+ macro_element_2.text = "test_macro_2"
262
+
263
+ # ... which requires this horror
264
+ widget_element = fromstring(tostring(widget_element))
265
+
266
+ return widget_element
@@ -2,7 +2,7 @@ import logging
2
2
  import os
3
3
  from io import StringIO
4
4
  from pathlib import Path
5
- from unittest.mock import Mock, mock_open, patch
5
+ from unittest.mock import MagicMock, Mock, mock_open, patch
6
6
 
7
7
  import pytest
8
8
  from lxml import objectify
@@ -12,6 +12,7 @@ from softioc.builder import ClearRecords, records
12
12
  from techui_builder.builder import (
13
13
  JsonMap,
14
14
  _get_action_group, # type: ignore
15
+ _get_nav_tabs, # type: ignore
15
16
  _serialise_json_map, # type: ignore
16
17
  )
17
18
 
@@ -342,9 +343,31 @@ def test_generate_json_map_embedded_screen(builder_with_test_files, example_json
342
343
  )
343
344
 
344
345
  test_json_map = builder_with_test_files._generate_json_map(screen_path, dest_path)
346
+
345
347
  assert test_json_map == example_json_map
346
348
 
347
349
 
350
+ def test_generate_json_map_nav_tabs(builder_with_test_files, example_json_map_root):
351
+ builder_with_test_files._get_component_label = Mock(
352
+ side_effect=["Display", "Tab1", "Tab2"]
353
+ )
354
+
355
+ screen_path = Path("tests/test_files/test_bob_navtabs.bob").absolute()
356
+ dest_path = Path("tests/test_files/")
357
+
358
+ example_json_map_root.file = "test_bob_navtabs.bob"
359
+ example_json_map_root.children.extend(
360
+ [
361
+ JsonMap(display_name="Tab1", file="tab1.bob", exists=False),
362
+ JsonMap(display_name="Tab2", file="tab2.bob", exists=False),
363
+ ]
364
+ )
365
+
366
+ test_json_map = builder_with_test_files._generate_json_map(screen_path, dest_path)
367
+
368
+ assert test_json_map == example_json_map_root
369
+
370
+
348
371
  def test_parse_display_name_with_name(builder):
349
372
  """Test parse display name when <name> tag is present"""
350
373
  display_name = builder._parse_display_name(
@@ -556,3 +579,20 @@ def test_get_component_label_with_current_component_name_invalid(
556
579
  display_name="new_name",
557
580
  )
558
581
  assert display_name == "new_name"
582
+
583
+
584
+ def test_get_nav_tabs(example_navtabs_widget):
585
+ tabs_widget = _get_nav_tabs(example_navtabs_widget)
586
+
587
+ assert isinstance(tabs_widget, list)
588
+
589
+
590
+ def test_get_nav_tabs_no_tabs_group(caplog):
591
+ mock_navtabs = MagicMock(spec=objectify.ObjectifiedElement)
592
+ mock_navtabs.name = "no_tabs"
593
+
594
+ with caplog.at_level(logging.ERROR):
595
+ _get_nav_tabs(mock_navtabs)
596
+
597
+ for log_output in caplog.records:
598
+ assert "Tabs group not found" in log_output.message
@@ -0,0 +1,46 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!--Saved on 2026-05-20 13:34:00 by ryi58813-->
3
+ <display version="2.0.0">
4
+ <name>Display</name>
5
+ <widget type="navtabs" version="2.0.0">
6
+ <name>Navigation Tabs</name>
7
+ <tabs>
8
+ <tab>
9
+ <name>Tab1</name>
10
+ <file>tab1.bob</file>
11
+ <macros>
12
+ </macros>
13
+ <group_name/>
14
+ <selected_color>
15
+ <color red="236" green="236" blue="236">
16
+ </color>
17
+ </selected_color>
18
+ <deselected_color>
19
+ <color red="200" green="200" blue="200">
20
+ </color>
21
+ </deselected_color>
22
+ </tab>
23
+ <tab>
24
+ <name>Tab2</name>
25
+ <file>tab2.bob</file>
26
+ <macros>
27
+ </macros>
28
+ <group_name/>
29
+ <selected_color>
30
+ <color red="236" green="236" blue="236">
31
+ </color>
32
+ </selected_color>
33
+ <deselected_color>
34
+ <color red="200" green="200" blue="200">
35
+ </color>
36
+ </deselected_color>
37
+ </tab>
38
+ </tabs>
39
+ <x>150</x>
40
+ <y>120</y>
41
+ <width>820</width>
42
+ <height>530</height>
43
+ <direction>0</direction>
44
+ <tab_height>20</tab_height>
45
+ </widget>
46
+ </display>