diff options
Diffstat (limited to 'src/components')
| -rw-r--r-- | src/components/ParentBar.vue | 52 | ||||
| -rw-r--r-- | src/components/ParentBarTile.vue | 40 | ||||
| -rw-r--r-- | src/components/TileTree.vue | 54 |
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> |
