/* Copyright 2008-2010 Gephi Authors : Julian Bilcke <julian.bilcke@gephi.org> Website : http://www.gephi.org This file is part of Gephi. Gephi is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Gephi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Gephi. If not, see <http://www.gnu.org/licenses/>. */ package org.gephi.desktop.timeline; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import javax.swing.Timer; import javax.swing.event.ChangeEvent; import org.gephi.timeline.api.TimelineAnimator; import org.gephi.timeline.api.TimelineAnimatorListener; import org.gephi.timeline.api.TimelinePlayMode; /** * * @author Julian Bilcke */ public class TimelineAnimatorImpl implements TimelineAnimator, ActionListener { //Listeners private List<TimelineAnimatorListener> listeners; // private Timer timer; private double relativeSelectionStart; private double relativeSelectionEnd; private TimelinePlayMode playMode; private double stepByTick; private AtomicBoolean paused; public TimelineAnimatorImpl() { listeners = new ArrayList<TimelineAnimatorListener>(); playMode = playMode.OLDEST; stepByTick = 0.01; paused = new AtomicBoolean(true); relativeSelectionStart = 0.0; relativeSelectionEnd = 1.0; } public synchronized void setInterval(double from, double to) { setFrom(from); setTo(to); } public synchronized void setTo(double to) { if (to > 1.0) { relativeSelectionStart = 1.0; } else if (to <= 0.0) { relativeSelectionStart = 0.0; } else { relativeSelectionStart = to; } } public synchronized void setFrom(double from) { if (from > 1.0) { relativeSelectionEnd = 1.0; } else if (from <= 0.0) { relativeSelectionEnd = 0.0; } else { relativeSelectionEnd = from; } } public synchronized double getFrom() { return relativeSelectionStart; } public synchronized double getTo() { return relativeSelectionEnd; } public synchronized void play() { timer = new Timer(100, this); // 0.1 timer.setInitialDelay(1900); // 1.9 sec paused.set(false); timer.start(); } public synchronized void play(TimelinePlayMode playMode) { setTimelinePlayMode(playMode); play(); } public synchronized boolean togglePause() { boolean p = !paused.get(); paused.set(p); return p; } public synchronized void setPause(boolean p) { paused.set(p); } public synchronized void stop() { timer.stop(); } public synchronized boolean isPaused() { return paused.get(); } public synchronized boolean isStopped() { return !timer.isRunning(); } public synchronized void setTimelinePlayMode(TimelinePlayMode playMode) { this.playMode = playMode; } public synchronized TimelinePlayMode getTimelinePlayMode() { return playMode; } public synchronized void setStepByTick(double s) { stepByTick = s; } public synchronized double getStepByTick() { return stepByTick; } public void addListener(TimelineAnimatorListener listener) { if (!listeners.contains(listener)) { listeners.add(listener); } } public void removeListener(TimelineAnimatorListener listener) { listeners.remove(listener); } public void fireChangeEvent() { ChangeEvent evt = new ChangeEvent(this); for (TimelineAnimatorListener listener : listeners) { listener.timelineAnimatorChanged(evt); } } public synchronized void actionPerformed(ActionEvent ae) { if (paused.get()) return; double s = getStepByTick(); double f = getFrom(); double t = getTo(); switch(getTimelinePlayMode()) { case YOUNGEST: f += s; if (f >= 0.95) { stop(); f = 0.95f; } break; case BOTH: f += s; t += s; if (t >= 1.0) { stop(); t = 1.0f; f -= s; } break; case OLDEST: t += s; if (t >= 1.0) { stop(); t = 1.0f; } break; } setInterval(f, t); fireChangeEvent(); } }