You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
406 lines
13 KiB
Java
406 lines
13 KiB
Java
package main;
|
|
|
|
import java.awt.Color;
|
|
import java.awt.Font;
|
|
import java.awt.FontMetrics;
|
|
import java.awt.Graphics;
|
|
import java.awt.Graphics2D;
|
|
import java.awt.font.FontRenderContext;
|
|
import java.awt.font.TextLayout;
|
|
import javax.swing.JPanel;
|
|
import java.awt.geom.Rectangle2D;
|
|
|
|
public class Note extends JPanel{
|
|
|
|
int noTimesClicked = 0;
|
|
double x;
|
|
double y;
|
|
int n;
|
|
int d;
|
|
int v;
|
|
int p;
|
|
double pitch;
|
|
int clefChoice;
|
|
int octavaAndBassoChoice;
|
|
int spellingChoice;
|
|
int ratioChoice;
|
|
int noteHeadChoice = 0;
|
|
String[] clefs = {"\uf03f", "\uf042", "\uf042", "\uf026"};
|
|
String[] octavasAndBassos = {"15", "8", " ", "8", "15"};
|
|
String[] acc = {"\uf062","\uf06e", "\uf023"};
|
|
|
|
float clickAndPlayX1;
|
|
float clickAndPlayX2;
|
|
|
|
Color color = Color.BLACK;
|
|
|
|
boolean isListening = false;
|
|
|
|
public Note(double x, double y, double p, int v, int pP){
|
|
this.x = x;
|
|
this.y = y;
|
|
n = (int) (Rise.FIRST_NUM+v-pP);
|
|
d = (int) (Rise.FIRST_NUM-pP);
|
|
this.pitch = p + Rise.TRANSPOSE_SCORE * 100.;
|
|
this.v = v;
|
|
this.p = pP;
|
|
this.setOpaque(false);
|
|
this.setBackground(Color.WHITE);
|
|
this.setBounds((int) 0, (int) 0,(int) (Rise.PAGE_WIDTH*Rise.ZOOM), (int) (Rise.PAGE_HEIGHT*Rise.ZOOM));
|
|
initializeChoices();
|
|
}
|
|
|
|
public void paint(Graphics g){
|
|
g.setColor(color);
|
|
Graphics2D g2 = (Graphics2D) g;
|
|
this.setBounds((int) 0, (int) 0,(int) (Rise.PAGE_WIDTH*Rise.ZOOM), (int) (Rise.PAGE_HEIGHT*Rise.ZOOM));
|
|
g2.translate(Rise.PAGE_MARGIN*Rise.ZOOM, Rise.PAGE_MARGIN*Rise.ZOOM);
|
|
g2.scale(Rise.ZOOM, Rise.ZOOM);
|
|
|
|
FontRenderContext frc = g2.getFontRenderContext();
|
|
Font fontMusic = new Font("Maestro", Font.PLAIN, (int) Rise.FONT);
|
|
fontMusic.deriveFont(Rise.FONT);
|
|
Font fontNumbers = new Font("Liberation Serif", Font.PLAIN, (int) Math.round(Rise.FONT/1.714));
|
|
Font fontOBSigns = new Font("Liberation Serif", Font.PLAIN, (int) Math.round(Rise.FONT/2.4));
|
|
TextLayout note = new TextLayout("\uf0cf", fontMusic, frc);
|
|
TextLayout staff = new TextLayout("\uf03d\uf03d", fontMusic, frc);
|
|
TextLayout ledgerLine = new TextLayout("\uf02d", fontMusic, frc);
|
|
g2.setFont(fontMusic);
|
|
FontMetrics fontMetrics = g2.getFontMetrics();
|
|
double noteWidth = fontMetrics.stringWidth("\uf0cf");
|
|
double staffWidth = fontMetrics.stringWidth("\uf03d");
|
|
double ledgerWidth = fontMetrics.stringWidth("\uf02d");
|
|
double staffSpace = Rise.FONT/8.;
|
|
float noteX = (float) (x*Rise.IMAGE_WIDTH - noteWidth/2. /*- ((1./(Rise.VOICES-1))*(p-v)/p)*Rise.IMAGE_WIDTH*Rise.X_DIV*/);
|
|
float noteY = (float) y*Rise.IMAGE_HEIGHT;
|
|
|
|
float toneX1 = (float) (x*Rise.IMAGE_WIDTH - ((1./(Rise.VOICES-1))*(p-v)/p)*Rise.IMAGE_WIDTH*Rise.X_DIV);
|
|
float toneX2;
|
|
if (p != Rise.VOICES-1) {
|
|
toneX2 = (float) (x*Rise.IMAGE_WIDTH + ((1./(Rise.VOICES-1))*v/(p+1))*Rise.IMAGE_WIDTH*Rise.X_DIV);
|
|
}
|
|
else {
|
|
toneX2 = (float) (x*Rise.IMAGE_WIDTH + ((1./(Rise.VOICES-1))*.25)*Rise.IMAGE_WIDTH*Rise.X_DIV);
|
|
}
|
|
float toneY1 = (float) (noteY - note.getBounds().getMaxY()/3);
|
|
float toneY2 = (float) (noteY - note.getBounds().getMinY()/3);
|
|
|
|
//System.out.println("notes " + ((1./(Rise.VOICES-1))*(p-v)/p) + " " + ((1./(Rise.VOICES-1))*v/(p+1)));
|
|
|
|
g2.setColor(new Color(200, 200, 200));
|
|
g2.fill(new Rectangle2D.Float(toneX1, toneY1, toneX2-toneX1, toneY2-toneY1));
|
|
g2.setColor(color);
|
|
|
|
clickAndPlayX1 = toneX1;
|
|
clickAndPlayX2 = toneX2;
|
|
|
|
note.draw(g2,noteX,noteY);
|
|
|
|
double accWidth = fontMetrics.stringWidth(acc[getAcc((int) (Math.round(pitch/100.)%12))]);
|
|
TextLayout accidental = new TextLayout(acc[getAcc((int) (Math.round(pitch/100.)%12))], fontMusic, frc);
|
|
accidental.draw(g2,(float) (noteX-accWidth-2),(float) y*Rise.IMAGE_HEIGHT);
|
|
|
|
int notePosition = getNotePosition((int) (Math.round(pitch/100.)%12));
|
|
|
|
int centDeviation = (int) Math.round((pitch/100. - Math.round(pitch/100.))*100.);
|
|
TextLayout centDeviationText;
|
|
if (centDeviation >= 0) {
|
|
centDeviationText = new TextLayout("+" + String.valueOf(centDeviation), fontNumbers, frc);
|
|
}
|
|
else {
|
|
centDeviationText = new TextLayout(String.valueOf(centDeviation), fontNumbers, frc);
|
|
}
|
|
|
|
for (int i = d; i > 0; i--) {
|
|
if (Math.round((float) d/i) == (float) d/i
|
|
&& Math.round((float) n/i) == (float) n/i) {
|
|
n = n/i;
|
|
d = d/i;
|
|
}
|
|
}
|
|
TextLayout ratioText = new TextLayout(String.valueOf(n) + "/" + String.valueOf(d), fontNumbers, frc);
|
|
|
|
int stepsToLowestC = 0;
|
|
int addOctaves = 0;
|
|
int stepsToClef = 0;
|
|
|
|
if (clefChoice == 0){
|
|
stepsToLowestC = -11;
|
|
stepsToClef = 6;
|
|
}
|
|
else if (clefChoice == 1){
|
|
stepsToLowestC = -15;
|
|
stepsToClef = 6;
|
|
}
|
|
else if (clefChoice == 2){
|
|
stepsToLowestC = -17;
|
|
stepsToClef = 4;
|
|
}
|
|
else if (clefChoice == 3){
|
|
stepsToLowestC = -23;
|
|
stepsToClef = 2;
|
|
}
|
|
|
|
if (octavaAndBassoChoice == 0){
|
|
stepsToLowestC = stepsToLowestC+14;
|
|
}
|
|
else if (octavaAndBassoChoice == 1){
|
|
stepsToLowestC = stepsToLowestC+7;
|
|
}
|
|
else if (octavaAndBassoChoice == 2){
|
|
}
|
|
else if (octavaAndBassoChoice == 3){
|
|
stepsToLowestC = stepsToLowestC-7;
|
|
}
|
|
else if (octavaAndBassoChoice == 4){
|
|
stepsToLowestC = stepsToLowestC-14;
|
|
}
|
|
|
|
addOctaves = (int) (Math.round(pitch/100.)/12)*7;
|
|
float staffX = (float) (x*Rise.IMAGE_WIDTH - 1.5*staffWidth /*- ((1./(Rise.VOICES-1))*(p-v)/p)*Rise.IMAGE_WIDTH*Rise.X_DIV*noteHeadChoice*/);
|
|
float staffY = (float) (y*Rise.IMAGE_HEIGHT+(stepsToLowestC+notePosition+addOctaves)*staffSpace);
|
|
staff.draw(g2, staffX, staffY);
|
|
float clefX = (float) (x*Rise.IMAGE_WIDTH - 1.5*staffWidth /*- ((1./(Rise.VOICES-1))*(p-v)/p)*Rise.IMAGE_WIDTH*Rise.X_DIV*noteHeadChoice*/);
|
|
float clefY = (float) (y*Rise.IMAGE_HEIGHT+((stepsToLowestC-stepsToClef)+notePosition+addOctaves)*staffSpace);
|
|
TextLayout clef = new TextLayout(clefs[clefChoice], fontMusic, frc);
|
|
clef.draw(g2, clefX, clefY);
|
|
TextLayout octavaAndBasso = new TextLayout(octavasAndBassos[octavaAndBassoChoice], fontOBSigns, frc);
|
|
if (octavaAndBassoChoice < 2){
|
|
octavaAndBasso.draw(g2,(float) (clefX+clef.getVisibleAdvance()/2.-octavaAndBasso.getAdvance()/2),(float) (clefY+clef.getBounds().getMaxY()-octavaAndBasso.getBounds().getMinY()));
|
|
}
|
|
else if (octavaAndBassoChoice < 3){
|
|
}
|
|
else if(octavaAndBassoChoice < 5){
|
|
if (clefChoice == 3 && octavaAndBassoChoice == 3) {
|
|
octavaAndBasso.draw(g2,(float) (clefX+clef.getVisibleAdvance()/2.-octavaAndBasso.getAdvance()/16.),(float) (clefY+clef.getBounds().getMinY()));
|
|
}
|
|
else if (clefChoice == 3 && octavaAndBassoChoice == 4) {
|
|
octavaAndBasso.draw(g2,(float) (clefX+clef.getVisibleAdvance()/2.-octavaAndBasso.getAdvance()/4.),(float) (clefY+clef.getBounds().getMinY()));
|
|
}
|
|
else {
|
|
octavaAndBasso.draw(g2,(float) (clefX+clef.getVisibleAdvance()/2.-octavaAndBasso.getAdvance()/2),(float) (clefY+clef.getBounds().getMinY()));
|
|
}
|
|
}
|
|
|
|
if (noteY-staffY >= staffSpace*2){
|
|
float ledgerLineX = (float) (x*Rise.IMAGE_WIDTH - ledgerWidth/2.);
|
|
float ledgerLineY = (float) (staffY+staffSpace*2);
|
|
while (ledgerLineY <= noteY){
|
|
ledgerLine.draw(g2, ledgerLineX, ledgerLineY);
|
|
ledgerLineY = (float) (ledgerLineY+staffSpace*2);
|
|
}
|
|
}
|
|
if (staffY-noteY >= staffSpace*10){
|
|
float ledgerLineX = (float) (x*Rise.IMAGE_WIDTH - ledgerWidth/2.);
|
|
float ledgerLineY = (float) (staffY-staffSpace*10);
|
|
while (ledgerLineY >= noteY){
|
|
ledgerLine.draw(g2, ledgerLineX, ledgerLineY);
|
|
ledgerLineY = (float) (ledgerLineY-staffSpace*2);
|
|
}
|
|
}
|
|
|
|
if (noteY >= staffY-staffSpace*6){
|
|
centDeviationText.draw(g2, (float) (noteX-centDeviationText.getAdvance()/4.), (float) (staffY-staffSpace*9));
|
|
}
|
|
else {
|
|
centDeviationText.draw(g2, (float) (noteX-centDeviationText.getAdvance()/4.), (float) (noteY-staffSpace*3));
|
|
}
|
|
|
|
if (ratioChoice == 0) {
|
|
if (noteY <= staffY-staffSpace*2){
|
|
ratioText.draw(g2, (float) (noteX-ratioText.getAdvance()/4.), (float) (staffY+staffSpace*1+ratioText.getAscent()));
|
|
}
|
|
else {
|
|
ratioText.draw(g2, (float) (noteX-ratioText.getAdvance()/4.), (float) (noteY+staffSpace*3+ratioText.getAscent()));
|
|
}
|
|
}
|
|
}
|
|
|
|
public int getNotePosition(int mN) {
|
|
int notePosition = 0;
|
|
if (spellingChoice == 0) {
|
|
int modNote = mN;
|
|
switch(modNote) {
|
|
case 0 : notePosition = 0; break;
|
|
case 1 : notePosition = 0; break;
|
|
case 2 : notePosition = 1; break;
|
|
case 3 : notePosition = 1; break;
|
|
case 4 : notePosition = 2; break;
|
|
case 5 : notePosition = 3; break;
|
|
case 6 : notePosition = 3; break;
|
|
case 7 : notePosition = 4; break;
|
|
case 8 : notePosition = 4; break;
|
|
case 9 : notePosition = 5; break;
|
|
case 10 : notePosition = 5; break;
|
|
case 11: notePosition = 6; break;
|
|
case 12: notePosition = 7; break;
|
|
}
|
|
}
|
|
else if (spellingChoice == 1){
|
|
int modNote = mN;
|
|
switch(modNote) {
|
|
case 0 : notePosition = 0; break;
|
|
case 1 : notePosition = 1; break;
|
|
case 2 : notePosition = 1; break;
|
|
case 3 : notePosition = 2; break;
|
|
case 4 : notePosition = 2; break;
|
|
case 5 : notePosition = 3; break;
|
|
case 6 : notePosition = 4; break;
|
|
case 7 : notePosition = 4; break;
|
|
case 8 : notePosition = 5; break;
|
|
case 9 : notePosition = 5; break;
|
|
case 10 : notePosition = 6; break;
|
|
case 11: notePosition = 6; break;
|
|
case 12: notePosition = 7; break;
|
|
}
|
|
}
|
|
return notePosition;
|
|
}
|
|
|
|
public int getAcc(int mN) {
|
|
int accidental = 1;
|
|
if (spellingChoice == 0){
|
|
int modNote = mN;
|
|
switch(modNote) {
|
|
case 0 : accidental = 1; break;
|
|
case 1 : accidental = 2; break;
|
|
case 2 : accidental = 1; break;
|
|
case 3 : accidental = 2; break;
|
|
case 4 : accidental = 1; break;
|
|
case 5 : accidental = 1; break;
|
|
case 6 : accidental = 2; break;
|
|
case 7 : accidental = 1; break;
|
|
case 8 : accidental = 2; break;
|
|
case 9 : accidental = 1; break;
|
|
case 10 : accidental = 2; break;
|
|
case 11: accidental = 1; break;
|
|
case 12: accidental = 1; break;
|
|
}
|
|
}
|
|
if (spellingChoice == 1){
|
|
int modNote = mN;
|
|
switch(modNote) {
|
|
case 0 : accidental = 1; break;
|
|
case 1 : accidental = 0; break;
|
|
case 2 : accidental = 1; break;
|
|
case 3 : accidental = 0; break;
|
|
case 4 : accidental = 1; break;
|
|
case 5 : accidental = 1; break;
|
|
case 6 : accidental = 0; break;
|
|
case 7 : accidental = 1; break;
|
|
case 8 : accidental = 0; break;
|
|
case 9 : accidental = 1; break;
|
|
case 10 : accidental = 0; break;
|
|
case 11: accidental = 1; break;
|
|
case 12: accidental = 1; break;
|
|
}
|
|
}
|
|
return accidental;
|
|
}
|
|
|
|
public void initializeChoices(){
|
|
|
|
spellingChoice = 1;
|
|
ratioChoice = 0;
|
|
|
|
int stepsToLowestC = 0;
|
|
int addOctaves = 0;
|
|
double staffSpace = Rise.FONT/8.;
|
|
float noteY = (float) y*Rise.IMAGE_HEIGHT;
|
|
int notePosition = getNotePosition((int) (Math.round(pitch/100.)%12));
|
|
|
|
float min = 500000;
|
|
for (int c = 0; c < 4; c++){
|
|
int oBStart = 0;
|
|
int oBMax = 0;
|
|
if (c == 0) {
|
|
oBStart = 0;
|
|
oBMax = 3;
|
|
}
|
|
else if (c < 3) {
|
|
oBStart = 2;
|
|
oBMax = 3;
|
|
}
|
|
else if (c < 4) {
|
|
oBStart = 2;
|
|
oBMax = 5;
|
|
}
|
|
|
|
for (int oB = oBStart; oB < oBMax; oB++){
|
|
|
|
if (c == 0){
|
|
stepsToLowestC = -11;
|
|
}
|
|
else if (c == 1){
|
|
stepsToLowestC = -15;
|
|
}
|
|
else if (c == 2){
|
|
stepsToLowestC = -17;
|
|
}
|
|
else if (c == 3){
|
|
stepsToLowestC = -23;
|
|
}
|
|
|
|
if (oB == 0){
|
|
stepsToLowestC = stepsToLowestC+14;
|
|
}
|
|
else if (oB == 1){
|
|
stepsToLowestC = stepsToLowestC+7;
|
|
}
|
|
else if (oB == 2){
|
|
}
|
|
else if (oB == 3){
|
|
stepsToLowestC = stepsToLowestC-7;
|
|
}
|
|
else if (oB == 4){
|
|
stepsToLowestC = stepsToLowestC-14;
|
|
}
|
|
|
|
addOctaves = (int) (Math.round(pitch/100.)/12)*7;
|
|
float staffY = (float) (y*Rise.IMAGE_HEIGHT+(stepsToLowestC+notePosition+addOctaves)*staffSpace);
|
|
if (Math.abs((staffY-4*staffSpace)-noteY) < min){
|
|
clefChoice = c;
|
|
octavaAndBassoChoice = oB;
|
|
min = (float) Math.abs((staffY-4*staffSpace)-noteY);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public int testSelect(float x1, float y1, float x2, float y2){
|
|
if ((float) (Rise.PAGE_MARGIN*Rise.ZOOM+x*Rise.IMAGE_WIDTH*Rise.ZOOM) > x1
|
|
&& (float) (Rise.PAGE_MARGIN*Rise.ZOOM+x*Rise.IMAGE_WIDTH*Rise.ZOOM) < x2
|
|
&& (float) (Rise.PAGE_MARGIN*Rise.ZOOM+y*Rise.IMAGE_HEIGHT*Rise.ZOOM) > y1
|
|
&& (float) (Rise.PAGE_MARGIN*Rise.ZOOM+y*Rise.IMAGE_HEIGHT*Rise.ZOOM) < y2){
|
|
color = Color.BLUE;
|
|
isListening = true;
|
|
return 1;
|
|
}
|
|
else {
|
|
color = Color.BLACK;
|
|
isListening = false;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
public int testSelectClickAndPlay(float xMouse, float yMouse){
|
|
if ((Rise.PAGE_MARGIN*Rise.ZOOM + clickAndPlayX1*Rise.ZOOM) < xMouse
|
|
&& (Rise.PAGE_MARGIN*Rise.ZOOM + clickAndPlayX2*Rise.ZOOM) > xMouse
|
|
&& (float) (Rise.PAGE_MARGIN*Rise.ZOOM+(y)*Rise.IMAGE_HEIGHT*Rise.ZOOM + 10*Rise.ZOOM) > yMouse
|
|
&& (float) (Rise.PAGE_MARGIN*Rise.ZOOM+(y)*Rise.IMAGE_HEIGHT*Rise.ZOOM - 10*Rise.ZOOM) < yMouse){
|
|
color = Color.BLUE;
|
|
isListening = true;
|
|
//double toReturn = (xMouse - Rise.PAGE_MARGIN*Rise.ZOOM)/(Rise.IMAGE_WIDTH*Rise.ZOOM);
|
|
//System.out.println((xMouse) + " " + (clickAndPlayX1*Rise.ZOOM) + " " + (clickAndPlayX2*Rise.ZOOM) + " " + yMouse + " " + (Rise.PAGE_MARGIN*Rise.ZOOM+y*Rise.IMAGE_HEIGHT*Rise.ZOOM));
|
|
//System.out.println(toReturn);
|
|
return 1;
|
|
}
|
|
else {
|
|
color = Color.BLACK;
|
|
isListening = false;
|
|
return 0;
|
|
}
|
|
}
|
|
}
|