aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/App.vue40
-rw-r--r--src/components/SettingsModal.vue139
-rw-r--r--src/components/SettingsPane.vue136
3 files changed, 152 insertions, 163 deletions
diff --git a/src/App.vue b/src/App.vue
index e26de01..4a5efe8 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -5,8 +5,8 @@ import Tile from './components/Tile.vue';
import AncestryBar from './components/AncestryBar.vue';
import TileInfoModal from './components/TileInfoModal.vue';
import HelpModal from './components/HelpModal.vue';
+import SettingsModal from './components/SettingsModal.vue';
import SearchModal from './components/SearchModal.vue';
-import SettingsPane from './components/SettingsPane.vue';
// Icons
import HelpIcon from './components/icon/HelpIcon.vue';
import SearchIcon from './components/icon/SearchIcon.vue';
@@ -104,6 +104,7 @@ export default defineComponent({
helpOpen: false,
searchOpen: false,
settingsOpen: false,
+ tutorialOpen: true,
// For search and auto-mode
modeRunning: false,
lastFocused: null as LayoutNode | null,
@@ -604,8 +605,8 @@ export default defineComponent({
},
components: {
Tile, AncestryBar,
- HelpIcon, SearchIcon, PlayIcon, SettingsIcon,
- TileInfoModal, HelpModal, SearchModal, SettingsPane,
+ HelpIcon, SettingsIcon, SearchIcon, PlayIcon,
+ TileInfoModal, HelpModal, SearchModal, SettingsModal,
},
});
</script>
@@ -624,13 +625,16 @@ export default defineComponent({
@detached-ancestor-click="onDetachedAncestorClick" @info-icon-click="onInfoIconClick"/>
<!-- Icons -->
<help-icon @click="onHelpIconClick"
- class="absolute bottom-[6px] left-[6px] w-[18px] h-[18px]
+ class="absolute bottom-[6px] right-[6px] w-[18px] h-[18px]
+ text-white/40 hover:text-white hover:cursor-pointer"/>
+ <settings-icon @click="onSettingsIconClick"
+ class="absolute bottom-[6px] right-[30px] w-[18px] h-[18px]
text-white/40 hover:text-white hover:cursor-pointer"/>
<search-icon @click="onSearchIconClick"
- class="absolute bottom-[6px] left-[30px] w-[18px] h-[18px]
+ class="absolute bottom-[6px] right-[54px] w-[18px] h-[18px]
text-white/40 hover:text-white hover:cursor-pointer"/>
<play-icon @click="onPlayIconClick"
- class="absolute bottom-[6px] left-[54px] w-[18px] h-[18px]
+ class="absolute bottom-[6px] right-[78px] w-[18px] h-[18px]
text-white/40 hover:text-white hover:cursor-pointer"/>
<!-- Modals -->
<transition name="fade">
@@ -646,18 +650,9 @@ export default defineComponent({
<help-modal v-if="helpOpen" :uiOpts="uiOpts" @help-modal-close="helpOpen = false"/>
</transition>
<!-- Settings -->
- <transition name="slide-bottom-right">
- <settings-pane v-if="settingsOpen" :lytOpts="lytOpts" :uiOpts="uiOpts"
- @settings-close="settingsOpen = false"
- @layout-option-change="onLayoutOptionChange" @tree-change="onTreeChange"/>
- <div v-else class="absolute bottom-0 right-0 w-[100px] h-[100px] invisible">
- <!-- Note: Above enclosing div prevents transition interference with inner rotate -->
- <div class="absolute bottom-[-50px] right-[-50px] w-[100px] h-[100px] visible -rotate-45
- bg-black text-white hover:cursor-pointer" @click="onSettingsIconClick">
- <settings-icon class="w-6 h-6 mx-auto mt-2"/>
- </div>
- </div>
- </transition>
+ <settings-modal v-if="settingsOpen" :lytOpts="lytOpts" :uiOpts="uiOpts"
+ @settings-close="settingsOpen = false"
+ @layout-option-change="onLayoutOptionChange" @tree-change="onTreeChange"/>
<!-- Overlay used to prevent interaction and capture clicks -->
<div :style="{visibility: modeRunning ? 'visible' : 'hidden'}"
class="absolute left-0 top-0 w-full h-full" @click="modeRunning = false"></div>
@@ -673,13 +668,4 @@ export default defineComponent({
transition-duration: 300ms;
transition-timing-function: ease-out;
}
-.slide-bottom-right-enter-from, .slide-bottom-right-leave-to {
- transform: translate(100%, 100%);
- opacity: 0;
-}
-.slide-bottom-right-enter-active, .slide-bottom-right-leave-active {
- transition-property: transform, opacity;
- transition-duration: 300ms;
- transition-timing-function: ease-in-out;
-}
</style>
diff --git a/src/components/SettingsModal.vue b/src/components/SettingsModal.vue
new file mode 100644
index 0000000..5f3b3c4
--- /dev/null
+++ b/src/components/SettingsModal.vue
@@ -0,0 +1,139 @@
+<script lang="ts">
+import {defineComponent, PropType} from 'vue';
+import CloseIcon from './icon/CloseIcon.vue';
+import type {LayoutOptions} from '../layout';
+
+// Displays configurable options, and sends option-change requests
+export default defineComponent({
+ props: {
+ lytOpts: {type: Object as PropType<LayoutOptions>, required: true},
+ uiOpts: {type: Object, required: true},
+ },
+ methods: {
+ onCloseClick(evt: Event){
+ if (evt.target == this.$el || (this.$refs.closeIcon as typeof CloseIcon).$el.contains(evt.target)){
+ this.$emit('settings-close');
+ }
+ },
+ onLytOptChg(){
+ this.$emit('layout-option-change');
+ },
+ onMinTileSzChg(){
+ let minInput = this.$refs.minTileSzInput as HTMLInputElement;
+ let maxInput = this.$refs.maxTileSzInput as HTMLInputElement;
+ if (Number(minInput.value) > Number(maxInput.value)){
+ this.lytOpts.maxTileSz = this.lytOpts.minTileSz;
+ }
+ this.onLytOptChg();
+ },
+ onMaxTileSzChg(){
+ let minInput = this.$refs.minTileSzInput as HTMLInputElement;
+ let maxInput = this.$refs.maxTileSzInput as HTMLInputElement;
+ if (Number(maxInput.value) < Number(minInput.value)){
+ this.lytOpts.minTileSz = this.lytOpts.maxTileSz;
+ }
+ this.onLytOptChg();
+ },
+ onTreeChg(){
+ this.$emit('tree-change');
+ },
+ },
+ components: {CloseIcon, },
+ emits: ['settings-close', 'layout-option-change', 'tree-change', ],
+});
+</script>
+
+<template>
+<div class="fixed left-0 top-0 w-full h-full bg-black/40" @click="onCloseClick">
+ <div class="absolute left-1/2 -translate-x-1/2 w-4/5 top-1/2 -translate-y-1/2 max-h-[80%]
+ p-3 bg-stone-50 visible rounded-md shadow shadow-black">
+ <close-icon @click="onCloseClick" ref="closeIcon"
+ class="block absolute top-2 right-2 w-6 h-6 hover:cursor-pointer" />
+ <h1 class="text-xl font-bold mb-2">Settings</h1>
+ <hr class="border-stone-400"/>
+ <div>
+ <label>Tile Spacing <input type="range" min="0" max="20" class="mx-2 w-[3cm]"
+ v-model.number="lytOpts.tileSpacing" @input="onLytOptChg"/></label>
+ </div>
+ <hr class="border-stone-400"/>
+ <div>
+ <label>
+ <span class="inline-block w-[3cm]">Min Tile Size</span>
+ <input type="range" min="0" max="400" v-model.number="lytOpts.minTileSz" class="w-[3cm]"
+ @input="onMinTileSzChg" ref="minTileSzInput"/>
+ </label>
+ </div>
+ <div>
+ <label>
+ <span class="inline-block w-[3cm]">Max Tile Size</span>
+ <input type="range" min="0" max="400" v-model.number="lytOpts.maxTileSz" class="w-[3cm]"
+ @input="onMaxTileSzChg" ref="maxTileSzInput"/>
+ </label>
+ </div>
+ <hr class="border-stone-400"/>
+ <div>
+ Layout Method
+ <ul>
+ <li>
+ <label> <input type="radio" v-model="lytOpts.layoutType" value="sqr"
+ @change="onLytOptChg"/> Squares </label>
+ </li>
+ <li>
+ <label> <input type="radio" v-model="lytOpts.layoutType" value="rect"
+ @change="onLytOptChg"/> Rectangles </label>
+ </li>
+ <li>
+ <label> <input type="radio" v-model="lytOpts.layoutType" value="sweep"
+ @change="onLytOptChg"/> Sweep to side </label>
+ </li>
+ </ul>
+ </div>
+ <hr class="border-stone-400"/>
+ <div>
+ <label> <input type="checkbox" v-model="lytOpts.sweepToParent"
+ @change="onLytOptChg"/> Sweep to parent</label>
+ </div>
+ <hr class="border-stone-400"/>
+ <div>
+ Sweep Mode
+ <ul>
+ <li>
+ <label> <input type="radio" v-model="lytOpts.sweepMode" value="left"
+ @change="onLytOptChg"/> To left </label>
+ </li>
+ <li>
+ <label> <input type="radio" v-model="lytOpts.sweepMode" value="top"
+ @change="onLytOptChg"/> To top </label>
+ </li>
+ <li>
+ <label> <input type="radio" v-model="lytOpts.sweepMode" value="shorter"
+ @change="onLytOptChg"/> To shorter </label>
+ </li>
+ <li>
+ <label> <input type="radio" v-model="lytOpts.sweepMode" value="auto"
+ @change="onLytOptChg"/> Auto </label>
+ </li>
+ </ul>
+ </div>
+ <hr class="border-stone-400"/>
+ <div>
+ <label>Animation Duration <input type="range" min="0" max="3000" class="mx-2 w-[3cm]"
+ v-model.number="uiOpts.tileChgDuration"/></label>
+ </div>
+ <hr class="border-stone-400"/>
+ <div>
+ Tree
+ <ul>
+ <li>
+ <label> <input type="radio" v-model="uiOpts.useReducedTree" :value="false"
+ @change="onTreeChg"/> Default </label>
+ </li>
+ <li>
+ <label> <input type="radio" v-model="uiOpts.useReducedTree" :value="true"
+ @change="onTreeChg"/> Reduced </label>
+ </li>
+ </ul>
+ </div>
+ </div>
+</div>
+</template>
diff --git a/src/components/SettingsPane.vue b/src/components/SettingsPane.vue
deleted file mode 100644
index cf046c3..0000000
--- a/src/components/SettingsPane.vue
+++ /dev/null
@@ -1,136 +0,0 @@
-<script lang="ts">
-import {defineComponent, PropType} from 'vue';
-import CloseIcon from './icon/CloseIcon.vue';
-import type {LayoutOptions} from '../layout';
-
-// Displays configurable options, and sends option-change requests
-export default defineComponent({
- props: {
- lytOpts: {type: Object as PropType<LayoutOptions>, required: true},
- uiOpts: {type: Object, required: true},
- },
- methods: {
- onCloseClick(evt: Event){
- if (evt.target == this.$el || (this.$refs.closeIcon as typeof CloseIcon).$el.contains(evt.target)){
- this.$emit('settings-close');
- }
- },
- onLytOptChg(){
- this.$emit('layout-option-change');
- },
- onMinTileSzChg(){
- let minInput = this.$refs.minTileSzInput as HTMLInputElement;
- let maxInput = this.$refs.maxTileSzInput as HTMLInputElement;
- if (Number(minInput.value) > Number(maxInput.value)){
- this.lytOpts.maxTileSz = this.lytOpts.minTileSz;
- }
- this.onLytOptChg();
- },
- onMaxTileSzChg(){
- let minInput = this.$refs.minTileSzInput as HTMLInputElement;
- let maxInput = this.$refs.maxTileSzInput as HTMLInputElement;
- if (Number(maxInput.value) < Number(minInput.value)){
- this.lytOpts.minTileSz = this.lytOpts.maxTileSz;
- }
- this.onLytOptChg();
- },
- onTreeChg(){
- this.$emit('tree-change');
- },
- },
- components: {CloseIcon, },
- emits: ['settings-close', 'layout-option-change', 'tree-change', ],
-});
-</script>
-
-<template>
-<div class="absolute bottom-4 right-4 min-w-[5cm] p-3 bg-stone-50 visible rounded-md shadow shadow-black">
- <close-icon @click="onCloseClick" ref="closeIcon"
- class="block absolute top-2 right-2 w-6 h-6 hover:cursor-pointer" />
- <h1 class="text-xl font-bold mb-2">Settings</h1>
- <hr class="border-stone-400"/>
- <div>
- <label>Tile Spacing <input type="range" min="0" max="20" class="mx-2 w-[3cm]"
- v-model.number="lytOpts.tileSpacing" @input="onLytOptChg"/></label>
- </div>
- <hr class="border-stone-400"/>
- <div>
- <label>
- <span class="inline-block w-[3cm]">Min Tile Size</span>
- <input type="range" min="0" max="400" v-model.number="lytOpts.minTileSz" class="w-[3cm]"
- @input="onMinTileSzChg" ref="minTileSzInput"/>
- </label>
- </div>
- <div>
- <label>
- <span class="inline-block w-[3cm]">Max Tile Size</span>
- <input type="range" min="0" max="400" v-model.number="lytOpts.maxTileSz" class="w-[3cm]"
- @input="onMaxTileSzChg" ref="maxTileSzInput"/>
- </label>
- </div>
- <hr class="border-stone-400"/>
- <div>
- Layout Method
- <ul>
- <li>
- <label> <input type="radio" v-model="lytOpts.layoutType" value="sqr"
- @change="onLytOptChg"/> Squares </label>
- </li>
- <li>
- <label> <input type="radio" v-model="lytOpts.layoutType" value="rect"
- @change="onLytOptChg"/> Rectangles </label>
- </li>
- <li>
- <label> <input type="radio" v-model="lytOpts.layoutType" value="sweep"
- @change="onLytOptChg"/> Sweep to side </label>
- </li>
- </ul>
- </div>
- <hr class="border-stone-400"/>
- <div>
- <label> <input type="checkbox" v-model="lytOpts.sweepToParent"
- @change="onLytOptChg"/> Sweep to parent</label>
- </div>
- <hr class="border-stone-400"/>
- <div>
- Sweep Mode
- <ul>
- <li>
- <label> <input type="radio" v-model="lytOpts.sweepMode" value="left"
- @change="onLytOptChg"/> To left </label>
- </li>
- <li>
- <label> <input type="radio" v-model="lytOpts.sweepMode" value="top"
- @change="onLytOptChg"/> To top </label>
- </li>
- <li>
- <label> <input type="radio" v-model="lytOpts.sweepMode" value="shorter"
- @change="onLytOptChg"/> To shorter </label>
- </li>
- <li>
- <label> <input type="radio" v-model="lytOpts.sweepMode" value="auto"
- @change="onLytOptChg"/> Auto </label>
- </li>
- </ul>
- </div>
- <hr class="border-stone-400"/>
- <div>
- <label>Animation Duration <input type="range" min="0" max="3000" class="mx-2 w-[3cm]"
- v-model.number="uiOpts.tileChgDuration"/></label>
- </div>
- <hr class="border-stone-400"/>
- <div>
- Tree
- <ul>
- <li>
- <label> <input type="radio" v-model="uiOpts.useReducedTree" :value="false"
- @change="onTreeChg"/> Default </label>
- </li>
- <li>
- <label> <input type="radio" v-model="uiOpts.useReducedTree" :value="true"
- @change="onTreeChg"/> Reduced </label>
- </li>
- </ul>
- </div>
-</div>
-</template>