1
package org.herac.tuxguitar.gui.editors.tab;
3
import java.util.Iterator;
5
import org.herac.tuxguitar.gui.TuxGuitar;
6
import org.herac.tuxguitar.gui.editors.TGPainter;
7
import org.herac.tuxguitar.gui.editors.tab.layout.TrackSpacing;
8
import org.herac.tuxguitar.gui.editors.tab.layout.ViewLayout;
9
import org.herac.tuxguitar.gui.editors.tab.painters.TGNotePainter;
10
import org.herac.tuxguitar.gui.editors.tab.painters.TGSilencePainter;
11
import org.herac.tuxguitar.song.factory.TGFactory;
12
import org.herac.tuxguitar.song.models.TGBeat;
13
import org.herac.tuxguitar.song.models.TGDuration;
14
import org.herac.tuxguitar.song.models.TGTupleto;
16
public class TGBeatImpl extends TGBeat{
18
* desviacion a la izquierda
20
public static final int JOINED_TYPE_NONE_LEFT = 1;
22
* desviacion a la derecha
24
public static final int JOINED_TYPE_NONE_RIGHT = 2;
26
* Union a la izquierda
28
public static final int JOINED_TYPE_LEFT = 3;
32
public static final int JOINED_TYPE_RIGHT = 4;
36
private TGNoteImpl maxNote;
37
private TGNoteImpl minNote;
38
private boolean[] usedStrings;
39
private int joinedType;
40
private boolean joinedGreaterThanQuarter;
41
private TGBeatImpl join1;
42
private TGBeatImpl join2;
43
private TGBeatImpl previous;
44
private TGBeatImpl next;
45
private TGBeatGroup group;
47
public TGBeatImpl(TGFactory factory){
51
public int getPosX() {
55
public void setPosX(int posX) {
59
public int getWidth() {
63
public void setWidth(int width) {
67
public TGNoteImpl getMinNote(){
71
public TGNoteImpl getMaxNote(){
75
public TGMeasureImpl getMeasureImpl() {
76
return (TGMeasureImpl)getMeasure();
79
public boolean[] getUsedStrings() {
80
if(this.usedStrings == null){
81
this.usedStrings = new boolean[getMeasure().getTrack().stringCount()];
83
return this.usedStrings;
86
public TGBeatImpl getJoin1() {
90
public void setJoin1(TGBeatImpl join1) {
94
public TGBeatImpl getJoin2() {
98
public void setJoin2(TGBeatImpl join2) {
102
public boolean isJoinedGreaterThanQuarter() {
103
return this.joinedGreaterThanQuarter;
106
public void setJoinedGreaterThanQuarter(boolean joinedGreaterThanQuarter) {
107
this.joinedGreaterThanQuarter = joinedGreaterThanQuarter;
110
public int getJoinedType() {
111
return this.joinedType;
114
public void setJoinedType(int joinedType) {
115
this.joinedType = joinedType;
118
public void setPreviousBeat(TGBeatImpl previous){
119
this.previous = previous;
122
public void setNextBeat(TGBeatImpl next){
126
public TGBeatGroup getBeatGroup() {
130
public void setBeatGroup(TGBeatGroup group) {
134
public int getSpacing(){
135
return getMeasureImpl().getBeatSpacing(this);
138
public boolean isPlaying(ViewLayout layout){
139
return (getMeasureImpl().isPlaying(layout) && TuxGuitar.instance().getEditorCache().isPlaying(getMeasure(),this));
145
this.usedStrings = new boolean[getMeasure().getTrack().stringCount()];
148
public void check(TGNoteImpl note){
149
int value = note.getRealValue();
150
if(this.maxNote == null || value > this.maxNote.getRealValue()){
153
if(this.minNote == null || value < this.minNote.getRealValue()){
156
this.getUsedStrings();
157
this.usedStrings[note.getString() - 1] = true;
161
if(!TuxGuitar.instance().getPlayer().isRunning()){
162
new Thread(new Runnable() {
164
TuxGuitar.instance().getPlayer().playBeat(getMeasure().getTrack(),getNotes());
170
public void update(ViewLayout layout) {
172
this.joinedType = JOINED_TYPE_NONE_RIGHT;
173
this.joinedGreaterThanQuarter = false;
177
boolean noteJoined = false;
178
boolean withPrev = false;
180
//trato de unir con el componente anterior
181
if (this.previous != null && !this.previous.isRestBeat()) {
182
if (getMeasureImpl().canJoin(layout.getSongManager(),this, this.previous)) {
184
if (this.previous.getDuration().getValue() >= getDuration().getValue()) {
185
this.setJoin1(this.previous);
187
this.joinedType = JOINED_TYPE_LEFT;
190
if (this.previous.getDuration().getValue() > TGDuration.QUARTER){
191
this.joinedGreaterThanQuarter = true;
196
//trato de unir con el componente que le sigue
197
if (this.next != null && !this.next.isRestBeat() ) {
198
if (getMeasureImpl().canJoin(layout.getSongManager(),this, this.next)) {
199
if (this.next.getDuration().getValue() >= getDuration().getValue()) {
200
this.setJoin2(this.next);
201
if (this.previous == null || this.previous.isRestBeat() || this.previous.getDuration().getValue() < getDuration().getValue()) {
205
this.joinedType = JOINED_TYPE_RIGHT;
207
if (this.next.getDuration().getValue() > TGDuration.QUARTER){
208
this.joinedGreaterThanQuarter = true;
213
//si no hubo union decido para que lado girar la figura
214
if (!noteJoined && withPrev) {
215
this.joinedType = JOINED_TYPE_NONE_LEFT;
220
public void paint(ViewLayout layout,TGPainter painter, int fromX, int fromY) {
221
paint(layout, painter, fromX, fromY, false);
224
public void paint(ViewLayout layout,TGPainter painter, int fromX, int fromY/*,boolean playMode*/) {
225
if(!layout.isPlayModeEnabled() && (layout.getStyle() & ViewLayout.DISPLAY_SCORE) != 0 ){
226
paintExtraLines(painter, layout,fromX, fromY);
230
paintSilence(layout, painter, fromX, fromY);
233
Iterator notes = getNotes().iterator();
234
while (notes.hasNext()) {
235
TGNoteImpl note = (TGNoteImpl)notes.next();
236
note.paint(layout,painter,fromX ,fromY);
238
if(!layout.isPlayModeEnabled()){
239
paintBeat(layout, painter, fromX, fromY) ;
242
TGChordImpl chord = (TGChordImpl)getChord();
243
chord.paint(layout,painter,fromX,fromY);
250
public void paintSilence(ViewLayout layout,TGPainter painter, int fromX, int fromY) {
251
int style = layout.getStyle();
259
if((style & ViewLayout.DISPLAY_SCORE) != 0 ){
260
x = fromX + getPosX() + getSpacing();
261
firstLineY = fromY + getPaintPosition(TrackSpacing.POSITION_SCORE_MIDDLE_LINES);
262
lineSpacing = layout.getScoreLineSpacing();
264
scale = (lineSpacing / 9.0f);
266
x = fromX + getPosX() + getSpacing() - 1;
267
firstLineY = fromY + getPaintPosition(TrackSpacing.POSITION_TABLATURE);
268
lineSpacing = layout.getStringSpacing();
269
lineCount = getMeasure().getTrack().stringCount();
270
scale = (lineSpacing / 10.0f);
273
setStyle(layout, painter,(layout.isPlayModeEnabled() && isPlaying(layout)));
274
painter.initPath(TGPainter.PATH_FILL);
276
int duration = getDuration().getValue();
277
if(duration == TGDuration.WHOLE){
278
y = firstLineY + ( lineCount <= 5 ? lineSpacing : lineSpacing * 2 );
279
TGSilencePainter.paintWhole(painter, x, y , scale);
281
if(duration == TGDuration.HALF){
282
y = firstLineY + ( lineCount <= 5 ? lineSpacing * 2 : lineSpacing * 3 ) - (scale * 3);
283
TGSilencePainter.paintHalf(painter, x, y , scale);
285
if(duration == TGDuration.QUARTER){
286
y = firstLineY + ((lineSpacing * (lineCount - 1)) / 2) - (scale * 8) ;
287
TGSilencePainter.paintQuarter(painter, x, y, scale);
289
else if(duration == TGDuration.EIGHTH){
290
y = firstLineY + ((lineSpacing * (lineCount - 1)) / 2) - (scale * 6) ;
291
TGSilencePainter.paintEighth(painter, x, y, scale);
293
else if(duration == TGDuration.SIXTEENTH){
294
y = firstLineY + ((lineSpacing * (lineCount - 1)) / 2) - (scale * 8) ;
295
TGSilencePainter.paintSixteenth(painter, x, y, scale);
297
else if(duration == TGDuration.THIRTY_SECOND){
298
y = firstLineY + ((lineSpacing * (lineCount - 1)) / 2) - (scale * 12) ;
299
TGSilencePainter.paintThirtySecond(painter, x, y, scale);
301
else if(duration == TGDuration.SIXTY_FOURTH){
302
y = firstLineY + ((lineSpacing * (lineCount - 1)) / 2) - (scale * 14) ;
303
TGSilencePainter.paintSixtyFourth(painter, x, y, scale);
308
if(getDuration().isDotted() || getDuration().isDoubleDotted()){
309
layout.setDotStyle(painter);
311
painter.moveTo(x + 10,y +1);
312
painter.addOval(x + 10,y +1,1,1);
313
if(getDuration().isDoubleDotted()){
314
painter.moveTo(x + 13,y +1);
315
painter.addOval(x + 13,y +1,1,1);
319
if(!getDuration().getTupleto().isEqual(TGTupleto.NORMAL)){
320
layout.setTupletoStyle(painter);
321
if((style & ViewLayout.DISPLAY_SCORE) != 0 ){
322
painter.drawString(Integer.toString(getDuration().getTupleto().getEnters()), x,(fromY + getPaintPosition(TrackSpacing.POSITION_TUPLETO)));
324
painter.drawString(Integer.toString(getDuration().getTupleto().getEnters()),x,(fromY + getPaintPosition(TrackSpacing.POSITION_TUPLETO)));
329
public void setStyle(ViewLayout layout, TGPainter painter, boolean playMode){
330
if((layout.getStyle() & ViewLayout.DISPLAY_SCORE) != 0 ){
331
layout.setScoreSilenceStyle(painter, playMode);
333
layout.setTabSilenceStyle(painter, playMode);
337
public void paintExtraLines(TGPainter painter,ViewLayout layout,int fromX, int fromY){
339
int scoreY = (fromY + getMeasureImpl().getTs().getPosition(TrackSpacing.POSITION_SCORE_MIDDLE_LINES));
340
paintExtraLines(painter,layout,getMinNote(), fromX, scoreY);
341
paintExtraLines(painter,layout,getMaxNote(), fromX, scoreY);
345
private void paintExtraLines(TGPainter painter,ViewLayout layout,TGNoteImpl note,int fromX,int fromY){
346
float scale = layout.getScale();
347
int y = fromY + note.getScorePosY();
348
int x = fromX + getPosX() + getSpacing();
349
float x1 = x - (4 * scale);
350
float x2 = x + (12 * scale);
352
int scoreLineSpacing = layout.getScoreLineSpacing();
354
layout.setLineStyle(painter);
356
for(int i = fromY;i > y;i -= scoreLineSpacing){
358
painter.moveTo(x1,i);
359
painter.lineTo(x2,i);
362
}else if(y > (fromY + (scoreLineSpacing * 4))){
363
for(int i = (fromY +(scoreLineSpacing * 5));i < (y + scoreLineSpacing);i += scoreLineSpacing){
365
painter.moveTo(x1,i);
366
painter.lineTo(x2,i);
372
public void paintBeat(ViewLayout layout,TGPainter painter, int fromX, int fromY){
374
int style = layout.getStyle();
375
int spacing = getSpacing();
377
if((style & ViewLayout.DISPLAY_SCORE) != 0){
378
paintScoreBeat(layout, painter, fromX, fromY+getPaintPosition(TrackSpacing.POSITION_SCORE_MIDDLE_LINES), spacing);
380
if((style & ViewLayout.DISPLAY_TABLATURE) != 0 && (style & ViewLayout.DISPLAY_SCORE) == 0){
381
paintTablatureBeat(layout, painter, fromX, fromY + getPaintPosition(TrackSpacing.POSITION_TABLATURE), spacing);
386
public void paintTablatureBeat(ViewLayout layout,TGPainter painter, int fromX, int fromY, int spacing){
389
int stringSpacing = layout.getStringSpacing();
390
int x = ( fromX + getPosX() + spacing + xMove );
392
int y1 = (fromY + getMeasureImpl().getTrackImpl().getTabHeight() + (stringSpacing / 2));
393
int y2 = (fromY + getMeasureImpl().getTrackImpl().getTabHeight() + ((stringSpacing / 2) * 5));
395
if (getDuration().getValue() >= TGDuration.QUARTER) {
396
layout.setTabNoteFooterStyle(painter);
399
boolean painting = false;
400
boolean[] usedStrings = getUsedStrings();
401
for (int i = 0; i < usedStrings.length; i++) {
402
if (!usedStrings[i] && painting) {
403
int stringPosition = (fromY + (stringSpacing * (i + 1)) - stringSpacing);
404
int posY1 = stringPosition - (stringSpacing / 2);
405
int posY2 = stringPosition + (stringSpacing / 2);
406
posY2 = ((posY2 - posY1 < stringSpacing)?posY2 + 1:posY2);
407
painter.moveTo(x, posY1);
408
painter.lineTo(x, posY2);
410
painting = ( painting || usedStrings[i] );
412
painter.moveTo(x, y1);
413
painter.lineTo(x, y2);
415
if (getDuration().getValue() >= TGDuration.EIGHTH) {
418
int scale = (layout.getStringSpacing() / 2);
419
int joinedType = getJoinedType();
420
if(joinedType == TGBeatImpl.JOINED_TYPE_NONE_RIGHT){
421
x1 = getPosX() + xMove + spacing;
422
x2 = getPosX() + xMove + spacing + 6;
423
}else if(joinedType == TGBeatImpl.JOINED_TYPE_NONE_LEFT){
424
x1 = getPosX() + xMove + spacing - 5;
425
x2 = getPosX() + xMove + spacing;
427
x1 = getJoin1().getPosX() + xMove + getJoin1().getSpacing();
428
x2 = getJoin2().getPosX() + xMove + getJoin2().getSpacing();
430
int index = ( getDuration().getIndex() - 2);
432
painter.setLineWidth(2);
434
for(int i = index; i > 0 ;i --){
435
painter.moveTo(fromX + x1, y2 + (scale - (i * scale)));
436
painter.lineTo(fromX + x2, y2 + (scale - (i * scale)));
439
painter.setLineWidth(1);
442
} else if (getDuration().getValue() == TGDuration.HALF) {
443
layout.setTabNoteFooterStyle(painter);
445
painter.moveTo(x, (y1 + ((y2 - y1) / 2)));
446
painter.lineTo(x, y2);
450
//-------------puntillo--------------------------------------
451
if (getDuration().isDotted() || getDuration().isDoubleDotted()) {
452
int joinedType = getJoinedType();
454
float scale = (stringSpacing / 10.0f);
455
float posX = ((getDuration().getValue() > TGDuration.WHOLE)?((joinedType == TGBeatImpl.JOINED_TYPE_NONE_RIGHT || joinedType == TGBeatImpl.JOINED_TYPE_RIGHT)?(x+ (4.0f * scale)):(x- (5.0f * scale))):x);
456
float posY = (y2 - ((getDuration().getValue() >= TGDuration.EIGHTH)? ((stringSpacing / 2) * (getDuration().getIndex() - 2)):(1.0f * scale)));
457
paintDot(layout, painter, posX, posY,scale);
460
//-------------tresillo--------------------------------------
461
if (!getDuration().getTupleto().isEqual(TGTupleto.NORMAL)) {
462
layout.setTupletoStyle(painter);
463
painter.drawString(Integer.toString(getDuration().getTupleto().getEnters()), x - 3,((fromY - getPaintPosition(TrackSpacing.POSITION_TABLATURE)) + getPaintPosition(TrackSpacing.POSITION_TUPLETO)));
468
public void paintScoreBeat(ViewLayout layout,TGPainter painter, int fromX, int fromY, int spacing){
469
int vX = ( fromX + getPosX() + spacing );
472
if (!getDuration().getTupleto().isEqual(TGTupleto.NORMAL)) {
473
layout.setTupletoStyle(painter);
474
painter.drawString(Integer.toString(getDuration().getTupleto().getEnters()),vX ,((fromY - getPaintPosition(TrackSpacing.POSITION_SCORE_MIDDLE_LINES)) + getPaintPosition(TrackSpacing.POSITION_TUPLETO)));
477
if(getDuration().getValue() >= TGDuration.HALF){
478
layout.setScoreNoteFooterStyle(painter);
480
float scale = layout.getScale();
481
float lineSpacing = layout.getScoreLineSpacing();
482
int direction = this.group.getDirection();
483
int key = getMeasure().getKeySignature();
484
int clef = getMeasure().getClef();
486
int xMove = (direction == TGBeatGroup.DIRECTION_UP ? layout.getResources().getScoreNoteWidth() : 0);
487
int yMove = (direction == TGBeatGroup.DIRECTION_UP ? ((layout.getScoreLineSpacing() / 3) + 1) : ((layout.getScoreLineSpacing() / 3) * 2));
489
int vY1 = fromY + ( direction == TGBeatGroup.DIRECTION_DOWN ? this.maxNote.getScorePosY() : this.minNote.getScorePosY() );
490
int vY2 = fromY + this.group.getY2(layout,getPosX() + spacing,key,clef);
493
painter.moveTo(vX + xMove, vY1 + yMove);
494
painter.lineTo(vX + xMove, vY2);
497
if (getDuration().getValue() >= TGDuration.EIGHTH) {
498
int index = ( getDuration().getIndex() - 3);
500
int dir = (direction == TGBeatGroup.DIRECTION_DOWN)?1:-1;
501
int joinedType = getJoinedType();
502
boolean joinedGreaterThanQuarter = isJoinedGreaterThanQuarter();
504
if((joinedType == TGBeatImpl.JOINED_TYPE_NONE_LEFT || joinedType == TGBeatImpl.JOINED_TYPE_NONE_RIGHT) && !joinedGreaterThanQuarter){
505
float hX = (fromX + xMove + getPosX() + spacing);
506
float hY = ( (fromY + this.group.getY2(layout,getPosX() + spacing,key,clef)) - ( (lineSpacing * 2)* dir )) ;
507
for(int i = 0; i <= index; i ++){
508
painter.initPath(TGPainter.PATH_FILL);
509
TGNotePainter.paintFooter(painter,hX,(hY - ( (i * (lineSpacing / 2.0f)) * dir)),dir,lineSpacing);
515
if(joinedType == TGBeatImpl.JOINED_TYPE_NONE_RIGHT){
516
hX1 = getPosX() + spacing;
517
hX2 = getPosX() + spacing + 6;
518
}else if(joinedType == TGBeatImpl.JOINED_TYPE_NONE_LEFT){
519
hX1 = getPosX() + spacing - 5;
520
hX2 = getPosX() + spacing;
522
hX1 = getJoin1().getPosX() + getJoin1().getSpacing();
523
hX2 = getJoin2().getPosX() + getJoin2().getSpacing();
525
int hY1 = fromY + this.group.getY2(layout,hX1,key,clef);
526
int hY2 = fromY + this.group.getY2(layout,hX2,key,clef);
527
//painter.setLineWidth(3);
528
painter.setLineWidth(Math.max(1,Math.round(3f * scale)));
530
for(int i = 0; i <= index; i ++){
531
painter.moveTo(fromX + xMove + hX1, hY1 - ( (i * (5f * scale)) * dir));
532
painter.lineTo(fromX + xMove + hX2, hY2 - ( (i * (5f * scale)) * dir));
533
//painter.moveTo(fromX + xMove + hX1, hY1 - ( (i * (scale/1.6f)) * dir));
534
//painter.lineTo(fromX + xMove + hX2, hY2 - ( (i * (scale/1.6f)) * dir));
537
painter.setLineWidth(1);
544
public void paintDot(ViewLayout layout,TGPainter painter,float fromX, float fromY,float scale){
545
float dotSize = (3.0f * scale);
548
layout.setDotStyle(painter);
549
painter.initPath(TGPainter.PATH_FILL);
550
painter.moveTo(posX - (dotSize / 2), posY - (dotSize / 2));
551
painter.addOval(posX - (dotSize / 2), posY - (dotSize / 2), dotSize,dotSize);
552
if(getDuration().isDoubleDotted()){
553
painter.moveTo(posX + (dotSize + 2) - (dotSize / 2), posY - (dotSize / 2));
554
painter.addOval(posX + (dotSize + 2) - (dotSize / 2), posY - (dotSize / 2), dotSize,dotSize);
559
public int getPaintPosition(int index){
560
return getMeasureImpl().getTs().getPosition(index);
563
public void removeChord(){
565
TGChordImpl chord = (TGChordImpl)getChord();
571
public void dispose(){
573
TGChordImpl chord = (TGChordImpl)getChord();