Mercurial > hg > screen-ui
comparison src/melodyTriangle.cpp @ 38:330f2746fedd tip
Added keys help in a smaller font; changed loadness keyboard controls.
author | samer |
---|---|
date | Mon, 27 Feb 2012 20:09:10 +0000 |
parents | 260cc4f4d70a |
children |
comparison
equal
deleted
inserted
replaced
37:260cc4f4d70a | 38:330f2746fedd |
---|---|
1 #include "melodyTriangle.h" | 1 #include "melodyTriangle.h" |
2 #include <GLUT/GLUT.h> | 2 #include <GLUT/GLUT.h> |
3 | 3 |
4 #define BUFFER_ZONE 64 // have to drag this far to snap out of triange. | 4 #define BUFFER_ZONE 64 // have to drag this far to snap out of triange. |
5 #define NUM_TEMPI 9 | 5 #define NUM_TEMPI 9 |
6 #define NUMEL(a) sizeof(a)/sizeof(a[0]) | |
6 | 7 |
7 static int tempi[]={20,30,45,60,90,120,150,180,240}; | 8 static int tempi[]={20,30,45,60,90,120,150,180,240}; |
8 | 9 |
9 static ofxOscBundle& operator<<(ofxOscBundle &bundle, ofxOscMessage msg) { | 10 static ofxOscBundle& operator<<(ofxOscBundle &bundle, ofxOscMessage msg) { |
10 bundle.addMessage(msg); return bundle; | 11 bundle.addMessage(msg); return bundle; |
23 | 24 |
24 melodyTriangle::melodyTriangle(const char *host, int port, int numVoices, | 25 melodyTriangle::melodyTriangle(const char *host, int port, int numVoices, |
25 bool enableKeys,int voiceIdOffset,int receivePort): | 26 bool enableKeys,int voiceIdOffset,int receivePort): |
26 numVoices(numVoices), receivePort(receivePort), snapTruePos(enableKeys), | 27 numVoices(numVoices), receivePort(receivePort), snapTruePos(enableKeys), |
27 enableKeys(enableKeys), randInit(false),allowExit(true), ratio(2), tempoIndex(4), | 28 enableKeys(enableKeys), randInit(false),allowExit(true), ratio(2), tempoIndex(4), |
28 display_msg(""), display_frames(0) | 29 display_msg(""), display_frames(0), display_font(NULL) |
29 { | 30 { |
30 for (int i=0;i<numVoices;i++) voices[i]=new Voice(i+1+voiceIdOffset); | 31 for (int i=0;i<numVoices;i++) voices[i]=new Voice(i+1+voiceIdOffset); |
31 | 32 |
32 sender.setup( host,port ); | 33 sender.setup( host,port ); |
33 receiver.setup( receivePort ); | 34 receiver.setup( receivePort ); |
34 display_font.loadFont("/System/Library/Fonts/LucidaGrande.ttc",24); | 35 main_font.loadFont("/System/Library/Fonts/LucidaGrande.ttc",24); |
36 help_font.loadFont("/System/Library/Fonts/Menlo.ttc",16); | |
37 //help_font.loadFont("/System/Library/Fonts/Courier.dfont",16); | |
35 } | 38 } |
36 | 39 |
37 melodyTriangle::~melodyTriangle() { | 40 melodyTriangle::~melodyTriangle() { |
38 printf("Deleting voice objects...\n"); | 41 printf("Deleting voice objects...\n"); |
39 for (int i=0;i<numVoices;i++) delete voices[i]; | 42 for (int i=0;i<numVoices;i++) delete voices[i]; |
147 voices[i]->draw(enableKeys && voices[i]->isInVoice(mouseX,mouseY)); | 150 voices[i]->draw(enableKeys && voices[i]->isInVoice(mouseX,mouseY)); |
148 } | 151 } |
149 | 152 |
150 // display message if any | 153 // display message if any |
151 if (display_frames!=0) { | 154 if (display_frames!=0) { |
152 ofRectangle bbox=display_font.getStringBoundingBox(display_msg,0,0); | 155 ofRectangle bbox=display_font->getStringBoundingBox(display_msg,0,0); |
153 ofSetColor(220,220,220); | 156 ofSetColor(220,220,220); |
154 display_font.drawString(display_msg, | 157 display_font->drawString(display_msg, |
155 (ofGetWidth()-bbox.width)/2, (ofGetHeight()-bbox.height)/2); | 158 (ofGetWidth()-bbox.width)/2, (ofGetHeight()-bbox.height)/2); |
156 if (display_frames>0) display_frames--; | 159 if (display_frames>0) display_frames--; |
157 } | 160 } |
158 if (ratio!=2) { | 161 if (ratio!=2) { |
159 ofSetColor(160,160,160); | 162 ofSetColor(160,160,160); |
160 display_font.drawString(ofToString(ratio),16,ofGetHeight()-16); | 163 display_font->drawString(ofToString(ratio),16,ofGetHeight()-16); |
161 } | 164 } |
162 } | 165 } |
163 | 166 |
164 bool melodyTriangle::clipToTriangle(int *x, int *y) { | 167 bool melodyTriangle::clipToTriangle(int *x, int *y) { |
165 bool clipped; | 168 bool clipped; |
203 void melodyTriangle::keyReleased(int key){ | 206 void melodyTriangle::keyReleased(int key){ |
204 if (enableKeys && key>='2' && key<='9') { | 207 if (enableKeys && key>='2' && key<='9') { |
205 ratio=2; | 208 ratio=2; |
206 } | 209 } |
207 } | 210 } |
211 | |
212 struct command { | |
213 const char *key; | |
214 const char *desc; | |
215 }; | |
216 | |
217 struct command voice_commands[] = { | |
218 // { "←", "fractional delay" }, | |
219 // { "→", "fractional advance" }, | |
220 // { "↑", "multiply note rate" }, | |
221 // { "↓", "divide note rate" }, | |
222 { "[right]", "fractional delay" }, | |
223 { "[left]", "fractional advance" }, | |
224 { "[up]", "multiply note rate" }, | |
225 { "[down]", "divide note rate" }, | |
226 { "[", "transpose octave down" }, | |
227 { "]", "transpose octave up" }, | |
228 { "{", "quieter" }, | |
229 { "}", "louder" }, | |
230 { "c", "change to nearby pattern" }, | |
231 { "s", "shuffle notes" }, | |
232 { "h", "this help screen" }, | |
233 { "H", "global keys help screen" }, | |
234 }; | |
235 | |
236 struct command global_commands[] = { | |
237 { "<", "reduce tempo" }, | |
238 { ">", "increase tempo" }, | |
239 { "I", "toggle randomise on birth" }, | |
240 { "S", "save current pattern" }, | |
241 { "C", "calibrate triangle" }, | |
242 { "F", "toggle full screen" }, | |
243 { "R", "reset token positions" }, | |
244 { "Q", "quit" }, | |
245 { "H", "this help screen" }, | |
246 { "h", "token keys help screen" } | |
247 }; | |
248 | |
208 void melodyTriangle::keyPressed(int key){ | 249 void melodyTriangle::keyPressed(int key){ |
209 if (enableKeys){ | 250 if (enableKeys){ |
210 if (key>='2' && key<='9') { | 251 if (key>='2' && key<='9') { |
211 ratio=key-'0'; | 252 ratio=key-'0'; |
212 } else { | 253 } else { |
213 printf("got key: %d.\n",key); | 254 printf("got key: %d.\n",key); |
214 switch (key) { | 255 switch (key) { |
215 | 256 |
216 case '{': | 257 case '<': |
217 if (tempoIndex>0) tempoIndex--; | 258 if (tempoIndex>0) tempoIndex--; |
218 sender << msg("/tempo",tempi[tempoIndex]); | 259 sender << msg("/tempo",tempi[tempoIndex]); |
219 break; | 260 break; |
220 case '}': | 261 case '>': |
221 if (tempoIndex<NUM_TEMPI-1) tempoIndex++; | 262 if (tempoIndex<NUM_TEMPI-1) tempoIndex++; |
222 sender << msg("/tempo",tempi[tempoIndex]); | 263 sender << msg("/tempo",tempi[tempoIndex]); |
223 break; | 264 break; |
224 | 265 |
225 case ' ': sender << msg("/marker"); break; | 266 case ' ': sender << msg("/marker"); break; |
226 case 'S': sender << msg("/save"); break; | 267 case 'S': sender << msg("/save"); break; |
227 case 'r': sender << msg("/report"); break; | 268 case 'r': sender << msg("/report"); break; |
228 case 'i': | 269 case 'I': |
229 randInit ^= true; | 270 randInit ^= true; |
230 display_msg = (randInit?"randomise on birth":"no randomise on birth"); | 271 display_msg = (randInit?"randomise on birth":"no randomise on birth"); |
272 display_font = &main_font; | |
231 display_frames = 40; | 273 display_frames = 40; |
232 break; | 274 break; |
233 case 'C': { | 275 case 'C': { |
234 ofxOscBundle bundle; | 276 ofxOscBundle bundle; |
235 sender << (bundle << msgReplyTo() << msgCalibrate()); | 277 sender << (bundle << msgReplyTo() << msgCalibrate()); |
236 break; | 278 break; |
237 } | 279 } |
238 case 'F': ofToggleFullscreen(); break; | 280 case 'F': ofToggleFullscreen(); break; |
239 case 'R': reset(); break; | 281 case 'R': reset(); break; |
240 case 'Q': ofAppGlutWindow::exitApp(); | 282 case 'Q': ofAppGlutWindow::exitApp(); |
283 case '/': display_frames=0; break; | |
284 case 'h': | |
285 case 'H': | |
286 case '?': | |
287 display_frames = -1; | |
288 display_msg = help_string(key!='h'); | |
289 display_font = &help_font; | |
290 break; | |
291 | |
241 case OF_KEY_ESC: setKeyboardEnable(false); break; | 292 case OF_KEY_ESC: setKeyboardEnable(false); break; |
242 | 293 |
243 default: // otherwise, send key to all voices under mouse | 294 default: // otherwise, send key to all voices under mouse |
244 for (int i=0; i<numVoices; i++) | 295 for (int i=0; i<numVoices; i++) |
245 if (voices[i]->isInVoice(mouseX,mouseY)) | 296 if (voices[i]->isInVoice(mouseX,mouseY)) |
264 case OF_KEY_RIGHT: sender << msgShift(v->id,1,ratio); break; | 315 case OF_KEY_RIGHT: sender << msgShift(v->id,1,ratio); break; |
265 case OF_KEY_UP: sender << msgPeriod(v->id,1,ratio); break; | 316 case OF_KEY_UP: sender << msgPeriod(v->id,1,ratio); break; |
266 case OF_KEY_DOWN: sender << msgPeriod(v->id,ratio,1); break; | 317 case OF_KEY_DOWN: sender << msgPeriod(v->id,ratio,1); break; |
267 case ']': sender << msgOctave(v->id, ++v->octave); break; | 318 case ']': sender << msgOctave(v->id, ++v->octave); break; |
268 case '[': sender << msgOctave(v->id, --v->octave); break; | 319 case '[': sender << msgOctave(v->id, --v->octave); break; |
269 case '*': sender << msgAmplitude(v->id, v->louder()); break; | 320 case '}': sender << msgAmplitude(v->id, v->louder()); break; |
270 case '/': sender << msgAmplitude(v->id, v->quieter()); break; | 321 case '{': sender << msgAmplitude(v->id, v->quieter()); break; |
271 case 'c': sender << msg("/change",v->id); v->status=Voice::pending; break; | 322 case 'c': sender << msg("/change",v->id); v->status=Voice::pending; break; |
323 case 's': sender << msg("/shuffle",v->id); break; | |
272 default: printf("unrecognised key: %d.\n",key); | 324 default: printf("unrecognised key: %d.\n",key); |
273 } | 325 } |
274 } | 326 } |
327 | |
328 inline int max(int x, int y) { return y>x ? y : x; } | |
329 | |
330 string melodyTriangle::help_string(bool global) { | |
331 stringstream buf; | |
332 struct command *cmds; | |
333 int n, maxw=0; | |
334 | |
335 buf << " ( " << (global ? "GLOBAL" : "TOKEN") << " KEYBOARD CONTROLS ) \n\n"; | |
336 if (global) { cmds=global_commands; n=NUMEL(global_commands); } | |
337 else { cmds=voice_commands; n=NUMEL(voice_commands); } | |
338 | |
339 for (int i=0; i<n; i++) maxw=max(maxw,strlen(cmds[i].key)); | |
340 for (int i=0; i<n; i++) buf << setw(maxw) << cmds[i].key << " - " << cmds[i].desc << "\n"; | |
341 | |
342 buf << "\nPress '/' to dismiss."; | |
343 return buf.str(); | |
344 } | |
345 | |
275 | 346 |
276 //- Mouse ------------------------------------------------------ | 347 //- Mouse ------------------------------------------------------ |
277 | 348 |
278 void melodyTriangle::mouseDragged(int x, int y, int button){} | 349 void melodyTriangle::mouseDragged(int x, int y, int button){} |
279 void melodyTriangle::mouseMoved(int x, int y ){} | 350 void melodyTriangle::mouseMoved(int x, int y ){} |
376 voiceGrabbed=NULL; | 447 voiceGrabbed=NULL; |
377 } | 448 } |
378 } else if (msg_path=="/display") { | 449 } else if (msg_path=="/display") { |
379 display_msg=m.getArgAsString(0); | 450 display_msg=m.getArgAsString(0); |
380 display_frames=m.getArgAsInt32(1); | 451 display_frames=m.getArgAsInt32(1); |
452 display_font=&main_font; | |
381 } else if (msg_path=="/font") { | 453 } else if (msg_path=="/font") { |
382 display_font.loadFont(m.getArgAsString(0),m.getArgAsInt32(1)); | 454 main_font.loadFont(m.getArgAsString(0),m.getArgAsInt32(1)); |
383 } else if (msg_path=="/keyboard") { setKeyboardEnable(m.getArgAsInt32(0)); } | 455 } else if (msg_path=="/keyboard") { setKeyboardEnable(m.getArgAsInt32(0)); } |
384 else if (msg_path=="/reset") { reset(); } | 456 else if (msg_path=="/reset") { reset(); } |
385 else if (msg_path=="/fullscreen") { ofSetFullscreen(m.getArgAsInt32(0)); } | 457 else if (msg_path=="/fullscreen") { ofSetFullscreen(m.getArgAsInt32(0)); } |
386 else if (msg_path=="/quit") { ofAppGlutWindow::exitApp(); } | 458 else if (msg_path=="/quit") { ofAppGlutWindow::exitApp(); } |
387 else if (msg_path=="/allowExit") { allowExit=m.getArgAsInt32(0); } | 459 else if (msg_path=="/allowExit") { allowExit=m.getArgAsInt32(0); } |
406 void melodyTriangle::setKeyboardEnable(bool en) { | 478 void melodyTriangle::setKeyboardEnable(bool en) { |
407 enableKeys=en; | 479 enableKeys=en; |
408 snapTruePos=en; | 480 snapTruePos=en; |
409 display_msg=en ? "Keyboard enabled" : "Keybard disabled"; | 481 display_msg=en ? "Keyboard enabled" : "Keybard disabled"; |
410 display_frames=40; | 482 display_frames=40; |
483 display_font=&main_font; | |
411 } | 484 } |
412 | 485 |
413 // OSC Message sending ----------------------------------------- | 486 // OSC Message sending ----------------------------------------- |
414 | 487 |
415 ofxOscMessage melodyTriangle::msgPosition(Voice *v){ | 488 ofxOscMessage melodyTriangle::msgPosition(Voice *v){ |