diff --git a/src/DragContainer.vue b/src/DragContainer.vue index 25eaaeb9bb24374795c6c0ab5706f724f4759bd4..0b17261a384271f2564b16c61a226bd7a976d1a6 100644 --- a/src/DragContainer.vue +++ b/src/DragContainer.vue @@ -79,6 +79,16 @@ export default { required: true, }, disabled: Boolean, + numSiblings: { + type: Number, + required: false, + default: 1, + }, + siblingIndex: { + type: Number, + required: false, + default: 0, + }, }, computed: { isInGrid() { @@ -102,6 +112,12 @@ export default { cursor() { return this.disabled ? "auto" : "grab"; }, + width() { + return 100 / this.numSiblings + "%"; + }, + left() { + return (100 / this.numSiblings) * this.siblingIndex + "%"; + }, dataTransferString() { return JSON.stringify(this.dataTransfer); }, @@ -128,5 +144,7 @@ export default { calc(1px * v-bind(offsetY)) ); z-index: v-bind(zIndex); + width: v-bind(width); + left: v-bind(left); } </style> diff --git a/src/DragGrid.vue b/src/DragGrid.vue index 025bdfe0a1e092b9edb1015accf1975f50157c62..5d6e73b47927e0e076eb2604d86ced51cd922746 100644 --- a/src/DragGrid.vue +++ b/src/DragGrid.vue @@ -22,13 +22,15 @@ </div> <DragContainer - v-for="item in value" + v-for="item in items" :key="item.key" :drag-i-d="item.key" :x="getInt('x', item)" :y="getInt('y', item)" :w="getInt('w', item)" :h="getInt('h', item)" + :num-siblings="item.numSiblings" + :sibling-index="item.siblingIndex" :data="getObject('data', item)" :context="context" :grid-id="gridId" @@ -127,6 +129,11 @@ export default { required: false, default: false, }, + multipleItemsY: { + type: Boolean, + required: false, + default: false, + }, }, methods: { positionAllowed(x, y, key) { @@ -142,17 +149,19 @@ export default { return false; } - for (let item of this.value) { - if (key === item.key) continue; - if ( - x >= this.getInt("x", item) && - x < this.getInt("x", item) + this.getInt("w", item) - ) { + if (!this.multipleItemsY) { + for (let item of this.value) { + if (key === item.key) continue; if ( - y >= this.getInt("y", item) && - y < this.getInt("y", item) + this.getInt("h", item) + x >= this.getInt("x", item) && + x < this.getInt("x", item) + this.getInt("w", item) ) { - return false; + if ( + y >= this.getInt("y", item) && + y < this.getInt("y", item) + this.getInt("h", item) + ) { + return false; + } } } } @@ -299,6 +308,45 @@ export default { context: this.context, }; }, + items() { + if (!this.multipleItemsY) return this.value; + + // calculate numSiblings for each field + // First dimension: the columns + let xSiblings = []; + this.value.forEach((item) => { + for (let i = 0; i < item.h; i++) { + if (!xSiblings[item.x]) xSiblings[item.x] = []; + if (xSiblings[item.x][item.y + i] === undefined) { + xSiblings[item.x][item.y + i] = 0; + } + xSiblings[item.x][item.y + i]++; + } + }); + + let xSiblingsCopy = structuredClone(xSiblings); + + return this.value.map((item) => { + let numSiblings = xSiblings[item.x] + .filter((i, index) => { + return index >= item.y && index < item.y + item.h; + }) + .reduce((a, b) => Math.max(a, b), 0); + for (let i = item.y; i < item.h + item.y; i++) { + xSiblingsCopy[item.x][i]--; + } + let offset = xSiblingsCopy[item.x] + .filter((i, index) => { + return index >= item.y && index < item.y + item.h; + }) + .reduce((a, b) => Math.max(a, b), 0); + return { + ...item, + numSiblings: numSiblings, + siblingIndex: offset, + }; + }); + }, }, }; </script>