Skip to content

Commit e1bfa71

Browse files
ES6 ComponentsJS
1 parent c0b4f50 commit e1bfa71

3 files changed

Lines changed: 201 additions & 9 deletions

File tree

res/controllers/engine-api.d.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
21
/** ScriptConnectionJSProxy */
3-
42
declare interface ScriptConnection {
53
/**
64
* Disconnect the script connection,

res/controllers/midi-components-0.0.js

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* Components JS library for Mixxx
33
* Documentation is on the Mixxx wiki at
4-
* http://mixxx.org/wiki/doku.php/components_js
4+
* https://github.com/mixxxdj/mixxx/wiki/Components-JS
55
*
66
* Copyright (C) 2017 Be <be.0@gmx.com>
77
*
@@ -18,12 +18,6 @@
1818
* You should have received a copy of the GNU General Public License
1919
* along with this program; if not, write to the Free Software
2020
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21-
*
22-
*
23-
*
24-
* This library depends on Lodash, which is copyright JS Foundation
25-
* and other contributors and licensed under the MIT license. Refer to
26-
* the lodash.mixxx.js file in this directory for details.
2721
*/
2822

2923
(function(global) {
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
/**
2+
* Components JS library for Mixxx
3+
* Documentation is on the Mixxx wiki at
4+
* https://github.com/mixxxdj/mixxx/wiki/Components-JS
5+
*
6+
* Copyright (C) 2017 Be <be.0@gmx.com>
7+
*
8+
* This program is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU General Public License
10+
* as published by the Free Software Foundation; either version 2
11+
* of the License, or (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* GNU General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU General Public License
19+
* along with this program; if not, write to the Free Software
20+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21+
*/
22+
23+
(function(global) {
24+
/**
25+
* @typedef ComponentOpts
26+
* @property {number=} midiStatus
27+
* @property {number=} midiNo
28+
* @property {string=} group
29+
* @property {string=} inKey
30+
* @property {string=} outKey
31+
* @property {boolean} [outConnect=true]
32+
* @property {boolean} [outTrigger=true]
33+
* @property {number} [max=127]
34+
* @property {number} [shiftOffset=0]
35+
* @property {Component.SendShifted} [sendShifted=Component.SendShifted.NO]
36+
*/
37+
class Component {
38+
/**
39+
* @readonly
40+
* @enum {number}
41+
*/
42+
static SendShifted = Object.freeze({
43+
NO: 0,
44+
CHANNEL: 1,
45+
CONTROL: 2
46+
});
47+
48+
/** @type {ScriptConnection[]} */
49+
#connections = [];
50+
isShifted = false;
51+
52+
/** @param {(ComponentOpts|number[])} options */
53+
constructor(options) {
54+
if (Array.isArray(options)) {
55+
options = {midiStatus: options[0], midiNo: options[1]};
56+
}
57+
58+
/** type {ComponentOpts} */
59+
options = {
60+
midiStatus: undefined,
61+
midiNo: undefined,
62+
group: undefined,
63+
inKey: undefined,
64+
outKey: undefined,
65+
outConnect: true,
66+
outTrigger: true,
67+
max: 127,
68+
shiftOffset: 0,
69+
sendShifted: Component.SendShifted.NO,
70+
...options
71+
};
72+
73+
this.midiStatus = options.midiStatus;
74+
this.midiNo = options.midiNo;
75+
this.group = options.group;
76+
this.inKey = options.inKey;
77+
this.outKey = options.outKey;
78+
this.outConnect = options.outConnect;
79+
this.outTrigger = options.outTrigger;
80+
this.max = options.max;
81+
this.shiftOffset = options.shiftOffset;
82+
this.sendShifted = options.sendShifted;
83+
84+
if (this.outConnect) {
85+
this.connect();
86+
this.outTrigger ? this.trigger() : this.noop();
87+
}
88+
}
89+
90+
noop() { /* Does nothing */ }
91+
92+
inValueScale(value) {
93+
// Hack to get exact center of pots to return 0.5
94+
if (value > (this.max / 2)) {
95+
return (value - 1) / (this.max - 1);
96+
} else {
97+
return value / (this.max + 1);
98+
}
99+
}
100+
101+
input(channel, control, value, _status, _group) {
102+
this.inSetParameter(this.inValueScale(value));
103+
}
104+
105+
outValueScale(value) {
106+
return value * this.max;
107+
}
108+
109+
output(value, _group, _control) {
110+
this.send(this.outValueScale(value));
111+
}
112+
113+
// common functions
114+
// In most cases, you should not overwrite these.
115+
inGetParameter() {
116+
return engine.getParameter(this.group, this.inKey);
117+
}
118+
119+
inSetParameter(value) {
120+
engine.setParameter(this.group, this.inKey, value);
121+
}
122+
123+
inGetValue() {
124+
return engine.getValue(this.group, this.inKey);
125+
}
126+
127+
inSetValue(value) {
128+
engine.setValue(this.group, this.inKey, value);
129+
}
130+
131+
inToggle() {
132+
this.inSetValue(!this.inGetValue());
133+
}
134+
135+
outGetParameter() {
136+
return engine.getParameter(this.group, this.outKey);
137+
}
138+
139+
outSetParameter(value) {
140+
engine.setParameter(this.group, this.outKey, value);
141+
}
142+
143+
outGetValue() {
144+
return engine.getValue(this.group, this.outKey);
145+
}
146+
147+
outSetValue(value) {
148+
engine.setValue(this.group, this.outKey, value);
149+
}
150+
151+
outToggle() {
152+
this.outSetValue(!this.outGetValue());
153+
}
154+
155+
connect() {
156+
/**
157+
Override this method with a custom one to connect multiple Mixxx COs for a single Component.
158+
Add the connection objects to the this.connections array so they all get disconnected just
159+
by calling this.disconnect(). This can be helpful for multicolor LEDs that show a
160+
different color depending on the state of different Mixxx COs. Refer to
161+
SamplerButton.connect() and SamplerButton.output() for an example.
162+
*/
163+
if (this.group === undefined && this.outKey === undefined) {
164+
return;
165+
}
166+
167+
const connection = engine.makeConnection(this.group, this.outKey, this.output);
168+
if (connection !== undefined) {
169+
this.#connections.push(connection);
170+
}
171+
172+
}
173+
174+
disconnect() {
175+
this.#connections.forEach(it => it.disconnect());
176+
}
177+
178+
trigger() {
179+
this.#connections.forEach(it => it.trigger());
180+
}
181+
182+
send(value) {
183+
if (this.midiStatus === undefined || this.midiNo === undefined) {
184+
return;
185+
}
186+
187+
midi.sendShortMsg(this.midiStatus, this.midiNo, value);
188+
189+
if (this.sendShifted === Component.SendShifted.CHANNEL) {
190+
midi.sendShortMsg(this.midiStatus[0] + this.shiftOffset, this.midiNo[1], value);
191+
} else if (this.sendShifted === Component.SendShifted.CONTROL) {
192+
midi.sendShortMsg(this.midiStatus[0], this.midiNo[1] + this.shiftOffset, value);
193+
}
194+
}
195+
}
196+
197+
global.components = Object.freeze({
198+
Component
199+
});
200+
}(this));

0 commit comments

Comments
 (0)