Skip to content

Commit 7d91b2c

Browse files
author
simon
committed
Add a draggable resize handle to the JS puzzles.
Rather than design an ersatz 'window frame' surrounding the puzzle canvas, I've simply overlaid the resize handle on the corner of the puzzle itself (canvas or status bar, depending on whether the latter exists), trusting that all games in my collection provide a reasonable border within their drawing area. (OS X already does this with its resize handle, so it's not as if there's no precedent.) Unlike the desktop versions, I control the resize behaviour completely in this environment, so I can constrain the canvas to only ever be sensible sizes with no dead space round the edges (and, in particular, preserve the aspect ratio). Right-clicking the resize handle will restore the puzzle's default tile size. I had intended to implement a maximise-to-browser-window button too, but was annoyingly foiled by scrollbars - if you maximise to the current window width, and as a result the text below the puzzle scrolls off the bottom, then a vertical scrollbar appears and eats into the width you just maximised to. Gah. git-svn-id: svn://svn.tartarus.org/sgt/puzzles@9822 cda61777-01e9-0310-a592-d414129be87e
1 parent 5c427af commit 7d91b2c

File tree

5 files changed

+111
-8
lines changed

5 files changed

+111
-8
lines changed

emcc.c

+24-8
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,6 @@
2121
* by using the DOM File API to ask the user to select a file and
2222
* permit us to see its contents.
2323
*
24-
* - it ought to be possible to make the puzzle canvases resizable,
25-
* by superimposing some kind of draggable resize handle. Also I
26-
* quite like the idea of having a few buttons for standard sizes:
27-
* reset to default size, maximise to the browser window dimensions
28-
* (if we can find those out), and perhaps even go full-screen.
29-
*
3024
* - I should think about whether these webified puzzles can support
3125
* touchscreen-based tablet browsers (assuming there are any that
3226
* can cope with the reasonably modern JS and run it fast enough to
@@ -194,10 +188,12 @@ void timer_callback(double tplus)
194188
}
195189

196190
/* ----------------------------------------------------------------------
197-
* Helper function to resize the canvas, and variables to remember its
198-
* size for other functions (e.g. trimming blitter rectangles).
191+
* Helper functions to resize the canvas, and variables to remember
192+
* its size for other functions (e.g. trimming blitter rectangles).
199193
*/
200194
static int canvas_w, canvas_h;
195+
196+
/* Called when we resize as a result of changing puzzle settings */
201197
static void resize(void)
202198
{
203199
int w, h;
@@ -208,6 +204,26 @@ static void resize(void)
208204
canvas_h = h;
209205
}
210206

207+
/* Called from JS when the user uses the resize handle */
208+
void resize_puzzle(int w, int h)
209+
{
210+
midend_size(me, &w, &h, TRUE);
211+
if (canvas_w != w || canvas_h != h) {
212+
js_canvas_set_size(w, h);
213+
canvas_w = w;
214+
canvas_h = h;
215+
midend_force_redraw(me);
216+
}
217+
}
218+
219+
/* Called from JS when the user uses the restore button */
220+
void restore_puzzle_size(int w, int h)
221+
{
222+
midend_reset_tilesize(me);
223+
resize();
224+
midend_force_redraw(me);
225+
}
226+
211227
/*
212228
* HTML doesn't give us a default frontend colour of its own, so we
213229
* just make up a lightish grey ourselves.

emcclib.js

+1
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,7 @@ mergeInto(LibraryManager.library, {
567567
statusbar.style.width = (w - 4) + "px";
568568
document.getElementById("statusbarholder").style.width = w + "px";
569569
}
570+
resizable_div.style.width = w + "px";
570571

571572
onscreen_canvas.height = h;
572573
offscreen_canvas.height = h;

emccpre.js

+81
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ var permalink_seed, permalink_desc;
103103
// The undo and redo buttons. Used by js_enable_undo_redo().
104104
var undo_button, redo_button;
105105

106+
// A div element enclosing both the puzzle and its status bar, used
107+
// for positioning the resize handle.
108+
var resizable_div;
109+
106110
// Helper function to find the absolute position of a given DOM
107111
// element on a page, by iterating upwards through the DOM finding
108112
// each element's offset from its parent, and thus calculating the
@@ -268,6 +272,83 @@ function initPuzzle() {
268272
// Default to giving keyboard focus to the puzzle.
269273
onscreen_canvas.focus();
270274

275+
// Create the resize handle.
276+
var resize_handle = document.createElement("canvas");
277+
resize_handle.width = 10;
278+
resize_handle.height = 10;
279+
{
280+
var ctx = resize_handle.getContext("2d");
281+
ctx.beginPath();
282+
for (var i = 1; i <= 7; i += 3) {
283+
ctx.moveTo(8.5, i + 0.5);
284+
ctx.lineTo(i + 0.5, 8.5);
285+
}
286+
ctx.lineWidth = '1px';
287+
ctx.lineCap = 'round';
288+
ctx.lineJoin = 'round';
289+
ctx.strokeStyle = '#000000';
290+
ctx.stroke();
291+
}
292+
resizable_div = document.getElementById("resizable");
293+
resizable_div.appendChild(resize_handle);
294+
resize_handle.style.position = 'absolute';
295+
resize_handle.style.zIndex = 98;
296+
resize_handle.style.bottom = "0";
297+
resize_handle.style.right = "0";
298+
resize_handle.style.cursor = "se-resize";
299+
resize_handle.title = "Drag to resize the puzzle. Right-click to restore the default size.";
300+
var resize_xbase = null, resize_ybase = null, restore_pending = false;
301+
var resize_xoffset = null, resize_yoffset = null;
302+
var resize_puzzle = Module.cwrap('resize_puzzle',
303+
'void', ['number', 'number']);
304+
var restore_puzzle_size = Module.cwrap('restore_puzzle_size', 'void', []);
305+
resize_handle.oncontextmenu = function(event) { return false; }
306+
resize_handle.onmousedown = function(event) {
307+
if (event.button == 0) {
308+
var xy = element_coords(onscreen_canvas);
309+
resize_xbase = xy.x + onscreen_canvas.width / 2;
310+
resize_ybase = xy.y;
311+
resize_xoffset = xy.x + onscreen_canvas.width - event.pageX;
312+
resize_yoffset = xy.y + onscreen_canvas.height - event.pageY;
313+
} else {
314+
restore_pending = true;
315+
}
316+
resize_handle.setCapture(true);
317+
event.preventDefault();
318+
};
319+
window.addEventListener("mousemove", function(event) {
320+
if (resize_xbase !== null && resize_ybase !== null) {
321+
resize_puzzle((event.pageX + resize_xoffset - resize_xbase) * 2,
322+
(event.pageY + resize_yoffset - resize_ybase));
323+
event.preventDefault();
324+
// Chrome insists on selecting text during a resize drag
325+
// no matter what I do
326+
if (window.getSelection)
327+
window.getSelection().removeAllRanges();
328+
else
329+
document.selection.empty(); }
330+
});
331+
window.addEventListener("mouseup", function(event) {
332+
if (resize_xbase !== null && resize_ybase !== null) {
333+
resize_xbase = null;
334+
resize_ybase = null;
335+
onscreen_canvas.focus(); // return focus to the puzzle
336+
} else if (restore_pending) {
337+
// If you have the puzzle at larger than normal size and
338+
// then right-click to restore, I haven't found any way to
339+
// stop Chrome and IE popping up a context menu on the
340+
// revealed piece of document when you release the button
341+
// except by putting the actual restore into a setTimeout.
342+
// Gah.
343+
setTimeout(function() {
344+
restore_pending = false;
345+
restore_puzzle_size();
346+
onscreen_canvas.focus();
347+
}, 20);
348+
}
349+
event.preventDefault();
350+
});
351+
271352
// Run the C setup function, passing argv[1] as the fragment
272353
// identifier (so that permalinks of the form puzzle.html#game-id
273354
// can launch the specified id).

emccx.json

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
// Callbacks to return values from dialog boxes
2222
'_dlg_return_sval',
2323
'_dlg_return_ival',
24+
// Callbacks when the resizing controls are used
25+
'_resize_puzzle',
26+
'_restore_puzzle_size',
2427
// Main program, run at initialisation time
2528
'_main'
2629
]

html/jspage.pl

+2
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,12 @@
8484
<select id="gametype"></select>
8585
</p>
8686
<div align=center>
87+
<div id="resizable" style="position:relative; left:0; top:0">
8788
<canvas style="display: block" id="puzzlecanvas" width="1px" height="1px" tabindex="1">
8889
</canvas>
8990
<div id="statusbarholder" style="display: block">
9091
</div>
92+
</div>
9193
<p>
9294
Link to this puzzle:
9395
<a id="permalink-desc">by game ID</a>

0 commit comments

Comments
 (0)