comparison interfaces/ape.js @ 2538:464c6c6692d6

Beautified entire project.
author Nicholas Jillings <nicholas.jillings@mail.bcu.ac.uk>
date Mon, 14 Nov 2016 14:17:03 +0000
parents 1647bb807186
children 2d820b7413a7
comparison
equal deleted inserted replaced
2536:527020a63203 2538:464c6c6692d6
6 6
7 // Once this is loaded and parsed, begin execution 7 // Once this is loaded and parsed, begin execution
8 loadInterface(); 8 loadInterface();
9 9
10 function loadInterface() { 10 function loadInterface() {
11 11
12 // Get the dimensions of the screen available to the page 12 // Get the dimensions of the screen available to the page
13 var width = window.innerWidth; 13 var width = window.innerWidth;
14 var height = window.innerHeight; 14 var height = window.innerHeight;
15 15
16 // The injection point into the HTML page 16 // The injection point into the HTML page
17 interfaceContext.insertPoint = document.getElementById("topLevelBody"); 17 interfaceContext.insertPoint = document.getElementById("topLevelBody");
18 var testContent = document.createElement('div'); 18 var testContent = document.createElement('div');
19 19
20 testContent.id = 'testContent'; 20 testContent.id = 'testContent';
21 21
22 // Bindings for interfaceContext 22 // Bindings for interfaceContext
23 interfaceContext.checkAllPlayed = function() 23 interfaceContext.checkAllPlayed = function () {
24 { 24 hasBeenPlayed = audioEngineContext.checkAllPlayed();
25 hasBeenPlayed = audioEngineContext.checkAllPlayed(); 25 if (hasBeenPlayed.length > 0) // if a fragment has not been played yet
26 if (hasBeenPlayed.length > 0) // if a fragment has not been played yet 26 {
27 { 27 var str = "";
28 var str = ""; 28 if (hasBeenPlayed.length > 1) {
29 if (hasBeenPlayed.length > 1) { 29 for (var i = 0; i < hasBeenPlayed.length; i++) {
30 for (var i=0; i<hasBeenPlayed.length; i++) {
31 var ao_id = audioEngineContext.audioObjects[hasBeenPlayed[i]].interfaceDOM.getPresentedId(); 30 var ao_id = audioEngineContext.audioObjects[hasBeenPlayed[i]].interfaceDOM.getPresentedId();
32 str = str + ao_id; // start from 1 31 str = str + ao_id; // start from 1
33 if (i < hasBeenPlayed.length-2){ 32 if (i < hasBeenPlayed.length - 2) {
34 str += ", "; 33 str += ", ";
35 } else if (i == hasBeenPlayed.length-2) { 34 } else if (i == hasBeenPlayed.length - 2) {
36 str += " or "; 35 str += " or ";
37 } 36 }
38 } 37 }
39 str = 'You have not played fragments ' + str + ' yet. Please listen, rate and comment all samples before submitting.'; 38 str = 'You have not played fragments ' + str + ' yet. Please listen, rate and comment all samples before submitting.';
40 } else { 39 } else {
41 str = 'You have not played fragment ' + (audioEngineContext.audioObjects[hasBeenPlayed[0]].interfaceDOM.getPresentedId()) + ' yet. Please listen, rate and comment all samples before submitting.'; 40 str = 'You have not played fragment ' + (audioEngineContext.audioObjects[hasBeenPlayed[0]].interfaceDOM.getPresentedId()) + ' yet. Please listen, rate and comment all samples before submitting.';
42 } 41 }
43 this.storeErrorNode(str); 42 this.storeErrorNode(str);
44 interfaceContext.lightbox.post("Message",str); 43 interfaceContext.lightbox.post("Message", str);
45 return false; 44 return false;
46 } 45 }
47 return true; 46 return true;
48 }; 47 };
49 48
50 interfaceContext.checkAllMoved = function() { 49 interfaceContext.checkAllMoved = function () {
51 var state = true; 50 var state = true;
52 var str = 'You have not moved the following sliders. '; 51 var str = 'You have not moved the following sliders. ';
53 for (var i=0; i<this.interfaceSliders.length; i++) 52 for (var i = 0; i < this.interfaceSliders.length; i++) {
54 { 53 var interfaceTID = [];
55 var interfaceTID = []; 54 for (var j = 0; j < this.interfaceSliders[i].metrics.length; j++) {
56 for (var j=0; j<this.interfaceSliders[i].metrics.length; j++)
57 {
58 var ao_id = this.interfaceSliders[i].sliders[j].getAttribute("trackIndex"); 55 var ao_id = this.interfaceSliders[i].sliders[j].getAttribute("trackIndex");
59 if (this.interfaceSliders[i].metrics[j].wasMoved == false && audioEngineContext.audioObjects[ao_id].interfaceDOM.canMove()) 56 if (this.interfaceSliders[i].metrics[j].wasMoved == false && audioEngineContext.audioObjects[ao_id].interfaceDOM.canMove()) {
60 { 57 state = false;
61 state = false; 58 interfaceTID.push(j);
62 interfaceTID.push(j); 59 }
63 } 60 }
64 } 61 if (interfaceTID.length != 0) {
65 if (interfaceTID.length != 0) 62 var interfaceName = this.interfaceSliders[i].interfaceObject.title;
66 { 63 if (interfaceName == undefined) {
67 var interfaceName = this.interfaceSliders[i].interfaceObject.title; 64 str += 'On axis ' + String(i + 1) + ' you must move ';
68 if (interfaceName == undefined) { 65 } else {
69 str += 'On axis '+String(i+1)+' you must move '; 66 str += 'On axis "' + interfaceName + '" you must move ';
70 } else { 67 }
71 str += 'On axis "'+interfaceName+'" you must move '; 68 if (interfaceTID.length == 1) {
72 } 69 str += 'slider ' + (audioEngineContext.audioObjects[interfaceTID[0]].interfaceDOM.getPresentedId()) + '. '; // start from 1
73 if (interfaceTID.length == 1) 70 } else {
74 { 71 str += 'sliders ';
75 str += 'slider '+(audioEngineContext.audioObjects[interfaceTID[0]].interfaceDOM.getPresentedId())+'. '; // start from 1 72 for (var k = 0; k < interfaceTID.length - 1; k++) {
76 } 73 str += (audioEngineContext.audioObjects[interfaceTID[k]].interfaceDOM.getPresentedId()) + ', '; // start from 1
77 else { 74 }
78 str += 'sliders '; 75 str += (audioEngineContext.audioObjects[interfaceTID[interfaceTID.length - 1]].interfaceDOM.getPresentedId()) + '. ';
79 for (var k=0; k<interfaceTID.length-1; k++) 76 }
80 { 77 }
81 str += (audioEngineContext.audioObjects[interfaceTID[k]].interfaceDOM.getPresentedId())+', '; // start from 1 78 }
82 } 79 if (state != true) {
83 str += (audioEngineContext.audioObjects[interfaceTID[interfaceTID.length-1]].interfaceDOM.getPresentedId()) +'. ';
84 }
85 }
86 }
87 if (state != true)
88 {
89 this.storeErrorNode(str); 80 this.storeErrorNode(str);
90 interfaceContext.lightbox.post("Message",str); 81 interfaceContext.lightbox.post("Message", str);
91 console.log(str); 82 console.log(str);
92 } 83 }
93 return state; 84 return state;
94 }; 85 };
95 86
96 Interface.prototype.checkAllCommented = function() { 87 Interface.prototype.checkAllCommented = function () {
97 var audioObjs = audioEngineContext.audioObjects; 88 var audioObjs = audioEngineContext.audioObjects;
98 var audioHolder = testState.stateMap[testState.stateIndex]; 89 var audioHolder = testState.stateMap[testState.stateIndex];
99 var state = true; 90 var state = true;
100 if (audioHolder.elementComments) { 91 if (audioHolder.elementComments) {
101 var strNums = []; 92 var strNums = [];
102 for (var i=0; i<audioObjs.length; i++) 93 for (var i = 0; i < audioObjs.length; i++) {
103 { 94 if (audioObjs[i].commentDOM.trackCommentBox.value.length == 0) {
104 if (audioObjs[i].commentDOM.trackCommentBox.value.length == 0) { 95 state = false;
105 state = false; 96 strNums.push(i);
106 strNums.push(i); 97 }
107 } 98 }
108 } 99 if (state == false) {
109 if (state == false) {
110 var str = ""; 100 var str = "";
111 if (strNums.length > 1) { 101 if (strNums.length > 1) {
112 102
113 for (var i=0; i<strNums.length; i++) { 103 for (var i = 0; i < strNums.length; i++) {
114 var ao_id = audioEngineContext.audioObjects[strNums[i]].interfaceDOM.getPresentedId(); 104 var ao_id = audioEngineContext.audioObjects[strNums[i]].interfaceDOM.getPresentedId();
115 str = str + (ao_id); // start from 1 105 str = str + (ao_id); // start from 1
116 if (i < strNums.length-2){ 106 if (i < strNums.length - 2) {
117 str += ", "; 107 str += ", ";
118 } else if (i == strNums.length-2) { 108 } else if (i == strNums.length - 2) {
119 str += " or "; 109 str += " or ";
120 } 110 }
121 } 111 }
122 str = 'You have not commented on fragments ' + str + ' yet. Please listen, rate and comment all samples before submitting.'; 112 str = 'You have not commented on fragments ' + str + ' yet. Please listen, rate and comment all samples before submitting.';
123 } else { 113 } else {
124 str = 'You have not commented on fragment ' + (audioEngineContext.audioObjects[strNums[0]].interfaceDOM.getPresentedId()) + ' yet. Please listen, rate and comment all samples before submitting.'; 114 str = 'You have not commented on fragment ' + (audioEngineContext.audioObjects[strNums[0]].interfaceDOM.getPresentedId()) + ' yet. Please listen, rate and comment all samples before submitting.';
125 } 115 }
126 this.storeErrorNode(str); 116 this.storeErrorNode(str);
127 interfaceContext.lightbox.post("Message",str); 117 interfaceContext.lightbox.post("Message", str);
128 console.log(str); 118 console.log(str);
129 } 119 }
130 } 120 }
131 return state; 121 return state;
132 }; 122 };
133 123
134 Interface.prototype.checkScaleRange = function() 124 Interface.prototype.checkScaleRange = function () {
135 { 125 var audioObjs = audioEngineContext.audioObjects;
136 var audioObjs = audioEngineContext.audioObjects; 126 var audioHolder = testState.stateMap[testState.stateIndex];
137 var audioHolder = testState.stateMap[testState.stateIndex]; 127 var state = true;
138 var state = true; 128 var str = '';
139 var str = ''; 129 for (var i = 0; i < this.interfaceSliders.length; i++) {
140 for (var i=0; i<this.interfaceSliders.length; i++) 130 var minScale;
141 { 131 var maxScale;
142 var minScale; 132 var interfaceObject = interfaceContext.interfaceSliders[0].interfaceObject;
143 var maxScale; 133 for (var j = 0; j < interfaceObject.options.length; j++) {
144 var interfaceObject = interfaceContext.interfaceSliders[0].interfaceObject; 134 if (interfaceObject.options[j].check == "scalerange") {
145 for (var j=0; j<interfaceObject.options.length; j++) 135 minScale = interfaceObject.options[j].min;
146 { 136 maxScale = interfaceObject.options[j].max;
147 if (interfaceObject.options[j].check == "scalerange") { 137 break;
148 minScale = interfaceObject.options[j].min; 138 }
149 maxScale = interfaceObject.options[j].max; 139 }
150 break; 140 var minRanking = convSliderPosToRate(this.interfaceSliders[i].sliders[0]);
151 } 141 var maxRanking = minRanking;
152 } 142 for (var j = 1; j < this.interfaceSliders[i].sliders.length; j++) {
153 var minRanking = convSliderPosToRate(this.interfaceSliders[i].sliders[0]); 143 var ranking = convSliderPosToRate(this.interfaceSliders[i].sliders[j]);
154 var maxRanking = minRanking; 144 if (ranking < minRanking) {
155 for (var j=1; j<this.interfaceSliders[i].sliders.length; j++) 145 minRanking = ranking;
156 { 146 } else if (ranking > maxRanking) {
157 var ranking = convSliderPosToRate(this.interfaceSliders[i].sliders[j]); 147 maxRanking = ranking;
158 if (ranking < minRanking) 148 }
159 { 149 }
160 minRanking = ranking; 150 if (minRanking > minScale || maxRanking < maxScale) {
161 } else if (ranking > maxRanking) 151 state = false;
162 { 152 str += 'On axis "' + this.interfaceSliders[i].interfaceObject.title + '" you have not used the full width of the scale. ';
163 maxRanking = ranking; 153 }
164 } 154 }
165 } 155 if (state != true) {
166 if (minRanking > minScale || maxRanking < maxScale)
167 {
168 state = false;
169 str += 'On axis "'+this.interfaceSliders[i].interfaceObject.title+'" you have not used the full width of the scale. ';
170 }
171 }
172 if (state != true)
173 {
174 this.storeErrorNode(str); 156 this.storeErrorNode(str);
175 interfaceContext.lightbox.post("Message",str); 157 interfaceContext.lightbox.post("Message", str);
176 console.log(str); 158 console.log(str);
177 } 159 }
178 return state; 160 return state;
179 }; 161 };
180 162
181 Interface.prototype.objectSelected = null; 163 Interface.prototype.objectSelected = null;
182 Interface.prototype.objectMoved = false; 164 Interface.prototype.objectMoved = false;
183 Interface.prototype.selectObject = function(object) 165 Interface.prototype.selectObject = function (object) {
184 { 166 if (this.objectSelected == null) {
185 if (this.objectSelected == null) 167 this.objectSelected = object;
186 { 168 this.objectMoved = false;
187 this.objectSelected = object; 169 }
188 this.objectMoved = false; 170 };
189 } 171 Interface.prototype.moveObject = function () {
190 }; 172 if (this.objectMoved == false) {
191 Interface.prototype.moveObject = function() 173 this.objectMoved = true;
192 { 174 }
193 if (this.objectMoved == false) 175 };
194 { 176 Interface.prototype.releaseObject = function () {
195 this.objectMoved = true; 177 this.objectSelected = null;
196 } 178 this.objectMoved = false;
197 }; 179 };
198 Interface.prototype.releaseObject = function() 180 Interface.prototype.getSelectedObject = function () {
199 { 181 return this.objectSelected;
200 this.objectSelected = null; 182 };
201 this.objectMoved = false; 183 Interface.prototype.hasSelectedObjectMoved = function () {
202 }; 184 return this.objectMoved;
203 Interface.prototype.getSelectedObject = function() 185 };
204 { 186
205 return this.objectSelected; 187 // Bindings for slider interfaces
206 }; 188 Interface.prototype.interfaceSliders = [];
207 Interface.prototype.hasSelectedObjectMoved = function() 189
208 { 190 // Bindings for audioObjects
209 return this.objectMoved; 191
210 }; 192 // Create the top div for the Title element
211 193 var titleAttr = specification.title;
212 // Bindings for slider interfaces 194 var title = document.createElement('div');
213 Interface.prototype.interfaceSliders = []; 195 title.className = "title";
214 196 title.align = "center";
215 // Bindings for audioObjects 197 var titleSpan = document.createElement('span');
216
217 // Create the top div for the Title element
218 var titleAttr = specification.title;
219 var title = document.createElement('div');
220 title.className = "title";
221 title.align = "center";
222 var titleSpan = document.createElement('span');
223 titleSpan.id = "test-title"; 198 titleSpan.id = "test-title";
224 199
225 // Set title to that defined in XML, else set to default 200 // Set title to that defined in XML, else set to default
226 if (titleAttr != undefined) { 201 if (titleAttr != undefined) {
227 titleSpan.textContent = titleAttr; 202 titleSpan.textContent = titleAttr;
228 } else { 203 } else {
229 titleSpan.textContent = 'Listening test'; 204 titleSpan.textContent = 'Listening test';
230 } 205 }
231 // Insert the titleSpan element into the title div element. 206 // Insert the titleSpan element into the title div element.
232 title.appendChild(titleSpan); 207 title.appendChild(titleSpan);
233 208
234 // Create Interface buttons! 209 // Create Interface buttons!
235 var interfaceButtons = document.createElement('div'); 210 var interfaceButtons = document.createElement('div');
236 interfaceButtons.id = 'interface-buttons'; 211 interfaceButtons.id = 'interface-buttons';
237 212
238 // Create playback start/stop points 213 // Create playback start/stop points
239 var playback = document.createElement("button"); 214 var playback = document.createElement("button");
240 playback.innerHTML = 'Stop'; 215 playback.innerHTML = 'Stop';
241 playback.id = 'playback-button'; 216 playback.id = 'playback-button';
242 // onclick function. Check if it is playing or not, call the correct function in the 217 // onclick function. Check if it is playing or not, call the correct function in the
243 // audioEngine, change the button text to reflect the next state. 218 // audioEngine, change the button text to reflect the next state.
244 playback.onclick = function() { 219 playback.onclick = function () {
245 if (audioEngineContext.status == 1) { 220 if (audioEngineContext.status == 1) {
246 audioEngineContext.stop(); 221 audioEngineContext.stop();
247 this.innerHTML = 'Stop'; 222 this.innerHTML = 'Stop';
248 var time = audioEngineContext.timer.getTestTime(); 223 var time = audioEngineContext.timer.getTestTime();
249 console.log('Stopped at ' + time); // DEBUG/SAFETY 224 console.log('Stopped at ' + time); // DEBUG/SAFETY
250 } 225 }
251 }; 226 };
252 // Create Submit (save) button 227 // Create Submit (save) button
253 var submit = document.createElement("button"); 228 var submit = document.createElement("button");
254 submit.innerHTML = 'Next'; 229 submit.innerHTML = 'Next';
255 submit.onclick = buttonSubmitClick; 230 submit.onclick = buttonSubmitClick;
256 submit.id = 'submit-button'; 231 submit.id = 'submit-button';
257 // Append the interface buttons into the interfaceButtons object. 232 // Append the interface buttons into the interfaceButtons object.
258 interfaceButtons.appendChild(playback); 233 interfaceButtons.appendChild(playback);
259 interfaceButtons.appendChild(submit); 234 interfaceButtons.appendChild(submit);
260 235
261 var sliderHolder = document.createElement("div"); 236 var sliderHolder = document.createElement("div");
262 sliderHolder.id = "slider-holder"; 237 sliderHolder.id = "slider-holder";
263 238
264 // Create outside reference holder 239 // Create outside reference holder
265 var outsideRef = document.createElement("div"); 240 var outsideRef = document.createElement("div");
266 outsideRef.id = "outside-reference-holder"; 241 outsideRef.id = "outside-reference-holder";
267 242
268 // Global parent for the comment boxes on the page 243 // Global parent for the comment boxes on the page
269 var feedbackHolder = document.createElement('div'); 244 var feedbackHolder = document.createElement('div');
270 feedbackHolder.id = 'feedbackHolder'; 245 feedbackHolder.id = 'feedbackHolder';
271 246
272 testContent.style.zIndex = 1; 247 testContent.style.zIndex = 1;
273 interfaceContext.insertPoint.innerHTML = ""; // Clear the current schema 248 interfaceContext.insertPoint.innerHTML = ""; // Clear the current schema
274 249
275 // Inject into HTML 250 // Inject into HTML
276 testContent.appendChild(title); // Insert the title 251 testContent.appendChild(title); // Insert the title
277 testContent.appendChild(interfaceButtons); 252 testContent.appendChild(interfaceButtons);
278 testContent.appendChild(outsideRef); 253 testContent.appendChild(outsideRef);
279 testContent.appendChild(sliderHolder); 254 testContent.appendChild(sliderHolder);
280 testContent.appendChild(feedbackHolder); 255 testContent.appendChild(feedbackHolder);
281 interfaceContext.insertPoint.appendChild(testContent); 256 interfaceContext.insertPoint.appendChild(testContent);
282 257
283 // Load the full interface 258 // Load the full interface
284 testState.initialise(); 259 testState.initialise();
285 testState.advanceState(); 260 testState.advanceState();
286 261
287 } 262 }
288 263
289 function loadTest(audioHolderObject) 264 function loadTest(audioHolderObject) {
290 { 265 var width = window.innerWidth;
291 var width = window.innerWidth; 266 var height = window.innerHeight;
292 var height = window.innerHeight; 267 var id = audioHolderObject.id;
293 var id = audioHolderObject.id; 268
294 269 interfaceContext.interfaceSliders = [];
295 interfaceContext.interfaceSliders = []; 270
296 271 var feedbackHolder = document.getElementById('feedbackHolder');
297 var feedbackHolder = document.getElementById('feedbackHolder'); 272 var sliderHolder = document.getElementById('slider-holder');
298 var sliderHolder = document.getElementById('slider-holder'); 273 feedbackHolder.innerHTML = "";
299 feedbackHolder.innerHTML = ""; 274 sliderHolder.innerHTML = "";
300 sliderHolder.innerHTML = ""; 275
301
302 // Set the page title 276 // Set the page title
303 if (typeof audioHolderObject.title == "string" && audioHolderObject.title.length > 0) { 277 if (typeof audioHolderObject.title == "string" && audioHolderObject.title.length > 0) {
304 document.getElementById("test-title").textContent = audioHolderObject.title 278 document.getElementById("test-title").textContent = audioHolderObject.title
305 } 279 }
306 280
307 281
308 // Delete outside reference 282 // Delete outside reference
309 document.getElementById("outside-reference-holder").innerHTML = ""; 283 document.getElementById("outside-reference-holder").innerHTML = "";
310 284
311 var interfaceObj = audioHolderObject.interfaces; 285 var interfaceObj = audioHolderObject.interfaces;
312 for (var k=0; k<interfaceObj.length; k++) { 286 for (var k = 0; k < interfaceObj.length; k++) {
313 // Create the div box to center align 287 // Create the div box to center align
314 interfaceContext.interfaceSliders.push(new interfaceSliderHolder(interfaceObj[k])); 288 interfaceContext.interfaceSliders.push(new interfaceSliderHolder(interfaceObj[k]));
315 } 289 }
316 290
317 var interfaceList = audioHolderObject.interfaces.concat(specification.interfaces); 291 var interfaceList = audioHolderObject.interfaces.concat(specification.interfaces);
318 for (var k=0; k<interfaceList.length; k++) 292 for (var k = 0; k < interfaceList.length; k++) {
319 { 293 for (var i = 0; i < interfaceList[k].options.length; i++) {
320 for (var i=0; i<interfaceList[k].options.length; i++) 294 if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'playhead') {
321 {
322 if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'playhead')
323 {
324 var playbackHolder = document.getElementById('playback-holder'); 295 var playbackHolder = document.getElementById('playback-holder');
325 if (playbackHolder == null) 296 if (playbackHolder == null) {
326 {
327 playbackHolder = document.createElement('div'); 297 playbackHolder = document.createElement('div');
328 playbackHolder.style.width = "100%"; 298 playbackHolder.style.width = "100%";
329 playbackHolder.align = 'center'; 299 playbackHolder.align = 'center';
330 playbackHolder.appendChild(interfaceContext.playhead.object); 300 playbackHolder.appendChild(interfaceContext.playhead.object);
331 feedbackHolder.appendChild(playbackHolder); 301 feedbackHolder.appendChild(playbackHolder);
332 } 302 }
333 } else if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'page-count') 303 } else if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'page-count') {
334 {
335 var pagecountHolder = document.getElementById('page-count'); 304 var pagecountHolder = document.getElementById('page-count');
336 if (pagecountHolder == null) 305 if (pagecountHolder == null) {
337 {
338 pagecountHolder = document.createElement('div'); 306 pagecountHolder = document.createElement('div');
339 pagecountHolder.id = 'page-count'; 307 pagecountHolder.id = 'page-count';
340 } 308 }
341 pagecountHolder.innerHTML = '<span>Page '+(testState.stateIndex+1)+' of '+testState.stateMap.length+'</span>'; 309 pagecountHolder.innerHTML = '<span>Page ' + (testState.stateIndex + 1) + ' of ' + testState.stateMap.length + '</span>';
342 var inject = document.getElementById('interface-buttons'); 310 var inject = document.getElementById('interface-buttons');
343 inject.appendChild(pagecountHolder); 311 inject.appendChild(pagecountHolder);
344 } else if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'volume') { 312 } else if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'volume') {
345 if (document.getElementById('master-volume-holder') == null) 313 if (document.getElementById('master-volume-holder') == null) {
346 {
347 feedbackHolder.appendChild(interfaceContext.volume.object); 314 feedbackHolder.appendChild(interfaceContext.volume.object);
348 } 315 }
349 } else if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'comments') { 316 } else if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'comments') {
350 var commentHolder = document.createElement('div'); 317 var commentHolder = document.createElement('div');
351 commentHolder.id = 'commentHolder'; 318 commentHolder.id = 'commentHolder';
352 document.getElementById('testContent').appendChild(commentHolder); 319 document.getElementById('testContent').appendChild(commentHolder);
353 interfaceContext.commentBoxes.showCommentBoxes(feedbackHolder,true); 320 interfaceContext.commentBoxes.showCommentBoxes(feedbackHolder, true);
354 break; 321 break;
355 } 322 }
356 } 323 }
357 } 324 }
358 325
359 var commentBoxPrefix = "Comment on fragment"; 326 var commentBoxPrefix = "Comment on fragment";
360 327
361 var commentShow = audioHolderObject.elementComments; 328 var commentShow = audioHolderObject.elementComments;
362 329
363 var loopPlayback = audioHolderObject.loop; 330 var loopPlayback = audioHolderObject.loop;
364 331
365 currentTestHolder = document.createElement('audioHolder'); 332 currentTestHolder = document.createElement('audioHolder');
366 currentTestHolder.id = audioHolderObject.id; 333 currentTestHolder.id = audioHolderObject.id;
367 currentTestHolder.repeatCount = audioHolderObject.repeatCount; 334 currentTestHolder.repeatCount = audioHolderObject.repeatCount;
368 335
369 // Find all the audioElements from the audioHolder 336 // Find all the audioElements from the audioHolder
370 $(audioHolderObject.audioElements).each(function(index,element){ 337 $(audioHolderObject.audioElements).each(function (index, element) {
371 // Find URL of track 338 // Find URL of track
372 // In this jQuery loop, variable 'this' holds the current audioElement. 339 // In this jQuery loop, variable 'this' holds the current audioElement.
373 var audioObject = audioEngineContext.newTrack(element); 340 var audioObject = audioEngineContext.newTrack(element);
374 // Check if an outside reference 341 // Check if an outside reference
375 if (element.type == 'outside-reference') 342 if (element.type == 'outside-reference') {
376 { 343 // Construct outside reference;
377 // Construct outside reference; 344 var orNode = new outsideReferenceDOM(audioObject, index, document.getElementById("outside-reference-holder"));
378 var orNode = new outsideReferenceDOM(audioObject,index,document.getElementById("outside-reference-holder")); 345 audioObject.bindInterface(orNode);
379 audioObject.bindInterface(orNode); 346 } else {
380 } else { 347 // Create a slider per track
381 // Create a slider per track 348 var sliderNode = new sliderObject(audioObject, interfaceObj, index);
382 var sliderNode = new sliderObject(audioObject,interfaceObj,index); 349 audioObject.bindInterface(sliderNode);
383 audioObject.bindInterface(sliderNode);
384 interfaceContext.commentBoxes.createCommentBox(audioObject); 350 interfaceContext.commentBoxes.createCommentBox(audioObject);
385 } 351 }
386 }); 352 });
387 353
388 // Initialse the interfaceSlider object metrics 354 // Initialse the interfaceSlider object metrics
389 355
390 $('.track-slider').mousedown(function(event) { 356 $('.track-slider').mousedown(function (event) {
391 interfaceContext.selectObject($(this)[0]); 357 interfaceContext.selectObject($(this)[0]);
392 }); 358 });
393 $('.track-slider').on('touchstart',null,function(event) { 359 $('.track-slider').on('touchstart', null, function (event) {
394 interfaceContext.selectObject($(this)[0]); 360 interfaceContext.selectObject($(this)[0]);
395 }); 361 });
396 362
397 $('.track-slider').mousemove(function(event) { 363 $('.track-slider').mousemove(function (event) {
398 event.preventDefault(); 364 event.preventDefault();
399 }); 365 });
400 366
401 $('.slider').mousemove(function(event) { 367 $('.slider').mousemove(function (event) {
402 event.preventDefault(); 368 event.preventDefault();
403 var obj = interfaceContext.getSelectedObject(); 369 var obj = interfaceContext.getSelectedObject();
404 if (obj == null) {return;} 370 if (obj == null) {
405 var move = event.clientX-6; 371 return;
372 }
373 var move = event.clientX - 6;
406 var w = $(event.currentTarget).width(); 374 var w = $(event.currentTarget).width();
407 move = Math.max(50,move); 375 move = Math.max(50, move);
408 move = Math.min(w+50,move); 376 move = Math.min(w + 50, move);
409 $(obj).css("left",move + "px"); 377 $(obj).css("left", move + "px");
410 interfaceContext.moveObject(); 378 interfaceContext.moveObject();
411 }); 379 });
412 380
413 $('.slider').on('touchmove',null,function(event) { 381 $('.slider').on('touchmove', null, function (event) {
414 event.preventDefault(); 382 event.preventDefault();
415 var obj = interfaceContext.getSelectedObject(); 383 var obj = interfaceContext.getSelectedObject();
416 if (obj == null) {return;} 384 if (obj == null) {
417 var move = event.originalEvent.targetTouches[0].clientX - 6; 385 return;
386 }
387 var move = event.originalEvent.targetTouches[0].clientX - 6;
418 var w = $(event.currentTarget).width(); 388 var w = $(event.currentTarget).width();
419 move = Math.max(50,move); 389 move = Math.max(50, move);
420 move = Math.min(w+50,move); 390 move = Math.min(w + 50, move);
421 $(obj).css("left",move + "px"); 391 $(obj).css("left", move + "px");
422 interfaceContext.moveObject(); 392 interfaceContext.moveObject();
423 }); 393 });
424 394
425 $(document).mouseup(function(event){ 395 $(document).mouseup(function (event) {
426 event.preventDefault(); 396 event.preventDefault();
427 var obj = interfaceContext.getSelectedObject(); 397 var obj = interfaceContext.getSelectedObject();
428 if (obj == null) {return;} 398 if (obj == null) {
429 var interfaceID = obj.parentElement.getAttribute("interfaceid"); 399 return;
430 var trackID = obj.getAttribute("trackindex"); 400 }
431 if (interfaceContext.hasSelectedObjectMoved() == true) 401 var interfaceID = obj.parentElement.getAttribute("interfaceid");
432 { 402 var trackID = obj.getAttribute("trackindex");
433 var l = $(obj).css("left"); 403 if (interfaceContext.hasSelectedObjectMoved() == true) {
434 var id = obj.getAttribute('trackIndex'); 404 var l = $(obj).css("left");
435 var time = audioEngineContext.timer.getTestTime(); 405 var id = obj.getAttribute('trackIndex');
436 var rate = convSliderPosToRate(obj); 406 var time = audioEngineContext.timer.getTestTime();
437 audioEngineContext.audioObjects[id].metric.moved(time,rate); 407 var rate = convSliderPosToRate(obj);
438 interfaceContext.interfaceSliders[interfaceID].metrics[trackID].moved(time,rate); 408 audioEngineContext.audioObjects[id].metric.moved(time, rate);
439 console.log("slider "+id+" moved to "+rate+' ('+time+')'); 409 interfaceContext.interfaceSliders[interfaceID].metrics[trackID].moved(time, rate);
440 obj.setAttribute("slider-value",convSliderPosToRate(obj)); 410 console.log("slider " + id + " moved to " + rate + ' (' + time + ')');
441 } else { 411 obj.setAttribute("slider-value", convSliderPosToRate(obj));
442 var id = Number(obj.attributes['trackIndex'].value); 412 } else {
443 //audioEngineContext.metric.sliderPlayed(id); 413 var id = Number(obj.attributes['trackIndex'].value);
444 audioEngineContext.play(id); 414 //audioEngineContext.metric.sliderPlayed(id);
445 } 415 audioEngineContext.play(id);
446 interfaceContext.releaseObject(); 416 }
447 }); 417 interfaceContext.releaseObject();
448 418 });
449 $('.slider').on('touchend',null,function(event){ 419
450 var obj = interfaceContext.getSelectedObject(); 420 $('.slider').on('touchend', null, function (event) {
451 if (obj == null) {return;} 421 var obj = interfaceContext.getSelectedObject();
452 var interfaceID = obj.parentElement.getAttribute("interfaceid"); 422 if (obj == null) {
453 var trackID = obj.getAttribute("trackindex"); 423 return;
454 if (interfaceContext.hasSelectedObjectMoved() == true) 424 }
455 { 425 var interfaceID = obj.parentElement.getAttribute("interfaceid");
456 var l = $(obj).css("left"); 426 var trackID = obj.getAttribute("trackindex");
457 var id = obj.getAttribute('trackIndex'); 427 if (interfaceContext.hasSelectedObjectMoved() == true) {
458 var time = audioEngineContext.timer.getTestTime(); 428 var l = $(obj).css("left");
459 var rate = convSliderPosToRate(obj); 429 var id = obj.getAttribute('trackIndex');
460 audioEngineContext.audioObjects[id].metric.moved(time,rate); 430 var time = audioEngineContext.timer.getTestTime();
461 interfaceContext.interfaceSliders[interfaceID].metrics[trackID].moved(time,rate); 431 var rate = convSliderPosToRate(obj);
462 console.log("slider "+id+" moved to "+rate+' ('+time+')'); 432 audioEngineContext.audioObjects[id].metric.moved(time, rate);
463 } 433 interfaceContext.interfaceSliders[interfaceID].metrics[trackID].moved(time, rate);
464 interfaceContext.releaseObject(); 434 console.log("slider " + id + " moved to " + rate + ' (' + time + ')');
465 }); 435 }
466 436 interfaceContext.releaseObject();
437 });
438
467 var interfaceList = audioHolderObject.interfaces.concat(specification.interfaces); 439 var interfaceList = audioHolderObject.interfaces.concat(specification.interfaces);
468 for (var k=0; k<interfaceList.length; k++) 440 for (var k = 0; k < interfaceList.length; k++) {
469 { 441 for (var i = 0; i < interfaceList[k].options.length; i++) {
470 for (var i=0; i<interfaceList[k].options.length; i++) 442 if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'playhead') {
471 {
472 if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'playhead')
473 {
474 var playbackHolder = document.getElementById('playback-holder'); 443 var playbackHolder = document.getElementById('playback-holder');
475 if (playbackHolder == null) 444 if (playbackHolder == null) {
476 {
477 playbackHolder = document.createElement('div'); 445 playbackHolder = document.createElement('div');
478 playbackHolder.id = "playback-holder"; 446 playbackHolder.id = "playback-holder";
479 playbackHolder.style.width = "100%"; 447 playbackHolder.style.width = "100%";
480 playbackHolder.align = 'center'; 448 playbackHolder.align = 'center';
481 playbackHolder.appendChild(interfaceContext.playhead.object); 449 playbackHolder.appendChild(interfaceContext.playhead.object);
482 feedbackHolder.appendChild(playbackHolder); 450 feedbackHolder.appendChild(playbackHolder);
483 } 451 }
484 } else if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'page-count') 452 } else if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'page-count') {
485 {
486 var pagecountHolder = document.getElementById('page-count'); 453 var pagecountHolder = document.getElementById('page-count');
487 if (pagecountHolder == null) 454 if (pagecountHolder == null) {
488 {
489 pagecountHolder = document.createElement('div'); 455 pagecountHolder = document.createElement('div');
490 pagecountHolder.id = 'page-count'; 456 pagecountHolder.id = 'page-count';
491 } 457 }
492 pagecountHolder.innerHTML = '<span>Page '+(testState.stateIndex+1)+' of '+testState.stateMap.length+'</span>'; 458 pagecountHolder.innerHTML = '<span>Page ' + (testState.stateIndex + 1) + ' of ' + testState.stateMap.length + '</span>';
493 var inject = document.getElementById('interface-buttons'); 459 var inject = document.getElementById('interface-buttons');
494 inject.appendChild(pagecountHolder); 460 inject.appendChild(pagecountHolder);
495 } else if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'volume') { 461 } else if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'volume') {
496 if (document.getElementById('master-volume-holder') == null) 462 if (document.getElementById('master-volume-holder') == null) {
497 {
498 feedbackHolder.appendChild(interfaceContext.volume.object); 463 feedbackHolder.appendChild(interfaceContext.volume.object);
499 } 464 }
500 } else if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'comments') { 465 } else if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'comments') {
501 interfaceContext.commentBoxes.showCommentBoxes(feedbackHolder,true); 466 interfaceContext.commentBoxes.showCommentBoxes(feedbackHolder, true);
502 break; 467 break;
503 } 468 }
504 } 469 }
505 } 470 }
506 471
507 $(audioHolderObject.commentQuestions).each(function(index,element) { 472 $(audioHolderObject.commentQuestions).each(function (index, element) {
508 var node = interfaceContext.createCommentQuestion(element); 473 var node = interfaceContext.createCommentQuestion(element);
509 feedbackHolder.appendChild(node.holder); 474 feedbackHolder.appendChild(node.holder);
510 }); 475 });
511 476
512 //testWaitIndicator(); 477 //testWaitIndicator();
513 } 478 }
514 479
515 function interfaceSliderHolder(interfaceObject) 480 function interfaceSliderHolder(interfaceObject) {
516 { 481 this.sliders = [];
517 this.sliders = []; 482 this.metrics = [];
518 this.metrics = []; 483 this.id = document.getElementsByClassName("sliderCanvasDiv").length;
519 this.id = document.getElementsByClassName("sliderCanvasDiv").length; 484 this.name = interfaceObject.name;
520 this.name = interfaceObject.name; 485 this.interfaceObject = interfaceObject;
521 this.interfaceObject = interfaceObject; 486 this.sliderDOM = document.createElement('div');
522 this.sliderDOM = document.createElement('div'); 487 this.sliderDOM.className = 'sliderCanvasDiv';
523 this.sliderDOM.className = 'sliderCanvasDiv'; 488 this.sliderDOM.id = 'sliderCanvasHolder-' + this.id;
524 this.sliderDOM.id = 'sliderCanvasHolder-'+this.id; 489
525 490 var pagetitle = document.createElement('div');
526 var pagetitle = document.createElement('div'); 491 pagetitle.className = "pageTitle";
527 pagetitle.className = "pageTitle"; 492 pagetitle.align = "center";
528 pagetitle.align = "center"; 493 var titleSpan = document.createElement('span');
529 var titleSpan = document.createElement('span'); 494 titleSpan.id = "pageTitle-" + this.id;
530 titleSpan.id = "pageTitle-"+this.id; 495 if (interfaceObject.title != undefined && typeof interfaceObject.title == "string") {
531 if (interfaceObject.title != undefined && typeof interfaceObject.title == "string") 496 titleSpan.textContent = interfaceObject.title;
532 { 497 } else {
533 titleSpan.textContent = interfaceObject.title; 498 titleSpan.textContent = "Axis " + String(this.id + 1);
534 } else { 499 }
535 titleSpan.textContent = "Axis "+String(this.id+1); 500 pagetitle.appendChild(titleSpan);
536 } 501 this.sliderDOM.appendChild(pagetitle);
537 pagetitle.appendChild(titleSpan); 502
538 this.sliderDOM.appendChild(pagetitle); 503 // Create the slider box to hold the slider elements
539 504 this.canvas = document.createElement('div');
540 // Create the slider box to hold the slider elements 505 if (this.name != undefined)
541 this.canvas = document.createElement('div'); 506 this.canvas.id = 'slider-' + this.name;
542 if (this.name != undefined) 507 else
543 this.canvas.id = 'slider-'+this.name; 508 this.canvas.id = 'slider-' + this.id;
544 else 509 this.canvas.setAttribute("interfaceid", this.id);
545 this.canvas.id = 'slider-'+this.id; 510 this.canvas.className = 'slider';
546 this.canvas.setAttribute("interfaceid",this.id); 511 this.canvas.align = "left";
547 this.canvas.className = 'slider'; 512 this.canvas.addEventListener('dragover', function (event) {
548 this.canvas.align = "left"; 513 event.preventDefault();
549 this.canvas.addEventListener('dragover',function(event){ 514 event.dataTransfer.effectAllowed = 'none';
550 event.preventDefault(); 515 event.dataTransfer.dropEffect = 'copy';
551 event.dataTransfer.effectAllowed = 'none'; 516 return false;
552 event.dataTransfer.dropEffect = 'copy'; 517 }, false);
553 return false; 518 this.sliderDOM.appendChild(this.canvas);
554 },false); 519
555 this.sliderDOM.appendChild(this.canvas); 520 // Create the div to hold any scale objects
556 521 this.scale = document.createElement('div');
557 // Create the div to hold any scale objects 522 this.scale.className = 'sliderScale';
558 this.scale = document.createElement('div'); 523 this.scale.id = 'sliderScaleHolder-' + this.id;
559 this.scale.className = 'sliderScale'; 524 this.scale.align = 'left';
560 this.scale.id = 'sliderScaleHolder-'+this.id; 525 this.sliderDOM.appendChild(this.scale);
561 this.scale.align = 'left'; 526 var positionScale = this.canvas.style.width.substr(0, this.canvas.style.width.length - 2);
562 this.sliderDOM.appendChild(this.scale); 527 var offset = 50;
563 var positionScale = this.canvas.style.width.substr(0,this.canvas.style.width.length-2);
564 var offset = 50;
565 var dest = document.getElementById("slider-holder").appendChild(this.sliderDOM); 528 var dest = document.getElementById("slider-holder").appendChild(this.sliderDOM);
566 for (var scaleObj of interfaceObject.scales) 529 for (var scaleObj of interfaceObject.scales) {
567 { 530 var position = Number(scaleObj.position) * 0.01;
568 var position = Number(scaleObj.position)*0.01; 531 var pixelPosition = (position * $(this.canvas).width()) + offset;
569 var pixelPosition = (position*$(this.canvas).width())+offset; 532 var scaleDOM = document.createElement('span');
570 var scaleDOM = document.createElement('span');
571 scaleDOM.className = "ape-marker-text"; 533 scaleDOM.className = "ape-marker-text";
572 scaleDOM.textContent = scaleObj.text; 534 scaleDOM.textContent = scaleObj.text;
573 scaleDOM.setAttribute('value',position) 535 scaleDOM.setAttribute('value', position)
574 this.scale.appendChild(scaleDOM); 536 this.scale.appendChild(scaleDOM);
575 scaleDOM.style.left = Math.floor((pixelPosition-($(scaleDOM).width()/2)))+'px'; 537 scaleDOM.style.left = Math.floor((pixelPosition - ($(scaleDOM).width() / 2))) + 'px';
576 } 538 }
577 539
578 this.createSliderObject = function(audioObject,label) 540 this.createSliderObject = function (audioObject, label) {
579 { 541 var trackObj = document.createElement('div');
580 var trackObj = document.createElement('div');
581 trackObj.align = "center"; 542 trackObj.align = "center";
582 trackObj.className = 'track-slider track-slider-disabled track-slider-'+audioObject.id; 543 trackObj.className = 'track-slider track-slider-disabled track-slider-' + audioObject.id;
583 trackObj.id = 'track-slider-'+this.id+'-'+audioObject.id; 544 trackObj.id = 'track-slider-' + this.id + '-' + audioObject.id;
584 trackObj.setAttribute('trackIndex',audioObject.id); 545 trackObj.setAttribute('trackIndex', audioObject.id);
585 if (this.name != undefined) { 546 if (this.name != undefined) {
586 trackObj.setAttribute('interface-name',this.name); 547 trackObj.setAttribute('interface-name', this.name);
587 } else { 548 } else {
588 trackObj.setAttribute('interface-name',this.id); 549 trackObj.setAttribute('interface-name', this.id);
589 } 550 }
590 var offset = 50; 551 var offset = 50;
591 // Distribute it randomnly 552 // Distribute it randomnly
592 var w = window.innerWidth - (offset+8)*2; 553 var w = window.innerWidth - (offset + 8) * 2;
593 w = Math.random()*w; 554 w = Math.random() * w;
594 w = Math.floor(w+(offset+8)); 555 w = Math.floor(w + (offset + 8));
595 trackObj.style.left = w+'px'; 556 trackObj.style.left = w + 'px';
596 this.canvas.appendChild(trackObj); 557 this.canvas.appendChild(trackObj);
597 this.sliders.push(trackObj); 558 this.sliders.push(trackObj);
598 this.metrics.push(new metricTracker(this)); 559 this.metrics.push(new metricTracker(this));
599 var labelHolder = document.createElement("span"); 560 var labelHolder = document.createElement("span");
600 labelHolder.textContent = label; 561 labelHolder.textContent = label;
601 trackObj.appendChild(labelHolder); 562 trackObj.appendChild(labelHolder);
602 var rate = convSliderPosToRate(trackObj); 563 var rate = convSliderPosToRate(trackObj);
603 this.metrics[this.metrics.length-1].initialise(rate); 564 this.metrics[this.metrics.length - 1].initialise(rate);
604 trackObj.setAttribute("slider-value",rate); 565 trackObj.setAttribute("slider-value", rate);
605 return trackObj; 566 return trackObj;
606 }; 567 };
607 568
608 this.resize = function(event) 569 this.resize = function (event) {
609 { 570 var width = window.innerWidth;
610 var width = window.innerWidth; 571 var sliderDiv = this.canvas;
611 var sliderDiv = this.canvas; 572 var sliderScaleDiv = this.scale;
612 var sliderScaleDiv = this.scale; 573 var width = $(sliderDiv).width();
613 var width = $(sliderDiv).width();
614 var marginsize = 50; 574 var marginsize = 50;
615 // Move sliders into new position 575 // Move sliders into new position
616 for (var index = 0; index < this.sliders.length; index++) 576 for (var index = 0; index < this.sliders.length; index++) {
617 { 577 var pix = Number(this.sliders[index].getAttribute("slider-value")) * width;
618 var pix = Number(this.sliders[index].getAttribute("slider-value")) * width; 578 this.sliders[index].style.left = (pix + marginsize) + 'px';
619 this.sliders[index].style.left = (pix+marginsize)+'px'; 579 }
620 } 580
621 581 // Move scale labels
622 // Move scale labels 582 for (var index = 0; index < this.scale.children.length; index++) {
623 for (var index = 0; index < this.scale.children.length; index++) 583 var scaleObj = this.scale.children[index];
624 { 584 var position = Number(scaleObj.attributes['value'].value);
625 var scaleObj = this.scale.children[index]; 585 var pixelPosition = (position * width) + marginsize;
626 var position = Number(scaleObj.attributes['value'].value); 586 scaleObj.style.left = Math.floor((pixelPosition - ($(scaleObj).width() / 2))) + 'px';
627 var pixelPosition = (position*width)+marginsize; 587 }
628 scaleObj.style.left = Math.floor((pixelPosition-($(scaleObj).width()/2)))+'px'; 588 };
629 }
630 };
631 } 589 }
632 590
633 function sliderObject(audioObject,interfaceObjects,index) { 591 function sliderObject(audioObject, interfaceObjects, index) {
634 // Create a new slider object; 592 // Create a new slider object;
635 this.parent = audioObject; 593 this.parent = audioObject;
636 this.trackSliderObjects = []; 594 this.trackSliderObjects = [];
637 this.label = null; 595 this.label = null;
638 this.playing = false; 596 this.playing = false;
639 switch(audioObject.specification.parent.label) { 597 switch (audioObject.specification.parent.label) {
640 case "letter": 598 case "letter":
641 this.label = String.fromCharCode(97 + index); 599 this.label = String.fromCharCode(97 + index);
642 break; 600 break;
643 case "capital": 601 case "capital":
644 this.label = String.fromCharCode(65 + index); 602 this.label = String.fromCharCode(65 + index);
645 break; 603 break;
646 case "none": 604 case "none":
647 this.label = ""; 605 this.label = "";
648 break; 606 break;
649 default: 607 default:
650 this.label = ""+(index+1); 608 this.label = "" + (index + 1);
651 break; 609 break;
652 } 610 }
653 for (var i=0; i<interfaceContext.interfaceSliders.length; i++) 611 for (var i = 0; i < interfaceContext.interfaceSliders.length; i++) {
654 { 612 var trackObj = interfaceContext.interfaceSliders[i].createSliderObject(audioObject, this.label);
655 var trackObj = interfaceContext.interfaceSliders[i].createSliderObject(audioObject,this.label); 613 this.trackSliderObjects.push(trackObj);
656 this.trackSliderObjects.push(trackObj); 614 }
657 } 615
658 616 // Onclick, switch playback to that track
659 // Onclick, switch playback to that track 617
660 618 this.enable = function () {
661 this.enable = function() { 619 if (this.parent.state == 1) {
662 if (this.parent.state == 1) 620 $(this.trackSliderObjects).each(function (i, trackObj) {
663 { 621 $(trackObj).removeClass('track-slider-disabled');
664 $(this.trackSliderObjects).each(function(i,trackObj){ 622 });
665 $(trackObj).removeClass('track-slider-disabled'); 623 }
666 }); 624 };
667 } 625 this.updateLoading = function (progress) {
668 }; 626 if (progress != 100) {
669 this.updateLoading = function(progress) 627 progress = String(progress);
670 { 628 progress = progress.split('.')[0];
671 if (progress != 100) 629 this.trackSliderObjects[0].children[0].textContent = progress + '%';
672 { 630 } else {
673 progress = String(progress); 631 this.trackSliderObjects[0].children[0].textContent = this.label;
674 progress = progress.split('.')[0]; 632 }
675 this.trackSliderObjects[0].children[0].textContent = progress+'%'; 633 };
676 } else { 634 this.startPlayback = function () {
677 this.trackSliderObjects[0].children[0].textContent = this.label;
678 }
679 };
680 this.startPlayback = function()
681 {
682 $('.track-slider').removeClass('track-slider-playing'); 635 $('.track-slider').removeClass('track-slider-playing');
683 var name = ".track-slider-"+this.parent.id; 636 var name = ".track-slider-" + this.parent.id;
684 $(name).addClass('track-slider-playing'); 637 $(name).addClass('track-slider-playing');
685 $('.comment-div').removeClass('comment-box-playing'); 638 $('.comment-div').removeClass('comment-box-playing');
686 $('#comment-div-'+this.parent.id).addClass('comment-box-playing'); 639 $('#comment-div-' + this.parent.id).addClass('comment-box-playing');
687 $('.outside-reference').removeClass('track-slider-playing'); 640 $('.outside-reference').removeClass('track-slider-playing');
688 this.playing = true; 641 this.playing = true;
689 642
690 if (this.parent.specification.parent.playOne || specification.playOne) { 643 if (this.parent.specification.parent.playOne || specification.playOne) {
691 $('.track-slider').addClass('track-slider-disabled'); 644 $('.track-slider').addClass('track-slider-disabled');
692 $('.outside-reference').addClass('track-slider-disabled'); 645 $('.outside-reference').addClass('track-slider-disabled');
693 } 646 }
694 }; 647 };
695 this.stopPlayback = function() 648 this.stopPlayback = function () {
696 {
697 if (this.playing) { 649 if (this.playing) {
698 this.playing = false; 650 this.playing = false;
699 var name = ".track-slider-"+this.parent.id; 651 var name = ".track-slider-" + this.parent.id;
700 $(name).removeClass('track-slider-playing'); 652 $(name).removeClass('track-slider-playing');
701 $('#comment-div-'+this.parent.id).removeClass('comment-box-playing'); 653 $('#comment-div-' + this.parent.id).removeClass('comment-box-playing');
702 $('.track-slider').removeClass('track-slider-disabled'); 654 $('.track-slider').removeClass('track-slider-disabled');
703 $('.outside-reference').removeClass('track-slider-disabled'); 655 $('.outside-reference').removeClass('track-slider-disabled');
704 } 656 }
705 }; 657 };
706 this.exportXMLDOM = function(audioObject) { 658 this.exportXMLDOM = function (audioObject) {
707 // Called by the audioObject holding this element. Must be present 659 // Called by the audioObject holding this element. Must be present
708 var obj = []; 660 var obj = [];
709 $(this.trackSliderObjects).each(function(i,trackObj){ 661 $(this.trackSliderObjects).each(function (i, trackObj) {
710 var node = storage.document.createElement('value'); 662 var node = storage.document.createElement('value');
711 node.setAttribute("interface-name",trackObj.getAttribute("interface-name")); 663 node.setAttribute("interface-name", trackObj.getAttribute("interface-name"));
712 node.textContent = convSliderPosToRate(trackObj); 664 node.textContent = convSliderPosToRate(trackObj);
713 obj.push(node); 665 obj.push(node);
714 }); 666 });
715 667
716 return obj; 668 return obj;
717 }; 669 };
718 this.getValue = function() { 670 this.getValue = function () {
719 return convSliderPosToRate(this.trackSliderObjects[0]); 671 return convSliderPosToRate(this.trackSliderObjects[0]);
720 }; 672 };
721 this.getPresentedId = function() 673 this.getPresentedId = function () {
722 { 674 return this.label;
723 return this.label; 675 };
724 }; 676 this.canMove = function () {
725 this.canMove = function() 677 return true;
726 { 678 };
727 return true; 679 this.error = function () {
728 }; 680 // audioObject has an error!!
729 this.error = function() {
730 // audioObject has an error!!
731 this.playback.textContent = "Error"; 681 this.playback.textContent = "Error";
732 $(this.playback).addClass("error-colour"); 682 $(this.playback).addClass("error-colour");
733 } 683 }
734 } 684 }
735 685
736 function outsideReferenceDOM(audioObject,index,inject) 686 function outsideReferenceDOM(audioObject, index, inject) {
737 { 687 this.parent = audioObject;
738 this.parent = audioObject; 688 this.outsideReferenceHolder = document.createElement('div');
739 this.outsideReferenceHolder = document.createElement('div'); 689 this.outsideReferenceHolder.id = 'outside-reference';
740 this.outsideReferenceHolder.id = 'outside-reference'; 690 this.outsideReferenceHolder.className = 'outside-reference track-slider-disabled';
741 this.outsideReferenceHolder.className = 'outside-reference track-slider-disabled'; 691 var outsideReferenceHolderspan = document.createElement('span');
742 var outsideReferenceHolderspan = document.createElement('span'); 692 outsideReferenceHolderspan.textContent = 'Reference';
743 outsideReferenceHolderspan.textContent = 'Reference'; 693 this.outsideReferenceHolder.appendChild(outsideReferenceHolderspan);
744 this.outsideReferenceHolder.appendChild(outsideReferenceHolderspan); 694 this.outsideReferenceHolder.setAttribute('track-id', index);
745 this.outsideReferenceHolder.setAttribute('track-id',index); 695
746 696 this.outsideReferenceHolder.onclick = function (event) {
747 this.outsideReferenceHolder.onclick = function(event) 697 audioEngineContext.play(event.currentTarget.getAttribute('track-id'));
748 { 698 $('.track-slider').removeClass('track-slider-playing');
749 audioEngineContext.play(event.currentTarget.getAttribute('track-id'));
750 $('.track-slider').removeClass('track-slider-playing');
751 $('.comment-div').removeClass('comment-box-playing'); 699 $('.comment-div').removeClass('comment-box-playing');
752 if (event.currentTarget.nodeName == 'DIV') { 700 if (event.currentTarget.nodeName == 'DIV') {
753 $(event.currentTarget).addClass('track-slider-playing'); 701 $(event.currentTarget).addClass('track-slider-playing');
754 } else { 702 } else {
755 $(event.currentTarget.parentElement).addClass('track-slider-playing'); 703 $(event.currentTarget.parentElement).addClass('track-slider-playing');
756 } 704 }
757 }; 705 };
758 inject.appendChild(this.outsideReferenceHolder); 706 inject.appendChild(this.outsideReferenceHolder);
759 this.enable = function() 707 this.enable = function () {
760 { 708 if (this.parent.state == 1) {
761 if (this.parent.state == 1) 709 $(this.outsideReferenceHolder).removeClass('track-slider-disabled');
762 { 710 }
763 $(this.outsideReferenceHolder).removeClass('track-slider-disabled'); 711 };
764 } 712 this.updateLoading = function (progress) {
765 }; 713 if (progress != 100) {
766 this.updateLoading = function(progress) 714 progress = String(progress);
767 { 715 progress = progress.split('.')[0];
768 if (progress != 100) 716 this.outsideReferenceHolder.firstChild.textContent = progress + '%';
769 { 717 } else {
770 progress = String(progress); 718 this.outsideReferenceHolder.firstChild.textContent = "Play Reference";
771 progress = progress.split('.')[0]; 719 }
772 this.outsideReferenceHolder.firstChild.textContent = progress+'%'; 720 };
773 } else { 721 this.startPlayback = function () {
774 this.outsideReferenceHolder.firstChild.textContent = "Play Reference";
775 }
776 };
777 this.startPlayback = function()
778 {
779 $('.track-slider').removeClass('track-slider-playing'); 722 $('.track-slider').removeClass('track-slider-playing');
780 $(this.outsideReferenceHolder).addClass('track-slider-playing'); 723 $(this.outsideReferenceHolder).addClass('track-slider-playing');
781 $('.comment-div').removeClass('comment-box-playing'); 724 $('.comment-div').removeClass('comment-box-playing');
782 }; 725 };
783 this.stopPlayback = function() 726 this.stopPlayback = function () {
784 {
785 $(this.outsideReferenceHolder).removeClass('track-slider-playing'); 727 $(this.outsideReferenceHolder).removeClass('track-slider-playing');
786 }; 728 };
787 this.exportXMLDOM = function(audioObject) 729 this.exportXMLDOM = function (audioObject) {
788 { 730 return null;
789 return null; 731 };
790 }; 732 this.getValue = function () {
791 this.getValue = function() 733 return 0;
792 { 734 };
793 return 0; 735 this.getPresentedId = function () {
794 }; 736 return 'reference';
795 this.getPresentedId = function() 737 };
796 { 738 this.canMove = function () {
797 return 'reference'; 739 return false;
798 }; 740 };
799 this.canMove = function() 741 this.error = function () {
800 { 742 // audioObject has an error!!
801 return false;
802 };
803 this.error = function() {
804 // audioObject has an error!!
805 this.outsideReferenceHolder.textContent = "Error"; 743 this.outsideReferenceHolder.textContent = "Error";
806 $(this.outsideReferenceHolder).addClass("error-colour"); 744 $(this.outsideReferenceHolder).addClass("error-colour");
807 } 745 }
808 } 746 }
809 747
810 function buttonSubmitClick() 748 function buttonSubmitClick() {
811 { 749 var checks = [];
812 var checks = []; 750 checks = checks.concat(testState.currentStateMap.interfaces[0].options);
813 checks = checks.concat(testState.currentStateMap.interfaces[0].options); 751 checks = checks.concat(specification.interfaces.options);
814 checks = checks.concat(specification.interfaces.options); 752 var canContinue = true;
815 var canContinue = true; 753
816 754 // Check that the anchor and reference objects are correctly placed
817 // Check that the anchor and reference objects are correctly placed 755 if (interfaceContext.checkHiddenAnchor() == false) {
818 if (interfaceContext.checkHiddenAnchor() == false) {return;} 756 return;
819 if (interfaceContext.checkHiddenReference() == false) {return;} 757 }
820 758 if (interfaceContext.checkHiddenReference() == false) {
821 for (var i=0; i<checks.length; i++) { 759 return;
822 if (checks[i].type == 'check') 760 }
823 { 761
824 switch(checks[i].name) { 762 for (var i = 0; i < checks.length; i++) {
825 case 'fragmentPlayed': 763 if (checks[i].type == 'check') {
826 // Check if all fragments have been played 764 switch (checks[i].name) {
827 var checkState = interfaceContext.checkAllPlayed(); 765 case 'fragmentPlayed':
828 if (checkState == false) {canContinue = false;} 766 // Check if all fragments have been played
829 break; 767 var checkState = interfaceContext.checkAllPlayed();
830 case 'fragmentFullPlayback': 768 if (checkState == false) {
831 // Check all fragments have been played to their full length 769 canContinue = false;
832 var checkState = interfaceContext.checkFragmentsFullyPlayed(); 770 }
833 if (checkState == false) {canContinue = false;} 771 break;
834 break; 772 case 'fragmentFullPlayback':
835 case 'fragmentMoved': 773 // Check all fragments have been played to their full length
836 // Check all fragment sliders have been moved. 774 var checkState = interfaceContext.checkFragmentsFullyPlayed();
837 var checkState = interfaceContext.checkAllMoved(); 775 if (checkState == false) {
838 if (checkState == false) {canContinue = false;} 776 canContinue = false;
839 break; 777 }
840 case 'fragmentComments': 778 break;
841 // Check all fragment sliders have been moved. 779 case 'fragmentMoved':
842 var checkState = interfaceContext.checkAllCommented(); 780 // Check all fragment sliders have been moved.
843 if (checkState == false) {canContinue = false;} 781 var checkState = interfaceContext.checkAllMoved();
844 break; 782 if (checkState == false) {
845 case 'scalerange': 783 canContinue = false;
846 // Check the scale is used to its full width outlined by the node 784 }
847 var checkState = interfaceContext.checkScaleRange(); 785 break;
848 if (checkState == false) {canContinue = false;} 786 case 'fragmentComments':
849 break; 787 // Check all fragment sliders have been moved.
850 default: 788 var checkState = interfaceContext.checkAllCommented();
851 console.log("WARNING - Check option "+checks[i].name+" is not supported on this interface"); 789 if (checkState == false) {
852 break; 790 canContinue = false;
853 } 791 }
854 792 break;
855 } 793 case 'scalerange':
856 if (!canContinue) {break;} 794 // Check the scale is used to its full width outlined by the node
857 } 795 var checkState = interfaceContext.checkScaleRange();
858 796 if (checkState == false) {
797 canContinue = false;
798 }
799 break;
800 default:
801 console.log("WARNING - Check option " + checks[i].name + " is not supported on this interface");
802 break;
803 }
804
805 }
806 if (!canContinue) {
807 break;
808 }
809 }
810
859 if (canContinue) { 811 if (canContinue) {
860 if (audioEngineContext.status == 1) { 812 if (audioEngineContext.status == 1) {
861 var playback = document.getElementById('playback-button'); 813 var playback = document.getElementById('playback-button');
862 playback.click(); 814 playback.click();
863 // This function is called when the submit button is clicked. Will check for any further tests to perform, or any post-test options 815 // This function is called when the submit button is clicked. Will check for any further tests to perform, or any post-test options
864 } else 816 } else {
865 { 817 if (audioEngineContext.timer.testStarted == false) {
866 if (audioEngineContext.timer.testStarted == false) 818 interfaceContext.lightbox.post("Warning", 'You have not started the test! Please click a fragment to begin the test!');
867 { 819 return;
868 interfaceContext.lightbox.post("Warning",'You have not started the test! Please click a fragment to begin the test!'); 820 }
869 return; 821 }
870 } 822 testState.advanceState();
871 } 823 }
872 testState.advanceState();
873 }
874 } 824 }
875 825
876 function convSliderPosToRate(trackSlider) 826 function convSliderPosToRate(trackSlider) {
877 { 827 var slider = trackSlider.parentElement;
878 var slider = trackSlider.parentElement; 828 var maxPix = $(slider).width();
879 var maxPix = $(slider).width(); 829 var marginsize = 50;
880 var marginsize = 50; 830 var pix = trackSlider.style.left;
881 var pix = trackSlider.style.left; 831 pix = pix.substr(0, pix.length - 2);
882 pix = pix.substr(0,pix.length-2); 832 var rate = (pix - marginsize) / maxPix;
883 var rate = (pix-marginsize)/maxPix; 833 return rate;
884 return rate;
885 } 834 }
886 835
887 function resizeWindow(event){ 836 function resizeWindow(event) {
888 // Function called when the window has been resized. 837 // Function called when the window has been resized.
889 // MANDATORY FUNCTION 838 // MANDATORY FUNCTION
890 839
891 // Resize the slider objects 840 // Resize the slider objects
892 for (var i=0; i<interfaceContext.interfaceSliders.length; i++) 841 for (var i = 0; i < interfaceContext.interfaceSliders.length; i++) {
893 { 842 interfaceContext.interfaceSliders[i].resize(event);
894 interfaceContext.interfaceSliders[i].resize(event); 843 }
895 }
896 } 844 }
897 845
898 function pageXMLSave(store, pageSpecification) 846 function pageXMLSave(store, pageSpecification) {
899 { 847 // MANDATORY
900 // MANDATORY 848 // Saves a specific test page
901 // Saves a specific test page 849 // You can use this space to add any extra nodes to your XML <audioHolder> saves
902 // You can use this space to add any extra nodes to your XML <audioHolder> saves 850 // Get the current <page> information in store (remember to appendChild your data to it)
903 // Get the current <page> information in store (remember to appendChild your data to it) 851 // pageSpecification is the current page node configuration
904 // pageSpecification is the current page node configuration 852 // To create new XML nodes, use storage.document.createElement();
905 // To create new XML nodes, use storage.document.createElement(); 853
906 854 if (interfaceContext.interfaceSliders.length == 1) {
907 if (interfaceContext.interfaceSliders.length == 1) 855 // If there is only one axis, there only needs to be one metric return
908 { 856 return;
909 // If there is only one axis, there only needs to be one metric return 857 }
910 return; 858 var audioelements = store.getElementsByTagName("audioelement");
911 } 859 for (var i = 0; i < audioelements.length; i++) {
912 var audioelements = store.getElementsByTagName("audioelement"); 860 // Have to append the metric specific nodes
913 for (var i=0; i<audioelements.length; i++) 861 if (pageSpecification.outsideReference == null || pageSpecification.outsideReference.id != audioelements[i].id) {
914 { 862 var inject = audioelements[i].getElementsByTagName("metric");
915 // Have to append the metric specific nodes 863 if (inject.length == 0) {
916 if (pageSpecification.outsideReference == null || pageSpecification.outsideReference.id != audioelements[i].id) 864 inject = storage.document.createElement("metric");
917 { 865 } else {
918 var inject = audioelements[i].getElementsByTagName("metric"); 866 inject = inject[0];
919 if (inject.length == 0) 867 }
920 { 868 for (var k = 0; k < interfaceContext.interfaceSliders.length; k++) {
921 inject = storage.document.createElement("metric"); 869 var mrnodes = interfaceContext.interfaceSliders[k].metrics[i].exportXMLDOM(inject);
922 } else { 870 for (var j = 0; j < mrnodes.length; j++) {
923 inject = inject[0]; 871 var name = mrnodes[j].getAttribute("name");
924 } 872 if (name == "elementTracker" || name == "elementTrackerFull" || name == "elementInitialPosition" || name == "elementFlagMoved") {
925 for (var k=0; k<interfaceContext.interfaceSliders.length; k++) 873 mrnodes[j].setAttribute("interface-name", interfaceContext.interfaceSliders[k].name);
926 { 874 mrnodes[j].setAttribute("interface-id", k);
927 var mrnodes = interfaceContext.interfaceSliders[k].metrics[i].exportXMLDOM(inject); 875 inject.appendChild(mrnodes[j]);
928 for (var j=0; j<mrnodes.length; j++) 876 }
929 { 877 }
930 var name = mrnodes[j].getAttribute("name"); 878 }
931 if (name == "elementTracker" || name == "elementTrackerFull" || name == "elementInitialPosition" || name == "elementFlagMoved") 879 }
932 { 880 }
933 mrnodes[j].setAttribute("interface-name",interfaceContext.interfaceSliders[k].name);
934 mrnodes[j].setAttribute("interface-id",k);
935 inject.appendChild(mrnodes[j]);
936 }
937 }
938 }
939 }
940 }
941 } 881 }