aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/ParentBar.vue52
-rw-r--r--src/components/ParentBarTile.vue40
-rw-r--r--src/components/TileTree.vue54
3 files changed, 140 insertions, 6 deletions
diff --git a/src/components/ParentBar.vue b/src/components/ParentBar.vue
new file mode 100644
index 0000000..cee8bea
--- /dev/null
+++ b/src/components/ParentBar.vue
@@ -0,0 +1,52 @@
+<script lang="ts">
+import {defineComponent, PropType} from 'vue';
+import {LayoutNode} from '../lib';
+import ParentBarTile from './ParentBarTile.vue'
+
+export default defineComponent({
+ props: {
+ pos: {type: Array as unknown as PropType<[number,number]>, required: true},
+ dims: {type: Array as unknown as PropType<[number,number]>, required: true},
+ nodes: {type: Array as PropType<LayoutNode[]>, required: true},
+ },
+ data(){
+ return {
+ tileMargin: 5, //px (gap between separated-parent tiles)
+ };
+ },
+ computed: {
+ wideArea(){
+ return this.dims[0] >= this.dims[1];
+ },
+ tileSz(){
+ return (this.wideArea ? this.dims[1] : this.dims[0]) - (this.tileMargin * 2);
+ },
+ styles(): Record<string,string> {
+ return {
+ position: 'absolute',
+ left: this.pos[0] + 'px',
+ top: this.pos[1] + 'px',
+ width: this.dims[0] + 'px',
+ height: this.dims[1] + 'px',
+ overflowX: this.wideArea ? 'auto' : 'hidden',
+ overflowY: this.wideArea ? 'hidden' : 'auto',
+ display: 'flex',
+ flexDirection: this.wideArea ? 'row' : 'column',
+ gap: this.tileMargin + 'px',
+ padding: this.tileMargin + 'px',
+ backgroundColor: 'gray',
+ };
+ },
+ },
+ components: {
+ ParentBarTile,
+ },
+});
+</script>
+
+<template>
+<div :style="styles">
+ <parent-bar-tile v-for="node in nodes" :key="node.tolNode.name"
+ :layoutNode="node" :tileSz="tileSz"/>
+</div>
+</template>
diff --git a/src/components/ParentBarTile.vue b/src/components/ParentBarTile.vue
new file mode 100644
index 0000000..7e17ba6
--- /dev/null
+++ b/src/components/ParentBarTile.vue
@@ -0,0 +1,40 @@
+<script lang="ts">
+import {defineComponent, PropType} from 'vue';
+import {LayoutNode} from '../lib';
+
+export default defineComponent({
+ props: {
+ layoutNode: {type: Object as PropType<LayoutNode>, required: true},
+ tileSz: {type: Number, required: true}, //px (length of tile edge)
+ },
+ computed: {
+ styles(): Record<string,string> {
+ return {
+ border: '1px black solid',
+ width: this.tileSz + 'px',
+ height: this.tileSz + 'px',
+ minWidth: this.tileSz + 'px',
+ minHeight: this.tileSz + 'px',
+ backgroundImage: 'url(\'/img/' + this.layoutNode.tolNode.name.replaceAll('\'', '\\\'') + '.png\')',
+ backgroundSize: 'cover',
+ borderRadius: '5px',
+ };
+ },
+ headerStyles(): Record<string,string> {
+ return {
+ color: 'greenyellow',
+ // For ellipsis
+ overflow: 'hidden',
+ textOverflow: 'ellipsis',
+ whiteSpace: 'nowrap',
+ };
+ },
+ },
+});
+</script>
+
+<template>
+ <div :style="styles">
+ <div :style="headerStyles">{{layoutNode.tolNode.name}}</div>
+ </div>
+</template>
diff --git a/src/components/TileTree.vue b/src/components/TileTree.vue
index 5a5f251..3ea21b4 100644
--- a/src/components/TileTree.vue
+++ b/src/components/TileTree.vue
@@ -1,6 +1,7 @@
<script lang="ts">
import {defineComponent, PropType} from 'vue';
import Tile from './Tile.vue';
+import ParentBar from './ParentBar.vue';
import {TolNode, LayoutNode, initLayoutTree, tryLayout} from '../lib';
import type {LayoutOptions} from '../lib';
// Import paths lack a .ts or .js extension because .ts makes vue-tsc complain, and .js makes vite complain
@@ -33,6 +34,7 @@ const defaultLayoutOptions: LayoutOptions = {
const defaultOtherOptions = {
transitionDuration: 300, //ms
tileAreaOffset: 5, //px (space between root tile and display boundary)
+ parentBarSz: defaultLayoutOptions.minTileSz * 2, //px (breadth of separated-parents area)
};
// Component holds a tree structure representing a subtree of 'tol' to be rendered
@@ -48,18 +50,56 @@ export default defineComponent({
layoutTree: layoutTree,
activeRoot: layoutTree,
layoutOptions: {...defaultLayoutOptions},
- otherOptions: {...defaultOtherOptions},
+ ...defaultOtherOptions,
}
},
computed: {
+ wideArea(){
+ return this.dims[0] >= this.dims[1];
+ },
+ separatedParents(): LayoutNode[] | null {
+ if (this.activeRoot == this.layoutTree){
+ return null;
+ }
+ let parents = [];
+ let node = this.activeRoot.parent;
+ while (node != null){
+ parents.push(node);
+ node = node.parent;
+ }
+ return parents.reverse();
+ },
tileAreaPos(){
- return [this.otherOptions.tileAreaOffset, this.otherOptions.tileAreaOffset] as [number, number];
+ let pos = [this.tileAreaOffset, this.tileAreaOffset] as [number, number];
+ if (this.separatedParents != null){
+ if (this.wideArea){
+ pos[0] += this.parentBarSz;
+ } else {
+ pos[1] += this.parentBarSz;
+ }
+ }
+ return pos;
},
tileAreaDims(){
- return [
- this.dims[0] - this.otherOptions.tileAreaOffset * 2,
- this.dims[1] - this.otherOptions.tileAreaOffset * 2
+ let dims = [
+ this.dims[0] - this.tileAreaOffset*2,
+ this.dims[1] - this.tileAreaOffset*2
] as [number, number];
+ if (this.separatedParents != null){
+ if (this.wideArea){
+ dims[0] -= this.parentBarSz;
+ } else {
+ dims[1] -= this.parentBarSz;
+ }
+ }
+ return dims;
+ },
+ parentBarDims(){
+ if (this.wideArea){
+ return [this.parentBarSz, this.dims[1]]
+ } else {
+ return [this.dims[0], this.parentBarSz];
+ }
},
styles(): Record<string,string> {
return {
@@ -123,6 +163,7 @@ export default defineComponent({
},
components: {
Tile,
+ ParentBar,
},
});
</script>
@@ -131,9 +172,10 @@ export default defineComponent({
<div :style="styles">
<tile :layoutNode="layoutTree"
:headerSz="layoutOptions.headerSz" :tileSpacing="layoutOptions.tileSpacing"
- :transitionDuration="otherOptions.transitionDuration"
+ :transitionDuration="transitionDuration"
@leaf-clicked="onInnerLeafClicked" @header-clicked="onInnerHeaderClicked"
@leaf-dbl-clicked="onInnerLeafDblClicked" @header-dbl-clicked="onInnerHeaderDblClicked"/>
+ <parent-bar v-if="separatedParents != null" :pos="[0,0]" :dims="parentBarDims" :nodes="separatedParents"/>
</div>
</template>