diff options
Diffstat (limited to 'src/components')
| -rw-r--r-- | src/components/Tile.vue | 21 | ||||
| -rw-r--r-- | src/components/TileTree.vue | 78 |
2 files changed, 63 insertions, 36 deletions
diff --git a/src/components/Tile.vue b/src/components/Tile.vue index 1b5c2b7..9830a69 100644 --- a/src/components/Tile.vue +++ b/src/components/Tile.vue @@ -1,27 +1,13 @@ <script> -import {defaultLayout} from '/src/layout.js'; export default { name: 'tile', data(){ return { zIdx: 0, - layoutSys: defaultLayout, } }, props: { tree: Object, - x: Number, - y: Number, - width: Number, - height: Number, - hideHeader: Boolean, - }, - computed: { - layout(){ - if (this.tree.children.length == 0) - return {}; - return this.layoutSys.genLayout(this.tree.children, 0, 0, this.width, this.height, this.hideHeader); - } }, methods: { onImgClick(){ @@ -48,20 +34,19 @@ export default { <template> <div - :style="{position: 'absolute', left: x+'px', top: y+'px', width: width+'px', height: height+'px', zIndex: zIdx}" + :style="{position: 'absolute', left: tree.x+'px', top: tree.y+'px', + width: tree.w+'px', height: tree.h+'px', zIndex: zIdx}" class="transition-[left,top,width,height] duration-300 ease-out border border-stone-900 bg-white overflow-hidden"> <div v-if="tree.children.length == 0" :style="{backgroundImage: 'url(\'/src/assets/' + tree.tolNode.name + '.jpg\')'}" class="hover:cursor-pointer w-full h-full bg-cover" @click="onImgClick" /> <div v-else> - <div v-if="!hideHeader" :style="{height: this.layoutSys.HEADER_SZ + 'px'}" + <div v-if="tree.headerSz > 0" :style="{height: tree.headerSz+'px'}" class="text-center hover:cursor-pointer bg-stone-300" @click="onHeaderClick"> {{tree.tolNode.name}} </div> <tile v-for="child in tree.children" :key="child.tolNode.name" :tree="child" - :x="layout.coords[child.tolNode.name].x" :y="layout.coords[child.tolNode.name].y" - :width="layout.coords[child.tolNode.name].w" :height="layout.coords[child.tolNode.name].h" @tile-clicked="onInnerTileClicked" @header-clicked="onInnerHeaderClicked" ></tile> </div> diff --git a/src/components/TileTree.vue b/src/components/TileTree.vue index b1fb3fd..5c3d08e 100644 --- a/src/components/TileTree.vue +++ b/src/components/TileTree.vue @@ -1,29 +1,49 @@ <script> -import tol from '/src/tol.json'; -import {defaultLayout, initTree} from '/src/layout.js'; import Tile from './Tile.vue'; +import tol from '/src/tol.json'; +function preprocessTol(tree){ + if (!tree.children){ + tree.children = []; + } else { + tree.children.forEach(preprocessTol); + } +} +preprocessTol(tol); + +import {staticSqrLayout, staticRectLayout, sweepToSideLayout} from '/src/layout.js'; +let LAYOUT_SYS = sweepToSideLayout; + export default { data(){ return { - tree: initTree(this.preprocessTol(tol), 1), + tree: this.initTree(tol, 1), width: document.documentElement.clientWidth, height: document.documentElement.clientHeight, - layoutSys: defaultLayout, } }, methods: { - preprocessTol(tree){ - if (!tree.children){ - tree.children = []; - } else { - tree.children.forEach(this.preprocessTol); + initTree(tol, lvl){ + let tree = { + tolNode:tol, children:[], + x:0, y:0, w:0, h:0, headerSz:0, + }; + function initTreeRec(tree, lvl){ + if (lvl > 0) + tree.children = tree.tolNode.children.map(tNode => initTreeRec({ + tolNode: tNode, children: [], + x:0, y:0, w:0, h:0, headerSz:0, + }, lvl-1)); + return tree; } + initTreeRec(tree, lvl); + LAYOUT_SYS.initLayoutInfo(tree) return tree; }, onResize(){ this.width = document.documentElement.clientWidth; this.height = document.documentElement.clientHeight; + this.tryLayout(); //use best-effort collapsing-layout? }, onInnerTileClicked(nodeList){ //nodeList holds an array of tree-objects, from the clicked-on-tile's tree-object upward @@ -33,20 +53,43 @@ export default { return; } //add children - nodeList[0].children = nodeList[0].tolNode.children.map(e => ({ - tolNode: e, - children: [], + nodeList[0].children = nodeList[0].tolNode.children.map(tNode => ({ + tolNode: tNode, children: [], + x:0, y:0, w:0, h:0, headerSz:0, })); - this.layoutSys.updateLayoutInfoOnExpand(nodeList); + LAYOUT_SYS.updateLayoutInfoOnExpand(nodeList); + //try to layout tree + if (!this.tryLayout()) + nodeList[0].children = []; }, - onInnerHeaderClicked(nodeList){ - //nodeList will hold an array of tree-objects, from the clicked-on-tile's tree-object upward + onInnerHeaderClicked(nodeList){ //nodeList is array of tree-objects, from clicked-on-tile's tree-object upward nodeList[0].children = []; - this.layoutSys.updateLayoutInfoOnCollapse(nodeList); + LAYOUT_SYS.updateLayoutInfoOnCollapse(nodeList); + this.tryLayout(); }, + tryLayout(){ + let layout = LAYOUT_SYS.genLayout(this.tree, 0, 0, this.width, this.height, true); + if (layout == null){ + console.log('Unable to layout tree'); + return false; + } else { + this.applyLayout(layout, this.tree); + return true; + } + }, + applyLayout(layout, tree){ + //layout format: {x, y, w, h, headerSz, children:[layout1, ...], contentW, contentH, empSpc} + tree.x = layout.x; + tree.y = layout.y; + tree.w = layout.w; + tree.h = layout.h; + tree.headerSz = layout.headerSz; + layout.children.forEach((n,i) => this.applyLayout(n, tree.children[i])); + } }, created(){ window.addEventListener('resize', this.onResize); + this.tryLayout(); }, unmounted(){ window.removeEventListener('resize', this.onResize); @@ -59,8 +102,7 @@ export default { <template> <div class="h-[100vh]"> - <tile :tree="tree" :x="0" :y="0" :width="width" :height="height" hideHeader - @tile-clicked="onInnerTileClicked" @header-clicked="onInnerHeaderClicked"></tile> + <tile :tree="tree" @tile-clicked="onInnerTileClicked" @header-clicked="onInnerHeaderClicked"></tile> </div> </template> |
