Warning, /frameworks/kirigami/autotests/tst_formlayout.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 * SPDX-FileCopyrightText: 2022 Connor Carney <hello@connorcarney.com> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 import QtQuick 0008 import QtQuick.Window 0009 import QtQuick.Layouts 0010 import org.kde.kirigami as Kirigami 0011 import QtTest 0012 0013 TestCase { 0014 id: testCase 0015 name: "FormLayout" 0016 0017 width: 400 0018 height: 400 0019 visible: true 0020 0021 when: windowShown 0022 0023 Component { 0024 id: fractionalSizeRoundingComponent 0025 Window { 0026 property var item: fractionalSizeItem 0027 width: 600 0028 height: 400 0029 Kirigami.FormLayout { 0030 anchors.fill: parent 0031 Item { 0032 id: fractionalSizeItem 0033 implicitWidth: 160.375 0034 implicitHeight: 17.001 0035 Layout.fillWidth: true 0036 } 0037 } 0038 } 0039 } 0040 0041 function test_fractional_width_rounding() { 0042 let window = createTemporaryObject(fractionalSizeRoundingComponent); 0043 let item = window.item; 0044 window.show(); 0045 0046 verify(item.width >= item.implicitWidth, "implicit width should not be rounded down"); 0047 fuzzyCompare(item.width, item.implicitWidth, 1); 0048 0049 window.close(); 0050 } 0051 0052 function test_fractional_height_rounding() { 0053 let window = createTemporaryObject(fractionalSizeRoundingComponent); 0054 let item = window.item; 0055 window.show(); 0056 0057 verify(item.height >= item.implicitHeight, "implicit height should not be rounded down"); 0058 fuzzyCompare(item.height, item.implicitHeight, 1); 0059 0060 window.close(); 0061 } 0062 0063 0064 Component { 0065 id: dynamicBuddyFormComponent 0066 0067 Kirigami.FormLayout { 0068 id: form 0069 0070 readonly property string labelText: "You found me!" 0071 readonly property alias buddyColumn: buddyColumn 0072 readonly property alias target1: target1 0073 readonly property alias target2: target2 0074 readonly property alias target3: target3 0075 0076 wideMode: true 0077 0078 ColumnLayout { 0079 id: buddyColumn 0080 0081 spacing: 0 0082 0083 Kirigami.FormData.label: form.labelText 0084 0085 Rectangle { 0086 id: target1 0087 implicitWidth: 100 0088 implicitHeight: 100 0089 color: "red" 0090 } 0091 Rectangle { 0092 id: target2 0093 implicitWidth: 100 0094 implicitHeight: 100 0095 color: "green" 0096 Rectangle { 0097 id: target3 0098 anchors.left: parent.left 0099 anchors.bottom: parent.bottom 0100 implicitWidth: 100 0101 implicitHeight: 100 0102 color: "blue" 0103 } 0104 } 0105 } 0106 } 0107 } 0108 0109 function findChildLabel(parent: Item, text: string): Text { 0110 for (let i = 0; i < parent.children.length; i++) { 0111 const child = parent.children[i]; 0112 if ((child instanceof Text) && (child.text === text)) { 0113 return child; 0114 } else { 0115 const label = findChildLabel(child, text); 0116 if (label !== null) { 0117 return label; 0118 } 0119 } 0120 } 0121 return null; 0122 } 0123 0124 function getYOffsetOfLabel(form: Kirigami.FormLayout, label: Item): real { 0125 return label.mapToItem(form, 0, 0).y; 0126 } 0127 0128 function test_dynamicBuddyFor() { 0129 const form = createTemporaryObject(dynamicBuddyFormComponent, this); 0130 compare(form.buddyColumn.Kirigami.FormData.buddyFor, form.buddyColumn); 0131 0132 const label = findChildLabel(form, form.labelText); 0133 verify(label); 0134 0135 form.buddyColumn.Kirigami.FormData.buddyFor = form.target1; 0136 compare(form.buddyColumn.Kirigami.FormData.buddyFor, form.target1); 0137 wait(100); // Unfortunately, this is needed due to async timer-based updates of FormLayout 0138 const offset1 = getYOffsetOfLabel(form, label); 0139 0140 form.buddyColumn.Kirigami.FormData.buddyFor = form.target2; 0141 compare(form.buddyColumn.Kirigami.FormData.buddyFor, form.target2); 0142 wait(100); 0143 const offset2 = getYOffsetOfLabel(form, label); 0144 0145 verify(offset1 < offset2); 0146 } 0147 0148 function test_nestedBuddyNotSupported() { 0149 const form = createTemporaryObject(dynamicBuddyFormComponent, this); 0150 compare(form.buddyColumn.Kirigami.FormData.buddyFor, form.buddyColumn); 0151 0152 ignoreWarning(/FormData.buddyFor must be a direct child of the attachee.*/); 0153 form.buddyColumn.Kirigami.FormData.buddyFor = form.target3; 0154 // shouldn't change 0155 compare(form.buddyColumn.Kirigami.FormData.buddyFor, form.buddyColumn); 0156 } 0157 0158 SignalSpy { 0159 id: buddyChangeSpy 0160 signalName: "buddyForChanged" 0161 } 0162 0163 Component { 0164 id: buddyRepeaterFormComponent 0165 0166 Kirigami.FormLayout { 0167 id: form 0168 0169 readonly property string labelText: "You found me!" 0170 readonly property alias buddyColumn: buddyColumn 0171 property alias repeaterModel: repeater.model 0172 property Item buddyCreatedByRepeater 0173 0174 wideMode: true 0175 0176 ColumnLayout { 0177 id: buddyColumn 0178 0179 spacing: 0 0180 0181 Kirigami.FormData.label: form.labelText 0182 0183 Repeater { 0184 id: repeater 0185 0186 model: 0 0187 0188 Rectangle { 0189 implicitWidth: 100 0190 implicitHeight: 100 0191 color: "red" 0192 } 0193 0194 onItemAdded: (index, item) => { 0195 form.buddyCreatedByRepeater = item; 0196 buddyColumn.Kirigami.FormData.buddyFor = item; 0197 } 0198 } 0199 } 0200 } 0201 } 0202 0203 function test_buddyCreatedAndDestroyedByRepeater() { 0204 // The point is to test automatic destruction as done by a Repeater 0205 0206 const form = createTemporaryObject(buddyRepeaterFormComponent, this); 0207 compare(form.buddyColumn.Kirigami.FormData.buddyFor, form.buddyColumn); 0208 0209 buddyChangeSpy.target = form.buddyColumn.Kirigami.FormData; 0210 buddyChangeSpy.clear(); 0211 verify(buddyChangeSpy.valid); 0212 0213 form.repeaterModel = 1; 0214 0215 verify(form.buddyCreatedByRepeater); 0216 compare(form.buddyColumn.Kirigami.FormData.buddyFor, form.buddyCreatedByRepeater); 0217 compare(buddyChangeSpy.count, 1); 0218 0219 form.repeaterModel = 0; 0220 wait(100); // Give Repeater some time to react to model changes. 0221 0222 verify(!form.buddyCreatedByRepeater); 0223 compare(form.buddyColumn.Kirigami.FormData.buddyFor, form.buddyColumn); 0224 compare(buddyChangeSpy.count, 2); 0225 } 0226 0227 Component { 0228 id: buddyComponentFormComponent 0229 0230 Kirigami.FormLayout { 0231 id: form 0232 0233 readonly property string labelText: "You found me!" 0234 readonly property alias buddyColumn: buddyColumn 0235 0236 function addBuddyFromComponent(component: Component): Item { 0237 const buddy = component.createObject(buddyColumn); 0238 buddyColumn.Kirigami.FormData.buddyFor = buddy; 0239 return buddy; 0240 } 0241 0242 wideMode: true 0243 0244 ColumnLayout { 0245 id: buddyColumn 0246 0247 spacing: 0 0248 0249 Kirigami.FormData.label: form.labelText 0250 } 0251 } 0252 } 0253 0254 Component { 0255 id: buddyComponent 0256 0257 Rectangle { 0258 implicitWidth: 100 0259 implicitHeight: 100 0260 color: "red" 0261 } 0262 } 0263 0264 function test_buddyCreatedAndDestroyedByComponent() { 0265 // The point is to test manual destruction as done by calling destroy() 0266 0267 const form = createTemporaryObject(buddyComponentFormComponent, this); 0268 compare(form.buddyColumn.Kirigami.FormData.buddyFor, form.buddyColumn); 0269 0270 buddyChangeSpy.target = form.buddyColumn.Kirigami.FormData; 0271 buddyChangeSpy.clear(); 0272 verify(buddyChangeSpy.valid); 0273 0274 const buddy = form.addBuddyFromComponent(buddyComponent); 0275 verify(buddy); 0276 compare(form.buddyColumn.Kirigami.FormData.buddyFor, buddy); 0277 compare(buddyChangeSpy.count, 1); 0278 0279 wait(100); 0280 0281 buddy.destroy(); 0282 0283 wait(100); 0284 0285 // should revert back to parent 0286 compare(form.buddyColumn.Kirigami.FormData.buddyFor, form.buddyColumn); 0287 compare(buddyChangeSpy.count, 2); 0288 } 0289 }