Index: trunk/src/org/apollo/widgets/LinkedTrack.java
===================================================================
--- trunk/src/org/apollo/widgets/LinkedTrack.java	(revision 1006)
+++ trunk/src/org/apollo/widgets/LinkedTrack.java	(revision 1102)
@@ -1,6 +1,4 @@
 package org.apollo.widgets;
 
-import java.awt.Color;
-import java.awt.Font;
 import java.awt.FontMetrics;
 import java.awt.GradientPaint;
@@ -8,8 +6,5 @@
 import java.awt.Graphics2D;
 import java.awt.Paint;
-import java.awt.Point;
 import java.awt.Rectangle;
-import java.awt.Shape;
-import java.awt.Stroke;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
@@ -19,5 +14,4 @@
 import java.awt.event.MouseListener;
 import java.awt.event.MouseMotionListener;
-import java.awt.geom.Area;
 import java.awt.geom.Rectangle2D;
 import java.util.LinkedList;
@@ -29,7 +23,7 @@
 import javax.swing.SwingUtilities;
 
+import org.apollo.ApolloGestureActions;
+import org.apollo.ApolloKBMGestureTranslator;
 import org.apollo.ApolloSystem;
-import org.apollo.AudioFrameKeyboardActions;
-import org.apollo.AudioFrameMouseActions;
 import org.apollo.audio.ApolloSubjectChangedEvent;
 import org.apollo.audio.SampledAudioManager;
@@ -62,23 +56,37 @@
 import org.apollo.util.Mutable;
 import org.apollo.util.ODFrameHeirarchyFetcher;
-import org.apollo.util.PopupReaper;
 import org.apollo.util.StringEx;
 import org.apollo.util.ODFrameHeirarchyFetcher.ODFrameReceiver;
+import org.expeditee.core.Clip;
+import org.expeditee.core.Colour;
+import org.expeditee.core.EnforcedClipStack.EnforcedClipKey;
+import org.expeditee.core.Fill;
+import org.expeditee.core.Font;
+import org.expeditee.core.Line;
+import org.expeditee.core.Point;
+import org.expeditee.core.Stroke;
+import org.expeditee.core.TextLayout;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.GraphicsManager;
+import org.expeditee.gio.TextLayoutManager;
+import org.expeditee.gio.swing.MouseEventRouter;
+import org.expeditee.gio.swing.SwingConversions;
+import org.expeditee.gio.swing.SwingMiscManager;
 import org.expeditee.gui.Browser;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameGraphics;
 import org.expeditee.gui.FrameUtils;
 import org.expeditee.gui.MessageBay;
-import org.expeditee.gui.MouseEventRouter;
 import org.expeditee.gui.PopupManager;
 import org.expeditee.items.Item;
 import org.expeditee.items.ItemParentStateChangedEvent;
 import org.expeditee.items.Text;
-import org.expeditee.items.widgets.InteractiveWidget;
 import org.expeditee.items.widgets.InteractiveWidgetInitialisationFailedException;
 import org.expeditee.items.widgets.InteractiveWidgetNotAvailableException;
-
-public class LinkedTrack extends InteractiveWidget implements ODFrameReceiver, Observer, MultitrackLoadListener, PlaybackClockListener {
+import org.expeditee.items.widgets.SwingWidget;
+import org.expeditee.items.widgets.Widget;
+
+public class LinkedTrack extends SwingWidget implements ODFrameReceiver, Observer, MultitrackLoadListener, PlaybackClockListener {
 	
 	private String virtualFilename; // immutable 
@@ -92,5 +100,4 @@
 	
 	private PlaybackPopup playbackControlPopup = null;
-
 
 	// private SoundDeskPopup soundDeskPopup = null;
@@ -116,22 +123,22 @@
 	private String abortMessage = null;
 	
-	private static final Color FAILED_MESSAGE_COLOR = Color.RED;
+	private static final Colour FAILED_MESSAGE_COLOR = Colour.RED;
 	private static final Font MESSAGE_FONT = TrackWidgetCommons.FREESPACE_TRACKNAME_FONT;
-	private static final Font HELPER_FONT = new Font("Arial", Font.BOLD, 12);
-	
-	private static final Color[] TRACK_COLOR_WHEEL = { 
-							new Color(66, 145, 255), 
-							new Color(255, 163, 33), 
-							new Color(155, 227, 48), 
+	private static final Font HELPER_FONT = new Font("Arial", Font.Style.BOLD, 12);
+	
+	private static final Colour[] TRACK_COLOR_WHEEL = { 
+							Colour.FromRGB255(66, 145, 255), 
+							Colour.FromRGB255(255, 163, 33), 
+							Colour.FromRGB255(155, 227, 48)
 						};
-	private static final Color TRACK_LOAD_COLOR = Color.BLACK;
-	private static final Color TRACK_FAIL_COLOR = Color.RED;
-	
-	private static final Color SELECTION_COLOR = new Color(0,0,0,100);
+	private static final Colour TRACK_LOAD_COLOR = Colour.BLACK;
+	private static final Colour TRACK_FAIL_COLOR = Colour.RED;
+	
+	private static final Colour SELECTION_COLOR = Colour.FromRGBA255(0,0,0,100);
 
 	private static final Stroke TRACK_BORDER = Strokes.SOLID_1;
 	private static final Stroke TRACK_SELECTED_BORDER = Strokes.SOLID_2;
-	private static final Color TRACK_BORDER_COLOR = Color.BLACK;
-	private static final Color TRACK_SELECTED_BORDER_COLOR = new Color(253, 255, 201);
+	private static final Colour TRACK_BORDER_COLOR = Colour.BLACK;
+	private static final Colour TRACK_SELECTED_BORDER_COLOR = Colour.FromRGB255(253, 255, 201);
 	
 	
@@ -154,5 +161,6 @@
 	 * @param args
 	 */
-	public LinkedTrack(Text source, String[] args) {
+	public LinkedTrack(Text source, String[] args)
+	{
 		super(source, new JPanel(), 
 				100, -1, 
@@ -187,6 +195,6 @@
 		playbackControlPopup = new PlaybackPopup();
 		
-		nameLabel = new EmulatedTextItem(_swingComponent, new Point(10, 20));
-		nameLabel.setBackgroundColor(Color.WHITE);	
+		nameLabel = new EmulatedTextItem("", new Point(10, 20));
+		nameLabel.setBackgroundColor(Colour.WHITE);	
 		
 		String metaName = getStrippedDataString(TrackWidgetCommons.META_NAME_TAG);
@@ -210,8 +218,4 @@
 			public void keyPressed(KeyEvent e) {
 				if ((state != PLAYING && state != STOPPED) || e.isControlDown()) return;
-				if (nameLabel.onKeyPressed(e, _swingComponent)) {
-					e.consume();
-					return;
-				}
 			}
 
@@ -219,12 +223,13 @@
 				if ((state != PLAYING && state != STOPPED)) return;
 				else if (e.isControlDown()) {
-					if (e.getKeyCode() == KeyEvent.VK_LEFT || e.getKeyCode() == KeyEvent.VK_RIGHT) {
-						AudioFrameKeyboardActions.adjustInitationTime(LinkedTrack.this, e.getKeyCode() == KeyEvent.VK_LEFT);
-					} else if (e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_DOWN) {
-						AudioFrameKeyboardActions.adjustVerticlePosition(LinkedTrack.this, e.getKeyCode() == KeyEvent.VK_UP);
+					if (e.getKeyCode() == KeyEvent.VK_LEFT) {
+						ApolloGestureActions.adjustInitiationTime(LinkedTrack.this, -ApolloKBMGestureTranslator.TRACK_WIDGET_TIMELINE_ADJUSTMENT);
+					} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
+						ApolloGestureActions.adjustInitiationTime(LinkedTrack.this, ApolloKBMGestureTranslator.TRACK_WIDGET_TIMELINE_ADJUSTMENT);
+					} else if (e.getKeyCode() == KeyEvent.VK_UP) {
+						ApolloGestureActions.adjustVerticalPosition(LinkedTrack.this, -ApolloKBMGestureTranslator.TRACK_WIDGET_VERTICAL_ADJUSTMENT);
+					} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
+						ApolloGestureActions.adjustVerticalPosition(LinkedTrack.this, ApolloKBMGestureTranslator.TRACK_WIDGET_VERTICAL_ADJUSTMENT);
 					}
-				} else if (nameLabel.onKeyReleased(e, _swingComponent)) {
-					e.consume();
-					return;
 				}
 			}
@@ -234,5 +239,4 @@
 			
 		});
-		
 		
 		updateBorderColor();
@@ -346,5 +350,5 @@
 			playbackControlPopup.stopButton.setEnabled(false);
 			playbackControlPopup.playPauseButton.setEnabled(true);
-			playbackControlPopup.playPauseButton.setIcon(IconRepository.getIcon("play.png"));
+			SwingMiscManager.setJButtonIcon(playbackControlPopup.playPauseButton, IconRepository.getIcon("play.png"));
 		
 
@@ -363,5 +367,5 @@
 			playbackControlPopup.rewindButton.setEnabled(false);
 			playbackControlPopup.playPauseButton.setEnabled(true);
-			playbackControlPopup.playPauseButton.setIcon(IconRepository.getIcon("pause.png"));
+			SwingMiscManager.setJButtonIcon(playbackControlPopup.playPauseButton, IconRepository.getIcon("pause.png"));
 
 			setWidgetEdgeThickness(TrackWidgetCommons.PLAYING_TRACK_EDGE_THICKNESS);
@@ -408,5 +412,5 @@
 		
 		invalidateSelf();
-		FrameGraphics.refresh(true);
+		DisplayController.requestRefresh(true);
 	}
 	
@@ -528,5 +532,5 @@
 			for (Track t : tracks) setTrackState(t, TRACKSTATE_READY);
 			invalidateSelf();
-			FrameGraphics.refresh(true);
+			DisplayController.requestRefresh(true);
 			break;
 		case MultitrackLoadListener.LOAD_FAILED_BAD_GRAPH:
@@ -552,5 +556,5 @@
 			setTrackState((String) state, TRACKSTATE_READY);
 			invalidateSelf();
-			FrameGraphics.refresh(true);
+			DisplayController.requestRefresh(true);
 			break;
 
@@ -611,5 +615,5 @@
 	 */
 	@Override
-	public InteractiveWidget copy() 
+	public Widget copy() 
 		throws InteractiveWidgetNotAvailableException, InteractiveWidgetInitialisationFailedException {
 		
@@ -632,5 +636,5 @@
 		source.setData(data);
 		
-		return InteractiveWidget.createWidget((Text)source);
+		return Widget.createWidget((Text)source);
 
 	}
@@ -640,5 +644,6 @@
 	 */
 	@Override
-	protected void onParentStateChanged(int eventType) {
+	protected void onParentStateChanged(int eventType)
+	{
 		super.onParentStateChanged(eventType);
 		
@@ -667,5 +672,5 @@
 				boolean inferInitTime = true;
 	
-				if (AudioFrameMouseActions.isYAxisRestictionOn()) {
+				if (ApolloGestureActions.isYAxisRestictionOn()) {
 					Mutable.Long ms = getInitiationTimeFromMeta();
 					if (ms != null) {
@@ -683,7 +688,7 @@
 				
 				// Also must not set initiation time if the frame is simply being displayed
-				inferInitTime &= 
-					(AudioFrameMouseActions.isMouseAnchoring() || AudioFrameMouseActions.isMouseStamping());
-
+				//inferInitTime &= (AudioFrameMouseActions.isMouseAnchoring() || AudioFrameMouseActions.isMouseStamping());
+				inferInitTime &= (eventType == ItemParentStateChangedEvent.EVENT_TYPE_ADDED);
+				
 				if (inferInitTime) {
 					initTime = Mutable.createMutableLong(FrameLayoutDaemon.getInstance().getMSAtX(getX(), parent));
@@ -731,5 +736,5 @@
 			if (MouseEventRouter.getCurrentMouseEvent() != null &&
 					MouseEventRouter.getCurrentMouseEvent().getButton() == MouseEvent.BUTTON2) {
-				Frame suspended = DisplayIO.getCurrentFrame();
+				Frame suspended = DisplayController.getCurrentFrame();
 				if (suspended != null) {
 					FrameLayoutDaemon.getInstance().suspendLayout(suspended, this);
@@ -755,5 +760,5 @@
 				public void run() {
 					invalidateSelf();
-					FrameGraphics.refresh(true);
+					DisplayController.requestRefresh(true);
 				}
 			}); // NOTE TO REPEAT: Pick up a linked track and delete it directly from freespace
@@ -946,29 +951,18 @@
 	 */
 	@Override
-	public void paint(Graphics g) {
+	public void paintSwingWidget(Graphics2D gm) {
 		
 		if (Browser._theBrowser == null) return;
 		
+		GraphicsManager g = EcosystemManager.getGraphicsManager();
+		
 		// Ensure that load bar or any text doesn't spill over widgets invalidation area
-		Area clip = FrameGraphics.getCurrentClip();
-		
-		Shape clipBackUp = g.getClip();
-		
-		Area tmpClip = (clip != null) ? clip : 
-			new Area(new Rectangle(0, 0, 
-					Browser._theBrowser.getContentPane().getWidth(), 
-					Browser._theBrowser.getContentPane().getHeight()));
-		
-		tmpClip.intersect(new Area(getBounds()));
-
-		if (tmpClip.isEmpty()) return;
-
-		g.setClip(tmpClip);
+		EnforcedClipKey clipKey = g.pushClip(new Clip(getBounds()));
 		
 		// Paint backing
-		g.setColor(SampledTrackGraphView.DEFAULT_BACKGROUND_COLOR);
-		g.fillRect(getX(), getY(), getWidth(), getHeight());
+		g.drawRectangle(getBounds(), 0.0, new Fill(SwingConversions.fromSwingColor(SampledTrackGraphView.DEFAULT_BACKGROUND_COLOR)), null, null, null);
 		
 		String centralizedMessage = null;
+		Colour colour = null;
 
 		// Render according to the currently widget state
@@ -978,24 +972,20 @@
 
 		case FAILED_STATE: 
+			centralizedMessage = failMessage;
+			assert(failMessage != null);
+			colour = FAILED_MESSAGE_COLOR;
+			break;
 		case EMPTY_STATE:
+			if (getLink() == null) {
+				centralizedMessage = "Click to create";
+			} else {
+				centralizedMessage = "Nothing to play";
+			}
+			
+			colour = Colour.DARK_GREY;
+			break;
 		case LOADING_TRACK_GRAPH:
-			
-			if (state == FAILED_STATE) {
-				centralizedMessage = failMessage;
-				assert(failMessage != null);
-				g.setColor(FAILED_MESSAGE_COLOR);
-			} else if (state == LOADING_TRACK_GRAPH){
-				centralizedMessage = "Loading...";
-				g.setColor(Color.DARK_GRAY);
-			} else { // empty
-				if (getLink() == null) {
-					centralizedMessage = "Click to create";
-				} else {
-					centralizedMessage = "Nothing to play";
-				}
-				
-				g.setColor(Color.DARK_GRAY);
-			}
-
+			centralizedMessage = "Loading...";
+			colour = Colour.DARK_GREY;
 			break;
 			
@@ -1008,12 +998,12 @@
 
 			for (Track track : tracks) {
-				track.paintTrackArea((Graphics2D)g, x, y);
+				track.paintTrackArea(x, y);
 				if (track.isSelected) {
 					selected = track;
 				} else {
-					track.paintTrackBorder(g, x, y);
+					track.paintTrackBorder(x, y);
 					
 					if (track.area.height > 15) { // don't clutter up busy linked tracks
-						drawTrackName(track, g, Color.DARK_GRAY);
+						drawTrackName(track, Colour.DARK_GREY);
 					}
 	
@@ -1025,6 +1015,6 @@
 			// the selected border is drawn last
 			if (selected != null) {
-				selected.paintTrackBorder(g, x, y);
-				drawTrackName(selected, g, Color.BLACK);
+				selected.paintTrackBorder(x, y);
+				drawTrackName(selected, Colour.BLACK);
 			}
 
@@ -1038,5 +1028,5 @@
 				
 				centralizedMessage = "Loading dubs...";
-				g.setColor(Color.BLACK);
+				colour = Colour.BLACK;
 				
 			} else {
@@ -1045,13 +1035,11 @@
 				int selLeftX = XatFrame(selectionStart);
 				if (selectionLength > 1) {
-					g.setColor(SELECTION_COLOR);
-					g.fillRect(	getX() + selLeftX, 
-								getY(), 
-								XatFrame(selectionStart + selectionLength) - selLeftX, 
-								getHeight());
+					colour = SELECTION_COLOR;
+					AxisAlignedBoxBounds b = new AxisAlignedBoxBounds(	getX() + selLeftX, 
+							getY(), 
+							XatFrame(selectionStart + selectionLength) - selLeftX, 
+							getHeight());
+					g.drawRectangle(b, 0.0, new Fill(colour), null, null, null);
 				}
-				
-				// Draw selection start bar
-				((Graphics2D)g).setStroke(SampledTrackGraphView.GRAPH_BAR_STROKE);
 				
 				// Note that if the start line is near the edges of the panel it can be concealed - thus
@@ -1063,11 +1051,11 @@
 					x = getWidth() - 1;
 				}
-				
-				g.setColor(Color.RED);
-				g.drawLine(
+				colour = Colour.RED;
+				Line l = new Line(
 						x, 
 						getY(), 
 						x,
 						getY() + getHeight());
+				g.drawLine(l, colour, SwingConversions.fromSwingStroke(SampledTrackGraphView.GRAPH_BAR_STROKE));
 	
 				
@@ -1076,14 +1064,11 @@
 					
 					x = XatFrame(currentPlaybackFramePosition) + getX();
-					
-					((Graphics2D)g).setStroke(SampledTrackGraphView.GRAPH_BAR_STROKE);
-					g.setColor(SampledTrackGraphView.PLAYBACK_BAR_COLOR);
-					g.drawLine(x, getY(), x, getY() + getHeight());
+					colour = SwingConversions.fromSwingColor(SampledTrackGraphView.PLAYBACK_BAR_COLOR);
+					Line l2 = new Line(x, getY(), x, getY() + getHeight());
+					g.drawLine(l2, colour, SwingConversions.fromSwingStroke(SampledTrackGraphView.GRAPH_BAR_STROKE));
 				
 				}
 			
 			}
-			
-
 			
 			break;
@@ -1094,21 +1079,24 @@
 		if (centralizedMessage != null) {
 
-			FontMetrics fm   = g.getFontMetrics(MESSAGE_FONT);
-			Rectangle2D rect = fm.getStringBounds(centralizedMessage, g);
+			TextLayoutManager t = EcosystemManager.getTextLayoutManager();
+			
+			TextLayout layout = t.layoutString(centralizedMessage, MESSAGE_FONT, Point.ORIGIN, null, Integer.MAX_VALUE, 0, true, false).get(0);
+			
+			AxisAlignedBoxBounds layoutBounds = layout.getPixelBounds(0, 0);
 
 			// Calc centered position
-			int x = getX() + ((getWidth() / 2) - (int)(rect.getWidth() / 2));
-			int y = getY() + ((getHeight() / 2) + (int)(rect.getHeight() / 2) - 4);
+			int x = getX() + ((getWidth() / 2) - (int)(layoutBounds.getWidth() / 2));
+			int y = getY() + ((getHeight() / 2) + (int)(layoutBounds.getHeight() / 2) - 4);
 			
 			// Draw text
-			g.setFont(MESSAGE_FONT);
-			g.drawString(centralizedMessage, x, y);
+			g.drawTextLayout(layout, new Point(x, y), colour);
 			
 			// Draw add icon if waiting for a link
 			if (getLink() == null) {
-				IconRepository.getIcon("goto.png").paintIcon(null,
+				/*IconRepository.getIcon("goto.png").paintIcon(null,
 						g, 
 						x - 34, 
-						getY() + (getHeight() / 2) - 12);
+						getY() + (getHeight() / 2) - 12);*/
+				g.drawImage(IconRepository.getIcon("goto.png"), new Point(x - 34, getY() + (getHeight() / 2) - 12));
 			}
 				
@@ -1116,15 +1104,14 @@
 
 		// Paint name label over everything
-		if (state != NOT_INITIALIZED && state != FAILED_STATE && state != EMPTY_STATE)
-			nameLabel.paint(g);
-		
-		g.setClip(clipBackUp);
-		
-		super.paintLink((Graphics2D)g);
-
-	}
-	
-	private void drawTrackName(Track track, Graphics g, Color textColor) {
-
+		if (state != NOT_INITIALIZED && state != FAILED_STATE && state != EMPTY_STATE) nameLabel.paint();
+		
+		g.popClip(clipKey);
+
+	}
+	
+	private void drawTrackName(Track track, Colour textColor)
+	{
+		Graphics2D g = SwingMiscManager.getIfUsingSwingGraphicsManager().getCurrentSurface();
+		
 		// Draw helper message for user to give meaningful information of what they
 		// are actually highlighting
@@ -1133,5 +1120,5 @@
 		helperMessage = helperMessage + " (" + track.getParentFrameName() +  ")";
 		
-		FontMetrics fm   = g.getFontMetrics(HELPER_FONT);
+		FontMetrics fm   = g.getFontMetrics(SwingMiscManager.getIfUsingSwingFontManager().getInternalFont(HELPER_FONT));
 		Rectangle2D rect = fm.getStringBounds(helperMessage, g);
 
@@ -1149,6 +1136,6 @@
 		
 		// Draw text
-		g.setColor(textColor);
-		g.setFont(HELPER_FONT);
+		g.setColor(SwingConversions.toSwingColor(textColor));
+		g.setFont(SwingMiscManager.getIfUsingSwingFontManager().getInternalFont(HELPER_FONT));
 		g.drawString(helperMessage, xoff, yoff);
 
@@ -1156,15 +1143,14 @@
 	
 	@Override
-	protected void paintInFreeSpace(Graphics g) {
-
-		super.paintInFreeSpace(g);
-
-		Shape clipBackUp = g.getClip();
-		Rectangle tmpClip = (clipBackUp != null) ? clipBackUp.getBounds() : 
-			new Rectangle(0, 0, 
-					Browser._theBrowser.getContentPane().getWidth(), 
-					Browser._theBrowser.getContentPane().getHeight());
-			
-		g.setClip(tmpClip.intersection(getBounds()));
+	protected void paintInFreeSpace()
+	{
+		super.paintInFreeSpace();
+		
+		// Draw the name of the track
+		
+		GraphicsManager g = EcosystemManager.getGraphicsManager();
+
+		// Ensure that load bar or any text doesn't spill over widgets invalidation area
+		EnforcedClipKey clipKey = g.pushClip(new Clip(getBounds()));
 	
 		// Draw the name
@@ -1173,21 +1159,18 @@
 			name = "Unnamed";
 		}
-
-		g.setFont(TrackWidgetCommons.FREESPACE_TRACKNAME_FONT);
-		g.setColor(TrackWidgetCommons.FREESPACE_TRACKNAME_TEXT_COLOR);
-		
-		// Center track name
-		FontMetrics fm   = g.getFontMetrics(TrackWidgetCommons.FREESPACE_TRACKNAME_FONT);
-		Rectangle2D rect = fm.getStringBounds(name, g);
-		
-		g.drawString(
-				name, 
-				this.getX() + (int)((getWidth() - rect.getWidth()) / 2), 
-				this.getY() + (int)((getHeight() - rect.getHeight()) / 2) + (int)rect.getHeight()
-				);
-		
-		g.setClip(clipBackUp);
-	
-
+		
+		List<TextLayout> layouts = EcosystemManager.getTextLayoutManager().layoutString(name, TrackWidgetCommons.FREESPACE_TRACKNAME_FONT, getBounds().getTopLeft(), null, getBounds().getWidth(), 0, true, false);
+
+		// Centre the track name
+		int lineYDelta = 0;
+		for (TextLayout layout : layouts) {
+			AxisAlignedBoxBounds bounds = layout.getPixelBounds(getBounds().getMinX(), getBounds().getMinY() + lineYDelta);
+			int centreXOffset = (getBounds().getWidth() - bounds.getWidth()) / 2;
+			bounds.translate(centreXOffset, 0);
+			g.drawTextLayout(layout, bounds.getTopLeft(), TrackWidgetCommons.FREESPACE_TRACKNAME_TEXT_COLOR);
+			lineYDelta += bounds.getHeight();
+		}
+		
+		g.popClip(clipKey);
 	}
 
@@ -1205,5 +1188,5 @@
 				x = XatFrame(currentPlaybackFramePosition);
 				
-				FrameGraphics.invalidateArea(new Rectangle(
+				DisplayController.invalidateArea(new AxisAlignedBoxBounds(
 					x + offsetX, 
 					offsetY, 
@@ -1220,5 +1203,5 @@
 				x = XatFrame(currentPlaybackFramePosition);
 		
-				FrameGraphics.invalidateArea(new Rectangle(
+				DisplayController.invalidateArea(new AxisAlignedBoxBounds(
 						x + offsetX , 
 						offsetY, 
@@ -1462,7 +1445,7 @@
 		
 		// Get border color currently used
-		Color oldC = getSource().getBorderColor();
-		
-		Color newC = TrackWidgetCommons.getBorderColor(
+		Colour oldC = getSource().getBorderColor();
+		
+		Colour newC = TrackWidgetCommons.getBorderColor(
 				SoundDesk.getInstance().isSolo(masterMix.getChannelID()), 
 						masterMix.isMuted());
@@ -1518,29 +1501,27 @@
 	 *
 	 */
-	private class PlaybackPopup extends PlaybackControlPopup {
-
-		private static final long serialVersionUID = 1L;
-		
+	private class PlaybackPopup extends PlaybackControlPopup
+	{
 		public PlaybackPopup() {
 			miscButton.setActionCommand("goto");
-			miscButton.setIcon(IconRepository.getIcon("goto.png"));
+			SwingMiscManager.setJButtonIcon(miscButton, IconRepository.getIcon("goto.png"));
 			miscButton.setToolTipText("Goto linked frame");
 		}
 
 		@Override
-		public void onHide() {
-			super.onHide();
+		public void onHide()
+		{
 		}
 
 		@Override
-		public void onShow() {
-			super.onShow();
+		public void onShow()
+		{
 			updateVolume((int)(100 * masterMix.getVolume()));
 			updateMute(masterMix.isMuted());
 			updateSolo(SoundDesk.getInstance().isSolo(masterMix.getChannelID()));
 		}
-
-		public void actionPerformed(ActionEvent e) {
-			
+		
+		public void actionPerformed(ActionEvent e)
+		{
 			if (e.getSource() == miscButton) {
 				
@@ -1670,5 +1651,5 @@
 				currentPlaybackFramePosition = -1;
 				setSelection(0, 0); // invalidates
-				FrameGraphics.refresh(true);
+				DisplayController.requestRefresh(true);
 				
 			}
@@ -1691,7 +1672,8 @@
 	}
 	
-	private class MouseActions implements MouseListener, MouseMotionListener {
-
-		public void mouseClicked(MouseEvent e) {
+	private class MouseActions implements MouseListener, MouseMotionListener
+	{
+		public void mouseClicked(MouseEvent e)
+		{
 			assert(state != EMPTY_STATE);
 			
@@ -1705,18 +1687,18 @@
 		}
 
-
-		public void mouseEntered(MouseEvent e) {
+		public void mouseEntered(MouseEvent e)
+		{
 			assert(state != EMPTY_STATE);
 		}
 
 
-		public void mouseExited(MouseEvent e) {
+		public void mouseExited(MouseEvent e)
+		{
 			assert(state != EMPTY_STATE);
-			
-		}
-
-
-		public void mousePressed(MouseEvent e) {
-			
+		}
+
+
+		public void mousePressed(MouseEvent e)
+		{
 			assert(state != EMPTY_STATE);
 			
@@ -1732,13 +1714,11 @@
 			setSelection(frameAtX(selectionStartX), 1);
 			
-			FrameGraphics.refresh(true);
-		}
-
-
-		public void mouseReleased(MouseEvent e) {
-			
-
+			DisplayController.requestRefresh(true);
+		}
+
+
+		public void mouseReleased(MouseEvent e)
+		{
 			assert(state != EMPTY_STATE);
-			
 			
 			// Was the release a simple click
@@ -1765,11 +1745,9 @@
 				return;
 			}
-
-			
-		}
-		
-
-		public void mouseDragged(MouseEvent e) {
-			
+		}
+		
+
+		public void mouseDragged(MouseEvent e)
+		{
 			assert(state != EMPTY_STATE);
 			
@@ -1800,15 +1778,15 @@
 			}
 			
-			FrameGraphics.refresh(true);
-		}
-
-		public void mouseMoved(MouseEvent e) {
+			DisplayController.requestRefresh(true);
+		}
+
+		public void mouseMoved(MouseEvent e)
+		{
 			assert(state != EMPTY_STATE);
 			
 			if (state != PLAYING && state != STOPPED) return;
 
-			if (nameLabel.onMouseMoved(e, _swingComponent)) {
-				e.consume();
-				return;
+			if (nameLabel != null) {
+				nameLabel.gainFocus();
 			}
 
@@ -1822,39 +1800,27 @@
 				
 				// Get rid of all popups
-				PopupManager.getInstance().hideAutohidePopups();
-				
-				Rectangle animationSource = _swingComponent.getBounds();
+				PopupManager.getInstance().hideAutoHidePopups();
+				
+				AxisAlignedBoxBounds animationSource = SwingConversions.fromSwingRectangle(_swingComponent.getBounds());
 				
 				// Determine where popup should show
 				int x = LinkedTrack.this.getX();
-				int y = LinkedTrack.this.getY() - playbackControlPopup.getHeight() - 2; // by default show above
+				int y = LinkedTrack.this.getY() - playbackControlPopup.getFullBounds().getHeight() - 2; // by default show above
 				
 				// I get sick.dizzy from the popup expanding from the whole thing...
-				animationSource.height = 1;
-				animationSource.width = Math.min(animationSource.width, playbackControlPopup.getWidth());
+				animationSource.getSize().height = 1;
+				animationSource.getSize().width = Math.min(animationSource.getWidth(), playbackControlPopup.getFullBounds().getWidth());
 				
 				if (y < 0) {
 					y = LinkedTrack.this.getY() + LinkedTrack.this.getHeight() + 2;
-					animationSource.y = y - 2;
+					animationSource.getTopLeft().y = y - 2;
 				} 
 
 				// Animate the popup
-				PopupManager.getInstance().showPopup(
-						playbackControlPopup, 
-						new Point(x, y), 
-						_swingComponent,
-						PopupManager.getInstance().new ExpandShrinkAnimator(
-								animationSource,
-								Color.LIGHT_GRAY));
-				
-				PopupReaper.getInstance().initPopupLifetime(
-						playbackControlPopup, 
-						PopupManager.getInstance().new ExpandShrinkAnimator(
-								animationSource,
-								Color.LIGHT_GRAY), 
-								TrackWidgetCommons.POPUP_LIFETIME);
-				
+				playbackControlPopup.getAutoHideTime().setLifetime(TrackWidgetCommons.POPUP_LIFETIME);
+				PopupManager.getInstance().add(playbackControlPopup);
+				playbackControlPopup.show();
 			} else {
-				PopupReaper.getInstance().revivePopup(playbackControlPopup, TrackWidgetCommons.POPUP_LIFETIME);
+				playbackControlPopup.show();
 			}
 			
@@ -1878,5 +1844,5 @@
 			if (shouldInvalidate) {
 				invalidateSelf();
-				FrameGraphics.refresh(true);
+				DisplayController.requestRefresh(true);
 			}
 		}
@@ -1888,11 +1854,11 @@
 	 * @author Brook Novak
 	 */
-	private class Track {
-		
+	private class Track
+	{
 		private AbsoluteTrackNode absNode; // immutable. Never null
 		
 		private Rectangle area;
 		
-		private Color baseColor;
+		private Colour baseColor;
 		
 		boolean isSelected = false;
@@ -1900,10 +1866,12 @@
 		private int state = TRACKSTATE_READY;
 		
-		Track(AbsoluteTrackNode absNode) {
+		Track(AbsoluteTrackNode absNode)
+		{
 			assert(absNode != null);
 			this.absNode = absNode;
 		}
 		
-		public String getChannelID() {
+		public String getChannelID()
+		{
 			return absNode.getChannelID();
 		}
@@ -1929,12 +1897,14 @@
 		}
 		
-		public void paintTrackArea(Graphics2D g, int x, int y) {
+		public void paintTrackArea(int x, int y)
+		{
+			Graphics2D g = SwingMiscManager.getIfUsingSwingGraphicsManager().getCurrentSurface();
 			
 			if (state == TRACKSTATE_LOADING && LinkedTrack.this.state == PLAYBACK_LOADING) {
-				g.setColor(TRACK_LOAD_COLOR);
+				g.setColor(SwingConversions.toSwingColor(TRACK_LOAD_COLOR));
 			} else if (state == TRACKSTATE_FAILED) {
-				g.setColor(TRACK_FAIL_COLOR);
+				g.setColor(SwingConversions.toSwingColor(TRACK_FAIL_COLOR));
 			} else {
-				g.setColor(baseColor);
+				g.setColor(SwingConversions.toSwingColor(baseColor));
 			}
 			
@@ -1943,10 +1913,10 @@
 
 				GradientPaint gp = new GradientPaint(
-						(int) (area.x + x + (area.width / 2)), area.y + y + (int)(area.height * 0.8), baseColor,
-						(int) (area.x + x + (area.width / 2)), area.y + y, TRACK_SELECTED_BORDER_COLOR);
+						(int) (area.x + x + (area.width / 2)), area.y + y + (int)(area.height * 0.8), SwingConversions.toSwingColor(baseColor),
+						(int) (area.x + x + (area.width / 2)), area.y + y, SwingConversions.toSwingColor(TRACK_SELECTED_BORDER_COLOR));
 				g.setPaint(gp);
 			}
 			
-			// Draw a filled rect - represented a track in the heirarchy
+			// Draw a filled rect - represented a track in the hierarchy
 			g.fillRect(area.x + x, area.y + y, area.width, area.height);
 			
@@ -1957,12 +1927,14 @@
 		}
 		
-		public void paintTrackBorder(Graphics g, int x, int y) {
+		public void paintTrackBorder(int x, int y)
+		{
+			Graphics g = SwingMiscManager.getIfUsingSwingGraphicsManager().getCurrentSurface();
 			
 			if (isSelected) {
-				g.setColor(TRACK_SELECTED_BORDER_COLOR);
-				((Graphics2D)g).setStroke(TRACK_SELECTED_BORDER);
+				g.setColor(SwingConversions.toSwingColor(TRACK_SELECTED_BORDER_COLOR));
+				((Graphics2D)g).setStroke(SwingConversions.toSwingStroke(TRACK_SELECTED_BORDER));
 			} else {
-				g.setColor(TRACK_BORDER_COLOR);
-				((Graphics2D)g).setStroke(TRACK_BORDER); // todo muted colors etc...
+				g.setColor(SwingConversions.toSwingColor(TRACK_BORDER_COLOR));
+				((Graphics2D)g).setStroke(SwingConversions.toSwingStroke(TRACK_BORDER)); // todo muted colors etc...
 			}
 			
@@ -1972,4 +1944,5 @@
 	}
 	
+	// TODO: Why not? cts16
 	@Override
 	public boolean isWidgetEdgeThicknessAdjustable() {
