/** * @author julian * @author Nikola Kolarovic * <p>WIDGET SET that allows complex chord choosing<br> * Chord theory according to <a * href="http://www.jazzguitar.be/quick_crd_ref.html">http://www.jazzguitar.be/quick_crd_ref.html</a>. */ public class ChordSelector extends Composite { public static final String[][] KEY_NAMES = new String[][] { TGMusicKeyUtils.getSharpKeyNames(TGMusicKeyUtils.PREFIX_CHORD), TGMusicKeyUtils.getFlatKeyNames(TGMusicKeyUtils.PREFIX_CHORD), }; private ChordDialog dialog; private int[] tuning; private List tonicList; private List chordList; private List alterationList; private Button sharpButton; private Button flatButton; private Combo bassCombo; private Button addCheck; private List plusMinusList; private List _5List; private List _9List; private List _11List; private boolean refresh; public ChordSelector(ChordDialog dialog, Composite parent, int style, int[] tuning) { super(parent, style); this.setLayout(new GridLayout(3, false)); this.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); this.dialog = dialog; this.tuning = tuning; this.refresh = true; this.init(); } public void init() { Composite tonicComposite = new Composite(this, SWT.NONE); tonicComposite.setLayout(this.dialog.gridLayout(1, false, 0, 0)); tonicComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); this.tonicList = new List(tonicComposite, SWT.BORDER); this.tonicList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); // sharp & flat buttons Composite buttonsComposite = new Composite(tonicComposite, SWT.NONE); buttonsComposite.setLayout(this.dialog.gridLayout(2, true, 0, 0)); GridData buttonGd = new GridData(SWT.FILL, SWT.TOP, true, false); buttonGd.heightHint = 28; buttonGd.widthHint = 28; this.sharpButton = new Button(buttonsComposite, SWT.TOGGLE); this.sharpButton.setLayoutData(buttonGd); this.flatButton = new Button(buttonsComposite, SWT.TOGGLE); this.flatButton.setLayoutData(buttonGd); // TODO: maybe put an image instead of #,b this.sharpButton.setText("#"); this.flatButton.setText("b"); this.chordList = new List(this, SWT.BORDER); this.chordList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); Label separator = new Label(tonicComposite, SWT.SEPARATOR | SWT.HORIZONTAL); separator.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, true)); Button customizeButton = new Button(tonicComposite, SWT.PUSH); customizeButton.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, false)); customizeButton.setText(TuxGuitar.getProperty("settings")); customizeButton.addSelectionListener( new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent arg0) { if (new ChordSettingsDialog().open(ChordSelector.this.getShell())) { new SyncThread( new Runnable() { @Override public void run() { ChordSelector.this.showChord(); getChordList().redraw(); } }) .start(); } } }); initChordWidgets(); // fill the List widgets with text insertTonicNames(true); for (int i = 0; i < ChordDatabase.length(); i++) { this.chordList.add(ChordDatabase.get(i).getName()); } /* Iterator chordInfo = ChordCreatorUtil.getChordData().getChords().iterator(); while(chordInfo.hasNext()) { this.chordList.add( ((ChordDatabase.ChordInfo)chordInfo.next()).getName() ); } */ this.chordList.setSelection(0); String[] alterationNames = getAlterationNames(); for (int i = 0; i < alterationNames.length; i++) { this.alterationList.add(alterationNames[i]); } this.alterationList.setSelection(0); String[] plusMinus = this.getPlusMinus(""); for (int i = 0; i < plusMinus.length; i++) { this.plusMinusList.add(plusMinus[i]); } this.plusMinusList.setSelection(0); String[] plus5Minus = this.getPlusMinus("/5"); for (int i = 0; i < plus5Minus.length; i++) { this._5List.add(plus5Minus[i]); } this._5List.setSelection(0); String[] plus9Minus = this.getPlusMinus("/9"); for (int i = 0; i < plus9Minus.length; i++) { this._9List.add(plus9Minus[i]); } this._9List.setSelection(0); String[] plus11Minus = this.getPlusMinus("/11"); for (int i = 0; i < plus11Minus.length; i++) { this._11List.add(plus11Minus[i]); } this._11List.setSelection(0); // LISTENERS this.tonicList.addSelectionListener( new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { if (ChordSelector.this.getRefresh()) { if (getDialog().getEditor() != null && getDialog().getList() != null) { getBassCombo().select(getTonicList().getSelectionIndex()); showChord(); } } } }); this.bassCombo.addSelectionListener( new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { if (ChordSelector.this.getRefresh()) { if (getDialog().getEditor() != null && getDialog().getList() != null) { showChord(); } } } }); this.chordList.addSelectionListener( new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { if (getDialog().getEditor() != null && getDialog().getList() != null) { adjustWidgetAvailability(); if (ChordSelector.this.getRefresh()) { showChord(); } } } }); this.alterationList.addSelectionListener( new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { if (getDialog().getEditor() != null && getDialog().getList() != null) { ChordSelector.this.adjustWidgetAvailability(); if (ChordSelector.this.getRefresh()) { showChord(); } } } }); this.addCheck.addSelectionListener( new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent arg0) { if (getDialog().getEditor() != null && getDialog().getList() != null) { ChordSelector.this.adjustWidgetAvailability(); /* if (getAddCheck().getSelection()) { updateWidget(get_9List(), false); updateWidget(get_11List(), false); } */ if (ChordSelector.this.getRefresh()) { showChord(); // ChordSelector.this.dialog.getList().redraw(); } } } }); this._5List.addSelectionListener( new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { if (getDialog().getEditor() != null && getDialog().getList() != null) { if (ChordSelector.this.getRefresh()) { showChord(); } } } }); this._9List.addSelectionListener( new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { if (getDialog().getEditor() != null && getDialog().getList() != null) { if (ChordSelector.this.getRefresh()) { showChord(); } } } }); this._11List.addSelectionListener( new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { if (getDialog().getEditor() != null && getDialog().getList() != null) { if (ChordSelector.this.getRefresh()) { showChord(); } } } }); this.plusMinusList.addSelectionListener( new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { if (getDialog().getEditor() != null && getDialog().getList() != null) { if (ChordSelector.this.getRefresh()) { showChord(); // ChordSelector.this.dialog.getList().redraw(); } } } }); this.sharpButton.addSelectionListener( new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent arg0) { insertTonicNames(true); } }); this.flatButton.addSelectionListener( new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent arg0) { insertTonicNames(false); } }); this.adjustWidgetAvailability(); } protected void initChordWidgets() { Composite alterationComposite = new Composite(this, SWT.NONE); alterationComposite.setLayout(this.dialog.gridLayout(1, true, 0, 0)); alterationComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); Composite aboveComposite = new Composite(alterationComposite, SWT.NONE); aboveComposite.setLayout(this.dialog.gridLayout(2, true, 0, 0)); aboveComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); Composite firstComposite = new Composite(aboveComposite, SWT.NONE); firstComposite.setLayout(this.dialog.gridLayout(1, false, 0, 0)); firstComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); this.alterationList = new List(firstComposite, SWT.BORDER); this.alterationList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); this.plusMinusList = new List(firstComposite, SWT.BORDER); this.plusMinusList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); Composite secondComposite = new Composite(aboveComposite, SWT.NONE); secondComposite.setLayout(this.dialog.gridLayout(1, false, 0, 0)); secondComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); this._5List = new List(secondComposite, SWT.BORDER); this._5List.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); this._9List = new List(secondComposite, SWT.BORDER); this._9List.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); this._11List = new List(secondComposite, SWT.BORDER); this._11List.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); Composite bassComposite = new Composite(alterationComposite, SWT.NONE); bassComposite.setLayout(this.dialog.gridLayout(1, true, 0, 0)); bassComposite.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, true)); this.addCheck = new Button(bassComposite, SWT.CHECK | SWT.LEFT); this.addCheck.setText("add"); // this.addCheck.setSelection(false); // this.addCheck.setEnabled(false); this.addCheck.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, true)); Label separator = new Label(bassComposite, SWT.SEPARATOR | SWT.HORIZONTAL); separator.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, true)); Label bText = new Label(bassComposite, SWT.LEFT); bText.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, false)); bText.setText(TuxGuitar.getProperty("chord.bass")); this.bassCombo = new Combo(bassComposite, SWT.DROP_DOWN | SWT.READ_ONLY); this.bassCombo.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, false)); } protected void insertTonicNames(boolean sharp) { String[] names = KEY_NAMES[sharp ? 0 : 1]; // update the buttons this.flatButton.setSelection(!sharp); this.sharpButton.setSelection(sharp); // keep the old position int indexL = this.tonicList.getSelectionIndex(); if (indexL == -1) indexL = 0; int indexC = this.bassCombo.getSelectionIndex(); if (indexC == -1) indexC = 0; // update the list this.tonicList.removeAll(); this.bassCombo.removeAll(); for (int i = 0; i < names.length; i++) { this.tonicList.add(names[i]); this.bassCombo.add(names[i]); } this.tonicList.setSelection(indexL); this.bassCombo.select(indexC); } private String[] getPlusMinus(String text) { String[] names = new String[3]; names[0] = " "; names[1] = text + "+"; names[2] = text + "-"; return names; } private String[] getAlterationNames() { String[] names = new String[4]; names[0] = " "; names[1] = "9"; names[2] = "11"; names[3] = "13"; return names; } protected void showChord() { TuxGuitar.instance().loadCursor(getShell(), SWT.CURSOR_WAIT); ChordCreatorListener listener = new ChordCreatorListener() { @Override public void notifyChords( final ChordCreatorUtil instance, final java.util.List<TGChord> chords) { try { TGSynchronizer.instance() .addRunnable( new TGSynchronizer.TGRunnable() { @Override public void run() { if (instance.isValidProcess() && !getDialog().isDisposed()) { getDialog().getList().setChords(chords); TuxGuitar.instance().loadCursor(getShell(), SWT.CURSOR_ARROW); } } }); } catch (Throwable e) { e.printStackTrace(); } } }; ChordCreatorUtil.getChords( listener, this.tuning, this.chordList.getSelectionIndex(), this.alterationList.getSelectionIndex(), this.plusMinusList.getSelectionIndex(), this.addCheck.getSelection(), this._5List.getSelectionIndex(), this._9List.getSelectionIndex(), this._11List.getSelectionIndex(), this.bassCombo.getSelectionIndex(), this.tonicList.getSelectionIndex(), this.sharpButton.getSelection()); } protected void updateWidget(List widget, boolean enabled) { widget.setEnabled(enabled); if (!enabled) { widget.setSelection(0); } } protected void updateWidget(Button widget, boolean enabled) { widget.setEnabled(enabled); if (!enabled) { widget.setSelection(false); } } /** Sets all the widgets' fields into recognized chord (tonic, bass, chord, alterations) */ public void adjustWidgets( int tonic, int chordBasic, int alteration, int bass, int plusMinus, int addBoolean, int index5, int index9, int index11) { this.setRefresh(false); // adjust widgets this.tonicList.setSelection(tonic); this.alterationList.setSelection(alteration); this.bassCombo.select(bass); this.plusMinusList.setSelection(plusMinus); this.addCheck.setSelection(addBoolean != 0); this._5List.setSelection(index5); this._9List.setSelection(index9); this._11List.setSelection(index11); this.chordList.setSelection(chordBasic); this.adjustWidgetAvailability(); this.setRefresh(true); this.showChord(); } /** adjusts the widgets availability according to chord theory options */ protected void adjustWidgetAvailability() { String chordName = ChordDatabase.get(getChordList().getSelectionIndex()).getName(); if (chordName.equals("dim") || chordName.equals("dim7") || chordName.equals("aug") || chordName.equals("5")) { updateWidget(getAlterationList(), false); updateWidget(getAddCheck(), false); updateWidget(get_9List(), false); updateWidget(get_11List(), false); updateWidget(getPlusMinusList(), false); if (!chordName.equals("5")) { updateWidget(get_5List(), false); // disableWidget(get_5List()); } else { updateWidget(get_5List(), true); } } else { // enable and don't change the selection index // getAlterationList().setEnabled(true); // get_5List().setEnabled(true); updateWidget(getAlterationList(), true); updateWidget(get_5List(), true); } if (this.alterationList.isEnabled()) { int currentIndex = this.alterationList.getSelectionIndex(); // handle the +- list and ADD checkbox // handle the 9 and 11 list updateWidget(this.plusMinusList, (currentIndex > 0)); updateWidget(this.addCheck, (currentIndex > 0)); updateWidget(this._9List, (currentIndex >= 2 && !this.addCheck.getSelection())); updateWidget(this._11List, (currentIndex >= 3 && !this.addCheck.getSelection())); } } public boolean getRefresh() { return this.refresh; } public void setRefresh(boolean refresh) { this.refresh = refresh; } public void setTuning(int[] tuning) { this.tuning = tuning; } public int[] getTuning() { return this.tuning; } protected ChordDialog getDialog() { return this.dialog; } protected List getTonicList() { return this.tonicList; } protected List getChordList() { return this.chordList; } protected List getAlterationList() { return this.alterationList; } protected Button getSharpButton() { return this.sharpButton; } protected Button getFlatButton() { return this.flatButton; } protected Combo getBassCombo() { return this.bassCombo; } protected Button getAddCheck() { return this.addCheck; } protected List getPlusMinusList() { return this.plusMinusList; } protected List get_5List() { return this._5List; } protected List get_9List() { return this._9List; } protected List get_11List() { return this._11List; } }
public class MatrixEditor implements TGRedrawListener, IconLoader, LanguageLoader { private static final int BORDER_HEIGHT = 20; private static final int SCROLL_INCREMENT = 50; private static final String[] NOTE_NAMES = TGMusicKeyUtils.getSharpKeyNames(TGMusicKeyUtils.PREFIX_MATRIX); private static final MidiPercussion[] PERCUSSIONS = TuxGuitar.instance().getPlayer().getPercussions(); protected static final int[] DIVISIONS = new int[] {1, 2, 3, 4, 6, 8, 16}; private MatrixConfig config; private MatrixListener listener; private Shell dialog; private Composite composite; private Composite toolbar; private Composite editor; private Rectangle clientArea; private TGImage buffer; private BufferDisposer bufferDisposer; private Label durationLabel; private Label gridsLabel; private Button settings; private float width; private float height; private float bufferWidth; private float bufferHeight; private float timeWidth; private float lineHeight; private int leftSpacing; private int minNote; private int maxNote; private int duration; private int selection; private int grids; private int playedTrack; private int playedMeasure; private TGBeat playedBeat; private TGImage selectionBackBuffer; private int selectionX; private int selectionY; private boolean selectionPaintDisabled; public MatrixEditor() { this.grids = this.loadGrids(); this.listener = new MatrixListener(); } public void show() { this.config = new MatrixConfig(); this.config.load(); this.dialog = DialogUtils.newDialog(TuxGuitar.instance().getShell(), SWT.DIALOG_TRIM | SWT.RESIZE); this.dialog.setText(TuxGuitar.getProperty("matrix.editor")); this.dialog.setImage(TuxGuitar.instance().getIconManager().getAppIcon()); this.dialog.setLayout(new GridLayout()); this.dialog.addDisposeListener(new DisposeListenerImpl()); this.bufferDisposer = new BufferDisposer(); this.composite = new Composite(this.dialog, SWT.NONE); this.composite.setLayout(new GridLayout()); this.composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); this.initToolBar(); this.initEditor(); this.loadIcons(); this.addListeners(); this.dialog.addDisposeListener( new DisposeListener() { public void widgetDisposed(DisposeEvent e) { removeListeners(); TuxGuitar.instance().updateCache(true); } }); DialogUtils.openDialog(this.dialog, DialogUtils.OPEN_STYLE_CENTER); } public void addListeners() { TuxGuitar.instance().getkeyBindingManager().appendListenersTo(this.toolbar); TuxGuitar.instance().getkeyBindingManager().appendListenersTo(this.editor); TuxGuitar.instance().getIconManager().addLoader(this); TuxGuitar.instance().getLanguageManager().addLoader(this); TuxGuitar.instance().getEditorManager().addRedrawListener(this); } public void removeListeners() { TuxGuitar.instance().getIconManager().removeLoader(this); TuxGuitar.instance().getLanguageManager().removeLoader(this); TuxGuitar.instance().getEditorManager().removeRedrawListener(this); } private void initToolBar() { GridLayout layout = new GridLayout(); layout.makeColumnsEqualWidth = false; layout.numColumns = 0; layout.marginWidth = 0; layout.marginHeight = 0; this.toolbar = new Composite(this.composite, SWT.NONE); // position layout.numColumns++; Button goLeft = new Button(this.toolbar, SWT.ARROW | SWT.LEFT); goLeft.addSelectionListener(TuxGuitar.instance().getAction(GoLeftAction.NAME)); layout.numColumns++; Button goRight = new Button(this.toolbar, SWT.ARROW | SWT.RIGHT); goRight.addSelectionListener(TuxGuitar.instance().getAction(GoRightAction.NAME)); // separator layout.numColumns++; makeToolSeparator(this.toolbar); // duration layout.numColumns++; Button decrement = new Button(this.toolbar, SWT.ARROW | SWT.MIN); decrement.addSelectionListener(TuxGuitar.instance().getAction(DecrementDurationAction.NAME)); layout.numColumns++; this.durationLabel = new Label(this.toolbar, SWT.BORDER); layout.numColumns++; Button increment = new Button(this.toolbar, SWT.ARROW | SWT.MAX); increment.addSelectionListener(TuxGuitar.instance().getAction(IncrementDurationAction.NAME)); // separator layout.numColumns++; makeToolSeparator(this.toolbar); // grids layout.numColumns++; this.gridsLabel = new Label(this.toolbar, SWT.NONE); this.gridsLabel.setText(TuxGuitar.getProperty("matrix.grids")); layout.numColumns++; final Combo divisionsCombo = new Combo(this.toolbar, SWT.DROP_DOWN | SWT.READ_ONLY); divisionsCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, true)); for (int i = 0; i < DIVISIONS.length; i++) { divisionsCombo.add(Integer.toString(DIVISIONS[i])); if (this.grids == DIVISIONS[i]) { divisionsCombo.select(i); } } if (this.grids == 0) { divisionsCombo.select(0); } divisionsCombo.addSelectionListener( new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { int index = divisionsCombo.getSelectionIndex(); if (index >= 0 && index < DIVISIONS.length) { setGrids(DIVISIONS[index]); } } }); // settings layout.numColumns++; this.settings = new Button(this.toolbar, SWT.PUSH); this.settings.setImage(TuxGuitar.instance().getIconManager().getSettings()); this.settings.setToolTipText(TuxGuitar.getProperty("settings")); this.settings.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, true, true)); this.settings.addSelectionListener( new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { configure(); } }); this.toolbar.setLayout(layout); this.toolbar.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); } private void makeToolSeparator(Composite parent) { Label separator = new Label(parent, SWT.SEPARATOR); separator.setLayoutData(new GridData(20, 20)); } private void loadDurationImage(boolean force) { int duration = TuxGuitar.instance() .getTablatureEditor() .getTablature() .getCaret() .getDuration() .getValue(); if (force || this.duration != duration) { this.duration = duration; this.durationLabel.setImage(TuxGuitar.instance().getIconManager().getDuration(this.duration)); } } public void initEditor() { this.selection = -1; this.editor = new Composite( this.composite, SWT.DOUBLE_BUFFERED | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); this.editor.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); this.editor.setLayout(new FillLayout()); this.editor.setFocus(); this.editor.addPaintListener(this.listener); this.editor.addMouseListener(this.listener); this.editor.addMouseMoveListener(this.listener); this.editor.addMouseTrackListener(this.listener); this.editor.getHorizontalBar().setIncrement(SCROLL_INCREMENT); this.editor .getHorizontalBar() .addListener( SWT.Selection, new Listener() { public void handleEvent(Event event) { redrawLocked(); } }); this.editor.getVerticalBar().setIncrement(SCROLL_INCREMENT); this.editor .getVerticalBar() .addListener( SWT.Selection, new Listener() { public void handleEvent(Event event) { redrawLocked(); } }); } protected void updateScroll() { if (this.clientArea != null) { int borderWidth = this.editor.getBorderWidth(); ScrollBar vBar = this.editor.getVerticalBar(); ScrollBar hBar = this.editor.getHorizontalBar(); vBar.setMaximum(Math.round(this.height + (borderWidth * 2))); vBar.setThumb(Math.round(Math.min(this.height + (borderWidth * 2), this.clientArea.height))); hBar.setMaximum(Math.round(this.width + (borderWidth * 2))); hBar.setThumb(Math.round(Math.min(this.width + (borderWidth * 2), this.clientArea.width))); } } protected int getValueAt(float y) { if (this.clientArea == null || (y - BORDER_HEIGHT) < 0 || y + BORDER_HEIGHT > this.clientArea.height) { return -1; } int scroll = this.editor.getVerticalBar().getSelection(); int value = (this.maxNote - ((int) ((y + scroll - BORDER_HEIGHT) / this.lineHeight))); return value; } protected long getStartAt(float x) { TGMeasure measure = getMeasure(); float posX = (x + this.editor.getHorizontalBar().getSelection()); long start = (long) (measure.getStart() + (((posX - this.leftSpacing) * measure.getLength()) / (this.timeWidth * measure.getTimeSignature().getNumerator()))); return start; } protected void paintEditor(TGPainter painter) { if (!TuxGuitar.instance().getPlayer().isRunning()) { this.resetPlayed(); } this.disposeSelectionBuffer(); this.clientArea = this.editor.getClientArea(); if (this.clientArea != null) { TGImage buffer = getBuffer(); this.width = this.bufferWidth; this.height = (this.bufferHeight + (BORDER_HEIGHT * 2)); this.updateScroll(); int scrollX = this.editor.getHorizontalBar().getSelection(); int scrollY = this.editor.getVerticalBar().getSelection(); painter.drawImage(buffer, -scrollX, (BORDER_HEIGHT - scrollY)); this.paintMeasure(painter, (-scrollX), (BORDER_HEIGHT - scrollY)); this.paintBorders(painter, (-scrollX), 0); this.paintPosition(painter, (-scrollX), 0); this.paintSelection(painter, (-scrollX), (BORDER_HEIGHT - scrollY)); } } protected TGImage getBuffer() { if (this.clientArea != null) { this.bufferDisposer.update(this.clientArea.width, this.clientArea.height); if (this.buffer == null || this.buffer.isDisposed()) { String[] names = null; TGMeasure measure = getMeasure(); this.maxNote = 0; this.minNote = 127; if (TuxGuitar.instance() .getSongManager() .isPercussionChannel(measure.getTrack().getChannelId())) { names = new String[PERCUSSIONS.length]; for (int i = 0; i < names.length; i++) { this.minNote = Math.min(this.minNote, PERCUSSIONS[i].getValue()); this.maxNote = Math.max(this.maxNote, PERCUSSIONS[i].getValue()); names[i] = PERCUSSIONS[names.length - i - 1].getName(); } } else { for (int sNumber = 1; sNumber <= measure.getTrack().stringCount(); sNumber++) { TGString string = measure.getTrack().getString(sNumber); this.minNote = Math.min(this.minNote, string.getValue()); this.maxNote = Math.max(this.maxNote, (string.getValue() + 20)); } names = new String[this.maxNote - this.minNote + 1]; for (int i = 0; i < names.length; i++) { names[i] = (NOTE_NAMES[(this.maxNote - i) % 12] + ((this.maxNote - i) / 12)); } } int minimumNameWidth = 110; int minimumNameHeight = 0; TGPainter painter = new TGPainterImpl(new GC(this.dialog.getDisplay())); painter.setFont(new TGFontImpl(this.config.getFont())); for (int i = 0; i < names.length; i++) { int fmWidth = painter.getFMWidth(names[i]); if (fmWidth > minimumNameWidth) { minimumNameWidth = fmWidth; } int fmHeight = painter.getFMHeight(); if (fmHeight > minimumNameHeight) { minimumNameHeight = fmHeight; } } painter.dispose(); int cols = measure.getTimeSignature().getNumerator(); int rows = (this.maxNote - this.minNote); this.leftSpacing = minimumNameWidth + 10; this.lineHeight = Math.max( minimumNameHeight, ((this.clientArea.height - (BORDER_HEIGHT * 2.0f)) / (rows + 1.0f))); this.timeWidth = Math.max( (10 * (TGDuration.SIXTY_FOURTH / measure.getTimeSignature().getDenominator().getValue())), ((this.clientArea.width - this.leftSpacing) / cols)); this.bufferWidth = this.leftSpacing + (this.timeWidth * cols); this.bufferHeight = (this.lineHeight * (rows + 1)); this.buffer = new TGImageImpl( this.editor.getDisplay(), Math.round(this.bufferWidth), Math.round(this.bufferHeight)); painter = this.buffer.createPainter(); painter.setFont(new TGFontImpl(this.config.getFont())); painter.setForeground(new TGColorImpl(this.config.getColorForeground())); for (int i = 0; i <= rows; i++) { painter.setBackground(new TGColorImpl(this.config.getColorLine(i % 2))); painter.initPath(TGPainter.PATH_FILL); painter.setAntialias(false); painter.addRectangle(0, (i * this.lineHeight), this.bufferWidth, this.lineHeight); painter.closePath(); painter.drawString( names[i], 5, (Math.round((i * this.lineHeight)) + Math.round((this.lineHeight - minimumNameHeight) / 2))); } for (int i = 0; i < cols; i++) { float colX = this.leftSpacing + (i * this.timeWidth); float divisionWidth = (this.timeWidth / this.grids); for (int j = 0; j < this.grids; j++) { if (j == 0) { painter.setLineStyleSolid(); } else { painter.setLineStyleDot(); } painter.initPath(); painter.setAntialias(false); painter.moveTo(Math.round(colX + (j * divisionWidth)), 0); painter.lineTo(Math.round(colX + (j * divisionWidth)), this.bufferHeight); painter.closePath(); } } painter.dispose(); } } return this.buffer; } protected void paintMeasure(TGPainter painter, float fromX, float fromY) { if (this.clientArea != null) { TGMeasure measure = getMeasure(); if (measure != null) { Iterator it = measure.getBeats().iterator(); while (it.hasNext()) { TGBeat beat = (TGBeat) it.next(); paintBeat(painter, measure, beat, fromX, fromY); } } } } protected void paintBeat( TGPainter painter, TGMeasure measure, TGBeat beat, float fromX, float fromY) { if (this.clientArea != null) { int minimumY = BORDER_HEIGHT; int maximumY = (this.clientArea.height - BORDER_HEIGHT); for (int v = 0; v < beat.countVoices(); v++) { TGVoice voice = beat.getVoice(v); for (int i = 0; i < voice.countNotes(); i++) { TGNoteImpl note = (TGNoteImpl) voice.getNote(i); float x1 = (fromX + this.leftSpacing + (((beat.getStart() - measure.getStart()) * (this.timeWidth * measure.getTimeSignature().getNumerator())) / measure.getLength()) + 1); float y1 = (fromY + (((this.maxNote - this.minNote) - (note.getRealValue() - this.minNote)) * this.lineHeight) + 1); float x2 = (x1 + ((voice.getDuration().getTime() * this.timeWidth) / measure.getTimeSignature().getDenominator().getTime()) - 2); float y2 = (y1 + this.lineHeight - 2); if (y1 >= maximumY || y2 <= minimumY) { continue; } y1 = (y1 < minimumY ? minimumY : y1); y2 = (y2 > maximumY ? maximumY : y2); if ((x2 - x1) > 0 && (y2 - y1) > 0) { painter.setBackground( new TGColorImpl( (note.getBeatImpl() .isPlaying( TuxGuitar.instance() .getTablatureEditor() .getTablature() .getViewLayout()) ? this.config.getColorPlay() : this.config.getColorNote()))); painter.initPath(TGPainter.PATH_FILL); painter.setAntialias(false); painter.addRectangle(x1, y1, (x2 - x1), (y2 - y1)); painter.closePath(); } } } } } protected void paintBorders(TGPainter painter, float fromX, float fromY) { if (this.clientArea != null) { painter.setBackground(new TGColorImpl(this.config.getColorBorder())); painter.initPath(TGPainter.PATH_FILL); painter.setAntialias(false); painter.addRectangle(fromX, fromY, this.bufferWidth, BORDER_HEIGHT); painter.addRectangle( fromX, fromY + (this.clientArea.height - BORDER_HEIGHT), this.bufferWidth, BORDER_HEIGHT); painter.closePath(); painter.initPath(); painter.setAntialias(false); painter.addRectangle(fromX, fromY, this.width, this.clientArea.height); painter.closePath(); } } protected void paintPosition(TGPainter painter, float fromX, float fromY) { if (this.clientArea != null && !TuxGuitar.instance().getPlayer().isRunning()) { Caret caret = getCaret(); TGMeasure measure = getMeasure(); TGBeat beat = caret.getSelectedBeat(); if (beat != null) { float x = (((beat.getStart() - measure.getStart()) * (this.timeWidth * measure.getTimeSignature().getNumerator())) / measure.getLength()); float width = ((beat.getVoice(caret.getVoice()).getDuration().getTime() * this.timeWidth) / measure.getTimeSignature().getDenominator().getTime()); painter.setBackground(new TGColorImpl(this.config.getColorPosition())); painter.initPath(TGPainter.PATH_FILL); painter.setAntialias(false); painter.addRectangle(fromX + (this.leftSpacing + x), fromY, width, BORDER_HEIGHT); painter.closePath(); painter.initPath(TGPainter.PATH_FILL); painter.setAntialias(false); painter.addRectangle( fromX + (this.leftSpacing + x), fromY + (this.clientArea.height - BORDER_HEIGHT), width, BORDER_HEIGHT); painter.closePath(); } } } protected void paintSelection(TGPainter painter, float fromX, float fromY) { if (!this.selectionPaintDisabled && this.clientArea != null && !TuxGuitar.instance().getPlayer().isRunning()) { selectionFinish(); if (this.selection >= 0) { this.selectionPaintDisabled = true; int x = Math.round(fromX); int y = Math.round(fromY + ((this.maxNote - this.selection) * this.lineHeight)); int width = Math.round(this.bufferWidth); int height = Math.round(this.lineHeight); TGImage selectionArea = new TGImageImpl(this.editor.getDisplay(), width, height); painter.copyArea(selectionArea, x, y); painter.setAlpha(100); painter.setBackground(new TGColorImpl(this.config.getColorLine(2))); painter.initPath(TGPainter.PATH_FILL); painter.setAntialias(false); painter.addRectangle(x, y, width, height); painter.closePath(); this.selectionX = x; this.selectionY = y; this.selectionBackBuffer = selectionArea; this.selectionPaintDisabled = false; } } } protected void updateSelection(float y) { if (!TuxGuitar.instance().getPlayer().isRunning()) { int selection = getValueAt(y); if (this.selection != selection) { this.selection = selection; int scrollX = this.editor.getHorizontalBar().getSelection(); int scrollY = this.editor.getVerticalBar().getSelection(); TGPainter painter = new TGPainterImpl(new GC(this.editor)); this.paintSelection(painter, (-scrollX), (BORDER_HEIGHT - scrollY)); painter.dispose(); } } } public void selectionFinish() { if (this.selectionBackBuffer != null && !this.selectionBackBuffer.isDisposed()) { TGPainter painter = new TGPainterImpl(new GC(this.editor)); painter.drawImage(this.selectionBackBuffer, this.selectionX, this.selectionY); painter.dispose(); } disposeSelectionBuffer(); } protected void disposeSelectionBuffer() { if (this.selectionBackBuffer != null && !this.selectionBackBuffer.isDisposed()) { this.selectionBackBuffer.dispose(); this.selectionBackBuffer = null; } } protected void hit(float x, float y) { if (!TuxGuitar.instance().getPlayer().isRunning()) { TGMeasure measure = getMeasure(); Caret caret = getCaret(); int value = getValueAt(y); long start = getStartAt(x); if (start >= measure.getStart() && start < (measure.getStart() + measure.getLength())) { caret.update(caret.getTrack().getNumber(), start, caret.getStringNumber()); TuxGuitar.instance().updateCache(true); } if (value >= this.minNote || value <= this.maxNote) { if (start >= measure.getStart()) { TGVoice voice = TuxGuitar.instance() .getSongManager() .getMeasureManager() .getVoiceIn(measure, start, caret.getVoice()); if (voice != null) { if (!removeNote(voice.getBeat(), value)) { addNote(voice.getBeat(), start, value); } } } else { play(value); } } } } private boolean removeNote(TGBeat beat, int value) { Caret caret = TuxGuitar.instance().getTablatureEditor().getTablature().getCaret(); TGMeasure measure = getMeasure(); for (int v = 0; v < beat.countVoices(); v++) { TGVoice voice = beat.getVoice(v); Iterator it = voice.getNotes().iterator(); while (it.hasNext()) { TGNoteImpl note = (TGNoteImpl) it.next(); if (note.getRealValue() == value) { caret.update(measure.getTrack().getNumber(), beat.getStart(), note.getString()); // comienza el undoable UndoableMeasureGeneric undoable = UndoableMeasureGeneric.startUndo(); TGSongManager manager = TuxGuitar.instance().getSongManager(); manager.getMeasureManager().removeNote(note); // termia el undoable TuxGuitar.instance().getUndoableManager().addEdit(undoable.endUndo()); TuxGuitar.instance().getFileHistory().setUnsavedFile(); this.afterAction(); return true; } } } return false; } private boolean addNote(TGBeat beat, long start, int value) { if (beat != null) { TGMeasure measure = getMeasure(); Caret caret = TuxGuitar.instance().getTablatureEditor().getTablature().getCaret(); List strings = measure.getTrack().getStrings(); for (int i = 0; i < strings.size(); i++) { TGString string = (TGString) strings.get(i); if (value >= string.getValue()) { boolean emptyString = true; for (int v = 0; v < beat.countVoices(); v++) { TGVoice voice = beat.getVoice(v); Iterator it = voice.getNotes().iterator(); while (it.hasNext()) { TGNoteImpl note = (TGNoteImpl) it.next(); if (note.getString() == string.getNumber()) { emptyString = false; break; } } } if (emptyString) { TGSongManager manager = TuxGuitar.instance().getSongManager(); // comienza el undoable UndoableMeasureGeneric undoable = UndoableMeasureGeneric.startUndo(); TGNote note = manager.getFactory().newNote(); note.setValue((value - string.getValue())); note.setVelocity(caret.getVelocity()); note.setString(string.getNumber()); TGDuration duration = manager.getFactory().newDuration(); caret.getDuration().copy(duration); manager.getMeasureManager().addNote(beat, note, duration, start, caret.getVoice()); caret.moveTo( caret.getTrack(), caret.getMeasure(), note.getVoice().getBeat(), note.getString()); // termia el undoable TuxGuitar.instance().getUndoableManager().addEdit(undoable.endUndo()); TuxGuitar.instance().getFileHistory().setUnsavedFile(); // reprodusco las notas en el pulso TuxGuitar.instance().playBeat(caret.getSelectedBeat()); this.afterAction(); return true; } } } } return false; } protected void afterAction() { TuxGuitar.instance() .getTablatureEditor() .getTablature() .updateMeasure(getMeasure().getNumber()); TuxGuitar.instance().updateCache(true); this.editor.redraw(); } protected void play(final int value) { new Thread( new Runnable() { public void run() { TGTrack tgTrack = getMeasure().getTrack(); TGChannel tgChannel = TuxGuitar.instance().getSongManager().getChannel(tgTrack.getChannelId()); if (tgChannel != null) { int volume = TGChannel.DEFAULT_VOLUME; int balance = TGChannel.DEFAULT_BALANCE; int chorus = tgChannel.getChorus(); int reverb = tgChannel.getReverb(); int phaser = tgChannel.getPhaser(); int tremolo = tgChannel.getTremolo(); int channel = tgChannel.getChannel(); int program = tgChannel.getProgram(); int bank = tgChannel.getBank(); int[][] beat = new int[][] {new int[] {(tgTrack.getOffset() + value), TGVelocities.DEFAULT}}; TuxGuitar.instance() .getPlayer() .playBeat( channel, bank, program, volume, balance, chorus, reverb, phaser, tremolo, beat); } } }) .start(); } protected int loadGrids() { int grids = TuxGuitar.instance().getConfig().getIntConfigValue(TGConfigKeys.MATRIX_GRIDS); // check if is valid value for (int i = 0; i < DIVISIONS.length; i++) { if (grids == DIVISIONS[i]) { return grids; } } return DIVISIONS[1]; } protected void setGrids(int grids) { this.grids = grids; this.disposeBuffer(); this.redrawLocked(); } public int getGrids() { return this.grids; } protected TGMeasure getMeasure() { if (TuxGuitar.instance().getPlayer().isRunning()) { TGMeasure measure = TuxGuitar.instance().getEditorCache().getPlayMeasure(); if (measure != null) { return measure; } } return TuxGuitar.instance().getTablatureEditor().getTablature().getCaret().getMeasure(); } protected Caret getCaret() { return TuxGuitar.instance().getTablatureEditor().getTablature().getCaret(); } public boolean isDisposed() { return (this.dialog == null || this.dialog.isDisposed()); } protected void resetPlayed() { this.playedBeat = null; this.playedMeasure = -1; this.playedTrack = -1; } public void redrawLocked() { if (!TuxGuitar.instance().isLocked()) { TuxGuitar.instance().lock(); this.redraw(); TuxGuitar.instance().unlock(); } } public void redraw() { if (!isDisposed() && !TuxGuitar.instance().isLocked()) { // TuxGuitar.instance().lock(); this.editor.redraw(); this.loadDurationImage(false); // TuxGuitar.instance().unlock(); } } public void redrawPlayingMode() { if (!isDisposed() && !TuxGuitar.instance().isLocked() && TuxGuitar.instance().getPlayer().isRunning()) { // TuxGuitar.instance().lock(); TGMeasure measure = TuxGuitar.instance().getEditorCache().getPlayMeasure(); TGBeat beat = TuxGuitar.instance().getEditorCache().getPlayBeat(); if (measure != null && beat != null) { int currentMeasure = measure.getNumber(); int currentTrack = measure.getTrack().getNumber(); boolean changed = (currentMeasure != this.playedMeasure || currentTrack != this.playedTrack); if (changed) { this.resetPlayed(); this.editor.redraw(); } else { TGPainter painter = new TGPainterImpl(new GC(this.editor)); int scrollX = this.editor.getHorizontalBar().getSelection(); int scrollY = this.editor.getVerticalBar().getSelection(); if (this.playedBeat != null) { this.paintBeat( painter, measure, this.playedBeat, (-scrollX), (BORDER_HEIGHT - scrollY)); } this.paintBeat(painter, measure, beat, (-scrollX), (BORDER_HEIGHT - scrollY)); painter.dispose(); } this.playedMeasure = currentMeasure; this.playedTrack = currentTrack; this.playedBeat = beat; } // TuxGuitar.instance().unlock(); } } protected void configure() { this.config.configure(this.dialog); this.disposeBuffer(); this.redrawLocked(); } private void layout() { if (!isDisposed()) { this.toolbar.layout(); this.editor.layout(); this.composite.layout(true, true); } } public void loadIcons() { if (!isDisposed()) { this.dialog.setImage(TuxGuitar.instance().getIconManager().getAppIcon()); this.settings.setImage(TuxGuitar.instance().getIconManager().getSettings()); this.loadDurationImage(true); this.layout(); this.redraw(); } } public void loadProperties() { if (!isDisposed()) { this.dialog.setText(TuxGuitar.getProperty("matrix.editor")); this.gridsLabel.setText(TuxGuitar.getProperty("matrix.grids")); this.settings.setToolTipText(TuxGuitar.getProperty("settings")); this.disposeBuffer(); this.layout(); this.redraw(); } } public void dispose() { if (!isDisposed()) { this.dialog.dispose(); } } protected void disposeBuffer() { if (this.buffer != null && !this.buffer.isDisposed()) { this.buffer.dispose(); this.buffer = null; } } protected void dispose(Resource[] resources) { if (resources != null) { for (int i = 0; i < resources.length; i++) { dispose(resources[i]); } } } protected void dispose(Resource resource) { if (resource != null) { resource.dispose(); } } protected void disposeAll() { this.disposeBuffer(); this.disposeSelectionBuffer(); this.config.dispose(); } protected Composite getEditor() { return this.editor; } protected class BufferDisposer { private int numerator; private int denominator; private int track; private boolean percussion; private int width; private int height; public void update(int width, int height) { TGMeasure measure = getMeasure(); int track = measure.getTrack().getNumber(); int numerator = measure.getTimeSignature().getNumerator(); int denominator = measure.getTimeSignature().getDenominator().getValue(); boolean percussion = TuxGuitar.instance() .getSongManager() .isPercussionChannel(measure.getTrack().getChannelId()); if (width != this.width || height != this.height || this.track != track || this.numerator != numerator || this.denominator != denominator || this.percussion != percussion) { disposeBuffer(); } this.track = track; this.numerator = numerator; this.denominator = denominator; this.percussion = percussion; this.width = width; this.height = height; } } protected class DisposeListenerImpl implements DisposeListener { public void widgetDisposed(DisposeEvent e) { disposeAll(); } } protected class MatrixListener implements PaintListener, MouseListener, MouseMoveListener, MouseTrackListener { public MatrixListener() { super(); } public void paintControl(PaintEvent e) { if (!TuxGuitar.instance().isLocked()) { TuxGuitar.instance().lock(); TGPainter painter = new TGPainterImpl(e.gc); paintEditor(painter); TuxGuitar.instance().unlock(); } } public void mouseUp(MouseEvent e) { getEditor().setFocus(); if (e.button == 1) { if (!TuxGuitar.instance().isLocked() && !ActionLock.isLocked()) { ActionLock.lock(); hit(e.x, e.y); ActionLock.unlock(); } } } public void mouseMove(MouseEvent e) { if (!TuxGuitar.instance().isLocked() && !ActionLock.isLocked()) { updateSelection(e.y); } } public void mouseExit(MouseEvent e) { if (!TuxGuitar.instance().isLocked() && !ActionLock.isLocked()) { updateSelection(-1); } } public void mouseEnter(MouseEvent e) { if (!TuxGuitar.instance().isLocked() && !ActionLock.isLocked()) { redrawLocked(); } } public void mouseDoubleClick(MouseEvent e) { // TODO Auto-generated method stub } public void mouseDown(MouseEvent e) { // TODO Auto-generated method stub } public void mouseHover(MouseEvent e) { // TODO Auto-generated method stub } } public void doRedraw(int type) { if (type == TGRedrawListener.NORMAL) { this.redraw(); } else if (type == TGRedrawListener.PLAYING_NEW_BEAT) { this.redrawPlayingMode(); } } }