linphone-desktop/Linphone/view/Control/Container/Call/Mosaic.qml
Alexandre Jörgensen c73eea248f Format QML files
2026-03-10 12:32:35 +01:00

120 lines
3.3 KiB
QML

import QtQuick
import QtQuick.Controls.Basic
import QtQuick.Layouts
import QtQml.Models
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
// =============================================================================
ColumnLayout {
id: mainLayout
property alias delegateModel: grid.model
property alias cellHeight: grid.cellHeight
property alias cellWidth: grid.cellWidth
property alias margins: grid.margin
function appendItem(item) {
mainLayout.delegateModel.model.append(item);
}
function add(item) {
if (!grid.isLayoutWillChanged())
appendItem(item);
else
bufferModels.append(item);
}
function remove(index) {
if (mainLayout.delegateModel.model.count > index)
mainLayout.delegateModel.model.remove(index, 1);
}
function get(index) {
return mainLayout.delegateModel.model.get(index);
}
function tryToAdd(item) {
if (!grid.isLayoutWillChanged()) {
appendItem(item);
return true;
} else
return false;
}
function clear() {
if (mainLayout.delegateModel.model.clear) {
mainLayout.delegateModel.model.clear();
bufferModels.clear();
}
}
property int transitionCount: 0
property var bufferModels: ListModel {}
onWidthChanged: grid.updateLayout()
onHeightChanged: grid.updateLayout()
spacing: 0
GridView {
id: grid
property real margin: Utils.getSizeWithScreenRatio(10)
property int itemCount: model.count ? model.count : (model.length ? model.length : 0)
property int columns: 1
property int rows: 1
function getBestLayout(itemCount) {
var availableW = mainLayout.width - grid.margin;
var availableH = mainLayout.height - grid.margin;
var bestSize = 0;
var bestC = 1, bestR = 1;
for (var R = 1; R <= itemCount; ++R) {
for (var C = itemCount; C >= 1; --C) {
if (R * C >= itemCount) {
// This is a good layout candidate
var estimatedSize = Math.min(availableW / C, availableH / R);
if (estimatedSize > bestSize // Size is better
|| (estimatedSize == bestSize && Math.abs(bestR - bestC) > Math.abs(R - C))) {
// Stickers are more homogenized
bestSize = estimatedSize;
bestC = C;
bestR = R;
}
}
}
}
return [bestR, bestC];
}
function updateLayout() {
var bestLayout = getBestLayout(itemCount);
if (rows != bestLayout[0])
rows = bestLayout[0];
if (columns != bestLayout[1])
columns = bestLayout[1];
}
function updateCells() {
cellWidth = Math.min(computedWidth, computedHeight);
cellHeight = Math.min(computedWidth, computedHeight);
}
onItemCountChanged: updateLayout()
property real computedWidth: (mainLayout.width - grid.margin) / columns
property real computedHeight: (mainLayout.height - grid.margin) / rows
onComputedHeightChanged: Qt.callLater(updateCells)
onComputedWidthChanged: Qt.callLater(updateCells)
cellWidth: Math.min(computedWidth, computedHeight)
cellHeight: Math.min(computedWidth, computedHeight)
function isLayoutWillChanged() {
var bestLayout = getBestLayout(itemCount + 1);
return rows !== bestLayout[0] || columns !== bestLayout[1];
}
Layout.preferredWidth: cellWidth * columns
Layout.preferredHeight: cellHeight * rows
Layout.alignment: Qt.AlignCenter
interactive: false
model: DelegateModel {}
onCountChanged: grid.updateLayout()
}
}