* emcclib.js: one of the Javascript components of an Emscripten-based
* web/Javascript front end for Puzzles.
*
- * The other parts of this system live in emcc.c and emccpre.js.
+ * The other parts of this system live in emcc.c and emccpre.js. It
+ * also depends on being run in the context of a web page containing
+ * an appropriate collection of bits and pieces (a canvas, some
+ * buttons and links etc), which is generated for each puzzle by the
+ * script html/jspage.pl.
*
* This file contains a set of Javascript functions which we insert
* into Emscripten's library object via the --js-library option; this
* the name of the preset. (The corresponding game_params stays on
* the C side and never comes out this far; we just pass a numeric
* index back to the C code when a selection is made.)
+ *
+ * The special 'Custom' preset is requested by passing NULL to
+ * this function, rather than the string "Custom", since in that
+ * case we need to do something special - see below.
*/
js_add_preset: function(ptr) {
+ var name = (ptr == 0 ? "Custom..." : Pointer_stringify(ptr));
+ var value = gametypeoptions.length;
+
var option = document.createElement("option");
- option.value = gametypeoptions.length;
- option.appendChild(document.createTextNode(Pointer_stringify(ptr)));
+ option.value = value;
+ option.appendChild(document.createTextNode(name));
gametypeselector.appendChild(option);
gametypeoptions.push(option);
+
+ if (ptr == 0) {
+ // Create a _second_ element called 'Custom', which is
+ // hidden.
+ //
+ // Hiding this element (that is, setting it display:none)
+ // has the effect of making it not show up when the
+ // drop-down list is actually opened, but still show up
+ // when the item is selected.
+ //
+ // So what happens is that there's one element marked
+ // 'Custom' that the _user_ selects, but a second one to
+ // which we reset the dropdown after the config box
+ // returns (if we don't then turn out to select a
+ // different preset anyway). The point is that if the user
+ // has 'Custom' selected, but then wants to customise
+ // their settings a second time, we still get an onchange
+ // event when they select the Custom option again, which
+ // we wouldn't get if the browser thought it was already
+ // the selected one. But here, it's _not_ the selected
+ // option already; its invisible evil twin is selected.
+ //
+ // (Actually, they're not _identical_ evil twins: we label
+ // the two slightly differently. The visible one that the
+ // user can select is labelled "Custom..." to hint that it
+ // opens a dialog box, whereas the invisible one that's
+ // left shown after the box closes is just "Custom",
+ // because that's telling you what you _have_ got
+ // selected.)
+ option = document.createElement("option");
+ option.value = value;
+ option.appendChild(document.createTextNode("Custom"));
+ option.style.display = "none";
+ gametypeselector.appendChild(option);
+ gametypehiddencustom = option;
+ }
},
/*
* which turn out to exactly match a preset).
*/
js_select_preset: function(n) {
- gametypeoptions[n].selected = true;
+ if (gametypeoptions[n].value == gametypehiddencustom.value) {
+ // If we're asked to select the visible Custom option,
+ // select the invisible one instead. See comment above in
+ // js_add_preset.
+ gametypehiddencustom.selected = true;
+ } else {
+ gametypeoptions[n].selected = true;
+ }
},
/*
ctx.moveTo(x1 + 0.5, y1 + 0.5);
ctx.lineTo(x2 + 0.5, y2 + 0.5);
ctx.lineWidth = width;
- ctx.lineCap = '1';
- ctx.lineJoin = '1';
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
ctx.strokeStyle = colour;
ctx.stroke();
ctx.fillStyle = colour;
ctx.fill();
}
ctx.lineWidth = '1';
- ctx.lineCap = '1';
- ctx.lineJoin = '1';
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
ctx.strokeStyle = Pointer_stringify(outline);
ctx.stroke();
},
ctx.fill();
}
ctx.lineWidth = '1';
- ctx.lineCap = '1';
- ctx.lineJoin = '1';
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
ctx.strokeStyle = Pointer_stringify(outline);
ctx.stroke();
},
blitters[id] = document.createElement("canvas");
blitters[id].width = w;
blitters[id].height = h;
+ return id;
},
/*
*/
js_focus_canvas: function() {
onscreen_canvas.focus();
- },
+ }
});