X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=emcclib.js;h=385281ad0b6778e0120a554c86e827de9f18aa04;hb=3234912f921916a1b8da164fd61dc75579358577;hp=8fb9dd8efa4a7d62c5ab0853909cfff5c90c07cb;hpb=9826ecd5c3b79320823cd762880c302253e88d06;p=sgt-puzzles.git diff --git a/emcclib.js b/emcclib.js index 8fb9dd8..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 @@ -67,7 +71,7 @@ mergeInto(LibraryManager.library, { * case we need to do something special - see below. */ js_add_preset: function(ptr) { - var name = (ptr == 0 ? "Custom" : Pointer_stringify(ptr)); + var name = (ptr == 0 ? "Customise..." : Pointer_stringify(ptr)); var value = gametypeoptions.length; var option = document.createElement("option"); @@ -77,31 +81,20 @@ mergeInto(LibraryManager.library, { 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. + // 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 = value; - option.appendChild(document.createTextNode(name)); - option.style.display = "none"; - gametypeselector.appendChild(option); - gametypehiddencustom = option; + option.value = -2; + option.appendChild(document.createTextNode("Custom")); + gametypethiscustom = option; } }, @@ -128,11 +121,31 @@ mergeInto(LibraryManager.library, { * which turn out to exactly match a preset). */ js_select_preset: function(n) { - 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; + 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; } @@ -313,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; @@ -342,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(); }, @@ -363,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(); }, @@ -399,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 @@ -463,6 +476,7 @@ mergeInto(LibraryManager.library, { blitters[id] = document.createElement("canvas"); blitters[id].width = w; blitters[id].height = h; + return id; }, /* @@ -512,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); }, /* @@ -547,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; @@ -574,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"); @@ -734,5 +753,5 @@ mergeInto(LibraryManager.library, { */ js_focus_canvas: function() { onscreen_canvas.focus(); - }, + } });