1 package camidion.chordhelper.midieditor;
\r
3 import java.awt.Dimension;
\r
4 import java.awt.Graphics;
\r
5 import java.awt.Graphics2D;
\r
6 import java.awt.GridLayout;
\r
7 import java.awt.Insets;
\r
8 import java.awt.Point;
\r
9 import java.awt.Rectangle;
\r
10 import java.awt.event.ActionEvent;
\r
11 import java.awt.event.ActionListener;
\r
12 import java.awt.event.ComponentEvent;
\r
13 import java.awt.event.ComponentListener;
\r
14 import java.awt.event.InputEvent;
\r
15 import java.awt.event.MouseEvent;
\r
16 import java.awt.event.MouseListener;
\r
17 import java.util.ArrayList;
\r
18 import java.util.Vector;
\r
20 import javax.sound.midi.MidiChannel;
\r
21 import javax.sound.midi.Sequence;
\r
22 import javax.swing.AbstractAction;
\r
23 import javax.swing.Action;
\r
24 import javax.swing.BoxLayout;
\r
25 import javax.swing.JButton;
\r
26 import javax.swing.JCheckBox;
\r
27 import javax.swing.JComboBox;
\r
28 import javax.swing.JComponent;
\r
29 import javax.swing.JDialog;
\r
30 import javax.swing.JLabel;
\r
31 import javax.swing.JPanel;
\r
32 import javax.swing.JScrollPane;
\r
33 import javax.swing.JSpinner;
\r
34 import javax.swing.JTabbedPane;
\r
35 import javax.swing.JTextArea;
\r
36 import javax.swing.JTextField;
\r
37 import javax.swing.SpinnerNumberModel;
\r
38 import javax.swing.event.ChangeEvent;
\r
39 import javax.swing.event.ChangeListener;
\r
41 import camidion.chordhelper.ButtonIcon;
\r
42 import camidion.chordhelper.ChordHelperApplet;
\r
43 import camidion.chordhelper.music.AbstractNoteTrackSpec;
\r
44 import camidion.chordhelper.music.ChordProgression;
\r
45 import camidion.chordhelper.music.DrumTrackSpec;
\r
46 import camidion.chordhelper.music.FirstTrackSpec;
\r
47 import camidion.chordhelper.music.MelodyTrackSpec;
\r
48 import camidion.chordhelper.music.Range;
\r
49 import camidion.chordhelper.pianokeyboard.PianoKeyboardListener;
\r
50 import camidion.chordhelper.pianokeyboard.PianoKeyboardPanel;
\r
53 * 新しいMIDIシーケンスを生成するダイアログ
\r
55 public class NewSequenceDialog extends JDialog {
\r
56 private static final Insets ZERO_INSETS = new Insets(0,0,0,0);
\r
57 private static final Integer[] PPQList = {
\r
58 48,60,80,96,120,160,192,240,320,384,480,960
\r
60 private static final String INITIAL_CHORD_STRING =
\r
61 "Key: C\nC G/B | Am Em/G | F C/E | Dm7 G7 C % | F G7 | Csus4 C\n";
\r
62 private JTextArea chordText = new JTextArea(INITIAL_CHORD_STRING, 18, 30);
\r
63 private JTextField seqNameText = new JTextField();
\r
64 private JComboBox<Integer> ppqComboBox = new JComboBox<Integer>(PPQList);
\r
65 private TimeSignatureSelecter timesigSelecter = new TimeSignatureSelecter();
\r
66 private TempoSelecter tempoSelecter = new TempoSelecter();
\r
67 private MeasureSelecter measureSelecter = new MeasureSelecter();
\r
68 private TrackSpecPanel trackSpecPanel = new TrackSpecPanel() {{
\r
69 DrumTrackSpec dts = new DrumTrackSpec(9, "Percussion track");
\r
72 MelodyTrackSpec mts;
\r
73 mts = new MelodyTrackSpec(2, "Bass track", new Range(36,48));
\r
77 mts = new MelodyTrackSpec(1, "Chord track", new Range(60,72));
\r
79 mts = new MelodyTrackSpec(0, "Melody track", new Range(60,84));
\r
80 mts.randomMelody = true;
\r
81 mts.beatPattern = 0xFFFF;
\r
82 mts.continuousBeatPattern = 0x820A;
\r
88 public Action openAction = new AbstractAction("New") {
\r
90 String tooltip = "Generate new song - 新しい曲を生成";
\r
91 putValue(Action.SHORT_DESCRIPTION, tooltip);
\r
94 public void actionPerformed(ActionEvent e) { setVisible(true); }
\r
96 private MidiSequenceEditor midiEditor;
\r
100 public Action generateAction = new AbstractAction(
\r
101 "Generate & Add to PlayList",
\r
102 new ButtonIcon(ButtonIcon.EJECT_ICON)
\r
105 public void actionPerformed(ActionEvent e) {
\r
106 midiEditor.sequenceListTable.getModel().addSequenceAndPlay(getMidiSequence());
\r
107 NewSequenceDialog.this.setVisible(false);
\r
111 * 新しいMIDIシーケンスを生成するダイアログを構築します。
\r
112 * @param midiEditor シーケンス追加先エディタ
\r
114 public NewSequenceDialog(MidiSequenceEditor midiEditor) {
\r
115 this.midiEditor = midiEditor;
\r
116 trackSpecPanel.setChannels(midiEditor.getVirtualMidiDevice().getChannels());
\r
117 setTitle("Generate new sequence - " + ChordHelperApplet.VersionInfo.NAME);
\r
118 add(new JTabbedPane() {{
\r
119 add("Sequence", new JPanel() {{
\r
120 setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
\r
121 add(new JPanel() {{
\r
122 setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
\r
123 add(new JLabel("Sequence name:"));
\r
126 add(new JPanel() {{
\r
127 setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
\r
128 add(new JLabel("Resolution in PPQ ="));
\r
130 add(measureSelecter);
\r
132 add(new JButton("Randomize (Tempo, Time signature, Chord progression)") {{
\r
133 setMargin(ZERO_INSETS);
\r
134 addActionListener(new ActionListener() {
\r
136 public void actionPerformed(ActionEvent e) {
\r
137 setRandomChordProgression(
\r
138 measureSelecter.getMeasureDuration()
\r
143 add(new JPanel() {{
\r
144 setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
\r
145 add(tempoSelecter);
\r
146 add(new JPanel() {{
\r
147 add(new JLabel("Time signature ="));
\r
148 add(timesigSelecter);
\r
151 add(new JPanel() {{
\r
152 setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
\r
153 add(new JLabel("Chord progression :"));
\r
154 add(new JLabel("Transpose"));
\r
155 add(new JButton(" + Up ") {{
\r
156 setMargin(ZERO_INSETS);
\r
157 addActionListener(new ActionListener() {
\r
159 public void actionPerformed(ActionEvent e) {
\r
160 ChordProgression cp = createChordProgression();
\r
162 setChordProgression(cp);
\r
166 add(new JButton(" - Down ") {{
\r
167 setMargin(ZERO_INSETS);
\r
168 addActionListener(new ActionListener() {
\r
170 public void actionPerformed(ActionEvent e) {
\r
171 ChordProgression cp = createChordProgression();
\r
173 setChordProgression(cp);
\r
177 add(new JButton(" Enharmonic ") {{
\r
178 setMargin(ZERO_INSETS);
\r
179 addActionListener(new ActionListener() {
\r
181 public void actionPerformed(ActionEvent e) {
\r
182 ChordProgression cp = createChordProgression();
\r
183 cp.toggleEnharmonically();
\r
184 setChordProgression(cp);
\r
188 add(new JButton("Relative key") {{
\r
189 setMargin(ZERO_INSETS);
\r
190 addActionListener(new ActionListener() {
\r
192 public void actionPerformed(ActionEvent e) {
\r
193 ChordProgression cp = createChordProgression();
\r
194 cp.toggleKeyMajorMinor();
\r
195 setChordProgression(cp);
\r
200 add(new JScrollPane(chordText));
\r
201 add(new JPanel() {{
\r
202 setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
\r
203 add(new JButton(generateAction){{setMargin(ZERO_INSETS);}});
\r
206 add("Track", trackSpecPanel);
\r
208 setBounds( 250, 200, 600, 540 );
\r
211 * 新しいコード進行を生成して返します。
\r
214 private ChordProgression createChordProgression() {
\r
215 return new ChordProgression(chordText.getText());
\r
218 * MIDIシーケンスを生成して返します。
\r
219 * @return MIDIシーケンス
\r
221 public Sequence getMidiSequence() {
\r
222 FirstTrackSpec firstTrackSpec = new FirstTrackSpec(
\r
223 seqNameText.getText(),
\r
224 tempoSelecter.getTempoByteArray(),
\r
225 timesigSelecter.getByteArray()
\r
227 return createChordProgression().toMidiSequence(
\r
228 (int)ppqComboBox.getSelectedItem(),
\r
229 measureSelecter.getStartMeasurePosition(),
\r
230 measureSelecter.getEndMeasurePosition(),
\r
232 trackSpecPanel.getTrackSpecs()
\r
236 * コード進行を設定します。テキスト欄に反映されます。
\r
239 public void setChordProgression(ChordProgression cp) {
\r
240 chordText.setText(cp.toString());
\r
243 * テンポ・拍子・コード進行をランダムに設定
\r
244 * @param measureLength 小節数
\r
246 public void setRandomChordProgression(int measureLength) {
\r
247 tempoSelecter.setTempo( 80 + (int)(Math.random() * 100) );
\r
248 int timesig_upper = 4;
\r
249 int timesig_lower_index = 2;
\r
250 switch( (int)(Math.random() * 10) ) {
\r
251 case 0: timesig_upper = 3; break; // 3/4
\r
253 timesigSelecter.setValue((byte)timesig_upper, (byte)timesig_lower_index);
\r
254 setChordProgression(new ChordProgression(measureLength, timesig_upper));
\r
259 private static class TrackSpecPanel extends JPanel
\r
260 implements PianoKeyboardListener, ActionListener, ChangeListener
\r
262 JComboBox<AbstractNoteTrackSpec> trackSelecter = new JComboBox<>();
\r
263 JLabel trackTypeLabel = new JLabel();
\r
264 JTextField nameTextField = new JTextField(20);
\r
265 MidiChannelComboSelecter chSelecter =
\r
266 new MidiChannelComboSelecter("MIDI Channel:");
\r
267 MidiProgramSelecter pgSelecter = new MidiProgramSelecter();
\r
268 MidiProgramFamilySelecter pgFamilySelecter =
\r
269 new MidiProgramFamilySelecter(pgSelecter) {{
\r
270 pgSelecter.setFamilySelecter(pgFamilySelecter);
\r
272 PianoKeyboardPanel keyboardPanel = new PianoKeyboardPanel() {{
\r
273 keyboard.octaveSizeModel.setValue(6);
\r
274 keyboard.setPreferredSize(new Dimension(400,40));
\r
275 keyboard.setMaxSelectable(2);
\r
277 JPanel rangePanel = new JPanel() {{
\r
278 add( new JLabel("Range:") );
\r
279 add(keyboardPanel);
\r
281 JCheckBox randomMelodyCheckbox = new JCheckBox("Random melody");
\r
282 JCheckBox bassCheckbox = new JCheckBox("Bass note");
\r
283 JCheckBox randomLyricCheckbox = new JCheckBox("Random lyrics");
\r
284 JCheckBox nsx39Checkbox = new JCheckBox("NSX-39");;
\r
285 BeatPadPanel beatPadPanel = new BeatPadPanel(this);
\r
286 private MidiChannel[] midiChannels;
\r
288 public TrackSpecPanel() {
\r
289 nameTextField.addActionListener(this);
\r
290 keyboardPanel.keyboard.addPianoKeyboardListener(this);
\r
291 add(new JPanel() {{
\r
292 add(new JLabel("Track select:"));
\r
293 add(trackSelecter);
\r
295 add(trackTypeLabel);
\r
296 add(new JPanel() {{
\r
297 add(new JLabel("Track name (Press [Enter] key to change):"));
\r
298 add(nameTextField);
\r
301 add(new VelocitySelecter(keyboardPanel.keyboard.velocityModel));
\r
302 add(new JPanel() {{
\r
303 add(pgFamilySelecter);
\r
307 bassCheckbox.addChangeListener(this);
\r
309 randomMelodyCheckbox.addChangeListener(this);
\r
310 add(randomMelodyCheckbox);
\r
311 randomLyricCheckbox.addChangeListener(this);
\r
312 add(randomLyricCheckbox);
\r
313 nsx39Checkbox.addChangeListener(this);
\r
314 add(nsx39Checkbox);
\r
316 trackSelecter.addActionListener(this);
\r
317 chSelecter.comboBox.addActionListener(this);
\r
318 keyboardPanel.keyboard.velocityModel.addChangeListener(
\r
319 new ChangeListener() {
\r
320 public void stateChanged(ChangeEvent e) {
\r
321 AbstractNoteTrackSpec ants = getTrackSpec();
\r
322 ants.velocity = keyboardPanel.keyboard.velocityModel.getValue();
\r
326 pgSelecter.addActionListener(this);
\r
329 public void stateChanged(ChangeEvent e) {
\r
330 Object src = e.getSource();
\r
331 if( src == bassCheckbox ) {
\r
332 AbstractNoteTrackSpec ants = getTrackSpec();
\r
333 if( ants instanceof MelodyTrackSpec ) {
\r
334 MelodyTrackSpec mts = (MelodyTrackSpec)ants;
\r
335 mts.isBass = bassCheckbox.isSelected();
\r
338 else if( src == randomMelodyCheckbox ) {
\r
339 AbstractNoteTrackSpec ants = getTrackSpec();
\r
340 if( ants instanceof MelodyTrackSpec ) {
\r
341 MelodyTrackSpec mts = (MelodyTrackSpec)ants;
\r
342 mts.randomMelody = randomMelodyCheckbox.isSelected();
\r
345 else if( src == randomLyricCheckbox ) {
\r
346 AbstractNoteTrackSpec ants = getTrackSpec();
\r
347 if( ants instanceof MelodyTrackSpec ) {
\r
348 MelodyTrackSpec mts = (MelodyTrackSpec)ants;
\r
349 mts.randomLyric = randomLyricCheckbox.isSelected();
\r
352 else if( src == nsx39Checkbox ) {
\r
353 AbstractNoteTrackSpec ants = getTrackSpec();
\r
354 if( ants instanceof MelodyTrackSpec ) {
\r
355 MelodyTrackSpec mts = (MelodyTrackSpec)ants;
\r
356 mts.nsx39 = nsx39Checkbox.isSelected();
\r
361 public void actionPerformed(ActionEvent e) {
\r
362 Object src = e.getSource();
\r
363 AbstractNoteTrackSpec ants;
\r
364 if( src == nameTextField ) {
\r
365 getTrackSpec().name = nameTextField.getText();
\r
367 else if( src == trackSelecter ) {
\r
368 ants = (AbstractNoteTrackSpec)(trackSelecter.getSelectedItem());
\r
369 String trackTypeString = "Track type: " + (
\r
370 ants instanceof DrumTrackSpec ? "Percussion" :
\r
371 ants instanceof MelodyTrackSpec ? "Melody" : "(Unknown)"
\r
373 trackTypeLabel.setText(trackTypeString);
\r
374 nameTextField.setText(ants.name);
\r
375 chSelecter.setSelectedChannel(ants.midiChannel);
\r
376 keyboardPanel.keyboard.velocityModel.setValue(ants.velocity);
\r
377 pgSelecter.setProgram(ants.programNumber);
\r
378 keyboardPanel.keyboard.clear();
\r
379 if( ants instanceof DrumTrackSpec ) {
\r
380 rangePanel.setVisible(false);
\r
381 randomMelodyCheckbox.setVisible(false);
\r
382 randomLyricCheckbox.setVisible(false);
\r
383 nsx39Checkbox.setVisible(false);
\r
384 bassCheckbox.setVisible(false);
\r
386 else if( ants instanceof MelodyTrackSpec ) {
\r
387 MelodyTrackSpec ts = (MelodyTrackSpec)ants;
\r
388 rangePanel.setVisible(true);
\r
389 keyboardPanel.keyboard.setSelectedNote(ts.range.min_note);
\r
390 keyboardPanel.keyboard.setSelectedNote(ts.range.max_note);
\r
391 keyboardPanel.keyboard.autoScroll(ts.range.min_note);
\r
392 randomMelodyCheckbox.setSelected(ts.randomMelody);
\r
393 randomLyricCheckbox.setSelected(ts.randomLyric);
\r
394 bassCheckbox.setSelected(ts.isBass);
\r
395 randomMelodyCheckbox.setVisible(true);
\r
396 randomLyricCheckbox.setVisible(true);
\r
397 nsx39Checkbox.setVisible(true);
\r
398 bassCheckbox.setVisible(true);
\r
400 beatPadPanel.setTrackSpec(ants);
\r
402 else if( src == chSelecter.comboBox ) {
\r
403 getTrackSpec().midiChannel = chSelecter.getSelectedChannel();
\r
405 else if( src == pgSelecter ) {
\r
406 getTrackSpec().programNumber = pgSelecter.getProgram();
\r
410 public void pianoKeyPressed(int n, InputEvent e) {
\r
412 AbstractNoteTrackSpec ants = getTrackSpec();
\r
413 if( ants instanceof MelodyTrackSpec ) {
\r
414 MelodyTrackSpec ts = (MelodyTrackSpec)ants;
\r
415 ts.range = new Range(keyboardPanel.keyboard.getSelectedNotes());
\r
419 public void pianoKeyReleased(int n, InputEvent e) { noteOff(n); }
\r
420 public void octaveMoved(ChangeEvent event) {}
\r
421 public void octaveResized(ChangeEvent event) {}
\r
422 public void noteOn(int n) {
\r
423 if( midiChannels == null ) return;
\r
424 MidiChannel mc = midiChannels[chSelecter.getSelectedChannel()];
\r
425 mc.noteOn( n, keyboardPanel.keyboard.velocityModel.getValue() );
\r
427 public void noteOff(int n) {
\r
428 if( midiChannels == null ) return;
\r
429 MidiChannel mc = midiChannels[chSelecter.getSelectedChannel()];
\r
430 mc.noteOff( n, keyboardPanel.keyboard.velocityModel.getValue() );
\r
432 public void setChannels( MidiChannel midiChannels[] ) {
\r
433 this.midiChannels = midiChannels;
\r
435 public AbstractNoteTrackSpec getTrackSpec() {
\r
436 Object trackSpecObj = trackSelecter.getSelectedItem();
\r
437 AbstractNoteTrackSpec ants = (AbstractNoteTrackSpec)trackSpecObj;
\r
438 ants.name = nameTextField.getText();
\r
441 public Vector<AbstractNoteTrackSpec> getTrackSpecs() {
\r
442 Vector<AbstractNoteTrackSpec> trackSpecs = new Vector<>();
\r
443 int i=0, n_items = trackSelecter.getItemCount();
\r
444 while( i < n_items ) {
\r
445 trackSpecs.add((AbstractNoteTrackSpec)trackSelecter.getItemAt(i++));
\r
449 public void addTrackSpec(AbstractNoteTrackSpec trackSpec) {
\r
450 trackSelecter.addItem(trackSpec);
\r
453 private static class MeasureSelecter extends JPanel {
\r
454 public MeasureSelecter() {
\r
455 setLayout(new GridLayout(2,3));
\r
457 add(new JLabel("Start",JLabel.CENTER));
\r
458 add(new JLabel("End",JLabel.CENTER));
\r
459 add(new JLabel("Measure",JLabel.RIGHT));
\r
460 add(new JSpinner(startModel));
\r
461 add(new JSpinner(endModel));
\r
463 private SpinnerNumberModel startModel = new SpinnerNumberModel( 3, 1, 9999, 1 );
\r
464 private SpinnerNumberModel endModel = new SpinnerNumberModel( 8, 1, 9999, 1 );
\r
465 public int getStartMeasurePosition() {
\r
466 return startModel.getNumber().intValue();
\r
468 public int getEndMeasurePosition() {
\r
469 return endModel.getNumber().intValue();
\r
471 public int getMeasureDuration() {
\r
472 return getEndMeasurePosition() - getStartMeasurePosition() + 1;
\r
475 //////////////////////////////////////////////////////////////////
\r
477 // □=□=□=□=□=□=□=□=
\r
478 // □=□=□=□=□=□=□=□=
\r
480 private static class BeatPadPanel extends JPanel implements ActionListener {
\r
481 PianoKeyboardListener piano_keyboard_listener;
\r
482 JPanel percussion_selecters_panel;
\r
483 java.util.List<JComboBox<String>> percussionSelecters =
\r
484 new ArrayList<JComboBox<String>>() {
\r
486 for( int i=0; i < DrumTrackSpec.defaultPercussions.length; i++ ) {
\r
487 add(new JComboBox<String>());
\r
493 public BeatPadPanel(PianoKeyboardListener pkl) {
\r
494 piano_keyboard_listener = pkl;
\r
495 percussion_selecters_panel = new JPanel();
\r
496 percussion_selecters_panel.setLayout(
\r
497 new BoxLayout( percussion_selecters_panel, BoxLayout.Y_AXIS )
\r
499 for( JComboBox<String> cb : percussionSelecters ) {
\r
500 percussion_selecters_panel.add(cb);
\r
501 cb.addActionListener(this);
\r
503 add( percussion_selecters_panel );
\r
504 add( beat_pad = new BeatPad(pkl) );
\r
505 beat_pad.setPreferredSize( new Dimension(400,200) );
\r
506 setLayout( new BoxLayout( this, BoxLayout.X_AXIS ) );
\r
508 public void actionPerformed(ActionEvent e) {
\r
509 Object src = e.getSource();
\r
510 for( JComboBox<String> cb : percussionSelecters ) {
\r
511 if( src != cb ) continue;
\r
513 (DrumTrackSpec.PercussionComboBoxModel)cb.getModel()
\r
514 ).getSelectedNoteNo();
\r
515 piano_keyboard_listener.pianoKeyPressed(note_no,(InputEvent)null);
\r
518 public void setTrackSpec( AbstractNoteTrackSpec ants ) {
\r
519 beat_pad.setTrackSpec(ants);
\r
520 if( ants instanceof DrumTrackSpec ) {
\r
521 DrumTrackSpec dts = (DrumTrackSpec)ants;
\r
523 for( JComboBox<String> cb : percussionSelecters ) {
\r
524 cb.setModel(dts.models[i++]);
\r
526 percussion_selecters_panel.setVisible(true);
\r
528 else if( ants instanceof MelodyTrackSpec ) {
\r
529 percussion_selecters_panel.setVisible(false);
\r
533 private static class BeatPad extends JComponent implements MouseListener, ComponentListener {
\r
534 PianoKeyboardListener piano_keyboard_listener;
\r
535 private int on_note_no = -1;
\r
536 AbstractNoteTrackSpec track_spec;
\r
538 public static final int MAX_BEATS = 16;
\r
539 Rectangle beat_buttons[][];
\r
540 Rectangle continuous_beat_buttons[][];
\r
542 public BeatPad(PianoKeyboardListener pkl) {
\r
543 piano_keyboard_listener = pkl;
\r
544 addMouseListener(this);
\r
545 addComponentListener(this);
\r
546 // addMouseMotionListener(this);
\r
548 public void paint(Graphics g) {
\r
550 Graphics2D g2 = (Graphics2D) g;
\r
552 int note, beat, mask;
\r
554 if( track_spec instanceof DrumTrackSpec ) {
\r
555 DrumTrackSpec dts = (DrumTrackSpec)track_spec;
\r
556 for( note=0; note<dts.beat_patterns.length; note++ ) {
\r
557 for( beat=0, mask=0x8000; beat<MAX_BEATS; beat++, mask >>>= 1 ) {
\r
558 r = beat_buttons[note][beat];
\r
559 if( (dts.beat_patterns[note] & mask) != 0 )
\r
560 g2.fillRect( r.x, r.y, r.width, r.height );
\r
562 g2.drawRect( r.x, r.y, r.width, r.height );
\r
566 else if( track_spec instanceof MelodyTrackSpec ) {
\r
567 MelodyTrackSpec mts = (MelodyTrackSpec)track_spec;
\r
568 for( beat=0, mask=0x8000; beat<MAX_BEATS; beat++, mask >>>= 1 ) {
\r
569 r = beat_buttons[0][beat];
\r
570 if( (mts.beatPattern & mask) != 0 )
\r
571 g2.fillRect( r.x, r.y, r.width, r.height );
\r
573 g2.drawRect( r.x, r.y, r.width, r.height );
\r
574 r = continuous_beat_buttons[0][beat];
\r
575 if( (mts.continuousBeatPattern & mask) != 0 )
\r
576 g2.fillRect( r.x, r.y, r.width, r.height );
\r
578 g2.drawRect( r.x, r.y, r.width, r.height );
\r
583 public void componentShown(ComponentEvent e) { }
\r
584 public void componentHidden(ComponentEvent e) { }
\r
585 public void componentMoved(ComponentEvent e) { }
\r
586 public void componentResized(ComponentEvent e) {
\r
589 public void mousePressed(MouseEvent e) {
\r
591 if( on_note_no >= 0 ) {
\r
592 piano_keyboard_listener.pianoKeyPressed( on_note_no ,(InputEvent)e );
\r
595 public void mouseReleased(MouseEvent e) {
\r
596 if( on_note_no >= 0 ) {
\r
597 piano_keyboard_listener.pianoKeyReleased( on_note_no ,(InputEvent)e );
\r
601 public void mouseEntered(MouseEvent e) {
\r
602 if((e.getModifiers() & InputEvent.BUTTON1_MASK) == InputEvent.BUTTON1_MASK) {
\r
606 public void mouseExited(MouseEvent e) { }
\r
607 public void mouseClicked(MouseEvent e) { }
\r
608 private void sizeChanged() {
\r
609 int beat, note, width, height;
\r
610 Dimension d = getSize();
\r
612 if( track_spec instanceof DrumTrackSpec ) {
\r
613 DrumTrackSpec dts = (DrumTrackSpec)track_spec;
\r
614 num_notes = dts.models.length;
\r
616 beat_buttons = new Rectangle[num_notes][];
\r
617 continuous_beat_buttons = new Rectangle[num_notes][];
\r
618 for( note=0; note<beat_buttons.length; note++ ) {
\r
619 beat_buttons[note] = new Rectangle[MAX_BEATS];
\r
620 continuous_beat_buttons[note] = new Rectangle[MAX_BEATS];
\r
621 for( beat=0; beat<MAX_BEATS; beat++ ) {
\r
622 width = (d.width * 3) / (MAX_BEATS * 4);
\r
623 height = d.height / num_notes - 1;
\r
624 beat_buttons[note][beat] = new Rectangle(
\r
625 beat * d.width / MAX_BEATS,
\r
630 width = d.width / (MAX_BEATS * 3);
\r
631 continuous_beat_buttons[note][beat] = new Rectangle(
\r
632 (beat+1) * d.width / MAX_BEATS - width + 1,
\r
633 note * height + height / 3,
\r
640 private void catchEvent(MouseEvent e) {
\r
641 Point point = e.getPoint();
\r
642 int note, beat, mask;
\r
645 if( track_spec instanceof DrumTrackSpec ) {
\r
646 DrumTrackSpec dts = (DrumTrackSpec)track_spec;
\r
647 for( note=0; note<dts.beat_patterns.length; note++ ) {
\r
648 for( beat=0, mask=0x8000; beat<MAX_BEATS; beat++, mask >>>= 1 ) {
\r
649 if( beat_buttons[note][beat].contains(point) ) {
\r
650 dts.beat_patterns[note] ^= mask;
\r
651 on_note_no = dts.models[note].getSelectedNoteNo();
\r
657 else if( track_spec instanceof MelodyTrackSpec ) {
\r
658 MelodyTrackSpec mts = (MelodyTrackSpec)track_spec;
\r
659 for( beat=0, mask=0x8000; beat<MAX_BEATS; beat++, mask >>>= 1 ) {
\r
660 if( beat_buttons[0][beat].contains(point) ) {
\r
661 mts.beatPattern ^= mask;
\r
664 if( continuous_beat_buttons[0][beat].contains(point) ) {
\r
665 mts.continuousBeatPattern ^= mask;
\r
671 public void setTrackSpec( AbstractNoteTrackSpec ants ) {
\r