comparison interfaces/ape.js @ 3094:95e946ee225b

Merge branch 'vnext' into Dev_main # Conflicts: # interfaces/ape.js JSHinting Project
author Nicholas Jillings <n.g.r.jillings@se14.qmul.ac.uk>
date Fri, 12 Jan 2018 16:11:20 +0000
parents d70a2d48d635 68e5a789702f
children 20de79c56ad7
comparison
equal deleted inserted replaced
3092:30ba1b9ed867 3094:95e946ee225b
2 * ape.js 2 * ape.js
3 * Create the APE interface 3 * Create the APE interface
4 */ 4 */
5 5
6 /*globals window,interfaceContext, document, audioEngineContext, console, $, Interface, testState, storage, specification */ 6 /*globals window,interfaceContext, document, audioEngineContext, console, $, Interface, testState, storage, specification */
7 /*globals metricTracker */ 7 /*globals metricTracker, module, randomiseOrder */
8 // Once this is loaded and parsed, begin execution 8 // Once this is loaded and parsed, begin execution
9 loadInterface(); 9 loadInterface();
10 10
11 function loadInterface() { 11 function loadInterface() {
12 12
216 //testWaitIndicator(); 216 //testWaitIndicator();
217 module.resize(); 217 module.resize();
218 } 218 }
219 219
220 function ape() { 220 function ape() {
221 var axis = [] 221 var axis = [];
222 var DOMRoot = document.getElementById("slider-holder"); 222 var DOMRoot = document.getElementById("slider-holder");
223 var AOIs = []; 223 var AOIs = [];
224 var page = undefined; 224 var page;
225 225
226 function audioObjectInterface(audioObject, parent) { 226 function audioObjectInterface(audioObject, parent) {
227 // The audioObject communicates with this object 227 // The audioObject communicates with this object
228 var playing = false; 228 var playing = false;
229 var sliders = []; 229 var sliders = [];
230 this.enable = function () { 230 this.enable = function () {
231 sliders.forEach(function (s) { 231 sliders.forEach(function (s) {
232 s.enable(); 232 s.enable();
233 }); 233 });
234 } 234 };
235 235
236 this.updateLoading = function (p) { 236 this.updateLoading = function (p) {
237 sliders.forEach(function (s) { 237 sliders.forEach(function (s) {
238 s.updateLoading(p); 238 s.updateLoading(p);
239 }); 239 });
240 } 240 };
241 241
242 this.startPlayback = function () { 242 this.startPlayback = function () {
243 playing = true; 243 playing = true;
244 sliders.forEach(function (s) { 244 sliders.forEach(function (s) {
245 s.playing(); 245 s.playing();
246 }); 246 });
247 } 247 };
248 248
249 this.stopPlayback = function () { 249 this.stopPlayback = function () {
250 playing = false; 250 playing = false;
251 sliders.forEach(function (s) { 251 sliders.forEach(function (s) {
252 s.stopped(); 252 s.stopped();
253 }); 253 });
254 } 254 };
255 255
256 this.getValue = function () { 256 this.getValue = function () {
257 return sliders[0].value; 257 return sliders[0].value;
258 } 258 };
259 259
260 this.getPresentedId = function () { 260 this.getPresentedId = function () {
261 return sliders[0].label; 261 return sliders[0].label;
262 } 262 };
263 263
264 this.canMove = function () { 264 this.canMove = function () {
265 return true; 265 return true;
266 } 266 };
267 267
268 this.exportXMLDOM = function (audioObject) { 268 this.exportXMLDOM = function (audioObject) {
269 var elements = []; 269 var elements = [];
270 sliders.forEach(function (s) { 270 sliders.forEach(function (s) {
271 elements.push(s.exportXMLDOM()); 271 elements.push(s.exportXMLDOM());
272 }); 272 });
273 return elements; 273 return elements;
274 } 274 };
275 275
276 this.error = function () { 276 this.error = function () {
277 sliders.forEach(function (s) { 277 sliders.forEach(function (s) {
278 s.error(); 278 s.error();
279 }); 279 });
280 } 280 };
281 281
282 this.addSlider = function (s) { 282 this.addSlider = function (s) {
283 sliders.push(s); 283 sliders.push(s);
284 } 284 };
285 285
286 this.clicked = function (event) { 286 this.clicked = function (event) {
287 if (!playing) { 287 if (!playing) {
288 audioEngineContext.play(audioObject.id); 288 audioEngineContext.play(audioObject.id);
289 } else { 289 } else {
290 audioEngineContext.stop(); 290 audioEngineContext.stop();
291 } 291 }
292 playing = !playing; 292 playing = !playing;
293 } 293 };
294 294
295 this.pageXMLSave = function (store) { 295 this.pageXMLSave = function (store) {
296 var inject = audioObject.storeDOM.getElementsByTagName("metric")[0]; 296 var inject = audioObject.storeDOM.getElementsByTagName("metric")[0];
297 sliders.forEach(function (s) { 297 sliders.forEach(function (s) {
298 s.pageXMLSave(inject); 298 s.pageXMLSave(inject);
299 }); 299 });
300 } 300 };
301 301
302 } 302 }
303 303
304 function axisObject(interfaceObject, parent) { 304 function axisObject(interfaceObject, parent) {
305 305
314 trackObj.appendChild(labelHolder); 314 trackObj.appendChild(labelHolder);
315 axisInterface.sliderRail.appendChild(trackObj); 315 axisInterface.sliderRail.appendChild(trackObj);
316 metric.initialise(this.value); 316 metric.initialise(this.value);
317 this.setLabel = function (s) { 317 this.setLabel = function (s) {
318 label = s; 318 label = s;
319 } 319 };
320 this.resize = function (event) { 320 this.resize = function (event) {
321 var width = $(axisInterface.sliderRail).width(); 321 var width = $(axisInterface.sliderRail).width();
322 var w = Number(value * width); 322 var w = Number(value * width);
323 trackObj.style.left = String(w) + "px"; 323 trackObj.style.left = String(w) + "px";
324 } 324 };
325 this.playing = function () { 325 this.playing = function () {
326 trackObj.classList.add("track-slider-playing"); 326 trackObj.classList.add("track-slider-playing");
327 } 327 };
328 this.stopped = function () { 328 this.stopped = function () {
329 trackObj.classList.remove("track-slider-playing"); 329 trackObj.classList.remove("track-slider-playing");
330 } 330 };
331 this.enable = function () { 331 this.enable = function () {
332 trackObj.addEventListener("mousedown", this); 332 trackObj.addEventListener("mousedown", this);
333 trackObj.addEventListener("mouseup", this); 333 trackObj.addEventListener("mouseup", this);
334 trackObj.classList.remove("track-slider-disabled"); 334 trackObj.classList.remove("track-slider-disabled");
335 labelHolder.textContent = label; 335 labelHolder.textContent = label;
336 } 336 };
337 this.updateLoading = function (progress) { 337 this.updateLoading = function (progress) {
338 labelHolder.textContent = progress + "%"; 338 labelHolder.textContent = progress + "%";
339 } 339 };
340 this.exportXMLDOM = function () { 340 this.exportXMLDOM = function () {
341 var node = storage.document.createElement('value'); 341 var node = storage.document.createElement('value');
342 node.setAttribute("interface-name", axisInterface.name) 342 node.setAttribute("interface-name", axisInterface.name);
343 node.textContent = this.value; 343 node.textContent = this.value;
344 return node; 344 return node;
345 } 345 };
346 this.error = function () { 346 this.error = function () {
347 trackObj.classList.add("error-colour"); 347 trackObj.classList.add("error-colour");
348 trackObj.removeEventListener("mousedown"); 348 trackObj.removeEventListener("mousedown");
349 trackObj.removeEventListener("mouseup"); 349 trackObj.removeEventListener("mouseup");
350 } 350 };
351 var timing = undefined; 351 var timing;
352 this.handleEvent = function (e) { 352 this.handleEvent = function (e) {
353 // This is only for the mousedown / touchdown 353 // This is only for the mousedown / touchdown
354 if (e.preventDefault) { 354 if (e.preventDefault) {
355 e.preventDefault(); 355 e.preventDefault();
356 } 356 }
359 } else if (e.type == "mouseup" || e.type == "touchend" || e.type == "touchcancel") { 359 } else if (e.type == "mouseup" || e.type == "touchend" || e.type == "touchcancel") {
360 axisInterface.mouseup(this); 360 axisInterface.mouseup(this);
361 metric.moved(audioEngineContext.timer.getTestTime(), this.value); 361 metric.moved(audioEngineContext.timer.getTestTime(), this.value);
362 console.log("Slider " + label + " on axis " + axisInterface.name + " moved to " + this.value); 362 console.log("Slider " + label + " on axis " + axisInterface.name + " moved to " + this.value);
363 } 363 }
364 } 364 };
365 this.clicked = function (e) { 365 this.clicked = function (e) {
366 AOI.clicked(); 366 AOI.clicked();
367 } 367 };
368 this.pageXMLSave = function (inject) { 368 this.pageXMLSave = function (inject) {
369 var nodes = metric.exportXMLDOM(inject); 369 var nodes = metric.exportXMLDOM(inject);
370 nodes.forEach(function (elem) { 370 nodes.forEach(function (elem) {
371 var name = elem.getAttribute("name"); 371 var name = elem.getAttribute("name");
372 if (name == "elementTracker" || name == "elementTrackerFull" || name == "elementInitialPosition" || name == "elementFlagMoved") { 372 if (name == "elementTracker" || name == "elementTrackerFull" || name == "elementInitialPosition" || name == "elementFlagMoved") {
373 elem.setAttribute("interface-name", axisInterface.name); 373 elem.setAttribute("interface-name", axisInterface.name);
374 } else { 374 } else {
375 inject.removeChild(elem); 375 inject.removeChild(elem);
376 } 376 }
377 }); 377 });
378 } 378 };
379 this.hasMoved = function () { 379 this.hasMoved = function () {
380 return metric.wasMoved; 380 return metric.wasMoved;
381 } 381 };
382 Object.defineProperties(this, { 382 Object.defineProperties(this, {
383 "DOM": { 383 "DOM": {
384 "value": trackObj 384 "value": trackObj
385 }, 385 },
386 "value": { 386 "value": {
448 } 448 }
449 var sliders = []; 449 var sliders = [];
450 var UI = { 450 var UI = {
451 selected: undefined, 451 selected: undefined,
452 startTime: undefined 452 startTime: undefined
453 } 453 };
454 this.name = interfaceObject.name; 454 this.name = interfaceObject.name;
455 var DOMRoot = document.createElement("div"); 455 var DOMRoot = document.createElement("div");
456 parent.getDOMRoot().appendChild(DOMRoot); 456 parent.getDOMRoot().appendChild(DOMRoot);
457 DOMRoot.className = "sliderCanvasDiv"; 457 DOMRoot.className = "sliderCanvasDiv";
458 DOMRoot.id = "sliderCanvasHolder-" + this.name; 458 DOMRoot.id = "sliderCanvasHolder-" + this.name;
459 var sliders = [];
460 459
461 var axisTitle = document.createElement("div"); 460 var axisTitle = document.createElement("div");
462 axisTitle.className = "pageTitle"; 461 axisTitle.className = "pageTitle";
463 axisTitle.align = "center"; 462 axisTitle.align = "center";
464 var titleSpan = document.createElement('span'); 463 var titleSpan = document.createElement('span');
525 }); 524 });
526 scale.innerHTML = ""; 525 scale.innerHTML = "";
527 tickCanvas.width = $(sliderRail).width(); 526 tickCanvas.width = $(sliderRail).width();
528 tickCanvas.style.width = tickCanvas.width + "px"; 527 tickCanvas.style.width = tickCanvas.width + "px";
529 createScaleMarkers(interfaceObject, scale, $(sliderRail).width()); 528 createScaleMarkers(interfaceObject, scale, $(sliderRail).width());
530 } 529 };
531 this.playing = function (id) { 530 this.playing = function (id) {
532 var node = audioEngineContext.audioObjects.find(function (a) { 531 var node = audioEngineContext.audioObjects.find(function (a) {
533 return a.id == id; 532 return a.id == id;
534 }); 533 });
535 if (node === undefined) { 534 if (node === undefined) {
536 this.imageHolder.setImage(interfaceObject.image || ""); 535 this.imageHolder.setImage(interfaceObject.image || "");
537 return; 536 return;
538 } 537 }
539 var imgurl = node.specification.image || interfaceObject.image || ""; 538 var imgurl = node.specification.image || interfaceObject.image || "";
540 this.imageHolder.setImage(imgurl); 539 this.imageHolder.setImage(imgurl);
541 } 540 };
542 this.stopped = function () { 541 this.stopped = function () {
543 var imgurl = interfaceObject.image || ""; 542 var imgurl = interfaceObject.image || "";
544 this.imageHolder.setImage(imgurl); 543 this.imageHolder.setImage(imgurl);
545 } 544 };
546 this.addSlider = function (aoi) { 545 this.addSlider = function (aoi) {
547 var node = new sliderInterface(aoi, this); 546 var node = new sliderInterface(aoi, this);
548 sliders.push(node); 547 sliders.push(node);
549 return node; 548 return node;
550 } 549 };
551 this.mousedown = function (sliderUI) { 550 this.mousedown = function (sliderUI) {
552 UI.selected = sliderUI; 551 UI.selected = sliderUI;
553 UI.startTime = new Date(); 552 UI.startTime = new Date();
554 } 553 };
555 this.mouseup = function (event) { 554 this.mouseup = function (event) {
556 var delta = new Date() - UI.startTime; 555 var delta = new Date() - UI.startTime;
557 if (delta < 200) { 556 if (delta < 200) {
558 UI.selected.clicked(); 557 UI.selected.clicked();
559 } else if (event.type == "touchend" || event.type == "touchcancel") { 558 } else if (event.type == "touchend" || event.type == "touchcancel") {
560 UI.selected.handleEvent(event); 559 UI.selected.handleEvent(event);
561 } 560 }
562 UI.selected = undefined; 561 UI.selected = undefined;
563 UI.startTime = undefined; 562 UI.startTime = undefined;
564 } 563 };
565 this.handleEvent = function (event) { 564 this.handleEvent = function (event) {
566 function getTargetSlider(target) { 565 function getTargetSlider(target) {
567 return sliders.find(function (a) { 566 return sliders.find(function (a) {
568 return a.DOM == target; 567 return a.DOM == target;
569 }); 568 });
607 } else if (event.type == "touchend" || event.type == "touchcancel") { 606 } else if (event.type == "touchend" || event.type == "touchcancel") {
608 if (UI.selected == getTargetSlider(event.target)) { 607 if (UI.selected == getTargetSlider(event.target)) {
609 this.mouseup(event); 608 this.mouseup(event);
610 } 609 }
611 } 610 }
612 } 611 };
613 this.checkAllMoved = function () { 612 this.checkAllMoved = function () {
614 var notMoved = sliders.filter(function (s) { 613 var notMoved = sliders.filter(function (s) {
615 return !s.hasMoved(); 614 return !s.hasMoved();
616 }); 615 });
617 if (notMoved.length !== 0) { 616 if (notMoved.length !== 0) {
618 var ls = []; 617 var ls = [];
619 notMoved.forEach(function (s) { 618 notMoved.forEach(function (s) {
620 ls.push(s.label); 619 ls.push(s.label);
621 }) 620 });
622 var str = "On axis \"" + interfaceObject.title + "\", "; 621 var str = "On axis \"" + interfaceObject.title + "\", ";
623 if (ls.length == 1) { 622 if (ls.length == 1) {
624 str += "slider " + ls[0]; 623 str += "slider " + ls[0];
625 } else { 624 } else {
626 str += "sliders " + [ls.slice(0, ls.length - 1).join(", ")].concat(ls[ls.length - 1]).join(" and "); 625 str += "sliders " + [ls.slice(0, ls.length - 1).join(", ")].concat(ls[ls.length - 1]).join(" and ");
628 str += "."; 627 str += ".";
629 return str; 628 return str;
630 } else { 629 } else {
631 return ""; 630 return "";
632 } 631 }
633 } 632 };
634 this.checkScaleRange = function () { 633 this.checkScaleRange = function () {
635 var scaleRange = interfaceObject.options.find(function (a) { 634 var scaleRange = interfaceObject.options.find(function (a) {
636 return a.name == "scalerange"; 635 return a.name == "scalerange";
637 }); 636 });
638 if (scaleRange === undefined) { 637 if (scaleRange === undefined) {
650 }, 100); 649 }, 100);
651 if (minSlider >= scales.min || maxSlider <= scales.max) { 650 if (minSlider >= scales.min || maxSlider <= scales.max) {
652 return "On axis \"" + interfaceObject.title + "\", you have not used the required width of the scales"; 651 return "On axis \"" + interfaceObject.title + "\", you have not used the required width of the scales";
653 } 652 }
654 return ""; 653 return "";
655 } 654 };
656 sliderRail.addEventListener("mousemove", this); 655 sliderRail.addEventListener("mousemove", this);
657 sliderRail.addEventListener("touchstart", this); 656 sliderRail.addEventListener("touchstart", this);
658 sliderRail.addEventListener("touchmove", this); 657 sliderRail.addEventListener("touchmove", this);
659 sliderRail.addEventListener("touchend", this); 658 sliderRail.addEventListener("touchend", this);
660 sliderRail.addEventListener("touchcancel", this); 659 sliderRail.addEventListener("touchcancel", this);
664 } 663 }
665 }); 664 });
666 } 665 }
667 this.getDOMRoot = function () { 666 this.getDOMRoot = function () {
668 return DOMRoot; 667 return DOMRoot;
669 } 668 };
670 this.getPage = function () { 669 this.getPage = function () {
671 return page; 670 return page;
672 } 671 };
673 this.clear = function () { 672 this.clear = function () {
674 page = undefined; 673 page = undefined;
675 axis = []; 674 axis = [];
676 AOIs = []; 675 AOIs = [];
677 DOMRoot.innerHTML = ""; 676 DOMRoot.innerHTML = "";
678 } 677 };
679 this.initialisePage = function (page_init) { 678 this.initialisePage = function (page_init) {
680 this.clear(); 679 this.clear();
681 page = page_init; 680 page = page_init;
682 var randomiseAxisOrder; 681 var randomiseAxisOrder;
683 if (page.randomiseAxisOrder !== undefined) { 682 if (page.randomiseAxisOrder !== undefined) {
721 if (commentBoxes) { 720 if (commentBoxes) {
722 interfaceContext.commentBoxes.createCommentBox(audioObject); 721 interfaceContext.commentBoxes.createCommentBox(audioObject);
723 } 722 }
724 } 723 }
725 }); 724 });
726 } 725 };
727 this.checkAllMoved = function () { 726 this.checkAllMoved = function () {
728 var str = "You have not moved the following sliders. " 727 var str = "You have not moved the following sliders. ";
729 var cont = true; 728 var cont = true;
730 axis.forEach(function (a) { 729 axis.forEach(function (a) {
731 var msg = a.checkAllMoved(); 730 var msg = a.checkAllMoved();
732 if (msg.length > 0) { 731 if (msg.length > 0) {
733 cont = false; 732 cont = false;
738 interfaceContext.lightbox.post("Error", str); 737 interfaceContext.lightbox.post("Error", str);
739 interfaceContext.storeErrorNode(str); 738 interfaceContext.storeErrorNode(str);
740 console.log(str); 739 console.log(str);
741 } 740 }
742 return cont; 741 return cont;
743 } 742 };
744 this.checkScaleRange = function () { 743 this.checkScaleRange = function () {
745 var str = ""; 744 var str = "";
746 var cont = true; 745 var cont = true;
747 axis.forEach(function (a) { 746 axis.forEach(function (a) {
748 var msg = a.checkScaleRange(); 747 var msg = a.checkScaleRange();
755 interfaceContext.lightbox.post("Error", str); 754 interfaceContext.lightbox.post("Error", str);
756 interfaceContext.storeErrorNode(str); 755 interfaceContext.storeErrorNode(str);
757 console.log(str); 756 console.log(str);
758 } 757 }
759 return cont; 758 return cont;
760 } 759 };
761 this.pageXMLSave = function (store, pageSpecification) { 760 this.pageXMLSave = function (store, pageSpecification) {
762 if (axis.length > 1) { 761 if (axis.length > 1) {
763 AOIs.forEach(function (ao) { 762 AOIs.forEach(function (ao) {
764 ao.pageXMLSave(store); 763 ao.pageXMLSave(store);
765 }); 764 });
766 } 765 }
767 } 766 };
768 this.resize = function (event) { 767 this.resize = function (event) {
769 axis.forEach(function (a) { 768 axis.forEach(function (a) {
770 a.resize(event); 769 a.resize(event);
771 }); 770 });
772 } 771 };
773 } 772 }
774 773
775 function outsideReferenceDOM(audioObject, index, inject) { 774 function outsideReferenceDOM(audioObject, index, inject) {
776 this.parent = audioObject; 775 this.parent = audioObject;
777 this.outsideReferenceHolder = document.createElement('div'); 776 this.outsideReferenceHolder = document.createElement('div');