2
* Created on 26-nov-2005
4
* TODO To change the template for this generated file go to
5
* Window - Preferences - Java - Code Style - Code Templates
7
package org.herac.tuxguitar.gui.editors.tab;
9
import java.util.ArrayList;
10
import java.util.Iterator;
11
import java.util.List;
13
import org.eclipse.swt.graphics.Point;
14
import org.herac.tuxguitar.gui.TuxGuitar;
15
import org.herac.tuxguitar.gui.editors.TGPainter;
16
import org.herac.tuxguitar.gui.editors.tab.layout.TrackSpacing;
17
import org.herac.tuxguitar.gui.editors.tab.layout.ViewLayout;
18
import org.herac.tuxguitar.gui.editors.tab.painters.TGClefPainter;
19
import org.herac.tuxguitar.gui.editors.tab.painters.TGKeySignaturePainter;
20
import org.herac.tuxguitar.gui.editors.tab.painters.TGTempoPainter;
21
import org.herac.tuxguitar.gui.editors.tab.painters.TGTripletFeelPainter;
22
import org.herac.tuxguitar.gui.helper.SyncThread;
23
import org.herac.tuxguitar.song.managers.TGSongManager;
24
import org.herac.tuxguitar.song.models.TGBeat;
25
import org.herac.tuxguitar.song.models.TGChord;
26
import org.herac.tuxguitar.song.models.TGDuration;
27
import org.herac.tuxguitar.song.models.TGMeasure;
28
import org.herac.tuxguitar.song.models.TGMeasureHeader;
29
import org.herac.tuxguitar.song.models.TGNoteEffect;
30
import org.herac.tuxguitar.song.models.TGTupleto;
35
* TODO To change the template for this generated type comment go to Window - Preferences - Java - Code Style - Code Templates
37
public class TGMeasureImpl extends TGMeasure{
39
public static final int NATURAL = 1;
40
public static final int SHARP = 2;
41
public static final int FLAT = 3;
43
public static final int KEY_SIGNATURES[][] = new int[][]{
44
//------------NATURAL------------------------------------
45
{NATURAL,NATURAL,NATURAL,NATURAL,NATURAL,NATURAL,NATURAL}, // NATURAL
46
//------------SHARPS------------------------------------
47
{NATURAL,NATURAL,NATURAL,SHARP,NATURAL,NATURAL,NATURAL}, // 1 SHARP
48
{SHARP,NATURAL,NATURAL,SHARP,NATURAL,NATURAL,NATURAL}, // 2 SHARPS
49
{SHARP,NATURAL,NATURAL,SHARP,SHARP,NATURAL,NATURAL}, // 3 SHARPS
50
{SHARP,SHARP,NATURAL,SHARP,SHARP,NATURAL,NATURAL}, // 4 SHARPS
51
{SHARP,SHARP,NATURAL,SHARP,SHARP,SHARP,NATURAL}, // 5 SHARPS
52
{SHARP,SHARP,SHARP,SHARP,SHARP,SHARP,NATURAL}, // 6 SHARPS
53
{SHARP,SHARP,SHARP,SHARP,SHARP,SHARP,SHARP}, // 7 SHARPS
54
//------------FLATS------------------------------------
55
{NATURAL,NATURAL,NATURAL,NATURAL,NATURAL,NATURAL,FLAT}, // 1 FLAT
56
{NATURAL,NATURAL,FLAT,NATURAL,NATURAL,NATURAL,FLAT}, // 2 FLATS
57
{NATURAL,NATURAL,FLAT,NATURAL,NATURAL,FLAT,FLAT}, // 3 FLATS
58
{NATURAL,FLAT,FLAT,NATURAL,NATURAL,FLAT,FLAT}, // 4 FLATS
59
{NATURAL,FLAT,FLAT,NATURAL,FLAT,FLAT,FLAT}, // 5 FLATS
60
{FLAT,FLAT,FLAT,NATURAL,FLAT,FLAT,FLAT}, // 6 FLATS
61
{FLAT,FLAT,FLAT,FLAT,FLAT,FLAT,FLAT}, // 7 FLATS
64
public static final int ACCIDENTAL_SHARP_NOTES[] = new int[]{0,0,1,1,2,3,3,4,4,5,5,6};
65
public static final int ACCIDENTAL_FLAT_NOTES [] = new int[]{0,1,1,2,2,3,4,4,5,5,6,6};
66
public static final boolean ACCIDENTAL_NOTES[] = new boolean[]{false,true,false,true,false,false,true,false,true,false,true,false};
68
public static final int SCORE_KEY_OFFSETS[] = new int[]{30,18,22,24};
70
public static final int SCORE_KEY_SHARP_POSITIONS[] = new int[]{ 1 , 4, 0, 3, 6, 2 , 5 };
72
public static final int SCORE_KEY_FLAT_POSITIONS[] = new int[]{ 5, 2, 6, 3, 0, 4, 1 };
75
* Espacio por defecto de la clave
77
private static final int DEFAULT_CLEF_SPACING = 40;
79
* Espacio por defecto entre negra y negra
81
private static final int DEFAULT_QUARTER_SPACING = 30;
91
* Espacio entre negras
93
private int quarterSpacing;
95
* Espacio entre pulsos
97
private long divisionLength;
99
* Boolean para saber si hay que pintar la clave
101
private boolean paintClef = true;
103
* Boolean para saber si hay que pintar el KeySignature
105
private boolean paintKeySignature = true;
109
private TGMeasure prevMeasure;
111
* Boolean para saber si el compas esta en el area de pantalla
113
private boolean outOfBounds;
115
* Boolean para saber si el compas es el primero de la linea
117
private boolean firstOfLine;
119
private boolean compactMode;
123
private TrackSpacing ts;
129
private int notEmptyBeats;
131
private int widthBeats = 0;
133
private List beatGroups;
135
private TGMeasureBuffer buffer;
137
private boolean bufferCreated;
139
private int lyricBeatIndex;
142
private boolean text;
143
private boolean chord;
144
private boolean accentuated;
145
private boolean harmonic;
146
private boolean tapping;
147
private boolean palmMute;
148
private boolean vibrato;
149
private boolean tupleto;
150
private boolean fadeIn;
152
private boolean[][] registeredAccidentals;
154
public TGMeasureImpl(TGMeasureHeader header) {
156
this.beatGroups = new ArrayList();
157
this.registeredAccidentals = new boolean[11][7];
161
* Crea los valores necesarios
163
public void create(ViewLayout layout) {
164
this.divisionLength = TGSongManager.getDivisionLength(getHeader());
166
this.autoCompleteSilences(layout.getSongManager());
167
this.orderBeats(layout.getSongManager());
168
this.checkCompactMode(layout);
169
this.clearRegisteredAccidentals();
170
this.calculateBeats(layout);
171
this.calculateWidth(layout);
172
this.setFirstOfLine(false);
176
* Actualiza los valores para dibujar
178
public void update(ViewLayout layout) {
179
updateComponents(layout);
180
setOutOfBounds(true);
181
setBufferCreated(false);
184
private void checkCompactMode(ViewLayout layout){
185
boolean compactMode = ( (layout.getStyle() & ViewLayout.DISPLAY_COMPACT) != 0 );
186
if(compactMode && (layout.getStyle() & ViewLayout.DISPLAY_MULTITRACK) != 0){
187
compactMode = (layout.getSongManager().getSong().countTracks() == 1);
189
this.compactMode = compactMode;
192
private void clearRegisteredAccidentals(){
193
for( int i = 0 ; i < 11 ; i ++ ){
194
for( int n = 0 ; n < 7 ; n ++ ){
195
this.registeredAccidentals[i][n] = false;
200
public void calculateWidth(ViewLayout layout) {
201
if(this.compactMode){
202
this.width = this.widthBeats;
205
double quartersInSignature = ((1.00 / this.getTimeSignature().getDenominator().getValue()) * 4.00) * this.getTimeSignature().getNumerator();
206
this.width = (int)(getQuarterSpacing() * quartersInSignature);
209
this.width += getFirstNoteSpacing(layout);
210
this.width += (this.getRepeatClose() > 0)?20:0;
211
this.width += getHeaderImpl().getLeftSpacing(layout);
212
this.width += getHeaderImpl().getRightSpacing(layout);
214
this.getHeaderImpl().notifyWidth(this.width);
217
private void calculateBeats(ViewLayout layout) {
218
TGChord previousChord = null;
219
TGDuration minDuration = null;
220
TGBeatImpl previousBeat = null;
221
TGBeatGroup group = null;
222
int style = layout.getStyle();
223
int minimunChordLength = 0;
224
boolean beatChanged = false;
225
boolean chordEnabled = ((style & (ViewLayout.DISPLAY_CHORD_DIAGRAM | ViewLayout.DISPLAY_CHORD_NAME)) != 0);
227
this.notEmptyBeats = 0;
228
this.beatGroups.clear();
230
for (int i = 0; i < countBeats(); i++) {
231
TGBeatImpl beat = (TGBeatImpl)getBeat(i);
233
if (minDuration == null || beat.getDuration().getTime() <= minDuration.getTime()) {
234
minDuration = beat.getDuration();
237
Iterator it = beat.getNotes().iterator();
239
TGNoteImpl note = (TGNoteImpl)it.next();
243
if( ( group == null ) || (beatChanged && !canJoin(layout.getSongManager(),beat,previousBeat) ) ){
244
group = new TGBeatGroup();
245
this.beatGroups.add(group);
247
group.check(note,getClef());
248
note.setBeatGroup(group);
252
if(chordEnabled && beat.getChord() != null){
253
if(previousChord != null){
254
int length = (int) (beat.getStart() - previousChord.getBeat().getStart());
255
minimunChordLength = (minimunChordLength > 0)?Math.min(minimunChordLength, Math.abs(length)):length;
257
previousChord = beat.getChord();
260
makeBeat(layout,beat,previousBeat,group,chordEnabled);
264
if(!this.compactMode){
265
this.quarterSpacing = (minDuration != null)?layout.getSpacingForQuarter(minDuration): Math.round(DEFAULT_QUARTER_SPACING * layout.getScale());
266
if(chordEnabled && minimunChordLength > 0){
267
int chordWidth = (layout.getChordFretIndexSpacing() + layout.getChordStringSpacing() + (getTrack().stringCount() * layout.getChordStringSpacing()));
268
int minimunSpacing = (int)((TGDuration.QUARTER_TIME * chordWidth) / minimunChordLength);
269
this.quarterSpacing = Math.max(minimunSpacing,this.quarterSpacing);
271
this.getHeaderImpl().notifyQuarterSpacing(this.quarterSpacing);
275
public boolean canJoin(TGSongManager manager,TGBeatImpl b1,TGBeatImpl b2){
276
if( b1 == null || b2 == null || b1.isRestBeat() || b2.isRestBeat() ){
280
long divisionLength = getDivisionLength();
281
long start = getStart();
282
long start1 = (manager.getMeasureManager().getRealStart(this, b1.getStart()) - start);
283
long start2 = (manager.getMeasureManager().getRealStart(this, b2.getStart()) - start);
285
if(b1.getDuration().getValue() < TGDuration.EIGHTH || b2.getDuration().getValue() < TGDuration.EIGHTH ){
286
return ( start1 == start2);
289
long p1 = ((divisionLength + start1) / divisionLength);
290
long p2 = ((divisionLength + start2) / divisionLength);
295
private void makeBeat(ViewLayout layout,TGBeatImpl beat,TGBeatImpl previousBeat,TGBeatGroup group,boolean chordEnabled){
296
beat.setWidth((int)layout.getBeatWidth(beat));
297
beat.setBeatGroup( group );
298
this.notEmptyBeats += (beat.isRestBeat() ? 0 : 1);
299
this.widthBeats += beat.getWidth();
301
if(previousBeat != null){
302
beat.setPreviousBeat(previousBeat);
303
previousBeat.setNextBeat(beat);
305
if(chordEnabled && beat.isChordBeat() && previousBeat.isChordBeat()){
306
int previousWidth = previousBeat.getWidth();
307
int chordWidth = (layout.getChordFretIndexSpacing() + layout.getChordStringSpacing() + (getTrack().stringCount() * layout.getChordStringSpacing()));
308
previousBeat.setWidth(Math.max(chordWidth,previousWidth));
309
this.widthBeats -= previousWidth;
310
this.widthBeats += previousBeat.getWidth();
316
* Calcula si debe pintar el TimeSignature
318
public void calculateMeasureChanges(ViewLayout layout) {
319
this.paintClef = false;
320
this.paintKeySignature = false;
321
this.prevMeasure = (layout.isFirstMeasure(this) ? null : (TGMeasureImpl)layout.getSongManager().getTrackManager().getPrevMeasure(this));
322
if((layout.getStyle() & ViewLayout.DISPLAY_SCORE) != 0 ){
323
if(this.prevMeasure == null || getClef() != this.prevMeasure.getClef()){
324
this.paintClef = true;
325
this.getHeaderImpl().notifyClefSpacing( Math.round(DEFAULT_CLEF_SPACING * layout.getScale()) );
327
if(this.prevMeasure == null || getKeySignature() != this.prevMeasure.getKeySignature()){
328
this.paintKeySignature = true;
329
this.getHeaderImpl().notifyKeySignatureSpacing(calculateKeySignatureSpacing(layout));
335
* Calcula si hay espacios libres. y crea nuevos silencios
337
private void autoCompleteSilences(TGSongManager manager){
338
manager.getMeasureManager().autoCompleteSilences(this);
342
* Llama a update de todas las notas del compas
344
private void updateComponents(ViewLayout layout) {
348
int spacing = getFirstNoteSpacing(layout);
350
for (int i = 0; i < countBeats(); i++) {
351
TGBeatImpl beat = (TGBeatImpl) getBeat(i);
353
if(this.compactMode){
355
tmpX += beat.getWidth();
358
int quarterWidth = getMaxQuarterSpacing(layout);
359
int x1 = (spacing + TablatureUtil.getStartPosition(this, beat.getStart(), quarterWidth));
360
int x2 = (spacing + TablatureUtil.getStartPosition(this, beat.getStart() + beat.getDuration().getTime(), quarterWidth));
362
beat.setWidth( x2 - x1 );
365
Iterator notes = beat.getNotes().iterator();
366
while(notes.hasNext()){
367
TGNoteImpl note = (TGNoteImpl)notes.next();
369
checkEffects(layout,note.getEffect());
375
if(!this.chord && beat.isChordBeat()){
379
if(!this.text && beat.isTextBeat()){
383
if(!this.tupleto && !beat.getDuration().getTupleto().isEqual(TGTupleto.NORMAL)){
387
Iterator groups = this.beatGroups.iterator();
388
while (groups.hasNext()) {
389
TGBeatGroup group = (TGBeatGroup)groups.next();
390
checkValue(layout,group.getMinNote(),group.getDirection());
391
checkValue(layout,group.getMaxNote(),group.getDirection());
395
public int getNoteAccidental(int noteValue){
396
if( noteValue >= 0 && noteValue < 128 ){
397
int key = getKeySignature();
398
int note = (noteValue % 12);
399
int octave = (noteValue / 12);
400
int accidentalValue = (key <= 7 ? SHARP : FLAT );
401
int [] accidentalNotes = (key <= 7 ? ACCIDENTAL_SHARP_NOTES : ACCIDENTAL_FLAT_NOTES );
402
boolean isAccidentalNote = ACCIDENTAL_NOTES[ note ];
403
boolean isAccidentalKey = KEY_SIGNATURES[key][accidentalNotes[ note ]] == accidentalValue;
405
if(isAccidentalKey != isAccidentalNote && !this.registeredAccidentals[ octave ][ accidentalNotes[ note ] ]){
406
this.registeredAccidentals[ octave ][ accidentalNotes[note ] ] = true;
407
return (isAccidentalNote ? accidentalValue : NATURAL);
410
if(isAccidentalKey == isAccidentalNote && this.registeredAccidentals[ octave ][ accidentalNotes[ note ] ]){
411
this.registeredAccidentals[ octave ][ accidentalNotes[ note ] ] = false;
412
return (isAccidentalNote ? accidentalValue : NATURAL);
418
private void checkValue(ViewLayout layout,TGNoteImpl note,int direction){
419
int y = note.getScorePosY();
420
float upOffset = TGBeatGroup.getUpOffset(layout);
421
float downOffset = TGBeatGroup.getDownOffset(layout);
423
if(direction == TGBeatGroup.DIRECTION_UP && y > this.maxY ){
425
}else if(direction == TGBeatGroup.DIRECTION_DOWN && (y + downOffset) > this.maxY ){
426
this.maxY = (int)(y + downOffset + 2);
429
if(direction == TGBeatGroup.DIRECTION_UP && (y - upOffset) < this.minY ){
430
this.minY = (int)(y - upOffset - 2);
431
}else if(direction == TGBeatGroup.DIRECTION_DOWN && y < this.minY ){
436
private void checkEffects(ViewLayout layout,TGNoteEffect effect){
437
if(effect.isAccentuatedNote() || effect.isHeavyAccentuatedNote()){
438
this.accentuated = true;
440
if(effect.isHarmonic() && (layout.getStyle() & ViewLayout.DISPLAY_SCORE) == 0 ){
441
this.harmonic = true;
443
if(effect.isTapping() || effect.isSlapping() || effect.isPopping()){
446
if(effect.isPalmMute()){
447
this.palmMute = true;
449
if(effect.isFadeIn()){
452
if(effect.isVibrato() || effect.isTrill()){
457
private void resetEffects(){
460
this.tupleto = false;
461
this.accentuated = false;
462
this.harmonic = false;
463
this.tapping = false;
464
this.palmMute = false;
466
this.vibrato = false;
469
public void registerEffects(ViewLayout layout,TrackSpacing ts){
471
ts.setSize(TrackSpacing.POSITION_CHORD,layout.getDefaultChordSpacing());
474
ts.setSize(TrackSpacing.POSITION_TEXT,layout.getTextSpacing());
476
if(this.getHeader().getRepeatAlternative() > 0){
477
ts.setSize(TrackSpacing.POSITION_REPEAT_ENDING,layout.getRepeatEndingSpacing());
480
ts.setSize(TrackSpacing.POSITION_TUPLETO,layout.getTupletoSpacing());
482
if(this.accentuated){
483
ts.setSize(TrackSpacing.POSITION_ACCENTUATED_EFFECT,layout.getEffectSpacing());
486
ts.setSize(TrackSpacing.POSITION_HARMONIC_EFFEC,layout.getEffectSpacing());
489
ts.setSize(TrackSpacing.POSITION_TAPPING_EFFEC,layout.getEffectSpacing());
492
ts.setSize(TrackSpacing.POSITION_PALM_MUTE_EFFEC,layout.getEffectSpacing());
495
ts.setSize(TrackSpacing.POSITION_FADE_IN,layout.getEffectSpacing());
498
ts.setSize(TrackSpacing.POSITION_VIBRATO_EFFEC,layout.getEffectSpacing());
502
private void orderBeats(TGSongManager manager){
503
manager.getMeasureManager().orderBeats(this);
506
public void paintMeasure(ViewLayout layout,TGPainter painter) {
507
this.setOutOfBounds(false);
509
boolean bufferEnabled = layout.isBufferEnabled();
511
if(shouldRepaintBuffer() || !bufferEnabled ){
512
TGPainter painterBuffer = painter;
513
int x = (bufferEnabled ? 0 : getPosX());
514
int y = (bufferEnabled ? 0 : getPosY());
516
getBuffer().makeBuffer(getWidth(layout) + getSpacing(), getTs().getSize(),layout.getResources().getBackgroundColor());
517
painterBuffer = getBuffer().getPainter();
519
layout.paintLines(getTrackImpl(),getTs(),painterBuffer,x,y, getWidth(layout) + getSpacing());
520
paintTimeSignature(layout,painterBuffer,x,y);
521
paintClef(layout,painterBuffer,x,y);
522
paintKeySignature(layout,painterBuffer,x,y);
523
paintComponents(layout,painterBuffer,x,y);
525
setBufferCreated(true);
528
painter.setBackground(layout.getResources().getBackgroundColor());
529
getBuffer().paintImage(painter,getPosX(),getPosY(),getTs().getPosition(TrackSpacing.POSITION_BUFFER_SEPARATOR));
531
this.paintTexts(layout,painter);
532
this.paintTempo(layout,painter);
533
this.paintTripletFeel(layout,painter);
534
this.paintDivisions(layout,painter);
535
this.paintRepeatEnding(layout,painter);
536
this.paintPlayMode(layout,painter);
539
private boolean shouldRepaintBuffer(){
540
return (isDisposed() || !isBufferCreated());
543
public void paintRepeatEnding(ViewLayout layout,TGPainter painter){
544
if(getHeader().getRepeatAlternative() > 0){
545
float scale = layout.getScale();
546
float x1 = (getPosX() + getHeaderImpl().getLeftSpacing(layout) + getFirstNoteSpacing(layout));
547
float x2 = (getPosX() + getWidth(layout) + getSpacing());
548
float y1 = (getPosY() + getTs().getPosition(TrackSpacing.POSITION_REPEAT_ENDING));
549
float y2 = (y1 + (layout.getRepeatEndingSpacing() * 0.75f ));
550
String string = new String();
551
for(int i = 0; i < 8; i ++){
552
if((getHeader().getRepeatAlternative() & (1 << i)) != 0){
553
string += ((string.length() > 0)?(", ") + Integer.toString(i + 1):Integer.toString(i + 1));
556
layout.setRepeatEndingStyle(painter);
558
painter.moveTo(x1, y2);
559
painter.lineTo(x1, y1);
560
painter.lineTo(x2, y1);
562
painter.drawString(string,Math.round( x1 + (5.0f * scale) ),Math.round( y1 + (2.0f * scale) ));
569
public void paintComponents(ViewLayout layout,TGPainter painter, int fromX, int fromY) {
570
Iterator it = getBeats().iterator();
572
TGBeatImpl beat = (TGBeatImpl)it.next();
573
beat.paint(layout, painter, fromX + getHeaderImpl().getLeftSpacing(layout) ,fromY);
578
* Pinta las divisiones del compas
580
private void paintDivisions(ViewLayout layout,TGPainter painter) {
582
int x2 = getPosX() + getWidth(layout);
586
int style = layout.getStyle();
587
boolean addInfo = false;
588
//-----SCORE ------------------------------------//
589
if((style & ViewLayout.DISPLAY_SCORE) != 0 ){
590
y1 = getPosY() + getTs().getPosition(TrackSpacing.POSITION_SCORE_MIDDLE_LINES);
591
y2 = y1 + (layout.getScoreLineSpacing() * 4);
593
if( (style & ViewLayout.DISPLAY_TABLATURE) != 0 && (layout.isFirstMeasure(this) || isFirstOfLine())){
594
offsetY = ( getPosY() + getTs().getPosition(TrackSpacing.POSITION_TABLATURE)) - y2;
596
paintDivisions(layout, painter, x1, y1, x2, y2, offsetY, addInfo );
598
//-----TABLATURE ------------------------------------//
599
if( (style & ViewLayout.DISPLAY_TABLATURE) != 0 ){
600
y1 = getPosY() + getTs().getPosition(TrackSpacing.POSITION_TABLATURE);
601
y2 = y1 + ((getTrack().getStrings().size() - 1 ) * layout.getStringSpacing());
602
addInfo = ( (style & ViewLayout.DISPLAY_SCORE) == 0 );
604
paintDivisions(layout, painter, x1, y1, x2, y2, offsetY, addInfo );
608
private void paintDivisions(ViewLayout layout,TGPainter painter,int x1, int y1, int x2, int y2, int offsetY, boolean addInfo) {
609
float scale = layout.getScale();
610
int lineWidthSmall = 1;
611
int lineWidthBig = Math.max(lineWidthSmall,Math.round(3f * scale));
615
String number = Integer.toString(this.getNumber());
616
layout.setMeasureNumberStyle(painter);
617
painter.drawString(number,getPosX() + Math.round(scale),(y1 - painter.getStringExtent(number).y) - Math.round(scale));
620
layout.setDivisionsStyle(painter,true);
623
if(this.isRepeatOpen() || layout.isFirstMeasure(this)){
624
painter.initPath(TGPainter.PATH_DRAW | TGPainter.PATH_FILL);
625
painter.setLineWidth(lineWidthSmall);
626
painter.addRectangle( x1, y1, lineWidthBig, (y2 + offsetY) - y1);
630
painter.setLineWidth(lineWidthSmall);
631
painter.moveTo(x1 + lineWidthBig + scale + lineWidthSmall, y1);
632
painter.lineTo(x1 + lineWidthBig + scale + lineWidthSmall, (y2 + offsetY));
635
if(this.isRepeatOpen()){
636
int size = Math.max(1,Math.round(4f * scale));
637
float xMove = ((lineWidthBig + scale + lineWidthSmall) + (2f * scale));
638
float yMove = ((lineWidthBig + scale + lineWidthSmall) + (2f * scale));
640
painter.setLineWidth(lineWidthSmall);
641
painter.initPath(TGPainter.PATH_FILL);
642
painter.moveTo(x1 + xMove, y1 + ((y2 - y1) / 2) - (yMove + (size / 2)));
643
painter.addOval(x1 + xMove, y1 + ((y2 - y1) / 2) - (yMove + (size / 2)), size,size);
644
painter.moveTo(x1 + xMove, y1 + ((y2 - y1) / 2) + (yMove - (size / 2)));
645
painter.addOval(x1 + xMove, y1 + ((y2 - y1) / 2) + (yMove - (size / 2)), size, size);
650
painter.setLineWidth(lineWidthSmall);
651
painter.moveTo(x1, y1);
652
painter.lineTo(x1, (y2 + offsetY));
657
if(this.getRepeatClose() > 0 || layout.isLastMeasure(this)){
659
painter.setLineWidth(lineWidthSmall);
660
painter.moveTo( (x2 + getSpacing()) - (lineWidthBig + scale + lineWidthSmall) , y1);
661
painter.lineTo( (x2 + getSpacing()) - (lineWidthBig + scale + lineWidthSmall) , y2);
664
painter.initPath(TGPainter.PATH_DRAW | TGPainter.PATH_FILL);
665
painter.setLineWidth(lineWidthSmall);
666
painter.addRectangle( (x2 + getSpacing()) - lineWidthBig, y1, lineWidthBig, y2 - y1);
669
if(this.getRepeatClose() > 0){
670
int size = Math.max(1,Math.round(4f * scale));
671
float xMove = (((lineWidthBig + scale + lineWidthSmall) + (2f * scale)) + size);
672
float yMove = ( (lineWidthBig + scale + lineWidthSmall) + (2f * scale) );
674
painter.setLineWidth(lineWidthSmall);
675
painter.initPath(TGPainter.PATH_FILL);
676
painter.moveTo((x2 - xMove) + getSpacing(), y1 + ((y2 - y1) / 2) - (yMove + (size / 2)));
677
painter.addOval((x2 - xMove) + getSpacing(), y1 + ((y2 - y1) / 2) - (yMove + (size / 2)), size,size);
678
painter.moveTo((x2 - xMove) + getSpacing(), y1 + ((y2 - y1) / 2) + (yMove - (size / 2)));
679
painter.addOval((x2 - xMove) + getSpacing(), y1 + ((y2 - y1) / 2) + (yMove - (size / 2)), size, size);
682
layout.setDivisionsStyle(painter,false);
683
String repetitions = ("x" + this.getRepeatClose());
684
Point numberSize = painter.getStringExtent(repetitions);
685
painter.drawString(repetitions,x2 - numberSize.x + getSpacing() - size,(y1 - numberSize.y) - Math.round(scale));
690
painter.setLineWidth(lineWidthSmall);
691
painter.moveTo(x2 + getSpacing(), y1);
692
painter.lineTo(x2 + getSpacing(), y2);
695
painter.setLineWidth(lineWidthSmall);
701
private void paintClef(ViewLayout layout,TGPainter painter,int fromX, int fromY) {
702
//-----SCORE ------------------------------------//
703
if((layout.getStyle() & ViewLayout.DISPLAY_SCORE) != 0 && this.paintClef){
704
int x = fromX + Math.round( 14 * layout.getScale() ) ;
705
int y = fromY + getTs().getPosition(TrackSpacing.POSITION_SCORE_MIDDLE_LINES);
706
layout.setClefStyle(painter);
707
painter.initPath(TGPainter.PATH_FILL);
708
if(this.getClef() == TGMeasure.CLEF_TREBLE){
709
TGClefPainter.paintTreble(painter, x, y,layout.getScoreLineSpacing());
711
else if(this.getClef() == TGMeasure.CLEF_BASS){
712
TGClefPainter.paintBass(painter, x, y,layout.getScoreLineSpacing());
714
else if(this.getClef() == TGMeasure.CLEF_TENOR){
715
TGClefPainter.paintTenor(painter, x, y,layout.getScoreLineSpacing());
717
else if(this.getClef() == TGMeasure.CLEF_ALTO){
718
TGClefPainter.paintAlto(painter, x, y,layout.getScoreLineSpacing());
725
* Pinta la Armadura de Clave
727
private void paintKeySignature(ViewLayout layout,TGPainter painter, int fromX, int fromY) {
728
if((layout.getStyle() & ViewLayout.DISPLAY_SCORE) != 0 && this.paintKeySignature){
729
float scale = layout.getScoreLineSpacing();
730
int x = fromX + getClefSpacing(layout) + 10;
731
int y = fromY + getTs().getPosition(TrackSpacing.POSITION_SCORE_MIDDLE_LINES);
732
int currentKey = this.getKeySignature();
733
int previousKey = (this.prevMeasure != null ? this.prevMeasure.getKeySignature() : 0);
735
if(this.getClef() == TGMeasure.CLEF_TREBLE){
738
else if(this.getClef() == TGMeasure.CLEF_BASS){
741
else if(this.getClef() == TGMeasure.CLEF_TENOR){
744
else if(this.getClef() == TGMeasure.CLEF_ALTO){
748
layout.setKeySignatureStyle(painter);
751
if(currentKey >= 1 && currentKey <= 7){
752
for(int i = 0; i < currentKey; i ++ ){
753
float offset = ( (scale / 2) * ( ( (SCORE_KEY_SHARP_POSITIONS[i] + offsetClef) + 7) % 7) ) - (scale / 2);
754
painter.initPath(TGPainter.PATH_FILL);
755
TGKeySignaturePainter.paintSharp(painter,x, (y + offset ), scale);
757
x += (scale - (scale / 4));
761
else if(currentKey >= 8 && currentKey <= 14){
762
for(int i = 7; i < currentKey; i ++ ){
763
float offset = ( (scale / 2) * ( ( (SCORE_KEY_FLAT_POSITIONS[i - 7] + offsetClef) + 7) % 7) ) - (scale / 2);
764
painter.initPath(TGPainter.PATH_FILL);
765
TGKeySignaturePainter.paintFlat(painter,x, (y + offset ), scale);
767
x += (scale - (scale / 4));
771
if(previousKey >= 1 && previousKey <= 7){
772
int naturalFrom = (currentKey >= 1 && currentKey <= 7) ? currentKey : 0;
773
for(int i = naturalFrom; i < previousKey; i ++ ){
774
float offset = ( (scale / 2) * ( ( (SCORE_KEY_SHARP_POSITIONS[i] + offsetClef) + 7) % 7) ) - (scale / 2);
775
painter.initPath(TGPainter.PATH_FILL);
776
TGKeySignaturePainter.paintNatural(painter,x, (y + offset ), scale);
778
x += (scale - (scale / 4));
781
else if(previousKey >= 8 && previousKey <= 14){
782
int naturalFrom = (currentKey >= 8 && currentKey <= 14) ? currentKey : 7;
783
for(int i = naturalFrom; i < previousKey; i ++ ){
784
float offset = ( (scale / 2) * ( ( (SCORE_KEY_FLAT_POSITIONS[i - 7] + offsetClef) + 7) % 7) ) - (scale / 2);
785
painter.initPath(TGPainter.PATH_FILL);
786
TGKeySignaturePainter.paintNatural(painter,x, (y + offset ), scale);
788
x += (scale - (scale / 4));
794
private void paintTimeSignature(ViewLayout layout,TGPainter painter, int fromX, int fromY){
795
if(this.getHeaderImpl().shouldPaintTimeSignature()){
796
layout.setTimeSignatureStyle(painter);
797
float scale = layout.getScale();
798
int style = layout.getStyle();
799
int leftSpacing = Math.round( 5.0f * scale );
800
int x = (getClefSpacing(layout) + getKeySignatureSpacing(layout) + getHeaderImpl().getLeftSpacing(layout) + leftSpacing);
801
String numerator = Integer.toString(getTimeSignature().getNumerator());
802
String denominator = Integer.toString(getTimeSignature().getDenominator().getValue());
803
if( (style & ViewLayout.DISPLAY_SCORE) != 0 ){
804
int y = getTs().getPosition(TrackSpacing.POSITION_SCORE_MIDDLE_LINES);
805
int y1 = (int)(y - (3f * scale));
806
int y2 = (int)(((y + (layout.getScoreLineSpacing() * 4)) - painter.getStringExtent(denominator).y) + (3f * scale));
807
painter.drawString(numerator,fromX + x,fromY + y1,true);
808
painter.drawString(denominator,fromX + x,fromY + y2,true);
809
}else if( (style & ViewLayout.DISPLAY_TABLATURE) != 0 ){
810
int y = getTs().getPosition(TrackSpacing.POSITION_TABLATURE);
811
int move = (int)((8f - getTrack().stringCount()) * scale);
813
int y2 = ((y + getTrackImpl().getTabHeight()) - painter.getStringExtent(denominator).y) + move;
814
painter.drawString(numerator,fromX + x,fromY + y1,true);
815
painter.drawString(denominator,fromX + x,fromY + y2,true);
820
private void paintTempo(ViewLayout layout,TGPainter painter){
821
if(this.getHeaderImpl().shouldPaintTempo()){
822
float scale = 5f * layout.getScale();
823
int x = (getPosX() + getHeaderImpl().getLeftSpacing(layout));
825
int lineSpacing = (Math.max(layout.getScoreLineSpacing() , layout.getStringSpacing()));
826
int style = layout.getStyle();
827
if( (style & ViewLayout.DISPLAY_SCORE) != 0 ){
828
y += ( getTs().getPosition(TrackSpacing.POSITION_SCORE_MIDDLE_LINES) - lineSpacing ) ;
829
}else if( (style & ViewLayout.DISPLAY_TABLATURE) != 0 ){
830
y += ( getTs().getPosition(TrackSpacing.POSITION_TABLATURE) - lineSpacing ) ;
833
layout.setTempoStyle(painter, false);
835
int imgY = (y - (Math.round(scale * 3.5f ) + 2));
836
if( layout.isBufferEnabled() ){
837
painter.drawImage(layout.getResources().getTempoImage(),imgX , imgY );
839
TGTempoPainter.paintTempo(painter, imgX, imgY, scale);
842
layout.setTempoStyle(painter, true);
843
String value = (" = " + getTempo().getValue());
844
int fontX = x + (Math.round( (1.33f * scale) ) + 1 );
845
int fontY = Math.round(y - painter.getStringExtent( value ).y - (1.0f * layout.getScale()));
846
painter.drawString(value , fontX, fontY, true);
850
private void paintTripletFeel(ViewLayout layout,TGPainter painter){
851
if(this.getHeaderImpl().shouldPaintTripletFeel()){
852
float scale = (5f * layout.getScale());
853
int x = (getPosX() + getHeaderImpl().getLeftSpacing(layout) + getHeaderImpl().getTempoSpacing(layout));
855
int lineSpacing = (Math.max(layout.getScoreLineSpacing() , layout.getStringSpacing()));
856
int style = layout.getStyle();
857
if( (style & ViewLayout.DISPLAY_SCORE) != 0 ){
858
y += ( getTs().getPosition(TrackSpacing.POSITION_SCORE_MIDDLE_LINES) - lineSpacing );
859
}else if( (style & ViewLayout.DISPLAY_TABLATURE) != 0 ){
860
y += ( getTs().getPosition(TrackSpacing.POSITION_TABLATURE) - lineSpacing );
863
layout.setTripletFeelStyle(painter, true);
864
String equal = (" = ");
865
Point fontSize = painter.getStringExtent( equal );
866
int fontX = x + (Math.round( (1.33f * scale) + (1.5f * scale) ));
867
int fontY = Math.round(y - fontSize.y - (1.0f * layout.getScale()));
868
painter.drawString(equal, fontX , fontY, true);
870
layout.setTripletFeelStyle(painter, false);
872
int x2 = x + (Math.round( (1.33f * scale) + (1.5f * scale) ) + fontSize.x);
873
int y1 = y - (Math.round( (1.0f * scale) + (2.5f * scale) ) + 2);
874
int y2 = y - (Math.round( (1.0f * scale) + (2.5f * scale) + (1.0f * scale)) + 2);
876
if(getTripletFeel() == TGMeasureHeader.TRIPLET_FEEL_NONE && this.prevMeasure != null){
877
int previous = this.prevMeasure.getTripletFeel();
878
if(previous == TGMeasureHeader.TRIPLET_FEEL_EIGHTH){
879
if( layout.isBufferEnabled() ){
880
painter.drawImage(layout.getResources().getTripletFeel8(), x1, y2 );
881
painter.drawImage(layout.getResources().getTripletFeelNone8(),x2 , y1 );
884
TGTripletFeelPainter.paintTripletFeel8(painter, x1, y2, scale );
885
TGTripletFeelPainter.paintTripletFeelNone8(painter, x2 , y1, scale );
888
else if(previous == TGMeasureHeader.TRIPLET_FEEL_SIXTEENTH){
889
if( layout.isBufferEnabled() ){
890
painter.drawImage(layout.getResources().getTripletFeel16(), x1, y2 );
891
painter.drawImage(layout.getResources().getTripletFeelNone16(),x2 , y1 );
894
TGTripletFeelPainter.paintTripletFeel16(painter, x1, y2, scale );
895
TGTripletFeelPainter.paintTripletFeelNone16(painter, x2 , y1, scale );
899
else if(getTripletFeel() == TGMeasureHeader.TRIPLET_FEEL_EIGHTH){
900
if( layout.isBufferEnabled() ){
901
painter.drawImage(layout.getResources().getTripletFeelNone8(), x1, y1 );
902
painter.drawImage(layout.getResources().getTripletFeel8(),x2 , y2 );
905
TGTripletFeelPainter.paintTripletFeelNone8(painter, x1, y1, scale );
906
TGTripletFeelPainter.paintTripletFeel8(painter, x2 , y2, scale );
909
else if(getTripletFeel() == TGMeasureHeader.TRIPLET_FEEL_SIXTEENTH){
910
if( layout.isBufferEnabled() ){
911
painter.drawImage(layout.getResources().getTripletFeelNone16(), x1, y1 );
912
painter.drawImage(layout.getResources().getTripletFeel16(),x2 , y2 );
915
TGTripletFeelPainter.paintTripletFeelNone16(painter, x1, y1, scale );
916
TGTripletFeelPainter.paintTripletFeel16(painter, x2 , y2, scale );
922
private void paintTexts(ViewLayout layout,TGPainter painter){
923
Iterator it = getBeats().iterator();
925
TGBeat beat = (TGBeat)it.next();
926
if( beat.isTextBeat() ){
927
TGTextImpl text = (TGTextImpl)beat.getText();
928
text.paint(layout, painter,(getPosX() + getHeaderImpl().getLeftSpacing(layout) ),getPosY());
933
private void paintPlayMode(ViewLayout layout,TGPainter painter){
934
if(layout.isPlayModeEnabled() && isPlaying(layout)){
935
float scale = layout.getScale();
936
int width = getWidth(layout) + getSpacing();
939
int style = layout.getStyle();
940
if( (style & (ViewLayout.DISPLAY_SCORE | ViewLayout.DISPLAY_TABLATURE)) == (ViewLayout.DISPLAY_SCORE | ViewLayout.DISPLAY_TABLATURE) ){
941
y1 += (getTs().getPosition(TrackSpacing.POSITION_SCORE_MIDDLE_LINES) - layout.getScoreLineSpacing());
942
y2 += (getTs().getPosition(TrackSpacing.POSITION_TABLATURE) + getTrackImpl().getTabHeight() + layout.getStringSpacing());
943
}else if( (style & ViewLayout.DISPLAY_SCORE) != 0 ){
944
y1 += (getTs().getPosition(TrackSpacing.POSITION_SCORE_MIDDLE_LINES) - layout.getScoreLineSpacing());
945
y2 += (getTs().getPosition(TrackSpacing.POSITION_SCORE_MIDDLE_LINES) + (layout.getScoreLineSpacing() * 5));
946
} else if( (style & ViewLayout.DISPLAY_TABLATURE) != 0 ){
947
y1 += (getTs().getPosition(TrackSpacing.POSITION_TABLATURE) - layout.getStringSpacing());
948
y2 += (getTs().getPosition(TrackSpacing.POSITION_TABLATURE) + getTrackImpl().getTabHeight() + layout.getStringSpacing());
950
layout.setMeasurePlayingStyle(painter);
951
// Don't uncomment "lineStyle" until be sure SWT bug has fixed.
952
// See bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=225725
953
//painter.setLineStyle(SWT.LINE_DASH);
954
painter.setLineWidth(1);
956
painter.addRectangle(getPosX() + (5f * scale),y1,width - (10f * scale),(y2 - y1));
958
//painter.setLineStyle(SWT.LINE_SOLID);
963
* Retorna true si se esta reproduciendo y la posicion del player esta en este compas.
965
public boolean isPlaying(ViewLayout layout){
966
return (getTrackImpl().hasCaret(layout) && TuxGuitar.instance().getEditorCache().isPlaying(this));
969
public int getBeatSpacing(TGBeat beat){
970
return (int)((beat.getStart() - getStart()) * getSpacing() / getLength());
973
public boolean hasTrack(int number){
974
return (getTrack().getNumber() == number);
978
* Retorna el ancho del Compas
980
public int getWidth(ViewLayout layout) {
981
return ((layout.getStyle() & ViewLayout.DISPLAY_MULTITRACK) != 0 ?this.getHeaderImpl().getMaxWidth():this.width);
984
private int calculateKeySignatureSpacing(ViewLayout layout){
986
if(this.paintKeySignature){
987
if(this.getKeySignature() <= 7){
988
spacing += Math.round( ( 6f * layout.getScale() ) * this.getKeySignature() ) ;
990
spacing += Math.round( ( 6f * layout.getScale() ) * (this.getKeySignature() - 7) ) ;
992
if(this.prevMeasure != null ){
993
if(this.prevMeasure.getKeySignature() <= 7){
994
spacing += Math.round( ( 6f * layout.getScale() ) * this.prevMeasure.getKeySignature() ) ;
996
spacing += Math.round( ( 6f * layout.getScale() ) * (this.prevMeasure.getKeySignature() - 7) ) ;
1003
public int getFirstNoteSpacing(ViewLayout layout){
1004
return getHeaderImpl().getFirstNoteSpacing(layout,this);
1007
public int getClefSpacing(ViewLayout layout){
1008
return getHeaderImpl().getClefSpacing(layout, this);
1011
public int getKeySignatureSpacing(ViewLayout layout){
1012
return getHeaderImpl().getKeySignatureSpacing(layout, this);
1015
public long getDivisionLength(){
1016
return this.divisionLength;
1019
public boolean isBufferCreated() {
1020
return this.bufferCreated;
1023
public void setBufferCreated(boolean bufferCreated) {
1024
this.bufferCreated = bufferCreated;
1028
* Retorna la posicion X dentro del compas
1030
public int getPosX() {
1035
* Asigna la posicion X dentro del compas
1037
public void setPosX(int posX) {
1042
* Retorna la posicion Y dentro del compas
1044
public int getPosY() {
1049
* Asigna la posicion Y dentro del compas
1051
public void setPosY(int posY) {
1056
* Retorna el spacing de negras
1058
private int getQuarterSpacing(){
1059
return this.quarterSpacing;
1063
* Retorna el spacing de negras
1065
private int getMaxQuarterSpacing(ViewLayout layout){
1066
return (((layout.getStyle() & ViewLayout.DISPLAY_MULTITRACK) != 0)?getHeaderImpl().getMaxQuarterSpacing():this.quarterSpacing);
1069
public TGMeasureHeaderImpl getHeaderImpl(){
1070
return (TGMeasureHeaderImpl)super.getHeader();
1073
public int getSpacing() {
1074
return this.spacing;
1077
public void setSpacing(int spacing) {
1078
if(spacing != this.spacing){
1079
setBufferCreated(false);
1081
this.spacing = spacing;
1084
public boolean isOutOfBounds() {
1085
return this.outOfBounds;
1088
public void setOutOfBounds(boolean outOfBounds) {
1089
this.outOfBounds = outOfBounds;
1092
public boolean isFirstOfLine() {
1093
return this.firstOfLine;
1096
public void setFirstOfLine(boolean firstOfLine) {
1097
this.firstOfLine = firstOfLine;
1100
public TGTrackImpl getTrackImpl(){
1101
return (TGTrackImpl)super.getTrack();
1104
public TrackSpacing getTs() {
1108
public void setTs(TrackSpacing ts) {
1109
if(getTs() == null){
1110
setBufferCreated(false);
1111
}else if(getTs().getPosition(TrackSpacing.POSITION_SCORE_MIDDLE_LINES) != ts.getPosition(TrackSpacing.POSITION_SCORE_MIDDLE_LINES)){
1112
setBufferCreated(false);
1113
}else if(getTs().getPosition(TrackSpacing.POSITION_TABLATURE) != ts.getPosition(TrackSpacing.POSITION_TABLATURE)){
1114
setBufferCreated(false);
1119
public int getMaxY() {
1123
public int getMinY() {
1127
public int getNotEmptyBeats(){
1128
return this.notEmptyBeats;
1131
public int getLyricBeatIndex() {
1132
return this.lyricBeatIndex;
1135
public void setLyricBeatIndex(int lyricBeatIndex) {
1136
this.lyricBeatIndex = lyricBeatIndex;
1139
public boolean isPaintClef() {
1140
return this.paintClef;
1143
public boolean isPaintKeySignature() {
1144
return this.paintKeySignature;
1147
public boolean isDisposed(){
1148
return getBuffer().isDisposed();
1151
public TGMeasureBuffer getBuffer(){
1152
if(this.buffer == null){
1153
this.buffer = new TGMeasureBuffer(TuxGuitar.instance().getDisplay());
1158
public void dispose(){
1159
new SyncThread( new Runnable() {
1161
if(!TuxGuitar.isDisposed()){
1162
getBuffer().dispose();
1163
Iterator it = getBeats().iterator();
1164
while(it.hasNext()){
1165
TGBeatImpl beat = (TGBeatImpl)it.next();
b'\\ No newline at end of file'