--- jsampler/trunk/src/org/jsampler/view/fantasia/Channel.java 2008/04/30 23:31:08 1730 +++ jsampler/trunk/src/org/jsampler/view/fantasia/Channel.java 2008/05/03 01:40:06 1732 @@ -23,22 +23,37 @@ package org.jsampler.view.fantasia; import java.awt.Container; +import java.awt.Dimension; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.text.NumberFormat; + +import javax.swing.AbstractAction; +import javax.swing.Action; import javax.swing.BoxLayout; +import javax.swing.ButtonGroup; import javax.swing.DefaultListCellRenderer; +import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JMenuItem; import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JRadioButtonMenuItem; import javax.swing.JScrollPane; import javax.swing.JToggleButton; +import javax.swing.JToolBar; +import net.sf.juife.InformationDialog; import net.sf.juife.TitleBar; import org.jdesktop.swingx.JXCollapsiblePane; @@ -52,7 +67,17 @@ import org.jsampler.event.SamplerChannelListListener; import org.jsampler.event.SamplerChannelListener; +import org.jsampler.view.std.JSChannelOutputRoutingDlg; +import org.jsampler.view.std.JSFxSendsPane; +import org.jsampler.view.std.JSInstrumentChooser; +import org.jsampler.view.std.JSVolumeEditorPopup; + +import org.linuxsampler.lscp.SamplerChannel; + +import static org.jsampler.view.fantasia.FantasiaI18n.i18n; import static org.jsampler.view.fantasia.FantasiaPrefs.*; +import static org.jsampler.view.fantasia.FantasiaUtils.*; +import static org.jsampler.view.std.JSVolumeEditorPopup.VolumeType; /** @@ -65,6 +90,10 @@ private ChannelOptionsView channelOptionsView; private final ChannelOptionsPane optionsPane = new ChannelOptionsPane(); + private InformationDialog fxSendsDlg = null; + + private final ContextMenu contextMenu = new ContextMenu(); + private boolean selected = false; private AnimatedPorpetyListener animatedPorpetyListener = new AnimatedPorpetyListener(); @@ -107,13 +136,14 @@ new BoxLayout(mainPane.getContentPane(), BoxLayout.Y_AXIS) ); - channelView = new NormalChannelView(this); - channelOptionsView = channelView.getChannelOptionsView(); - - optionsPane.setContentPane(channelOptionsView.getComponent()); - - mainPane.add(channelView.getComponent()); - mainPane.add(optionsPane); + int viewIdx = preferences().getIntProperty(DEFAULT_CHANNEL_VIEW); + if(viewIdx == 0) { + contextMenu.rbmiSmallView.doClick(0); + } else if(viewIdx == 1) { + contextMenu.rbmiNormalView.doClick(0); + } else { + contextMenu.rbmiNormalView.doClick(0); + } setOpaque(false); @@ -215,6 +245,17 @@ channelOptionsView.updateChannelInfo(); } + public void + loadInstrument() { + JSInstrumentChooser dlg = FantasiaUtils.createInstrumentChooser(CC.getMainFrame()); + dlg.setVisible(true); + + if(!dlg.isCancelled()) { + SamplerChannelModel m = getModel(); + m.loadBackendInstrument(dlg.getInstrumentFile(), dlg.getInstrumentIndex()); + } + } + protected void onDestroy() { CC.getSamplerModel().removeSamplerChannelListListener(getHandler()); @@ -239,6 +280,21 @@ public void showOptionsPane(boolean show) { optionsPane.showOptionsPane(show); } + public void + showFxSendsDialog() { + if(fxSendsDlg != null && fxSendsDlg.isVisible()) { + fxSendsDlg.toFront(); + return; + } + FxSendsPane p = new FxSendsPane(getModel()); + int id = getModel().getChannelId(); + fxSendsDlg = new InformationDialog(CC.getMainFrame(), p); + fxSendsDlg.setTitle(i18n.getLabel("FxSendsDlg.title", id)); + fxSendsDlg.setModal(false); + fxSendsDlg.showCloseButton(false); + fxSendsDlg.setVisible(true); + } + private final EventHandler eventHandler = new EventHandler(); private EventHandler @@ -302,6 +358,373 @@ } } } + + class EditInstrumentAction extends AbstractAction implements SamplerChannelListener { + EditInstrumentAction() { + super(i18n.getMenuLabel("channels.editInstrument")); + channelChanged(null); + getModel().addSamplerChannelListener(this); + } + + public void + actionPerformed(ActionEvent e) { + CC.getSamplerModel().editBackendInstrument(getChannelId()); + } + + public void + channelChanged(SamplerChannelEvent e) { + boolean b = getChannelInfo().getInstrumentStatus() == 100; + setEnabled(b); + } + + public void + streamCountChanged(SamplerChannelEvent e) { } + + public void + voiceCountChanged(SamplerChannelEvent e) { } + } + + class FxSendsAction extends AbstractAction { + FxSendsAction() { + super(i18n.getMenuLabel("channels.fxSends")); + } + + public void + actionPerformed(ActionEvent e) { + showFxSendsDialog(); + } + } + + class ChannelRoutingAction extends AbstractAction implements SamplerChannelListener { + ChannelRoutingAction() { + super(i18n.getMenuLabel("channels.channelRouting")); + channelChanged(null); + getModel().addSamplerChannelListener(this); + } + + public void + actionPerformed(ActionEvent e) { + SamplerChannel c = getChannelInfo(); + new JSChannelOutputRoutingDlg(CC.getMainFrame(), c).setVisible(true); + } + + public void + channelChanged(SamplerChannelEvent e) { + boolean b = getChannelInfo().getAudioOutputDevice() != -1; + setEnabled(b); + } + + public void + streamCountChanged(SamplerChannelEvent e) { } + + public void + voiceCountChanged(SamplerChannelEvent e) { } + } + + class SetSmallViewAction extends AbstractAction { + SetSmallViewAction() { + super(i18n.getMenuLabel("channels.smallView")); + } + + public void + actionPerformed(ActionEvent e) { + if(channelView instanceof SmallChannelView) return; + + if(channelView != null) { + mainPane.remove(channelView.getComponent()); + mainPane.remove(optionsPane); + + channelView.uninstallView(); + channelOptionsView.uninstallView(); + } + + channelView = new SmallChannelView(Channel.this); + channelOptionsView = channelView.getChannelOptionsView(); + + optionsPane.setContentPane(channelOptionsView.getComponent()); + + updateChannelInfo(); + + mainPane.add(channelView.getComponent()); + mainPane.add(optionsPane); + mainPane.validate(); + } + } + + class SetNormalViewAction extends AbstractAction { + SetNormalViewAction() { + super(i18n.getMenuLabel("channels.normalView")); + } + + public void + actionPerformed(ActionEvent e) { + if(channelView instanceof NormalChannelView) return; + + if(channelView != null) { + mainPane.remove(channelView.getComponent()); + mainPane.remove(optionsPane); + + channelView.uninstallView(); + channelOptionsView.uninstallView(); + } + + channelView = new NormalChannelView(Channel.this); + channelOptionsView = channelView.getChannelOptionsView(); + + optionsPane.setContentPane(channelOptionsView.getComponent()); + + updateChannelInfo(); + + mainPane.add(channelView.getComponent()); + mainPane.add(optionsPane); + mainPane.validate(); + } + } + + public ContextMenu + getContextMenu() { return contextMenu; } + + class ContextMenu extends MouseAdapter { + private final JPopupMenu menu = new JPopupMenu(); + + protected final JRadioButtonMenuItem rbmiSmallView; + protected final JRadioButtonMenuItem rbmiNormalView; + + ContextMenu() { + menu.add(new JMenuItem(new EditInstrumentAction())); + menu.addSeparator(); + + rbmiSmallView = new JRadioButtonMenuItem(new SetSmallViewAction()); + rbmiNormalView = new JRadioButtonMenuItem(new SetNormalViewAction()); + + ButtonGroup group = new ButtonGroup(); + group.add(rbmiSmallView); + group.add(rbmiNormalView); + + menu.add(rbmiSmallView); + menu.add(rbmiNormalView); + + menu.addSeparator(); + menu.add(new JMenuItem(new FxSendsAction())); + menu.add(new JMenuItem(new ChannelRoutingAction())); + } + + public void + mousePressed(MouseEvent e) { + if(e.isPopupTrigger()) show(e); + } + + public void + mouseReleased(MouseEvent e) { + if(e.isPopupTrigger()) show(e); + } + + void + show(MouseEvent e) { + menu.show(e.getComponent(), e.getX(), e.getY()); + } + } + + class FxSendsPane extends JSFxSendsPane { + FxSendsPane(SamplerChannelModel model) { + super(model); + + actionAddFxSend.putValue(Action.SMALL_ICON, Res.iconNew16); + actionRemoveFxSend.putValue(Action.SMALL_ICON, Res.iconDelete16); + } + + protected JToolBar + createToolBar() { + JToolBar tb = new JToolBar(); + Dimension d = new Dimension(Short.MAX_VALUE, tb.getPreferredSize().height); + tb.setMaximumSize(d); + tb.setFloatable(false); + tb.setAlignmentX(JPanel.RIGHT_ALIGNMENT); + + tb.add(new ToolbarButton(actionAddFxSend)); + tb.add(new ToolbarButton(actionRemoveFxSend)); + + return tb; + } + } + + public static class StreamVoiceCountPane extends JPanel { + private final Channel channel; + + private final JLabel lStreams = createScreenLabel(" --"); + private final JLabel lSlash = createScreenLabel("/"); + private final JLabel lVoices = createScreenLabel("-- "); + + public + StreamVoiceCountPane(Channel channel) { + this.channel = channel; + + setOpaque(false); + setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); + lStreams.setFont(Res.fontScreenMono); + lStreams.setHorizontalAlignment(JLabel.RIGHT); + lStreams.setToolTipText(i18n.getLabel("Channel.streamVoiceCount")); + + Dimension d = lStreams.getPreferredSize(); + lStreams.setMinimumSize(d); + lStreams.setPreferredSize(d); + lStreams.setMaximumSize(d); + add(lStreams); + + lSlash.setFont(Res.fontScreenMono); + lSlash.setToolTipText(i18n.getLabel("Channel.streamVoiceCount")); + add(lSlash); + + lVoices.setFont(Res.fontScreenMono); + lVoices.setToolTipText(i18n.getLabel("Channel.streamVoiceCount")); + + d = lStreams.getPreferredSize(); + lVoices.setMinimumSize(d); + lVoices.setPreferredSize(d); + lVoices.setMaximumSize(d); + add(lVoices); + + lStreams.addMouseListener(channel.getContextMenu()); + lSlash.addMouseListener(channel.getContextMenu()); + lVoices.addMouseListener(channel.getContextMenu()); + } + + public void + updateStreamCount(int count) { + lStreams.setText(count == 0 ? " --" : String.valueOf(count)); + } + + public void + updateVoiceCount(int count) { + lVoices.setText(count == 0 ? "-- " : String.valueOf(count)); + } + } + + public static class VolumePane extends JPanel { + private final Channel channel; + private final JButton btnVolume = createScreenButton(""); + private JSVolumeEditorPopup popupVolume; + + private static NumberFormat numberFormat = NumberFormat.getInstance(); + static { numberFormat.setMaximumFractionDigits(1); } + + public + VolumePane(final Channel channel) { + this.channel = channel; + setOpaque(false); + setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); + + btnVolume.setIcon(Res.iconVolume14); + btnVolume.setIconTextGap(2); + btnVolume.setAlignmentX(RIGHT_ALIGNMENT); + btnVolume.setHorizontalAlignment(btnVolume.LEFT); + updateVolumeInfo(100); + Dimension d = btnVolume.getPreferredSize(); + d.width = 57; + btnVolume.setPreferredSize(d); + btnVolume.setMinimumSize(d); + + add(btnVolume); + + btnVolume.addActionListener(new ActionListener() { + public void + actionPerformed(ActionEvent e) { + if(popupVolume.isVisible()) { + popupVolume.commit(); + popupVolume.hide(); + } else { + float vol = channel.getModel().getChannelInfo().getVolume(); + popupVolume.setCurrentVolume(vol); + popupVolume.show(); + } + } + }); + + popupVolume = new JSVolumeEditorPopup(btnVolume, VolumeType.CHANNEL); + + popupVolume.addActionListener(new ActionListener() { + public void + actionPerformed(ActionEvent e) { + channel.getModel().setBackendVolume(popupVolume.getVolumeFactor()); + } + }); + + btnVolume.addMouseListener(channel.getContextMenu()); + } + + public void + updateVolumeInfo(int volume) { + if(CC.getViewConfig().isMeasurementUnitDecibel()) { + String s = numberFormat.format(HF.percentsToDecibels(volume)); + btnVolume.setText(s + "dB"); + } else { + btnVolume.setText(String.valueOf(volume) + "%"); + } + } + } + + public static class PowerButton extends PixmapToggleButton implements ActionListener { + private final Channel channel; + + PowerButton(Channel channel) { + this(channel, Res.gfxPowerOff, Res.gfxPowerOn); + } + + PowerButton(Channel channel, ImageIcon defaultIcon, ImageIcon selectedIcon) { + super(defaultIcon, selectedIcon); + + this.channel = channel; + + setSelected(true); + addActionListener(this); + setToolTipText(i18n.getButtonLabel("Channel.ttRemoveChannel")); + } + + public void + actionPerformed(ActionEvent e) { + boolean b = preferences().getBoolProperty(CONFIRM_CHANNEL_REMOVAL); + if(b) { + String s = i18n.getMessage("Channel.remove?", channel.getChannelId()); + if(!HF.showYesNoDialog(channel, s)) { + setSelected(true); + return; + } + } + channel.remove(); + } + + public boolean + contains(int x, int y) { return (x - 11)*(x - 11) + (y - 11)*(y - 11) < 71; } + } + + public static class OptionsButton extends PixmapToggleButton implements ActionListener { + private final Channel channel; + + OptionsButton(Channel channel) { + super(Res.gfxOptionsOff, Res.gfxOptionsOn); + + this.channel = channel; + + setRolloverIcon(Res.gfxOptionsOffRO); + this.setRolloverSelectedIcon(Res.gfxOptionsOnRO); + addActionListener(this); + setToolTipText(i18n.getButtonLabel("Channel.ttShowOptions")); + } + + public void + actionPerformed(ActionEvent e) { + channel.showOptionsPane(isSelected()); + + String s; + if(isSelected()) s = i18n.getButtonLabel("Channel.ttHideOptions"); + else s = i18n.getButtonLabel("Channel.ttShowOptions"); + + setToolTipText(s); + } + + public boolean + contains(int x, int y) { return super.contains(x, y) & y < 13; } + } } class ChannelOptionsPane extends JXCollapsiblePane {