diff --git a/plugins/qlab/cue.ejs b/plugins/qlab/cue.ejs
index b7809f6..e3547f1 100644
--- a/plugins/qlab/cue.ejs
+++ b/plugins/qlab/cue.ejs
@@ -2,7 +2,7 @@
<% let playbackPosition = workspace.playbackPosition==cue.uniqueID ? "playback-position" : "" %>
<% let selected = workspace.selected.includes(cue.uniqueID) ? "selected": "" %>
-<% if(cueKeys && cueKeys.parent && cueKeys.nestedGroupPosition){ %>
+<% if(cueKeys && cueKeys.parent){ %>
@@ -48,38 +48,54 @@
| <%= cueKeys.number || " " %> |
+ <% let nextCue = cueKeys.cueInWorkspace.parent.cues[cueKeys.cueInWorkspace.sortIndex+1]; %>
- <% for(let i=0; i
+ <% for(let i=0; i
+ <% let parent = cueKeys.parentKeys[i+1]; %>
+ <% %>
- <% if(cue.type=="Group" && cue.cues.length==0 && i==cueKeys.nestedGroupModes.length-1){ %>
- |
-
- <% }else if(cue.type=="Group" && i==cueKeys.nestedGroupModes.length-1){ %>
- |
+ <% if(cueKeys.type=="Group" && cueKeys.cues.length==0 && i==cueKeys.parentKeys.length-1){ %>
+ |
- <% }else if(cueKeys.nestedGroupPosition[i]<=0){ %>
- <% if(cueKeys.nestedGroupPosition.slice(i+1).every(v => v === 0)){ %>
- |
+ <% }else if(cueKeys.type=="Group" && i==cueKeys.parentKeys.length-1){ %>
+ |
+
+ <%}else if(parent){%>
+
+ <% let parentCues = parent.cueInWorkspace.cues %>
+ <% let lastCueInMe = parentCues[parentCues.length-1]%>
+
+ <% while(lastCueInMe.type=="Group" && lastCueInMe.cues.length){
+ parentCues = lastCueInMe.cues;
+ lastCueInMe = parentCues[parentCues.length-1];
+ } %>
+
+ <% if(lastCueInMe.uniqueID == cueKeys.uniqueID){ %>
+ x |
<% }else{ %>
- |
+ |
+
<% } %>
- <% }else if(i
- |
- <% }else if(cueKeys.nestedGroupPosition[i]==undefined && cueKeys.nestedGroupPosition[i-1]==0){ %>
- |
+ <% }else if(cueKeys.parentKeys[i]){ %>
+ <% let nextCue2 = cueKeys.parentKeys[i].cues[cueKeys.cueInWorkspace.sortIndex+1]; %>
+
+ <% if(!nextCue2){ %>
+ |
+
+ <% }else{ %>
+ |
+
+ <% } %>
- <% }else{ %>
- |
<% } %>
-
- <% } %>
+ <% } %>
@@ -87,19 +103,19 @@
<% if(cue.type=="Group"){ %>
- <% if(cue.cues.length==0){ %>
- <%= cueKeys.listName %> |
+ <% if(cue.cues && cue.cues.length==0){ %>
+ <%= cueKeys.listName %> |
<% }else{ %>
- <%= cueKeys.listName %> |
+ <%= cueKeys.listName %> |
<% } %>
- <% }else if(cueKeys.nestedGroupPosition[cueKeys.nestedGroupModes.length-2]==0){ %>
- <%= cueKeys.listName %> |
+ <% }else if(!nextCue){ %>
+ <%= cueKeys.listName %> |
<% }else{ %>
- <%= cueKeys.listName %> |
+ <%= cueKeys.listName %> |
<% } %>
diff --git a/plugins/qlab/cuelist.ejs b/plugins/qlab/cuelist.ejs
index a3d64f8..558e420 100644
--- a/plugins/qlab/cuelist.ejs
+++ b/plugins/qlab/cuelist.ejs
@@ -6,8 +6,8 @@
|
|
Number |
- |
Name |
+ |
|
|
|
diff --git a/plugins/qlab/main.js b/plugins/qlab/main.js
index eaee39e..ad9037b 100644
--- a/plugins/qlab/main.js
+++ b/plugins/qlab/main.js
@@ -100,9 +100,7 @@ exports.data = function data(_device, oscData) {
device.send(`/workspace/${msgAddr[2]}/updates`, [{ type: 'i', value: 1 }]);
}
} else if (/reply\/workspace\/.*\/cueLists/.test(oscData.address)) {
- device.data.workspaces[msgAddr[2]].cueLists = json.data;
- processCueList(device.data.workspaces[msgAddr[2]].cueLists, Object.keys(device.data.cueKeys), device, []);
- device.draw();
+ insertChildCues(device, device.data.workspaces[msgAddr[2]].cueLists, json.data, '[root group of cue lists]');
} else if (/reply\/cue_id\/.*\/valuesForKeys/.test(oscData.address)) {
const keyValues = json.data;
let cue = device.data.cueKeys[msgAddr[2]];
@@ -143,29 +141,22 @@ exports.data = function data(_device, oscData) {
device.data.lastElapsedMessage = device.data.ticks;
}
- let testCue = device.data.cueKeys[msgAddr[2]];
- let nestedGroupModes;
-
- if (cue.type === 'Group') {
- nestedGroupModes = [testCue.mode];
- } else if (cue.parent !== '[root group of cue lists]') {
- nestedGroupModes = [device.data.cueKeys[cue.parent].mode];
+ if (cue.parent !== '[root group of cue lists]') {
+ cue.parent = device.data.cueKeys[cue.parent];
}
- while (testCue.parent !== '[root group of cue lists]') {
- testCue = device.data.cueKeys[testCue.parent];
- if (testCue === undefined) {
- break;
- }
-
- nestedGroupModes.unshift(testCue.mode);
- cue.nestedGroupModes = nestedGroupModes;
- }
if (cue.type === 'Cue List' || cue.type === 'Group' || cue.type === 'Cart') {
- if (device.data.cueKeys[msgAddr[2]].cueInWorkspace) {
- device.data.cueKeys[msgAddr[2]].cueInWorkspace.cues = [...keyValues.children];
+ if (device.data.cueKeys[msgAddr[2]].cueInWorkspace && cue.cues) {
+ insertChildCues(
+ device,
+ device.data.cueKeys[msgAddr[2]].cueInWorkspace.cues,
+ [...keyValues.children],
+ device.data.cueKeys[msgAddr[2]].cueInWorkspace
+ );
}
+ device.draw();
}
+
if (cue.type !== 'Cue List' && cue.type !== 'Cart') {
device.update('updateCueRow', { cue, workspace: device.data.workspaces[json.workspace_id] });
}
@@ -201,24 +192,8 @@ exports.data = function data(_device, oscData) {
workspace.selected.push(json.data[i].uniqueID);
}
device.update('updatePlaybackAndSelected', { workspace: device.data.workspaces[json.workspace_id] });
- } else if (/reply\/(workspace\/.*\/)?cue_id\/(.*)\/children/.test(oscData.address)) {
- // qlab 4 leaves off the workspace/ portion of the address this regex handles that
- const addressMatch = oscData.address.match(/reply\/(workspace\/.*\/)?cue_id\/(.*)\/children/);
- // trying to use .cueInWorkspace to reference the related cue in data.workspaces
- device.data.cueKeys[addressMatch[2]].cueInWorkspace.cues = [...json.data];
- console.log(device.data.cueKeys[addressMatch[2]].cueInWorkspace.cues);
-
- device.draw();
} else if (/update\/workspace\/.*\/cue_id\/.*/.test(oscData.address)) {
- if (device.data.cueKeys[msgAddr[4]] && device.data.cueKeys[msgAddr[4]].type === 'Group') {
- device.send(`/workspace/${msgAddr[2]}/cue_id/${msgAddr[4]}/children/`);
- } else if (device.data.cueKeys[msgAddr[4]] && device.data.cueKeys[msgAddr[4]].type === 'Cue List') {
- device.send(`/workspace/${msgAddr[2]}/cueLists`);
- } else if (device.data.cueKeys[msgAddr[4]] && device.data.cueKeys[msgAddr[4]].type === 'Cart') {
- device.send(`/workspace/${msgAddr[2]}/cueLists`);
- } else {
- device.send(`/cue_id/${msgAddr[4]}/valuesForKeys`, [{ type: 's', value: valuesForKeysString }]);
- }
+ device.send(`/cue_id/${msgAddr[4]}/valuesForKeys`, [{ type: 's', value: valuesForKeysString }]);
} else if (/update\/workspace\/.*\/cueList\/.*\/playbackPosition/.test(oscData.address)) {
const workspace = device.data.workspaces[msgAddr[2]];
if (workspace) {
@@ -231,46 +206,12 @@ exports.data = function data(_device, oscData) {
}
};
-function processCueList(list, knownCueIDs, _device, _nestedIndex) {
- const nestedIndex = _nestedIndex;
- const device = _device;
-
- for (let i = 0; i < list.length; i++) {
- const cue = list[i];
- nestedIndex[nestedIndex.length - 1] = list.length - i - 1;
-
- if (!knownCueIDs.includes(cue.uniqueID)) {
- device.send(`/cue_id/${cue.uniqueID}/valuesForKeys`, [{ type: 's', value: valuesForKeysString }]);
- }
-
- if (cue.cues?.length > 0) {
- const nest2 = [..._nestedIndex];
- nest2.push(cue.cues.length);
- processCueList(cue.cues, knownCueIDs, device, nest2);
- for (let j = 0; j < nestedIndex.length; j++) {
- nestedIndex[j]++;
- }
- }
-
- if (!knownCueIDs.includes(cue.uniqueID)) {
- device.data.cueKeys[cue.uniqueID] = {
- nestedGroupPosition: [...nestedIndex],
- };
- } else {
- device.data.cueKeys[cue.uniqueID].nestedGroupPosition = [...nestedIndex];
- }
-
- // working theory is that list[i] is a new object rather pointing to the object within data.workspaces
- device.data.cueKeys[cue.uniqueID].cueInWorkspace = list[i];
- }
-}
-
exports.update = function update(device, _doc, updateType, data) {
const doc = _doc;
if (updateType === 'updateCueRow') {
const $elem = doc.getElementById(data.cue.uniqueID);
if ($elem) {
- if (device.data.cueKeys[data.cue.parent].type === 'Cart') {
+ if (data.cue.parent.type === 'Cart') {
$elem.outerHTML = device.templates.tile({
allCues: device.data.cueKeys,
cue: data.cue,
@@ -311,7 +252,7 @@ exports.update = function update(device, _doc, updateType, data) {
}
const cue = device.data.cueKeys[data.workspace.playbackPosition];
- if (cue) {
+ if (cue && $playheadName) {
$playheadName.setAttribute('class', `playhead-name cartColor-${cue.colorName} playhead-disarmed`);
$playheadInfo.classList.add('playhead-active');
if (cue.number) {
@@ -339,7 +280,8 @@ exports.update = function update(device, _doc, updateType, data) {
}
};
-exports.heartbeat = function heartbeat(device) {
+exports.heartbeat = function heartbeat(_device) {
+ const device = _device;
device.data.ticks++;
if (device.data.ticks % 10 === 0) {
device.send(`/thump`);
@@ -350,3 +292,97 @@ exports.heartbeat = function heartbeat(device) {
device.send(`/cue_id/active/actionElapsed`);
}
};
+
+function insertChildCues(_device, _oldCues, newCues, _parent) {
+ const device = _device;
+ const newIDs = _.keyBy(newCues, 'uniqueID');
+ const oldCues = _oldCues;
+ const parent = _parent;
+
+ if (!oldCues) {
+ return;
+ }
+
+ for (let i = 0; i < oldCues.length; i++) {
+ const oldCue = oldCues[i];
+
+ if (!newIDs[oldCue.uniqueID]) {
+ oldCues.splice(i, 1);
+ i--;
+ }
+
+ const indexOfOldCueInNew = _.findIndex(newCues, (o) => o.uniqueID === oldCue.uniqueID);
+
+ if (indexOfOldCueInNew >= 0) {
+ const newCue = newCues[indexOfOldCueInNew];
+ oldCues[i].armed = newCue.armed;
+ oldCues[i].colorName = newCue.colorName;
+ oldCues[i].colorNameLive = newCue['colorName/live'];
+
+ oldCues[i].flagged = newCue.flagged;
+ oldCues[i].listName = newCue.listName;
+ oldCues[i].name = newCue.name;
+ oldCues[i].number = newCue.number;
+ oldCues[i].type = newCue.type;
+ oldCues[i].sortIndex = indexOfOldCueInNew;
+ oldCues[i].parent = parent;
+
+ newCue.used = true;
+
+ let keys = device.data.cueKeys[oldCues[i].uniqueID];
+ if (!keys) {
+ device.data.cueKeys[oldCues[i].uniqueID] = {};
+ keys = device.data.cueKeys[oldCues[i].uniqueID];
+ }
+
+ keys.cueInWorkspace = oldCues[i];
+
+ if (oldCues[i].type === 'Group' || oldCues[i].type === 'Cue List' || oldCues[i].type === 'Cart') {
+ insertChildCues(device, oldCues[i].cues, newCue.cues, oldCues[i]);
+ }
+ }
+ }
+ for (let i = 0; i < newCues.length; i++) {
+ const newCue = newCues[i];
+ if (newCue.used !== true) {
+ const newIndex = oldCues.push({
+ armed: newCue.armed,
+ colorName: newCue.colorName,
+ colorNameLive: newCue['colorName/live'],
+ flagged: newCue.flagged,
+ listName: newCue.listName,
+ name: newCue.name,
+ number: newCue.number,
+ type: newCue.type,
+ uniqueID: newCue.uniqueID,
+ sortIndex: i,
+ parent,
+ });
+
+ const freshCue = oldCues[newIndex - 1];
+
+ let keys = device.data.cueKeys[freshCue.uniqueID];
+ if (!keys) {
+ device.data.cueKeys[freshCue.uniqueID] = {};
+ keys = device.data.cueKeys[freshCue.uniqueID];
+ }
+
+ if (freshCue.parent === '[root group of cue lists]') {
+ keys.parentKeys = [];
+ } else {
+ keys.parentKeys = [...device.data.cueKeys[freshCue.parent.uniqueID].parentKeys];
+ keys.parentKeys.push(device.data.cueKeys[freshCue.parent.uniqueID]);
+ }
+
+ device.send(`/cue_id/${newCue.uniqueID}/valuesForKeys`, [{ type: 's', value: valuesForKeysString }]);
+
+ keys.cueInWorkspace = freshCue;
+
+ if (freshCue.type === 'Group' || freshCue.type === 'Cue List' || oldCues[i].type === 'Cart') {
+ freshCue.cues = [];
+ insertChildCues(device, freshCue.cues, newCue.cues, freshCue);
+ }
+ }
+ }
+ oldCues.sort((a, b) => a.sortIndex - b.sortIndex);
+}
diff --git a/plugins/qlab/tile.ejs b/plugins/qlab/tile.ejs
index 82134c7..df8d5f6 100644
--- a/plugins/qlab/tile.ejs
+++ b/plugins/qlab/tile.ejs
@@ -7,8 +7,8 @@
let parent = allCues[cue.parent];
if(cueKeys.parent){
- width = 100/allCues[cueKeys.parent].cartColumns;
- height = 600/allCues[cueKeys.parent].cartRows;
+ width = 100/cueKeys.parent.cartColumns;
+ height = 600/cueKeys.parent.cartRows;
top = (cueKeys.cartPosition[0]-1)*height;
left = (cueKeys.cartPosition[1]-1)*width;