diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/App.vue | 4 | ||||
| -rw-r--r-- | src/lib.ts | 32 |
2 files changed, 32 insertions, 4 deletions
diff --git a/src/App.vue b/src/App.vue index 91cb7bc..51e2f79 100644 --- a/src/App.vue +++ b/src/App.vue @@ -44,7 +44,7 @@ const defaultLayoutOptions: LayoutOptions = { minTileSz: 50, //px maxTileSz: 200, //px layoutType: 'sweep', //'sqr' | 'rect' | 'sweep' - rectMode: 'auto', //'horz' | 'vert' | 'linear' | 'auto' + rectMode: 'auto first-row', //'horz' | 'vert' | 'linear' | 'auto' | 'auto first-row' sweepMode: 'left', //'left' | 'top' | 'shorter' | 'auto' sweptNodesPrio: 'pow-2/3', //'linear' | 'sqrt' | 'pow-2/3' sweepingToParent: true, @@ -469,7 +469,7 @@ export default defineComponent({ <settings v-if="settingsOpen" :layoutOptions="layoutOptions" :componentOptions="componentOptions" @settings-close="onSettingsClose" @layout-option-change="onLayoutOptionChange"/> <!-- outer div prevents transition interference with inner rotate --> - <div v-else class="absolute bottom-0 right-0 w-[100px] h-[100px]"> + <div v-else class="absolute bottom-0 right-0 w-[100px] h-[100px] invisible"> <div class="absolute bottom-[-50px] right-[-50px] w-[100px] h-[100px] visible -rotate-45 bg-black text-white hover:cursor-pointer" @click="onSettingsIconClick"> <svg class="w-6 h-6 mx-auto mt-2"><use href="#svg-settings"/></svg> @@ -142,7 +142,8 @@ export type LayoutOptions = { minTileSz: number; // Minimum size of a tile edge, in pixels (ignoring borders) maxTileSz: number; layoutType: 'sqr' | 'rect' | 'sweep'; // The LayoutFn function to use - rectMode: 'horz' | 'vert' | 'linear' | 'auto'; // Layout in 1 row, 1 column, 1 row or column, or multiple rows + rectMode: 'horz' | 'vert' | 'linear' | 'auto' | 'auto first-row'; + // Layout in 1 row, 1 column, 1 row or column, or multiple rows (with/without first-row-heuristic) sweepMode: 'left' | 'top' | 'shorter' | 'auto'; // Sweep to left, top, shorter-side, or to minimise empty space sweptNodesPrio: 'linear' | 'sqrt' | 'pow-2/3'; // Specifies allocation of space to swept-vs-remaining nodes sweepingToParent: boolean; // Allow swept nodes to occupy empty space in a parent's swept-leaves area @@ -341,7 +342,7 @@ let rectLayout: LayoutFn = function (node, pos, dims, showHeader, allowCollapse, return false; } // Try finding arrangement with low empty space - // Done by searching possible row groupings, allocating within rows using dCounts, and trimming empty space + // Done by searching possible rows groupings, allocating within rows using dCounts, and trimming empty space let numChildren = node.children.length; let rowBrks: number[] = []; // Will hold indices for nodes at which each row starts let lowestEmpSpc = Number.POSITIVE_INFINITY; @@ -389,6 +390,33 @@ let rectLayout: LayoutFn = function (node, pos, dims, showHeader, allowCollapse, } } break; + case 'auto first-row': // Like auto, but only iterates over first-rows, determining the rest with dCounts + if (rowBrks.length == 0){ + rowBrks = [0]; + } else { + // Get next possible first row + let idxFirstRowLastEl = (rowBrks.length == 1 ? numChildren : rowBrks[1]) - 1; + if (idxFirstRowLastEl == 0){ + break rowBrksLoop; + } + rowBrks = [0]; + rowBrks.push(idxFirstRowLastEl); + // Allocate remaining rows + let firstRowDCount = arraySum(range(rowBrks[1]).map(idx => node.children[idx].dCount)); + let dCountTotal = node.children[idxFirstRowLastEl].dCount; + let nextRowIdx = idxFirstRowLastEl + 1; + while (nextRowIdx < numChildren){ // Over potential next row breaks + let nextDCountTotal = dCountTotal + node.children[nextRowIdx].dCount; + if (nextDCountTotal <= firstRowDCount){ // If acceptable within current row + dCountTotal = nextDCountTotal; + } else { + rowBrks.push(nextRowIdx); + dCountTotal = node.children[nextRowIdx].dCount; + } + nextRowIdx++; + } + } + break; } // Create array-of-arrays representing each rows' cells' dCounts let rowsOfCnts: number[][] = new Array(rowBrks.length); |
