@@ -28,7 +28,7 @@ import Unity.Application 0.1
2828Item {
2929 id: root
3030 height: units.gu(60)
31− width: units.gu(60)
31+ width: units.gu(85)
3232
3333 Binding {
3434 target: PanelState
@@ -41,14 +41,20 @@ Item {
4141
4242 Item {
4343 id: fakeWindow
44− property alias minWidth: windowResizeArea.minWidth
45− property alias minHeight: windowResizeArea.minHeight
44+ property alias resizeAreaMinWidth: windowResizeArea.minWidth
45+ property alias resizeAreaMinHeight: windowResizeArea.minHeight
4646 x: units.gu(20)
4747 y: units.gu(20)
4848 width: requestedWidth
4949 height: requestedHeight
5050 property real requestedWidth
5151 property real requestedHeight
52+ property real minimumWidth: 0
53+ property real minimumHeight: 0
54+ property real maximumWidth: 0
55+ property real maximumHeight: 0
56+ property real widthIncrement: 0
57+ property real heightIncrement: 0
5258 state: "normal"
5359
5460 function maximize() {
@@ -80,6 +86,10 @@ Item {
8086 anchors.fill: parent
8187 hoverEnabled: true
8288 }
89+ Text {
90+ text: parent.width + "x" + parent.height
91+ color: "white"
92+ }
8393 }
8494 }
8595 }
@@ -90,27 +100,107 @@ Item {
90100 active: windowLoaderCheckbox.checked
91101 }
92102
93− Column {
94− MouseTouchEmulationCheckbox {
95− checked: false
96− color: "black"
97− }
98− RowLayout {
99− Layout.fillWidth: true
100− CheckBox {
101− id: windowLoaderCheckbox
102− checked: true
103− activeFocusOnPress: false
103+ Rectangle {
104+ anchors.right: parent.right
105+ anchors.top: parent.top
106+ anchors.bottom: parent.bottom
107+ width: units.gu(25)
108+ color: "lightgrey"
109+ Column {
110+ width: parent.width
111+ spacing: units.gu(1)
112+ MouseTouchEmulationCheckbox {
113+ checked: false
114+ color: "black"
115+ }
116+ RowLayout {
117+ Layout.fillWidth: true
118+ CheckBox {
119+ id: windowLoaderCheckbox
120+ checked: true
121+ activeFocusOnPress: false
122+ }
123+ Label {
124+ color: "black"
125+ text: "Window loader active"
126+ anchors.verticalCenter: parent.verticalCenter
127+ }
104128 }
105129 Label {
106− id: label
130+ color: "black"; font.bold: true
131+ text: "Size Hints:"
132+ }
133+ SizeHintField { id: minWidthText; text: "min width" }
134+ SizeHintField { id: maxWidthText; text: "max width" }
135+ SizeHintField { id: minHeightText; text: "min height" }
136+ SizeHintField { id: maxHeightText; text: "max height" }
137+ SizeHintField { id: widthIncrText; text: "width incr" }
138+ SizeHintField { id: heightIncrText; text: "height incr" }
139+ Button {
107140 color: "black"
108− text: "Window loader active"
109− anchors.verticalCenter: parent.verticalCenter
141+ anchors.horizontalCenter: parent.horizontalCenter
142+ text: "Apply"
143+ onClicked: {
144+ var value = parseInt(minWidthText.value);
145+ if (isNaN(value)) {
146+ windowLoader.item.minimumWidth = 0;
147+ } else {
148+ windowLoader.item.resizeAreaMinWidth = 1; // get it out of the way
149+ windowLoader.item.minimumWidth = value;
150+ }
151+
152+ value = parseInt(maxWidthText.value);
153+ if (isNaN(value)) {
154+ windowLoader.item.maximumWidth = 0;
155+ } else {
156+ windowLoader.item.maximumWidth = value;
157+ }
158+
159+ value = parseInt(minHeightText.value);
160+ if (isNaN(value)) {
161+ windowLoader.item.minimumHeight = 0;
162+ } else {
163+ windowLoader.item.resizeAreaMinHeight = 1; // get it out of the way
164+ windowLoader.item.minimumHeight = value;
165+ }
166+
167+ value = parseInt(maxHeightText.value);
168+ if (isNaN(value)) {
169+ windowLoader.item.maximumHeight = 0;
170+ } else {
171+ windowLoader.item.maximumHeight = value;
172+ }
173+
174+ value = parseInt(widthIncrText.value);
175+ if (isNaN(value)) {
176+ windowLoader.item.widthIncrement = 0;
177+ } else {
178+ windowLoader.item.widthIncrement = value;
179+ }
180+
181+ value = parseInt(heightIncrText.value);
182+ if (isNaN(value)) {
183+ windowLoader.item.heightIncrement = 0;
184+ } else {
185+ windowLoader.item.heightIncrement = value;
186+ }
187+ }
110188 }
111189 }
112190 }
113191
192+ SignalSpy {
193+ id: windowRequestedWidthSpy
194+ target: windowLoader.item
195+ signalName: "onRequestedWidthChanged"
196+ }
197+
198+ SignalSpy {
199+ id: windowRequestedHeightSpy
200+ target: windowLoader.item
201+ signalName: "onRequestedHeightChanged"
202+ }
203+
114204 UnityTestCase {
115205 name: "WindowResizeArea"
116206 when: windowShown
@@ -122,6 +212,18 @@ Item {
122212 fakeWindow.y = units.gu(20)
123213 fakeWindow.requestedWidth = units.gu(20)
124214 fakeWindow.requestedHeight = units.gu(20)
215+ fakeWindow.resizeAreaMinWidth = units.gu(15);
216+ fakeWindow.resizeAreaMinHeight = units.gu(10);
217+ fakeWindow.minimumWidth = 0;
218+ fakeWindow.minimumHeight = 0;
219+ fakeWindow.maximumWidth = 0;
220+ fakeWindow.maximumHeight = 0;
221+ fakeWindow.widthIncrement = 0;
222+ fakeWindow.heightIncrement = 0;
223+
224+ // Our test window resizes instantly
225+ compare(fakeWindow.width, fakeWindow.requestedWidth);
226+ compare(fakeWindow.height, fakeWindow.requestedHeight);
125227 }
126228
127229 function test_resizeWindowRightBottom_data() {
@@ -143,8 +245,8 @@ Item {
143245 var startDragY = initialWindowY + initialWindowHeight + 1
144246 mouseFlick(root, startDragX, startDragY, startDragX + data.dx, startDragY + data.dy, true, true, units.gu(.5), 10);
145247
146− tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + data.dx, fakeWindow.minWidth));
147− tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + data.dy, fakeWindow.minHeight));
248+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + data.dx, fakeWindow.resizeAreaMinWidth));
249+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + data.dy, fakeWindow.resizeAreaMinHeight));
148250
149251 compare(fakeWindow.x, initialWindowX);
150252 compare(fakeWindow.y, initialWindowY);
@@ -169,11 +271,11 @@ Item {
169271 var startDragY = initialWindowY - 1
170272 mouseFlick(root, startDragX, startDragY, startDragX + data.dx, startDragY + data.dy, true, true, units.gu(.5), 10);
171273
172− tryCompare(fakeWindow, "width", Math.max(initialWindowWidth - data.dx, fakeWindow.minWidth));
173− tryCompare(fakeWindow, "height", Math.max(initialWindowHeight - data.dy, fakeWindow.minHeight));
274+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth - data.dx, fakeWindow.resizeAreaMinWidth));
275+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight - data.dy, fakeWindow.resizeAreaMinHeight));
174276
175− var maxMoveX = initialWindowWidth - fakeWindow.minWidth;
176− var maxMoveY = initialWindowHeight - fakeWindow.minHeight;
277+ var maxMoveX = initialWindowWidth - fakeWindow.resizeAreaMinWidth;
278+ var maxMoveY = initialWindowHeight - fakeWindow.resizeAreaMinHeight;
177279 compare(fakeWindow.x, Math.min(initialWindowX + data.dx, initialWindowX + maxMoveX));
178280 compare(fakeWindow.y, Math.min(initialWindowY + data.dy, initialWindowY + maxMoveY));
179281 }
@@ -189,8 +291,8 @@ Item {
189291 var startDragY = initialWindowY + initialWindowHeight + 1
190292 mouseFlick(root, startDragX, startDragY, startDragX + resizeDelta, startDragY + resizeDelta, true, true, units.gu(.5), 10);
191293
192− tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + resizeDelta, fakeWindow.minWidth));
193− tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + resizeDelta, fakeWindow.minHeight));
294+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + resizeDelta, fakeWindow.resizeAreaMinWidth));
295+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + resizeDelta, fakeWindow.resizeAreaMinHeight));
194296
195297 // This will destroy the window and recreate it
196298 windowLoader.active = false;
@@ -198,8 +300,8 @@ Item {
198300 windowLoader.active = true;
199301
200302 // Make sure its size is again the same as before
201− tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + resizeDelta, fakeWindow.minWidth));
202− tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + resizeDelta, fakeWindow.minHeight));
303+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + resizeDelta, fakeWindow.resizeAreaMinWidth));
304+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + resizeDelta, fakeWindow.resizeAreaMinHeight));
203305 }
204306
205307 // This tests if dragging smaller than minSize and then larger again, will keep the edge sticking
@@ -220,8 +322,8 @@ Item {
220322 var startDragX = initialWindowX + data.startX
221323 var startDragY = initialWindowY + data.startY
222324 mouseFlick(root, startDragX, startDragY, startDragX + data.dx, startDragY + data.dy, true, false, units.gu(.05), 10);
223− tryCompare(fakeWindow, "width", Math.max(initialWindowWidth - Math.abs(data.dx), fakeWindow.minWidth));
224− tryCompare(fakeWindow, "height", Math.max(initialWindowHeight - Math.abs(data.dy), fakeWindow.minHeight));
325+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth - Math.abs(data.dx), fakeWindow.resizeAreaMinWidth));
326+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight - Math.abs(data.dy), fakeWindow.resizeAreaMinHeight));
225327 mouseFlick(root, startDragX + data.dx, startDragY + data.dy, startDragX, startDragY, false, true, units.gu(.05), 10);
226328 tryCompare(fakeWindow, "width", initialWindowWidth);
227329 tryCompare(fakeWindow, "height", initialWindowHeight);
@@ -257,7 +359,6 @@ Item {
257359 fakeWindow.state = "normal"
258360 }
259361
260−
261362 function test_restoreMovesIntoBounds_data() {
262363 return [
263364 {tag: "left off", x: -units.gu(5), y: units.gu(5), w: units.gu(10), h: units.gu(10)},
@@ -290,5 +391,99 @@ Item {
290391
291392 waitForRendering(root)
292393 }
394+
395+ /*
396+ Tests that even though you dragged the window bottom right corner continously (ie,
397+ through multiple intermediate steps), its (requested) width and height changed only
398+ once. And, furthermore, its dimensions increased by a multiple of its size (width
399+ and height) increment value.
400+ */
401+ function test_sizeIncrement() {
402+ var initialWindowX = fakeWindow.x;
403+ var initialWindowY = fakeWindow.y;
404+ var initialWindowWidth = fakeWindow.width
405+ var initialWindowHeight = fakeWindow.height
406+
407+ fakeWindow.widthIncrement = 70;
408+ fakeWindow.heightIncrement = 70;
409+
410+ var startDragX = initialWindowX + initialWindowWidth + 1
411+ var startDragY = initialWindowY + initialWindowHeight + 1
412+ var deltaX = 100;
413+ var deltaY = 100;
414+
415+ windowRequestedWidthSpy.clear();
416+ verify(windowRequestedWidthSpy.valid);
417+
418+ windowRequestedHeightSpy.clear();
419+ verify(windowRequestedHeightSpy.valid);
420+
421+ mouseFlick(root, startDragX, startDragY, startDragX + deltaX, startDragY + deltaY, true, true, units.gu(.5), 10);
422+
423+ compare(windowRequestedWidthSpy.count, 1);
424+ compare(fakeWindow.width, initialWindowWidth + fakeWindow.widthIncrement);
425+ compare(windowRequestedHeightSpy.count, 1);
426+ compare(fakeWindow.height, initialWindowHeight + fakeWindow.heightIncrement);
427+ }
428+
429+ /*
430+ Tests that when dragging a window border you cannot make it bigger than its maximum size
431+ */
432+ function test_maximumSize() {
433+ fakeWindow.x = units.gu(1);
434+ fakeWindow.y = units.gu(1);
435+ fakeWindow.resizeAreaMinWidth = 1; // so it does not interfere with anything
436+ fakeWindow.resizeAreaMinHeight = 1; // so it does not interfere with anything
437+ fakeWindow.requestedWidth = units.gu(10);
438+ fakeWindow.requestedHeight = units.gu(10);
439+
440+ fakeWindow.maximumWidth = units.gu(20);
441+ fakeWindow.maximumHeight = units.gu(20);
442+
443+ // Our test window resizes instantly
444+ compare(fakeWindow.width, fakeWindow.requestedWidth);
445+ compare(fakeWindow.height, fakeWindow.requestedHeight);
446+
447+ var startDragX = fakeWindow.width + 1
448+ var startDragY = fakeWindow.height + 1
449+ var endDragX = (fakeWindow.maximumWidth * 2) + 1;
450+ var endDragY = (fakeWindow.maximumHeight * 2) + 1;
451+
452+ mouseFlick(fakeWindow, startDragX, startDragY, endDragX, endDragY,
453+ true/*pressMouse*/, true/*releaseMouse*/, units.gu(.5)/*speed*/, 20/*iterations*/);
454+
455+ compare(fakeWindow.requestedWidth, fakeWindow.maximumWidth);
456+ compare(fakeWindow.requestedHeight, fakeWindow.maximumHeight);
457+ }
458+
459+ /*
460+ Tests that when dragging a window border you cannot make it smaller than its minimum size
461+ */
462+ function test_minimumSize() {
463+ fakeWindow.x = units.gu(1);
464+ fakeWindow.y = units.gu(1);
465+ fakeWindow.resizeAreaMinWidth = 1; // so it does not interfere with anything
466+ fakeWindow.resizeAreaMinHeight = 1; // so it does not interfere with anything
467+ fakeWindow.requestedWidth = units.gu(20);
468+ fakeWindow.requestedHeight = units.gu(20);
469+
470+ fakeWindow.minimumWidth = units.gu(10);
471+ fakeWindow.minimumHeight = units.gu(10);
472+
473+ // Our test window resizes instantly
474+ compare(fakeWindow.width, fakeWindow.requestedWidth);
475+ compare(fakeWindow.height, fakeWindow.requestedHeight);
476+
477+ var startDragX = fakeWindow.width + 1
478+ var startDragY = fakeWindow.height + 1
479+ var endDragX = (fakeWindow.minimumWidth * 0.5) + 1;
480+ var endDragY = (fakeWindow.minimumHeight * 0.5) + 1;
481+
482+ mouseFlick(fakeWindow, startDragX, startDragY, endDragX, endDragY,
483+ true/*pressMouse*/, true/*releaseMouse*/, units.gu(.5)/*speed*/, 20/*iterations*/);
484+
485+ compare(fakeWindow.requestedWidth, fakeWindow.minimumWidth);
486+ compare(fakeWindow.requestedHeight, fakeWindow.minimumHeight);
487+ }
293488 }
294489}