/* Copyright (C) 2006 Christian Schneider * * This file is part of Nomad. * * Nomad is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Nomad 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nomad; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* * Created on Apr 29, 2006 */ package net.sf.nmedit.jtheme.clavia.nordmodular; import java.awt.Color; import java.awt.ComponentOrientation; import java.awt.Dimension; import java.awt.Font; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.AbstractSpinnerModel; import javax.swing.Action; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JComponent; import javax.swing.JFormattedTextField; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JSpinner; import javax.swing.JTextField; import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import net.sf.nmedit.jpatch.clavia.nordmodular.NMPatch; import net.sf.nmedit.jpatch.clavia.nordmodular.event.PPatchSettingsEvent; import net.sf.nmedit.jpatch.clavia.nordmodular.event.PPatchSettingsListener; import net.sf.nmedit.jpatch.event.PModuleContainerEvent; import net.sf.nmedit.jpatch.event.PModuleContainerListener; import net.sf.nmedit.jsynth.clavia.nordmodular.NmSlot; import net.sf.nmedit.jtheme.clavia.nordmodular.misc.GradientProgressBar; import net.sf.nmedit.nmutils.math.Math2; import net.sf.nmedit.nmutils.swing.LimitedText; public class JTPatchSettingsBar extends JPanel implements PModuleContainerListener, PropertyChangeListener, PPatchSettingsListener /*implements PatchListener */ { /** * */ private static final long serialVersionUID = 7266333456740910212L; private JTextField pName; private JSpinner pVoices; private VoicesNumberModel voices; private NMPatch patch = null; // private JPanel dspPane; private JProgressBar dspTotal; private JProgressBar dspPoly; // private CableToggler cableToggler = new CableToggler(); private JTNMPatch pui; private static Font smallFont = null; private static Font getSmallFont() { Font f = smallFont; if (f != null) return f; f = UIManager.getDefaults().getFont("Label.font"); if (f == null) f = new Font("sansserif", Font.PLAIN, 10); else { // make font appear smaller float oldSize = f.getSize2D(); int newSize = (int) Math.floor((oldSize*.8f)); final int minSize = 8; if (newSize<minSize) newSize = minSize; f = new Font(f.getName(), f.getStyle(), newSize); } smallFont = f; // store font return f; } public JTPatchSettingsBar(JTNMPatch patchUI) { final int STRUT = 3; this.pui = patchUI; this.patch = patchUI.getPatch(); // panel setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); //setMinimumSize(new Dimension(100,28)); // setPreferredSize(new Dimension(100,28)); setBorder(BorderFactory.createEmptyBorder(2,2,2,2)); patch.getPolyVoiceArea().addModuleContainerListener(this); patch.getCommonVoiceArea().addModuleContainerListener(this); patch.addPropertyChangeListener(NMPatch.NAME, new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { pName.setText((String) evt.getNewValue()); } } ); pName = left(centery(new JTextField(new LimitedText(16), "Name", 16))); pName.setToolTipText("Patch Name"); pName.setMargin(new Insets(1,1,1,1)); pName.setMaximumSize(new Dimension(140,Short.MAX_VALUE)); pName.addKeyListener(new PatchNameKeyAdapter()); pName.addActionListener(new ActionListener() { public void actionPerformed( ActionEvent e ) { if (patch!=null) patch.setName(pName.getText()); }}); pVoices = centery(new JSpinner()); voices = new VoicesNumberModel(1, 1, 32); pVoices.setToolTipText("requested voices / available voices"); pVoices.setModel(voices); pVoices.setValue(1);//voices.getMinimum()); pVoices.setMinimumSize(new Dimension(20,10)); pVoices.setMaximumSize(new Dimension(140,Short.MAX_VALUE)); pVoices.setSize(pVoices.getPreferredSize()); try { JFormattedTextField spinnerText = ((JSpinner.DefaultEditor)pVoices.getEditor()).getTextField(); spinnerText.setMargin(new Insets(1,1,1,1)); } catch (NullPointerException e) { // ignore } catch (ClassCastException e) { // ignore } voices.addChangeListener(new ChangeListener() { public void stateChanged( ChangeEvent e ) { if (patch!=null) patch.getHeader().setRequestedVoices(voices.getRequestedVoices()); } }); dspPoly = createBar(); dspTotal = createBar(); dspPoly.setToolTipText("dsp load: poly voice area"); dspTotal.setToolTipText("dsp load: total"); // morphs JTMorphModule morphModule = new JTMorphModule(patchUI.getContext()); morphModule.setModule(patch.getMorphSection().getMorphModule()); morphModule.setMinimumSize(new Dimension(160, 10)); Box loadContainer = Box.createHorizontalBox(); loadContainer.setMaximumSize(new Dimension(100, 30)); Font sf = getSmallFont(); setFont(sf); dspPoly.setFont(sf); dspTotal.setFont(sf); loadContainer.setFont(sf); Box lcLeft = Box.createVerticalBox(); lcLeft.add(left(label("PVA:", dspPoly, sf))); lcLeft.add(Box.createVerticalStrut(1)); lcLeft.add(left(label("E:", dspPoly, sf))); Box lcMain = Box.createVerticalBox(); lcMain.add(left(dspPoly)); lcMain.add(Box.createVerticalStrut(1)); lcMain.add(left(dspTotal)); loadContainer.add(lcLeft); loadContainer.add(Box.createHorizontalStrut(1)); loadContainer.add(lcMain); add(((label("Patch:", pName)))); add(Box.createHorizontalStrut(STRUT)); add(((pName))); add(Box.createHorizontalStrut(STRUT)); add(left(centery(label("Voices:", pVoices)))); add(Box.createHorizontalStrut(STRUT)); add(centery(left(pVoices))); add(Box.createHorizontalStrut(STRUT)); add (left(centery(new JLabel("Load:")))); add(Box.createHorizontalStrut(STRUT)); add(left(centery(loadContainer))); add(Box.createHorizontalStrut(STRUT)); Box mbox = Box.createVerticalBox(); mbox.add(centery(morphModule)); add(left(centery(mbox))); add(Box.createHorizontalGlue()); Action showNoteDialogA = null; //add(new JButton(showNoteDialogA)); //pane.add(cableToggler); updateValues(); installListeners(); } private JLabel label(String title, JComponent forComponent, Font font) { JLabel label = label(title, forComponent); label.setFont(font); return label; } private JLabel label(String title, JComponent forComponent) { JLabel label = new JLabel(title); label.setLabelFor(forComponent); return label; } private <T extends JComponent> T left(T c) { c.setAlignmentX(JComponent.LEFT_ALIGNMENT); return c; } private <T extends JComponent> T centery(T c) { c.setAlignmentY(JComponent.CENTER_ALIGNMENT); return c; } private class PatchNameKeyAdapter extends KeyAdapter { public void keyPressed( KeyEvent e ) { if (e.getKeyCode()==KeyEvent.VK_ESCAPE) { if (patch!=null) { pName.setBackground(Color.WHITE); pName.setText(patch.getName()); } } } public void keyReleased( KeyEvent e ) { if (patch!=null) { String name = patch.getName(); if (name == null) name = ""; pName.setBackground ( name.equals(pName.getText()) ? Color.WHITE:Color.RED ); } } } private static final Color GP_BLUE_BRIGHT = Color.decode("#92C5FF"); private static final Color GP_BLUE_DARK = Color.decode("#567597"); private static final Border GP_BORDER = BorderFactory.createMatteBorder(1,1,1,1,GP_BLUE_DARK); private JProgressBar createBar() { GradientProgressBar gp = new GradientProgressBar(); // gp.setBackground(NomadClassicColors.TEXT_DISPLAY_BACKGROUND); gp.setBorder(GP_BORDER); gp.setBackground(GP_BLUE_BRIGHT); gp.setForeground(Color.GREEN); gp.setGradient(Color.RED); gp.setEnabled(true); gp.setMinimum(0); gp.setMaximum(100); gp.setMaximumSize(new Dimension(40,12));/* gp.setPreferredSize(new Dimension(40,4));*/ /* gp.setMinimumSize(new Dimension(40, 12)); gp.setMaximumSize(new Dimension(40, Short.MAX_VALUE));*/ gp.setPreferredSize(new Dimension(40, 10)); gp.setAlignmentY(JComponent.CENTER_ALIGNMENT); gp.setStringPainted(true); return gp; } private void updateValues() { /* if (patch!=null) { patch.removeListener(this); }*/ patch = pui.getPatch(); pVoices.setEnabled(true); voices.setValue(patch.getHeader().getRequestedVoices()); pName.setEnabled(true); String n = patch.getName(); pName.setText(n == null ? "" : n); NmSlot slot = (NmSlot) patch.getSlot(); voices.setVoiceCount(slot==null?null:slot.getVoiceCount()); /* if (patch!=null) patch.addPatchListener(this); */ updateCyclesInfo(); } private void updateCyclesInfo() { if (patch==null) { dspPoly.setValue(0); dspTotal.setValue(0); } else { double pva = patch.getPolyVoiceArea().getTotalCycles(); double cva = patch.getCommonVoiceArea().getTotalCycles(); double total = Math2.roundTo(pva+cva, -2); pva = Math2.roundTo(pva, -2); dspPoly.setValue((int)pva); dspTotal.setValue((int)total); percentString(dspPoly); percentString(dspTotal); } } private static void percentString(JProgressBar bar) { int d = (bar.getMaximum()-bar.getMinimum()); if (d <= 0) { bar.setString(null); } int f = (int) Math.round((100*(bar.getValue()-bar.getMinimum()))/(double)d); bar.setString(f+"%"); } private void disableView() { pVoices.setEnabled(false); voices.setValue(32); pName.setEnabled(false); pName.setText(""); updateCyclesInfo(); } public void updateView() { updateValues(); } private static class VoicesNumberModel extends AbstractSpinnerModel { private class Voices { final int value; public Voices(int value) { this.value = value; } public String toString() { StringBuffer sb = new StringBuffer(); if (value<10) sb.append(' '); sb.append(Integer.toString(value)); sb.append("/"); if (voiceCount==null) sb.append("- "); else { if (voiceCount.intValue()<10) sb.append(' '); sb.append(voiceCount); } return sb.toString(); } } private Integer voiceCount = null; private Voices voices; private Number minimum; private Number maximum; public VoicesNumberModel(Number value, Number minimum, Number maximum) { voices = new Voices(value.intValue()); this.minimum = minimum; this.maximum = maximum; } public int getRequestedVoices() { return voices.value; } public void setVoiceCount(Integer i) { if (!(voiceCount==null?i==null:voiceCount.equals(i))) { this.voiceCount = i; fireStateChanged(); } } public Object getValue() { return voices; } public void setValue( Object value ) { if (value==null||(!(value instanceof Number||value instanceof Voices))) throw new IllegalArgumentException(); int n = value instanceof Number ? ((Number)value).intValue() : ((Voices)value).value; if (n!=voices.value) { voices = new Voices(n); fireStateChanged(); } } public Object getNextValue() { return (maximum.intValue()<=voices.value)?null: new Voices(voices.value+1); } public Object getPreviousValue() { return (minimum.intValue()>=voices.value)?null: new Voices(voices.value-1); } public String toString() { return voices.toString(); } } public void moduleAdded(PModuleContainerEvent e) { updateCyclesInfo(); } public void moduleRemoved(PModuleContainerEvent e) { updateCyclesInfo(); } public void dispose() { uninstallListeners(); } private void uninstallListeners() { patch.removePropertyChangeListener(NMPatch.SLOT_PROPERTY, this); patch.removePatchSettingsListener(this); NmSlot slot = (NmSlot) patch.getSlot(); if (slot != null) slot.removePropertyChangeListener(this); } private void installListeners() { patch.addPropertyChangeListener(NMPatch.SLOT_PROPERTY, this); patch.addPatchSettingsListener(this); NmSlot slot = (NmSlot) patch.getSlot(); if (slot != null) slot.addPropertyChangeListener(this); } public void propertyChange(PropertyChangeEvent evt) { if (NMPatch.SLOT_PROPERTY == evt.getPropertyName()) { NmSlot slot = (NmSlot) evt.getOldValue(); if (slot != null) slot.removePropertyChangeListener(this); slot = (NmSlot) evt.getNewValue(); if (slot != null) slot.addPropertyChangeListener(this); updateValues(); } else if (NmSlot.PROPERTY_VOICECOUNT == evt.getPropertyName()) { updateValues(); } } public void patchSettingsChanged(PPatchSettingsEvent e) { updateValues(); } /* public void patchHeaderChanged( Event e ) { } public void patchPropertyChanged( Event e ) { if (Patch.VAPOLY_CYCLES.equals(e.getPropertyName()) ||Patch.VACOMMON_CYCLES.equals(e.getPropertyName())) { updateCyclesInfo(); } }*/ }