Skip to content

Commit 53a9804

Browse files
committed
Split gridCount into independent rows and cols configs
1 parent 2dddb8f commit 53a9804

File tree

5 files changed

+67
-50
lines changed

5 files changed

+67
-50
lines changed

packages/streamwall-control-ui/src/index.tsx

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -256,10 +256,11 @@ export function ControlUI({
256256
role,
257257
} = connection
258258
const {
259-
gridCount,
259+
cols,
260+
rows,
260261
width: windowWidth,
261262
height: windowHeight,
262-
} = config ?? { gridCount: null, width: null, height: null }
263+
} = config ?? { cols: null, rows: null, width: null, height: null }
263264

264265
const [showDebug, setShowDebug] = useState(false)
265266
const handleChangeShowDebug = useCallback<
@@ -311,20 +312,24 @@ export function ControlUI({
311312
const [hoveringIdx, setHoveringIdx] = useState<number>()
312313
const updateHoveringIdx = useCallback(
313314
(ev: MouseEvent) => {
314-
if (gridCount == null || !(ev.currentTarget instanceof HTMLElement)) {
315+
if (
316+
cols == null ||
317+
rows == null ||
318+
!(ev.currentTarget instanceof HTMLElement)
319+
) {
315320
return
316321
}
317322
const { width, height, left, top } =
318323
ev.currentTarget.getBoundingClientRect()
319324
const x = Math.floor(ev.clientX - left)
320325
const y = Math.floor(ev.clientY - top)
321-
const spaceWidth = width / gridCount
322-
const spaceHeight = height / gridCount
326+
const spaceWidth = width / cols
327+
const spaceHeight = height / rows
323328
const idx =
324-
Math.floor(y / spaceHeight) * gridCount + Math.floor(x / spaceWidth)
329+
Math.floor(y / spaceHeight) * cols + Math.floor(x / spaceWidth)
325330
setHoveringIdx(idx)
326331
},
327-
[setHoveringIdx, gridCount],
332+
[setHoveringIdx, cols, rows],
328333
)
329334
const [dragStart, setDragStart] = useState<number | undefined>()
330335
const handleDragStart = useCallback(
@@ -347,14 +352,19 @@ export function ControlUI({
347352
)
348353
useLayoutEffect(() => {
349354
function endDrag() {
350-
if (dragStart == null || gridCount == null || hoveringIdx == null) {
355+
if (
356+
dragStart == null ||
357+
cols == null ||
358+
rows == null ||
359+
hoveringIdx == null
360+
) {
351361
return
352362
}
353363
stateDoc.transact(() => {
354364
const viewsState = stateDoc.getMap<Y.Map<string | undefined>>('views')
355365
const streamId = viewsState.get(String(dragStart))?.get('streamId')
356-
for (let idx = 0; idx < gridCount ** 2; idx++) {
357-
if (idxInBox(gridCount, dragStart, hoveringIdx, idx)) {
366+
for (let idx = 0; idx < cols * rows; idx++) {
367+
if (idxInBox(cols, dragStart, hoveringIdx, idx)) {
358368
viewsState.get(String(idx))?.set('streamId', streamId)
359369
}
360370
}
@@ -462,7 +472,7 @@ export function ControlUI({
462472

463473
const handleClickId = useCallback(
464474
(streamId: string) => {
465-
if (gridCount == null || sharedState == null) {
475+
if (cols == null || rows == null || sharedState == null) {
466476
return
467477
}
468478

@@ -477,15 +487,15 @@ export function ControlUI({
477487
return
478488
}
479489

480-
const availableIdx = range(gridCount * gridCount).find(
490+
const availableIdx = range(cols * rows).find(
481491
(i) => !sharedState.views[i].streamId,
482492
)
483493
if (availableIdx === undefined) {
484494
return
485495
}
486496
handleSetView(availableIdx, streamId)
487497
},
488-
[gridCount, sharedState, focusedInputIdx],
498+
[cols, rows, sharedState, focusedInputIdx],
489499
)
490500

491501
const handleChangeCustomStream = useCallback(
@@ -660,29 +670,29 @@ export function ControlUI({
660670
/>
661671
)}
662672
<StyledDataContainer isConnected={isConnected}>
663-
{gridCount && (
673+
{cols != null && rows != null && (
664674
<StyledGridContainer
665675
className="grid"
666676
onMouseMove={updateHoveringIdx}
667677
windowWidth={windowWidth}
668678
windowHeight={windowHeight}
669679
>
670680
<StyledGridInputs>
671-
{range(0, gridCount).map((y) =>
672-
range(0, gridCount).map((x) => {
673-
const idx = gridCount * y + x
681+
{range(0, rows).map((y) =>
682+
range(0, cols).map((x) => {
683+
const idx = cols * y + x
674684
const { streamId } = sharedState?.views?.[idx] ?? {}
675685
const isDragHighlighted =
676686
dragStart != null &&
677687
hoveringIdx != null &&
678-
idxInBox(gridCount, dragStart, hoveringIdx, idx)
688+
idxInBox(cols, dragStart, hoveringIdx, idx)
679689
return (
680690
<GridInput
681691
style={{
682-
width: `${100 / gridCount}%`,
683-
height: `${100 / gridCount}%`,
684-
left: `${(100 * x) / gridCount}%`,
685-
top: `${(100 * y) / gridCount}%`,
692+
width: `${100 / cols}%`,
693+
height: `${100 / rows}%`,
694+
left: `${(100 * x) / cols}%`,
695+
top: `${(100 * y) / rows}%`,
686696
}}
687697
idx={idx}
688698
spaceValue={streamId ?? ''}

packages/streamwall-shared/src/geometry.ts

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ export interface ViewContent {
1616
export type ViewContentMap = Map<string, ViewContent>
1717

1818
export function boxesFromViewContentMap(
19-
width: number,
20-
height: number,
19+
cols: number,
20+
rows: number,
2121
viewContentMap: ViewContentMap,
2222
) {
2323
const boxes = []
@@ -28,36 +28,36 @@ export function boxesFromViewContentMap(
2828
y: number,
2929
content: ViewContent | undefined,
3030
) {
31-
const checkIdx = width * y + x
31+
const checkIdx = cols * y + x
3232
return (
3333
!visited.has(checkIdx) &&
3434
isEqual(viewContentMap.get(String(checkIdx)), content)
3535
)
3636
}
3737

3838
function findLargestBox(x: number, y: number) {
39-
const idx = width * y + x
39+
const idx = cols * y + x
4040
const spaces = [idx]
4141
const content = viewContentMap.get(String(idx))
4242

4343
let maxY
44-
for (maxY = y + 1; maxY < height; maxY++) {
44+
for (maxY = y + 1; maxY < rows; maxY++) {
4545
if (!isPosContent(x, maxY, content)) {
4646
break
4747
}
48-
spaces.push(width * maxY + x)
48+
spaces.push(cols * maxY + x)
4949
}
5050

5151
let cx = x
5252
let cy = y
53-
scan: for (cx = x + 1; cx < width; cx++) {
53+
scan: for (cx = x + 1; cx < cols; cx++) {
5454
for (cy = y; cy < maxY; cy++) {
5555
if (!isPosContent(cx, cy, content)) {
5656
break scan
5757
}
5858
}
5959
for (let cy = y; cy < maxY; cy++) {
60-
spaces.push(width * cy + cx)
60+
spaces.push(cols * cy + cx)
6161
}
6262
}
6363
const w = cx - x
@@ -66,9 +66,9 @@ export function boxesFromViewContentMap(
6666
return { content, x, y, w, h, spaces }
6767
}
6868

69-
for (let y = 0; y < width; y++) {
70-
for (let x = 0; x < height; x++) {
71-
const idx = width * y + x
69+
for (let y = 0; y < rows; y++) {
70+
for (let x = 0; x < cols; x++) {
71+
const idx = cols * y + x
7272
if (visited.has(idx) || viewContentMap.get(String(idx)) === undefined) {
7373
continue
7474
}
@@ -84,21 +84,21 @@ export function boxesFromViewContentMap(
8484
return boxes
8585
}
8686

87-
export function idxToCoords(gridCount: number, idx: number) {
88-
const x = idx % gridCount
89-
const y = Math.floor(idx / gridCount)
87+
export function idxToCoords(cols: number, idx: number) {
88+
const x = idx % cols
89+
const y = Math.floor(idx / cols)
9090
return { x, y }
9191
}
9292

9393
export function idxInBox(
94-
gridCount: number,
94+
cols: number,
9595
start: number,
9696
end: number,
9797
idx: number,
9898
) {
99-
const { x: startX, y: startY } = idxToCoords(gridCount, start)
100-
const { x: endX, y: endY } = idxToCoords(gridCount, end)
101-
const { x, y } = idxToCoords(gridCount, idx)
99+
const { x: startX, y: startY } = idxToCoords(cols, start)
100+
const { x: endX, y: endY } = idxToCoords(cols, end)
101+
const { x, y } = idxToCoords(cols, idx)
102102
const lowX = Math.min(startX, endX)
103103
const highX = Math.max(startX, endX)
104104
const lowY = Math.min(startY, endY)

packages/streamwall-shared/src/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import type { ViewContent, ViewPos } from './geometry.ts'
22
import type { StreamwallRole } from './roles.ts'
33

44
export interface StreamWindowConfig {
5-
gridCount: number
5+
cols: number
6+
rows: number
67
width: number
78
height: number
89
x?: number

packages/streamwall/src/main/StreamWindow.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -198,11 +198,11 @@ export default class StreamWindow extends EventEmitter<StreamWindowEventMap> {
198198
}
199199

200200
setViews(viewContentMap: ViewContentMap, streams: StreamList) {
201-
const { width, height, gridCount } = this.config
202-
const spaceWidth = Math.floor(width / gridCount)
203-
const spaceHeight = Math.floor(height / gridCount)
201+
const { width, height, cols, rows } = this.config
202+
const spaceWidth = Math.floor(width / cols)
203+
const spaceHeight = Math.floor(height / rows)
204204
const { win, views } = this
205-
const boxes = boxesFromViewContentMap(gridCount, gridCount, viewContentMap)
205+
const boxes = boxesFromViewContentMap(cols, rows, viewContentMap)
206206
const remainingBoxes = new Set(boxes)
207207
const unusedViews = new Set(views.values())
208208
const viewsToDisplay = []

packages/streamwall/src/main/index.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ const SENTRY_DSN =
3434
export interface StreamwallConfig {
3535
help: boolean
3636
grid: {
37-
count: number
37+
cols: number
38+
rows: number
3839
}
3940
window: {
4041
x?: number
@@ -97,8 +98,12 @@ function parseArgs(): StreamwallConfig {
9798
.config('config', (configPath) => {
9899
return TOML.parse(fs.readFileSync(configPath, 'utf-8'))
99100
})
100-
.group(['grid.count'], 'Grid dimensions')
101-
.option('grid.count', {
101+
.group(['grid.cols', 'grid.rows'], 'Grid dimensions')
102+
.option('grid.cols', {
103+
number: true,
104+
default: 3,
105+
})
106+
.option('grid.rows', {
102107
number: true,
103108
default: 3,
104109
})
@@ -267,7 +272,8 @@ async function main(argv: ReturnType<typeof parseArgs>) {
267272
const overlayStreamData = new LocalStreamData()
268273

269274
const streamWindowConfig = {
270-
gridCount: argv.grid.count,
275+
cols: argv.grid.cols,
276+
rows: argv.grid.rows,
271277
width: argv.window.width,
272278
height: argv.window.height,
273279
x: argv.window.x,
@@ -337,7 +343,7 @@ async function main(argv: ReturnType<typeof parseArgs>) {
337343
)
338344

339345
stateDoc.transact(() => {
340-
for (let i = 0; i < argv.grid.count ** 2; i++) {
346+
for (let i = 0; i < argv.grid.cols * argv.grid.rows; i++) {
341347
if (viewsState.has(String(i))) {
342348
continue
343349
}

0 commit comments

Comments
 (0)