|
|
|
<template>
|
|
|
|
<Headline
|
|
|
|
v-bind="{ labelFonts, themes }"
|
|
|
|
@select:font="setFont($event)"
|
|
|
|
@select:theme="setTheme($event)"
|
|
|
|
/>
|
|
|
|
<SystemDiagram v-bind="{ star, objects, selectedObject }"
|
|
|
|
@select="selectObject"
|
|
|
|
@update="updateSelectedObject"
|
|
|
|
/>
|
|
|
|
|
|
|
|
<section id="settings">
|
|
|
|
<ObjectSettings v-if="selectedObject"
|
|
|
|
v-model:name="selectedObject.name"
|
|
|
|
v-model:distance="selectedObject.distance"
|
|
|
|
v-model:type="selectedObject.type"
|
|
|
|
v-model:radius="selectedObject.radius"
|
|
|
|
v-model:rings="selectedObject.rings"
|
|
|
|
v-model:satellites="selectedObject.satellites"
|
|
|
|
:auto-name="autoName(selectedObject)"
|
|
|
|
@delete="deleteObject"
|
|
|
|
@close="editObject(null)"
|
|
|
|
/>
|
|
|
|
<Tips>
|
|
|
|
<li>Edit planets by clicking directly inside the graphic or in the table below.</li>
|
|
|
|
<li>Drag planets around to change their distance.</li>
|
|
|
|
<li>Use the scrollwheel to change their size (click first to activate).</li>
|
|
|
|
<li>To change satellites, click their respective buttons in the planet dialog.</li>
|
|
|
|
<li>You can also drag satellite buttons around to reorder them.</li>
|
|
|
|
<li>The last removed object can be restored from the table.</li>
|
|
|
|
<li><strong>ONLY THE LAST</strong> removed object can be restored.</li>
|
|
|
|
</Tips>
|
|
|
|
<SystemSettings v-model:designation="star.designation" v-model:radius="star.radius" />
|
|
|
|
<ObjectList v-bind="{ objects, deletedObject, editObject, deleteObject, restoreDeleted }" />
|
|
|
|
</section>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
import { ref, reactive } from 'vue'
|
|
|
|
import exampleData from './example-data'
|
|
|
|
import Headline from './components/Headline.vue'
|
|
|
|
import SystemDiagram from './components/SystemDiagram.vue'
|
|
|
|
import Tips from './components/Tips.vue'
|
|
|
|
import SystemSettings from './components/SystemSettings.vue'
|
|
|
|
import ObjectList from './components/ObjectList.vue'
|
|
|
|
import ObjectSettings from './components/ObjectSettings.vue'
|
|
|
|
|
|
|
|
const star = reactive({
|
|
|
|
designation: 'Sol',
|
|
|
|
radius: 400,
|
|
|
|
})
|
|
|
|
|
|
|
|
const objects = reactive(exampleData)
|
|
|
|
const labelFonts = ['xolonium', 'douar', 'lack']
|
|
|
|
const themes = ['default', 'retro', 'inverse', 'paper']
|
|
|
|
|
|
|
|
const selectedObject = ref(null)
|
|
|
|
const deletedObject = ref(null) // { index: Number, object: Object }
|
|
|
|
|
|
|
|
function editObject (object) {
|
|
|
|
if (object) {
|
|
|
|
document.documentElement.scrollTop = 0
|
|
|
|
document.body.scrollTop = 0
|
|
|
|
}
|
|
|
|
selectedObject.value = object
|
|
|
|
}
|
|
|
|
function selectObject (object) {
|
|
|
|
selectedObject.value = object
|
|
|
|
}
|
|
|
|
|
|
|
|
function updateSelectedObject (payload) {
|
|
|
|
for (const key in payload) {
|
|
|
|
selectedObject.value[key] = payload[key]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function deleteObject (object) {
|
|
|
|
if (deletedObject.value) {
|
|
|
|
const lost = deletedObject.value.object.name
|
|
|
|
const confirmed = confirm(`
|
|
|
|
Attention! Only the LAST deleted object can be restored.
|
|
|
|
${lost} will be lost forever! Proceed anyway?`
|
|
|
|
)
|
|
|
|
if (!confirmed) return
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!object) object = selectedObject.value
|
|
|
|
const index = objects.indexOf(object)
|
|
|
|
|
|
|
|
console.debug('deleting object at index', index)
|
|
|
|
|
|
|
|
if (index >= 0) objects.splice(index, 1)
|
|
|
|
if (object === selectedObject.value) selectedObject.value = null
|
|
|
|
|
|
|
|
deletedObject.value = { index, object }
|
|
|
|
}
|
|
|
|
|
|
|
|
function restoreDeleted () {
|
|
|
|
const { index, object } = deletedObject.value
|
|
|
|
console.debug('restoring deleted object', index)
|
|
|
|
objects.splice(index, 0, object)
|
|
|
|
deletedObject.value = null
|
|
|
|
}
|
|
|
|
|
|
|
|
function autoName (obj) {
|
|
|
|
const index = objects.indexOf(obj)
|
|
|
|
return `${star.designation}-${index}`
|
|
|
|
}
|
|
|
|
|
|
|
|
function setTheme (theme) {
|
|
|
|
const classes = document.body.className.split(' ')
|
|
|
|
const currentTheme = classes.find(c => c.startsWith('theme-'))
|
|
|
|
const newTheme = `theme-${theme}`
|
|
|
|
|
|
|
|
if (currentTheme) {
|
|
|
|
document.body.classList.replace(currentTheme, newTheme)
|
|
|
|
} else {
|
|
|
|
document.body.classList.add(newTheme)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function setFont (font) {
|
|
|
|
const classes = document.body.className.split(' ')
|
|
|
|
const currentFont = classes.find(c => c.startsWith('title-'))
|
|
|
|
const newFont = `title-${font}`
|
|
|
|
|
|
|
|
if (currentFont) {
|
|
|
|
document.body.classList.replace(currentFont, newFont)
|
|
|
|
} else {
|
|
|
|
document.body.classList.add(newFont)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setTheme(themes[0])
|
|
|
|
setFont(labelFonts[0])
|
|
|
|
</script>
|