-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6826fac
commit 0130515
Showing
6 changed files
with
413 additions
and
1 deletion.
There are no files selected for viewing
70 changes: 70 additions & 0 deletions
70
packages/renderer/src/components/Controls/GridComponentControls.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
<template> | ||
<Controls title="Grid Component"> | ||
<FormNumberInput | ||
v-model="columnCount" | ||
label="Column Count" | ||
:shows-slider="isWindows" | ||
/> | ||
<FormNumberInput | ||
v-model="columnSpacing" | ||
label="Column Spacing" | ||
:shows-slider="isWindows" | ||
/> | ||
<FormNumberInput | ||
v-model="rowSpacing" | ||
label="Row Spacing" | ||
:shows-slider="isWindows" | ||
/> | ||
<FormSelect | ||
v-model="distribution" | ||
label="Distribution" | ||
> | ||
<option value="leading"> | ||
Leading | ||
</option> | ||
<option value="center"> | ||
Center | ||
</option> | ||
<option value="trailing"> | ||
Trailing | ||
</option> | ||
<option value="justify-between"> | ||
Justify Between | ||
</option> | ||
</FormSelect> | ||
</Controls> | ||
</template> | ||
|
||
<script lang="ts" setup> | ||
import type { GridComponent } from '/@/layout'; | ||
import { useIsWindows } from '/@/integration/platform'; | ||
import { computed } from 'vue'; | ||
import FormSelect from '/@/components/Form/FormSelect.vue'; | ||
import FormNumberInput from '/@/components/Form/FormNumberInput.vue'; | ||
import Controls from './Controls.vue'; | ||
import { setColumnCount, setColumnSpacing, setDistribution, setRowSpacing } from '/@/store/components/grid'; | ||
const props = defineProps<{ | ||
component: GridComponent | ||
}>(); | ||
const isWindows = useIsWindows(); | ||
const distribution = computed({ | ||
get(): 'leading' | 'center' | 'trailing' | 'justify-between' { return props.component.distribution; }, | ||
set(distribution: 'leading' | 'center' | 'trailing' | 'justify-between') { setDistribution(distribution); }, | ||
}); | ||
const columnSpacing = computed({ | ||
get() { return props.component.columnSpacing; }, | ||
set(spacing: number) { setColumnSpacing(spacing); }, | ||
}); | ||
const rowSpacing = computed({ | ||
get() { return props.component.rowSpacing; }, | ||
set(spacing: number) { setRowSpacing(spacing); }, | ||
}); | ||
const columnCount = computed({ | ||
get() { return props.component.columnCount; }, | ||
set(count: number) { setColumnCount(count); }, | ||
}); | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import ContainerLayoutNode from './ContainerLayoutNode'; | ||
import ContainerComponent from './ContainerComponent'; | ||
import Frame from './Frame'; | ||
import Size from './Size'; | ||
import type LayoutNode from './LayoutNode'; | ||
import type Component from './Component'; | ||
|
||
export default class GridComponent extends ContainerComponent { | ||
rowSpacing = 0; | ||
columnSpacing = 0; | ||
columnCount = 1; | ||
distribution: 'leading' | 'center' | 'trailing' | 'justify-between' = 'center'; | ||
|
||
static get displayName(): string { | ||
return 'Grid Component'; | ||
} | ||
|
||
exerciseLayout(size: Size): LayoutNode { | ||
if (!this.children.length) { | ||
return new ContainerLayoutNode(this.id, new Frame(0, 0, size.width, size.height)); | ||
} | ||
|
||
const rowCount = Math.ceil(this.children.length / this.columnCount); | ||
const totalColumnSpacing = this.columnSpacing * (this.columnCount - 1); | ||
const totalRowSpacing = (rowCount - 1) * this.rowSpacing; | ||
|
||
if (totalColumnSpacing >= size.width || totalRowSpacing >= size.height) { | ||
return new ContainerLayoutNode(this.id, new Frame(0, 0, size.width, size.height)); | ||
} | ||
|
||
let availableHeight = size.height; | ||
const childSize = new Size((size.width - totalColumnSpacing) / this.columnCount, (size.height - totalRowSpacing) / rowCount); | ||
let childNodes: LayoutNode[] = []; | ||
let yOffset = 0; | ||
let containerHeight = (rowCount - 1) * this.rowSpacing; | ||
|
||
for (let row = 0; row < rowCount; row++) { | ||
const rowNodes: LayoutNode[] = []; | ||
|
||
for (let column = 0; column < this.columnCount; column++) { | ||
const index = column + (row * this.columnCount); | ||
if (index >= this.children.length) { break; } | ||
|
||
rowNodes.push(this.children[index].exerciseLayout(childSize)); | ||
} | ||
|
||
const rowHeight = rowNodes.reduce((height, node) => Math.max(height, node.frame.height), 0); | ||
|
||
rowNodes.forEach((node, column) => { | ||
let xOffset = (column % this.columnCount) * (childSize.width + this.columnSpacing); | ||
|
||
if (row == rowCount - 1 && rowNodes.length != this.columnCount) { | ||
switch (this.distribution) { | ||
case 'center': { | ||
const totalChildWidth = rowNodes.length * childSize.width + (rowNodes.length - 1) * this.columnSpacing; | ||
xOffset += (size.width - totalChildWidth) / 2.0; | ||
break; | ||
} | ||
case 'leading': | ||
break; | ||
case 'trailing': | ||
xOffset += (this.columnCount - rowNodes.length) * (childSize.width + this.columnSpacing); | ||
break; | ||
case 'justify-between': { | ||
const spacing = (size.width - (rowNodes.length * childSize.width)) / (rowNodes.length - 1); | ||
xOffset = (column % rowNodes.length) * (childSize.width + spacing); | ||
break; | ||
} | ||
} | ||
} | ||
|
||
node.frame.x = xOffset + (childSize.width - node.frame.width) / 2.0; | ||
node.frame.y = yOffset + (rowHeight - node.frame.height) / 2.0; | ||
}); | ||
|
||
availableHeight -= rowHeight + this.rowSpacing; | ||
yOffset += rowHeight + this.rowSpacing; | ||
containerHeight += rowHeight; | ||
|
||
const remainingRowCount = rowCount - (row + 1); | ||
childSize.height = (availableHeight - (remainingRowCount - 1) * this.rowSpacing) / remainingRowCount; | ||
|
||
childNodes = childNodes.concat(rowNodes); | ||
} | ||
|
||
return new ContainerLayoutNode(this.id, new Frame(0, 0, size.width, containerHeight), childNodes); | ||
} | ||
|
||
clone(): Component { | ||
const clone = new GridComponent(); | ||
clone.columnSpacing = this.columnSpacing; | ||
clone.columnCount = this.columnCount; | ||
clone.rowSpacing = this.rowSpacing; | ||
clone.distribution = this.distribution; | ||
this.children.forEach(child => clone.addChild(child.clone())); | ||
return clone; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { useLayoutStore } from '/@/store/layout'; | ||
import { GridComponent } from '/@/layout'; | ||
|
||
export const setDistribution = (distribution: 'leading' | 'center' | 'trailing' | 'justify-between') => { | ||
const store = useLayoutStore(); | ||
if (!store.selectedComponent || !(store.selectedComponent instanceof GridComponent)) { | ||
return; | ||
} | ||
store.selectedComponent.distribution = distribution; | ||
|
||
store.exerciseLayout(); | ||
}; | ||
|
||
export const setColumnSpacing = (spacing: number) => { | ||
const store = useLayoutStore(); | ||
if (!store.selectedComponent || !(store.selectedComponent instanceof GridComponent)) { | ||
return; | ||
} | ||
store.selectedComponent.columnSpacing = spacing; | ||
|
||
store.exerciseLayout(); | ||
}; | ||
|
||
export const setRowSpacing = (spacing: number) => { | ||
const store = useLayoutStore(); | ||
if (!store.selectedComponent || !(store.selectedComponent instanceof GridComponent)) { | ||
return; | ||
} | ||
store.selectedComponent.rowSpacing = spacing; | ||
|
||
store.exerciseLayout(); | ||
}; | ||
|
||
export const setColumnCount = (count: number) => { | ||
const store = useLayoutStore(); | ||
if (!store.selectedComponent || !(store.selectedComponent instanceof GridComponent)) { | ||
return; | ||
} | ||
store.selectedComponent.columnCount = count; | ||
|
||
store.exerciseLayout(); | ||
}; |
Oops, something went wrong.