package nodebox.client;
import nodebox.ui.DraggableNumber;
import nodebox.ui.NButton;
import nodebox.ui.Theme;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.io.IOException;
import java.io.InputStream;
public class AnimationBar extends JPanel implements ChangeListener {
private static final int ANIMATION_BAR_HEIGHT = 27;
static {
try {
animationBackground = ImageIO.read(AnimationBar.class.getResourceAsStream("/animation-background.png"));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static final Image animationBackground;
private final NodeBoxDocument document;
private final DraggableNumber frameNumber;
private final NButton playButton;
private double frame;
public AnimationBar(final NodeBoxDocument document) {
super(new FlowLayout(FlowLayout.LEADING, 5, 0));
setPreferredSize(new Dimension(100, ANIMATION_BAR_HEIGHT));
setMinimumSize(new Dimension(100, ANIMATION_BAR_HEIGHT));
setMaximumSize(new Dimension(100, ANIMATION_BAR_HEIGHT));
this.document = document;
// We use a number of tricks here to make the frame number line up with the buttons.
// - We use a panel with a flow layout so we can set a border. (Setting it directly on the DraggableNumber does not work)
// - We use an inset border with a positive top margin (the actual space we want to move) and a negative bottom margin
// (to compensate for the effect).
JPanel frameNumberPanel = new JPanel();
frameNumberPanel.setOpaque(false);
frameNumberPanel.setLayout(new FlowLayout(FlowLayout.LEADING, 0, 0));
frameNumberPanel.setBorder(new Theme.InsetsBorder(5, 0, -4, 0));
frameNumber = new DraggableNumber();
frameNumber.addChangeListener(this);
frameNumberPanel.add(frameNumber);
add(frameNumberPanel);
playButton = new NButton("Play", getImageStream("/animation-play.png"), getImageStream("/animation-stop.png"));
playButton.setToolTipText("Play Animation");
playButton.setActionMethod(this, "playAnimation");
forcePlayButtonWidth(52);
NButton rewindButton = new NButton("Rewind", getImageStream("/animation-rewind.png"));
rewindButton.setToolTipText("Rewind Animation");
rewindButton.setActionMethod(this, "rewindAnimation");
add(playButton);
add(rewindButton);
setFrame(1);
}
private InputStream getImageStream(String name) {
return getClass().getResourceAsStream(name);
}
public void setFrame(double frame) {
this.frame = frame;
frameNumber.setValue(frame);
}
public void stateChanged(ChangeEvent changeEvent) {
frame = frameNumber.getValue();
document.setFrame(frame);
}
public void toggleAnimation() {
if (playButton.isChecked())
stopAnimation();
else
playAnimation();
}
public void playAnimation() {
if (!playButton.isChecked()) playButton.setChecked(true);
document.playAnimation();
playButton.setText("Pause");
playButton.setToolTipText("Pause Animation");
playButton.setActionMethod(this, "stopAnimation");
forcePlayButtonWidth(52);
}
public void stopAnimation() {
if (playButton.isChecked()) playButton.setChecked(false);
document.stopAnimation();
playButton.setText("Play");
playButton.setToolTipText("Play Animation");
playButton.setActionMethod(this, "playAnimation");
forcePlayButtonWidth(52);
}
public void rewindAnimation() {
stopAnimation();
document.rewindAnimation();
}
private void forcePlayButtonWidth(int width) {
Dimension d = new Dimension(width, NButton.BUTTON_HEIGHT);
playButton.setSize(d);
playButton.setPreferredSize(d);
playButton.setMinimumSize(d);
playButton.setMaximumSize(d);
}
@Override
protected void paintComponent(Graphics g) {
g.drawImage(animationBackground, 0, 0, getWidth(), ANIMATION_BAR_HEIGHT, null);
}
}