jclic 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -7
- package/dist-node/jclic-node.js +14157 -0
- package/dist-node/jclic-node.umd.cjs +530 -0
- package/package.json +38 -26
- package/.vscode/launch.json +0 -33
- package/.vscode/settings.json +0 -13
- package/CHANGELOG.md +0 -664
- package/TRANSLATIONS.md +0 -11
- package/build-locales.mjs +0 -82
- package/dist/jclic-node.js +0 -31678
- package/dist/jclic-node.js.map +0 -1
- package/dist/jclic.components.LICENSE +0 -2254
- package/dist/jclic.min.js +0 -27
- package/dist/jclic.min.js.map +0 -1
- package/eslint.config.mjs +0 -31
- package/jsdoc.config.js +0 -71
- package/locales/ar.po +0 -244
- package/locales/ast.po +0 -246
- package/locales/bs.po +0 -247
- package/locales/ca.po +0 -248
- package/locales/ca_ES@valencia.po +0 -248
- package/locales/cs.po +0 -244
- package/locales/da.po +0 -244
- package/locales/de.po +0 -246
- package/locales/el.po +0 -244
- package/locales/es.po +0 -248
- package/locales/eu.po +0 -244
- package/locales/fr.po +0 -244
- package/locales/gl.po +0 -244
- package/locales/he.po +0 -244
- package/locales/hr.po +0 -245
- package/locales/it.po +0 -246
- package/locales/ja.po +0 -242
- package/locales/jclic.js.pot +0 -241
- package/locales/nb_NO.po +0 -244
- package/locales/nl.po +0 -244
- package/locales/pl.po +0 -244
- package/locales/pt.po +0 -244
- package/locales/pt_BR.po +0 -248
- package/locales/ro.po +0 -248
- package/locales/ru.po +0 -245
- package/locales/ta.po +0 -244
- package/locales/tr.po +0 -246
- package/locales/uk.po +0 -247
- package/locales/vec.po +0 -244
- package/locales/zh_TW.po +0 -246
- package/patches/po2json+1.0.0-beta-3.patch +0 -12
- package/src/AWT.js +0 -2067
- package/src/Activity.js +0 -1311
- package/src/Deps.js +0 -232
- package/src/GlobalData.js +0 -5
- package/src/JClic.js +0 -196
- package/src/JClicPlayer.js +0 -1308
- package/src/PlayerHistory.js +0 -305
- package/src/Utils.js +0 -1355
- package/src/activities/associations/ComplexAssociation.js +0 -321
- package/src/activities/associations/SimpleAssociation.js +0 -519
- package/src/activities/memory/MemoryGame.js +0 -423
- package/src/activities/panels/Explore.js +0 -349
- package/src/activities/panels/Identify.js +0 -356
- package/src/activities/panels/InformationScreen.js +0 -262
- package/src/activities/panels/Menu.js +0 -209
- package/src/activities/panels/icons/ico00.png +0 -0
- package/src/activities/panels/icons/ico01.png +0 -0
- package/src/activities/panels/icons/ico02.png +0 -0
- package/src/activities/panels/icons/ico03.png +0 -0
- package/src/activities/panels/icons/icofolder.png +0 -0
- package/src/activities/puzzles/DoublePuzzle.js +0 -424
- package/src/activities/puzzles/ExchangePuzzle.js +0 -374
- package/src/activities/puzzles/HolePuzzle.js +0 -360
- package/src/activities/text/Complete.js +0 -127
- package/src/activities/text/Evaluator.js +0 -534
- package/src/activities/text/FillInBlanks.js +0 -426
- package/src/activities/text/IdentifyText.js +0 -253
- package/src/activities/text/OrderText.js +0 -421
- package/src/activities/text/TextActivityBase.js +0 -557
- package/src/activities/text/TextActivityDocument.js +0 -658
- package/src/activities/text/WrittenAnswer.js +0 -557
- package/src/activities/textGrid/CrossWord.js +0 -565
- package/src/activities/textGrid/WordSearch.js +0 -458
- package/src/activities/textGrid/icons/hIcon.svg +0 -3
- package/src/activities/textGrid/icons/vIcon.svg +0 -3
- package/src/automation/AutoContentProvider.js +0 -182
- package/src/automation/arith/Arith.js +0 -864
- package/src/bags/ActivitySequence.js +0 -318
- package/src/bags/ActivitySequenceElement.js +0 -161
- package/src/bags/ActivitySequenceJump.js +0 -140
- package/src/bags/ConditionalJumpInfo.js +0 -113
- package/src/bags/JumpInfo.js +0 -136
- package/src/bags/MediaBag.js +0 -215
- package/src/bags/MediaBagElement.js +0 -516
- package/src/boxes/AbstractBox.js +0 -699
- package/src/boxes/ActiveBagContent.js +0 -494
- package/src/boxes/ActiveBox.js +0 -810
- package/src/boxes/ActiveBoxBag.js +0 -357
- package/src/boxes/ActiveBoxContent.js +0 -484
- package/src/boxes/ActiveBoxGrid.js +0 -179
- package/src/boxes/BoxBag.js +0 -500
- package/src/boxes/BoxBase.js +0 -398
- package/src/boxes/BoxConnector.js +0 -325
- package/src/boxes/TextGrid.js +0 -887
- package/src/boxes/TextGridContent.js +0 -215
- package/src/init-jsdom.js +0 -65
- package/src/jclic-node.js +0 -219
- package/src/media/ActiveMediaBag.js +0 -145
- package/src/media/ActiveMediaPlayer.js +0 -297
- package/src/media/AudioBuffer.js +0 -219
- package/src/media/EventSounds.js +0 -169
- package/src/media/EventSoundsElement.js +0 -155
- package/src/media/MediaContent.js +0 -328
- package/src/media/MidiAudioPlayer.js +0 -254
- package/src/media/icons/audio.svg +0 -3
- package/src/media/icons/generic.svg +0 -3
- package/src/media/icons/mic.svg +0 -3
- package/src/media/icons/movie.svg +0 -3
- package/src/media/icons/music.svg +0 -3
- package/src/media/icons/url.svg +0 -3
- package/src/media/sounds/actionError.mp3 +0 -0
- package/src/media/sounds/actionOk.mp3 +0 -0
- package/src/media/sounds/click.mp3 +0 -0
- package/src/media/sounds/finishedError.mp3 +0 -0
- package/src/media/sounds/finishedOk.mp3 +0 -0
- package/src/media/sounds/start.mp3 +0 -0
- package/src/project/JClicProject.js +0 -282
- package/src/project/ProjectSettings.js +0 -273
- package/src/report/ActionReg.js +0 -123
- package/src/report/ActivityReg.js +0 -271
- package/src/report/EncryptMin.js +0 -210
- package/src/report/Reporter.js +0 -727
- package/src/report/SCORM.js +0 -272
- package/src/report/SequenceReg.js +0 -275
- package/src/report/SessionReg.js +0 -340
- package/src/report/SessionStorageReporter.js +0 -131
- package/src/report/TCPReporter.js +0 -628
- package/src/shapers/ClassicJigSaw.js +0 -138
- package/src/shapers/Holes.js +0 -77
- package/src/shapers/JigSaw.js +0 -161
- package/src/shapers/Rectangular.js +0 -78
- package/src/shapers/Shaper.js +0 -386
- package/src/shapers/TriangularJigSaw.js +0 -121
- package/src/skins/BlueSkin.js +0 -80
- package/src/skins/Counter.js +0 -152
- package/src/skins/CustomSkin.js +0 -412
- package/src/skins/DefaultSkin.js +0 -376
- package/src/skins/EmptySkin.js +0 -82
- package/src/skins/GreenSkin.js +0 -94
- package/src/skins/MiniSkin.js +0 -130
- package/src/skins/OrangeSkin.js +0 -78
- package/src/skins/SimpleSkin.js +0 -92
- package/src/skins/Skin.js +0 -1021
- package/src/skins/assets/actionsIcon.svg +0 -3
- package/src/skins/assets/appLogo.svg +0 -8
- package/src/skins/assets/basic.css +0 -41
- package/src/skins/assets/closeDialogIcon.svg +0 -3
- package/src/skins/assets/closeIcon.svg +0 -3
- package/src/skins/assets/copyIcon.svg +0 -3
- package/src/skins/assets/fullScreenExitIcon.svg +0 -3
- package/src/skins/assets/fullScreenIcon.svg +0 -3
- package/src/skins/assets/infoIcon.svg +0 -3
- package/src/skins/assets/main.css +0 -43
- package/src/skins/assets/mainHalf.css +0 -23
- package/src/skins/assets/mainTwoThirds.css +0 -23
- package/src/skins/assets/mini.css +0 -15
- package/src/skins/assets/nextIcon.svg +0 -3
- package/src/skins/assets/okDialogIcon.svg +0 -3
- package/src/skins/assets/prevIcon.svg +0 -3
- package/src/skins/assets/reports.css +0 -156
- package/src/skins/assets/reportsIcon.svg +0 -3
- package/src/skins/assets/scoreIcon.svg +0 -3
- package/src/skins/assets/simple.css +0 -16
- package/src/skins/assets/simpleHalf.css +0 -11
- package/src/skins/assets/simpleTwoThirds.css +0 -11
- package/src/skins/assets/timeIcon.svg +0 -4
- package/src/skins/assets/waitAnim.css +0 -54
- package/src/skins/assets/waitImgBig.svg +0 -3
- package/src/skins/assets/waitImgSmall.svg +0 -3
- package/webpack.config.mjs +0 -169
package/src/Activity.js
DELETED
|
@@ -1,1311 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* File : Activity.js
|
|
3
|
-
* Created : 07/04/2015
|
|
4
|
-
* By : Francesc Busquets <francesc@gmail.com>
|
|
5
|
-
*
|
|
6
|
-
* JClic.js
|
|
7
|
-
* An HTML5 player of JClic activities
|
|
8
|
-
* https://projectestac.github.io/jclic.js
|
|
9
|
-
*
|
|
10
|
-
* @source https://github.com/projectestac/jclic.js
|
|
11
|
-
*
|
|
12
|
-
* @license EUPL-1.2
|
|
13
|
-
* @licstart
|
|
14
|
-
* (c) 2000-2020 Educational Telematic Network of Catalonia (XTEC)
|
|
15
|
-
*
|
|
16
|
-
* Licensed under the EUPL, Version 1.1 or -as soon they will be approved by
|
|
17
|
-
* the European Commission- subsequent versions of the EUPL (the "Licence");
|
|
18
|
-
* You may not use this work except in compliance with the Licence.
|
|
19
|
-
*
|
|
20
|
-
* You may obtain a copy of the Licence at:
|
|
21
|
-
* https://joinup.ec.europa.eu/software/page/eupl
|
|
22
|
-
*
|
|
23
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
24
|
-
* distributed under the Licence is distributed on an "AS IS" basis, WITHOUT
|
|
25
|
-
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
26
|
-
* Licence for the specific language governing permissions and limitations
|
|
27
|
-
* under the Licence.
|
|
28
|
-
* @licend
|
|
29
|
-
* @module
|
|
30
|
-
*/
|
|
31
|
-
|
|
32
|
-
/* global window */
|
|
33
|
-
|
|
34
|
-
import $ from 'jquery';
|
|
35
|
-
import { settings, log, getMsg, attrForEach, nSlash, getBoolean, getXmlText, checkColor, isNullOrUndef, getAttr, setAttr } from './Utils.js';
|
|
36
|
-
import { Rectangle, Gradient, Point, Dimension, Container } from './AWT.js';
|
|
37
|
-
import EventSounds from './media/EventSounds.js';
|
|
38
|
-
import ActiveBoxContent from './boxes/ActiveBoxContent.js';
|
|
39
|
-
import ActiveBagContent from './boxes/ActiveBagContent.js';
|
|
40
|
-
import BoxBase from './boxes/BoxBase.js';
|
|
41
|
-
import AutoContentProvider from './automation/AutoContentProvider.js';
|
|
42
|
-
import TextGridContent from './boxes/TextGridContent.js';
|
|
43
|
-
import Evaluator from './activities/text/Evaluator.js';
|
|
44
|
-
import TextActivityDocument from './activities/text/TextActivityDocument.js';
|
|
45
|
-
|
|
46
|
-
// Event used for detecting touch devices
|
|
47
|
-
const TOUCH_TEST_EVENT = 'touchstart';
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Activity is the abstract base class of JClic activities. It defines also the inner class
|
|
51
|
-
* {@link module:Activity.ActivityPanel ActivityPanel}, wich is responsible for user interaction with the activity
|
|
52
|
-
* content.
|
|
53
|
-
* Activities should extend both `Activity` and `ActivityPanel` classes in order to become fully
|
|
54
|
-
* operative.
|
|
55
|
-
* @abstract
|
|
56
|
-
*/
|
|
57
|
-
export class Activity {
|
|
58
|
-
/**
|
|
59
|
-
* Activity constructor
|
|
60
|
-
* @param {module:project/JClicProject.JClicProject} project - The {@link module:project/JClicProject.JClicProject JClicProject} to which this activity belongs
|
|
61
|
-
*/
|
|
62
|
-
constructor(project) {
|
|
63
|
-
this.project = project;
|
|
64
|
-
this.eventSounds = new EventSounds(this.project.settings.eventSounds);
|
|
65
|
-
this.messages = {};
|
|
66
|
-
this.abc = {};
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Registers a new type of activity
|
|
71
|
-
* @param {string} activityName - The name used to identify this activity
|
|
72
|
-
* @param {function} activityClass - The activity class, usually extending Activity
|
|
73
|
-
* @returns {module:Activity.Activity} - The provided activity class
|
|
74
|
-
*/
|
|
75
|
-
static registerClass(activityName, activityClass) {
|
|
76
|
-
Activity.CLASSES[activityName] = activityClass;
|
|
77
|
-
return activityClass;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Factory constructor that returns a specific type of Activity based on the `class` attribute
|
|
82
|
-
* declared in `data`.
|
|
83
|
-
* @param {object|external:jQuery} data - Can be a jQuery XML element, or an object obtained with a call to `getAttributes`
|
|
84
|
-
* @param {module:project/JClicProject.JClicProject} project - The {@link module:project/JClicProject.JClicProject JClicProject} to which this activity belongs
|
|
85
|
-
* @returns {module:Activity.Activity}
|
|
86
|
-
*/
|
|
87
|
-
static getActivity(data, project) {
|
|
88
|
-
let act = null;
|
|
89
|
-
const isXml = data.jquery && true;
|
|
90
|
-
if (data && project) {
|
|
91
|
-
const className = isXml ? (data.attr('class') || '').replace(/^edu\.xtec\.jclic\.activities\./, '@') : data.className;
|
|
92
|
-
const cl = Activity.CLASSES[className];
|
|
93
|
-
if (cl) {
|
|
94
|
-
act = new cl(project);
|
|
95
|
-
if (isXml)
|
|
96
|
-
act.setProperties(data);
|
|
97
|
-
else
|
|
98
|
-
act.setAttributes(data);
|
|
99
|
-
} else
|
|
100
|
-
log('error', `Unknown activity class: ${className}`);
|
|
101
|
-
}
|
|
102
|
-
return act;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Loads this object settings from an XML element
|
|
107
|
-
* @param {external:jQuery} $xml - The jQuery XML element to parse
|
|
108
|
-
*/
|
|
109
|
-
setProperties($xml) {
|
|
110
|
-
|
|
111
|
-
// Read attributes
|
|
112
|
-
attrForEach($xml.get(0).attributes, (name, val) => {
|
|
113
|
-
switch (name) {
|
|
114
|
-
// Generic attributes:
|
|
115
|
-
case 'name':
|
|
116
|
-
val = nSlash(val);
|
|
117
|
-
/* falls through */
|
|
118
|
-
case 'code':
|
|
119
|
-
case 'type':
|
|
120
|
-
case 'description':
|
|
121
|
-
this[name] = val;
|
|
122
|
-
break;
|
|
123
|
-
|
|
124
|
-
case 'class':
|
|
125
|
-
this.className = val.replace(/^edu\.xtec\.jclic\.activities\./, '@');
|
|
126
|
-
break;
|
|
127
|
-
|
|
128
|
-
case 'inverse':
|
|
129
|
-
this.invAss = getBoolean(val, false);
|
|
130
|
-
break;
|
|
131
|
-
|
|
132
|
-
case 'autoJump':
|
|
133
|
-
case 'forceOkToAdvance':
|
|
134
|
-
case 'amongParagraphs':
|
|
135
|
-
this[name] = getBoolean(val, false);
|
|
136
|
-
break;
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
// Read specific nodes
|
|
141
|
-
$xml.children().each((_n, child) => {
|
|
142
|
-
const $node = $(child);
|
|
143
|
-
switch (child.nodeName) {
|
|
144
|
-
case 'settings':
|
|
145
|
-
// Read more attributes
|
|
146
|
-
attrForEach($node.get(0).attributes, (name, val) => {
|
|
147
|
-
switch (name) {
|
|
148
|
-
case 'infoUrl':
|
|
149
|
-
case 'infoCmd':
|
|
150
|
-
this[name] = val;
|
|
151
|
-
break;
|
|
152
|
-
|
|
153
|
-
case 'margin':
|
|
154
|
-
case 'maxTime':
|
|
155
|
-
case 'maxActions':
|
|
156
|
-
this[name] = Number(val);
|
|
157
|
-
break;
|
|
158
|
-
|
|
159
|
-
case 'report':
|
|
160
|
-
this.includeInReports = getBoolean(val, false);
|
|
161
|
-
break;
|
|
162
|
-
case 'countDownTime':
|
|
163
|
-
case 'countDownActions':
|
|
164
|
-
case 'reportActions':
|
|
165
|
-
case 'useOrder':
|
|
166
|
-
case 'dragCells':
|
|
167
|
-
this[name] = getBoolean(val, false);
|
|
168
|
-
break;
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
// Read elements of _settings_
|
|
173
|
-
$node.children().each((_n, child) => {
|
|
174
|
-
const $node = $(child);
|
|
175
|
-
switch (child.nodeName) {
|
|
176
|
-
case 'skin':
|
|
177
|
-
this.skinFileName = $node.attr('file');
|
|
178
|
-
break;
|
|
179
|
-
|
|
180
|
-
case 'helpWindow':
|
|
181
|
-
this.helpMsg = getXmlText(this);
|
|
182
|
-
this.showSolution = getBoolean($node.attr('showSolution'), false);
|
|
183
|
-
this.helpWindow = this.helpMsg !== null || this.showSolution;
|
|
184
|
-
break;
|
|
185
|
-
|
|
186
|
-
case 'container':
|
|
187
|
-
// Read settings related to the 'container'
|
|
188
|
-
// (the main panel containing the activity and other elements)
|
|
189
|
-
this.bgColor = checkColor($node.attr('bgColor'), settings.BoxBase.BACK_COLOR);
|
|
190
|
-
|
|
191
|
-
$node.children().each((_n, child) => {
|
|
192
|
-
const $child = $(child);
|
|
193
|
-
switch (child.nodeName) {
|
|
194
|
-
case 'image':
|
|
195
|
-
this.bgImageFile = $child.attr('name');
|
|
196
|
-
this.tiledBgImg = getBoolean($child.attr('tiled'), false);
|
|
197
|
-
break;
|
|
198
|
-
case 'counters':
|
|
199
|
-
this.bTimeCounter = getBoolean($child.attr('time'), true);
|
|
200
|
-
this.bActionsCounter = getBoolean($child.attr('actions'), true);
|
|
201
|
-
this.bScoreCounter = getBoolean($child.attr('score'), true);
|
|
202
|
-
break;
|
|
203
|
-
case 'gradient':
|
|
204
|
-
this.bgGradient = new Gradient().setProperties($child);
|
|
205
|
-
break;
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
break;
|
|
209
|
-
|
|
210
|
-
case 'window':
|
|
211
|
-
// Read settings related to the 'window'
|
|
212
|
-
// (the panel where the activity deploys its content)
|
|
213
|
-
this.activityBgColor = checkColor($node.attr('bgColor'), settings.DEFAULT_BG_COLOR);
|
|
214
|
-
this.transparentBg = getBoolean($node.attr('transparent'), false);
|
|
215
|
-
this.border = getBoolean($node.attr('border'), false);
|
|
216
|
-
$node.children().each((_n, child) => {
|
|
217
|
-
const $child = $(child);
|
|
218
|
-
switch (child.nodeName) {
|
|
219
|
-
case 'gradient':
|
|
220
|
-
this.activityBgGradient = new Gradient().setProperties($child);
|
|
221
|
-
break;
|
|
222
|
-
case 'position':
|
|
223
|
-
this.absolutePosition = new Point().setProperties($child);
|
|
224
|
-
this.absolutePositioned = true;
|
|
225
|
-
break;
|
|
226
|
-
case 'size':
|
|
227
|
-
this.windowSize = new Dimension().setProperties($child);
|
|
228
|
-
break;
|
|
229
|
-
}
|
|
230
|
-
});
|
|
231
|
-
break;
|
|
232
|
-
|
|
233
|
-
case 'eventSounds':
|
|
234
|
-
// eventSounds is already created in constructor,
|
|
235
|
-
// just read properties
|
|
236
|
-
this.eventSounds.setProperties($node);
|
|
237
|
-
break;
|
|
238
|
-
}
|
|
239
|
-
});
|
|
240
|
-
break;
|
|
241
|
-
|
|
242
|
-
case 'messages':
|
|
243
|
-
$node.children('cell').each((_n, child) => {
|
|
244
|
-
const m = this.readMessage($(child));
|
|
245
|
-
// Possible message types are: `initial`, `final`, `previous`, `finalError`
|
|
246
|
-
this.messages[m.type] = m;
|
|
247
|
-
});
|
|
248
|
-
break;
|
|
249
|
-
|
|
250
|
-
case 'automation':
|
|
251
|
-
// Read the automation settings ('Arith' or other automation engines)
|
|
252
|
-
this.acp = AutoContentProvider.getProvider($node, this.project);
|
|
253
|
-
if (this.acp)
|
|
254
|
-
this.numericContent = this.acp.numericContent;
|
|
255
|
-
break;
|
|
256
|
-
|
|
257
|
-
// Settings specific to panel-type activities (puzzles, associations...)
|
|
258
|
-
case 'cells':
|
|
259
|
-
// Read the [ActiveBagContent](ActiveBagContent.html) objects
|
|
260
|
-
const cellSet = new ActiveBagContent().setProperties($node, this.project.mediaBag);
|
|
261
|
-
// Valid ids:
|
|
262
|
-
// - Panel activities: 'primary', 'secondary', solvedPrimary'
|
|
263
|
-
// - Textpanel activities: 'acrossClues', 'downClues', 'answers'
|
|
264
|
-
this.abc[cellSet.id] = cellSet;
|
|
265
|
-
break;
|
|
266
|
-
|
|
267
|
-
case 'scramble':
|
|
268
|
-
// Read the 'shuffle' mode
|
|
269
|
-
this.shuffles = Number($node.attr('times'));
|
|
270
|
-
this.shuffleA = getBoolean($node.attr('primary'));
|
|
271
|
-
this.shuffleB = getBoolean($node.attr('secondary'));
|
|
272
|
-
break;
|
|
273
|
-
|
|
274
|
-
case 'layout':
|
|
275
|
-
attrForEach($node.get(0).attributes, (name, value) => {
|
|
276
|
-
switch (name) {
|
|
277
|
-
case 'position':
|
|
278
|
-
this.boxGridPos = value;
|
|
279
|
-
break;
|
|
280
|
-
case 'wildTransparent':
|
|
281
|
-
case 'upperCase':
|
|
282
|
-
case 'checkCase':
|
|
283
|
-
this[name] = getBoolean(value);
|
|
284
|
-
}
|
|
285
|
-
});
|
|
286
|
-
break;
|
|
287
|
-
|
|
288
|
-
// Element specific to 'Menu' activities:
|
|
289
|
-
case 'menuElement':
|
|
290
|
-
this.menuElements.push({
|
|
291
|
-
caption: $node.attr('caption') || '',
|
|
292
|
-
icon: $node.attr('icon') || null,
|
|
293
|
-
projectPath: $node.attr('path') || null,
|
|
294
|
-
sequence: $node.attr('sequence') || null,
|
|
295
|
-
description: $node.attr('description') || ''
|
|
296
|
-
});
|
|
297
|
-
break;
|
|
298
|
-
|
|
299
|
-
// Element specific to 'CrossWord' and
|
|
300
|
-
// 'WordSearch' activities:
|
|
301
|
-
case 'textGrid':
|
|
302
|
-
// Read the 'textGrid' element into a 'TextGridContent'
|
|
303
|
-
this.tgc = new TextGridContent().setProperties($node);
|
|
304
|
-
break;
|
|
305
|
-
|
|
306
|
-
// Read the clues of 'WordSearch' activities
|
|
307
|
-
case 'clues':
|
|
308
|
-
// Read the array of clues
|
|
309
|
-
this.clues = [];
|
|
310
|
-
this.clueItems = [];
|
|
311
|
-
$node.children('clue').each((n, child) => {
|
|
312
|
-
this.clueItems[n] = Number($(child).attr('id'));
|
|
313
|
-
this.clues[n] = child.textContent;
|
|
314
|
-
});
|
|
315
|
-
break;
|
|
316
|
-
|
|
317
|
-
// Elements specific to text activities:
|
|
318
|
-
case 'checkButton':
|
|
319
|
-
this.checkButtonText = child.textContent || 'check';
|
|
320
|
-
break;
|
|
321
|
-
|
|
322
|
-
case 'prevScreen':
|
|
323
|
-
this.prevScreen = true;
|
|
324
|
-
this.prevScreenMaxTime = $node.attr('maxTime') || -1;
|
|
325
|
-
$node.children().each((_n, child) => {
|
|
326
|
-
switch (child.nodeName) {
|
|
327
|
-
case 'style':
|
|
328
|
-
this.prevScreenStyle = new BoxBase().setProperties($(child));
|
|
329
|
-
break;
|
|
330
|
-
case 'p':
|
|
331
|
-
if (this.prevScreenText === null)
|
|
332
|
-
this.prevScreenText = '';
|
|
333
|
-
this.prevScreenText += `<p>${child.textContent}</p>`;
|
|
334
|
-
break;
|
|
335
|
-
}
|
|
336
|
-
});
|
|
337
|
-
break;
|
|
338
|
-
|
|
339
|
-
case 'evaluator':
|
|
340
|
-
this.ev = Evaluator.getEvaluator($node);
|
|
341
|
-
break;
|
|
342
|
-
|
|
343
|
-
case 'document':
|
|
344
|
-
// Read main document of text activities
|
|
345
|
-
this.document = new TextActivityDocument().setProperties($node, this.project.mediaBag);
|
|
346
|
-
break;
|
|
347
|
-
}
|
|
348
|
-
});
|
|
349
|
-
return this;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
/**
|
|
353
|
-
* Read an activity message from an XML element
|
|
354
|
-
* @param {external:jQuery} $xml - The XML element to be parsed
|
|
355
|
-
* @returns {module:boxes/ActiveBoxContent.ActiveBoxContent}
|
|
356
|
-
*/
|
|
357
|
-
readMessage($xml) {
|
|
358
|
-
const msg = new ActiveBoxContent().setProperties($xml, this.project.mediaBag);
|
|
359
|
-
//
|
|
360
|
-
// Allowed types are: `initial`, `final`, `previous`, `finalError`
|
|
361
|
-
msg.type = $xml.attr('type');
|
|
362
|
-
if (isNullOrUndef(msg.style))
|
|
363
|
-
msg.style = new BoxBase(null);
|
|
364
|
-
return msg;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
/**
|
|
368
|
-
* Gets a object with the basic attributes needed to rebuild this instance excluding functions,
|
|
369
|
-
* parent references, constants and also attributes retaining the default value.
|
|
370
|
-
* The resulting object is commonly usued to serialize elements in JSON format.
|
|
371
|
-
* @returns {object} - The resulting object, with minimal attrributes
|
|
372
|
-
*/
|
|
373
|
-
getAttributes() {
|
|
374
|
-
return getAttr(this, [
|
|
375
|
-
'name', 'className', 'code', 'type', 'description',
|
|
376
|
-
'invAss', 'numericContent',
|
|
377
|
-
'autoJump', 'forceOkToAdvance', 'amongParagraphs',
|
|
378
|
-
'infoUrl', 'infoCmd',
|
|
379
|
-
`margin|${settings.DEFAULT_MARGIN}`, 'maxTime', 'maxActions',
|
|
380
|
-
'includeInReports|true', 'reportActions|false',
|
|
381
|
-
'countDownTime', 'countDownActions',
|
|
382
|
-
'useOrder', 'dragCells',
|
|
383
|
-
'skinFileName',
|
|
384
|
-
'showSolution|false', 'helpMsg',
|
|
385
|
-
`bgColor|${settings.DEFAULT_BG_COLOR}`, 'bgImageFile', 'tiledBgImg',
|
|
386
|
-
'bTimeCounter|true', 'bActionsCounter|true', 'bScoreCounter|true',
|
|
387
|
-
`activityBgColor|${settings.DEFAULT_BG_COLOR}`, 'transparentBg|false', 'border|true',
|
|
388
|
-
'shuffleA', 'shuffleB', 'shuffles', 'boxGridPos',
|
|
389
|
-
'wildTransparent', 'upperCase', 'checkCase',
|
|
390
|
-
'checkButtonText',
|
|
391
|
-
'prevScreen', 'prevScreenMaxTime', 'prevScreenText',
|
|
392
|
-
'bgGradient', 'activityBgGradient', // Gradient
|
|
393
|
-
'absolutePosition', // Point
|
|
394
|
-
'windowSize', // Dimension
|
|
395
|
-
'eventSounds', // EventSounds
|
|
396
|
-
'messages', // ActiveBoxContent{}
|
|
397
|
-
'acp', // AutoContentProvider
|
|
398
|
-
'abc', // ActiveBagContent{}
|
|
399
|
-
'menuElements', // Activity~menuElement
|
|
400
|
-
'tgc', // TextGridContent
|
|
401
|
-
'clues', // string[]
|
|
402
|
-
'clueItems', // number[]
|
|
403
|
-
'prevScreenStyle', // BoxBase
|
|
404
|
-
'ev', // Evaluator
|
|
405
|
-
'document', // TextActivityDocument
|
|
406
|
-
]);
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
/**
|
|
410
|
-
* Load the activity settings from a data object
|
|
411
|
-
* @param {object} data - The data object to parse
|
|
412
|
-
*/
|
|
413
|
-
setAttributes(data, mediaBag = this.project.mediaBag) {
|
|
414
|
-
setAttr(this, data, [
|
|
415
|
-
'name', 'className', 'code', 'type', 'description', 'invAss', 'numericContent',
|
|
416
|
-
'autoJump', 'forceOkToAdvance', 'amongParagraphs', 'infoUrl', 'infoCmd',
|
|
417
|
-
'margin', 'maxTime', 'maxActions', 'includeInReports', 'reportActions',
|
|
418
|
-
'countDownTime', 'countDownActions', 'useOrder', 'dragCells', 'skinFileName',
|
|
419
|
-
'showSolution', 'helpMsg', 'bgColor', 'bgImageFile', 'tiledBgImg',
|
|
420
|
-
'bTimeCounter', 'bActionsCounter', 'bScoreCounter',
|
|
421
|
-
'activityBgColor', 'transparentBg', 'border',
|
|
422
|
-
'shuffleA', 'shuffleB', 'shuffles', 'boxGridPos',
|
|
423
|
-
'wildTransparent', 'upperCase', 'checkCase', 'checkButtonText',
|
|
424
|
-
'prevScreen', 'prevScreenMaxTime', 'prevScreenText',
|
|
425
|
-
{ key: 'bgGradient', fn: Gradient },
|
|
426
|
-
{ key: 'activityBgGradient', fn: Gradient },
|
|
427
|
-
{ key: 'absolutePosition', fn: Point },
|
|
428
|
-
{ key: 'windowSize', fn: Dimension },
|
|
429
|
-
{ key: 'messages', fn: ActiveBoxContent, group: 'object', init: 'key', params: [mediaBag] },
|
|
430
|
-
{ key: 'abc', fn: ActiveBagContent, group: 'object', init: 'key', params: [mediaBag] },
|
|
431
|
-
{ key: 'acp', fn: AutoContentProvider, params: [mediaBag] },
|
|
432
|
-
'menuElements',
|
|
433
|
-
{ key: 'tgc', fn: TextGridContent },
|
|
434
|
-
'clues',
|
|
435
|
-
'clueItems',
|
|
436
|
-
{ key: 'prevScreenStyle', fn: BoxBase },
|
|
437
|
-
{ key: 'ev', fn: Evaluator },
|
|
438
|
-
{ key: 'document', fn: TextActivityDocument, params: [mediaBag] },
|
|
439
|
-
]);
|
|
440
|
-
|
|
441
|
-
// Reused objects
|
|
442
|
-
if (data.eventSounds)
|
|
443
|
-
this.eventSounds.setAttributes(data.eventSounds);
|
|
444
|
-
|
|
445
|
-
// Manual settings
|
|
446
|
-
if (this.absolutePosition)
|
|
447
|
-
this.absolutePositioned = true;
|
|
448
|
-
|
|
449
|
-
return this;
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
/**
|
|
453
|
-
* Initialises the {@link module:automation/AutoContentProvider.AutoContentProvider AutoContentProvider}, when defined.
|
|
454
|
-
*/
|
|
455
|
-
initAutoContentProvider() {
|
|
456
|
-
if (this.acp !== null)
|
|
457
|
-
this.acp.init();
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
/**
|
|
461
|
-
* Preloads the media content of the activity.
|
|
462
|
-
* @param {module:JClicPlayer.JClicPlayer} ps - The {@link module:JClicPlayer.JClicPlayer} used to realize the media objects.
|
|
463
|
-
*/
|
|
464
|
-
prepareMedia(ps) {
|
|
465
|
-
this.eventSounds.realize(ps, this.project.mediaBag);
|
|
466
|
-
$.each(this.messages, (_key, msg) => {
|
|
467
|
-
if (msg !== null) msg.prepareMedia(ps);
|
|
468
|
-
});
|
|
469
|
-
$.each(this.abc, (_key, abc) => {
|
|
470
|
-
if (abc !== null)
|
|
471
|
-
abc.prepareMedia(ps);
|
|
472
|
-
});
|
|
473
|
-
return true;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
/**
|
|
477
|
-
* Whether the activity allows the user to request the solution.
|
|
478
|
-
* @returns {boolean}
|
|
479
|
-
*/
|
|
480
|
-
helpSolutionAllowed() {
|
|
481
|
-
return false;
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
/**
|
|
485
|
-
* Whether the activity allows the user to request help.
|
|
486
|
-
* @returns {boolean}
|
|
487
|
-
*/
|
|
488
|
-
helpWindowAllowed() {
|
|
489
|
-
return this.helpWindow &&
|
|
490
|
-
(this.helpSolutionAllowed() && this.showSolution || this.helpMsg !== null);
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
/**
|
|
494
|
-
* Retrieves the minimum number of actions needed to solve this activity.
|
|
495
|
-
* @returns {number}
|
|
496
|
-
*/
|
|
497
|
-
getMinNumActions() {
|
|
498
|
-
return 0;
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
/**
|
|
502
|
-
* When this method returns `true`, the automatic jump to the next activity must be paused at
|
|
503
|
-
* this activity.
|
|
504
|
-
* @returns {boolean}
|
|
505
|
-
*/
|
|
506
|
-
mustPauseSequence() {
|
|
507
|
-
return this.getMinNumActions() !== 0;
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
/**
|
|
511
|
-
* Whether or not the activity can be reset
|
|
512
|
-
* @returns {boolean}
|
|
513
|
-
*/
|
|
514
|
-
canReinit() {
|
|
515
|
-
return true;
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
/**
|
|
519
|
-
* Whether or not the activity has additional information to be shown.
|
|
520
|
-
* @returns {boolean}
|
|
521
|
-
*/
|
|
522
|
-
hasInfo() {
|
|
523
|
-
return this.infoUrl !== null && this.infoUrl.length > 0 ||
|
|
524
|
-
this.infoCmd !== null && this.infoCmd.length > 0;
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
/**
|
|
528
|
-
* Whether or not the activity uses random to shuffle internal components
|
|
529
|
-
* @returns {boolean}
|
|
530
|
-
*/
|
|
531
|
-
hasRandom() {
|
|
532
|
-
return false;
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
/**
|
|
536
|
-
* When `true`, the activity must always be shuffled
|
|
537
|
-
* @returns {boolean}
|
|
538
|
-
*/
|
|
539
|
-
shuffleAlways() {
|
|
540
|
-
return false;
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
/**
|
|
544
|
-
* When `true`, the activity makes use of the keyboard
|
|
545
|
-
* @returns {boolean}
|
|
546
|
-
*/
|
|
547
|
-
needsKeyboard() {
|
|
548
|
-
return false;
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
/**
|
|
552
|
-
* Called when the activity must be disposed
|
|
553
|
-
*/
|
|
554
|
-
end() {
|
|
555
|
-
this.eventSounds.close();
|
|
556
|
-
this.clear();
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
/**
|
|
560
|
-
* Called when the activity must reset its internal components
|
|
561
|
-
*/
|
|
562
|
-
clear() {
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
/**
|
|
566
|
-
*
|
|
567
|
-
* Getter method for `windowSize`
|
|
568
|
-
* @returns {module:AWT.Dimension}
|
|
569
|
-
*/
|
|
570
|
-
getWindowSize() {
|
|
571
|
-
return new Dimension(this.windowSize);
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
/**
|
|
575
|
-
* Setter method for `windowSize`
|
|
576
|
-
* @param {module:AWT.Dimension} windowSize
|
|
577
|
-
*/
|
|
578
|
-
setWindowSize(windowSize) {
|
|
579
|
-
this.windowSize = new Dimension(windowSize);
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
/**
|
|
583
|
-
* Builds the {@link module:Activity.ActivityPanel ActivityPanel} object.
|
|
584
|
-
* Subclasses must update the `Panel` member of its prototypes to produce specific panels.
|
|
585
|
-
* @param {module:JClicPlayer.JClicPlayer} ps - The {@link module:JClicPlayer.JClicPlayer JClicPlayer} used to build media objects.
|
|
586
|
-
* @returns {module:Activity.ActivityPanel}
|
|
587
|
-
*/
|
|
588
|
-
getActivityPanel(ps) {
|
|
589
|
-
return new this.constructor.Panel(this, ps);
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
/**
|
|
594
|
-
* Classes derived from `Activity` should register themselves by adding a field to
|
|
595
|
-
* `Activity.CLASSES` using `Activity.registerClass`
|
|
596
|
-
* @type {object}
|
|
597
|
-
*/
|
|
598
|
-
Activity.CLASSES = {
|
|
599
|
-
'@panels.Menu': Activity
|
|
600
|
-
};
|
|
601
|
-
|
|
602
|
-
Object.assign(Activity.prototype, {
|
|
603
|
-
/**
|
|
604
|
-
* The {@link module:project/JClicProject.JClicProject JClicProject} to which this activity belongs
|
|
605
|
-
* @name module:Activity.Activity#project
|
|
606
|
-
* @type {module:project/JClicProject.JClicProject} */
|
|
607
|
-
project: null,
|
|
608
|
-
/**
|
|
609
|
-
* The Activity name
|
|
610
|
-
* @name module:Activity.Activity#name
|
|
611
|
-
* @type {string} */
|
|
612
|
-
name: settings.DEFAULT_NAME,
|
|
613
|
-
/**
|
|
614
|
-
* The class name of this Activity
|
|
615
|
-
* @name module:Activity.Activity#className
|
|
616
|
-
* @type {string} */
|
|
617
|
-
className: null,
|
|
618
|
-
/**
|
|
619
|
-
* Code used in reports to filter queries. Default is `null`.
|
|
620
|
-
* @name module:Activity.Activity#code
|
|
621
|
-
* @type {string} */
|
|
622
|
-
code: null,
|
|
623
|
-
/**
|
|
624
|
-
* Type of activity, used in text activities to distinguish between different variants of the
|
|
625
|
-
* same activity. Possible values are: `orderWords`, `orderParagraphs`, `identifyWords` and
|
|
626
|
-
* `identifyChars`.
|
|
627
|
-
* @name module:Activity.Activity#type
|
|
628
|
-
* @type {string} */
|
|
629
|
-
type: null,
|
|
630
|
-
/**
|
|
631
|
-
* A short description of the activity
|
|
632
|
-
* @name module:Activity.Activity#description
|
|
633
|
-
* @type {string} */
|
|
634
|
-
description: null,
|
|
635
|
-
/**
|
|
636
|
-
* The space between the activity components measured in pixels.
|
|
637
|
-
* @name module:Activity.Activity#margin
|
|
638
|
-
* @type {number} */
|
|
639
|
-
margin: settings.DEFAULT_MARGIN,
|
|
640
|
-
/**
|
|
641
|
-
* The background color of the activity panel
|
|
642
|
-
* @name module:Activity.Activity#bgColor
|
|
643
|
-
* @type {string} */
|
|
644
|
-
bgColor: settings.DEFAULT_BG_COLOR,
|
|
645
|
-
/**
|
|
646
|
-
* When set, gradient used to draw the activity window background
|
|
647
|
-
* @name module:Activity.Activity#bgGradient
|
|
648
|
-
* @type {module:AWT.Gradient} */
|
|
649
|
-
bgGradient: null,
|
|
650
|
-
/**
|
|
651
|
-
* Whether the bgImage (if any) has to be tiled across the panel background
|
|
652
|
-
* @name module:Activity.Activity#tiledBgImg
|
|
653
|
-
* @type {boolean} */
|
|
654
|
-
tiledBgImg: false,
|
|
655
|
-
/**
|
|
656
|
-
* Filename of the image used as a panel background.
|
|
657
|
-
* @name module:Activity.Activity#bgImageFile
|
|
658
|
-
* @type {string} */
|
|
659
|
-
bgImageFile: null,
|
|
660
|
-
/**
|
|
661
|
-
* Whether to draw a border around the activity panel
|
|
662
|
-
* @name module:Activity.Activity#border
|
|
663
|
-
* @type {boolean} */
|
|
664
|
-
border: true,
|
|
665
|
-
/**
|
|
666
|
-
* Whether to place the activity panel at the point specified by `absolutePosition` or leave
|
|
667
|
-
* it centered on the main player's window.
|
|
668
|
-
* @name module:Activity.Activity#absolutePositioned
|
|
669
|
-
* @type {boolean} */
|
|
670
|
-
absolutePositioned: false,
|
|
671
|
-
/**
|
|
672
|
-
* The position of the activity panel on the player.
|
|
673
|
-
* @name module:Activity.Activity#absolutePosition
|
|
674
|
-
* @type {module:AWT.Point} */
|
|
675
|
-
absolutePosition: null,
|
|
676
|
-
/**
|
|
677
|
-
* Whether to generate usage reports
|
|
678
|
-
* @name module:Activity.Activity#includeInReports
|
|
679
|
-
* @type {boolean} */
|
|
680
|
-
includeInReports: true,
|
|
681
|
-
/**
|
|
682
|
-
* Whether to send action events to the {@link module:Reporter.Reporter Reporter}
|
|
683
|
-
* @name module:Activity.Activity#reportActions
|
|
684
|
-
* @type {boolean} */
|
|
685
|
-
reportActions: false,
|
|
686
|
-
/**
|
|
687
|
-
* Whether to allow help about the activity or not.
|
|
688
|
-
* @name module:Activity.Activity#helpWindow
|
|
689
|
-
* @type {boolean} */
|
|
690
|
-
helpWindow: false,
|
|
691
|
-
/**
|
|
692
|
-
* Whether to show the solution on the help window.
|
|
693
|
-
* @name module:Activity.Activity#showSolution
|
|
694
|
-
* @type {boolean} */
|
|
695
|
-
showSolution: false,
|
|
696
|
-
/**
|
|
697
|
-
* Message to be shown in the help window when `showSolution` is `false`.
|
|
698
|
-
* @name module:Activity.Activity#helpMsg
|
|
699
|
-
* @type {string} */
|
|
700
|
-
helpMsg: '',
|
|
701
|
-
/**
|
|
702
|
-
* Specific set of {@link module:media/EventSounds.EventSounds EventSounds} used in the activity. The default is `null`, meaning
|
|
703
|
-
* to use the default event sounds.
|
|
704
|
-
* @name module:Activity.Activity#eventSounds
|
|
705
|
-
* @type {module:media/EventSounds.EventSounds} */
|
|
706
|
-
eventSounds: null,
|
|
707
|
-
/**
|
|
708
|
-
* Wheter the activity must be solved in a specific order or not.
|
|
709
|
-
* @name module:Activity.Activity#useOrder
|
|
710
|
-
* @type {boolean} */
|
|
711
|
-
useOrder: false,
|
|
712
|
-
/**
|
|
713
|
-
* Wheter the cells of the activity will be dragged across the screen.
|
|
714
|
-
* When `false`, a line will be painted to link elements.
|
|
715
|
-
* @name module:Activity.Activity#dragCells
|
|
716
|
-
* @type {boolean} */
|
|
717
|
-
dragCells: false,
|
|
718
|
-
/**
|
|
719
|
-
* File name of the Skin used by the activity. The default value is `null`, meaning that the
|
|
720
|
-
* activity will use the skin specified for the project.
|
|
721
|
-
* @name module:Activity.Activity#skinFileName
|
|
722
|
-
* @type {string} */
|
|
723
|
-
skinFileName: null,
|
|
724
|
-
/**
|
|
725
|
-
* Maximum amount of time (seconds) to solve the activity. The default value is 0, meaning
|
|
726
|
-
* unlimited time.
|
|
727
|
-
* @name module:Activity.Activity#maxTime
|
|
728
|
-
* @type {number}*/
|
|
729
|
-
maxTime: 0,
|
|
730
|
-
/**
|
|
731
|
-
* Whether the time counter should display a countdown when `maxTime > 0`
|
|
732
|
-
* @name module:Activity.Activity#countDownTime
|
|
733
|
-
* @type {boolean} */
|
|
734
|
-
countDownTime: false,
|
|
735
|
-
/**
|
|
736
|
-
* Maximum number of actions allowed to solve the activity. The default value is 0, meaning
|
|
737
|
-
* unlimited actions.
|
|
738
|
-
* @name module:Activity.Activity#maxActions
|
|
739
|
-
* @type {number}*/
|
|
740
|
-
maxActions: 0,
|
|
741
|
-
/**
|
|
742
|
-
* Whether the actions counter should display a countdown when `maxActions > 0`
|
|
743
|
-
* @name module:Activity.Activity#countDownActions
|
|
744
|
-
* @type {boolean} */
|
|
745
|
-
countDownActions: false,
|
|
746
|
-
/**
|
|
747
|
-
* URL to be launched when the user clicks on the 'info' button. Default is `null`.
|
|
748
|
-
* @name module:Activity.Activity#infoUrl
|
|
749
|
-
* @type {string} */
|
|
750
|
-
infoUrl: null,
|
|
751
|
-
/**
|
|
752
|
-
* System command to be launched when the user clicks on the 'info' button. Default is `null`.
|
|
753
|
-
* Important: this parameter is currently not being used
|
|
754
|
-
* @name module:Activity.Activity#infoCmd
|
|
755
|
-
* @type {string} */
|
|
756
|
-
infoCmd: null,
|
|
757
|
-
/**
|
|
758
|
-
* The content of the initial, final, previous and error messages shown by the activity.
|
|
759
|
-
* @name module:Activity.Activity#messages
|
|
760
|
-
* @type {module:boxes/ActiveBoxContent.ActiveBoxContent[]} */
|
|
761
|
-
messages: null,
|
|
762
|
-
/**
|
|
763
|
-
* Preferred dimension of the activity window
|
|
764
|
-
* @name module:Activity.Activity#windowSize
|
|
765
|
-
* @type {module:AWT.Dimension} */
|
|
766
|
-
windowSize: new Dimension(settings.DEFAULT_WIDTH, settings.DEFAULT_HEIGHT),
|
|
767
|
-
/**
|
|
768
|
-
* Whether the activity window has transparent background.
|
|
769
|
-
* @name module:Activity.Activity#transparentBg
|
|
770
|
-
* @type {boolean} */
|
|
771
|
-
transparentBg: false,
|
|
772
|
-
/**
|
|
773
|
-
* The background color of the activity
|
|
774
|
-
* @name module:Activity.Activity#activityBgColor
|
|
775
|
-
* @type {string} */
|
|
776
|
-
activityBgColor: settings.DEFAULT_BG_COLOR,
|
|
777
|
-
/**
|
|
778
|
-
* Gradient used to draw backgrounds inside the activity.
|
|
779
|
-
* @name module:Activity.Activity#activityBgGradient
|
|
780
|
-
* @type {module:AWT.Gradient} */
|
|
781
|
-
activityBgGradient: null,
|
|
782
|
-
/**
|
|
783
|
-
* Whether to display or not the 'time' counter
|
|
784
|
-
* @name module:Activity.Activity#bTimeCounter
|
|
785
|
-
* @type {boolean} */
|
|
786
|
-
bTimeCounter: true,
|
|
787
|
-
/**
|
|
788
|
-
* Whether to display or not the 'score' counter
|
|
789
|
-
* @name module:Activity.Activity#bScoreCounter
|
|
790
|
-
* @type {boolean} */
|
|
791
|
-
bScoreCounter: true,
|
|
792
|
-
/**
|
|
793
|
-
* Whether to display or not the 'actions' counter
|
|
794
|
-
* @name module:Activity.Activity#bActionsCounter
|
|
795
|
-
* @type {boolean} */
|
|
796
|
-
bActionsCounter: true,
|
|
797
|
-
/**
|
|
798
|
-
* Special object used to generate random content at the start of the activity
|
|
799
|
-
* @name module:Activity.Activity#acp
|
|
800
|
-
* @type {module:automation/AutoContentProvider.AutoContentProvider} */
|
|
801
|
-
acp: null,
|
|
802
|
-
//
|
|
803
|
-
// Fields used only in certain activity types
|
|
804
|
-
// ------------------------------------------
|
|
805
|
-
//
|
|
806
|
-
/**
|
|
807
|
-
* Array of bags with the description of the content to be displayed on panels and cells.
|
|
808
|
-
* @name module:Activity.Activity#abc
|
|
809
|
-
* @type {module:boxes/ActiveBagContent.ActiveBagContent[]} */
|
|
810
|
-
abc: null,
|
|
811
|
-
/**
|
|
812
|
-
* Content of the grid of letters used in crosswords and shuffled letters
|
|
813
|
-
* @name module:Activity.Activity#tgc
|
|
814
|
-
* @type {module:boxes/TextGridContent.TextGridContent} */
|
|
815
|
-
tgc: null,
|
|
816
|
-
/**
|
|
817
|
-
* The main document used in text activities
|
|
818
|
-
* @name module:Activity.Activity#document
|
|
819
|
-
* @type {module:activities/text/TextActivityDocument.TextActivityDocument} */
|
|
820
|
-
document: null,
|
|
821
|
-
/**
|
|
822
|
-
* Relative position of the text grid (uses the same position codes as box grids)
|
|
823
|
-
* @name module:Activity.Activity#boxGridPos
|
|
824
|
-
* @type {string} */
|
|
825
|
-
boxGridPos: 'AB',
|
|
826
|
-
/**
|
|
827
|
-
* Number of times to shuffle the cells at the beginning of the activity
|
|
828
|
-
* @name module:Activity.Activity#shuffles
|
|
829
|
-
* @type {number} */
|
|
830
|
-
shuffles: settings.DEFAULT_SHUFFLES,
|
|
831
|
-
/**
|
|
832
|
-
* Box grid A must be shuffled.
|
|
833
|
-
* @name module:Activity.Activity#shuffleA
|
|
834
|
-
* @type {boolean} */
|
|
835
|
-
shuffleA: true,
|
|
836
|
-
/**
|
|
837
|
-
* Box grid B must be shuffled.
|
|
838
|
-
* @name module:Activity.Activity#shuffleB
|
|
839
|
-
* @type {boolean} */
|
|
840
|
-
shuffleB: true,
|
|
841
|
-
/**
|
|
842
|
-
* Flag to indicate "inverse resolution" in complex associations
|
|
843
|
-
* @name module:Activity.Activity#invAss
|
|
844
|
-
* @type {boolean} */
|
|
845
|
-
invAss: false,
|
|
846
|
-
/**
|
|
847
|
-
* Array of menu elements, used in activities of type {@link module:activities/panels/Menu.Menu Menu}
|
|
848
|
-
* @name module:Activity.Activity#menuElements
|
|
849
|
-
* @type {object[]} */
|
|
850
|
-
menuElements: null,
|
|
851
|
-
/**
|
|
852
|
-
* This activity uses numeric expressions, so text literals should be
|
|
853
|
-
* converted to numbers for comparisions, taking in account the
|
|
854
|
-
* number format of the current locale (dot or comma as decimal separator)
|
|
855
|
-
* @name module:Activity.Activity#numericContent
|
|
856
|
-
* @type {boolean} */
|
|
857
|
-
numericContent: false,
|
|
858
|
-
});
|
|
859
|
-
|
|
860
|
-
/**
|
|
861
|
-
* This object is responsible for rendering the contents of the activity on the screen and
|
|
862
|
-
* managing user's interaction.
|
|
863
|
-
* Each type of Activity must implement its own `ActivityPanel`.
|
|
864
|
-
* In JClic, {@link http://projectestac.github.io/jclic/apidoc/edu/xtec/jclic/Activity.Panel.html Activity.Panel}
|
|
865
|
-
* extends {@link http://docs.oracle.com/javase/7/docs/api/javax/swing/JPanel.html javax.swing.JPanel}.
|
|
866
|
-
* On this implementation, the JPanel will be replaced by an HTML `div` tag.
|
|
867
|
-
* @extends module:AWT.Container
|
|
868
|
-
*/
|
|
869
|
-
export class ActivityPanel extends Container {
|
|
870
|
-
/**
|
|
871
|
-
* ActivityPanel constructor
|
|
872
|
-
* @param {module:Activity.Activity} act - The {@link module:Activity.Activity Activity} to which this Panel belongs
|
|
873
|
-
* @param {module:JClicPlayer.JClicPlayer} ps - Any object implementing the methods defined in the
|
|
874
|
-
* {@link http://projectestac.github.io/jclic/apidoc/edu/xtec/jclic/PlayStation.html PlayStation}
|
|
875
|
-
* Java interface.
|
|
876
|
-
* @param {external:jQuery} [$div] - The jQuery DOM element where this Panel will deploy
|
|
877
|
-
*/
|
|
878
|
-
constructor(act, ps, $div) {
|
|
879
|
-
// ActivityPanel extends Container
|
|
880
|
-
super();
|
|
881
|
-
this.act = act;
|
|
882
|
-
this.ps = ps;
|
|
883
|
-
this.minimumSize = new Dimension(100, 100);
|
|
884
|
-
this.preferredSize = new Dimension(500, 400);
|
|
885
|
-
if ($div)
|
|
886
|
-
this.$div = $div;
|
|
887
|
-
else
|
|
888
|
-
this.$div = $('<div/>', { class: 'JClicActivity', 'aria-label': getMsg('Activity panel') });
|
|
889
|
-
this.act.initAutoContentProvider();
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
/**
|
|
893
|
-
* Sets the size and position of this activity panel
|
|
894
|
-
* @param {module:AWT.Rectangle} rect
|
|
895
|
-
*/
|
|
896
|
-
setBounds(rect) {
|
|
897
|
-
this.pos.x = rect.pos.x;
|
|
898
|
-
this.pos.y = rect.pos.y;
|
|
899
|
-
this.dim.width = rect.dim.width;
|
|
900
|
-
this.dim.height = rect.dim.height;
|
|
901
|
-
|
|
902
|
-
this.invalidate(rect);
|
|
903
|
-
this.$div.css({
|
|
904
|
-
position: 'relative',
|
|
905
|
-
left: rect.pos.x,
|
|
906
|
-
top: rect.pos.y,
|
|
907
|
-
width: rect.dim.width,
|
|
908
|
-
height: rect.dim.height
|
|
909
|
-
});
|
|
910
|
-
}
|
|
911
|
-
|
|
912
|
-
/**
|
|
913
|
-
* Prepares the visual components of the activity
|
|
914
|
-
*/
|
|
915
|
-
buildVisualComponents() {
|
|
916
|
-
this.playing = false;
|
|
917
|
-
this.skin = null;
|
|
918
|
-
if (this.act.skinFileName && this.act.skinFileName.length > 0 && this.act.skinFileName !== this.act.project.settings.skinFileName)
|
|
919
|
-
this.skin = this.act.project.mediaBag.getSkinElement(this.act.skinFileName, this.ps);
|
|
920
|
-
|
|
921
|
-
this.bgImage = null;
|
|
922
|
-
if (this.act.bgImageFile && this.act.bgImageFile.length > 0) {
|
|
923
|
-
const mbe = this.act.project.mediaBag.getElement(this.act.bgImageFile, true);
|
|
924
|
-
if (mbe)
|
|
925
|
-
this.bgImage = mbe.data;
|
|
926
|
-
}
|
|
927
|
-
|
|
928
|
-
this.backgroundColor = this.act.activityBgColor;
|
|
929
|
-
|
|
930
|
-
if (this.act.transparentBg)
|
|
931
|
-
this.backgroundTransparent = true;
|
|
932
|
-
|
|
933
|
-
// TODO: fix bevel-border type
|
|
934
|
-
if (this.act.border)
|
|
935
|
-
this.border = true;
|
|
936
|
-
|
|
937
|
-
const cssAct = {
|
|
938
|
-
display: 'block',
|
|
939
|
-
'background-color': this.backgroundTransparent ? 'transparent' : this.backgroundColor
|
|
940
|
-
};
|
|
941
|
-
|
|
942
|
-
// Border shadow style Material Design, inspired in [http://codepen.io/Stenvh/pen/EaeWqW]
|
|
943
|
-
if (this.border) {
|
|
944
|
-
cssAct['box-shadow'] = '0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12)';
|
|
945
|
-
cssAct['border-radius'] = '2px';
|
|
946
|
-
cssAct['color'] = '#272727';
|
|
947
|
-
}
|
|
948
|
-
|
|
949
|
-
if (this.act.activityBgGradient)
|
|
950
|
-
cssAct['background-image'] = this.act.activityBgGradient.getCss();
|
|
951
|
-
|
|
952
|
-
this.$div.css(cssAct);
|
|
953
|
-
}
|
|
954
|
-
|
|
955
|
-
/**
|
|
956
|
-
* Activities should implement this method to update the graphic content of its panel. The method
|
|
957
|
-
* will be called from {@link module:AWT.Container#update} when needed.
|
|
958
|
-
* @param {module:AWT.Rectangle} dirtyRegion - Specifies the area to be updated. When `null`,
|
|
959
|
-
* it's the whole panel.
|
|
960
|
-
*/
|
|
961
|
-
updateContent(dirtyRegion) {
|
|
962
|
-
// To be overridden by subclasses. Here does nothing.
|
|
963
|
-
return super.updateContent(dirtyRegion);
|
|
964
|
-
}
|
|
965
|
-
|
|
966
|
-
/**
|
|
967
|
-
* Plays the specified event sound
|
|
968
|
-
* @param {string} event - The type of event to be performed
|
|
969
|
-
*/
|
|
970
|
-
playEvent(event) {
|
|
971
|
-
this.act.eventSounds.play(event);
|
|
972
|
-
}
|
|
973
|
-
|
|
974
|
-
/**
|
|
975
|
-
* Basic initialization procedure, common to all activities.
|
|
976
|
-
*/
|
|
977
|
-
initActivity() {
|
|
978
|
-
if (this.playing) {
|
|
979
|
-
this.playing = false;
|
|
980
|
-
this.ps.reportEndActivity(this.act, this.solved);
|
|
981
|
-
}
|
|
982
|
-
this.solved = false;
|
|
983
|
-
this.ps.reportNewActivity(this.act, 0);
|
|
984
|
-
this.attachEvents();
|
|
985
|
-
this.enableCounters();
|
|
986
|
-
}
|
|
987
|
-
|
|
988
|
-
/**
|
|
989
|
-
* Called when the activity starts playing
|
|
990
|
-
*/
|
|
991
|
-
startActivity() {
|
|
992
|
-
this.playing = true;
|
|
993
|
-
}
|
|
994
|
-
|
|
995
|
-
/**
|
|
996
|
-
* Called by {@link module:JClicPlayer.JClicPlayer JClicPlayer} when this activity panel is fully visible, just after the
|
|
997
|
-
* initialization process.
|
|
998
|
-
*/
|
|
999
|
-
activityReady() {
|
|
1000
|
-
// To be overrided by subclasses
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
|
-
/**
|
|
1004
|
-
* Displays help about the activity
|
|
1005
|
-
*/
|
|
1006
|
-
showHelp() {
|
|
1007
|
-
// To be overrided by subclasses
|
|
1008
|
-
}
|
|
1009
|
-
|
|
1010
|
-
/**
|
|
1011
|
-
* Sets the real dimension of this ActivityPanel.
|
|
1012
|
-
* @param {module:AWT.Dimension} maxSize - The maximum surface available for the activity panel
|
|
1013
|
-
* @returns {module:AWT.Dimension}
|
|
1014
|
-
*/
|
|
1015
|
-
setDimension(maxSize) {
|
|
1016
|
-
return new Dimension(
|
|
1017
|
-
Math.min(maxSize.width, this.act.windowSize.width),
|
|
1018
|
-
Math.min(maxSize.height, this.act.windowSize.height));
|
|
1019
|
-
}
|
|
1020
|
-
|
|
1021
|
-
/**
|
|
1022
|
-
* Attaches the events specified in the `events` member to the `$div` member
|
|
1023
|
-
*/
|
|
1024
|
-
attachEvents() {
|
|
1025
|
-
this.events.forEach(ev => this.attachEvent(this.$div, ev));
|
|
1026
|
-
// Prepare handler to check if we are in a touch device
|
|
1027
|
-
if (!settings.TOUCH_DEVICE && $.inArray(TOUCH_TEST_EVENT, this.events) === -1)
|
|
1028
|
-
this.attachEvent(this.$div, TOUCH_TEST_EVENT);
|
|
1029
|
-
}
|
|
1030
|
-
|
|
1031
|
-
/**
|
|
1032
|
-
* Attaches a single event to the specified object
|
|
1033
|
-
* @param {external:jQuery} $obj - The object to which the event will be attached
|
|
1034
|
-
* @param {string} evt - The event name
|
|
1035
|
-
*/
|
|
1036
|
-
attachEvent($obj, evt) {
|
|
1037
|
-
$obj.on(evt, this, event => {
|
|
1038
|
-
if (event.type === TOUCH_TEST_EVENT) {
|
|
1039
|
-
if (!settings.TOUCH_DEVICE)
|
|
1040
|
-
settings.TOUCH_DEVICE = true;
|
|
1041
|
-
if ($.inArray(TOUCH_TEST_EVENT, this.events) === -1) {
|
|
1042
|
-
// Disconnect handler
|
|
1043
|
-
$obj.off(TOUCH_TEST_EVENT);
|
|
1044
|
-
return;
|
|
1045
|
-
}
|
|
1046
|
-
}
|
|
1047
|
-
return event.data.processEvent.call(event.data, event);
|
|
1048
|
-
});
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1051
|
-
/**
|
|
1052
|
-
* Main handler used to process mouse, touch, keyboard and edit events.
|
|
1053
|
-
* @param {external:Event} event - The HTML event to be processed
|
|
1054
|
-
* @returns {boolean} - When this event handler returns `false`, jQuery will stop its
|
|
1055
|
-
* propagation through the DOM tree. See: {@link http://api.jquery.com/on}
|
|
1056
|
-
*/
|
|
1057
|
-
processEvent(_event) {
|
|
1058
|
-
return false;
|
|
1059
|
-
}
|
|
1060
|
-
|
|
1061
|
-
/**
|
|
1062
|
-
* Fits the panel within the `proposed` rectangle. The panel can occupy more space, but always
|
|
1063
|
-
* not surpassing the `bounds` rectangle.
|
|
1064
|
-
* @param {module:AWT.Rectangle} proposed - The proposed rectangle
|
|
1065
|
-
* @param {module:AWT.Rectangle} bounds - The maximum allowed bounds
|
|
1066
|
-
*/
|
|
1067
|
-
fitTo(proposed, bounds) {
|
|
1068
|
-
const origin = new Point();
|
|
1069
|
-
if (this.act.absolutePositioned && this.act.absolutePosition !== null) {
|
|
1070
|
-
origin.x = Math.max(0, this.act.absolutePosition.x + proposed.pos.x);
|
|
1071
|
-
origin.y = Math.max(0, this.act.absolutePosition.y + proposed.pos.y);
|
|
1072
|
-
proposed.dim.width -= this.act.absolutePosition.x;
|
|
1073
|
-
proposed.dim.height -= this.act.absolutePosition.y;
|
|
1074
|
-
}
|
|
1075
|
-
const d = this.setDimension(new Dimension(
|
|
1076
|
-
Math.max(2 * this.act.margin + settings.MINIMUM_WIDTH, proposed.dim.width),
|
|
1077
|
-
Math.max(2 * this.act.margin + settings.MINIMUM_HEIGHT, proposed.dim.height)));
|
|
1078
|
-
if (!this.act.absolutePositioned) {
|
|
1079
|
-
origin.moveTo(
|
|
1080
|
-
Math.max(0, proposed.pos.x + (proposed.dim.width - d.width) / 2),
|
|
1081
|
-
Math.max(0, proposed.pos.y + (proposed.dim.height - d.height) / 2));
|
|
1082
|
-
}
|
|
1083
|
-
if (origin.x + d.width > bounds.dim.width)
|
|
1084
|
-
origin.x = Math.max(0, bounds.dim.width - d.width);
|
|
1085
|
-
if (origin.y + d.height > bounds.dim.height)
|
|
1086
|
-
origin.y = Math.max(0, bounds.dim.height - d.height);
|
|
1087
|
-
this.setBounds(new Rectangle(origin.x, origin.y, d.width, d.height));
|
|
1088
|
-
|
|
1089
|
-
// Build accessible components at the end of current tree
|
|
1090
|
-
window.setTimeout(() => this.buildAccessibleComponents(), 0);
|
|
1091
|
-
}
|
|
1092
|
-
|
|
1093
|
-
/**
|
|
1094
|
-
*
|
|
1095
|
-
* Builds the accessible components needed for this ActivityPanel
|
|
1096
|
-
* This method is called when all main elements are placed and visible, when the activity is ready
|
|
1097
|
-
* to start or when resized.
|
|
1098
|
-
*/
|
|
1099
|
-
buildAccessibleComponents() {
|
|
1100
|
-
// Clear existing elements
|
|
1101
|
-
if (this.accessibleCanvas && this.$canvas && this.$canvas.children().length > 0) {
|
|
1102
|
-
// UPDATED May 2020: clearHitRegions has been deprecated!
|
|
1103
|
-
// this.$canvas.get(-1).getContext('2d').clearHitRegions();
|
|
1104
|
-
this.$canvas.empty();
|
|
1105
|
-
}
|
|
1106
|
-
// Create accessible elements in subclasses
|
|
1107
|
-
}
|
|
1108
|
-
|
|
1109
|
-
/**
|
|
1110
|
-
* Forces the ending of the activity.
|
|
1111
|
-
*/
|
|
1112
|
-
forceFinishActivity() {
|
|
1113
|
-
// to be overrided by subclasses
|
|
1114
|
-
}
|
|
1115
|
-
|
|
1116
|
-
/**
|
|
1117
|
-
* Ordinary ending of the activity, usually called form `processEvent`
|
|
1118
|
-
* @param {boolean} result - `true` if the activity was successfully completed, `false` otherwise
|
|
1119
|
-
*/
|
|
1120
|
-
finishActivity(result) {
|
|
1121
|
-
this.playing = false;
|
|
1122
|
-
this.solved = result;
|
|
1123
|
-
|
|
1124
|
-
if (this.bc !== null)
|
|
1125
|
-
this.bc.end();
|
|
1126
|
-
|
|
1127
|
-
if (result) {
|
|
1128
|
-
this.setAndPlayMsg('final', 'finishedOk');
|
|
1129
|
-
} else {
|
|
1130
|
-
this.setAndPlayMsg('finalError', 'finishedError');
|
|
1131
|
-
}
|
|
1132
|
-
this.ps.activityFinished(this.solved);
|
|
1133
|
-
this.ps.reportEndActivity(this.act, this.solved);
|
|
1134
|
-
}
|
|
1135
|
-
|
|
1136
|
-
/**
|
|
1137
|
-
* Sets the message to be displayed in the skin message box and optionally plays a sound event.
|
|
1138
|
-
* @param {string} msgCode - Type of message (initial, final, finalError...)
|
|
1139
|
-
* @param {string} [eventSoundsCode] - Optional name of the event sound to be played.
|
|
1140
|
-
*/
|
|
1141
|
-
setAndPlayMsg(msgCode, eventSoundsCode) {
|
|
1142
|
-
const msg = this.act.messages[msgCode] || null;
|
|
1143
|
-
this.ps.setMsg(msg);
|
|
1144
|
-
if (msg === null || msg.mediaContent === null)
|
|
1145
|
-
this.playEvent(eventSoundsCode);
|
|
1146
|
-
}
|
|
1147
|
-
|
|
1148
|
-
/**
|
|
1149
|
-
* Ends the activity
|
|
1150
|
-
*/
|
|
1151
|
-
end() {
|
|
1152
|
-
this.forceFinishActivity();
|
|
1153
|
-
if (this.playing) {
|
|
1154
|
-
if (this.bc !== null)
|
|
1155
|
-
this.bc.end();
|
|
1156
|
-
this.ps.reportEndActivity(this.act, this.solved);
|
|
1157
|
-
this.playing = false;
|
|
1158
|
-
this.solved = false;
|
|
1159
|
-
}
|
|
1160
|
-
this.clear();
|
|
1161
|
-
}
|
|
1162
|
-
|
|
1163
|
-
/**
|
|
1164
|
-
* Miscellaneous cleaning operations
|
|
1165
|
-
*/
|
|
1166
|
-
clear() {
|
|
1167
|
-
// to be overridden by subclasses
|
|
1168
|
-
}
|
|
1169
|
-
|
|
1170
|
-
/**
|
|
1171
|
-
* Enables or disables the three counters (time, score and actions)
|
|
1172
|
-
* @param {boolean} eTime - Whether to enable or disable the time counter
|
|
1173
|
-
* @param {boolean} eScore - Whether to enable or disable the score counter
|
|
1174
|
-
* @param {boolean} eActions - Whether to enable or disable the actions counter
|
|
1175
|
-
*/
|
|
1176
|
-
enableCounters(eTime, eScore, eActions) {
|
|
1177
|
-
if (typeof eTime === 'undefined')
|
|
1178
|
-
eTime = this.act.bTimeCounter;
|
|
1179
|
-
if (typeof eScore === 'undefined')
|
|
1180
|
-
eScore = this.act.bScoreCounter;
|
|
1181
|
-
if (typeof eActions === 'undefined')
|
|
1182
|
-
eActions = this.act.bActionsCounter;
|
|
1183
|
-
|
|
1184
|
-
this.ps.setCounterEnabled('time', eTime);
|
|
1185
|
-
if (this.act.countDownTime)
|
|
1186
|
-
this.ps.setCountDown('time', this.act.maxTime);
|
|
1187
|
-
this.ps.setCounterEnabled('score', eScore);
|
|
1188
|
-
this.ps.setCounterEnabled('actions', eActions);
|
|
1189
|
-
if (this.act.countDownActions)
|
|
1190
|
-
this.ps.setCountDown('actions', this.act.maxActions);
|
|
1191
|
-
}
|
|
1192
|
-
|
|
1193
|
-
/**
|
|
1194
|
-
* Shuffles the contents of the activity
|
|
1195
|
-
* @param {module:boxes/ActiveBoxBag.ActiveBoxBag[]} bg - The sets of boxes to be shuffled
|
|
1196
|
-
* @param {boolean} visible - The shuffle process must be animated on the screen (not yet implemented!)
|
|
1197
|
-
* @param {boolean} fitInArea - Shuffled pieces cannot go out of the current area
|
|
1198
|
-
*/
|
|
1199
|
-
shuffle(bg, visible, fitInArea) {
|
|
1200
|
-
const steps = this.act.shuffles;
|
|
1201
|
-
let i = steps;
|
|
1202
|
-
while (i > 0) {
|
|
1203
|
-
const k = i > steps ? steps : i;
|
|
1204
|
-
bg.forEach(abb => { if (abb) abb.shuffleCells(k, fitInArea); });
|
|
1205
|
-
i -= steps;
|
|
1206
|
-
}
|
|
1207
|
-
}
|
|
1208
|
-
}
|
|
1209
|
-
|
|
1210
|
-
Object.assign(ActivityPanel.prototype, {
|
|
1211
|
-
/**
|
|
1212
|
-
* The Activity this panel is related to
|
|
1213
|
-
* @name module:Activity.ActivityPanel#act
|
|
1214
|
-
* @type {module:Activity.Activity} */
|
|
1215
|
-
act: null,
|
|
1216
|
-
/**
|
|
1217
|
-
* The jQuery div element used by this panel
|
|
1218
|
-
* @name module:Activity.ActivityPanel#$div
|
|
1219
|
-
* @type {external:jQuery} */
|
|
1220
|
-
$div: null,
|
|
1221
|
-
/**
|
|
1222
|
-
* The jQuery main canvas element used by this panel
|
|
1223
|
-
* @name module:Activity.ActivityPanel#$canvas
|
|
1224
|
-
* @type {external:jQuery} */
|
|
1225
|
-
$canvas: null,
|
|
1226
|
-
/**
|
|
1227
|
-
* Always true, since canvas hit regions have been deprecated!
|
|
1228
|
-
* See: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility
|
|
1229
|
-
* @name module:Activity.ActivityPanel#accessibleCanvas
|
|
1230
|
-
* @type {boolean}
|
|
1231
|
-
*/
|
|
1232
|
-
accessibleCanvas: true,
|
|
1233
|
-
/**
|
|
1234
|
-
* The realized current {@link module:skins/Skin.Skin Skin}
|
|
1235
|
-
* @name module:Activity.ActivityPanel#skin
|
|
1236
|
-
* @type {module:skins/Skin.Skin} */
|
|
1237
|
-
skin: null,
|
|
1238
|
-
/**
|
|
1239
|
-
* Background element (currently a `span`) used to place animated GIFs when needed
|
|
1240
|
-
* @name module:Activity.ActivityPanel#$animatedBg
|
|
1241
|
-
* @type {external:jQuery} */
|
|
1242
|
-
$animatedBg: null,
|
|
1243
|
-
/**
|
|
1244
|
-
* Additional background element for animated GIFs, used in associations
|
|
1245
|
-
* @name module:Activity.ActivityPanel#$animatedBgB
|
|
1246
|
-
* @type {external:jQuery} */
|
|
1247
|
-
$animatedBgB: null,
|
|
1248
|
-
/**
|
|
1249
|
-
* `true` when the activity is solved, `false` otherwise
|
|
1250
|
-
* @name module:Activity.ActivityPanel#solved
|
|
1251
|
-
* @type {boolean} */
|
|
1252
|
-
solved: false,
|
|
1253
|
-
/**
|
|
1254
|
-
* The realized image used as a background
|
|
1255
|
-
* @name module:Activity.ActivityPanel#bgImage
|
|
1256
|
-
* @type {external:HTMLImageElement} */
|
|
1257
|
-
bgImage: null,
|
|
1258
|
-
/**
|
|
1259
|
-
* `true` while the activity is playing
|
|
1260
|
-
* @name module:Activity.ActivityPanel#playing
|
|
1261
|
-
* @type {boolean} */
|
|
1262
|
-
playing: false,
|
|
1263
|
-
/**
|
|
1264
|
-
* `true` if the activity is running for first time (not due to a click on the `replay` button)
|
|
1265
|
-
* @name module:Activity.ActivityPanel#firstRun
|
|
1266
|
-
* @type {boolean} */
|
|
1267
|
-
firstRun: true,
|
|
1268
|
-
/**
|
|
1269
|
-
* Currently selected item. Used in some types of activities.
|
|
1270
|
-
* @name module:Activity.ActivityPanel#currentItem
|
|
1271
|
-
* @type {number} */
|
|
1272
|
-
currentItem: 0,
|
|
1273
|
-
/**
|
|
1274
|
-
* The object used to connect cells and other elements in some types of activity
|
|
1275
|
-
* @name module:Activity.ActivityPanel#bc
|
|
1276
|
-
* @type {module:boxes/BoxConnector.BoxConnector} */
|
|
1277
|
-
bc: null,
|
|
1278
|
-
/**
|
|
1279
|
-
* The PlayStation used to realize media objects and communicate with the player services
|
|
1280
|
-
* (usually a {@link module:JClicPlayer.JClicPlayer JClicPlayer}
|
|
1281
|
-
* @name module:Activity.ActivityPanel#ps
|
|
1282
|
-
* @type {module:JClicPlayer.JClicPlayer} */
|
|
1283
|
-
ps: null,
|
|
1284
|
-
/**
|
|
1285
|
-
* The minimum size of this kind of ActivityPanel
|
|
1286
|
-
* @name module:Activity.ActivityPanel#minimumSize
|
|
1287
|
-
* @type {module:AWT.Dimension} */
|
|
1288
|
-
minimumSize: null,
|
|
1289
|
-
/**
|
|
1290
|
-
* The preferred size of this kind of ActivityPanel
|
|
1291
|
-
* @name module:Activity.ActivityPanel#preferredSize
|
|
1292
|
-
* @type {module:AWT.Dimension} */
|
|
1293
|
-
preferredSize: null,
|
|
1294
|
-
/**
|
|
1295
|
-
* List of events intercepted by this ActivityPanel. Current events are: 'keydown', 'keyup',
|
|
1296
|
-
* 'keypress', 'mousedown', 'mouseup', 'click', 'dblclick', 'mousemove', 'mouseenter',
|
|
1297
|
-
* 'mouseleave', 'mouseover', 'mouseout', 'touchstart', 'touchend', 'touchmove' and 'touchcancel'.
|
|
1298
|
-
* @name module:Activity.ActivityPanel#events
|
|
1299
|
-
* @type {string[]} */
|
|
1300
|
-
events: ['click'],
|
|
1301
|
-
backgroundColor: null,
|
|
1302
|
-
backgroundTransparent: false,
|
|
1303
|
-
border: null,
|
|
1304
|
-
});
|
|
1305
|
-
|
|
1306
|
-
/**
|
|
1307
|
-
* The panel class associated to each type of activity
|
|
1308
|
-
* @type {module:Activity.ActivityPanel} */
|
|
1309
|
-
Activity.Panel = ActivityPanel;
|
|
1310
|
-
|
|
1311
|
-
export default Activity;
|