/* * Copyright (C) 2015 たんらる */ package fourthline.mabiicco.fx; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.paint.Color; import javafx.scene.text.Font; public final class KeyboardView { private int playNote = -1; private final int width = 60; private final PianoRollView pianoRollView; private Canvas canvas; /** * Create the panel. */ public KeyboardView(Canvas canvas, final PianoRollView pianoRollView) { this.canvas = canvas; this.pianoRollView = pianoRollView; canvas.setWidth( width ); paint(); } private void updateHeight() { canvas.setHeight( 12*PianoRollView.OCTNUM*pianoRollView.getNoteHeight()+1 ); } public void paint() { updateHeight(); GraphicsContext gc = canvas.getGraphicsContext2D(); paintComponent(gc); } /** * 1オクターブ 12 x 6 * 9オクターブ分つくると、648 */ public void paintComponent(GraphicsContext gc) { int height = pianoRollView.getTotalHeight()-1; gc.setFill(Color.WHITE); gc.fillRect(0, 0, width, height); for (int i = 0; i < PianoRollView.OCTNUM; i++) { paintOctPianoLine(gc, i, (char)('0'+PianoRollView.OCTNUM-i-1)); } gc.setFill(Color.BLUE); gc.fillRect(width-1, 0, 1, height); paintPlayNote(gc); } private boolean isWhiteKey(int note) { switch (note%12) { case 0: case 2: case 4: case 5: case 7: case 9: case 11: return true; default: return false; } } private void paintPlayNote(GraphicsContext gc) { int yAdd[] = { -2, -2, -1, -2, 1, -3, -2, -2, -1, 0, 0, 2 }; // 補正値 if (playNote < 0) { return; } int x = 15; if ( isWhiteKey(playNote) ) { x += 20; } int y = pianoRollView.getTotalHeight() - ((playNote +1) * pianoRollView.getNoteHeight()) + yAdd[playNote%12]; gc.setFill(Color.RED); gc.fillOval(x, y, 4, 4); } private void drawRect(GraphicsContext gc, int x, int y, int width, int height) { gc.fillRect(x, y, 1, height); gc.fillRect(x, y, width, 1); gc.fillRect(x+width, y, 1, height); gc.fillRect(x, y+height, width, 1); } private void paintOctPianoLine(GraphicsContext gc, int pos, char posText) { int octHeight = pianoRollView.getNoteHeight() * 12; // ド~シのしろ鍵盤 gc.setFill(Color.color(0.3f, 0.3f, 0.3f)); int startY = octHeight * pos; for (int i = 0; i < 7; i++) { double y1 = octHeight * i / 7; double y2 = octHeight * (i+1) / 7; drawRect(gc, 0, (int)(startY+y1), 40, (int)(y2-y1)); } // 黒鍵盤 int black_posIndex[] = { 1, // A# 2, // G# 3, // F# 5, // D# 6 // C# }; for (int i = 0; i < black_posIndex.length; i++) { int y = octHeight * black_posIndex[i] / 7 - pianoRollView.getNoteHeight() / 2-1; y += startY; gc.setFill(Color.color(0.0f, 0.0f, 0.0f)); gc.fillRect(0, y, 20, pianoRollView.getNoteHeight()); gc.setFill(Color.color(0.3f, 0.3f, 0.3f)); drawRect(gc, 0, y, 20, pianoRollView.getNoteHeight()); } // グリッド gc.setFill(Color.color(0.3f, 0.3f, 0.6f)); gc.fillRect(40, startY, width, 1); // オクターブ String o_str = "o" + posText; gc.setFont(Font.font(12)); int y = startY + octHeight; gc.fillText(o_str, 42, y); gc.fillRect(40, y, width, 1); } }