/* * PanoramaButton.java * Eisenkraut * * Copyright (c) 2004-2016 Hanns Holger Rutz. All rights reserved. * * This software is published under the GNU General Public License v3+ * * * For further information, please contact Hanns Holger Rutz at * contact@sciss.de */ package de.sciss.eisenkraut.gui; import de.sciss.eisenkraut.session.SessionCollection; import de.sciss.eisenkraut.timeline.AudioTrack; import de.sciss.eisenkraut.util.MapManager; import de.sciss.gui.ModificationButton; import de.sciss.util.Disposable; import javax.swing.*; import java.awt.*; import java.awt.geom.AffineTransform; import java.awt.geom.Ellipse2D; import java.awt.geom.Line2D; import java.awt.geom.Point2D; @SuppressWarnings("serial") public class PanoramaButton extends ModificationButton implements Disposable { private static final Color colrNormalLight = new Color(0x3C, 0x3C, 0x3C, 0xFF); private static final Color colrPressedLight = new Color(0x06, 0x06, 0x06, 0xFF); private static final Color colrDisabledLight = new Color(0x6C, 0x6C, 0x6C, 0x7F); private static final Color colrNormalDark = new Color(0xC3, 0xC3, 0xC3, 0xFF); private static final Color colrPressedDark = new Color(0xF9, 0xF9, 0xF9, 0xFF); private static final Color colrDisabledDark = new Color(0x93, 0x93, 0x93, 0x7F); protected static final Paint pntCtrlLight = new Color(0x00, 0x00, 0x00, 0x7F); protected static final Paint pntCtrlDark = new Color(0xFF, 0xFF, 0xFF, 0x7F); protected final static Stroke strkInside = new BasicStroke(0.333f); protected final static Stroke strkOutside = new BasicStroke(0.75f); protected final static Shape shpLine = new Line2D.Double(0.5, 14.5, 28.5, 14.5); protected static final Shape shpCtrl = new Ellipse2D.Double(-2, -2, 5, 5); protected AudioTrackPanorama atPan = null; private final Point2D ctrlPt = new Point2D.Double(); private final AudioTrack t; private final PopupTriggerMonitor popMon; public PanoramaButton(final AudioTrack t, final SessionCollection tracks) { this(t, tracks, UIManager.getBoolean("dark-skin")); } public PanoramaButton(final AudioTrack t, final SessionCollection tracks, final boolean isDark) { super(new PantaRei(isDark ? colrNormalDark : colrNormalLight , isDark ? pntCtrlDark : pntCtrlLight), new PantaRei(isDark ? colrPressedDark : colrPressedLight , isDark ? pntCtrlDark : pntCtrlLight), new PantaRei(isDark ? colrDisabledDark : colrDisabledLight, isDark ? pntCtrlDark : pntCtrlLight)); this.t = t; ((PantaRei) icnNormal ).setCtrlPoint(ctrlPt); ((PantaRei) icnPressed ).setCtrlPoint(ctrlPt); ((PantaRei) icnDisabled).setCtrlPoint(ctrlPt); t.getMap().addListener(new MapManager.Listener() { public void mapChanged(MapManager.Event e) { if (e.getPropertyNames().contains(AudioTrack.MAP_KEY_PANAZIMUTH) || e.getPropertyNames().contains(AudioTrack.MAP_KEY_PANSPREAD)) { updateButtonState(); } } public void mapOwnerModified(MapManager.Event e) { /* ignore */ } }); popMon = new PopupTriggerMonitor(this); popMon.addListener(new PopupTriggerMonitor.Listener() { public void componentClicked(PopupTriggerMonitor m) { if (atPan == null) { atPan = new AudioTrackPanorama(t, tracks); } atPan.showPalette(); } public void popupTriggered(PopupTriggerMonitor m) { if (atPan == null) { atPan = new AudioTrackPanorama(t, tracks); } atPan.showPopup(m.getComponent(), m.getComponent().getWidth(), 0, true); } }); updateButtonState(); } public void dispose() { if (atPan != null) { atPan.dispose(); atPan = null; } popMon.dispose(); } protected void updateButtonState() { Object o; o = t.getMap().getValue(AudioTrack.MAP_KEY_PANAZIMUTH); double azi = (o != null) && (o instanceof Number) ? ((Number) o).doubleValue() : 0.0; o = t.getMap().getValue(AudioTrack.MAP_KEY_PANSPREAD); double spread = (o != null) && (o instanceof Number) ? ((Number) o).doubleValue() : 2.0; ctrlPt.setLocation(PanoramaPanel.aziAndSpreadToCtrlPoint(azi, spread)); ctrlPt.setLocation((ctrlPt.getX() + 1.0) * 14.5, (1.0 - ctrlPt.getY()) * 14.5); if (isVisible()) repaint(); } private static class PantaRei implements Icon { private final Paint pntView; private final Paint pntCtrl; private Point2D ctrlPt; protected PantaRei(Paint pntView, Paint pntCtrl) { this.pntView = pntView; this.pntCtrl = pntCtrl; } public int getIconWidth() { return 31; } public int getIconHeight() { return 31; } protected void setCtrlPoint(Point2D ctrlPt) { this.ctrlPt = ctrlPt; } public void paintIcon(Component c, Graphics g, int x, int y) { final Graphics2D g2 = (Graphics2D) g; final Stroke strkOrig = g2.getStroke(); final AffineTransform atOrig = g2.getTransform(); g2.translate(x + 0.5f, y + 0.5f); // +0.5 = "smoother" g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); g2.setPaint(pntView); g2.setStroke(strkOutside); g2.drawOval(0, 0, 29, 29); g2.setStroke(strkInside); g2.drawOval(3, 3, 23, 23); g2.draw(shpLine); g2.translate(ctrlPt.getX() - 0.5f, ctrlPt.getY() - 0.5f); g2.setPaint(pntCtrl); g2.fill(shpCtrl); g2.setTransform(atOrig); g2.setStroke(strkOrig); } } }