@@ -123,7 +123,6 @@ public static Bdv getInstance() {
123123 // Grace period added on top of an animated setViewerTransform()'s own duration before a trace click
124124 // is accepted again; mirrors Bvv's own RECENTER_SETTLE_BUFFER_MS constant/rationale.
125125 private static final long TRANSFORM_SETTLE_BUFFER_MS = 150 ;
126- private JProgressBar progressBar ; // Docked at CardPanel bottom; see updateStatus()
127126
128127
129128
@@ -640,32 +639,6 @@ public void repaint() {
640639 if (viewerPanel != null ) viewerPanel .requestRepaint ();
641640 }
642641
643- /**
644- * @see AbstractBigViewer#updateStatus(String, int, int)
645- */
646- @ Override
647- public void updateStatus (final String message , final int step , final int nSteps ) {
648- SwingUtilities .invokeLater (() -> {
649- if (progressBar == null ) return ;
650- if (nSteps == 0 ) {
651- progressBar .setIndeterminate (false );
652- progressBar .setVisible (false );
653- progressBar .setValue (0 );
654- progressBar .setString ("" );
655- } else if (nSteps < 0 ) {
656- progressBar .setIndeterminate (true );
657- progressBar .setString (message == null ? "" : message );
658- progressBar .setVisible (true );
659- } else {
660- progressBar .setIndeterminate (false );
661- progressBar .setMaximum (nSteps );
662- progressBar .setValue (step );
663- progressBar .setString (message == null ? "" : message );
664- progressBar .setVisible (true );
665- }
666- });
667- }
668-
669642 /**
670643 * @see AbstractBigViewer#resyncCalibrationFromActiveSource()
671644 */
@@ -917,6 +890,23 @@ private void updateSliceClip(final AffineTransform3D transform) {
917890 annotationOverlay .setCamParams (Double .MAX_VALUE , slabZ , slabZ );
918891 }
919892
893+ /** Places a marker at the current mouse position (M key) */
894+ private Action addMarkerAction () {
895+ return new AbstractAction ("Add Marker" ) {
896+ @ Override
897+ public void actionPerformed (final java .awt .event .ActionEvent e ) {
898+ if (blockMarkerPlacement ()) return ;
899+ final RealPoint pos = new RealPoint (3 );
900+ getGlobalMouseCoordinates (pos );
901+ final double x = pos .getDoublePosition (0 );
902+ final double y = pos .getDoublePosition (1 );
903+ final double z = pos .getDoublePosition (2 );
904+ getMarkerManager ().add (x , y , z );
905+ showViewerMessage (String .format ("Marker placed at (%.1f, %.1f, %.1f)" , x , y , z ));
906+ }
907+ };
908+ }
909+
920910 private void initializeCardPanel () {
921911 // addCard() below builds JComponents (Card/HeaderPanel) directly, which is
922912 // unsafe if this runs off-EDT (e.g. from a SciJava command thread): it can
@@ -944,68 +934,14 @@ private void initializeCardPanel() {
944934 cp .setCardExpanded ("SNT Controls" , true );
945935 });
946936 resizeCardPanelsAsNeeded (cp .getComponent ());
947- // Progress bar: docked at the bottom of the card panel, below all cards, without a card
948- // header - see Bvv's identical placement for why (avoids viewport flicker vs. BorderLayout.SOUTH)
949- progressBar = new JProgressBar (0 , 100 );
950- progressBar .setStringPainted (true );
951- progressBar .setString ("" );
952- progressBar .setVisible (false );
953- addToCardPanelBottom (cp , progressBar );
937+ initProgressBar (cp );
954938 }
955939
956940 // M and H keys via BDV's keybindings system so the trigger layer sees them
957941 if (bdvHandle .getSplitPanel ().getTopLevelAncestor () instanceof bdv .viewer .ViewerFrame vf ) {
958942 final javax .swing .InputMap sntIMap = new javax .swing .InputMap ();
959943 final javax .swing .ActionMap sntAMap = new javax .swing .ActionMap ();
960- sntIMap .put (KeyStroke .getKeyStroke (KeyEvent .VK_M , 0 ), "snt-add-marker" );
961- sntAMap .put ("snt-add-marker" , new AbstractAction () {
962- @ Override
963- public void actionPerformed (final java .awt .event .ActionEvent e ) {
964- if (blockMarkerPlacement ()) return ;
965- final RealPoint pos = new RealPoint (3 );
966- getGlobalMouseCoordinates (pos );
967- final double x = pos .getDoublePosition (0 );
968- final double y = pos .getDoublePosition (1 );
969- final double z = pos .getDoublePosition (2 );
970- getMarkerManager ().add (x , y , z );
971- showViewerMessage (String .format ("Marker placed at (%.1f, %.1f, %.1f)" , x , y , z ));
972- }
973- });
974- sntIMap .put (KeyStroke .getKeyStroke (KeyEvent .VK_H , 0 , false ), "snt-hide-annotations-press" );
975- sntIMap .put (KeyStroke .getKeyStroke (KeyEvent .VK_H , 0 , true ), "snt-hide-annotations-release" );
976- sntAMap .put ("snt-hide-annotations-press" , actions .hideAnnotationsPressAction ());
977- sntAMap .put ("snt-hide-annotations-release" , actions .hideAnnotationsReleaseAction ());
978- sntIMap .put (KeyStroke .getKeyStroke (KeyEvent .VK_L , 0 ), "snt-toggle-secondary-layer" );
979- sntAMap .put ("snt-toggle-secondary-layer" , actions .toggleSecondaryLayerTracingAction ());
980- sntIMap .put (KeyStroke .getKeyStroke (KeyEvent .VK_P , 0 ), "snt-pick-sigma-point" );
981- sntAMap .put ("snt-pick-sigma-point" , actions .pickSigmaPointAction ());
982- if (tracer != null ) {
983- // Grab Nearest Path/Add Nearest Path to Selection: mirrors InteractiveTracerCanvas's
984- // G/Shift+G shortcuts on the classic canvas (see AbstractTracer#getSelectNearestPathAction).
985- // NB: this intentionally shadows BDV/BVV's own native "toggle grouping" (plain G)
986- sntIMap .put (KeyStroke .getKeyStroke (KeyEvent .VK_G , 0 ), "snt-select-nearest-path" );
987- sntAMap .put ("snt-select-nearest-path" , tracer .getSelectNearestPathAction (false ));
988- sntIMap .put (KeyStroke .getKeyStroke (KeyEvent .VK_G , java .awt .event .InputEvent .SHIFT_DOWN_MASK ), "snt-append-nearest-path" );
989- sntAMap .put ("snt-append-nearest-path" , tracer .getSelectNearestPathAction (true ));
990- // Finish/discard the in-progress tracing path without a canvas click (see Bvv's identical
991- // wiring for why Enter/Esc are used instead of a double click to finish)
992- sntIMap .put (KeyStroke .getKeyStroke (KeyEvent .VK_ENTER , 0 ), "snt-finish-path" );
993- sntAMap .put ("snt-finish-path" , tracer .getFinishPathAction ());
994- sntIMap .put (KeyStroke .getKeyStroke (KeyEvent .VK_ESCAPE , 0 ), "snt-discard-path" );
995- sntAMap .put ("snt-discard-path" , tracer .getDiscardPathAction ());
996- sntIMap .put (KeyStroke .getKeyStroke (KeyEvent .VK_Z , 0 ), "snt-undo-segment" ); // see Tracer#undoLastSegment
997- sntAMap .put ("snt-undo-segment" , tracer .getUndoSegmentAction ());
998- // Space: a quick tap flips tracing on/off permanently (like clicking No tracing/ Manual/Interactive);
999- // holding it past a threshold instead changes to "No tracing" for as long as it's held and snaps back
1000- // on release (mirrors InteractiveTracerCanvas#mousePressed hold-Space-to-pan convention). See
1001- // AbstractTracer#getToggleTracingHoldPressAction/ReleaseAction for the tap/hold logic. Like G above,
1002- // this intentionally shadows BDV's own native Space binding, if any, since both maps share this same
1003- // "snt" input map
1004- sntIMap .put (KeyStroke .getKeyStroke (KeyEvent .VK_SPACE , 0 , false ), "snt-toggle-tracing-hold-press" );
1005- sntIMap .put (KeyStroke .getKeyStroke (KeyEvent .VK_SPACE , 0 , true ), "snt-toggle-tracing-hold-release" );
1006- sntAMap .put ("snt-toggle-tracing-hold-press" , tracer .getToggleTracingHoldPressAction ());
1007- sntAMap .put ("snt-toggle-tracing-hold-release" , tracer .getToggleTracingHoldReleaseAction ());
1008- }
944+ registerSntKeybindings (sntIMap , sntAMap , actions , addMarkerAction (), tracer );
1009945 registerKeyframeCapture (sntIMap , sntAMap );
1010946 // Command palette shortcut: wired unconditionally (not just in Stream mode), since the BDV
1011947 // window can be opened in classic mode too, and its own keybindings layer needs this regardless
0 commit comments