diff options
| -rw-r--r-- | emcc.c | 32 | ||||
| -rw-r--r-- | emcclib.js | 1 | ||||
| -rw-r--r-- | emccpre.js | 81 | ||||
| -rw-r--r-- | emccx.json | 3 | ||||
| -rwxr-xr-x | html/jspage.pl | 2 |
5 files changed, 111 insertions, 8 deletions
@@ -21,12 +21,6 @@ * by using the DOM File API to ask the user to select a file and * permit us to see its contents. * - * - it ought to be possible to make the puzzle canvases resizable, - * by superimposing some kind of draggable resize handle. Also I - * quite like the idea of having a few buttons for standard sizes: - * reset to default size, maximise to the browser window dimensions - * (if we can find those out), and perhaps even go full-screen. - * * - I should think about whether these webified puzzles can support * touchscreen-based tablet browsers (assuming there are any that * can cope with the reasonably modern JS and run it fast enough to @@ -194,10 +188,12 @@ void timer_callback(double tplus) } /* ---------------------------------------------------------------------- - * Helper function to resize the canvas, and variables to remember its - * size for other functions (e.g. trimming blitter rectangles). + * Helper functions to resize the canvas, and variables to remember + * its size for other functions (e.g. trimming blitter rectangles). */ static int canvas_w, canvas_h; + +/* Called when we resize as a result of changing puzzle settings */ static void resize(void) { int w, h; @@ -208,6 +204,26 @@ static void resize(void) canvas_h = h; } +/* Called from JS when the user uses the resize handle */ +void resize_puzzle(int w, int h) +{ + midend_size(me, &w, &h, TRUE); + if (canvas_w != w || canvas_h != h) { + js_canvas_set_size(w, h); + canvas_w = w; + canvas_h = h; + midend_force_redraw(me); + } +} + +/* Called from JS when the user uses the restore button */ +void restore_puzzle_size(int w, int h) +{ + midend_reset_tilesize(me); + resize(); + midend_force_redraw(me); +} + /* * HTML doesn't give us a default frontend colour of its own, so we * just make up a lightish grey ourselves. @@ -567,6 +567,7 @@ mergeInto(LibraryManager.library, { 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; @@ -103,6 +103,10 @@ var permalink_seed, permalink_desc; // The undo and redo buttons. Used by js_enable_undo_redo(). var undo_button, redo_button; +// A div element enclosing both the puzzle and its status bar, used +// for positioning the resize handle. +var resizable_div; + // Helper function to find the absolute position of a given DOM // element on a page, by iterating upwards through the DOM finding // each element's offset from its parent, and thus calculating the @@ -268,6 +272,83 @@ function initPuzzle() { // Default to giving keyboard focus to the puzzle. onscreen_canvas.focus(); + // Create the resize handle. + var resize_handle = document.createElement("canvas"); + resize_handle.width = 10; + resize_handle.height = 10; + { + var ctx = resize_handle.getContext("2d"); + ctx.beginPath(); + for (var i = 1; i <= 7; i += 3) { + ctx.moveTo(8.5, i + 0.5); + ctx.lineTo(i + 0.5, 8.5); + } + ctx.lineWidth = '1px'; + ctx.lineCap = 'round'; + ctx.lineJoin = 'round'; + ctx.strokeStyle = '#000000'; + ctx.stroke(); + } + resizable_div = document.getElementById("resizable"); + resizable_div.appendChild(resize_handle); + resize_handle.style.position = 'absolute'; + resize_handle.style.zIndex = 98; + resize_handle.style.bottom = "0"; + resize_handle.style.right = "0"; + resize_handle.style.cursor = "se-resize"; + resize_handle.title = "Drag to resize the puzzle. Right-click to restore the default size."; + var resize_xbase = null, resize_ybase = null, restore_pending = false; + var resize_xoffset = null, resize_yoffset = null; + var resize_puzzle = Module.cwrap('resize_puzzle', + 'void', ['number', 'number']); + var restore_puzzle_size = Module.cwrap('restore_puzzle_size', 'void', []); + resize_handle.oncontextmenu = function(event) { return false; } + resize_handle.onmousedown = function(event) { + if (event.button == 0) { + var xy = element_coords(onscreen_canvas); + resize_xbase = xy.x + onscreen_canvas.width / 2; + resize_ybase = xy.y; + resize_xoffset = xy.x + onscreen_canvas.width - event.pageX; + resize_yoffset = xy.y + onscreen_canvas.height - event.pageY; + } else { + restore_pending = true; + } + resize_handle.setCapture(true); + event.preventDefault(); + }; + window.addEventListener("mousemove", function(event) { + if (resize_xbase !== null && resize_ybase !== null) { + resize_puzzle((event.pageX + resize_xoffset - resize_xbase) * 2, + (event.pageY + resize_yoffset - resize_ybase)); + event.preventDefault(); + // Chrome insists on selecting text during a resize drag + // no matter what I do + if (window.getSelection) + window.getSelection().removeAllRanges(); + else + document.selection.empty(); } + }); + window.addEventListener("mouseup", function(event) { + if (resize_xbase !== null && resize_ybase !== null) { + resize_xbase = null; + resize_ybase = null; + onscreen_canvas.focus(); // return focus to the puzzle + } else if (restore_pending) { + // If you have the puzzle at larger than normal size and + // then right-click to restore, I haven't found any way to + // stop Chrome and IE popping up a context menu on the + // revealed piece of document when you release the button + // except by putting the actual restore into a setTimeout. + // Gah. + setTimeout(function() { + restore_pending = false; + restore_puzzle_size(); + onscreen_canvas.focus(); + }, 20); + } + event.preventDefault(); + }); + // Run the C setup function, passing argv[1] as the fragment // identifier (so that permalinks of the form puzzle.html#game-id // can launch the specified id). @@ -21,6 +21,9 @@ // Callbacks to return values from dialog boxes '_dlg_return_sval', '_dlg_return_ival', + // Callbacks when the resizing controls are used + '_resize_puzzle', + '_restore_puzzle_size', // Main program, run at initialisation time '_main' ] diff --git a/html/jspage.pl b/html/jspage.pl index d6e4167..19868bd 100755 --- a/html/jspage.pl +++ b/html/jspage.pl @@ -84,10 +84,12 @@ ${unfinishedpara} <select id="gametype"></select> </p> <div align=center> + <div id="resizable" style="position:relative; left:0; top:0"> <canvas style="display: block" id="puzzlecanvas" width="1px" height="1px" tabindex="1"> </canvas> <div id="statusbarholder" style="display: block"> </div> + </div> <p> Link to this puzzle: <a id="permalink-desc">by game ID</a> |