/[svn]/jsampler/trunk/src/org/jsampler/view/std/BasicPianoRollPainter.java
ViewVC logotype

Contents of /jsampler/trunk/src/org/jsampler/view/std/BasicPianoRollPainter.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1778 - (show annotations) (download)
Sun Sep 28 20:38:36 2008 UTC (15 years, 6 months ago) by iliev
File size: 8093 byte(s)
* Fantasia: Improved look and feel
* Fantasia: Added buttons for increasing/decreasing the key number
  of the MIDI keyboard (Ctrl+Up Arrow/Ctrl+Down Arrow)
* Fantasia: Added buttons for scrolling left/right on the MIDI keyboard
  (Ctrl+Left Arrow/Ctrl+Right Arrow)
* Added key bindings for triggering MIDI notes using the computer keyboard
  (from a to ' for the white keys and from 0 to 7 for changing the octaves)
* Notes are now triggered when dragging the mouse over the MIDI keyboard

1 /*
2 * JSampler - a java front-end for LinuxSampler
3 *
4 * Copyright (C) 2005-2008 Grigor Iliev <grigor@grigoriliev.com>
5 *
6 * This file is part of JSampler.
7 *
8 * JSampler is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation.
11 *
12 * JSampler is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with JSampler; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
21 */
22
23 package org.jsampler.view.std;
24
25 import java.awt.Font;
26 import java.awt.FontMetrics;
27 import java.awt.Color;
28 import java.awt.Font;
29 import java.awt.FontMetrics;
30 import java.awt.GradientPaint;
31 import java.awt.Graphics2D;
32 import java.awt.Point;
33 import java.awt.Rectangle;
34 import java.awt.RenderingHints;
35
36 import java.awt.geom.RoundRectangle2D;
37
38 /**
39 *
40 * @author Grigor Iliev
41 */
42 public class BasicPianoRollPainter implements PianoRollPainter {
43 private PianoRoll pianoRoll;
44
45 private Color borderColor = Color.BLACK;
46 private Color keyColor = Color.WHITE;
47 private Color disabledKeyColor = new Color(0xaaaaaa);
48 private Color pressedKeyColor = Color.GREEN;
49 private Color keySwitchColor = Color.PINK;
50 private Color blackKeyColor = Color.BLACK;
51
52 public
53 BasicPianoRollPainter(PianoRoll pianoRoll) {
54 if(pianoRoll == null) {
55 throw new IllegalArgumentException("piano roll must be non-null");
56 }
57 this.pianoRoll = pianoRoll;
58 }
59
60 @Override
61 public void
62 paint(PianoRoll pianoRoll, Graphics2D g) {
63 double whiteKeyWidth = getWhiteKeyWidth();
64 double whiteKeyHeight = getWhiteKeyHeight();
65 double arcw = whiteKeyWidth/4.0d;
66 double arch = whiteKeyHeight/14.0d;
67
68 g.setPaint(keyColor);
69
70 RoundRectangle2D.Double rect;
71
72 g.setRenderingHint (
73 RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF
74 );
75
76 int i = 0;
77 for(int j = pianoRoll.getFirstKey(); j <= pianoRoll.getLastKey(); j++) {
78 if(!PianoRoll.isWhiteKey(j)) continue;
79
80 Color c = getKeyColor(j);
81 if(g.getPaint() != c) g.setPaint(c);
82
83 rect = new RoundRectangle2D.Double (
84 // If you change this you should also change getKeyRectangle()
85 whiteKeyWidth * i + i, 0,
86 whiteKeyWidth, whiteKeyHeight,
87 arcw, arch
88 );
89
90 g.fill(rect);
91 i++;
92 }
93
94 g.setRenderingHint (
95 RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON
96 );
97
98 g.setStroke(new java.awt.BasicStroke(1.5f));
99 g.setPaint(borderColor);
100
101 i = 0;
102 for(int j = pianoRoll.getFirstKey(); j <= pianoRoll.getLastKey(); j++) {
103 if(!PianoRoll.isWhiteKey(j)) continue;
104
105 rect = new RoundRectangle2D.Double (
106 whiteKeyWidth * i + i, 0,
107 whiteKeyWidth, whiteKeyHeight,
108 arcw, arch
109 );
110
111 g.draw(rect);
112 i++;
113 }
114
115
116 g.setStroke(new java.awt.BasicStroke(2.5f));
117 double blackKeyWidth = getBlackKeyWidth();
118 double blackKeyHeight = getBlackKeyHeight();
119
120 i = 0;
121 for(int j = pianoRoll.getFirstKey(); j <= pianoRoll.getLastKey(); j++) {
122 if(pianoRoll.getOctaveLabelsVisible() && j % 12 == 0) {
123 int octave = j / 12 - 2;
124 paintOctaveLabel(g, octave, i);
125 }
126 if(!PianoRoll.isWhiteKey(j)) continue;
127
128 int k = (i + PianoRoll.getKeyOctaveIndex(pianoRoll.getFirstKey())) % 7;
129 if(k == 2 || k == 6) { i++; continue; }
130
131 Color c = (j == pianoRoll.getLastKey()) ? blackKeyColor : getKeyColor(j + 1);
132 if(g.getPaint() != c) g.setPaint(c);
133
134 // If you change this you should also change getKeyRectangle()
135 double x = blackKeyWidth * (2*(i + 1)) - blackKeyWidth * 0.5d + i;
136 rect = new RoundRectangle2D.Double (
137 // If you change this you should also change getKeyRectangle()
138 x, 0,
139 blackKeyWidth, blackKeyHeight,
140 arcw, arch
141 );
142 ///////
143
144 boolean pressed = (j == pianoRoll.getLastKey()) ? false : pianoRoll.getKey(j + 1).isPressed();
145 if(!pressed) g.fill(rect);
146
147 RoundRectangle2D.Double rect2;
148 rect2 = new RoundRectangle2D.Double (
149 x, 0,
150 blackKeyWidth, arch,
151 arcw, arch / 1.8d
152 );
153
154 g.fill(rect2);
155 g.setPaint(borderColor);
156 g.draw(rect);
157
158 if(pressed) {
159 GradientPaint gr = new GradientPaint (
160 (float)(x + blackKeyWidth/2), (float)(blackKeyHeight/4), Color.BLACK,
161 (float)(x + blackKeyWidth/2), (float)blackKeyHeight, new Color(0x058a02)
162 );
163 g.setPaint(gr);
164 g.fill(rect);
165 }
166 i++;
167 }
168 }
169
170 protected void
171 paintOctaveLabel(Graphics2D g, int octave, int whiteKeyIndex) {
172 double h = pianoRoll.getSize().getHeight();
173 double whiteKeyWidth = getWhiteKeyWidth();
174 g.setPaint(Color.BLACK);
175 int fsize = (int) (whiteKeyWidth / (1.5 + whiteKeyWidth / 50));
176 if(fsize < 8) fsize = 8;
177 g.setFont(g.getFont().deriveFont(Font.BOLD, fsize));
178
179 float x = (float) (whiteKeyWidth * whiteKeyIndex + whiteKeyIndex);
180 float y = (float) (h - 1);
181
182 String s = String.valueOf(octave);
183 FontMetrics fm = g.getFontMetrics();
184
185 // center text
186 int i = fm.stringWidth(s);
187 if(i < whiteKeyWidth) {
188 x += (whiteKeyWidth - i) / 2;
189 } else {
190 x += 2;
191 }
192
193 y -= (h / 12);
194
195 g.drawString(s, x, y);
196 }
197
198 private Color
199 getKeyColor(int key) {
200 PianoRoll.Key k = pianoRoll.getKey(key);
201 if(PianoRoll.isWhiteKey(key)) {
202 if(k.isPressed()) return pressedKeyColor;
203 if(k.isKeyswitch()) return keySwitchColor;
204 if(k.isDisabled()) return disabledKeyColor;
205 return keyColor;
206 } else {
207 if(k.isPressed()) return Color.GREEN;
208 return blackKeyColor;
209 }
210 }
211
212
213 private double
214 getWhiteKeyWidth() {
215 double w = pianoRoll.getSize().getWidth();
216 return (w - pianoRoll.getWhiteKeyCount()) / pianoRoll.getWhiteKeyCount();
217 }
218
219 private double
220 getWhiteKeyHeight() {
221 return pianoRoll.getSize().getHeight() - 3.0d;
222 }
223
224 private double
225 getBlackKeyWidth() {
226 return getWhiteKeyWidth() / 2.0d;
227 }
228
229 private double
230 getBlackKeyHeight() {
231 return getWhiteKeyHeight() / 1.5d;
232 }
233
234 /**
235 * Gets the index of the key containing the specified point.
236 * @return Number between 0 and 127 (inclusive) as specified in the MIDI standard.
237 */
238 @Override
239 public int
240 getKeyByPoint(Point p) {
241 double w = getWhiteKeyWidth() + /* space between keys */ 1.0d;
242 if(w == 0) return -1;
243 int whiteKeyNumber = (int) (p.getX() / w);
244 double leftBorder = whiteKeyNumber * w;
245 int key = pianoRoll.getWhiteKeyByNumber(whiteKeyNumber);
246 if(key == -1) return -1;
247
248 double bh = getBlackKeyHeight();
249 double blackKeyOffset = w / 4.0d;
250 if(p.getY() > bh) return key;
251 if(key != pianoRoll.getFirstKey() && !PianoRoll.isWhiteKey(key - 1)) {
252 if(p.getX() <= leftBorder + blackKeyOffset) return key - 1;
253 }
254 if(key != pianoRoll.getLastKey() && !PianoRoll.isWhiteKey(key + 1)) {
255 if(p.getX() >= leftBorder + 3 * blackKeyOffset - 3) return key + 1;
256 }
257
258 return key;
259 }
260
261 @Override
262 public Rectangle
263 getKeyRectangle(int key) {
264 Rectangle r = new Rectangle();
265 if(!pianoRoll.hasKey(key)) return r;
266
267 int whiteKeyIndex = PianoRoll.getWhiteKeyCount(pianoRoll.getFirstKey(), key) - 1;
268
269 if(PianoRoll.isWhiteKey(key)) {
270 double whiteKeyWidth = getWhiteKeyWidth();
271 double whiteKeyHeight = getWhiteKeyHeight();
272 double x = whiteKeyWidth * whiteKeyIndex + whiteKeyIndex;
273 r.setRect(x, 0, whiteKeyWidth, whiteKeyHeight);
274 } else {
275 double blackKeyWidth = getBlackKeyWidth();
276 double blackKeyHeight = getBlackKeyHeight();
277 int i = whiteKeyIndex;
278 double x = blackKeyWidth * (2*(i + 1)) - blackKeyWidth * 0.5d + i;
279 r.setRect(x, 0, blackKeyWidth, blackKeyHeight);
280 }
281
282 return r;
283 }
284
285 @Override
286 public int
287 getVelocity(Point p, int key) {
288 boolean whiteKey = PianoRoll.isWhiteKey(key);
289 double h = whiteKey ? getWhiteKeyHeight() : getBlackKeyHeight();
290 int velocity = (int) ((p.getY() / h) * 127.0d + 1);
291 if(velocity < 0) velocity = 0;
292 if(velocity > 127) velocity = 127;
293 return velocity;
294 }
295 }

  ViewVC Help
Powered by ViewVC