comparison interfaces/mushra.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 342ef7948c47
comparison
equal deleted inserted replaced
2536:527020a63203 2538:464c6c6692d6
5 5
6 // Once this is loaded and parsed, begin execution 6 // Once this is loaded and parsed, begin execution
7 loadInterface(); 7 loadInterface();
8 8
9 function loadInterface() { 9 function loadInterface() {
10 // Get the dimensions of the screen available to the page 10 // Get the dimensions of the screen available to the page
11 var width = window.innerWidth; 11 var width = window.innerWidth;
12 var height = window.innerHeight; 12 var height = window.innerHeight;
13 13
14 // The injection point into the HTML page 14 // The injection point into the HTML page
15 interfaceContext.insertPoint = document.getElementById("topLevelBody"); 15 interfaceContext.insertPoint = document.getElementById("topLevelBody");
16 var testContent = document.createElement('div'); 16 var testContent = document.createElement('div');
17 testContent.id = 'testContent'; 17 testContent.id = 'testContent';
18 18
19 // Create the top div for the Title element 19 // Create the top div for the Title element
20 var titleAttr = specification.title; 20 var titleAttr = specification.title;
21 var title = document.createElement('div'); 21 var title = document.createElement('div');
22 title.className = "title"; 22 title.className = "title";
23 title.align = "center"; 23 title.align = "center";
24 var titleSpan = document.createElement('span'); 24 var titleSpan = document.createElement('span');
25 titleSpan.id = "test-title"; 25 titleSpan.id = "test-title";
26 26
27 // Set title to that defined in XML, else set to default 27 // Set title to that defined in XML, else set to default
28 if (titleAttr != undefined) { 28 if (titleAttr != undefined) {
29 titleSpan.textContent = titleAttr; 29 titleSpan.textContent = titleAttr;
30 } else { 30 } else {
31 titleSpan.textContent = 'Listening test'; 31 titleSpan.textContent = 'Listening test';
32 } 32 }
33 // Insert the titleSpan element into the title div element. 33 // Insert the titleSpan element into the title div element.
34 title.appendChild(titleSpan); 34 title.appendChild(titleSpan);
35 35
36 var pagetitle = document.createElement('div'); 36 var pagetitle = document.createElement('div');
37 pagetitle.className = "pageTitle"; 37 pagetitle.className = "pageTitle";
38 pagetitle.align = "center"; 38 pagetitle.align = "center";
39 var titleSpan = document.createElement('span'); 39 var titleSpan = document.createElement('span');
40 titleSpan.id = "pageTitle"; 40 titleSpan.id = "pageTitle";
41 pagetitle.appendChild(titleSpan); 41 pagetitle.appendChild(titleSpan);
42 42
43 // Create Interface buttons! 43 // Create Interface buttons!
44 var interfaceButtons = document.createElement('div'); 44 var interfaceButtons = document.createElement('div');
45 interfaceButtons.id = 'interface-buttons'; 45 interfaceButtons.id = 'interface-buttons';
46 interfaceButtons.style.height = '25px'; 46 interfaceButtons.style.height = '25px';
47 47
48 // Create playback start/stop points 48 // Create playback start/stop points
49 var playback = document.createElement("button"); 49 var playback = document.createElement("button");
50 playback.innerHTML = 'Stop'; 50 playback.innerHTML = 'Stop';
51 playback.id = 'playback-button'; 51 playback.id = 'playback-button';
52 playback.style.float = 'left'; 52 playback.style.float = 'left';
53 // onclick function. Check if it is playing or not, call the correct function in the 53 // onclick function. Check if it is playing or not, call the correct function in the
54 // audioEngine, change the button text to reflect the next state. 54 // audioEngine, change the button text to reflect the next state.
55 playback.onclick = function() { 55 playback.onclick = function () {
56 if (audioEngineContext.status == 1) { 56 if (audioEngineContext.status == 1) {
57 audioEngineContext.stop(); 57 audioEngineContext.stop();
58 this.innerHTML = 'Stop'; 58 this.innerHTML = 'Stop';
59 var time = audioEngineContext.timer.getTestTime(); 59 var time = audioEngineContext.timer.getTestTime();
60 console.log('Stopped at ' + time); // DEBUG/SAFETY 60 console.log('Stopped at ' + time); // DEBUG/SAFETY
61 } 61 }
62 }; 62 };
63 // Create Submit (save) button 63 // Create Submit (save) button
64 var submit = document.createElement("button"); 64 var submit = document.createElement("button");
65 submit.innerHTML = 'Next'; 65 submit.innerHTML = 'Next';
66 submit.onclick = buttonSubmitClick; 66 submit.onclick = buttonSubmitClick;
67 submit.id = 'submit-button'; 67 submit.id = 'submit-button';
68 submit.style.float = 'left'; 68 submit.style.float = 'left';
69 // Append the interface buttons into the interfaceButtons object. 69 // Append the interface buttons into the interfaceButtons object.
70 interfaceButtons.appendChild(playback); 70 interfaceButtons.appendChild(playback);
71 interfaceButtons.appendChild(submit); 71 interfaceButtons.appendChild(submit);
72 72
73 // Create outside reference holder 73 // Create outside reference holder
74 var outsideRef = document.createElement("div"); 74 var outsideRef = document.createElement("div");
75 outsideRef.id = "outside-reference-holder"; 75 outsideRef.id = "outside-reference-holder";
76 76
77 77
78 // Create a slider box 78 // Create a slider box
79 var sliderBox = document.createElement('div'); 79 var sliderBox = document.createElement('div');
80 sliderBox.style.width = "100%"; 80 sliderBox.style.width = "100%";
81 sliderBox.style.height = window.innerHeight - 200+12 + 'px'; 81 sliderBox.style.height = window.innerHeight - 200 + 12 + 'px';
82 sliderBox.style.marginBottom = '10px'; 82 sliderBox.style.marginBottom = '10px';
83 sliderBox.id = 'slider'; 83 sliderBox.id = 'slider';
84 var scaleHolder = document.createElement('div'); 84 var scaleHolder = document.createElement('div');
85 scaleHolder.id = "scale-holder"; 85 scaleHolder.id = "scale-holder";
86 sliderBox.appendChild(scaleHolder); 86 sliderBox.appendChild(scaleHolder);
87 var scaleText = document.createElement('div'); 87 var scaleText = document.createElement('div');
88 scaleText.id = "scale-text-holder"; 88 scaleText.id = "scale-text-holder";
89 scaleHolder.appendChild(scaleText); 89 scaleHolder.appendChild(scaleText);
90 var scaleCanvas = document.createElement('canvas'); 90 var scaleCanvas = document.createElement('canvas');
91 scaleCanvas.id = "scale-canvas"; 91 scaleCanvas.id = "scale-canvas";
92 scaleHolder.appendChild(scaleCanvas); 92 scaleHolder.appendChild(scaleCanvas);
93 var sliderObjectHolder = document.createElement('div'); 93 var sliderObjectHolder = document.createElement('div');
94 sliderObjectHolder.id = 'slider-holder'; 94 sliderObjectHolder.id = 'slider-holder';
95 sliderObjectHolder.align = "center"; 95 sliderObjectHolder.align = "center";
96 sliderBox.appendChild(sliderObjectHolder); 96 sliderBox.appendChild(sliderObjectHolder);
97 97
98 // Global parent for the comment boxes on the page 98 // Global parent for the comment boxes on the page
99 var feedbackHolder = document.createElement('div'); 99 var feedbackHolder = document.createElement('div');
100 feedbackHolder.id = 'feedbackHolder'; 100 feedbackHolder.id = 'feedbackHolder';
101 101
102 testContent.style.zIndex = 1; 102 testContent.style.zIndex = 1;
103 interfaceContext.insertPoint.innerHTML = ""; // Clear the current schema 103 interfaceContext.insertPoint.innerHTML = ""; // Clear the current schema
104 104
105 // Inject into HTML 105 // Inject into HTML
106 testContent.appendChild(title); // Insert the title 106 testContent.appendChild(title); // Insert the title
107 testContent.appendChild(pagetitle); 107 testContent.appendChild(pagetitle);
108 testContent.appendChild(interfaceButtons); 108 testContent.appendChild(interfaceButtons);
109 testContent.appendChild(outsideRef); 109 testContent.appendChild(outsideRef);
110 testContent.appendChild(sliderBox); 110 testContent.appendChild(sliderBox);
111 testContent.appendChild(feedbackHolder); 111 testContent.appendChild(feedbackHolder);
112 interfaceContext.insertPoint.appendChild(testContent); 112 interfaceContext.insertPoint.appendChild(testContent);
113 113
114 // Load the full interface 114 // Load the full interface
115 testState.initialise(); 115 testState.initialise();
116 testState.advanceState(); 116 testState.advanceState();
117 } 117 }
118 118
119 function loadTest(audioHolderObject) 119 function loadTest(audioHolderObject) {
120 { 120 var id = audioHolderObject.id;
121 var id = audioHolderObject.id; 121
122 122 var feedbackHolder = document.getElementById('feedbackHolder');
123 var feedbackHolder = document.getElementById('feedbackHolder');
124 feedbackHolder.innerHTML = ""; 123 feedbackHolder.innerHTML = "";
125 var interfaceObj = audioHolderObject.interfaces; 124 var interfaceObj = audioHolderObject.interfaces;
126 if (interfaceObj.length > 1) 125 if (interfaceObj.length > 1) {
127 { 126 console.log("WARNING - This interface only supports one <interface> node per page. Using first interface node");
128 console.log("WARNING - This interface only supports one <interface> node per page. Using first interface node"); 127 }
129 } 128 interfaceObj = interfaceObj[0];
130 interfaceObj = interfaceObj[0]; 129
131
132 // Set the page title 130 // Set the page title
133 if (typeof audioHolderObject.title == "string" && audioHolderObject.title.length > 0) { 131 if (typeof audioHolderObject.title == "string" && audioHolderObject.title.length > 0) {
134 document.getElementById("test-title").textContent = audioHolderObject.title 132 document.getElementById("test-title").textContent = audioHolderObject.title
135 } 133 }
136 134
137 if(interfaceObj.title != null) 135 if (interfaceObj.title != null) {
138 { 136 document.getElementById("pageTitle").textContent = interfaceObj.title;
139 document.getElementById("pageTitle").textContent = interfaceObj.title; 137 }
140 } 138
141 139 // Delete outside reference
142 // Delete outside reference 140 var outsideReferenceHolder = document.getElementById("outside-reference-holder");
143 var outsideReferenceHolder = document.getElementById("outside-reference-holder");
144 outsideReferenceHolder.innerHTML = ""; 141 outsideReferenceHolder.innerHTML = "";
145 142
146 var sliderBox = document.getElementById('slider-holder'); 143 var sliderBox = document.getElementById('slider-holder');
147 sliderBox.innerHTML = ""; 144 sliderBox.innerHTML = "";
148 145
149 var commentBoxPrefix = "Comment on track"; 146 var commentBoxPrefix = "Comment on track";
150 if (interfaceObj.commentBoxPrefix != undefined) { 147 if (interfaceObj.commentBoxPrefix != undefined) {
151 commentBoxPrefix = interfaceObj.commentBoxPrefix; 148 commentBoxPrefix = interfaceObj.commentBoxPrefix;
152 } 149 }
153 var loopPlayback = audioHolderObject.loop; 150 var loopPlayback = audioHolderObject.loop;
154 151
155 currentTestHolder = document.createElement('audioHolder'); 152 currentTestHolder = document.createElement('audioHolder');
156 currentTestHolder.id = audioHolderObject.id; 153 currentTestHolder.id = audioHolderObject.id;
157 currentTestHolder.repeatCount = audioHolderObject.repeatCount; 154 currentTestHolder.repeatCount = audioHolderObject.repeatCount;
158 155
159 // Find all the audioElements from the audioHolder 156 // Find all the audioElements from the audioHolder
160 var index = 0; 157 var index = 0;
161 $(audioHolderObject.audioElements).each(function(index,element){ 158 $(audioHolderObject.audioElements).each(function (index, element) {
162 // Find URL of track 159 // Find URL of track
163 // In this jQuery loop, variable 'this' holds the current audioElement. 160 // In this jQuery loop, variable 'this' holds the current audioElement.
164 161
165 var audioObject = audioEngineContext.newTrack(element); 162 var audioObject = audioEngineContext.newTrack(element);
166 if (element.type == 'outside-reference') 163 if (element.type == 'outside-reference') {
167 { 164 // Construct outside reference;
168 // Construct outside reference; 165 var orNode = new interfaceContext.outsideReferenceDOM(audioObject, index, outsideReferenceHolder);
169 var orNode = new interfaceContext.outsideReferenceDOM(audioObject,index,outsideReferenceHolder); 166 audioObject.bindInterface(orNode);
170 audioObject.bindInterface(orNode); 167 } else {
171 } else { 168 // Create a slider per track
172 // Create a slider per track 169 switch (audioObject.specification.parent.label) {
173 switch(audioObject.specification.parent.label) {
174 case "none": 170 case "none":
175 label = ""; 171 label = "";
176 break; 172 break;
177 case "letter": 173 case "letter":
178 label = String.fromCharCode(97 + index); 174 label = String.fromCharCode(97 + index);
179 break; 175 break;
180 case "capital": 176 case "capital":
181 label = String.fromCharCode(65 + index); 177 label = String.fromCharCode(65 + index);
182 break; 178 break;
183 default: 179 default:
184 label = ""+index; 180 label = "" + index;
185 break; 181 break;
186 } 182 }
187 var sliderObj = new sliderObject(audioObject,label); 183 var sliderObj = new sliderObject(audioObject, label);
188 184
189 if (typeof audioHolderObject.initialPosition === "number") 185 if (typeof audioHolderObject.initialPosition === "number") {
190 { 186 // Set the values
191 // Set the values 187 sliderObj.slider.value = audioHolderObject.initalPosition;
192 sliderObj.slider.value = audioHolderObject.initalPosition; 188 } else {
193 } else { 189 // Distribute it randomnly
194 // Distribute it randomnly 190 sliderObj.slider.value = Math.random();
195 sliderObj.slider.value = Math.random(); 191 }
196 } 192 sliderBox.appendChild(sliderObj.holder);
197 sliderBox.appendChild(sliderObj.holder); 193 audioObject.bindInterface(sliderObj);
198 audioObject.bindInterface(sliderObj);
199 interfaceContext.commentBoxes.createCommentBox(audioObject); 194 interfaceContext.commentBoxes.createCommentBox(audioObject);
200 index += 1; 195 index += 1;
201 } 196 }
202 197
203 }); 198 });
204 199
205 200
206 var interfaceOptions = specification.interfaces.options.concat(interfaceObj.options); 201 var interfaceOptions = specification.interfaces.options.concat(interfaceObj.options);
207 for (var option of interfaceOptions) 202 for (var option of interfaceOptions) {
208 { 203 if (option.type == "show") {
209 if (option.type == "show") 204 switch (option.name) {
210 {
211 switch(option.name) {
212 case "playhead": 205 case "playhead":
213 var playbackHolder = document.getElementById('playback-holder'); 206 var playbackHolder = document.getElementById('playback-holder');
214 if (playbackHolder == null) 207 if (playbackHolder == null) {
215 {
216 playbackHolder = document.createElement('div'); 208 playbackHolder = document.createElement('div');
217 playbackHolder.style.width = "100%"; 209 playbackHolder.style.width = "100%";
218 playbackHolder.align = 'center'; 210 playbackHolder.align = 'center';
219 playbackHolder.appendChild(interfaceContext.playhead.object); 211 playbackHolder.appendChild(interfaceContext.playhead.object);
220 feedbackHolder.appendChild(playbackHolder); 212 feedbackHolder.appendChild(playbackHolder);
221 } 213 }
222 break; 214 break;
223 case "page-count": 215 case "page-count":
224 var pagecountHolder = document.getElementById('page-count'); 216 var pagecountHolder = document.getElementById('page-count');
225 if (pagecountHolder == null) 217 if (pagecountHolder == null) {
226 {
227 pagecountHolder = document.createElement('div'); 218 pagecountHolder = document.createElement('div');
228 pagecountHolder.id = 'page-count'; 219 pagecountHolder.id = 'page-count';
229 } 220 }
230 pagecountHolder.innerHTML = '<span>Page '+(testState.stateIndex+1)+' of '+testState.stateMap.length+'</span>'; 221 pagecountHolder.innerHTML = '<span>Page ' + (testState.stateIndex + 1) + ' of ' + testState.stateMap.length + '</span>';
231 var inject = document.getElementById('interface-buttons'); 222 var inject = document.getElementById('interface-buttons');
232 inject.appendChild(pagecountHolder); 223 inject.appendChild(pagecountHolder);
233 break; 224 break;
234 case "volume": 225 case "volume":
235 if (document.getElementById('master-volume-holder') == null) 226 if (document.getElementById('master-volume-holder') == null) {
236 {
237 feedbackHolder.appendChild(interfaceContext.volume.object); 227 feedbackHolder.appendChild(interfaceContext.volume.object);
238 } 228 }
239 break; 229 break;
240 case "comments": 230 case "comments":
241 interfaceContext.commentBoxes.showCommentBoxes(feedbackHolder,true); 231 interfaceContext.commentBoxes.showCommentBoxes(feedbackHolder, true);
242 break; 232 break;
243 } 233 }
244 } 234 }
245 } 235 }
246 236
247 $(audioHolderObject.commentQuestions).each(function(index,element) { 237 $(audioHolderObject.commentQuestions).each(function (index, element) {
248 var node = interfaceContext.createCommentQuestion(element); 238 var node = interfaceContext.createCommentQuestion(element);
249 feedbackHolder.appendChild(node.holder); 239 feedbackHolder.appendChild(node.holder);
250 }); 240 });
251 241
252 // Auto-align 242 // Auto-align
253 resizeWindow(null); 243 resizeWindow(null);
254 } 244 }
255 245
256 function sliderObject(audioObject,label) 246 function sliderObject(audioObject, label) {
257 { 247 // Constructs the slider object. We use the HTML5 slider object
258 // Constructs the slider object. We use the HTML5 slider object 248 this.parent = audioObject;
259 this.parent = audioObject; 249 this.holder = document.createElement('div');
260 this.holder = document.createElement('div'); 250 this.title = document.createElement('span');
261 this.title = document.createElement('span'); 251 this.slider = document.createElement('input');
262 this.slider = document.createElement('input'); 252 this.play = document.createElement('button');
263 this.play = document.createElement('button'); 253
264 254 this.holder.className = 'track-slider';
265 this.holder.className = 'track-slider'; 255 this.holder.style.height = window.innerHeight - 200 + 'px';
266 this.holder.style.height = window.innerHeight-200 + 'px'; 256 this.holder.appendChild(this.title);
267 this.holder.appendChild(this.title); 257 this.holder.appendChild(this.slider);
268 this.holder.appendChild(this.slider); 258 this.holder.appendChild(this.play);
269 this.holder.appendChild(this.play); 259 this.holder.align = "center";
270 this.holder.align = "center"; 260 if (label == 0) {
271 if (label == 0) 261 this.holder.style.marginLeft = '0px';
272 { 262 }
273 this.holder.style.marginLeft = '0px'; 263 this.holder.setAttribute('trackIndex', audioObject.id);
274 } 264
275 this.holder.setAttribute('trackIndex',audioObject.id); 265 this.title.textContent = label;
276 266 this.title.style.width = "100%";
277 this.title.textContent = label; 267 this.title.style.float = "left";
278 this.title.style.width = "100%"; 268
279 this.title.style.float = "left"; 269 this.slider.type = "range";
280 270 this.slider.className = "track-slider-range track-slider-not-moved";
281 this.slider.type = "range"; 271 this.slider.min = "0";
282 this.slider.className = "track-slider-range track-slider-not-moved"; 272 this.slider.max = "1";
283 this.slider.min = "0"; 273 this.slider.step = "0.01";
284 this.slider.max = "1"; 274 this.slider.setAttribute('orient', 'vertical');
285 this.slider.step = "0.01"; 275 this.slider.style.height = window.innerHeight - 250 + 'px';
286 this.slider.setAttribute('orient','vertical'); 276 this.slider.onchange = function () {
287 this.slider.style.height = window.innerHeight-250 + 'px'; 277 var time = audioEngineContext.timer.getTestTime();
288 this.slider.onchange = function() 278 var id = Number(this.parentNode.getAttribute('trackIndex'));
289 { 279 audioEngineContext.audioObjects[id].metric.moved(time, this.value);
290 var time = audioEngineContext.timer.getTestTime(); 280 console.log('slider ' + id + ' moved to ' + this.value + ' (' + time + ')');
291 var id = Number(this.parentNode.getAttribute('trackIndex')); 281 $(this).removeClass('track-slider-not-moved');
292 audioEngineContext.audioObjects[id].metric.moved(time,this.value); 282 };
293 console.log('slider '+id+' moved to '+this.value+' ('+time+')'); 283
294 $(this).removeClass('track-slider-not-moved'); 284 this.play.textContent = "Loading...";
295 }; 285 this.play.value = audioObject.id;
296 286 this.play.style.float = "left";
297 this.play.textContent = "Loading..."; 287 this.play.style.width = "100%";
298 this.play.value = audioObject.id; 288 this.play.disabled = true;
299 this.play.style.float = "left"; 289 this.play.setAttribute("playstate", "ready");
300 this.play.style.width = "100%"; 290 this.play.onclick = function (event) {
301 this.play.disabled = true; 291 var id = Number(event.currentTarget.value);
302 this.play.setAttribute("playstate","ready"); 292 //audioEngineContext.metric.sliderPlayed(id);
303 this.play.onclick = function(event) 293 if (event.currentTarget.getAttribute("playstate") == "ready") {
304 { 294 audioEngineContext.play(id);
305 var id = Number(event.currentTarget.value); 295 } else if (event.currentTarget.getAttribute("playstate") == "playing") {
306 //audioEngineContext.metric.sliderPlayed(id); 296 audioEngineContext.stop();
307 if (event.currentTarget.getAttribute("playstate") == "ready") 297 }
308 {audioEngineContext.play(id);} 298 };
309 else if (event.currentTarget.getAttribute("playstate") == "playing") 299
310 {audioEngineContext.stop();} 300 this.enable = function () {
311 }; 301 this.play.disabled = false;
312 302 this.play.textContent = "Play";
313 this.enable = function() { 303 $(this.slider).removeClass('track-slider-disabled');
314 this.play.disabled = false; 304 };
315 this.play.textContent = "Play"; 305
316 $(this.slider).removeClass('track-slider-disabled'); 306 this.exportXMLDOM = function (audioObject) {
317 }; 307 // Called by the audioObject holding this element. Must be present
318 308 var node = storage.document.createElement('value');
319 this.exportXMLDOM = function(audioObject) { 309 node.textContent = this.slider.value;
320 // Called by the audioObject holding this element. Must be present 310 return node;
321 var node = storage.document.createElement('value'); 311 };
322 node.textContent = this.slider.value; 312 this.startPlayback = function () {
323 return node;
324 };
325 this.startPlayback = function()
326 {
327 // Called when playback has begun 313 // Called when playback has begun
328 this.play.setAttribute("playstate","playing"); 314 this.play.setAttribute("playstate", "playing");
329 $(".track-slider").removeClass('track-slider-playing'); 315 $(".track-slider").removeClass('track-slider-playing');
330 $(this.holder).addClass('track-slider-playing'); 316 $(this.holder).addClass('track-slider-playing');
331 var outsideReference = document.getElementById('outside-reference'); 317 var outsideReference = document.getElementById('outside-reference');
332 if (outsideReference != null) { 318 if (outsideReference != null) {
333 $(outsideReference).removeClass('track-slider-playing'); 319 $(outsideReference).removeClass('track-slider-playing');
334 } 320 }
335 this.play.textContent = "Stop"; 321 this.play.textContent = "Stop";
336 }; 322 };
337 this.stopPlayback = function() 323 this.stopPlayback = function () {
338 {
339 // Called when playback has stopped. This gets called even if playback never started! 324 // Called when playback has stopped. This gets called even if playback never started!
340 this.play.setAttribute("playstate","ready"); 325 this.play.setAttribute("playstate", "ready");
341 $(this.holder).removeClass('track-slider-playing'); 326 $(this.holder).removeClass('track-slider-playing');
342 this.play.textContent = "Play"; 327 this.play.textContent = "Play";
343 }; 328 };
344 this.getValue = function() { 329 this.getValue = function () {
345 return this.slider.value; 330 return this.slider.value;
346 }; 331 };
347 332
348 this.resize = function(event) 333 this.resize = function (event) {
349 { 334 this.holder.style.height = window.innerHeight - 200 + 'px';
350 this.holder.style.height = window.innerHeight-200 + 'px'; 335 this.slider.style.height = window.innerHeight - 250 + 'px';
351 this.slider.style.height = window.innerHeight-250 + 'px'; 336 };
352 }; 337 this.updateLoading = function (progress) {
353 this.updateLoading = function(progress) 338 progress = String(progress);
354 { 339 progress = progress.substr(0, 5);
355 progress = String(progress); 340 this.play.textContent = "Loading: " + progress + "%";
356 progress = progress.substr(0,5); 341 };
357 this.play.textContent = "Loading: "+progress+"%"; 342
358 }; 343 if (this.parent.state == 1) {
359 344 this.enable();
360 if (this.parent.state == 1) 345 }
361 { 346 this.getPresentedId = function () {
362 this.enable(); 347 return this.title.textContent;
363 } 348 };
364 this.getPresentedId = function() 349 this.canMove = function () {
365 { 350 return true;
366 return this.title.textContent; 351 };
367 }; 352 this.error = function () {
368 this.canMove = function() 353 // audioObject has an error!!
369 {
370 return true;
371 };
372 this.error = function() {
373 // audioObject has an error!!
374 this.playback.textContent = "Error"; 354 this.playback.textContent = "Error";
375 $(this.playback).addClass("error-colour"); 355 $(this.playback).addClass("error-colour");
376 } 356 }
377 } 357 }
378 358
379 function resizeWindow(event) 359 function resizeWindow(event) {
380 { 360 // Function called when the window has been resized.
381 // Function called when the window has been resized. 361 // MANDATORY FUNCTION
382 // MANDATORY FUNCTION 362
383 363 var outsideRef = document.getElementById('outside-reference');
384 var outsideRef = document.getElementById('outside-reference'); 364 if (outsideRef != null) {
385 if(outsideRef != null) 365 outsideRef.style.left = (window.innerWidth - 120) / 2 + 'px';
386 { 366 }
387 outsideRef.style.left = (window.innerWidth-120)/2 + 'px'; 367
388 } 368 // Auto-align
389 369 var numObj = document.getElementsByClassName('track-slider').length;
390 // Auto-align 370 var totalWidth = (numObj - 1) * 150 + 100;
391 var numObj = document.getElementsByClassName('track-slider').length; 371 var diff = (window.innerWidth - totalWidth) / 2;
392 var totalWidth = (numObj-1)*150+100; 372 document.getElementById('slider').style.height = window.innerHeight - 180 + 'px';
393 var diff = (window.innerWidth - totalWidth)/2; 373 if (diff <= 0) {
394 document.getElementById('slider').style.height = window.innerHeight - 180 + 'px'; 374 diff = 0;
395 if (diff <= 0){diff = 0;} 375 }
396 document.getElementById('slider-holder').style.marginLeft = diff + 'px'; 376 document.getElementById('slider-holder').style.marginLeft = diff + 'px';
397 for (var i in audioEngineContext.audioObjects) 377 for (var i in audioEngineContext.audioObjects) {
398 { 378 if (audioEngineContext.audioObjects[i].specification.type != 'outside-reference') {
399 if (audioEngineContext.audioObjects[i].specification.type != 'outside-reference'){ 379 audioEngineContext.audioObjects[i].interfaceDOM.resize(event);
400 audioEngineContext.audioObjects[i].interfaceDOM.resize(event); 380 }
401 } 381 }
402 } 382 document.getElementById('scale-holder').style.marginLeft = (diff - 100) + 'px';
403 document.getElementById('scale-holder').style.marginLeft = (diff-100) + 'px'; 383 document.getElementById('scale-text-holder').style.height = window.innerHeight - 194 + 'px';
404 document.getElementById('scale-text-holder').style.height = window.innerHeight-194 + 'px';
405 // Cheers edge for making me delete a canvas every resize. 384 // Cheers edge for making me delete a canvas every resize.
406 var canvas = document.getElementById('scale-canvas'); 385 var canvas = document.getElementById('scale-canvas');
407 var new_canvas = document.createElement("canvas"); 386 var new_canvas = document.createElement("canvas");
408 new_canvas.id = 'scale-canvas'; 387 new_canvas.id = 'scale-canvas';
409 canvas.parentElement.appendChild(new_canvas); 388 canvas.parentElement.appendChild(new_canvas);
410 canvas.parentElement.removeChild(canvas); 389 canvas.parentElement.removeChild(canvas);
411 new_canvas.width = totalWidth; 390 new_canvas.width = totalWidth;
412 new_canvas.height = window.innerHeight-194; 391 new_canvas.height = window.innerHeight - 194;
413 drawScale(); 392 drawScale();
414 } 393 }
415 394
416 function drawScale() 395 function drawScale() {
417 { 396 var interfaceObj = testState.currentStateMap.interfaces[0];
418 var interfaceObj = testState.currentStateMap.interfaces[0]; 397 var scales = testState.currentStateMap.interfaces[0].scales;
419 var scales = testState.currentStateMap.interfaces[0].scales; 398 scales = scales.sort(function (a, b) {
420 scales = scales.sort(function(a,b) { 399 return a.position - b.position;
421 return a.position - b.position; 400 });
422 }); 401 var canvas = document.getElementById('scale-canvas');
423 var canvas = document.getElementById('scale-canvas'); 402 var ctx = canvas.getContext("2d");
424 var ctx = canvas.getContext("2d"); 403 var height = canvas.height;
425 var height = canvas.height; 404 var width = canvas.width;
426 var width = canvas.width; 405 ctx.clearRect(0, 0, canvas.width, canvas.height);
427 ctx.clearRect(0,0,canvas.width,canvas.height); 406 var draw_heights = [24, height - 34];
428 var draw_heights = [24, height-34]; 407 var textHolder = document.getElementById('scale-text-holder');
429 var textHolder = document.getElementById('scale-text-holder'); 408 textHolder.innerHTML = "";
430 textHolder.innerHTML = ""; 409 var lastHeight = 0;
431 var lastHeight = 0; 410 for (var scale of scales) {
432 for (var scale of scales) 411 var posPercent = scale.position / 100.0;
433 { 412 var posPix = (1 - posPercent) * (draw_heights[1] - draw_heights[0]) + draw_heights[0];
434 var posPercent = scale.position / 100.0; 413 ctx.fillStyle = "#000000";
435 var posPix = (1-posPercent)*(draw_heights[1]-draw_heights[0])+draw_heights[0]; 414 ctx.setLineDash([1, 2]);
436 ctx.fillStyle = "#000000"; 415 ctx.moveTo(0, posPix);
437 ctx.setLineDash([1,2]); 416 ctx.lineTo(width, posPix);
438 ctx.moveTo(0,posPix); 417 ctx.stroke();
439 ctx.lineTo(width,posPix); 418 var text = document.createElement('div');
440 ctx.stroke(); 419 text.align = "right";
441 var text = document.createElement('div'); 420 var textC = document.createElement('span');
442 text.align = "right"; 421 textC.textContent = scale.text;
443 var textC = document.createElement('span'); 422 text.appendChild(textC);
444 textC.textContent = scale.text; 423 text.className = "scale-text";
445 text.appendChild(textC); 424 textHolder.appendChild(text);
446 text.className = "scale-text"; 425 text.style.top = (posPix - 9) + 'px';
447 textHolder.appendChild(text); 426 text.style.left = 100 - ($(text).width() + 3) + 'px';
448 text.style.top = (posPix-9) + 'px'; 427 lastHeight = posPix;
449 text.style.left = 100 - ($(text).width()+3) + 'px'; 428 }
450 lastHeight = posPix;
451 }
452 } 429 }
453 430
454 function buttonSubmitClick() // TODO: Only when all songs have been played! 431 function buttonSubmitClick() // TODO: Only when all songs have been played!
455 { 432 {
456 var checks = []; 433 var checks = [];
457 checks = checks.concat(testState.currentStateMap.interfaces[0].options); 434 checks = checks.concat(testState.currentStateMap.interfaces[0].options);
458 checks = checks.concat(specification.interfaces.options); 435 checks = checks.concat(specification.interfaces.options);
459 var canContinue = true; 436 var canContinue = true;
460 437
461 // Check that the anchor and reference objects are correctly placed 438 // Check that the anchor and reference objects are correctly placed
462 if (interfaceContext.checkHiddenAnchor() == false) {return;} 439 if (interfaceContext.checkHiddenAnchor() == false) {
463 if (interfaceContext.checkHiddenReference() == false) {return;} 440 return;
464 441 }
465 for (var i=0; i<checks.length; i++) { 442 if (interfaceContext.checkHiddenReference() == false) {
466 if (checks[i].type == 'check') 443 return;
467 { 444 }
468 switch(checks[i].name) { 445
469 case 'fragmentPlayed': 446 for (var i = 0; i < checks.length; i++) {
470 // Check if all fragments have been played 447 if (checks[i].type == 'check') {
471 var checkState = interfaceContext.checkAllPlayed(); 448 switch (checks[i].name) {
472 if (checkState == false) {canContinue = false;} 449 case 'fragmentPlayed':
473 break; 450 // Check if all fragments have been played
474 case 'fragmentFullPlayback': 451 var checkState = interfaceContext.checkAllPlayed();
475 // Check all fragments have been played to their full length 452 if (checkState == false) {
476 var checkState = interfaceContext.checkAllPlayed(); 453 canContinue = false;
477 if (checkState == false) {canContinue = false;} 454 }
478 console.log('NOTE: fragmentFullPlayback not currently implemented, performing check fragmentPlayed instead'); 455 break;
479 break; 456 case 'fragmentFullPlayback':
480 case 'fragmentMoved': 457 // Check all fragments have been played to their full length
481 // Check all fragment sliders have been moved. 458 var checkState = interfaceContext.checkAllPlayed();
482 var checkState = interfaceContext.checkAllMoved(); 459 if (checkState == false) {
483 if (checkState == false) {canContinue = false;} 460 canContinue = false;
484 break; 461 }
485 case 'fragmentComments': 462 console.log('NOTE: fragmentFullPlayback not currently implemented, performing check fragmentPlayed instead');
486 // Check all fragment sliders have been moved. 463 break;
487 var checkState = interfaceContext.checkAllCommented(); 464 case 'fragmentMoved':
488 if (checkState == false) {canContinue = false;} 465 // Check all fragment sliders have been moved.
489 break; 466 var checkState = interfaceContext.checkAllMoved();
490 case 'scalerange': 467 if (checkState == false) {
491 // Check the scale has been used effectively 468 canContinue = false;
492 var checkState = interfaceContext.checkScaleRange(checks[i].min,checks[i].max); 469 }
493 if (checkState == false) {canContinue = false;} 470 break;
494 break; 471 case 'fragmentComments':
495 default: 472 // Check all fragment sliders have been moved.
496 console.log("WARNING - Check option "+checks[i].check+" is not supported on this interface"); 473 var checkState = interfaceContext.checkAllCommented();
497 break; 474 if (checkState == false) {
498 } 475 canContinue = false;
499 476 }
500 } 477 break;
501 if (!canContinue) {break;} 478 case 'scalerange':
502 } 479 // Check the scale has been used effectively
503 480 var checkState = interfaceContext.checkScaleRange(checks[i].min, checks[i].max);
481 if (checkState == false) {
482 canContinue = false;
483 }
484 break;
485 default:
486 console.log("WARNING - Check option " + checks[i].check + " is not supported on this interface");
487 break;
488 }
489
490 }
491 if (!canContinue) {
492 break;
493 }
494 }
495
504 if (canContinue) { 496 if (canContinue) {
505 if (audioEngineContext.status == 1) { 497 if (audioEngineContext.status == 1) {
506 var playback = document.getElementById('playback-button'); 498 var playback = document.getElementById('playback-button');
507 playback.click(); 499 playback.click();
508 // This function is called when the submit button is clicked. Will check for any further tests to perform, or any post-test options 500 // This function is called when the submit button is clicked. Will check for any further tests to perform, or any post-test options
509 } else 501 } else {
510 { 502 if (audioEngineContext.timer.testStarted == false) {
511 if (audioEngineContext.timer.testStarted == false) 503 interfaceContext.lightbox.post("Message", 'You have not started the test! Please press start to begin the test!');
512 { 504 return;
513 interfaceContext.lightbox.post("Message",'You have not started the test! Please press start to begin the test!'); 505 }
514 return; 506 }
515 } 507 testState.advanceState();
516 } 508 }
517 testState.advanceState(); 509 }
518 } 510
519 } 511 function pageXMLSave(store, pageSpecification) {
520 512 // MANDATORY
521 function pageXMLSave(store, pageSpecification) 513 // Saves a specific test page
522 { 514 // You can use this space to add any extra nodes to your XML <audioHolder> saves
523 // MANDATORY 515 // Get the current <page> information in store (remember to appendChild your data to it)
524 // Saves a specific test page 516 // pageSpecification is the current page node configuration
525 // You can use this space to add any extra nodes to your XML <audioHolder> saves 517 // To create new XML nodes, use storage.document.createElement();
526 // Get the current <page> information in store (remember to appendChild your data to it) 518 }
527 // pageSpecification is the current page node configuration
528 // To create new XML nodes, use storage.document.createElement();
529 }