3333)
3434from .._tensor_elements_support import _TensorRecord
3535from .._typing import root_figure
36- from .._ui_utils import _set_axes_visible , _set_figure_bottom_reserved
36+ from .._ui_utils import _set_axes_visible , _set_figure_bottom_reserved , _style_control_tray_axes
3737from ..config import EngineName , PlotConfig , ViewName
3838from ..contraction_viewer import _MAIN_FIGURE_BOTTOM_RESERVED , _PLAYBACK_DETAILS_TOP
3939from ..einsum_module .trace import EinsumTrace
7373_INTERACTIVE_CHECK_FRAME_PROPS : dict [str , float ] = {"s" : 44.0 , "linewidth" : 0.9 }
7474_INTERACTIVE_CHECK_MARK_PROPS : dict [str , float ] = {"s" : 34.0 , "linewidth" : 1.0 }
7575_INTERACTIVE_RADIO_PROPS : dict [str , float ] = {"s" : 38.0 , "linewidth" : 0.9 }
76- _CONTROL_TRAY_FACE : tuple [float , float , float ] = (0.97 , 0.97 , 0.99 )
77- _CONTROL_TRAY_FRAME : tuple [float , float , float ] = (0.78 , 0.78 , 0.82 )
7876
7977
80- def _style_interactive_control_axes (ax : Axes ) -> None :
81- ax .set_xticks ([])
82- ax .set_yticks ([])
83- ax .set_navigate (False )
84- ax .patch .set_facecolor (_CONTROL_TRAY_FACE )
85- ax .patch .set_alpha (0.88 )
86- ax .patch .set_edgecolor (_CONTROL_TRAY_FRAME )
87- ax .patch .set_linewidth (0.6 )
88- for spine in ax .spines .values ():
89- spine .set_visible (True )
90- spine .set_linewidth (0.6 )
91- spine .set_color (_CONTROL_TRAY_FRAME )
78+ def _reveal_auxiliary_figure (figure : Figure ) -> None :
79+ manager = getattr (figure .canvas , "manager" , None )
80+ manager_show = getattr (manager , "show" , None )
81+ if callable (manager_show ):
82+ with suppress (AttributeError , RuntimeError , TypeError , ValueError ):
83+ manager_show ()
84+ else :
85+ figure_show = getattr (figure , "show" , None )
86+ if callable (figure_show ):
87+ with suppress (AttributeError , RuntimeError , TypeError , ValueError ):
88+ figure_show ()
89+ draw_idle = getattr (figure .canvas , "draw_idle" , None )
90+ if callable (draw_idle ):
91+ with suppress (AttributeError , RuntimeError , TypeError , ValueError ):
92+ draw_idle ()
93+ flush_events = getattr (figure .canvas , "flush_events" , None )
94+ if callable (flush_events ):
95+ with suppress (AttributeError , RuntimeError , TypeError , ValueError ):
96+ flush_events ()
9297
9398
9499class _LinkedTensorInspectorController :
@@ -111,6 +116,10 @@ def __init__(
111116 self ._closing_programmatically : bool = False
112117 self ._close_cid : int | None = None
113118
119+ @property
120+ def is_enabled (self ) -> bool :
121+ return self ._enabled
122+
114123 def bind_viewer (self , viewer : Any ) -> None :
115124 if self ._viewer is viewer :
116125 if self ._enabled and self ._viewer is not None :
@@ -128,9 +137,11 @@ def bind_viewer(self, viewer: Any) -> None:
128137 call_immediately = self ._enabled ,
129138 )
130139
131- def set_enabled (self , enabled : bool ) -> None :
140+ def set_enabled (self , enabled : bool , * , reveal : bool = False ) -> None :
132141 target = bool (enabled )
133142 if target == self ._enabled :
143+ if target and reveal and self ._figure is not None :
144+ _reveal_auxiliary_figure (self ._figure )
134145 if target and self ._viewer is not None :
135146 self ._sync_to_step (int (self ._viewer .current_step ))
136147 return
@@ -139,6 +150,8 @@ def set_enabled(self, enabled: bool) -> None:
139150 self ._close_figure ()
140151 return
141152 self ._ensure_figure ()
153+ if reveal and self ._figure is not None :
154+ _reveal_auxiliary_figure (self ._figure )
142155 if self ._viewer is not None :
143156 self ._sync_to_step (int (self ._viewer .current_step ))
144157 else :
@@ -295,6 +308,7 @@ def __init__(
295308 self .figure : Figure | None = None
296309 self ._tensor_inspector : _LinkedTensorInspectorController | None = None
297310 self ._figure_close_cid : int | None = None
311+ self ._initialized : bool = False
298312 if self .tensor_inspector_available :
299313 self ._tensor_inspector = _LinkedTensorInspectorController (
300314 trace = cast (EinsumTrace , network ),
@@ -314,6 +328,7 @@ def initialize(self) -> tuple[Figure, RenderedAxes]:
314328 return figure , ax
315329 self ._build_controls ()
316330 self ._apply_scene_state (self .current_scene )
331+ self ._initialized = True
317332 set_interactive_controls (figure , self )
318333 set_active_axes (figure , ax )
319334 figure ._tensor_network_viz_tensor_inspector = self ._tensor_inspector # type: ignore[attr-defined]
@@ -436,7 +451,7 @@ def _build_controls(self) -> None:
436451 )
437452 cb_bottom = float (cb_bounds [1 ])
438453 check_ax = self .figure .add_axes (cb_bounds )
439- _style_interactive_control_axes (check_ax )
454+ _style_control_tray_axes (check_ax )
440455 self ._check_ax = check_ax
441456 if not self ._external_ax :
442457 radio_bounds : tuple [float , float , float , float ] = (
@@ -446,7 +461,7 @@ def _build_controls(self) -> None:
446461 _VIEW_SELECTOR_HEIGHT ,
447462 )
448463 radio_ax = self .figure .add_axes (radio_bounds )
449- _style_interactive_control_axes (radio_ax )
464+ _style_control_tray_axes (radio_ax )
450465 self ._radio_ax = radio_ax
451466 active_index = 0 if self .current_view == "2d" else 1
452467 self ._radio = RadioButtons (
@@ -569,7 +584,15 @@ def _apply_scene_state(self, scene: _InteractiveSceneState) -> None:
569584 if self ._tensor_inspector is not None :
570585 self ._tensor_inspector .bind_viewer (controls ._viewer )
571586 if self ._tensor_inspector is not None :
572- self ._tensor_inspector .set_enabled (self .tensor_inspector_on )
587+ reveal_inspector = bool (
588+ self ._initialized
589+ and self .tensor_inspector_on
590+ and not self ._tensor_inspector .is_enabled
591+ )
592+ self ._tensor_inspector .set_enabled (
593+ self .tensor_inspector_on ,
594+ reveal = reveal_inspector ,
595+ )
573596 _apply_scene_hover_state (scene , hover_on = self .hover_on )
574597 self ._sync_checkbuttons ()
575598 if not self ._external_ax :
0 commit comments