You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2224 lines
49 KiB
2224 lines
49 KiB
import java.awt.Robot;
|
|
import java.awt.event.InputEvent.*;
|
|
|
|
class Control {
|
|
int x;
|
|
int y;
|
|
int xsize;
|
|
int ysize;
|
|
int type;
|
|
int state;
|
|
int number;
|
|
int value;
|
|
int velocity;
|
|
int softwarevalue;
|
|
boolean persistence;
|
|
boolean sn;
|
|
int timeout;
|
|
int idlecolor;
|
|
int activecolor;
|
|
int controlID;
|
|
int page;
|
|
int channel = customChannel;
|
|
int takeover;
|
|
int updatedelay = 50;
|
|
boolean TLOCK = false;
|
|
boolean TAKEOVER = false;
|
|
long threadsSpawned = 0;
|
|
long threadsFinished = 0;
|
|
Control owner;
|
|
boolean isChained = false;
|
|
int numberOfChains = 0;
|
|
boolean chainSendFlags[] = new boolean[MAXCHAINS];
|
|
Control chains[] = new Control[MAXCHAINS];
|
|
|
|
void up(){}
|
|
void down(){}
|
|
void on(){}
|
|
void off(){}
|
|
void send(){}
|
|
void setValue(int ivalue){}
|
|
void takeoverSetValue(int ivalue){}
|
|
void nakedSetValue(int ivalue) {}
|
|
void update(){}
|
|
void cancelSchedule(){}
|
|
|
|
|
|
void chainTo(Control control, boolean send) {
|
|
chains[numberOfChains] = control;
|
|
//debug("Chaining "+this+" to "+control);
|
|
chainSendFlags[numberOfChains] = send;
|
|
numberOfChains++;
|
|
isChained = true;
|
|
}
|
|
|
|
void propagateToChainedControls() {
|
|
if(isChained) {
|
|
for (int i = 0; i < numberOfChains; i++) {
|
|
//println("Chained update to c on "+chains[i].page+". now on "+selectedPage);
|
|
chains[i].setValue(value);
|
|
if (chainSendFlags[i]) chains[i].send();
|
|
if (chains[i].page == selectedPage) chains[i].update();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
class GridSegment extends Control {
|
|
void on() {
|
|
debug(this+"x="+this.x+" y="+this.y+" on()");
|
|
ledOn(x, y, activecolor);
|
|
}
|
|
|
|
void off() {
|
|
debug(this+"x="+this.x+" y="+this.y+" off()");
|
|
ledOn(x, y, idlecolor);
|
|
}
|
|
}
|
|
|
|
class PageButton extends GridSegment {
|
|
int number;
|
|
|
|
PageButton(int inumber) {
|
|
page = selectedPage;
|
|
//println(this+" on page "+page);
|
|
number = inumber;
|
|
idlecolor = PAGEBUTTONIDLECOLOR;
|
|
activecolor = PAGEBUTTONACTIVECOLOR;
|
|
grid[number] = this;
|
|
ledOn((number % 8), (int)((float)number / 8), idlecolor);
|
|
}
|
|
|
|
void down() {
|
|
ledOn((number % 8), (int)((float)number / 8), activecolor);
|
|
loadLayout(number+1);
|
|
}
|
|
|
|
void update() {
|
|
x = 8;
|
|
y = 7;
|
|
off();
|
|
}
|
|
}
|
|
|
|
class LED extends GridSegment {
|
|
LED(int ix, int iy) {
|
|
controlID = (int)random(1000);
|
|
page = selectedPage;
|
|
//println(this+" on page "+page);
|
|
x = ix;
|
|
y = iy;
|
|
value = 0;
|
|
state = OFF;
|
|
timeout = 0;
|
|
grid[y*8+x] = this;
|
|
idlecolor = INDICATOROFFCOLOR;
|
|
activecolor = INDICATORONCOLOR;
|
|
ledOn(x, y, idlecolor);
|
|
}
|
|
|
|
void send() {
|
|
controlOut(x, y, state);
|
|
}
|
|
|
|
void down() {
|
|
|
|
}
|
|
|
|
void up() {
|
|
|
|
}
|
|
|
|
void update() {
|
|
if (value == 0) {
|
|
off();
|
|
}
|
|
if (value > 0) {
|
|
on();
|
|
}
|
|
}
|
|
|
|
void nakedSetValue(int ivalue) { setValue(ivalue); }
|
|
void setValue(int ivalue) {
|
|
if (ivalue > 0) { value = ivalue; state = ON; } else { value = OFF; state = OFF; }
|
|
propagateToChainedControls();
|
|
}
|
|
}
|
|
|
|
class Button extends GridSegment {
|
|
Button(int ix, int iy, int itype) {
|
|
controlID = (int)random(1000);
|
|
page = selectedPage;
|
|
persistence = false;
|
|
sn = true;
|
|
//println(this+" on page "+page);
|
|
x = ix;
|
|
y = iy;
|
|
type = itype;
|
|
value = 0;
|
|
velocity = -1;
|
|
state = OFF;
|
|
timeout = 0;
|
|
if (x < 8) {
|
|
grid[y*8+x] = this;
|
|
}
|
|
if (x == 8 && y < 7) {
|
|
//debug("Mapping side button:"+this);
|
|
grid[65+y] = this;
|
|
}
|
|
if (type == HOLD) {
|
|
idlecolor = BUTTONIDLECOLOR;
|
|
activecolor = HOLDONCOLOR;
|
|
}
|
|
if (type == TOGGLE) {
|
|
idlecolor = TOGGLEOFFCOLOR;
|
|
activecolor = TOGGLEONCOLOR;
|
|
}
|
|
ledOn(x, y, idlecolor);
|
|
}
|
|
|
|
void setVelocity(int vel) {
|
|
velocity = vel;
|
|
}
|
|
|
|
void send() {
|
|
debug("Velocity is "+velocity);
|
|
if (channel != 0) outputChannel = channel-1;
|
|
if (velocity == -1) controlOut(x, y, state);
|
|
if (velocity != -1 && state == ON) controlOut(x, y, velocity);
|
|
if (velocity != -1 && state == OFF) controlOut(x, y, state);
|
|
}
|
|
|
|
void down() {
|
|
sn = false;
|
|
if (type == HOLD) {
|
|
state = ON;
|
|
setValue(ON);
|
|
send();
|
|
if (!persistence) on();
|
|
}
|
|
if (type == TOGGLE) {
|
|
if (state == OFF) {
|
|
state = ON;
|
|
send();
|
|
if (!persistence) on();
|
|
setValue(ON);
|
|
} else if (state == ON) {
|
|
state = OFF;
|
|
send();
|
|
if (!persistence) off();
|
|
setValue(OFF);
|
|
}
|
|
}
|
|
}
|
|
|
|
void up() {
|
|
sn = false;
|
|
if (type == HOLD) {
|
|
//state = OFF;
|
|
setValue(OFF);
|
|
send();
|
|
if (!persistence) off();
|
|
}
|
|
}
|
|
|
|
void update() {
|
|
debug("sn "+sn);
|
|
if (value == 0) {
|
|
off();
|
|
}
|
|
if (value == 127 || softwarevalue == 127) {
|
|
on();
|
|
}
|
|
}
|
|
|
|
void nakedSetValue(int ivalue) { setValue(ivalue); }
|
|
void setValue(int ivalue) {
|
|
softwarevalue = ivalue;
|
|
if (ivalue > 0) { value = 127; state = ON; } else { value = 0; state = OFF; }
|
|
propagateToChainedControls();
|
|
sn = true;
|
|
}
|
|
}
|
|
|
|
class Note extends GridSegment {
|
|
int note;
|
|
int vel;
|
|
boolean sendoff = false;
|
|
boolean toggle = false;
|
|
|
|
Note(int ix, int iy, int octave, String note, int vel) {
|
|
controlID = (int)random(1000);
|
|
page = selectedPage;
|
|
//println(this+" on page "+page);
|
|
x = ix;
|
|
y = iy;
|
|
value = 0;
|
|
state = OFF;
|
|
timeout = 0;
|
|
idlecolor = NOTEIDLECOLOR;
|
|
activecolor = NOTEACTIVECOLOR;
|
|
this.note = addOctave(parseNote(note), octave);
|
|
this.vel = vel;
|
|
|
|
if (x < 8) {
|
|
grid[y*8+x] = this;
|
|
}
|
|
if (x == 8 && y < 7) {
|
|
//debug("Mapping side button:"+this);
|
|
grid[65+y] = this;
|
|
}
|
|
|
|
ledOn(x, y, idlecolor);
|
|
}
|
|
|
|
Note(int ix, int iy, int midi, int vel) {
|
|
controlID = (int)random(1000);
|
|
page = selectedPage;
|
|
//println(this+" on page "+page);
|
|
x = ix;
|
|
y = iy;
|
|
value = 0;
|
|
state = OFF;
|
|
timeout = 0;
|
|
idlecolor = NOTEIDLECOLOR;
|
|
activecolor = NOTEACTIVECOLOR;
|
|
this.note = midi;
|
|
this.vel = vel;
|
|
|
|
if (x < 8) {
|
|
grid[y*8+x] = this;
|
|
}
|
|
if (x == 8 && y < 7) {
|
|
//debug("Mapping side button:"+this);
|
|
grid[65+y] = this;
|
|
}
|
|
|
|
ledOn(x, y, idlecolor);
|
|
}
|
|
|
|
int parseNote(String note) {
|
|
note = note.toLowerCase();
|
|
if (note.equals("c")) return 0;
|
|
if (note.equals("c#")) return 1;
|
|
if (note.equals("d")) return 2;
|
|
if (note.equals("d#")) return 3;
|
|
if (note.equals("e")) return 4;
|
|
if (note.equals("f")) return 5;
|
|
if (note.equals("f#")) return 6;
|
|
if (note.equals("g")) return 7;
|
|
if (note.equals("g#")) return 8;
|
|
if (note.equals("a")) return 9;
|
|
if (note.equals("a#")) return 10;
|
|
if (note.equals("b")) return 11;
|
|
return 0;
|
|
}
|
|
|
|
int addOctave(int note, int octave) {
|
|
octave = octave+1;
|
|
return note+(octave*12);
|
|
}
|
|
|
|
void send() {
|
|
if (channel != 0) outputChannel = channel-1;
|
|
if (sendoff) {
|
|
noteOut(note, 0);
|
|
sendoff = false;
|
|
} else {
|
|
//debug("sendOn");
|
|
noteOut(note, vel);
|
|
}
|
|
}
|
|
|
|
void sendOff() {
|
|
if (channel != 0) outputChannel = channel-1;
|
|
//debug("sendOff");
|
|
noteOut(note, 0);
|
|
}
|
|
|
|
void down() {
|
|
if (!toggle) {
|
|
send();
|
|
on();
|
|
} else {
|
|
if (state == OFF) {
|
|
send();
|
|
on();
|
|
state = ON;
|
|
} else if (state == ON) {
|
|
sendOff();
|
|
off();
|
|
state = OFF;
|
|
}
|
|
}
|
|
}
|
|
|
|
void up() {
|
|
if (!toggle) {
|
|
sendOff();
|
|
off();
|
|
}
|
|
}
|
|
|
|
void update() {
|
|
if (value == 0) {
|
|
off();
|
|
}
|
|
if (value == 127) {
|
|
on();
|
|
}
|
|
}
|
|
|
|
void nakedSetValue(int ivalue) { setValue(ivalue); }
|
|
void setValue(int ivalue) {
|
|
value = ivalue;
|
|
if (ivalue == 0) {
|
|
sendoff = true;
|
|
}
|
|
propagateToChainedControls();
|
|
}
|
|
}
|
|
|
|
class CC extends GridSegment {
|
|
int note;
|
|
int vel;
|
|
boolean toggle;
|
|
boolean sendoff = false;
|
|
|
|
CC(int ix, int iy, int cc, int vel) {
|
|
controlID = (int)random(1000);
|
|
page = selectedPage;
|
|
//println(this+" on page "+page);
|
|
x = ix;
|
|
y = iy;
|
|
value = 0;
|
|
state = OFF;
|
|
timeout = 0;
|
|
idlecolor = CCIDLECOLOR;
|
|
activecolor = CCACTIVECOLOR;
|
|
this.note = cc;
|
|
this.vel = vel;
|
|
toggle = false;
|
|
|
|
if (x < 8) {
|
|
grid[y*8+x] = this;
|
|
}
|
|
if (x == 8 && y < 7) {
|
|
//debug("Mapping side button:"+this);
|
|
grid[65+y] = this;
|
|
}
|
|
|
|
ledOn(x, y, idlecolor);
|
|
}
|
|
|
|
void send() {
|
|
if (channel != 0) outputChannel = channel-1;
|
|
if (sendoff) {
|
|
sendOff();
|
|
sendoff = false;
|
|
} else {
|
|
//debug("sendOn");
|
|
controlOut(note, vel);
|
|
}
|
|
}
|
|
|
|
void sendOff() {
|
|
//debug("sendOff");
|
|
//controlOut(note, 0);
|
|
}
|
|
|
|
void down() {
|
|
send();
|
|
on();
|
|
}
|
|
|
|
void up() {
|
|
sendOff();
|
|
off();
|
|
}
|
|
|
|
void update() {
|
|
if (value == 0) {
|
|
off();
|
|
}
|
|
if (value == 127) {
|
|
on();
|
|
}
|
|
}
|
|
|
|
void nakedSetValue(int ivalue) { setValue(ivalue); }
|
|
void setValue(int ivalue) {
|
|
value = ivalue;
|
|
if (ivalue == 0) {
|
|
sendoff = true;
|
|
}
|
|
propagateToChainedControls();
|
|
}
|
|
}
|
|
|
|
class PC extends GridSegment {
|
|
int note;
|
|
int vel;
|
|
boolean sendoff = false;
|
|
|
|
PC(int ix, int iy, int program) {
|
|
controlID = (int)random(1000);
|
|
page = selectedPage;
|
|
//println(this+" on page "+page);
|
|
x = ix;
|
|
y = iy;
|
|
value = 0;
|
|
state = OFF;
|
|
timeout = 0;
|
|
idlecolor = PCIDLECOLOR;
|
|
activecolor = PCACTIVECOLOR;
|
|
this.note = program;
|
|
|
|
if (x < 8) {
|
|
grid[y*8+x] = this;
|
|
}
|
|
if (x == 8 && y < 7) {
|
|
//debug("Mapping side button:"+this);
|
|
grid[65+y] = this;
|
|
}
|
|
|
|
ledOn(x, y, idlecolor);
|
|
}
|
|
|
|
void send() {
|
|
if (channel != 0) outputChannel = channel-1;
|
|
if (sendoff) {
|
|
sendOff();
|
|
sendoff = false;
|
|
} else {
|
|
//debug("sendOn");
|
|
programOut(note);
|
|
}
|
|
}
|
|
|
|
void sendOff() {
|
|
//debug("sendOff");
|
|
//controlOut(note, 0);
|
|
}
|
|
|
|
void down() {
|
|
send();
|
|
on();
|
|
}
|
|
|
|
void up() {
|
|
sendOff();
|
|
off();
|
|
|
|
}
|
|
|
|
void update() {
|
|
if (value == 0) {
|
|
off();
|
|
}
|
|
if (value == 127) {
|
|
on();
|
|
}
|
|
}
|
|
|
|
void nakedSetValue(int ivalue) { setValue(ivalue); }
|
|
void setValue(int ivalue) {
|
|
value = ivalue;
|
|
if (ivalue == 0) {
|
|
sendoff = true;
|
|
}
|
|
propagateToChainedControls();
|
|
}
|
|
}
|
|
|
|
class Kbd extends GridSegment {
|
|
int note;
|
|
int vel;
|
|
boolean sendoff = false;
|
|
Robot robot;
|
|
int keys[];
|
|
|
|
Kbd(int ix, int iy, String keystring) {
|
|
controlID = (int)random(1000);
|
|
page = selectedPage;
|
|
//println(this+" on page "+page);
|
|
x = ix;
|
|
y = iy;
|
|
value = 0;
|
|
state = OFF;
|
|
timeout = 0;
|
|
idlecolor = KBDIDLECOLOR;
|
|
activecolor = KBDACTIVECOLOR;
|
|
try {
|
|
robot = new Robot();
|
|
} catch (AWTException e) {
|
|
debug("Exception while creating robot "+e);
|
|
}
|
|
String keysS[] = split(keystring, "+");
|
|
keys = new int[keysS.length];
|
|
for (int i = 0; i < keys.length; i++) {
|
|
keys[i] = parseKey(keysS[i]);
|
|
}
|
|
|
|
if (x < 8) {
|
|
grid[y*8+x] = this;
|
|
}
|
|
if (x == 8 && y < 7) {
|
|
//debug("Mapping side button:"+this);
|
|
grid[65+y] = this;
|
|
}
|
|
|
|
ledOn(x, y, idlecolor);
|
|
}
|
|
|
|
int parseKey(String keystr) {
|
|
if (keystr.equals("shift")) return KeyEvent.VK_SHIFT;
|
|
if (keystr.equals("control")) return KeyEvent.VK_CONTROL;
|
|
if (keystr.equals("alt")) return KeyEvent.VK_ALT;
|
|
if (keystr.equals("altgr")) return KeyEvent.VK_ALT_GRAPH;
|
|
if (keystr.equals("command")) return KeyEvent.VK_META;
|
|
if (keystr.equals("1")) return KeyEvent.VK_1;
|
|
if (keystr.equals("2")) return KeyEvent.VK_2;
|
|
if (keystr.equals("3")) return KeyEvent.VK_3;
|
|
if (keystr.equals("4")) return KeyEvent.VK_4;
|
|
if (keystr.equals("5")) return KeyEvent.VK_5;
|
|
if (keystr.equals("6")) return KeyEvent.VK_6;
|
|
if (keystr.equals("7")) return KeyEvent.VK_7;
|
|
if (keystr.equals("8")) return KeyEvent.VK_8;
|
|
if (keystr.equals("9")) return KeyEvent.VK_9;
|
|
if (keystr.equals("0")) return KeyEvent.VK_0;
|
|
if (keystr.equals("a")) return KeyEvent.VK_A;
|
|
if (keystr.equals("b")) return KeyEvent.VK_B;
|
|
if (keystr.equals("c")) return KeyEvent.VK_C;
|
|
if (keystr.equals("d")) return KeyEvent.VK_D;
|
|
if (keystr.equals("e")) return KeyEvent.VK_E;
|
|
if (keystr.equals("f")) return KeyEvent.VK_F;
|
|
if (keystr.equals("g")) return KeyEvent.VK_G;
|
|
if (keystr.equals("h")) return KeyEvent.VK_H;
|
|
if (keystr.equals("i")) return KeyEvent.VK_I;
|
|
if (keystr.equals("j")) return KeyEvent.VK_J;
|
|
if (keystr.equals("k")) return KeyEvent.VK_K;
|
|
if (keystr.equals("l")) return KeyEvent.VK_L;
|
|
if (keystr.equals("m")) return KeyEvent.VK_M;
|
|
if (keystr.equals("n")) return KeyEvent.VK_N;
|
|
if (keystr.equals("o")) return KeyEvent.VK_O;
|
|
if (keystr.equals("p")) return KeyEvent.VK_P;
|
|
if (keystr.equals("q")) return KeyEvent.VK_Q;
|
|
if (keystr.equals("r")) return KeyEvent.VK_R;
|
|
if (keystr.equals("s")) return KeyEvent.VK_S;
|
|
if (keystr.equals("t")) return KeyEvent.VK_T;
|
|
if (keystr.equals("u")) return KeyEvent.VK_U;
|
|
if (keystr.equals("v")) return KeyEvent.VK_V;
|
|
if (keystr.equals("w")) return KeyEvent.VK_W;
|
|
if (keystr.equals("x")) return KeyEvent.VK_X;
|
|
if (keystr.equals("y")) return KeyEvent.VK_Y;
|
|
if (keystr.equals("z")) return KeyEvent.VK_Z;
|
|
if (keystr.equals("f1")) return KeyEvent.VK_F1;
|
|
if (keystr.equals("f2")) return KeyEvent.VK_F2;
|
|
if (keystr.equals("f3")) return KeyEvent.VK_F3;
|
|
if (keystr.equals("f4")) return KeyEvent.VK_F4;
|
|
if (keystr.equals("f5")) return KeyEvent.VK_F5;
|
|
if (keystr.equals("f6")) return KeyEvent.VK_F6;
|
|
if (keystr.equals("f7")) return KeyEvent.VK_F7;
|
|
if (keystr.equals("f8")) return KeyEvent.VK_F8;
|
|
if (keystr.equals("f9")) return KeyEvent.VK_F9;
|
|
if (keystr.equals("f10")) return KeyEvent.VK_F10;
|
|
if (keystr.equals("f11")) return KeyEvent.VK_F11;
|
|
if (keystr.equals("f12")) return KeyEvent.VK_F12;
|
|
if (keystr.equals("f13")) return KeyEvent.VK_F13;
|
|
if (keystr.equals("f14")) return KeyEvent.VK_F14;
|
|
if (keystr.equals("f15")) return KeyEvent.VK_F15;
|
|
if (keystr.equals("f16")) return KeyEvent.VK_F16;
|
|
if (keystr.equals("f17")) return KeyEvent.VK_F17;
|
|
if (keystr.equals("f18")) return KeyEvent.VK_F18;
|
|
if (keystr.equals("f19")) return KeyEvent.VK_F19;
|
|
if (keystr.equals("esc")) return KeyEvent.VK_ESCAPE;
|
|
if (keystr.equals("space")) return KeyEvent.VK_SPACE;
|
|
if (keystr.equals("enter")) return KeyEvent.VK_ENTER;
|
|
if (keystr.equals("tab")) return KeyEvent.VK_TAB;
|
|
if (keystr.equals("backspace")) return KeyEvent.VK_BACK_SPACE;
|
|
if (keystr.equals("delete")) return KeyEvent.VK_DELETE;
|
|
if (keystr.equals("caps")) return KeyEvent.VK_CAPS_LOCK;
|
|
if (keystr.equals("down")) return KeyEvent.VK_DOWN;
|
|
if (keystr.equals("up")) return KeyEvent.VK_UP;
|
|
if (keystr.equals("left")) return KeyEvent.VK_LEFT;
|
|
if (keystr.equals("right")) return KeyEvent.VK_RIGHT;
|
|
if (keystr.equals(",")) return KeyEvent.VK_COMMA;
|
|
if (keystr.equals(".")) return KeyEvent.VK_PERIOD;
|
|
if (keystr.equals("+")) return KeyEvent.VK_PLUS;
|
|
if (keystr.equals("-")) return KeyEvent.VK_MINUS;
|
|
return 0;
|
|
}
|
|
|
|
void send() {
|
|
for (int i = 0; i < keys.length; i++) {
|
|
if (keys[i] != 0) {
|
|
debug("Sending keyPress "+keys[i]);
|
|
robot.keyPress(keys[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
void sendOff() {
|
|
for (int i = 0; i < keys.length; i++) {
|
|
if (keys[i] != 0) {
|
|
robot.keyRelease(keys[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
void down() {
|
|
send();
|
|
on();
|
|
}
|
|
|
|
void up() {
|
|
sendOff();
|
|
off();
|
|
}
|
|
|
|
void update() {
|
|
if (value == 0) {
|
|
off();
|
|
}
|
|
if (value == 127) {
|
|
on();
|
|
}
|
|
}
|
|
|
|
void nakedSetValue(int ivalue) { setValue(ivalue); }
|
|
void setValue(int ivalue) {
|
|
value = ivalue;
|
|
if (ivalue == 0) {
|
|
sendoff = true;
|
|
}
|
|
propagateToChainedControls();
|
|
}
|
|
}
|
|
|
|
class FaderSegment extends GridSegment {
|
|
Fader owner;
|
|
|
|
FaderSegment(int ix, int iy, Fader iowner) {
|
|
page = selectedPage;
|
|
//println(this+" on page "+page);
|
|
x = ix;
|
|
y = iy;
|
|
owner = iowner;
|
|
controlID = (int)random(1000);
|
|
grid[y*8+x] = this;
|
|
idlecolor = FADERIDLECOLOR;
|
|
activecolor = FADERACTIVECOLOR;
|
|
off();
|
|
}
|
|
|
|
void down() {
|
|
owner.faderAction(this);
|
|
}
|
|
|
|
void update() {
|
|
if (x == owner.x && y == owner.y) {
|
|
owner.update();
|
|
}
|
|
}
|
|
|
|
void send() {
|
|
if (x == owner.x && y == owner.y) {
|
|
owner.send();
|
|
}
|
|
}
|
|
|
|
void nakedSetValue(int ivalue) { setValue(ivalue); }
|
|
void setValue(int ivalue) {
|
|
if (x == owner.x && y == owner.y) {
|
|
owner.nakedSetValue(ivalue);
|
|
}
|
|
}
|
|
|
|
void chainTo(Control control, boolean send) {
|
|
owner.chainTo(control, send);
|
|
}
|
|
|
|
void propagateToChainedControls() {
|
|
owner.propagateToChainedControls();
|
|
}
|
|
}
|
|
|
|
class Fader extends Control {
|
|
FaderSegment[] segments;
|
|
long lastupdate;
|
|
boolean schedule;
|
|
|
|
|
|
void faderAction(FaderSegment sender){}
|
|
|
|
boolean canUpdate() {
|
|
long now = (new Date()).getTime();
|
|
debug("l "+lastupdate);
|
|
debug("n "+now);
|
|
debug("d "+(now-lastupdate));
|
|
if (now - lastupdate < 100) {
|
|
lastupdate = now;
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
void schedule() {
|
|
schedule = true;
|
|
new Scheduler(this);
|
|
}
|
|
|
|
void cancelSchedule() {
|
|
schedule = false;
|
|
}
|
|
|
|
boolean hasSchedule() {
|
|
return schedule;
|
|
}
|
|
|
|
}
|
|
|
|
class XFader extends Fader {
|
|
int sx;
|
|
int lastsx;
|
|
|
|
XFader(int ix, int iy, int ixsize) {
|
|
page = selectedPage;
|
|
//println(this+" on page "+page);
|
|
x = ix;
|
|
y = iy;
|
|
xsize = ixsize;
|
|
sx = x;
|
|
lastsx = -1;
|
|
takeover = 0;
|
|
segments = new FaderSegment[xsize];
|
|
for (int i = 0; i < xsize; i++) {
|
|
segments[i] = new FaderSegment(x+i, y, this);
|
|
}
|
|
grid[y*8+x].on();
|
|
}
|
|
|
|
void faderAction(FaderSegment sender) {
|
|
sx = sender.x;
|
|
float relx = sx - x;
|
|
float quantum = relx * (1 / ((float)xsize - 1));
|
|
float amount = ((relx + quantum) / (float)xsize) * 127;
|
|
setValue((int)amount);
|
|
}
|
|
|
|
void update() {
|
|
//if (lastsx == sx && !hasSchedule()) schedule();
|
|
if (lastsx != sx || canUpdate()) {
|
|
if (page == selectedPage) {
|
|
for(int i = 0; i < xsize; i++) {
|
|
if (i <= sx) { grid[y*8+x+i].on(); } else { grid[y*8+x+i].off(); }
|
|
}
|
|
lastsx = sx;
|
|
lastupdate = (new Date()).getTime();
|
|
}
|
|
}
|
|
}
|
|
|
|
void send() {
|
|
if (channel != 0) outputChannel = channel-1;
|
|
controlOut(x, y, value);
|
|
}
|
|
|
|
void setTakeover(int itakeover) {
|
|
//debug("setTakeover()");
|
|
takeover = itakeover;
|
|
}
|
|
|
|
void nakedSetValue(int ivalue) {
|
|
if (TAKEOVER == false) {
|
|
float step = 127 / (xsize-1);
|
|
sx = (int)(ivalue / step);
|
|
value = ivalue;
|
|
propagateToChainedControls();
|
|
} else {
|
|
//debug("nakedSetValueX() blocked because takeover is in progress.");
|
|
}
|
|
}
|
|
|
|
void takeoverSetValue(int ivalue) {
|
|
float step = 127 / (xsize-1);
|
|
sx = (int)(ivalue / step);
|
|
value = ivalue;
|
|
send();
|
|
if (lastsx != sx) update();
|
|
propagateToChainedControls();
|
|
}
|
|
|
|
void setValue(int ivalue) {
|
|
if (takeover == 0) {
|
|
float step = 127 / (xsize-1);
|
|
sx = (int)(ivalue / step);
|
|
value = ivalue;
|
|
send();
|
|
if (lastsx != sx) update();
|
|
propagateToChainedControls();
|
|
} else {
|
|
//debug("Delegating control to takeover routine");
|
|
takeover(ivalue);
|
|
}
|
|
}
|
|
|
|
void takeover(int ivalue) {
|
|
threadsSpawned++;
|
|
TakeOver takeover = new TakeOver(this, ivalue, this.takeover);
|
|
}
|
|
|
|
}
|
|
|
|
class IXFader extends Fader {
|
|
int sx;
|
|
int lastsx;
|
|
|
|
IXFader(int ix, int iy, int ixsize) {
|
|
page = selectedPage;
|
|
//println(this+" on page "+page);
|
|
x = ix;
|
|
y = iy;
|
|
xsize = ixsize;
|
|
sx = 0;
|
|
lastsx = -1;
|
|
takeover = 0;
|
|
segments = new FaderSegment[xsize];
|
|
for (int i = 0; i < xsize; i++) {
|
|
segments[i] = new FaderSegment(x+i, y, this);
|
|
}
|
|
grid[y*8+x].on();
|
|
}
|
|
|
|
void faderAction(FaderSegment sender) {
|
|
sx = sender.x;
|
|
float relx = sx - x;
|
|
float quantum = relx * (1 / ((float)xsize - 1));
|
|
float amount = ((relx + quantum) / (float)xsize) * 127;
|
|
setValue(127-(int)amount);
|
|
}
|
|
|
|
void update() {
|
|
//if (lastsx == sx && !hasSchedule()) schedule();
|
|
if (lastsx != sx || canUpdate()) {
|
|
if (page == selectedPage) {
|
|
for(int i = xsize-1; i >= 0; i--) {
|
|
debug("sx="+((xsize-1)-sx)+" i="+i);
|
|
if (i >= (xsize-1)-sx) { grid[y*8+x+i].on(); } else { grid[y*8+x+i].off(); }
|
|
//if (i <= sx) { grid[y*8+x+i].on(); } else { grid[y*8+x+i].off(); }
|
|
}
|
|
lastsx = sx;
|
|
lastupdate = (new Date()).getTime();
|
|
}
|
|
}
|
|
}
|
|
|
|
void send() {
|
|
if (channel != 0) outputChannel = channel-1;
|
|
controlOut(x, y, value);
|
|
}
|
|
|
|
void setTakeover(int itakeover) {
|
|
//debug("setTakeover()");
|
|
takeover = itakeover;
|
|
}
|
|
|
|
void nakedSetValue(int ivalue) {
|
|
if (TAKEOVER == false) {
|
|
float step = 127 / (xsize-1);
|
|
sx = (int)(ivalue / step);
|
|
value = ivalue;
|
|
propagateToChainedControls();
|
|
} else {
|
|
//debug("nakedSetValueX() blocked because takeover is in progress.");
|
|
}
|
|
}
|
|
|
|
void takeoverSetValue(int ivalue) {
|
|
float step = 127 / (xsize-1);
|
|
sx = (int)(ivalue / step);
|
|
value = ivalue;
|
|
send();
|
|
if (lastsx != sx) update();
|
|
propagateToChainedControls();
|
|
}
|
|
|
|
void setValue(int ivalue) {
|
|
if (takeover == 0) {
|
|
float step = 127 / (xsize-1);
|
|
sx = (int)(ivalue / step);
|
|
value = ivalue;
|
|
send();
|
|
if (lastsx != sx) update();
|
|
propagateToChainedControls();
|
|
} else {
|
|
//debug("Delegating control to takeover routine");
|
|
takeover(ivalue);
|
|
}
|
|
}
|
|
|
|
void takeover(int ivalue) {
|
|
threadsSpawned++;
|
|
TakeOver takeover = new TakeOver(this, ivalue, this.takeover);
|
|
}
|
|
|
|
}
|
|
|
|
class YFader extends Fader {
|
|
int sy;
|
|
int lastsy;
|
|
|
|
YFader(int ix, int iy, int iysize) {
|
|
controlID = (int)random(1000);
|
|
page = selectedPage;
|
|
//println(this+" on page "+page);
|
|
x = ix;
|
|
y = iy;
|
|
ysize = iysize;
|
|
sy = y;
|
|
lastsy = -1;
|
|
value = 0;
|
|
segments = new FaderSegment[ysize];
|
|
for (int i = 0; i < ysize; i++) {
|
|
segments[i] = new FaderSegment(x, y - i, this);
|
|
}
|
|
grid[y*8+x].on();
|
|
}
|
|
|
|
void faderAction(FaderSegment sender) {
|
|
sy = sender.y;
|
|
float rely = sy - y;
|
|
float quantum = rely * (1 / ((float)ysize - 1));
|
|
float amount = ((rely + quantum) / (float)ysize) * 127;
|
|
setValue(0 - ((int)amount));
|
|
}
|
|
|
|
void update() {
|
|
//if (lastsy == sy && !hasSchedule()) schedule();
|
|
if (lastsy != sy || canUpdate()) {
|
|
|
|
if (page == selectedPage) {
|
|
for(int i = y; i > y - ysize; i--) {
|
|
if (i >= sy) { grid[i*8+x].on(); } else { grid[i*8+x].off(); }
|
|
}
|
|
lastsy = sy;
|
|
lastupdate = (new Date()).getTime();
|
|
}
|
|
}
|
|
}
|
|
|
|
void send() {
|
|
if (channel != 0) outputChannel = channel-1;
|
|
controlOut(x, y, value);
|
|
}
|
|
|
|
void setTakeover(int itakeover) {
|
|
//debug("setTakeover()");
|
|
takeover = itakeover;
|
|
}
|
|
|
|
void nakedSetValue(int ivalue) {
|
|
if (TAKEOVER == false) {
|
|
float step = 127 / (ysize-1);
|
|
int rely = ((int)(ivalue / step));
|
|
sy = y - rely;
|
|
value = ivalue;
|
|
propagateToChainedControls();
|
|
} else {
|
|
//debug("nakedSetValue() blocked because takeover is in progress.");
|
|
}
|
|
}
|
|
|
|
void takeoverSetValue(int ivalue) {
|
|
float step = 127 / (ysize-1);
|
|
int rely = ((int)(ivalue / step));
|
|
sy = y - rely;
|
|
value = ivalue;
|
|
send();
|
|
//debug("sy "+sy+" lastsy "+lastsy);
|
|
if (lastsy != sy) update();
|
|
propagateToChainedControls();
|
|
}
|
|
|
|
void setValue(int ivalue) {
|
|
if (takeover == 0) {
|
|
float step = 127 / (ysize-1);
|
|
int rely = ((int)(ivalue / step));
|
|
sy = y - rely;
|
|
value = ivalue;
|
|
send();
|
|
if (lastsy != sy) update();
|
|
propagateToChainedControls();
|
|
} else {
|
|
//debug("Delegating control to takeover routine");
|
|
takeover(ivalue);
|
|
}
|
|
}
|
|
|
|
void takeover(int ivalue) {
|
|
threadsSpawned++;
|
|
TakeOver takeover = new TakeOver(this, ivalue, this.takeover);
|
|
}
|
|
}
|
|
|
|
class IYFader extends Fader {
|
|
int sy;
|
|
int lastsy;
|
|
|
|
IYFader(int ix, int iy, int iysize) {
|
|
controlID = (int)random(1000);
|
|
page = selectedPage;
|
|
//println(this+" on page "+page);
|
|
x = ix;
|
|
y = iy;
|
|
ysize = iysize;
|
|
sy = y;
|
|
lastsy = -1;
|
|
value = 0;
|
|
segments = new FaderSegment[ysize];
|
|
for (int i = 0; i < ysize; i++) {
|
|
segments[i] = new FaderSegment(x, y - i, this);
|
|
}
|
|
grid[y*8+x].on();
|
|
}
|
|
|
|
void faderAction(FaderSegment sender) {
|
|
sy = sender.y;
|
|
debug("!! sy="+sy);
|
|
float rely = sy - y;
|
|
float quantum = rely * (1 / ((float)ysize - 1));
|
|
float amount = ((rely + quantum) / (float)ysize) * 127;
|
|
setValue(127 + ((int)amount));
|
|
debug("!! value="+(127 + ((int)amount)));
|
|
}
|
|
|
|
void update() {
|
|
if (lastsy != sy || canUpdate()) {
|
|
|
|
if (page == selectedPage) {
|
|
for(int i = 0; i < ysize; i++) {
|
|
int pos = y - sy;
|
|
pos = (ysize-1)-pos;
|
|
debug("i="+i+" sy="+sy+" pos="+pos);
|
|
if (i >= pos ) { grid[(y-i)*8+x].on(); } else { grid[(y-i)*8+x].off(); }
|
|
}
|
|
|
|
lastsy = sy;
|
|
lastupdate = (new Date()).getTime();
|
|
}
|
|
}
|
|
}
|
|
|
|
void send() {
|
|
if (channel != 0) outputChannel = channel-1;
|
|
controlOut(x, y, value);
|
|
}
|
|
|
|
void setTakeover(int itakeover) {
|
|
//debug("setTakeover()");
|
|
takeover = itakeover;
|
|
}
|
|
|
|
void nakedSetValue(int ivalue) {
|
|
if (TAKEOVER == false) {
|
|
float step = 127 / (ysize-1);
|
|
int rely = ((int)(ivalue / step));
|
|
sy = y - rely;
|
|
value = ivalue;
|
|
propagateToChainedControls();
|
|
} else {
|
|
//debug("nakedSetValue() blocked because takeover is in progress.");
|
|
}
|
|
}
|
|
|
|
void takeoverSetValue(int ivalue) {
|
|
float step = 127 / (ysize-1);
|
|
int rely = ((int)(ivalue / step));
|
|
sy = y - rely;
|
|
value = ivalue;
|
|
send();
|
|
//debug("sy "+sy+" lastsy "+lastsy);
|
|
if (lastsy != sy) update();
|
|
propagateToChainedControls();
|
|
}
|
|
|
|
void setValue(int ivalue) {
|
|
if (takeover == 0) {
|
|
float step = 127 / (ysize-1);
|
|
int rely = ((int)(ivalue / step));
|
|
sy = y - rely;
|
|
value = ivalue;
|
|
send();
|
|
if (lastsy != sy) update();
|
|
propagateToChainedControls();
|
|
} else {
|
|
//debug("Delegating control to takeover routine");
|
|
takeover(ivalue);
|
|
}
|
|
}
|
|
|
|
void takeover(int ivalue) {
|
|
threadsSpawned++;
|
|
TakeOver takeover = new TakeOver(this, ivalue, this.takeover);
|
|
}
|
|
}
|
|
|
|
class SliderSegment extends GridSegment {
|
|
Slider owner;
|
|
|
|
SliderSegment(int ix, int iy, Slider iowner) {
|
|
page = selectedPage;
|
|
//println(this+" on page "+page);
|
|
x = ix;
|
|
y = iy;
|
|
owner = iowner;
|
|
grid[y*8+x] = this;
|
|
idlecolor = SLIDERIDLECOLOR;
|
|
activecolor = SLIDERACTIVECOLOR;
|
|
off();
|
|
}
|
|
|
|
void down() {
|
|
owner.sliderAction(this);
|
|
}
|
|
|
|
void up() {
|
|
owner.liftFinger(this);
|
|
}
|
|
|
|
void update() {
|
|
off();
|
|
}
|
|
|
|
void send() {
|
|
if (x == owner.x && y == owner.y) {
|
|
owner.send();
|
|
}
|
|
}
|
|
|
|
void nakedSetValue(int ivalue) { setValue(ivalue); }
|
|
void setValue(int ivalue) {
|
|
if (x == owner.x && y == owner.y) {
|
|
owner.setValue(ivalue);
|
|
}
|
|
}
|
|
|
|
void chainTo(Control control, boolean send) {
|
|
owner.chainTo(control, send);
|
|
}
|
|
|
|
void propagateToChainedControls() {
|
|
owner.propagateToChainedControls();
|
|
}
|
|
}
|
|
|
|
class Slider extends Control {
|
|
SliderSegment[] segments;
|
|
|
|
void sliderAction(SliderSegment sender){}
|
|
void liftFinger(SliderSegment sender){};
|
|
|
|
void send() {
|
|
if (channel != 0) outputChannel = channel-1;
|
|
controlOut(x, y, value);
|
|
}
|
|
|
|
void nakedSetValue(int ivalue) { setValue(ivalue); }
|
|
void setValue(int ivalue) {
|
|
value = ivalue;
|
|
propagateToChainedControls();
|
|
}
|
|
}
|
|
|
|
class XSlider extends Slider {
|
|
int lastSegment;
|
|
int segment;
|
|
int granularity;
|
|
|
|
XSlider(int ix, int iy, int ixsize, int igranularity) {
|
|
page = selectedPage;
|
|
//println(this+" on page "+page);
|
|
x = ix;
|
|
y = iy;
|
|
xsize = ixsize;
|
|
value = SLIDERDEFAULTVALUE;
|
|
granularity = igranularity;
|
|
segments = new SliderSegment[xsize];
|
|
for (int i = 0; i < xsize; i++) {
|
|
segments[i] = new SliderSegment(x+i, y, this);
|
|
}
|
|
}
|
|
|
|
void sliderAction(SliderSegment sender) {
|
|
segment = sender.x;
|
|
if (lastSegment - 1 == segment) {
|
|
decrease();
|
|
//debug("Decreasing "+this+" to "+value);
|
|
}
|
|
if (lastSegment + 1 == segment) {
|
|
increase();
|
|
//debug("Increasing "+this+" to "+value);
|
|
}
|
|
sender.on();
|
|
lastSegment = segment;
|
|
}
|
|
|
|
void liftFinger(SliderSegment sender) {
|
|
sender.off();
|
|
}
|
|
|
|
void increase() {
|
|
if (value < 127) {
|
|
value += granularity;
|
|
}
|
|
if (value > 127) {
|
|
value = 127;
|
|
}
|
|
send();
|
|
propagateToChainedControls();
|
|
}
|
|
|
|
void decrease() {
|
|
if (value > 0) {
|
|
value -= granularity;
|
|
}
|
|
if (value < 0) {
|
|
value = 0;
|
|
}
|
|
send();
|
|
propagateToChainedControls();
|
|
}
|
|
}
|
|
|
|
class YSlider extends Slider {
|
|
int lastSegment;
|
|
int segment;
|
|
int granularity;
|
|
|
|
YSlider(int ix, int iy, int iysize, int igranularity) {
|
|
page = selectedPage;
|
|
//println(this+" on page "+page);
|
|
x = ix;
|
|
y = iy;
|
|
ysize = iysize;
|
|
value = SLIDERDEFAULTVALUE;
|
|
granularity = igranularity;
|
|
segments = new SliderSegment[ysize];
|
|
for (int i = 0; i < ysize; i++) {
|
|
segments[i] = new SliderSegment(x, y - i, this);
|
|
}
|
|
}
|
|
|
|
void sliderAction(SliderSegment sender) {
|
|
segment = sender.y;
|
|
if (lastSegment - 1 == segment) {
|
|
increase();
|
|
}
|
|
if (lastSegment + 1 == segment) {
|
|
decrease();
|
|
}
|
|
sender.on();
|
|
lastSegment = segment;
|
|
}
|
|
|
|
void liftFinger(SliderSegment sender) {
|
|
sender.off();
|
|
}
|
|
|
|
void increase() {
|
|
if (value < 127) {
|
|
value += granularity;
|
|
}
|
|
if (value > 127) {
|
|
value = 127;
|
|
}
|
|
send();
|
|
propagateToChainedControls();
|
|
}
|
|
|
|
void decrease() {
|
|
if (value > 0) {
|
|
value -= granularity;
|
|
}
|
|
if (value < 0) {
|
|
value = 0;
|
|
}
|
|
send();
|
|
propagateToChainedControls();
|
|
}
|
|
}
|
|
|
|
class PadSegment extends GridSegment {
|
|
Pad owner;
|
|
|
|
PadSegment(int ix, int iy, Pad iowner) {
|
|
x = ix;
|
|
y = iy;
|
|
owner = iowner;
|
|
grid[y*8+x] = this;
|
|
idlecolor = PADOFFCOLOR;
|
|
activecolor = PADONCOLOR;
|
|
off();
|
|
}
|
|
|
|
void down() {
|
|
owner.padAction(this);
|
|
}
|
|
|
|
void update() {
|
|
owner.update(this);
|
|
}
|
|
|
|
void send() {
|
|
if (x == owner.x && y == owner.y) {
|
|
owner.sendX();
|
|
}
|
|
if (x == owner.x+1 && y == owner.y) {
|
|
owner.sendY();
|
|
}
|
|
}
|
|
|
|
void nakedSetValue(int ivalue) { setValue(ivalue); }
|
|
void setValue(int ivalue) {
|
|
if (x == owner.x && y == owner.y) {
|
|
owner.nakedSetValueX(ivalue);
|
|
}
|
|
if (x == owner.x+1 && y == owner.y) {
|
|
owner.nakedSetValueY(ivalue);
|
|
}
|
|
}
|
|
|
|
void chainTo(Control control, boolean send) {
|
|
owner.chainTo(control, send);
|
|
}
|
|
|
|
void propagateToChainedControls() {
|
|
owner.propagateToChainedControls();
|
|
}
|
|
}
|
|
|
|
class Pad extends Control {
|
|
PadSegment[] padSegments;
|
|
int sx;
|
|
int sy;
|
|
int lastsx;
|
|
int lastsy;
|
|
int xvalue;
|
|
int yvalue;
|
|
boolean invertx = false;
|
|
boolean inverty = false;
|
|
boolean TAKEOVER;
|
|
long threadsSpawned = 0;
|
|
long threadsFinished = 0;
|
|
|
|
Pad(int ix, int iy, int ixsize, int iysize) {
|
|
page = selectedPage;
|
|
//println(this+" on page "+page);
|
|
x = ix;
|
|
y = iy;
|
|
xsize = ixsize;
|
|
ysize = iysize;
|
|
sx = x;
|
|
sy = y+ysize-1;
|
|
takeover = 0;
|
|
yvalue = 0;
|
|
xvalue = 0;
|
|
lastsx = x;
|
|
lastsy = y+ysize-1;
|
|
padSegments = new PadSegment[xsize*ysize];
|
|
|
|
for (int yi = 0; yi < ysize; yi++) {
|
|
for (int xi = 0; xi < xsize; xi++) {
|
|
padSegments[yi*ysize+xi] = new PadSegment(xi+x, yi+y, this);
|
|
}
|
|
}
|
|
}
|
|
|
|
void padAction(PadSegment sender) {
|
|
//debug("padAction()");
|
|
sy = sender.y;
|
|
float rely = sy - y;
|
|
float quantum = rely * (1 / ((float)ysize - 1));
|
|
float amounty = 127-((rely + quantum) / (float)ysize) * 127;
|
|
sx = sender.x;
|
|
float relx = sx - x;
|
|
quantum = relx * (1 / ((float)xsize - 1));
|
|
float amountx = ((relx + quantum) / (float)xsize) * 127;
|
|
setValue((int)amountx, (int)amounty);
|
|
}
|
|
|
|
void send() {
|
|
sendX();
|
|
sendY();
|
|
}
|
|
|
|
void sendX() {
|
|
if (channel != 0) outputChannel = channel-1;
|
|
if (!invertx) controlOut(x, y, xvalue);
|
|
if (invertx) controlOut(x, y, 127-xvalue);
|
|
}
|
|
|
|
void sendY() {
|
|
if (channel != 0) outputChannel = channel-1;
|
|
if (!inverty) controlOut(x+1, y, yvalue);
|
|
if (inverty) controlOut(x+1, y, 127-yvalue);
|
|
|
|
}
|
|
|
|
void setTakeover(int takeover) {
|
|
this.takeover = takeover;
|
|
}
|
|
|
|
void invertx() {
|
|
invertx = true;
|
|
}
|
|
|
|
void inverty() {
|
|
inverty = true;
|
|
}
|
|
|
|
void nakedSetValueX(int ivalue) {
|
|
if (invertx) ivalue = 127-ivalue;
|
|
if (TAKEOVER == false) {
|
|
float step = 127 / (xsize-1);
|
|
sx = x+(int)(ivalue / step);
|
|
xvalue = ivalue;
|
|
propagateToChainedControls();
|
|
//debug("nakedSetValueX() succeeded.");
|
|
} else {
|
|
//debug("nakedSetValueX() blocked because takeover is in progress.");
|
|
}
|
|
}
|
|
|
|
void nakedSetValueY(int ivalue) {
|
|
if (inverty) ivalue = 127-ivalue;
|
|
if (TAKEOVER == false) {
|
|
float step = 127 / (ysize-1);
|
|
int rely = ((int)(ivalue / step));
|
|
sy = (ysize-1)+(y - rely);
|
|
yvalue = ivalue;
|
|
propagateToChainedControls();
|
|
//debug("nakedSetValueY() succeeded.");
|
|
} else {
|
|
//debug("nakedSetValueY() blocked because takeover is in progress.");
|
|
}
|
|
}
|
|
|
|
void takeoverSetValue(int ixvalue, int iyvalue) {
|
|
float step = 127 / (ysize-1);
|
|
int rely = ((int)(iyvalue / step));
|
|
sy = (ysize-1)+(y - rely);
|
|
yvalue = iyvalue;
|
|
|
|
step = 127 / (xsize-1);
|
|
sx = x+(int)(ixvalue / step);
|
|
xvalue = ixvalue;
|
|
//debug("xvalue = "+xvalue+". sx = "+sx);
|
|
//debug("yvalue = "+yvalue+". sy = "+sy);
|
|
send();
|
|
if (lastsy != sy || lastsx != sx) update();
|
|
propagateToChainedControls();
|
|
}
|
|
|
|
void setValue(int ixvalue, int iyvalue) {
|
|
if (takeover == 0) {
|
|
float step = 127 / (ysize-1);
|
|
int rely = ((int)(iyvalue / step));
|
|
sy = (ysize-1)+(y - rely);
|
|
yvalue = iyvalue;
|
|
|
|
step = 127 / (xsize-1);
|
|
sx = x+(int)(ixvalue / step);
|
|
xvalue = ixvalue;
|
|
//debug("xvalue = "+xvalue+". sx = "+sx);
|
|
//debug("yvalue = "+yvalue+". sy = "+sy);
|
|
send();
|
|
if (lastsy != sy || lastsx != sx) update();
|
|
propagateToChainedControls();
|
|
} else {
|
|
//debug("Delegating control to takeover routine");
|
|
takeover(ixvalue, iyvalue);
|
|
}
|
|
}
|
|
|
|
void takeover(int ixvalue, int iyvalue) {
|
|
threadsSpawned++;
|
|
TakeOver2d takeover = new TakeOver2d(this, ixvalue, iyvalue, this.takeover);
|
|
}
|
|
|
|
void update() {
|
|
if (page == selectedPage) {
|
|
//debug("update() sx="+sx+" sy="+sy);
|
|
grid[lastsx+lastsy*8].off();
|
|
grid[sx+sy*8].on();
|
|
lastsx = sx;
|
|
lastsy = sy;
|
|
}
|
|
}
|
|
|
|
void update(PadSegment sender) {
|
|
//debug("update("+sender+") sx="+sx+" sy="+sy);
|
|
if ((sender.x == x && sender.y == y) || (sender.x-1 == x && sender.y == y)) {
|
|
//debug("is the case");
|
|
if (sender.x == sx && sender.y == sy) { sender.on(); } else { sender.off(); }
|
|
grid[sx+sy*8].on();
|
|
if (lastsx != sx || lastsy != sy) {
|
|
grid[lastsx+lastsy*8].off();
|
|
lastsx = sx;
|
|
lastsy = sy;
|
|
}
|
|
|
|
} else {
|
|
//debug("not the case");
|
|
if (sender.x == sx && sender.y == sy) sender.on();
|
|
if (sender.x != sx || sender.y != sy) sender.off();
|
|
}
|
|
/*lastsx = sx;
|
|
lastsy = sy;*/
|
|
|
|
}
|
|
}
|
|
|
|
class Drumrack extends Control {
|
|
|
|
Drumrack(int ix, int iy, int ixsize, int iysize, int startOctave, String startNote, int vel, boolean invert) {
|
|
page = selectedPage;
|
|
//println(this+" on page "+page);
|
|
x = ix;
|
|
y = iy;
|
|
xsize = ixsize;
|
|
ysize = iysize;
|
|
Note note;
|
|
|
|
int snote = addOctave(parseNote(startNote), startOctave);
|
|
|
|
if (invert) {
|
|
for (int yi = 0; yi < ysize; yi++) {
|
|
for (int xi = 0; xi < xsize; xi++) {
|
|
new Note(xi+x, ((ysize-1)-yi)+y, snote, vel);
|
|
snote++;
|
|
}
|
|
}
|
|
} else {
|
|
for (int yi = 0; yi < ysize; yi++) {
|
|
for (int xi = 0; xi < xsize; xi++) {
|
|
new Note(xi+x, yi+y, snote, vel);
|
|
snote++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int parseNote(String note) {
|
|
note = note.toLowerCase();
|
|
if (note.equals("c")) return 0;
|
|
if (note.equals("c#")) return 1;
|
|
if (note.equals("d")) return 2;
|
|
if (note.equals("d#")) return 3;
|
|
if (note.equals("e")) return 4;
|
|
if (note.equals("f")) return 5;
|
|
if (note.equals("f#")) return 6;
|
|
if (note.equals("g")) return 7;
|
|
if (note.equals("g#")) return 8;
|
|
if (note.equals("a")) return 9;
|
|
if (note.equals("a#")) return 10;
|
|
if (note.equals("b")) return 11;
|
|
return 0;
|
|
}
|
|
|
|
int addOctave(int note, int octave) {
|
|
octave = octave+1;
|
|
return note+(octave*12);
|
|
}
|
|
|
|
}
|
|
|
|
class MeterSegment extends GridSegment {
|
|
Meter owner;
|
|
|
|
MeterSegment(int ix, int iy, Meter iowner) {
|
|
page = selectedPage;
|
|
x = ix;
|
|
y = iy;
|
|
owner = iowner;
|
|
controlID = (int)random(1000);
|
|
grid[y*8+x] = this;
|
|
idlecolor = METERIDLECOLOR;
|
|
activecolor = METERACTIVECOLOR;
|
|
off();
|
|
}
|
|
|
|
void update() {
|
|
if (x == owner.x && y == owner.y) {
|
|
owner.update();
|
|
}
|
|
}
|
|
|
|
void nakedSetValue(int ivalue) { setValue(ivalue); }
|
|
void setValue(int ivalue) {
|
|
if (x == owner.x && y == owner.y) {
|
|
owner.nakedSetValue(ivalue);
|
|
}
|
|
}
|
|
|
|
void chainTo(Control control, boolean send) {
|
|
owner.chainTo(control, send);
|
|
}
|
|
|
|
void propagateToChainedControls() {
|
|
owner.propagateToChainedControls();
|
|
}
|
|
}
|
|
|
|
class Meter extends Control {
|
|
MeterSegment[] segments;
|
|
long lastupdate;
|
|
|
|
boolean canUpdate() {
|
|
long now = (new Date()).getTime();
|
|
if (now - lastupdate > updatedelay) {
|
|
lastupdate = now;
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
class XMeter extends Meter {
|
|
int sx;
|
|
float sxf;
|
|
int lastsx;
|
|
float lastsxf;
|
|
|
|
XMeter(int ix, int iy, int ixsize) {
|
|
page = selectedPage;
|
|
//println(this+" on page "+page);
|
|
x = ix;
|
|
y = iy;
|
|
xsize = ixsize;
|
|
sx = x;
|
|
lastsx = -1;
|
|
takeover = 0;
|
|
segments = new MeterSegment[xsize];
|
|
for (int i = 0; i < xsize; i++) {
|
|
segments[i] = new MeterSegment(x+i, y, this);
|
|
}
|
|
grid[y*8+x].on();
|
|
}
|
|
|
|
void update() {
|
|
|
|
if (canUpdate()) {
|
|
//debug("go");
|
|
if (page == selectedPage) {
|
|
for(int i = 0; i < xsize; i++) {
|
|
|
|
if (i != sx && i != sx+1) {
|
|
grid[y*8+x+i].off();
|
|
}
|
|
|
|
if (i == sx+1 && !(sxf - sx >= 0.56) && !(((sxf - sx) > 0.43 && (sxf - sx) < 0.56) && sx != xsize-1)) {
|
|
grid[y*8+x+i].off();
|
|
}
|
|
|
|
if (i == sx) {
|
|
if (sxf - sx <= 0.43) {
|
|
grid[y*8+x+i].on();
|
|
}
|
|
|
|
if (sxf - sx >= 0.56) {
|
|
grid[y*8+x+(i+1)].on();
|
|
}
|
|
|
|
if (((sxf - sx) > 0.43 && (sxf - sx) < 0.56) && sx != xsize-1) {
|
|
grid[y*8+x+i].on();
|
|
grid[y*8+x+i+1].on();
|
|
}
|
|
}
|
|
|
|
}
|
|
lastsx = sx;
|
|
lastsxf = sxf;
|
|
}
|
|
} else { /*debug("filtered");*/ }
|
|
}
|
|
|
|
|
|
void nakedSetValue(int ivalue) {
|
|
float step = 127 / (xsize-1);
|
|
sxf = (ivalue / step);
|
|
//println(sxf);
|
|
sx = (int)sxf;
|
|
value = ivalue;
|
|
propagateToChainedControls();
|
|
}
|
|
|
|
|
|
void setValue(int ivalue) {
|
|
float step = 127 / (xsize-1);
|
|
sxf = (ivalue / step);
|
|
//println(sxf);
|
|
sx = (int)sxf;
|
|
value = ivalue;
|
|
send();
|
|
if (lastsxf != sxf) update();
|
|
propagateToChainedControls();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
class YMeter extends Meter {
|
|
int sy;
|
|
int lastsy;
|
|
float syf;
|
|
float lastsyf;
|
|
|
|
YMeter(int ix, int iy, int iysize) {
|
|
controlID = (int)random(1000);
|
|
page = selectedPage;
|
|
//println(this+" on page "+page);
|
|
x = ix;
|
|
y = iy;
|
|
ysize = iysize;
|
|
sy = y;
|
|
lastsy = -1;
|
|
value = 0;
|
|
segments = new MeterSegment[ysize];
|
|
for (int i = 0; i < ysize; i++) {
|
|
segments[i] = new MeterSegment(x, y - i, this);
|
|
}
|
|
grid[y*8+x].on();
|
|
}
|
|
|
|
void update() {
|
|
//debug("diff: "+abs((lastsy-lastsyf) - (sy-syf)));
|
|
|
|
if (page == selectedPage && canUpdate()) {
|
|
for(int i = y; i >= y-(ysize-1); i--) {
|
|
if (i != sy && i != sy-1) {
|
|
grid[i*8+x].off();
|
|
//debug("turning off 0");
|
|
}
|
|
|
|
if (i == sy-1 && !(sy - syf >= 0.56) && !(((sy - syf) > 0.43 && (syf - sy) < 0.56))) {
|
|
grid[(i)*8+x].off();
|
|
}
|
|
|
|
|
|
if (i == sy) {
|
|
if (sy - syf <= 0.43) {
|
|
grid[i*8+x].on();
|
|
//debug("turning on 0");
|
|
}
|
|
|
|
if (sy - syf >= 0.56) {
|
|
grid[(i-1)*8+x].on();
|
|
//debug("turning on -1");
|
|
}
|
|
|
|
if (((sy - syf) > 0.43 && (syf - sy) < 0.56) && sy != y-ysize-1) {
|
|
grid[i*8+x].on();
|
|
grid[(i-1)*8+x].on();
|
|
//debug("turning on both");
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
lastsy = sy;
|
|
lastsyf = syf;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void nakedSetValue(int ivalue) {
|
|
float step = 127 / (ysize-1);
|
|
int rely = ((int)(ivalue / step));
|
|
syf = y - abs((ivalue / step));
|
|
sy = y - rely;
|
|
//debug("syf: "+syf);
|
|
value = ivalue;
|
|
propagateToChainedControls();
|
|
}
|
|
|
|
void setValue(int ivalue) {
|
|
float step = 127 / (ysize-1);
|
|
int rely = ((int)(ivalue / step));
|
|
sy = y - rely;
|
|
syf = y - abs((ivalue / step));
|
|
//debug("syf: "+syf);
|
|
value = ivalue;
|
|
send();
|
|
if (lastsyf != syf) update();
|
|
propagateToChainedControls();
|
|
}
|
|
}
|
|
|
|
class ProgressSegment extends GridSegment {
|
|
Progress owner;
|
|
|
|
ProgressSegment(int ix, int iy, Progress iowner) {
|
|
page = selectedPage;
|
|
//println(this+" on page "+page);
|
|
x = ix;
|
|
y = iy;
|
|
owner = iowner;
|
|
controlID = (int)random(1000);
|
|
grid[y*8+x] = this;
|
|
idlecolor = PROGRESSIDLECOLOR;
|
|
activecolor = PROGRESSACTIVECOLOR;
|
|
off();
|
|
}
|
|
|
|
|
|
void update() {
|
|
if (x == owner.x && y == owner.y) {
|
|
owner.update();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void nakedSetValue(int ivalue) { setValue(ivalue); }
|
|
void setValue(int ivalue) {
|
|
if (x == owner.x && y == owner.y) {
|
|
owner.nakedSetValue(ivalue);
|
|
}
|
|
}
|
|
|
|
void chainTo(Control control, boolean send) {
|
|
owner.chainTo(control, send);
|
|
}
|
|
|
|
void propagateToChainedControls() {
|
|
owner.propagateToChainedControls();
|
|
}
|
|
}
|
|
|
|
class Progress extends Control {
|
|
ProgressSegment[] segments;
|
|
long lastupdate;
|
|
|
|
boolean canUpdate() {
|
|
long now = (new Date()).getTime();
|
|
if (now - lastupdate > updatedelay) {
|
|
lastupdate = now;
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
class XProgress extends Progress {
|
|
int sx;
|
|
int lastsx;
|
|
|
|
XProgress(int ix, int iy, int ixsize) {
|
|
page = selectedPage;
|
|
//println(this+" on page "+page);
|
|
x = ix;
|
|
y = iy;
|
|
xsize = ixsize;
|
|
sx = x;
|
|
lastsx = -1;
|
|
takeover = 0;
|
|
segments = new ProgressSegment[xsize];
|
|
for (int i = 0; i < xsize; i++) {
|
|
segments[i] = new ProgressSegment(x+i, y, this);
|
|
}
|
|
grid[y*8+x].on();
|
|
}
|
|
|
|
void update() {
|
|
//if (lastsx != sx) {
|
|
if (page == selectedPage && canUpdate()) {
|
|
for(int i = 0; i < xsize; i++) {
|
|
if (i <= sx) { grid[y*8+x+i].on(); } else { grid[y*8+x+i].off(); }
|
|
}
|
|
lastsx = sx;
|
|
}
|
|
//}
|
|
}
|
|
|
|
void nakedSetValue(int ivalue) {
|
|
float step = 127 / (xsize-1);
|
|
sx = (int)(ivalue / step);
|
|
value = ivalue;
|
|
propagateToChainedControls();
|
|
}
|
|
|
|
|
|
void setValue(int ivalue) {
|
|
float step = 127 / (xsize-1);
|
|
sx = (int)(ivalue / step);
|
|
value = ivalue;
|
|
send();
|
|
if (lastsx != sx) update();
|
|
propagateToChainedControls();
|
|
}
|
|
}
|
|
|
|
class YProgress extends Progress {
|
|
int sy;
|
|
int lastsy;
|
|
|
|
YProgress(int ix, int iy, int iysize) {
|
|
controlID = (int)random(1000);
|
|
page = selectedPage;
|
|
//println(this+" on page "+page);
|
|
x = ix;
|
|
y = iy;
|
|
ysize = iysize;
|
|
sy = y;
|
|
lastsy = -1;
|
|
value = 0;
|
|
segments = new ProgressSegment[ysize];
|
|
for (int i = 0; i < ysize; i++) {
|
|
segments[i] = new ProgressSegment(x, y - i, this);
|
|
}
|
|
grid[y*8+x].on();
|
|
}
|
|
|
|
void update() {
|
|
//if (lastsy != sy) {
|
|
if (page == selectedPage && canUpdate()) {
|
|
for(int i = y; i > y - ysize; i--) {
|
|
if (i >= sy) { grid[i*8+x].on(); } else { grid[i*8+x].off(); }
|
|
}
|
|
lastsy = sy;
|
|
}
|
|
//}
|
|
}
|
|
|
|
void nakedSetValue(int ivalue) {
|
|
float step = 127 / (ysize-1);
|
|
int rely = ((int)(ivalue / step));
|
|
sy = y - rely;
|
|
value = ivalue;
|
|
propagateToChainedControls();
|
|
}
|
|
|
|
void setValue(int ivalue) {
|
|
float step = 127 / (ysize-1);
|
|
int rely = ((int)(ivalue / step));
|
|
sy = y - rely;
|
|
value = ivalue;
|
|
send();
|
|
if (lastsy != sy) update();
|
|
propagateToChainedControls();
|
|
|
|
}
|
|
}
|
|
|
|
class CrsFaderSegment extends GridSegment {
|
|
CrsFader owner;
|
|
|
|
CrsFaderSegment(int ix, int iy, CrsFader iowner) {
|
|
page = selectedPage;
|
|
//println(this+" on page "+page);
|
|
x = ix;
|
|
y = iy;
|
|
owner = iowner;
|
|
controlID = (int)random(1000);
|
|
grid[y*8+x] = this;
|
|
idlecolor = FADERIDLECOLOR;
|
|
activecolor = FADERACTIVECOLOR;
|
|
off();
|
|
}
|
|
|
|
void down() {
|
|
owner.faderAction(this);
|
|
}
|
|
|
|
void up() {
|
|
owner.stopAction();
|
|
}
|
|
|
|
void update() {
|
|
if (x == owner.x && y == owner.y) {
|
|
owner.update();
|
|
}
|
|
}
|
|
|
|
void send() {
|
|
if (x == owner.x && y == owner.y) {
|
|
owner.send();
|
|
}
|
|
}
|
|
|
|
void nakedSetValue(int ivalue) { setValue(ivalue); }
|
|
void setValue(int ivalue) {
|
|
if (x == owner.x && y == owner.y) {
|
|
owner.nakedSetValue(ivalue);
|
|
}
|
|
}
|
|
|
|
void chainTo(Control control, boolean send) {
|
|
owner.chainTo(control, send);
|
|
}
|
|
|
|
void propagateToChainedControls() {
|
|
owner.propagateToChainedControls();
|
|
}
|
|
}
|
|
|
|
class CrsFader extends Control {
|
|
int sx;
|
|
float sxf;
|
|
int lastsx;
|
|
float lastsxf;
|
|
float factor;
|
|
boolean running;
|
|
CrsFaderSegment[] segments;
|
|
long lastupdate;
|
|
|
|
CrsFader(int ix, int iy, int ixsize) {
|
|
page = selectedPage;
|
|
//println(this+" on page "+page);
|
|
x = ix;
|
|
y = iy;
|
|
xsize = ixsize;
|
|
sx = x;
|
|
lastsx = -1;
|
|
takeover = 0;
|
|
factor = 0;
|
|
running = false;
|
|
segments = new CrsFaderSegment[xsize];
|
|
for (int i = 0; i < xsize; i++) {
|
|
segments[i] = new CrsFaderSegment(x+i, y, this);
|
|
}
|
|
grid[y*8+x].on();
|
|
}
|
|
|
|
void stopAction() {
|
|
running = false;
|
|
factor = 0;
|
|
}
|
|
|
|
void faderAction(CrsFaderSegment sender) {
|
|
if (xsize % 2 != 0) {
|
|
int relx = sender.x - x + 1;
|
|
int center = abs(round(((float)xsize/2)));
|
|
float relpos = ((relx - center)/((float)xsize-1))*2;
|
|
|
|
debug("CrsFader update. Sender x = "+sender.x+", relx="+relx);
|
|
debug("Relative position: "+relpos+", center="+center);
|
|
} else {
|
|
int relx = sender.x - x + 1;
|
|
int center = xsize/2;
|
|
float relpos = 0;
|
|
|
|
if (relx <= center) {
|
|
relpos = (center - (relx-1))/(float)center * -1;
|
|
} else {
|
|
relpos = (relx - center)/(float)center;
|
|
}
|
|
|
|
debug("CrsFader update. Sender x = "+sender.x+", relx="+relx);
|
|
debug("Relative position: "+relpos+", center="+center);
|
|
|
|
factor = relpos;
|
|
if (factor != 0 && !running) {
|
|
running = true;
|
|
spawnThread();
|
|
}
|
|
}
|
|
}
|
|
|
|
void spawnThread() {
|
|
CrsUpdater updater = new CrsUpdater(this);
|
|
}
|
|
|
|
void updateValue() {
|
|
int nvalue = (int)(value+(factor*6));
|
|
if (nvalue < 0) nvalue = 0;
|
|
if (nvalue > 127) nvalue = 127;
|
|
setValue(nvalue);
|
|
}
|
|
|
|
boolean canUpdate() {
|
|
long now = (new Date()).getTime();
|
|
if (now - lastupdate > updatedelay) {
|
|
lastupdate = now;
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void update() {
|
|
|
|
if (canUpdate()) {
|
|
//debug("go");
|
|
if (page == selectedPage) {
|
|
for(int i = 0; i < xsize; i++) {
|
|
|
|
if (i != sx && i != sx+1) {
|
|
grid[y*8+x+i].off();
|
|
}
|
|
|
|
if (i == sx+1 && !(sxf - sx >= 0.56) && !(((sxf - sx) > 0.43 && (sxf - sx) < 0.56) && sx != xsize-1)) {
|
|
grid[y*8+x+i].off();
|
|
}
|
|
|
|
if (i == sx) {
|
|
if (sxf - sx <= 0.43) {
|
|
grid[y*8+x+i].on();
|
|
}
|
|
|
|
if (sxf - sx >= 0.56) {
|
|
grid[y*8+x+(i+1)].on();
|
|
}
|
|
|
|
if (((sxf - sx) > 0.43 && (sxf - sx) < 0.56) && sx != xsize-1) {
|
|
grid[y*8+x+i].on();
|
|
grid[y*8+x+i+1].on();
|
|
}
|
|
}
|
|
|
|
}
|
|
lastsx = sx;
|
|
lastsxf = sxf;
|
|
}
|
|
} else { /*debug("filtered");*/ }
|
|
}
|
|
|
|
|
|
void nakedSetValue(int ivalue) {
|
|
if (!running) {
|
|
float step = 127 / (xsize-1);
|
|
sxf = (ivalue / step);
|
|
//println(sxf);
|
|
sx = (int)sxf;
|
|
value = ivalue;
|
|
propagateToChainedControls();
|
|
} else {
|
|
debug("Blocked because thread is running");
|
|
}
|
|
}
|
|
|
|
|
|
void setValue(int ivalue) {
|
|
float step = 127 / (xsize-1);
|
|
sxf = (ivalue / step);
|
|
//println(sxf);
|
|
sx = (int)sxf;
|
|
value = ivalue;
|
|
send();
|
|
if (lastsxf != sxf) update();
|
|
propagateToChainedControls();
|
|
}
|
|
|
|
void send() {
|
|
controlOut(x, y, value);
|
|
}
|
|
|
|
}
|
|
|
|
|