puzzle/src/frontend/components/NewGameDialog.vue

137 lines
3 KiB
Vue
Raw Normal View History

2021-05-17 00:27:47 +02:00
<template>
2021-05-21 00:43:02 +02:00
<div class="overlay new-game-dialog" @click="$emit('bgclick')">
<div class="overlay-content" @click.stop="">
2021-05-13 14:01:10 +02:00
2021-05-21 00:43:02 +02:00
<div class="area-image">
<div class="has-image">
<responsive-image :src="image.url" :title="image.title" />
</div>
</div>
<div class="area-settings">
<table>
<tr>
<td><label>Pieces</label></td>
<td><input type="text" v-model="tiles" /></td>
</tr>
<tr>
<td><label>Scoring: </label></td>
<td>
<label><input type="radio" v-model="scoreMode" value="1" /> Any (Score when pieces are connected to each other or on final location)</label>
<br />
<label><input type="radio" v-model="scoreMode" value="0" /> Final (Score when pieces are put to their final location)</label>
</td>
</tr>
</table>
</div>
<div class="area-buttons">
<button class="btn" :disabled="!canStartNewGame" @click="onNewGameClick">
🧩 Generate Puzzle
</button>
</div>
2021-05-13 14:01:10 +02:00
</div>
2021-05-17 00:27:47 +02:00
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
2021-05-21 00:43:02 +02:00
import { GameSettings, ScoreMode } from './../../common/GameCommon'
import ResponsiveImage from './ResponsiveImage.vue'
2021-05-17 00:27:47 +02:00
export default defineComponent({
name: 'new-game-dialog',
components: {
2021-05-21 00:43:02 +02:00
ResponsiveImage,
2021-05-17 00:27:47 +02:00
},
2021-05-13 14:01:10 +02:00
props: {
2021-05-21 00:43:02 +02:00
image: {
type: Object,
required: true,
},
2021-05-13 14:01:10 +02:00
},
emits: {
newGame: null,
2021-05-21 00:43:02 +02:00
bgclick: null,
2021-05-13 14:01:10 +02:00
},
data() {
return {
tiles: 1000,
2021-05-17 02:32:33 +02:00
scoreMode: ScoreMode.ANY,
2021-05-13 14:01:10 +02:00
}
},
methods: {
2021-05-21 00:43:02 +02:00
onNewGameClick () {
2021-05-13 14:01:10 +02:00
this.$emit('newGame', {
tiles: this.tilesInt,
image: this.image,
scoreMode: this.scoreModeInt,
2021-05-21 00:43:02 +02:00
} as GameSettings)
2021-05-13 14:01:10 +02:00
},
},
computed: {
2021-05-21 00:43:02 +02:00
canStartNewGame () {
if (
!this.tilesInt
|| !this.image
|| !this.image.url
|| ![0, 1].includes(this.scoreModeInt)
) {
return false
}
return true
},
2021-05-17 00:27:47 +02:00
scoreModeInt (): number {
return parseInt(`${this.scoreMode}`, 10)
2021-05-13 14:01:10 +02:00
},
2021-05-17 00:27:47 +02:00
tilesInt (): number {
return parseInt(`${this.tiles}`, 10)
2021-05-13 14:01:10 +02:00
},
},
2021-05-17 00:27:47 +02:00
})
</script>
2021-05-21 00:43:02 +02:00
// TODO: scoped vs .new-game-dialog
<style>
.new-game-dialog .overlay-content {
display: grid;
grid-template-columns: auto 450px;
grid-template-rows: auto;
grid-template-areas:
"image settings"
"image buttons";
height: 90%;
width: 80%;
}
.new-game-dialog .area-image {
grid-area: image;
2021-05-22 01:51:44 +02:00
margin: 20px;
2021-05-21 00:43:02 +02:00
}
.new-game-dialog .area-settings {
grid-area: settings;
}
.new-game-dialog .area-settings table input[type="text"] {
width: 100%;
box-sizing: border-box;
}
.new-game-dialog .area-buttons {
align-self: end;
grid-area: buttons;
}
.new-game-dialog .area-buttons button {
width: 100%;
}
.new-game-dialog .has-image {
position: relative;
width: 100%;
height: 100%;
}
.new-game-dialog .has-image .remove {
position: absolute;
top: .5em;
left: .5em;
}
</style>