package org.apollo.gui; import org.apollo.audio.util.Timeline; import org.apollo.mvc.Observer; import org.apollo.mvc.Subject; import org.apollo.mvc.SubjectChangedEvent; import org.expeditee.core.Colour; import org.expeditee.core.Dimension; import org.expeditee.core.Fill; import org.expeditee.core.Point; import org.expeditee.core.Stroke; import org.expeditee.core.bounds.AxisAlignedBoxBounds; import org.expeditee.gio.EcosystemManager; import org.expeditee.gio.GraphicsManager; import org.expeditee.gio.InputManager.WindowEventListener; import org.expeditee.gio.InputManager.WindowEventType; import org.expeditee.gui.Browser; import org.expeditee.gui.DisplayController; /** * The global timeline on the current overdubbed frame * * @author Brook Novak * */ public class OverdubbedFrameTimeAxis implements Observer { //, DisplayIOObserver { private TimeAxis timeAxis = null; private AxisAlignedBoxBounds lastInvalidated; private Timeline lastTimeline = null; private static OverdubbedFrameTimeAxis instance = new OverdubbedFrameTimeAxis(); private static final int GLOBAL_TIMELINE_HEIGHT = 30; private static final Colour GLOBAL_TIMELINE_BACKCOLOR = Colour.FromRGBA255(220, 220, 220, 100); private static final Colour GLOBAL_EMPTY_TIMELINE_BACKCOLOR = Colour.FromRGBA255(240, 240, 240, 100); public static final Stroke TRACK_TIMELINE_STROKE = new Stroke(1.0f, Stroke.CAP.SQUARE, Stroke.JOIN.BEVEL, new float[] { 5.0f, 5.0f }, 0.0f); private static final Stroke TIMELINE_BORDER_STROKE = new Stroke(1.0f); /** * Singleton constructor, */ private OverdubbedFrameTimeAxis() { FrameLayoutDaemon.getInstance().addObserver(this); //DisplayIO.addDisplayIOObserver(this); // Listen for resize events EcosystemManager.getInputManager().addWindowEventListener(new WindowEventListener() { @Override public void onWindowEvent(WindowEventType type) { if (type == WindowEventType.WINDOW_RESIZED) updateAxis(); } }); } /** * * @return * The singleton instance. */ public static OverdubbedFrameTimeAxis getInstance() { return instance; } public void setObservedSubject(Subject parent) { } public Subject getObservedSubject() { return FrameLayoutDaemon.getInstance(); } public void modelChanged(Subject source, SubjectChangedEvent event) { updateAxis(); } /*public void frameChanged() { updateAxis(); }*/ private void updateAxis() { if (Browser._theBrowser == null) return; lastTimeline = FrameLayoutDaemon.getInstance().getLastComputedTimeline(); if (lastTimeline == null || FrameLayoutDaemon.getInstance().getTimelineOwner() != DisplayController.getCurrentFrame()) { // The frame layout daemon only lays out frames once - unless the user rearranges tracks // on a frame then the daemon we re-calc the timeline... thus a timeline must be infferred lastTimeline = FrameLayoutDaemon.inferTimeline(DisplayController.getCurrentFrame()); if (lastTimeline == null) { // no widgets if (timeAxis != null && lastInvalidated != null) { DisplayController.invalidateArea(lastInvalidated); // old position } timeAxis = null; return; } } timeAxis = new TimeAxis(); timeAxis.setAxis( 0, lastTimeline.getRunningTime(), -1, lastTimeline.getRunningTime(), lastTimeline.getPixelWidth()); AxisAlignedBoxBounds newBounds = getCurrentTimelineArea(); if (lastInvalidated != null && !lastInvalidated.equals(newBounds)) { DisplayController.invalidateArea(lastInvalidated); // old position } DisplayController.invalidateArea(newBounds); lastInvalidated = newBounds; DisplayController.requestRefresh(true); } public AxisAlignedBoxBounds getCurrentTimelineArea() { assert(Browser._theBrowser != null); int y = EcosystemManager.getGraphicsManager().getWindowSize().getHeight() - GLOBAL_TIMELINE_HEIGHT; if (!DisplayController.isAudienceMode()) { y -= DisplayController.getMessageBayPaintArea().getHeight(); } if (y < 0) y = 0; return new AxisAlignedBoxBounds(0, y, EcosystemManager.getGraphicsManager().getWindowSize().getWidth(), GLOBAL_TIMELINE_HEIGHT); } public void paint() { if (Browser._theBrowser == null) return; if (timeAxis != null && lastTimeline != null) { GraphicsManager gm = EcosystemManager.getGraphicsManager(); AxisAlignedBoxBounds r = getCurrentTimelineArea(); gm.drawRectangle(new Point(0, r.getMinY()), new Dimension(EcosystemManager.getGraphicsManager().getWindowSize().getWidth(), r.getHeight()), 0.0, new Fill(GLOBAL_EMPTY_TIMELINE_BACKCOLOR), null, null, null); timeAxis.paint( lastTimeline.getInitiationXPixel(), r.getMinY(), r.getHeight(), GLOBAL_TIMELINE_BACKCOLOR); gm.drawLine(new Point(0, r.getMinY()), new Point(EcosystemManager.getGraphicsManager().getWindowSize().getWidth(), r.getMinY()), Colour.DARK_GREY, TIMELINE_BORDER_STROKE); } } public Timeline getLastTimeline() { return lastTimeline; } public TimeAxis getTimeAxis() { return timeAxis; } }