Fluid 1.3.0
Material Design for QtQuick and Qml
Loading...
Searching...
No Matches
ColumnFlow.qml
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
2// SPDX-FileCopyrightText: 2018 Michael Spencer <sonrisesoftware@gmail.com>
3// SPDX-License-Identifier: MPL-2.0
4
5import QtQuick
6
40Item {
41 id: columnFlow
42 Accessible.ignored: true
43
48 property int columnWidth: 100
49
54 property int columns: Math.max(0, Math.floor(width / columnWidth))
55
63 property alias model: repeater.model
64
70 property alias delegate: repeater.delegate
71
75 property int contentHeight: 0
76
80 readonly property alias repeaterCompleted: __private.repeaterCompleted
81
82 height: contentHeight
83
84 onColumnsChanged: reEvalColumns()
85 onModelChanged: reEvalColumns()
86
87 onWidthChanged: updateWidths()
88
89 QtObject {
90 id: __private
91
92 property bool repeaterCompleted: false
93 }
94
98 function updateWidths() {
99 if (repeaterCompleted) {
100 var count = 0;
101
102 // Add the first <column> elements
103 for (var i = 0; count < columns && i < columnFlow.children.length; i++) {
104 if (!columnFlow.children[i] || String(columnFlow.children[i]).indexOf("QQuickRepeater") == 0)
105 continue;
106
107 columnFlow.children[i].width = width / columns;
108 count++;
109 }
110 }
111 }
112
116 function reEvalColumns() {
117 if (!repeaterCompleted)
118 return;
119 var i, j;
120 var columnHeights = new Array(columns);
121 var lastItem = new Array(columns);
122 var lastI = -1;
123 var count = 0;
124
125 // Add the first <column> elements
126 for (i = 0; count < columns && i < columnFlow.children.length; i++) {
127 if (!columnFlow.children[i] || String(columnFlow.children[i]).indexOf("QQuickRepeater") == 0 || !columnFlow.children[i].visible)
128 continue;
129
130 lastItem[count] = i;
131 columnHeights[count] = columnFlow.children[i].height;
132
133 columnFlow.children[i].anchors.top = columnFlow.top;
134 columnFlow.children[i].anchors.left = (lastI === -1 ? columnFlow.left : columnFlow.children[lastI].right);
135 columnFlow.children[i].anchors.right = undefined;
136 columnFlow.children[i].width = columnFlow.width / columns;
137
138 lastI = i;
139 count++;
140 }
141
142 // Add the other elements
143 for (i = i; i < columnFlow.children.length; i++) {
144 var highestHeight = Number.MAX_VALUE;
145 var newColumn = 0;
146
147 if (!columnFlow.children[i] || !columnFlow.children[i].visible)
148 continue;
149
150 // find the shortest column
151 for (j = 0; j < columns; j++) {
152 if (columnHeights[j] < highestHeight) {
153 newColumn = j;
154 highestHeight = columnHeights[j];
155 }
156 }
157
158 // add the element to the shortest column
159 columnFlow.children[i].anchors.top = columnFlow.children[lastItem[newColumn]].bottom;
160 columnFlow.children[i].anchors.left = columnFlow.children[lastItem[newColumn]].left;
161 columnFlow.children[i].anchors.right = columnFlow.children[lastItem[newColumn]].right;
162
163 lastItem[newColumn] = i;
164 columnHeights[newColumn] += columnFlow.children[i].height;
165 }
166
167 var cHeight = 0;
168 for (i = 0; i < columns; i++) {
169 if (!columnHeights[i])
170 continue;
171 cHeight = Math.max(cHeight, columnHeights[i]);
172 }
173 contentHeight = cHeight;
174
175 updateWidths();
176 }
177
178 Repeater {
179 id: repeater
180 model: columnFlow.model
181
182 Component.onCompleted: {
183 __private.repeaterCompleted = true;
184 columnFlow.reEvalColumns();
185 }
186 }
187}