1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
pragma Singleton
import Quickshell
Singleton {
id: root
function doLayout(windowList, outerWidth, outerHeight) {
var N = windowList.length
if (N === 0) return []
if (outerWidth <= 0 || outerHeight <= 0) return []
var gap = Math.min(outerWidth * 0.03, outerHeight * 0.03)
// --- 0. DEFINIZIONE AREA SICURA (SCALATA) ---
// Riduciamo l'area di calcolo al 90% per lasciare spazio alle animazioni hover
var contentScale = 0.9
var usableW = outerWidth * contentScale
var usableH = outerHeight * contentScale
// --- 1. TROVARE LA SCALA OTTIMALE ---
// Usiamo usableW/H per decidere la dimensione delle finestre
var TARGET_ASPECT = 16.0 / 9.0
var bestCols = 1
var bestRows = 1
var bestScale = 0
for (var cols = 1; cols <= N; cols++) {
var rows = Math.ceil(N / cols)
// Calcoliamo lo spazio basandoci sull'area ridotta
var availW = usableW - gap * (cols - 1)
var availH = usableH - gap * (rows - 1)
if (availW <= 0 || availH <= 0) continue
var cellW = availW / cols
var cellH = availH / rows
var scaleW = cellW / TARGET_ASPECT
var scaleH = cellH / 1.0
var currentScale = Math.min(scaleW, scaleH)
if (currentScale > bestScale) {
bestScale = currentScale
bestCols = cols
bestRows = rows
}
}
// --- 2. CALCOLO DIMENSIONI REALI ---
// Ricalcoliamo i limiti cella basati sull'area ridotta
var finalAvailW = usableW - gap * (bestCols - 1)
var finalAvailH = usableH - gap * (bestRows - 1)
var maxCellW = finalAvailW / bestCols
var maxCellH = finalAvailH / bestRows
// --- 3. POSIZIONAMENTO (CENTRATO NELL'AREA TOTALE) ---
// Calcoliamo l'altezza totale del blocco di contenuto
var totalGridContentH = bestRows * maxCellH + (bestRows - 1) * gap
// Per centrare verticalmente, usiamo l'outerHeight REALE (al 100%)
// In questo modo il blocco ridotto (90%) finisce esattamente al centro dello schermo fisico
var startOffsetY = (outerHeight - totalGridContentH) / 2
var result = []
// Iteriamo per RIGA
for (var r = 0; r < bestRows; r++) {
var rowItems = []
var startIndex = r * bestCols
var endIndex = Math.min(startIndex + bestCols, N)
if (startIndex >= N) break
var totalRowContentWidth = 0
// Fase 3a: Calcolo dimensioni miniature (Packed)
for (var i = startIndex; i < endIndex; i++) {
var item = windowList[i]
var w0 = (item.width && item.width > 0) ? item.width : 100
var h0 = (item.height && item.height > 0) ? item.height : 100
// Scala calcolata sui limiti "sicuri" (90%)
var scale = Math.min(maxCellW / w0, maxCellH / h0)
var thumbW = w0 * scale
var thumbH = h0 * scale
rowItems.push({
originalItem: item,
width: thumbW,
height: thumbH,
index: i,
col: i - startIndex
})
totalRowContentWidth += thumbW
}
// Aggiungiamo i gap totali della riga
if (rowItems.length > 1) {
totalRowContentWidth += (rowItems.length - 1) * gap
}
// Fase 3b: Posizionamento X
// Anche qui, usiamo outerWidth REALE per centrare il blocco riga nello schermo intero
var currentX = (outerWidth - totalRowContentWidth) / 2
var cellAbsY = startOffsetY + r * (maxCellH + gap)
for (var k = 0; k < rowItems.length; k++) {
var rItem = rowItems[k]
// Centratura verticale nella fascia
var currentY = cellAbsY + (maxCellH - rItem.height) / 2
result.push({
win: rItem.originalItem.win,
x: currentX,
y: currentY,
width: rItem.width,
height: rItem.height,
rowIndex: r,
colIndex: rItem.col
})
currentX += rItem.width + gap
}
}
return result
}
}
|