jace/src/main/java/jace/tracker/UserInterface.java

258 lines
9.7 KiB
Java

/*
* Copyright (C) 2012 Brendan Robert (BLuRry) brendan.robert@gmail.com.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package jace.tracker;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Font;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.HashMap;
import java.util.Map;
import javax.swing.BoxLayout;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.xml.transform.Source;
/**
*
* @author Brendan Robert (BLuRry) brendan.robert@gmail.com
*/
public class UserInterface {
static Font EDITOR_FONT = new Font(Font.MONOSPACED, Font.PLAIN, 12);
public static enum Theme {
background(0x000000),
foreground(0xffffff),
backgroundEdit(0x000080),
foregroundEdit(0xffff80);
Color color;
Theme(int col) {
color = new Color(col & 0x0ffffff);
}
}
public static int BASE_OCTAVE = 3;
public static enum Note {
C0("C", -1),
CS0("CS", -1),
D0("D", -1),
DS0("DS", -1),
E0("E", -1),
F0("F", -1),
FS0("FS", -1),
G0("G", -1),
GS0("GS", -1),
A0("A", -1),
AS0("AS", -1),
B0("B", -1),
C1("C", 0),
CS1("CS", 0),
D1("D", 0),
DS1("DS", 0),
E1("E", 0),
F1("F", 0),
FS1("FS", 0),
G1("G", 0),
GS1("GS", 0),
A1("A", 0),
AS1("AS", 0),
B1("B", 0),
C2("C", 1),
CS2("CS", 1),
D2("D", 1),
DS2("DS", 1),
E2("E", 1);
public String note;
public int octaveOffset;
Note(String n, int offset) {
note = n;
octaveOffset = offset;
}
};
public static final Map<Integer, Note> KEYBOARD_MAP = new HashMap<Integer, Note>();
static {
KEYBOARD_MAP.put(KeyEvent.VK_Z, Note.C0);
KEYBOARD_MAP.put(KeyEvent.VK_S, Note.CS0);
KEYBOARD_MAP.put(KeyEvent.VK_X, Note.D0);
KEYBOARD_MAP.put(KeyEvent.VK_D, Note.DS0);
KEYBOARD_MAP.put(KeyEvent.VK_C, Note.E0);
KEYBOARD_MAP.put(KeyEvent.VK_V, Note.F0);
KEYBOARD_MAP.put(KeyEvent.VK_G, Note.FS0);
KEYBOARD_MAP.put(KeyEvent.VK_B, Note.G0);
KEYBOARD_MAP.put(KeyEvent.VK_H, Note.GS0);
KEYBOARD_MAP.put(KeyEvent.VK_N, Note.A0);
KEYBOARD_MAP.put(KeyEvent.VK_J, Note.AS0);
KEYBOARD_MAP.put(KeyEvent.VK_M, Note.B0);
KEYBOARD_MAP.put(KeyEvent.VK_Q, Note.C1);
KEYBOARD_MAP.put(KeyEvent.VK_2, Note.CS1);
KEYBOARD_MAP.put(KeyEvent.VK_W, Note.D1);
KEYBOARD_MAP.put(KeyEvent.VK_3, Note.DS1);
KEYBOARD_MAP.put(KeyEvent.VK_E, Note.E1);
KEYBOARD_MAP.put(KeyEvent.VK_R, Note.F1);
KEYBOARD_MAP.put(KeyEvent.VK_5, Note.FS1);
KEYBOARD_MAP.put(KeyEvent.VK_T, Note.G1);
KEYBOARD_MAP.put(KeyEvent.VK_6, Note.GS1);
KEYBOARD_MAP.put(KeyEvent.VK_Y, Note.A1);
KEYBOARD_MAP.put(KeyEvent.VK_7, Note.AS1);
KEYBOARD_MAP.put(KeyEvent.VK_U, Note.B1);
KEYBOARD_MAP.put(KeyEvent.VK_I, Note.C2);
KEYBOARD_MAP.put(KeyEvent.VK_9, Note.CS2);
KEYBOARD_MAP.put(KeyEvent.VK_O, Note.D2);
KEYBOARD_MAP.put(KeyEvent.VK_0, Note.DS2);
KEYBOARD_MAP.put(KeyEvent.VK_P, Note.E2);
}
public static void main(String... args) {
Row r = new Row();
JFrame testWindow = new JFrame();
testWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
testWindow.setSize(900, 600);
Container content = testWindow.getContentPane();
content.setLayout(new BoxLayout(testWindow.getContentPane(), BoxLayout.Y_AXIS));
content.setBackground(Theme.background.color);
content.setForeground(Theme.foreground.color);
content.add(createRowEditor(r));
content.add(createRowEditor(r));
content.add(createRowEditor(r));
content.add(createRowEditor(r));
content.add(createRowEditor(r));
content.add(createRowEditor(r));
content.add(createRowEditor(r));
content.add(createRowEditor(r));
content.add(createRowEditor(r));
content.add(createRowEditor(r));
content.add(createRowEditor(r));
content.add(createRowEditor(r));
content.add(createRowEditor(r));
content.add(createRowEditor(r));
content.add(createRowEditor(r));
content.add(createRowEditor(r));
// testWindow.doLayout();
testWindow.setVisible(true);
}
public static KeyAdapter toneListner = new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
e.consume();
}
@Override
public void keyTyped(KeyEvent e) {
e.consume();
}
@Override
public void keyPressed(KeyEvent e) {
JTextField field = (JTextField) e.getSource();
if (KEYBOARD_MAP.containsKey(e.getKeyCode())) {
Note n = KEYBOARD_MAP.get(e.getKeyCode());
String noteval = n.note;
int octave = BASE_OCTAVE + n.octaveOffset;
noteval += octave;
try {
// Test the waters, is ths value ok?
Row.Note.valueOf(noteval);
// Looks like it worked -- use the value
field.setText(noteval);
} catch (Throwable t) {
// out of bounds or bad value
}
}
e.consume();
field.setFocusable(false);
field.setFocusable(true);
}
};
public static Component createRowEditor(Row r) {
JPanel rowEditor = new JPanel();
rowEditor.setSize(800, 24);
rowEditor.setLayout(new BoxLayout(rowEditor, BoxLayout.X_AXIS));
rowEditor.setBackground(Theme.background.color);
rowEditor.setOpaque(true);
rowEditor.add(EditableLabel.generateTextLabel(r, "channels.A1.tone", 3, toneListner));
rowEditor.add(EditableLabel.generateTextLabel(r, "channels.A1.volume", 1));
rowEditor.add(EditableLabel.generateTextLabel(r, "channels.A1.commands", 3));
rowEditor.add(EditableLabel.generateTextLabel(r, "channels.B1.tone", 3, toneListner));
rowEditor.add(EditableLabel.generateTextLabel(r, "channels.B1.volume", 1));
rowEditor.add(EditableLabel.generateTextLabel(r, "channels.B1.commands", 3));
rowEditor.add(EditableLabel.generateTextLabel(r, "channels.C1.tone", 3, toneListner));
rowEditor.add(EditableLabel.generateTextLabel(r, "channels.C1.volume", 1));
rowEditor.add(EditableLabel.generateTextLabel(r, "channels.C1.commands", 3));
rowEditor.add(EditableLabel.generateTextLabel(r, "ay1noisePeriod", 4));
rowEditor.add(EditableLabel.generateTextLabel(r, "ay1envelopePeriod", 4));
rowEditor.add(generateEnvelopeEditor(r.ay1envelopeShape, r, "ay2envelopeShape"));
rowEditor.add(EditableLabel.generateTextLabel(r, "channels.A2.tone", 3, toneListner));
rowEditor.add(EditableLabel.generateTextLabel(r, "channels.A2.volume", 1));
rowEditor.add(EditableLabel.generateTextLabel(r, "channels.A2.commands", 3));
rowEditor.add(EditableLabel.generateTextLabel(r, "channels.B2.tone", 3, toneListner));
rowEditor.add(EditableLabel.generateTextLabel(r, "channels.B2.volume", 1));
rowEditor.add(EditableLabel.generateTextLabel(r, "channels.B2.commands", 3));
rowEditor.add(EditableLabel.generateTextLabel(r, "channels.C2.tone", 3, toneListner));
rowEditor.add(EditableLabel.generateTextLabel(r, "channels.C2.volume", 1));
rowEditor.add(EditableLabel.generateTextLabel(r, "channels.C2.commands", 3));
rowEditor.add(EditableLabel.generateTextLabel(r, "ay2noisePeriod", 4));
rowEditor.add(EditableLabel.generateTextLabel(r, "ay2envelopePeriod", 4));
rowEditor.add(generateEnvelopeEditor(r.ay2envelopeShape, r, "ay2envelopeShape"));
rowEditor.add(EditableLabel.generateTextLabel(r, "globalCommands", 6));
rowEditor.doLayout();
return rowEditor;
}
public static Component generateEnvelopeEditor(Row.EnvelopeShape envelope, Row row, String property) {
if (envelope == null) {
envelope = Row.EnvelopeShape.unspecified;
}
JLabel label = new JLabel(envelope.icon) {
@Override
public void setText(String text) {
Row.EnvelopeShape e;
try {
e = Row.EnvelopeShape.valueOf(text);
} catch (Throwable ex) {
e = Row.EnvelopeShape.unspecified;
}
setIcon(e.getIcon());
}
};
label.setText(envelope.toString());
JComboBox editor = new JComboBox(Row.ENVELOPE_ICONS);
EditableLabel result = new EditableLabel(label, editor, 64, row, property);
return result;
}
}