Add overlay for seed input

Fixes #62.
This commit is contained in:
Florine W. Dekker 2020-08-04 21:41:10 +02:00
parent c2544c520c
commit 6fbdc17bce
Signed by: FWDekker
GPG Key ID: B1B567AF58D6EE0F
4 changed files with 123 additions and 49 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "minesweeper", "name": "minesweeper",
"version": "0.73.1", "version": "0.74.0",
"description": "Just Minesweeper!", "description": "Just Minesweeper!",
"author": "Felix W. Dekker", "author": "Felix W. Dekker",
"browser": "dist/bundle.js", "browser": "dist/bundle.js",

View File

@ -46,7 +46,7 @@
</form> </form>
<!-- Seed --> <!-- Seed -->
<form id="seedForm"> <form id="seedOpenForm">
<button>Enter seed</button> <button>Enter seed</button>
</form> </form>
</div> </div>
@ -105,6 +105,20 @@
</form> </form>
</div> </div>
</div> </div>
<!-- Seed input overlay -->
<div class="overlayWrapper" id="seedOverlay">
<div class="overlay">
<form id="seedForm">
<label for="seed">Seed</label>
<input id="seed" />
<button>New game</button>
</form>
<form id="seedCancelForm">
<button>Cancel</button>
</form>
</div>
</div>
</main> </main>

View File

@ -7,6 +7,7 @@ import {customDifficulty, defaultDifficulty, difficulties} from "./Difficulty";
import {Display} from "./Display"; import {Display} from "./Display";
import {Field} from "./Field"; import {Field} from "./Field";
import {Solver} from "./Solver"; import {Solver} from "./Solver";
import {Overlay} from "./UI";
/** /**
@ -15,14 +16,14 @@ import {Solver} from "./Solver";
export class Game { export class Game {
private readonly canvas: HTMLCanvasElement; private readonly canvas: HTMLCanvasElement;
private readonly difficultySelect: HTMLSelectElement; private readonly difficultySelect: HTMLSelectElement;
private readonly customDifficultyOverlay: HTMLDivElement;
private readonly customDifficultyForm: HTMLFormElement;
private readonly customDifficultyCancelForm: HTMLFormElement;
private readonly newGameForm: HTMLFormElement; private readonly newGameForm: HTMLFormElement;
private readonly restartForm: HTMLFormElement; private readonly restartForm: HTMLFormElement;
private readonly seedForm: HTMLFormElement; private readonly seedOverlay: Overlay;
private readonly seedOpenForm: HTMLFormElement;
private readonly seedInput: HTMLFormElement;
private readonly undoForm: HTMLFormElement; private readonly undoForm: HTMLFormElement;
private readonly solveForm: HTMLFormElement; private readonly solveForm: HTMLFormElement;
private readonly customDifficultyOverlay: Overlay;
private readonly widthInput: HTMLInputElement; private readonly widthInput: HTMLInputElement;
private readonly heightInput: HTMLInputElement; private readonly heightInput: HTMLInputElement;
private readonly minesInput: HTMLInputElement; private readonly minesInput: HTMLInputElement;
@ -81,7 +82,7 @@ export class Game {
return; return;
} }
this.customDifficultyOverlay.style.visibility = "unset"; this.customDifficultyOverlay.show();
this.widthInput.value = "" + (this.field?.width ?? defaultDifficulty.width); this.widthInput.value = "" + (this.field?.width ?? defaultDifficulty.width);
this.heightInput.value = "" + (this.field?.height ?? defaultDifficulty.height); this.heightInput.value = "" + (this.field?.height ?? defaultDifficulty.height);
this.minesInput.value = "" + (this.field?.mineCount ?? defaultDifficulty.mineCount); this.minesInput.value = "" + (this.field?.mineCount ?? defaultDifficulty.mineCount);
@ -92,28 +93,11 @@ export class Game {
); );
// Custom difficulty // Custom difficulty
this.customDifficultyOverlay = $("#customDifficultyOverlay"); this.customDifficultyOverlay = new Overlay(
this.customDifficultyOverlay.addEventListener( $("#customDifficultyOverlay"),
"mousedown", $("#customDifficultyForm"),
event => { $("#customDifficultyCancelForm"),
if (event.target === this.customDifficultyOverlay) () => {
this.customDifficultyOverlay.style.visibility = "hidden";
}
);
this.customDifficultyOverlay.addEventListener(
"keydown",
event => {
if (event.key === "Escape")
this.customDifficultyOverlay.style.visibility = "hidden";
}
);
this.customDifficultyForm = $("#customDifficultyForm");
this.customDifficultyForm.addEventListener(
"submit",
event => {
event.preventDefault();
this.customDifficultyOverlay.style.visibility = "hidden";
this.initNewField( this.initNewField(
+this.widthInput.value, +this.widthInput.value,
+this.heightInput.value, +this.heightInput.value,
@ -122,15 +106,6 @@ export class Game {
); );
} }
); );
this.customDifficultyCancelForm = $("#customDifficultyCancelForm");
this.customDifficultyCancelForm.addEventListener(
"submit",
event => {
event.preventDefault();
this.customDifficultyOverlay.style.visibility = "hidden";
}
);
this.widthInput = $("#settingsWidth"); this.widthInput = $("#settingsWidth");
this.widthInput.addEventListener("change", _ => this.setMineLimit()); this.widthInput.addEventListener("change", _ => this.setMineLimit());
@ -162,21 +137,30 @@ export class Game {
); );
// Seed // Seed
this.seedForm = $("#seedForm"); this.seedInput = $("#seed");
this.seedForm.addEventListener( this.seedOpenForm = $("#seedOpenForm");
this.seedOpenForm.addEventListener(
"submit", "submit",
event => { event => {
event.preventDefault(); event.preventDefault();
const input = window.prompt("Enter seed", "" + this.seed); this.seedOverlay.show();
if (input !== null) this.seedInput.value = this.seed;
this.initNewField( this.seedInput.focus();
this.field?.width, }
this.field?.height, );
this.field?.mineCount, this.seedOverlay = new Overlay(
this.field?.solvable, $("#seedOverlay"),
input $("#seedForm"),
); $("#seedCancelForm"),
() => {
this.initNewField(
this.field?.width,
this.field?.height,
this.field?.mineCount,
this.field?.solvable,
this.seedInput.value
);
} }
); );

76
src/main/js/UI.ts Normal file
View File

@ -0,0 +1,76 @@
/**
* An overlay displayed in HTML.
*/
export class Overlay {
private readonly overlay: HTMLDivElement;
private readonly submitForm: HTMLFormElement;
private readonly cancelForm: HTMLFormElement;
/**
* Constructs a new overlay.
*
* @param overlay the overlay element to show and hide
* @param submitForm the form that invokes `onSubmit` and closes the overlay when submitted
* @param cancelForm the form that closes the overlay when submitted
* @param onSubmit the callback to invoke when the form is submit
*/
constructor(
overlay: HTMLDivElement,
submitForm: HTMLFormElement,
cancelForm: HTMLFormElement,
onSubmit: () => void
) {
this.overlay = overlay;
overlay.addEventListener(
"mousedown",
event => {
if (event.target === overlay)
this.hide();
}
);
overlay.addEventListener(
"keydown",
event => {
if (event.key === "Escape")
this.hide();
}
);
this.submitForm = submitForm;
submitForm.addEventListener(
"submit",
event => {
event.preventDefault();
this.hide();
onSubmit();
}
);
this.cancelForm = cancelForm;
cancelForm.addEventListener(
"submit",
event => {
event.preventDefault();
this.hide();
}
);
}
/**
* Shows the overlay.
*/
show(): void {
this.overlay.style.visibility = "unset";
}
/**
* Hides the overlay.
*/
hide(): void {
this.overlay.style.visibility = "hidden";
}
}