/* * AbstractFlagsPanel.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.session; import de.sciss.eisenkraut.gui.GraphicsUtil; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; public abstract class AbstractFlagsPanel extends JPanel { public static final int FLAGS_SOLO = 0x01; public static final int FLAGS_MUTE = 0x02; public static final int FLAGS_SOLOSAFE = 0x04; public static final int FLAGS_VIRTUALMUTE = 0x08; private final FlagAction actionSolo, actionMute; public AbstractFlagsPanel() { super(new FlowLayout(FlowLayout.RIGHT, 0, 0)); actionSolo = new FlagAction(GraphicsUtil.ICON_SOLO, FLAGS_SOLO, FLAGS_SOLOSAFE); actionMute = new FlagAction(GraphicsUtil.ICON_MUTE, FLAGS_MUTE, FLAGS_VIRTUALMUTE); add(actionSolo.getButton()); add(actionMute.getButton()); } protected void updateButtons(int flags) { actionSolo.set(flags); actionMute.set(flags); } protected abstract void setFlags( int mask, boolean set ); protected abstract void broadcastFlags( int mask, boolean set ); protected abstract boolean isAny( int mask, boolean set ); // ---------------- interne Klassen ---------------- private abstract class TriStateAction extends AbstractAction { private final Icon normalState, thirdState; private final AbstractButton ab; private boolean isNormal = true; private final Icon[] icons; protected TriStateAction(int iconID, int normalID, int thirdID) { super(); icons = GraphicsUtil.createToolIcons(iconID); ab = new JToggleButton(this); ab.putClientProperty("styleId", "icon-hover"); ab.setBorderPainted(false); ab.setContentAreaFilled(false); ab.setMargin(new Insets(0, 0, 0, 0)); ab.setOpaque(false); ab.setFocusable(false); ab.setBorder(null); GraphicsUtil.setToolIcons(ab, icons); normalState = icons[normalID]; thirdState = icons[thirdID]; } protected AbstractButton getButton() { return ab; } protected void setThirdState(boolean b) { if (b == isNormal) { isNormal = !b; ab.setIcon(b ? thirdState : normalState); } } protected void setSelected(boolean b) { if (ab.isSelected() != b) { ab.setSelected(b); } } } @SuppressWarnings("serial") private class FlagAction extends TriStateAction { private final int normalMask; private final int thirdMask; private int flags; private final boolean isSolo; protected FlagAction(int iconID, int normalMask, int thirdMask) { super(iconID, 0, 2); this.normalMask = normalMask; this.thirdMask = thirdMask; isSolo = iconID == GraphicsUtil.ICON_SOLO; } protected void set(int flags) { this.flags = flags; setThirdState((flags & thirdMask ) != 0); setSelected ((flags & normalMask) != 0); } public void actionPerformed(ActionEvent e) { boolean meta = (e.getModifiers() & Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) != 0; boolean alt = (e.getModifiers() & ActionEvent.ALT_MASK) != 0; int mask = meta && isSolo ? thirdMask : normalMask; boolean set = alt && isSolo ? !isAny(mask, true) : (flags & mask) == 0; if (alt) { broadcastFlags(mask, set); } else { setFlags(mask, set); } } } }