X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=emcclib.js;h=385281ad0b6778e0120a554c86e827de9f18aa04;hb=3ce69e84cad15844282d691fa03e711c5353c05e;hp=cc6df284ecdd7ca0af9aa488bf117ff026675b2e;hpb=3e39f6b80b2b6e4308e2d3a9fa436cbbb9d9b621;p=sgt-puzzles.git diff --git a/emcclib.js b/emcclib.js index cc6df28..385281a 100644 --- a/emcclib.js +++ b/emcclib.js @@ -2,7 +2,11 @@ * 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 @@ -61,13 +65,37 @@ mergeInto(LibraryManager.library, { * 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 ? "Customise..." : 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) { + // The option we've just created is the one for inventing + // a new custom setup. + gametypenewcustom = option; + option.value = -1; + + // Now create another element called 'Custom', which will + // be auto-selected by us to indicate the custom settings + // you've previously selected. However, we don't add it to + // the game type selector; it will only appear when the + // user actually has custom settings selected. + option = document.createElement("option"); + option.value = -2; + option.appendChild(document.createTextNode("Custom")); + gametypethiscustom = option; + } }, /* @@ -93,7 +121,34 @@ mergeInto(LibraryManager.library, { * which turn out to exactly match a preset). */ js_select_preset: function(n) { - gametypeoptions[n].selected = true; + if (gametypethiscustom !== null) { + // Fiddle with the Custom/Customise options. If we're + // about to select the Custom option, then it should be in + // the menu, and the other one should read "Re-customise"; + // if we're about to select another one, then the static + // Custom option should disappear and the other one should + // read "Customise". + + if (gametypethiscustom.parentNode == gametypeselector) + gametypeselector.removeChild(gametypethiscustom); + if (gametypenewcustom.parentNode == gametypeselector) + gametypeselector.removeChild(gametypenewcustom); + + if (n < 0) { + gametypeselector.appendChild(gametypethiscustom); + gametypenewcustom.lastChild.data = "Re-customise..."; + } else { + gametypenewcustom.lastChild.data = "Customise..."; + } + gametypeselector.appendChild(gametypenewcustom); + gametypenewcustom.selected = false; + } + + if (n < 0) { + gametypethiscustom.selected = true; + } else { + gametypeoptions[n].selected = true; + } }, /* @@ -271,8 +326,8 @@ mergeInto(LibraryManager.library, { 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; @@ -300,8 +355,8 @@ mergeInto(LibraryManager.library, { ctx.fill(); } ctx.lineWidth = '1'; - ctx.lineCap = '1'; - ctx.lineJoin = '1'; + ctx.lineCap = 'round'; + ctx.lineJoin = 'round'; ctx.strokeStyle = Pointer_stringify(outline); ctx.stroke(); }, @@ -321,8 +376,8 @@ mergeInto(LibraryManager.library, { ctx.fill(); } ctx.lineWidth = '1'; - ctx.lineCap = '1'; - ctx.lineJoin = '1'; + ctx.lineCap = 'round'; + ctx.lineJoin = 'round'; ctx.strokeStyle = Pointer_stringify(outline); ctx.stroke(); }, @@ -357,7 +412,7 @@ mergeInto(LibraryManager.library, { // Find the width of the string var ctx1 = onscreen_canvas.getContext('2d'); ctx1.font = font; - var width = ctx1.measureText(midpoint_test_str).width; + var width = (ctx1.measureText(midpoint_test_str).width + 1) | 0; // Construct a test canvas of appropriate size, initialise it to // black, and draw the string on it in white @@ -421,6 +476,7 @@ mergeInto(LibraryManager.library, { blitters[id] = document.createElement("canvas"); blitters[id].width = w; blitters[id].height = h; + return id; }, /* @@ -470,18 +526,20 @@ mergeInto(LibraryManager.library, { * back end turns out to want one. */ js_canvas_make_statusbar: function() { - var statustd = document.getElementById("statusbarholder"); + var statusholder = document.getElementById("statusbarholder"); statusbar = document.createElement("div"); statusbar.style.overflow = "hidden"; - statusbar.style.width = onscreen_canvas.width - 4; + statusbar.style.width = (onscreen_canvas.width - 4) + "px"; + statusholder.style.width = onscreen_canvas.width + "px"; statusbar.style.height = "1.2em"; + statusbar.style.textAlign = "left"; statusbar.style.background = "#d8d8d8"; statusbar.style.borderLeft = '2px solid #c8c8c8'; statusbar.style.borderTop = '2px solid #c8c8c8'; statusbar.style.borderRight = '2px solid #e8e8e8'; statusbar.style.borderBottom = '2px solid #e8e8e8'; statusbar.appendChild(document.createTextNode(" ")); - statustd.appendChild(statusbar); + statusholder.appendChild(statusbar); }, /* @@ -505,8 +563,11 @@ mergeInto(LibraryManager.library, { js_canvas_set_size: function(w, h) { onscreen_canvas.width = w; offscreen_canvas.width = w; - if (statusbar !== null) - statusbar.style.width = w - 4; + if (statusbar !== null) { + statusbar.style.width = (w - 4) + "px"; + document.getElementById("statusbarholder").style.width = w + "px"; + } + resizable_div.style.width = w + "px"; onscreen_canvas.height = h; offscreen_canvas.height = h; @@ -532,15 +593,15 @@ mergeInto(LibraryManager.library, { // Now create a form which sits on top of that in turn. dlg_form = document.createElement("form"); - dlg_form.style.width = window.innerWidth * 2 / 3; + dlg_form.style.width = (window.innerWidth * 2 / 3) + "px"; dlg_form.style.opacity = 1; dlg_form.style.background = '#ffffff'; dlg_form.style.color = '#000000'; dlg_form.style.position = 'absolute'; dlg_form.style.border = "2px solid black"; - dlg_form.style.padding = 20; - dlg_form.style.top = window.innerHeight / 10; - dlg_form.style.left = window.innerWidth / 6; + dlg_form.style.padding = "20px"; + dlg_form.style.top = (window.innerHeight / 10) + "px"; + dlg_form.style.left = (window.innerWidth / 6) + "px"; dlg_form.style["z-index"] = 100; var title = document.createElement("p"); @@ -692,5 +753,5 @@ mergeInto(LibraryManager.library, { */ js_focus_canvas: function() { onscreen_canvas.focus(); - }, + } });