Mercurial > hg > webaudioevaluationtool
comparison interfaces/discrete.js @ 3045:f888168418ad
#126 Complete redesign of discrete interface
author | Nicholas Jillings <nicholas.jillings@mail.bcu.ac.uk> |
---|---|
date | Wed, 27 Sep 2017 13:17:11 +0100 |
parents | 5b652438802c |
children | 20de79c56ad7 |
comparison
equal
deleted
inserted
replaced
3044:2020be3c592c | 3045:f888168418ad |
---|---|
1 /* globals interfaceContext, document, window, $, specification, audioEngineContext, console, window, testState, storage */ | 1 /** |
2 * WAET Blank Template | |
3 * Use this to start building your custom interface | |
4 */ | |
5 | |
2 // Once this is loaded and parsed, begin execution | 6 // Once this is loaded and parsed, begin execution |
3 loadInterface(); | 7 loadInterface(); |
4 | 8 |
5 function loadInterface() { | 9 function loadInterface() { |
6 // Use this to do any one-time page / element construction. For instance, placing any stationary text objects, | 10 // Use this to do any one-time page / element construction. For instance, placing any stationary text objects, |
54 this.innerHTML = 'Stop'; | 58 this.innerHTML = 'Stop'; |
55 var time = audioEngineContext.timer.getTestTime(); | 59 var time = audioEngineContext.timer.getTestTime(); |
56 console.log('Stopped at ' + time); // DEBUG/SAFETY | 60 console.log('Stopped at ' + time); // DEBUG/SAFETY |
57 } | 61 } |
58 }; | 62 }; |
59 | |
60 // Create outside reference holder | |
61 var outsideRef = document.createElement("div"); | |
62 outsideRef.id = "outside-reference-holder"; | |
63 | |
64 // Create Submit (save) button | 63 // Create Submit (save) button |
65 var submit = document.createElement("button"); | 64 var submit = document.createElement("button"); |
66 submit.innerHTML = 'Next'; | 65 submit.innerHTML = 'Next'; |
67 submit.onclick = buttonSubmitClick; | 66 submit.onclick = buttonSubmitClick; |
68 submit.id = 'submit-button'; | 67 submit.id = 'submit-button'; |
79 // Append the interface buttons into the interfaceButtons object. | 78 // Append the interface buttons into the interfaceButtons object. |
80 interfaceButtons.appendChild(playback); | 79 interfaceButtons.appendChild(playback); |
81 interfaceButtons.appendChild(submit); | 80 interfaceButtons.appendChild(submit); |
82 interfaceButtons.appendChild(sort); | 81 interfaceButtons.appendChild(sort); |
83 | 82 |
84 // Create a slider box | 83 |
85 var sliderBox = document.createElement('div'); | 84 // Create outside reference holder |
86 sliderBox.style.width = "100%"; | 85 var outsideRef = document.createElement("div"); |
87 sliderBox.style.height = window.innerHeight - 200 + 12 + 'px'; | 86 outsideRef.id = "outside-reference-holder"; |
88 sliderBox.style.marginBottom = '10px'; | 87 |
89 sliderBox.id = 'slider'; | 88 // Create a holder for the slider rows |
90 var scaleHolder = document.createElement('div'); | 89 var sliderBox = document.createElement("div"); |
91 scaleHolder.id = "scale-holder"; | 90 sliderBox.id = 'slider-box'; |
92 scaleHolder.style.marginLeft = "107px"; | 91 var sliderGrid = document.createElement("div"); |
93 sliderBox.appendChild(scaleHolder); | 92 sliderGrid.id = "slider-grid"; |
93 sliderBox.appendChild(sliderGrid); | |
94 var scaleText = document.createElement('div'); | 94 var scaleText = document.createElement('div'); |
95 scaleText.id = "scale-text-holder"; | 95 scaleText.id = "scale-text-holder"; |
96 scaleText.style.height = "25px"; | 96 sliderGrid.appendChild(scaleText); |
97 scaleText.style.width = "100%"; | 97 |
98 scaleHolder.appendChild(scaleText); | |
99 var scaleCanvas = document.createElement('canvas'); | |
100 scaleCanvas.id = "scale-canvas"; | |
101 scaleCanvas.style.marginLeft = "150px"; | |
102 scaleHolder.appendChild(scaleCanvas); | |
103 var sliderObjectHolder = document.createElement('div'); | |
104 sliderObjectHolder.id = 'slider-holder'; | |
105 sliderObjectHolder.align = "center"; | |
106 sliderBox.appendChild(sliderObjectHolder); | |
107 | 98 |
108 // Global parent for the comment boxes on the page | 99 // Global parent for the comment boxes on the page |
109 var feedbackHolder = document.createElement('div'); | 100 var feedbackHolder = document.createElement('div'); |
110 feedbackHolder.id = 'feedbackHolder'; | 101 feedbackHolder.id = 'feedbackHolder'; |
111 | 102 |
122 interfaceContext.insertPoint.appendChild(testContent); | 113 interfaceContext.insertPoint.appendChild(testContent); |
123 | 114 |
124 // Load the full interface | 115 // Load the full interface |
125 testState.initialise(); | 116 testState.initialise(); |
126 testState.advanceState(); | 117 testState.advanceState(); |
127 } | 118 }; |
128 | 119 |
129 function loadTest(page) { | 120 function loadTest(page) { |
130 // Called each time a new test page is to be build. The page specification node is the only item passed in | 121 // Called each time a new test page is to be build. The page specification node is the only item passed in |
131 var id = page.id; | |
132 | 122 |
133 var feedbackHolder = document.getElementById('feedbackHolder'); | 123 var feedbackHolder = document.getElementById('feedbackHolder'); |
124 var sliderBox = document.getElementById('slider-box'); | |
125 var sliderGrid = document.getElementById("slider-grid"); | |
126 var scaleTextHolder = document.getElementById("scale-text-holder"); | |
127 var interfaceObj = interfaceContext.getCombinedInterfaces(page); | |
128 var commentBoxPrefix = "Comment on track"; | |
129 var loopPlayback = page.loop; | |
134 feedbackHolder.innerHTML = ""; | 130 feedbackHolder.innerHTML = ""; |
135 var interfaceObj = interfaceContext.getCombinedInterfaces(page); | 131 |
136 if (interfaceObj.length > 1) { | 132 if (interfaceObj.length > 1) { |
137 console.log("WARNING - This interface only supports one <interface> node per page. Using first interface node"); | 133 console.log("WARNING - This interface only supports one <interface> node per page. Using first interface node"); |
138 } | 134 } |
139 interfaceObj = interfaceObj[0]; | 135 interfaceObj = interfaceObj[0]; |
140 | 136 |
141 // Set the page title | 137 // Set the page title |
142 if (typeof page.title == "string" && page.title.length > 0) { | 138 if (typeof page.title == "string" && page.title.length > 0) { |
143 document.getElementById("test-title").textContent = page.title; | 139 document.getElementById("test-title").textContent = page.title; |
144 } | 140 } |
145 | 141 // Set the axis title |
146 if (interfaceObj.title !== null) { | 142 if (interfaceObj.title !== null) { |
147 document.getElementById("pageTitle").textContent = interfaceObj.title; | 143 document.getElementById("pageTitle").textContent = interfaceObj.title; |
148 } | 144 } |
149 | 145 |
150 if (interfaceObj.image !== undefined || page.audioElements.some(function (elem) { | 146 if (interfaceObj.image !== undefined || page.audioElements.some(function (elem) { |
155 } | 151 } |
156 | 152 |
157 // Delete outside reference | 153 // Delete outside reference |
158 document.getElementById("outside-reference-holder").innerHTML = ""; | 154 document.getElementById("outside-reference-holder").innerHTML = ""; |
159 | 155 |
160 var sliderBox = document.getElementById('slider-holder'); | 156 // Get the comment box prefix |
161 sliderBox.innerHTML = ""; | |
162 | |
163 var commentBoxPrefix = "Comment on track"; | |
164 if (interfaceObj.commentBoxPrefix !== undefined) { | 157 if (interfaceObj.commentBoxPrefix !== undefined) { |
165 commentBoxPrefix = interfaceObj.commentBoxPrefix; | 158 commentBoxPrefix = interfaceObj.commentBoxPrefix; |
166 } | 159 } |
167 var loopPlayback = page.loop; | 160 |
168 | 161 // Populate the comment questions |
162 $(page.commentQuestions).each(function (index, element) { | |
163 var node = interfaceContext.createCommentQuestion(element); | |
164 feedbackHolder.appendChild(node.holder); | |
165 }); | |
166 | |
167 // Configure the grid | |
168 var numRows = page.audioElements.filter(function (a) { | |
169 return (a.type !== "outside-reference"); | |
170 }).length; | |
171 var numColumns = page.interfaces[0].scales.length; | |
172 sliderGrid.style.gridTemplateRows = "50px repeat(" + numRows + ", 72px)"; | |
173 scaleTextHolder.style.gridTemplateColumns = "100px repeat(" + numColumns + ", 1fr) 100px"; | |
174 page.interfaces[0].scales.sort(function (a, b) { | |
175 if (a.position > b.position) { | |
176 return 1; | |
177 } else if (a.position < b.position) { | |
178 return -1; | |
179 } | |
180 return 0; | |
181 }).forEach(function (a, i) { | |
182 var h = document.createElement("div"); | |
183 var text = document.createElement("span"); | |
184 h.className = "scale-text"; | |
185 h.style.gridColumn = String(i + 2) + "/" + String(i + 3); | |
186 text.textContent = a.text; | |
187 h.appendChild(text); | |
188 scaleTextHolder.appendChild(h); | |
189 }) | |
190 | |
191 // Find all the audioElements from the audioHolder | |
192 var index = 0; | |
193 var labelType = page.label; | |
194 if (labelType == "default") { | |
195 labelType = "number"; | |
196 } | |
197 $(page.audioElements).each(function (pageIndex, element) { | |
198 // Find URL of track | |
199 // In this jQuery loop, variable 'this' holds the current audioElement. | |
200 | |
201 var audioObject = audioEngineContext.newTrack(element); | |
202 if (element.type == 'outside-reference') { | |
203 // Construct outside reference; | |
204 var orNode = new interfaceContext.outsideReferenceDOM(audioObject, index, document.getElementById("outside-reference-holder")); | |
205 audioObject.bindInterface(orNode); | |
206 } else { | |
207 // Create a slider per track | |
208 var label = interfaceContext.getLabel(labelType, index, page.labelStart); | |
209 var sliderObj = new discreteObject(audioObject, label); | |
210 sliderGrid.appendChild(sliderObj.DOMRoot); | |
211 audioObject.bindInterface(sliderObj); | |
212 interfaceContext.commentBoxes.createCommentBox(audioObject); | |
213 index += 1; | |
214 } | |
215 | |
216 }); | |
169 interfaceObj.options.forEach(function (option) { | 217 interfaceObj.options.forEach(function (option) { |
170 if (option.type == "show") { | 218 if (option.type == "show") { |
171 switch (option.name) { | 219 switch (option.name) { |
172 case "playhead": | 220 case "playhead": |
173 var playbackHolder = document.getElementById('playback-holder'); | 221 var playbackHolder = document.getElementById('playback-holder'); |
202 button.style.visibility = "visible"; | 250 button.style.visibility = "visible"; |
203 break; | 251 break; |
204 } | 252 } |
205 } | 253 } |
206 }); | 254 }); |
207 | |
208 // Find all the audioElements from the audioHolder | |
209 var index = 0; | |
210 var interfaceScales = page.interfaces[0].scales; | |
211 var labelType = page.label; | |
212 if (labelType == "default") { | |
213 labelType = "number"; | |
214 } | |
215 $(page.audioElements).each(function (pageIndex, element) { | |
216 // Find URL of track | |
217 // In this jQuery loop, variable 'this' holds the current audioElement. | |
218 | |
219 var audioObject = audioEngineContext.newTrack(element); | |
220 if (element.type == 'outside-reference') { | |
221 // Construct outside reference; | |
222 var orNode = new interfaceContext.outsideReferenceDOM(audioObject, index, document.getElementById("outside-reference-holder")); | |
223 audioObject.bindInterface(orNode); | |
224 } else { | |
225 // Create a slider per track | |
226 var label = interfaceContext.getLabel(labelType, index, page.labelStart); | |
227 var sliderObj = new discreteObject(audioObject, label, interfaceScales); | |
228 sliderBox.appendChild(sliderObj.holder); | |
229 audioObject.bindInterface(sliderObj); | |
230 interfaceContext.commentBoxes.createCommentBox(audioObject); | |
231 index += 1; | |
232 } | |
233 | |
234 }); | |
235 | |
236 $(page.commentQuestions).each(function (index, element) { | |
237 var node = interfaceContext.createCommentQuestion(element); | |
238 feedbackHolder.appendChild(node.holder); | |
239 }); | |
240 | |
241 // Auto-align | 255 // Auto-align |
242 resizeWindow(null); | 256 resizeWindow(null); |
243 } | 257 } |
244 | 258 |
245 function discreteObject(audioObject, label, interfaceScales) { | 259 function discreteObject(audioObject, label) { |
246 // An example node, you can make this however you want for each audioElement. | 260 // An example node, you can make this however you want for each audioElement. |
247 // However, every audioObject (audioEngineContext.audioObject) MUST have an interface object with the following | 261 // However, every audioObject (audioEngineContext.audioObject) MUST have an interface object with the following |
248 // You attach them by calling audioObject.bindInterface( ) | 262 // You attach them by calling audioObject.bindInterface( ) |
249 if (interfaceScales === null || interfaceScales.length === 0) { | 263 var playing = false; |
250 console.log("WARNING: The discrete radio's are built depending on the number of scale points specified! Ensure you have some specified. Defaulting to 5 for now!"); | 264 |
251 var numOptions = 5; | 265 function buttonClicked(event) { |
252 } | 266 if (!playing) { |
253 this.parent = audioObject; | 267 audioEngineContext.play(audioObject.id); |
254 | 268 } else { |
255 this.holder = document.createElement('div'); | 269 audioEngineContext.stop(); |
256 this.title = document.createElement('div'); | 270 } |
257 this.discreteHolder = document.createElement('div'); | 271 }; |
258 this.discretes = []; | 272 |
259 this.play = document.createElement('button'); | 273 function radioSelected(event) { |
260 | |
261 this.holder.className = 'track-slider'; | |
262 this.holder.style.width = window.innerWidth - 200 + 'px'; | |
263 this.holder.appendChild(this.title); | |
264 this.holder.appendChild(this.discreteHolder); | |
265 this.holder.appendChild(this.play); | |
266 this.holder.setAttribute('trackIndex', audioObject.id); | |
267 this.title.textContent = label; | |
268 this.title.className = 'track-slider-title'; | |
269 | |
270 this.discreteHolder.className = "track-slider-range"; | |
271 this.discreteHolder.style.width = window.innerWidth - 500 + 'px'; | |
272 this.radioClicked = function (event) { | |
273 var time = audioEngineContext.timer.getTestTime(); | 274 var time = audioEngineContext.timer.getTestTime(); |
274 if (audioEngineContext.status === 0) { | 275 audioObject.metric.moved(time, event.currentTarget.value); |
275 event.currentTarget.checked = false; | 276 console.log("slider " + audioObject.id + " moved to " + event.currentTarget.value + "(" + time + ")"); |
276 return; | 277 }; |
277 } | 278 |
278 var id = this.parent.id; | 279 var root = document.createElement("div"), |
279 var position = this.getValue(); | 280 labelHolder = document.createElement("div"), |
280 this.parent.metric.moved(time, position); | 281 button = document.createElement("button"); |
281 console.log('slider ' + id + ' moved to ' + position + ' (' + time + ')'); | 282 root.className = "discrete-row"; |
282 | 283 labelHolder.className = "discrete-label"; |
283 }; | 284 button.className = "discrete-button"; |
285 root.appendChild(labelHolder); | |
286 | |
287 var labelSpan = document.createElement("span"); | |
288 labelHolder.appendChild(labelSpan); | |
289 labelSpan.textContent = label; | |
290 button.textContent = "Listen"; | |
291 button.disabled = "true"; | |
292 button.addEventListener("click", this); | |
293 | |
294 var numScales = audioObject.specification.parent.interfaces[0].scales.length; | |
295 root.style.gridTemplateColumns = "100px repeat(" + numScales + ", 1fr) 100px"; | |
296 for (var n = 0; n < numScales; n++) { | |
297 var input = document.createElement("input"); | |
298 input.type = "radio"; | |
299 input.disabled = "true"; | |
300 input.value = n / (numScales - 1); | |
301 input.addEventListener("click", this); | |
302 input.name = audioObject.specification.id; | |
303 root.appendChild(input); | |
304 } | |
305 root.appendChild(button); | |
284 this.handleEvent = function (event) { | 306 this.handleEvent = function (event) { |
285 if (event.currentTarget.getAttribute("name") === this.parent.specification.id) { | 307 if (event.currentTarget === button) { |
286 this.radioClicked(event); | 308 buttonClicked(event); |
287 } | 309 } else if (event.currentTarget.type === "radio") { |
288 }; | 310 radioSelected(event); |
289 for (var i = 0; i < interfaceScales.length; i++) { | 311 } |
290 var node = document.createElement('input'); | 312 } |
291 node.setAttribute('type', 'radio'); | |
292 node.className = 'track-radio'; | |
293 node.disabled = true; | |
294 node.setAttribute('position', interfaceScales[i].position); | |
295 node.setAttribute('name', audioObject.specification.id); | |
296 node.setAttribute('id', audioObject.specification.id + '-' + String(i)); | |
297 this.discretes.push(node); | |
298 this.discreteHolder.appendChild(node); | |
299 node.addEventListener("click", this); | |
300 } | |
301 | |
302 this.play.className = 'track-slider-button'; | |
303 this.play.textContent = "Loading..."; | |
304 this.play.value = audioObject.id; | |
305 this.play.disabled = true; | |
306 this.play.setAttribute("playstate", "ready"); | |
307 this.play.onclick = function (event) { | |
308 var id = Number(event.currentTarget.value); | |
309 //audioEngineContext.metric.sliderPlayed(id); | |
310 if (event.currentTarget.getAttribute("playstate") == "ready") | |
311 audioEngineContext.play(id); | |
312 else if (event.currentTarget.getAttribute("playstate") == "playing") | |
313 audioEngineContext.stop(); | |
314 }; | |
315 this.resize = function (event) { | |
316 this.holder.style.width = window.innerWidth - 200 + 'px'; | |
317 this.discreteHolder.style.width = window.innerWidth - 500 + 'px'; | |
318 //text.style.left = (posPix+150-($(text).width()/2)) +'px'; | |
319 for (var i = 0; i < this.discretes.length; i++) { | |
320 var width = $(this.discreteHolder).width() - 20; | |
321 var node = this.discretes[i]; | |
322 var nodeW = $(node).width(); | |
323 var position = node.getAttribute('position'); | |
324 var posPix = Math.round(width * (position / 100.0)); | |
325 node.style.left = (posPix + 10 - (nodeW / 2)) + 'px'; | |
326 } | |
327 }; | |
328 this.enable = function () { | 313 this.enable = function () { |
329 // This is used to tell the interface object that playback of this node is ready | 314 // This is used to tell the interface object that playback of this node is ready |
330 this.play.disabled = false; | 315 button.disabled = ""; |
331 this.play.textContent = "Play"; | 316 var a = root.querySelectorAll("input[type=\"radio\"]"); |
332 $(this.slider).removeClass('track-slider-disabled'); | 317 for (var n = 0; n < a.length; n++) { |
333 this.discretes.forEach(function (elem) { | 318 a[n].disabled = false; |
334 elem.disabled = false; | 319 } |
335 }); | 320 button.textContent = "Listen"; |
336 }; | 321 }; |
337 this.updateLoading = function (progress) { | 322 this.updateLoading = function (progress) { |
338 // progress is a value from 0 to 100 indicating the current download state of media files | 323 // progress is a value from 0 to 100 indicating the current download state of media files |
339 if (progress != 100) { | 324 button.textContent = progress + "%"; |
340 progress = String(progress); | 325 }; |
341 progress = progress.split('.')[0]; | |
342 this.play.textContent = progress + '%'; | |
343 } else { | |
344 this.play.textContent = "Play"; | |
345 } | |
346 }; | |
347 | |
348 this.startPlayback = function () { | 326 this.startPlayback = function () { |
349 // Called by audioObject when playback begins | 327 // Called when playback has begun |
350 this.play.setAttribute("playstate", "playing"); | 328 playing = true; |
351 $(".track-slider").removeClass('track-slider-playing'); | 329 $(root).addClass("discrete-row-playing"); |
352 $(this.holder).addClass('track-slider-playing'); | 330 button.textContent = "Stop"; |
353 var outsideReference = document.getElementById('outside-reference'); | |
354 this.play.textContent = "Listening"; | |
355 if (outsideReference !== null) { | |
356 $(outsideReference).removeClass('track-slider-playing'); | |
357 } | |
358 if (this.parent.specification.parent.playOne || specification.playOne) { | |
359 $('.track-slider-button').text = "Wait"; | |
360 $('.track-slider-button').attr("disabled", "true"); | |
361 } | |
362 interfaceContext.commentBoxes.highlightById(audioObject.id); | |
363 if (audioObject.specification.image !== undefined) { | |
364 interfaceContext.imageHolder.setImage(audioObject.specification.image); | |
365 } | |
366 }; | 331 }; |
367 this.stopPlayback = function () { | 332 this.stopPlayback = function () { |
368 // Called by audioObject when playback stops | 333 // Called when playback has stopped. This gets called even if playback never started! |
369 if (this.play.getAttribute("playstate") == "playing") { | 334 playing = false; |
370 this.play.setAttribute("playstate", "ready"); | 335 $(root).removeClass("discrete-row-playing"); |
371 $(this.holder).removeClass('track-slider-playing'); | 336 button.textContent = "Listen"; |
372 $('.track-slider-button').text = "Play"; | 337 }; |
373 this.play.textContent = "Play"; | 338 this.getValue = function () { |
374 $('.track-slider-button').removeAttr("disabled"); | 339 // Return the current value of the object. If there is no value, return 0 |
375 var box = interfaceContext.commentBoxes.boxes.find(function (a) { | 340 var a = root.querySelectorAll("input[type=\"radio\"]"); |
376 return a.id === audioObject.id; | 341 for (var n = 0; n < a.length; n++) { |
377 }); | 342 if (a[n].checked) { |
378 if (box) { | 343 return Number(a[n].value); |
379 box.highlight(false); | |
380 } | 344 } |
381 if (audioObject.specification.parent.interfaces[0].image !== undefined) { | 345 } |
382 interfaceContext.imageHolder.setImage(audioObject.specification.parent.interfaces[0].image); | 346 return -1; |
383 } else { | |
384 interfaceContext.imageHolder.setImage(""); | |
385 } | |
386 } | |
387 }; | |
388 | |
389 this.getValue = function () { | |
390 // Return the current value of the object. If there is no value, return -1 | |
391 var checkedElement = this.discretes.find(function (elem) { | |
392 return elem.checked; | |
393 }); | |
394 if (checkedElement === undefined) { | |
395 return -1; | |
396 } | |
397 return checkedElement.getAttribute("position") / 100.0; | |
398 }; | 347 }; |
399 this.getPresentedId = function () { | 348 this.getPresentedId = function () { |
400 // Return the presented ID of the object. For instance, the APE has sliders starting from 0. Whilst AB has alphabetical scale | 349 // Return the presented ID of the object. For instance, the APE has sliders starting from 0. Whilst AB has alphabetical scale |
401 return this.title.textContent; | 350 return label; |
402 }; | 351 }; |
403 this.canMove = function () { | 352 this.canMove = function () { |
404 // Return either true or false if the interface object can be moved. AB / Reference cannot, whilst sliders can and therefore have a continuous scale. | 353 // Return either true or false if the interface object can be moved. AB / Reference cannot, whilst sliders can and therefore have a continuous scale. |
405 // These are checked primarily if the interface check option 'fragmentMoved' is enabled. | 354 // These are checked primarily if the interface check option 'fragmentMoved' is enabled. |
406 return true; | 355 return true; |
411 // If there are multiple value nodes (such as multiple scale / 2D scales), return an array of nodes with each value node having an 'interfaceName' attribute | 360 // If there are multiple value nodes (such as multiple scale / 2D scales), return an array of nodes with each value node having an 'interfaceName' attribute |
412 // Use storage.document.createElement('value'); to generate the XML node. | 361 // Use storage.document.createElement('value'); to generate the XML node. |
413 var node = storage.document.createElement('value'); | 362 var node = storage.document.createElement('value'); |
414 node.textContent = this.getValue(); | 363 node.textContent = this.getValue(); |
415 return node; | 364 return node; |
365 | |
416 }; | 366 }; |
417 this.error = function () { | 367 this.error = function () { |
418 // audioObject has an error!! | 368 // If there is an error with the audioObject, this will be called to indicate a failure |
419 this.playback.textContent = "Error"; | 369 }; |
420 $(this.playback).addClass("error-colour"); | 370 Object.defineProperties(this, { |
421 }; | 371 "DOMRoot": { |
422 } | 372 "value": root |
373 } | |
374 }); | |
375 }; | |
423 | 376 |
424 function resizeWindow(event) { | 377 function resizeWindow(event) { |
425 // Called on every window resize event, use this to scale your page properly | 378 // Called on every window resize event, use this to scale your page properly |
426 var numObj = document.getElementsByClassName('track-slider').length; | |
427 var totalHeight = (numObj * 66) - 30; | |
428 document.getElementById('scale-holder').style.width = window.innerWidth - 220 + 'px'; | |
429 // Cheers edge for making me delete a canvas every resize. | |
430 var canvas = document.getElementById('scale-canvas'); | |
431 var new_canvas = document.createElement("canvas"); | |
432 new_canvas.id = 'scale-canvas'; | |
433 new_canvas.style.marginLeft = "150px"; | |
434 canvas.parentElement.appendChild(new_canvas); | |
435 canvas.parentElement.removeChild(canvas); | |
436 new_canvas.width = window.innerWidth - 520; | |
437 new_canvas.height = totalHeight; | |
438 for (var i in audioEngineContext.audioObjects) { | |
439 if (audioEngineContext.audioObjects[i].specification.type != 'outside-reference') { | |
440 audioEngineContext.audioObjects[i].interfaceDOM.resize(event); | |
441 } | |
442 } | |
443 document.getElementById('slider-holder').style.height = totalHeight + 'px'; | |
444 document.getElementById('slider').style.height = totalHeight + 70 + 'px'; | |
445 drawScale(); | |
446 } | 379 } |
447 | 380 |
448 function drawScale() { | 381 function buttonSortFragmentClick() { |
449 var interfaceObj = testState.currentStateMap.interfaces[0]; | 382 var sortIndex = interfaceContext.sortFragmentsByScore(); |
450 var scales = testState.currentStateMap.interfaces[0].scales; | 383 var sliderBox = document.getElementById("slider-holder"); |
451 var ticks = specification.interfaces.options.concat(interfaceObj.options).find(function (a) { | 384 var nodes = audioEngineContext.audioObjects.filter(function (ao) { |
452 return (a.type == "show" && a.name == "ticks"); | 385 return ao.specification.type !== "outside-reference"; |
453 }); | 386 }); |
454 if (ticks !== undefined) { | 387 var i; |
455 ticks = true; | 388 nodes.forEach(function (ao) { |
456 } else { | 389 sliderBox.removeChild(ao.interfaceDOM.holder); |
457 ticks = false; | 390 }); |
458 } | 391 for (i = 0; i < nodes.length; i++) { |
459 scales = scales.sort(function (a, b) { | 392 var j = sortIndex[i]; |
460 return a.position - b.position; | 393 sliderBox.appendChild(nodes[j].interfaceDOM.holder); |
461 }); | 394 } |
462 var canvas = document.getElementById('scale-canvas'); | |
463 var ctx = canvas.getContext("2d"); | |
464 var height = canvas.height; | |
465 var width = canvas.width; | |
466 var textHolder = document.getElementById('scale-text-holder'); | |
467 textHolder.innerHTML = ""; | |
468 ctx.fillStyle = "#000000"; | |
469 ctx.setLineDash([1, 4]); | |
470 scales.forEach(function (scale) { | |
471 var posPercent = scale.position / 100.0; | |
472 var posPix = Math.round(width * posPercent); | |
473 if (posPix <= 0) { | |
474 posPix = 1; | |
475 } | |
476 if (posPix >= width) { | |
477 posPix = width - 1; | |
478 } | |
479 if (ticks) { | |
480 ctx.moveTo(posPix, 0); | |
481 ctx.lineTo(posPix, height); | |
482 ctx.stroke(); | |
483 } | |
484 | |
485 var text = document.createElement('div'); | |
486 text.align = "center"; | |
487 var textC = document.createElement('span'); | |
488 textC.textContent = scale.text; | |
489 text.appendChild(textC); | |
490 text.className = "scale-text"; | |
491 textHolder.appendChild(text); | |
492 text.style.width = $(text.children[0]).width() + 'px'; | |
493 text.style.left = (posPix + 150 - ($(text).width() / 2)) + 'px'; | |
494 }); | |
495 } | 395 } |
496 | 396 |
497 function buttonSubmitClick() // TODO: Only when all songs have been played! | 397 function buttonSubmitClick() // TODO: Only when all songs have been played! |
498 { | 398 { |
499 var checks = testState.currentStateMap.interfaces[0].options, | 399 var checks = testState.currentStateMap.interfaces[0].options, |
512 if (interfaceContext.checkCommentQuestions() === false) { | 412 if (interfaceContext.checkCommentQuestions() === false) { |
513 return; | 413 return; |
514 } | 414 } |
515 | 415 |
516 for (var i = 0; i < checks.length; i++) { | 416 for (var i = 0; i < checks.length; i++) { |
517 var checkState; | 417 var checkState = true; |
518 if (checks[i].type == 'check') { | 418 if (checks[i].type == 'check') { |
519 switch (checks[i].name) { | 419 switch (checks[i].name) { |
520 case 'fragmentPlayed': | 420 case 'fragmentPlayed': |
521 // Check if all fragments have been played | 421 // Check if all fragments have been played |
522 checkState = interfaceContext.checkAllPlayed(checks[i].errorMessage); | 422 checkState = interfaceContext.checkAllPlayed(checks[i].errorMessage); |
535 checkState = interfaceContext.checkAllCommented(checks[i].errorMessage); | 435 checkState = interfaceContext.checkAllCommented(checks[i].errorMessage); |
536 break; | 436 break; |
537 case 'scalerange': | 437 case 'scalerange': |
538 // Check the scale has been used effectively | 438 // Check the scale has been used effectively |
539 checkState = interfaceContext.checkScaleRange(checks[i].errorMessage); | 439 checkState = interfaceContext.checkScaleRange(checks[i].errorMessage); |
440 | |
540 break; | 441 break; |
541 default: | 442 default: |
542 console.log("WARNING - Check option " + checks[i].check + " is not supported on this interface"); | 443 console.log("WARNING - Check option " + checks[i].check + " is not supported on this interface"); |
543 break; | 444 break; |
544 } | 445 } |
545 if (checkState === false) { | 446 } |
546 canContinue = false; | 447 if (checkState === false) { |
547 } | 448 canContinue = false; |
548 } | |
549 if (!canContinue) { | |
550 break; | 449 break; |
551 } | 450 } |
552 } | 451 } |
553 | 452 |
554 if (canContinue) { | 453 if (canContinue) { |
564 } | 463 } |
565 testState.advanceState(); | 464 testState.advanceState(); |
566 } | 465 } |
567 } | 466 } |
568 | 467 |
569 function buttonSortFragmentClick() { | |
570 var sortIndex = interfaceContext.sortFragmentsByScore(); | |
571 var sliderBox = document.getElementById("slider-holder"); | |
572 var nodes = audioEngineContext.audioObjects.filter(function (ao) { | |
573 return ao.specification.type !== "outside-reference"; | |
574 }); | |
575 var i; | |
576 nodes.forEach(function (ao) { | |
577 sliderBox.removeChild(ao.interfaceDOM.holder); | |
578 }); | |
579 for (i = 0; i < nodes.length; i++) { | |
580 var j = sortIndex[i]; | |
581 sliderBox.appendChild(nodes[j].interfaceDOM.holder); | |
582 } | |
583 } | |
584 | |
585 function pageXMLSave(store, pageSpecification) { | 468 function pageXMLSave(store, pageSpecification) { |
586 // MANDATORY | 469 // MANDATORY |
587 // Saves a specific test page | 470 // Saves a specific test page |
588 // You can use this space to add any extra nodes to your XML <audioHolder> saves | 471 // You can use this space to add any extra nodes to your XML <audioHolder> saves |
589 // Get the current <page> information in store (remember to appendChild your data to it) | 472 // Get the current <page> information in store (remember to appendChild your data to it) |