scitex 2.14.0__py3-none-any.whl → 2.15.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 (218) hide show
  1. scitex/__init__.py +47 -0
  2. scitex/_env_loader.py +156 -0
  3. scitex/_mcp_resources/__init__.py +37 -0
  4. scitex/_mcp_resources/_cheatsheet.py +135 -0
  5. scitex/_mcp_resources/_figrecipe.py +138 -0
  6. scitex/_mcp_resources/_formats.py +102 -0
  7. scitex/_mcp_resources/_modules.py +337 -0
  8. scitex/_mcp_resources/_session.py +149 -0
  9. scitex/_mcp_tools/__init__.py +4 -0
  10. scitex/_mcp_tools/audio.py +66 -0
  11. scitex/_mcp_tools/diagram.py +11 -95
  12. scitex/_mcp_tools/introspect.py +191 -0
  13. scitex/_mcp_tools/plt.py +260 -305
  14. scitex/_mcp_tools/scholar.py +74 -0
  15. scitex/_mcp_tools/social.py +244 -0
  16. scitex/_mcp_tools/writer.py +21 -204
  17. scitex/ai/_gen_ai/_PARAMS.py +10 -7
  18. scitex/ai/classification/reporters/_SingleClassificationReporter.py +45 -1603
  19. scitex/ai/classification/reporters/_mixins/__init__.py +36 -0
  20. scitex/ai/classification/reporters/_mixins/_constants.py +67 -0
  21. scitex/ai/classification/reporters/_mixins/_cv_summary.py +387 -0
  22. scitex/ai/classification/reporters/_mixins/_feature_importance.py +119 -0
  23. scitex/ai/classification/reporters/_mixins/_metrics.py +275 -0
  24. scitex/ai/classification/reporters/_mixins/_plotting.py +179 -0
  25. scitex/ai/classification/reporters/_mixins/_reports.py +153 -0
  26. scitex/ai/classification/reporters/_mixins/_storage.py +160 -0
  27. scitex/audio/README.md +40 -36
  28. scitex/audio/__init__.py +127 -59
  29. scitex/audio/_branding.py +185 -0
  30. scitex/audio/_mcp/__init__.py +32 -0
  31. scitex/audio/_mcp/handlers.py +59 -6
  32. scitex/audio/_mcp/speak_handlers.py +238 -0
  33. scitex/audio/_relay.py +225 -0
  34. scitex/audio/engines/elevenlabs_engine.py +6 -1
  35. scitex/audio/mcp_server.py +228 -75
  36. scitex/canvas/README.md +1 -1
  37. scitex/canvas/editor/_dearpygui/__init__.py +25 -0
  38. scitex/canvas/editor/_dearpygui/_editor.py +147 -0
  39. scitex/canvas/editor/_dearpygui/_handlers.py +476 -0
  40. scitex/canvas/editor/_dearpygui/_panels/__init__.py +17 -0
  41. scitex/canvas/editor/_dearpygui/_panels/_control.py +119 -0
  42. scitex/canvas/editor/_dearpygui/_panels/_element_controls.py +190 -0
  43. scitex/canvas/editor/_dearpygui/_panels/_preview.py +43 -0
  44. scitex/canvas/editor/_dearpygui/_panels/_sections.py +390 -0
  45. scitex/canvas/editor/_dearpygui/_plotting.py +187 -0
  46. scitex/canvas/editor/_dearpygui/_rendering.py +504 -0
  47. scitex/canvas/editor/_dearpygui/_selection.py +295 -0
  48. scitex/canvas/editor/_dearpygui/_state.py +93 -0
  49. scitex/canvas/editor/_dearpygui/_utils.py +61 -0
  50. scitex/canvas/editor/flask_editor/templates/__init__.py +32 -70
  51. scitex/cli/__init__.py +38 -43
  52. scitex/cli/audio.py +76 -27
  53. scitex/cli/capture.py +13 -20
  54. scitex/cli/introspect.py +443 -0
  55. scitex/cli/main.py +198 -109
  56. scitex/cli/mcp.py +60 -34
  57. scitex/cli/scholar/__init__.py +8 -0
  58. scitex/cli/scholar/_crossref_scitex.py +296 -0
  59. scitex/cli/scholar/_fetch.py +25 -3
  60. scitex/cli/social.py +314 -0
  61. scitex/cli/writer.py +117 -0
  62. scitex/config/README.md +1 -1
  63. scitex/config/__init__.py +16 -2
  64. scitex/config/_env_registry.py +191 -0
  65. scitex/diagram/__init__.py +42 -19
  66. scitex/diagram/mcp_server.py +13 -125
  67. scitex/introspect/__init__.py +75 -0
  68. scitex/introspect/_call_graph.py +303 -0
  69. scitex/introspect/_class_hierarchy.py +163 -0
  70. scitex/introspect/_core.py +42 -0
  71. scitex/introspect/_docstring.py +131 -0
  72. scitex/introspect/_examples.py +113 -0
  73. scitex/introspect/_imports.py +271 -0
  74. scitex/introspect/_mcp/__init__.py +37 -0
  75. scitex/introspect/_mcp/handlers.py +208 -0
  76. scitex/introspect/_members.py +151 -0
  77. scitex/introspect/_resolve.py +89 -0
  78. scitex/introspect/_signature.py +131 -0
  79. scitex/introspect/_source.py +80 -0
  80. scitex/introspect/_type_hints.py +172 -0
  81. scitex/io/bundle/README.md +1 -1
  82. scitex/mcp_server.py +98 -5
  83. scitex/plt/__init__.py +248 -550
  84. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/_wrappers.py +5 -10
  85. scitex/plt/docs/EXTERNAL_PACKAGE_BRANDING.md +149 -0
  86. scitex/plt/gallery/README.md +1 -1
  87. scitex/plt/utils/_hitmap/__init__.py +82 -0
  88. scitex/plt/utils/_hitmap/_artist_extraction.py +343 -0
  89. scitex/plt/utils/_hitmap/_color_application.py +346 -0
  90. scitex/plt/utils/_hitmap/_color_conversion.py +121 -0
  91. scitex/plt/utils/_hitmap/_constants.py +40 -0
  92. scitex/plt/utils/_hitmap/_hitmap_core.py +334 -0
  93. scitex/plt/utils/_hitmap/_path_extraction.py +357 -0
  94. scitex/plt/utils/_hitmap/_query.py +113 -0
  95. scitex/plt/utils/_hitmap.py +46 -1616
  96. scitex/plt/utils/_metadata/__init__.py +80 -0
  97. scitex/plt/utils/_metadata/_artists/__init__.py +25 -0
  98. scitex/plt/utils/_metadata/_artists/_base.py +195 -0
  99. scitex/plt/utils/_metadata/_artists/_collections.py +356 -0
  100. scitex/plt/utils/_metadata/_artists/_extract.py +57 -0
  101. scitex/plt/utils/_metadata/_artists/_images.py +80 -0
  102. scitex/plt/utils/_metadata/_artists/_lines.py +261 -0
  103. scitex/plt/utils/_metadata/_artists/_patches.py +247 -0
  104. scitex/plt/utils/_metadata/_artists/_text.py +106 -0
  105. scitex/plt/utils/_metadata/_csv.py +416 -0
  106. scitex/plt/utils/_metadata/_detect.py +225 -0
  107. scitex/plt/utils/_metadata/_legend.py +127 -0
  108. scitex/plt/utils/_metadata/_rounding.py +117 -0
  109. scitex/plt/utils/_metadata/_verification.py +202 -0
  110. scitex/schema/README.md +1 -1
  111. scitex/scholar/__init__.py +8 -0
  112. scitex/scholar/_mcp/crossref_handlers.py +265 -0
  113. scitex/scholar/core/Scholar.py +63 -1700
  114. scitex/scholar/core/_mixins/__init__.py +36 -0
  115. scitex/scholar/core/_mixins/_enrichers.py +270 -0
  116. scitex/scholar/core/_mixins/_library_handlers.py +100 -0
  117. scitex/scholar/core/_mixins/_loaders.py +103 -0
  118. scitex/scholar/core/_mixins/_pdf_download.py +375 -0
  119. scitex/scholar/core/_mixins/_pipeline.py +312 -0
  120. scitex/scholar/core/_mixins/_project_handlers.py +125 -0
  121. scitex/scholar/core/_mixins/_savers.py +69 -0
  122. scitex/scholar/core/_mixins/_search.py +103 -0
  123. scitex/scholar/core/_mixins/_services.py +88 -0
  124. scitex/scholar/core/_mixins/_url_finding.py +105 -0
  125. scitex/scholar/crossref_scitex.py +367 -0
  126. scitex/scholar/docs/EXTERNAL_PACKAGE_BRANDING.md +149 -0
  127. scitex/scholar/examples/00_run_all.sh +120 -0
  128. scitex/scholar/jobs/_executors.py +27 -3
  129. scitex/scholar/pdf_download/ScholarPDFDownloader.py +38 -416
  130. scitex/scholar/pdf_download/_cli.py +154 -0
  131. scitex/scholar/pdf_download/strategies/__init__.py +11 -8
  132. scitex/scholar/pdf_download/strategies/manual_download_fallback.py +80 -3
  133. scitex/scholar/pipelines/ScholarPipelineBibTeX.py +73 -121
  134. scitex/scholar/pipelines/ScholarPipelineParallel.py +80 -138
  135. scitex/scholar/pipelines/ScholarPipelineSingle.py +43 -63
  136. scitex/scholar/pipelines/_single_steps.py +71 -36
  137. scitex/scholar/storage/_LibraryManager.py +97 -1695
  138. scitex/scholar/storage/_mixins/__init__.py +30 -0
  139. scitex/scholar/storage/_mixins/_bibtex_handlers.py +128 -0
  140. scitex/scholar/storage/_mixins/_library_operations.py +218 -0
  141. scitex/scholar/storage/_mixins/_metadata_conversion.py +226 -0
  142. scitex/scholar/storage/_mixins/_paper_saving.py +456 -0
  143. scitex/scholar/storage/_mixins/_resolution.py +376 -0
  144. scitex/scholar/storage/_mixins/_storage_helpers.py +121 -0
  145. scitex/scholar/storage/_mixins/_symlink_handlers.py +226 -0
  146. scitex/scholar/url_finder/.tmp/open_url/KNOWN_RESOLVERS.py +462 -0
  147. scitex/scholar/url_finder/.tmp/open_url/README.md +223 -0
  148. scitex/scholar/url_finder/.tmp/open_url/_DOIToURLResolver.py +694 -0
  149. scitex/scholar/url_finder/.tmp/open_url/_OpenURLResolver.py +1160 -0
  150. scitex/scholar/url_finder/.tmp/open_url/_ResolverLinkFinder.py +344 -0
  151. scitex/scholar/url_finder/.tmp/open_url/__init__.py +24 -0
  152. scitex/security/README.md +3 -3
  153. scitex/session/README.md +1 -1
  154. scitex/sh/README.md +1 -1
  155. scitex/social/__init__.py +153 -0
  156. scitex/social/docs/EXTERNAL_PACKAGE_BRANDING.md +149 -0
  157. scitex/template/README.md +1 -1
  158. scitex/template/clone_writer_directory.py +5 -5
  159. scitex/writer/README.md +1 -1
  160. scitex/writer/_mcp/handlers.py +11 -744
  161. scitex/writer/_mcp/tool_schemas.py +5 -335
  162. scitex-2.15.1.dist-info/METADATA +648 -0
  163. {scitex-2.14.0.dist-info → scitex-2.15.1.dist-info}/RECORD +166 -111
  164. scitex/canvas/editor/flask_editor/templates/_scripts.py +0 -4933
  165. scitex/canvas/editor/flask_editor/templates/_styles.py +0 -1658
  166. scitex/dev/plt/data/mpl/PLOTTING_FUNCTIONS.yaml +0 -90
  167. scitex/dev/plt/data/mpl/PLOTTING_SIGNATURES.yaml +0 -1571
  168. scitex/dev/plt/data/mpl/PLOTTING_SIGNATURES_DETAILED.yaml +0 -6262
  169. scitex/dev/plt/data/mpl/SIGNATURES_FLATTENED.yaml +0 -1274
  170. scitex/dev/plt/data/mpl/dir_ax.txt +0 -459
  171. scitex/diagram/_compile.py +0 -312
  172. scitex/diagram/_diagram.py +0 -355
  173. scitex/diagram/_mcp/__init__.py +0 -4
  174. scitex/diagram/_mcp/handlers.py +0 -400
  175. scitex/diagram/_mcp/tool_schemas.py +0 -157
  176. scitex/diagram/_presets.py +0 -173
  177. scitex/diagram/_schema.py +0 -182
  178. scitex/diagram/_split.py +0 -278
  179. scitex/plt/_mcp/__init__.py +0 -4
  180. scitex/plt/_mcp/_handlers_annotation.py +0 -102
  181. scitex/plt/_mcp/_handlers_figure.py +0 -195
  182. scitex/plt/_mcp/_handlers_plot.py +0 -252
  183. scitex/plt/_mcp/_handlers_style.py +0 -219
  184. scitex/plt/_mcp/handlers.py +0 -74
  185. scitex/plt/_mcp/tool_schemas.py +0 -497
  186. scitex/plt/mcp_server.py +0 -231
  187. scitex/scholar/data/.gitkeep +0 -0
  188. scitex/scholar/data/README.md +0 -44
  189. scitex/scholar/data/bib_files/bibliography.bib +0 -1952
  190. scitex/scholar/data/bib_files/neurovista.bib +0 -277
  191. scitex/scholar/data/bib_files/neurovista_enriched.bib +0 -441
  192. scitex/scholar/data/bib_files/neurovista_enriched_enriched.bib +0 -441
  193. scitex/scholar/data/bib_files/neurovista_processed.bib +0 -338
  194. scitex/scholar/data/bib_files/openaccess.bib +0 -89
  195. scitex/scholar/data/bib_files/pac-seizure_prediction_enriched.bib +0 -2178
  196. scitex/scholar/data/bib_files/pac.bib +0 -698
  197. scitex/scholar/data/bib_files/pac_enriched.bib +0 -1061
  198. scitex/scholar/data/bib_files/pac_processed.bib +0 -0
  199. scitex/scholar/data/bib_files/pac_titles.txt +0 -75
  200. scitex/scholar/data/bib_files/paywalled.bib +0 -98
  201. scitex/scholar/data/bib_files/related-papers-by-coauthors.bib +0 -58
  202. scitex/scholar/data/bib_files/related-papers-by-coauthors_enriched.bib +0 -87
  203. scitex/scholar/data/bib_files/seizure_prediction.bib +0 -694
  204. scitex/scholar/data/bib_files/seizure_prediction_processed.bib +0 -0
  205. scitex/scholar/data/bib_files/test_complete_enriched.bib +0 -437
  206. scitex/scholar/data/bib_files/test_final_enriched.bib +0 -437
  207. scitex/scholar/data/bib_files/test_seizure.bib +0 -46
  208. scitex/scholar/data/impact_factor/JCR_IF_2022.xlsx +0 -0
  209. scitex/scholar/data/impact_factor/JCR_IF_2024.db +0 -0
  210. scitex/scholar/data/impact_factor/JCR_IF_2024.xlsx +0 -0
  211. scitex/scholar/data/impact_factor/JCR_IF_2024_v01.db +0 -0
  212. scitex/scholar/data/impact_factor.db +0 -0
  213. scitex/scholar/examples/SUGGESTIONS.md +0 -865
  214. scitex/scholar/examples/dev.py +0 -38
  215. scitex-2.14.0.dist-info/METADATA +0 -1238
  216. {scitex-2.14.0.dist-info → scitex-2.15.1.dist-info}/WHEEL +0 -0
  217. {scitex-2.14.0.dist-info → scitex-2.15.1.dist-info}/entry_points.txt +0 -0
  218. {scitex-2.14.0.dist-info → scitex-2.15.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,119 @@
1
+ #!/usr/bin/env python3
2
+ # Timestamp: "2026-01-24 (ywatanabe)"
3
+ # File: /home/ywatanabe/proj/scitex-python/src/scitex/canvas/editor/_dearpygui/_panels/_control.py
4
+
5
+ """
6
+ Control panel creation for DearPyGui editor.
7
+
8
+ Main orchestrator that delegates to section modules.
9
+ """
10
+
11
+ from typing import TYPE_CHECKING
12
+
13
+ if TYPE_CHECKING:
14
+ from .._state import EditorState
15
+
16
+
17
+ def create_control_panel(state: "EditorState", dpg) -> None:
18
+ """Create the control panel with all editing options."""
19
+ from .._handlers import (
20
+ on_add_annotation,
21
+ on_apply_limits,
22
+ on_axis_element_change,
23
+ on_element_selected,
24
+ on_export_png,
25
+ on_legend_element_change,
26
+ on_remove_annotation,
27
+ on_reset_overrides,
28
+ on_save_manual,
29
+ on_text_element_change,
30
+ on_trace_property_change,
31
+ on_value_change,
32
+ )
33
+ from .._rendering import update_preview
34
+ from .._selection import deselect_element, get_all_element_labels
35
+ from ._sections import (
36
+ create_annotations_section,
37
+ create_axis_limits_section,
38
+ create_dimensions_section,
39
+ create_font_settings_section,
40
+ create_labels_section,
41
+ create_legend_section,
42
+ create_line_style_section,
43
+ create_selected_element_section,
44
+ create_style_section,
45
+ create_tick_settings_section,
46
+ )
47
+
48
+ o = state.current_overrides
49
+
50
+ with dpg.child_window(width=-1, height=-1, tag="control_panel"):
51
+ dpg.add_text("Properties", color=(100, 200, 100))
52
+ dpg.add_separator()
53
+
54
+ # Labels Section
55
+ create_labels_section(state, dpg, o, on_value_change)
56
+
57
+ # Axis Limits Section
58
+ create_axis_limits_section(state, dpg, o, on_apply_limits)
59
+
60
+ # Line Style Section
61
+ create_line_style_section(state, dpg, o, on_value_change)
62
+
63
+ # Font Settings Section
64
+ create_font_settings_section(state, dpg, o, on_value_change)
65
+
66
+ # Tick Settings Section
67
+ create_tick_settings_section(state, dpg, o, on_value_change)
68
+
69
+ # Style Section
70
+ create_style_section(state, dpg, o, on_value_change)
71
+
72
+ # Legend Section
73
+ create_legend_section(state, dpg, o, on_value_change)
74
+
75
+ # Selected Element Section
76
+ create_selected_element_section(
77
+ state,
78
+ dpg,
79
+ get_all_element_labels,
80
+ on_element_selected,
81
+ on_trace_property_change,
82
+ on_text_element_change,
83
+ on_axis_element_change,
84
+ on_legend_element_change,
85
+ deselect_element,
86
+ )
87
+
88
+ # Dimensions Section
89
+ create_dimensions_section(state, dpg, o, on_value_change)
90
+
91
+ # Annotations Section
92
+ create_annotations_section(state, dpg, on_add_annotation, on_remove_annotation)
93
+
94
+ dpg.add_separator()
95
+
96
+ # Action buttons
97
+ dpg.add_button(
98
+ label="Update Preview",
99
+ callback=lambda: update_preview(state, dpg),
100
+ width=-1,
101
+ )
102
+ dpg.add_button(
103
+ label="Save to .manual.json",
104
+ callback=lambda: on_save_manual(state, dpg),
105
+ width=-1,
106
+ )
107
+ dpg.add_button(
108
+ label="Reset to Original",
109
+ callback=lambda: on_reset_overrides(state, dpg),
110
+ width=-1,
111
+ )
112
+ dpg.add_button(
113
+ label="Export PNG",
114
+ callback=lambda: on_export_png(state, dpg),
115
+ width=-1,
116
+ )
117
+
118
+
119
+ # EOF
@@ -0,0 +1,190 @@
1
+ #!/usr/bin/env python3
2
+ # Timestamp: "2026-01-24 (ywatanabe)"
3
+ # File: /home/ywatanabe/proj/scitex-python/src/scitex/canvas/editor/_dearpygui/_panels/_element_controls.py
4
+
5
+ """
6
+ Element-specific control groups for DearPyGui editor.
7
+
8
+ Creates control groups for trace, text, axis, and legend elements.
9
+ """
10
+
11
+ from typing import TYPE_CHECKING, Callable
12
+
13
+ if TYPE_CHECKING:
14
+ from .._state import EditorState
15
+
16
+
17
+ def create_trace_controls(
18
+ state: "EditorState", dpg, on_trace_property_change: Callable
19
+ ) -> None:
20
+ """Create trace-specific controls."""
21
+ with dpg.group(tag="trace_controls_group", show=False):
22
+ dpg.add_input_text(
23
+ label="Label",
24
+ tag="trace_label_input",
25
+ callback=lambda s, a: on_trace_property_change(state, dpg),
26
+ on_enter=True,
27
+ width=200,
28
+ )
29
+ dpg.add_color_edit(
30
+ label="Color",
31
+ tag="trace_color_picker",
32
+ callback=lambda s, a: on_trace_property_change(state, dpg),
33
+ no_alpha=True,
34
+ width=200,
35
+ )
36
+ dpg.add_slider_float(
37
+ label="Line Width",
38
+ tag="trace_linewidth_slider",
39
+ default_value=1.0,
40
+ min_value=0.1,
41
+ max_value=5.0,
42
+ callback=lambda s, a: on_trace_property_change(state, dpg),
43
+ width=200,
44
+ )
45
+ dpg.add_combo(
46
+ label="Line Style",
47
+ items=["-", "--", "-.", ":", ""],
48
+ default_value="-",
49
+ tag="trace_linestyle_combo",
50
+ callback=lambda s, a: on_trace_property_change(state, dpg),
51
+ width=100,
52
+ )
53
+ dpg.add_combo(
54
+ label="Marker",
55
+ items=["", "o", "s", "^", "v", "D", "x", "+", "*"],
56
+ default_value="",
57
+ tag="trace_marker_combo",
58
+ callback=lambda s, a: on_trace_property_change(state, dpg),
59
+ width=100,
60
+ )
61
+ dpg.add_slider_float(
62
+ label="Marker Size",
63
+ tag="trace_markersize_slider",
64
+ default_value=6.0,
65
+ min_value=1.0,
66
+ max_value=20.0,
67
+ callback=lambda s, a: on_trace_property_change(state, dpg),
68
+ width=200,
69
+ )
70
+
71
+
72
+ def create_text_controls(
73
+ state: "EditorState", dpg, on_text_element_change: Callable
74
+ ) -> None:
75
+ """Create text element controls."""
76
+ with dpg.group(tag="text_controls_group", show=False):
77
+ dpg.add_input_text(
78
+ label="Text",
79
+ tag="element_text_input",
80
+ callback=lambda s, a: on_text_element_change(state, dpg),
81
+ on_enter=True,
82
+ width=200,
83
+ )
84
+ dpg.add_slider_int(
85
+ label="Font Size",
86
+ tag="element_fontsize_slider",
87
+ default_value=8,
88
+ min_value=4,
89
+ max_value=24,
90
+ callback=lambda s, a: on_text_element_change(state, dpg),
91
+ width=200,
92
+ )
93
+ dpg.add_color_edit(
94
+ label="Color",
95
+ tag="element_text_color",
96
+ callback=lambda s, a: on_text_element_change(state, dpg),
97
+ no_alpha=True,
98
+ default_value=[0, 0, 0],
99
+ width=200,
100
+ )
101
+
102
+
103
+ def create_axis_controls(
104
+ state: "EditorState", dpg, on_axis_element_change: Callable
105
+ ) -> None:
106
+ """Create axis element controls."""
107
+ with dpg.group(tag="axis_controls_group", show=False):
108
+ dpg.add_slider_float(
109
+ label="Line Width (mm)",
110
+ tag="axis_linewidth_slider",
111
+ default_value=0.2,
112
+ min_value=0.05,
113
+ max_value=1.0,
114
+ callback=lambda s, a: on_axis_element_change(state, dpg),
115
+ width=200,
116
+ )
117
+ dpg.add_slider_float(
118
+ label="Tick Length (mm)",
119
+ tag="axis_tick_length_slider",
120
+ default_value=0.8,
121
+ min_value=0.2,
122
+ max_value=3.0,
123
+ callback=lambda s, a: on_axis_element_change(state, dpg),
124
+ width=200,
125
+ )
126
+ dpg.add_slider_int(
127
+ label="Tick Font Size",
128
+ tag="axis_tick_fontsize_slider",
129
+ default_value=7,
130
+ min_value=4,
131
+ max_value=16,
132
+ callback=lambda s, a: on_axis_element_change(state, dpg),
133
+ width=200,
134
+ )
135
+ dpg.add_checkbox(
136
+ label="Show Spine",
137
+ tag="axis_show_spine_checkbox",
138
+ default_value=True,
139
+ callback=lambda s, a: on_axis_element_change(state, dpg),
140
+ )
141
+
142
+
143
+ def create_legend_controls(
144
+ state: "EditorState", dpg, on_legend_element_change: Callable
145
+ ) -> None:
146
+ """Create legend controls."""
147
+ with dpg.group(tag="legend_controls_group", show=False):
148
+ dpg.add_checkbox(
149
+ label="Visible",
150
+ tag="legend_visible_edit",
151
+ default_value=True,
152
+ callback=lambda s, a: on_legend_element_change(state, dpg),
153
+ )
154
+ dpg.add_checkbox(
155
+ label="Show Frame",
156
+ tag="legend_frameon_edit",
157
+ default_value=False,
158
+ callback=lambda s, a: on_legend_element_change(state, dpg),
159
+ )
160
+ dpg.add_combo(
161
+ label="Position",
162
+ items=[
163
+ "best",
164
+ "upper right",
165
+ "upper left",
166
+ "lower right",
167
+ "lower left",
168
+ "center right",
169
+ "center left",
170
+ "upper center",
171
+ "lower center",
172
+ "center",
173
+ ],
174
+ default_value="best",
175
+ tag="legend_loc_edit",
176
+ callback=lambda s, a: on_legend_element_change(state, dpg),
177
+ width=150,
178
+ )
179
+ dpg.add_slider_int(
180
+ label="Font Size",
181
+ tag="legend_fontsize_edit",
182
+ default_value=6,
183
+ min_value=4,
184
+ max_value=14,
185
+ callback=lambda s, a: on_legend_element_change(state, dpg),
186
+ width=200,
187
+ )
188
+
189
+
190
+ # EOF
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env python3
2
+ # Timestamp: "2026-01-24 (ywatanabe)"
3
+ # File: /home/ywatanabe/proj/scitex-python/src/scitex/canvas/editor/_dearpygui/_panels/_preview.py
4
+
5
+ """
6
+ Preview panel creation for DearPyGui editor.
7
+ """
8
+
9
+ from typing import TYPE_CHECKING
10
+
11
+ if TYPE_CHECKING:
12
+ from .._state import EditorState
13
+
14
+
15
+ def create_preview_panel(state: "EditorState", dpg) -> None:
16
+ """Create the preview panel with figure image, click handler, and hover detection."""
17
+ from .._handlers import on_preview_click, on_preview_hover
18
+
19
+ with dpg.child_window(width=900, height=-1, tag="preview_panel"):
20
+ dpg.add_text(
21
+ "Figure Preview (click to select, hover to highlight)",
22
+ color=(100, 200, 100),
23
+ )
24
+ dpg.add_separator()
25
+
26
+ # Image display with click and move handlers
27
+ with dpg.handler_registry(tag="preview_handler"):
28
+ dpg.add_mouse_click_handler(
29
+ callback=lambda s, a: on_preview_click(state, dpg, a)
30
+ )
31
+ dpg.add_mouse_move_handler(
32
+ callback=lambda s, a: on_preview_hover(state, dpg, a)
33
+ )
34
+
35
+ dpg.add_image("preview_texture", tag="preview_image")
36
+
37
+ dpg.add_separator()
38
+ dpg.add_text("", tag="hover_text", color=(150, 200, 150))
39
+ dpg.add_text("", tag="status_text", color=(150, 150, 150))
40
+ dpg.add_text("", tag="selection_text", color=(200, 200, 100))
41
+
42
+
43
+ # EOF