From c95fe72b4459c243d0e110f46bd8531c71917000 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch <tobias.pietzsch@gmail.com> Date: Thu, 5 Oct 2017 16:46:26 +0200 Subject: [PATCH] Move bookmark controls to DynamicBookmarksTimeSlider panel --- .../bookmarks/editor/BookmarksEditor.java | 1 + src/main/java/bdv/viewer/ViewerFrame.java | 1 - src/main/java/bdv/viewer/ViewerPanel.java | 363 ++++++++++-------- 3 files changed, 194 insertions(+), 171 deletions(-) diff --git a/src/main/java/bdv/tools/bookmarks/editor/BookmarksEditor.java b/src/main/java/bdv/tools/bookmarks/editor/BookmarksEditor.java index f386d479..e8d5119b 100644 --- a/src/main/java/bdv/tools/bookmarks/editor/BookmarksEditor.java +++ b/src/main/java/bdv/tools/bookmarks/editor/BookmarksEditor.java @@ -258,6 +258,7 @@ public class BookmarksEditor } } ); + // TODO: FIX viewer.getKeyFramePopupMenu().setBookmarksEditor( this ); } diff --git a/src/main/java/bdv/viewer/ViewerFrame.java b/src/main/java/bdv/viewer/ViewerFrame.java index 43dc6495..40c0058e 100644 --- a/src/main/java/bdv/viewer/ViewerFrame.java +++ b/src/main/java/bdv/viewer/ViewerFrame.java @@ -127,7 +127,6 @@ public class ViewerFrame extends JFrame if ( choice != UserSaveChoice.CANCEL ) { viewer.stop(); - viewer.stopPlayExecuter(); dispose(); } } diff --git a/src/main/java/bdv/viewer/ViewerPanel.java b/src/main/java/bdv/viewer/ViewerPanel.java index 80cca168..448b0c96 100644 --- a/src/main/java/bdv/viewer/ViewerPanel.java +++ b/src/main/java/bdv/viewer/ViewerPanel.java @@ -47,7 +47,6 @@ import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.LayoutManager; import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.MouseEvent; @@ -250,26 +249,10 @@ public class ViewerPanel extends JPanel implements OverlayRenderer, TransformLis protected final ViewerOptions.Values options; - protected final JButton previousKeyframeButton; - - protected final JButton addKeyframeButton; - - protected final JButton nextKeyframeButton; - - protected final JPlaySlider sliderPlay; - - protected final JPanel timeKeyframePanel; - - protected final KeyFramePanel keyframePanel; - protected final List< ActiveBookmarkChangedListener > activeBookmarkChangedListeners = new ArrayList<>(); protected final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); - protected final Timer playTimer = new Timer( 0, this::onPlayTimerTick ); - - protected final ActionMap actionMap; - public ViewerPanel( final List< SourceAndConverter< ? > > sources, final int numTimePoints, final CacheControl cacheControl, final ActionMap actionMap ) { this( sources, numTimePoints, cacheControl, ViewerOptions.options(), actionMap ); @@ -290,7 +273,6 @@ public class ViewerPanel extends JPanel implements OverlayRenderer, TransformLis super( new BorderLayout(), false ); options = optional.values; - this.actionMap = actionMap; final int numGroups = options.getNumSourceGroups(); final ArrayList< SourceGroup > groups = new ArrayList<>( numGroups ); @@ -334,116 +316,14 @@ public class ViewerPanel extends JPanel implements OverlayRenderer, TransformLis mouseCoordinates = new MouseCoordinateListener(); display.addHandler( mouseCoordinates ); - final JPanel sliderPanel = new JPanel(); - sliderPanel.setLayout( new BoxLayout( sliderPanel, BoxLayout.X_AXIS ) ); - - sliderPanel.add( Box.createRigidArea( new Dimension( 5, 5 ) ) ); - - previousKeyframeButton = new JButton( "<<" ); - previousKeyframeButton.setToolTipText( "Go to previous keyframe" ); - previousKeyframeButton.addActionListener( new ActionListener() - { - @Override - public void actionPerformed( final ActionEvent e ) - { - final Action action = actionMap.get( BigDataViewerActions.PREVIOUS_KEYFRAME ); - if ( action != null ) - action.actionPerformed( e ); - } - } ); - sliderPanel.add( previousKeyframeButton ); - - sliderPanel.add( Box.createRigidArea( new Dimension( 5, 5 ) ) ); - - addKeyframeButton = new JButton( "+" ); - addKeyframeButton.setToolTipText( "Add a new keyframe" ); - addKeyframeButton.addActionListener( new ActionListener() - { - @Override - public void actionPerformed( final ActionEvent e ) - { - final Action action = actionMap.get( BigDataViewerActions.ADD_KEYFRAME ); - if ( action != null ) - action.actionPerformed( e ); - } - } ); - sliderPanel.add( addKeyframeButton ); - - sliderPanel.add( Box.createRigidArea( new Dimension( 5, 5 ) ) ); - - nextKeyframeButton = new JButton( ">>" ); - nextKeyframeButton.setToolTipText( "Go to next keyframe" ); - nextKeyframeButton.addActionListener( new ActionListener() - { - @Override - public void actionPerformed( final ActionEvent e ) - { - final Action action = actionMap.get( BigDataViewerActions.NEXT_KEYFRAME ); - if ( action != null ) - action.actionPerformed( e ); - } - } ); - sliderPanel.add( nextKeyframeButton ); - - sliderPanel.add( Box.createRigidArea( new Dimension( 5, 5 ) ) ); - - sliderPlay = new JPlaySlider(); - sliderPlay.setPreferredSize( new Dimension( 200, 50 ) ); - sliderPlay.setMinimumSize( new Dimension( 200, 50 ) ); - sliderPlay.setMaximumSize( new Dimension( 200, 50 ) ); - sliderPlay.setAlignmentX( Component.LEFT_ALIGNMENT ); - sliderPanel.add( sliderPlay ); - sliderPlay.addChangeListener( new ChangeListener() - { - @Override - public void stateChanged( final ChangeEvent e ) - { - // if ( !e.getSource().equals( sliderPlay ) ) - // return; - - if ( sliderPlay.getValue() == 0 ) - { - stopPlayExecuter(); - return; - } - - final int periode = 1000 / ( 1 * Math.abs( sliderPlay.getValue() ) ); - playTimer.setDelay( periode ); - playTimer.start(); - } - } ); - sliderPlay.addComponentListener( new ComponentAdapter() - { - @Override - public void componentHidden( final ComponentEvent e ) - { - stopPlayExecuter(); - } - - } ); - - sliderPanel.add( Box.createRigidArea( new Dimension( 5, 5 ) ) ); - - timeKeyframePanel = new JPanel(); - timeKeyframePanel.setBorder( new EmptyBorder( 5, 0, 5, 0 ) ); - sliderPanel.add( timeKeyframePanel ); - timeKeyframePanel.setLayout( new BoxLayout( timeKeyframePanel, BoxLayout.Y_AXIS ) ); - - - sliderTime = new DefaultTimeSlider(); +// sliderTime = new DefaultTimeSlider(); + sliderTime = new DynamicBookmarksTimeSlider( actionMap, this ); sliderTime.updateNumTimepoints( 0, numTimepoints ); sliderTime.addTimePointListener( this::setTimepoint ); - timeKeyframePanel.add( sliderTime ); - - keyframePanel = new KeyFramePanel( sliderTime ); - keyframePanel.setMinimumSize( new Dimension( 36, 26 ) ); - keyframePanel.setPreferredSize( new Dimension( 36, 26 ) ); - timeKeyframePanel.add( keyframePanel ); - add( display, BorderLayout.CENTER ); if ( numTimepoints > 1 ) - add( sliderPanel, BorderLayout.SOUTH ); + add( sliderTime, BorderLayout.SOUTH ); visibilityAndGrouping = new VisibilityAndGrouping( state ); visibilityAndGrouping.addUpdateListener( this ); @@ -472,45 +352,10 @@ public class ViewerPanel extends JPanel implements OverlayRenderer, TransformLis painterThread.start(); } - public void stopPlayExecuter() - { - playTimer.stop(); - } - - private void onPlayTimerTick( final ActionEvent event ) - { - final int changeValue = Integer.signum( sliderPlay.getValue() ); - final int newTimepoint = state.getCurrentTimepoint() + changeValue; - final int numTimepoints = state.getNumTimepoints(); - - if ( newTimepoint < 0 ) - { - setTimepoint( 0 ); - stopPlayExecuter(); - sliderPlay.setValue( 0 ); - } - else if ( newTimepoint > numTimepoints - 1 ) - { - setTimepoint( numTimepoints - 1 ); - stopPlayExecuter(); - sliderPlay.setValue( 0 ); - } - else - { - setTimepoint( newTimepoint ); - } - } - - public void setKeyframeButtonEnable( final boolean enable ) - { - previousKeyframeButton.setEnabled( enable ); - addKeyframeButton.setEnabled( enable ); - nextKeyframeButton.setEnabled( enable ); - } - public KeyFramePopupMenu getKeyFramePopupMenu() // TODO: remove! { - return this.keyframePanel.getKeyFramePopupMenuPopupMenu(); + // TODO: FIX + return ( ( DynamicBookmarksTimeSlider ) sliderTime ).keyframePanel.getKeyFramePopupMenuPopupMenu(); } public void addSource( final SourceAndConverter< ? > sourceAndConverter ) @@ -963,16 +808,8 @@ public class ViewerPanel extends JPanel implements OverlayRenderer, TransformLis */ public synchronized void setActiveBookmark( final Bookmark bookmark ) { - final Bookmark previousBookmark = this.state.getActiveBookmark(); - this.state.setActiveBookmark( bookmark ); - - final boolean enableKeyframeButtons = bookmark instanceof DynamicBookmark; - setKeyframeButtonEnable( enableKeyframeButtons ); - - if ( bookmark instanceof DynamicBookmark ) - keyframePanel.setDynamicBookmark( ( DynamicBookmark ) bookmark ); - else - keyframePanel.setDynamicBookmark( null ); + final Bookmark previousBookmark = state.getActiveBookmark(); + state.setActiveBookmark( bookmark ); for ( final ActiveBookmarkChangedListener l : this.activeBookmarkChangedListeners ) l.activeBookmarkChanged( previousBookmark, bookmark ); @@ -1412,4 +1249,190 @@ public class ViewerPanel extends JPanel implements OverlayRenderer, TransformLis listeners.add( listener ); } } + + // TODO: move to separate file + public static class DynamicBookmarksTimeSlider extends TimeSlider implements ActiveBookmarkChangedListener + { + private final CopyOnWriteArrayList< TimePointListener > listeners; + + private final JSlider timeSlider; + + private final JButton previousKeyframeButton; + + private final JButton addKeyframeButton; + + private final JButton nextKeyframeButton; + + private final JPlaySlider sliderPlay; + + private final KeyFramePanel keyframePanel; + + private final Timer playTimer = new Timer( 0, this::onPlayTimerTick ); + + private final ViewerPanel viewer; + + public DynamicBookmarksTimeSlider( final ActionMap actionMap, final ViewerPanel viewer ) + { + super(); + this.viewer = viewer; + viewer.addActiveBookmarkChangedListener( this ); + + listeners = new CopyOnWriteArrayList<>(); + + previousKeyframeButton = new JButton( "<<" ); + previousKeyframeButton.setToolTipText( "Go to previous keyframe" ); + previousKeyframeButton.addActionListener( e -> { + final Action action = actionMap.get( BigDataViewerActions.PREVIOUS_KEYFRAME ); + if ( action != null ) + action.actionPerformed( e ); + } ); + previousKeyframeButton.setEnabled( false ); + + addKeyframeButton = new JButton( "+" ); + addKeyframeButton.setToolTipText( "Add a new keyframe" ); + addKeyframeButton.addActionListener( e -> { + final Action action = actionMap.get( BigDataViewerActions.ADD_KEYFRAME ); + if ( action != null ) + action.actionPerformed( e ); + } ); + addKeyframeButton.setEnabled( false ); + + nextKeyframeButton = new JButton( ">>" ); + nextKeyframeButton.setToolTipText( "Go to next keyframe" ); + nextKeyframeButton.addActionListener( e -> { + final Action action = actionMap.get( BigDataViewerActions.NEXT_KEYFRAME ); + if ( action != null ) + action.actionPerformed( e ); + } ); + nextKeyframeButton.setEnabled( false ); + + sliderPlay = new JPlaySlider(); + sliderPlay.setPreferredSize( new Dimension( 200, 50 ) ); + sliderPlay.setMinimumSize( new Dimension( 200, 50 ) ); + sliderPlay.setMaximumSize( new Dimension( 200, 50 ) ); + sliderPlay.setAlignmentX( Component.LEFT_ALIGNMENT ); + sliderPlay.addChangeListener( e -> { + // if ( !e.getSource().equals( sliderPlay ) ) + // return; + + if ( sliderPlay.getValue() == 0 ) + { + stopPlayExecuter(); + return; + } + + final int periode = 1000 / ( 1 * Math.abs( sliderPlay.getValue() ) ); + playTimer.setDelay( periode ); + playTimer.start(); + } ); + sliderPlay.addComponentListener( new ComponentAdapter() + { + @Override + public void componentHidden( final ComponentEvent e ) + { + stopPlayExecuter(); + } + } ); + + timeSlider = new JSlider( SwingConstants.HORIZONTAL ); + timeSlider.addChangeListener( new ChangeListener() + { + @Override + public void stateChanged( final ChangeEvent e ) + { + for ( final TimePointListener l : listeners ) + l.timePointChanged( timeSlider.getValue() ); + } + } ); + timeSlider.setSnapToTicks( true ); + + keyframePanel = new KeyFramePanel( timeSlider ); + keyframePanel.setMinimumSize( new Dimension( 36, 26 ) ); + keyframePanel.setPreferredSize( new Dimension( 36, 26 ) ); + + final JPanel timeKeyframePanel = new JPanel(); + timeKeyframePanel.setBorder( new EmptyBorder( 5, 0, 5, 0 ) ); + timeKeyframePanel.setLayout( new BoxLayout( timeKeyframePanel, BoxLayout.Y_AXIS ) ); + timeKeyframePanel.add( timeSlider ); + timeKeyframePanel.add( keyframePanel ); + + setLayout( new BoxLayout( this, BoxLayout.X_AXIS ) ); + add( previousKeyframeButton ); + add( Box.createRigidArea( new Dimension( 5, 5 ) ) ); + add( addKeyframeButton ); + add( Box.createRigidArea( new Dimension( 5, 5 ) ) ); + add( nextKeyframeButton ); + add( Box.createRigidArea( new Dimension( 5, 5 ) ) ); + add( sliderPlay ); + add( Box.createRigidArea( new Dimension( 5, 5 ) ) ); + add( timeKeyframePanel ); + } + + @Override + public void updateNumTimepoints( final int currentTimepoint, final int numTimepoints ) + { + timeSlider.setModel( new DefaultBoundedRangeModel( currentTimepoint, 0, 0, numTimepoints - 1 ) ); + } + + @Override + public void setTimepoint( final int timepoint ) + { + timeSlider.setValue( timepoint ); + } + + @Override + public synchronized void addTimePointListener( final TimePointListener listener ) + { + listeners.add( listener ); + } + + private void onPlayTimerTick( final ActionEvent event ) + { + final int changeValue = Integer.signum( sliderPlay.getValue() ); + final ViewerState state = viewer.getState(); + final int newTimepoint = state.getCurrentTimepoint() + changeValue; + final int numTimepoints = state.getNumTimepoints(); + + if ( newTimepoint < 0 ) + { + setTimepoint( 0 ); + stopPlayExecuter(); + sliderPlay.setValue( 0 ); + } + else if ( newTimepoint > numTimepoints - 1 ) + { + setTimepoint( numTimepoints - 1 ); + stopPlayExecuter(); + sliderPlay.setValue( 0 ); + } + else + { + setTimepoint( newTimepoint ); + } + } + + public void stopPlayExecuter() + { + playTimer.stop(); + } + + public void setKeyframeButtonEnable( final boolean enable ) + { + previousKeyframeButton.setEnabled( enable ); + addKeyframeButton.setEnabled( enable ); + nextKeyframeButton.setEnabled( enable ); + } + + @Override + public void activeBookmarkChanged( final Bookmark TODO_REMOVE_previousBookmark, final Bookmark bookmark ) + { + final boolean enableKeyframeButtons = bookmark instanceof DynamicBookmark; + setKeyframeButtonEnable( enableKeyframeButtons ); + + if ( bookmark instanceof DynamicBookmark ) + keyframePanel.setDynamicBookmark( ( DynamicBookmark ) bookmark ); + else + keyframePanel.setDynamicBookmark( null ); + } + } } -- GitLab