@@ -697,6 +697,50 @@ def __init__(self, napari_viewer):
697697 # (Of course this will be a problem if we start using it everywhere so do not reuse lightly)
698698 QTimer .singleShot (10 , self .silently_dock_matplotlib_canvas )
699699
700+ # Retroactively initialize KeypointStores for Points layers that were
701+ # added before this widget was fully initialized (timing issue where
702+ # on_insert never fires for pre-existing layers).
703+ self ._init_retry_count = 0
704+ QTimer .singleShot (1000 , self ._retroactive_store_init )
705+
706+ def _retroactive_store_init (self ):
707+ self ._init_retry_count += 1
708+ if self ._stores :
709+ return
710+ has_points = any (
711+ isinstance (l , Points ) and l .metadata .get ("header" )
712+ for l in self .viewer .layers
713+ )
714+ if not has_points :
715+ if self ._init_retry_count < 10 :
716+ QTimer .singleShot (1000 , self ._retroactive_store_init )
717+ return
718+ for layer in self .viewer .layers :
719+ if isinstance (layer , Points ) and layer .metadata .get ("header" ):
720+ store = keypoints .KeypointStore (self .viewer , layer )
721+ self ._stores [layer ] = store
722+ if root := layer .metadata .get ("root" ):
723+ update_save_history (root )
724+ layer .metadata ["controls" ] = self
725+ layer .text .visible = False
726+ layer .bind_key ("M" , self .cycle_through_label_modes )
727+ layer .bind_key ("F" , self .cycle_through_color_modes )
728+ func = partial (_paste_data , store = store )
729+ layer ._paste_data = MethodType (func , layer )
730+ layer .add = MethodType (keypoints ._add , store )
731+ layer .events .add (query_next_frame = Event )
732+ layer .events .query_next_frame .connect (store ._advance_step )
733+ layer .bind_key ("Shift-Right" , store ._find_first_unlabeled_frame )
734+ layer .bind_key ("Shift-Left" , store ._find_first_unlabeled_frame )
735+ layer .bind_key ("Down" , store .next_keypoint , overwrite = True )
736+ layer .bind_key ("Up" , store .prev_keypoint , overwrite = True )
737+ layer .face_color_mode = "cycle"
738+ self ._form_dropdown_menus (store )
739+ self ._radio_box .setEnabled (True )
740+ self ._color_grp .setEnabled (True )
741+ self ._trail_cb .setEnabled (True )
742+ self ._show_traj_plot_cb .setEnabled (True )
743+
700744 def _ensure_mpl_canvas_docked (self ) -> None :
701745 """
702746 Dock the Matplotlib canvas as a napari dock widget, exactly once,
@@ -1225,6 +1269,9 @@ def on_insert(self, event):
12251269
12261270 return
12271271
1272+ if not layer .metadata .get ("header" ):
1273+ return
1274+
12281275 if layer .metadata .get ("tables" , "" ):
12291276 self ._keypoint_mapping_button .show ()
12301277
0 commit comments