├── .travis.yml
├── LICENSE.md
├── README.md
├── documentation
├── ImportAll.hx
└── compile.hxml
├── haxedoc.xml
├── haxelib.json
├── layout
├── Layout.hx
├── LayoutGroup.hx
├── LayoutItem.hx
└── LayoutType.hx
├── skylark
└── layout
│ ├── Layout.hx
│ ├── LayoutGroup.hx
│ ├── LayoutItem.hx
│ └── LayoutType.hx
└── tests
├── .gitignore
├── .munit
├── test.hxml
└── test
├── BasicLayoutTest.hx
└── GroupTest.hx
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: c++
2 |
3 | before_install:
4 | - export DISPLAY=:99.0
5 | - sh -e /etc/init.d/xvfb start
6 | - /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac -screen 0 1280x1024x32 -extension GLX
7 | - export AUDIODEV=null
8 | - sudo add-apt-repository ppa:eyecreate/haxe -y
9 | - sudo apt-get update
10 |
11 | install:
12 | - sudo apt-get install haxe -y --force-yes
13 | - sudo apt-get install g++-multilib gcc-multilib
14 | - sudo apt-get install mesa-common-dev libgl1-mesa-dev libglu1-mesa-dev -y
15 | - mkdir ~/haxelib
16 | - haxelib setup ~/haxelib
17 | - haxelib install hxcpp
18 | - haxelib install mcover
19 | - git clone https://github.com/jgranick/MassiveUnit ~/munit --depth 1
20 | - haxelib dev munit ~/munit/src
21 | - haxelib dev layout $(pwd)
22 | - cd ~/munit/tool
23 | - haxe build.hxml
24 |
25 | before_script:
26 | - cd $TRAVIS_BUILD_DIR/tests
27 | - haxelib run munit gen
28 |
29 | script:
30 | - haxelib run munit test -as3 -norun
31 | - haxelib run munit test -browser phantomjs
32 | - haxelib run munit test -neko
33 | - haxelib run munit test -cpp
34 |
35 | notifications:
36 | slack: openfl:sBwVO0kgB7EuWLYzZzUezVIz
37 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | License
2 | =======
3 |
4 | The MIT License (MIT)
5 |
6 | Copyright (c) 2009-2015 Joshua Granick
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining a copy
9 | of this software and associated documentation files (the "Software"), to deal
10 | in the Software without restriction, including without limitation the rights
11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | copies of the Software, and to permit persons to whom the Software is
13 | furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in
16 | all copies or substantial portions of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | THE SOFTWARE.
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](LICENSE.md) [](http://lib.haxe.org/p/layout)
2 |
3 | Layout
4 | =====
5 |
6 | Layout is an easy-to-use library for handling fluid layout.
7 |
8 |
9 | Installation
10 | ============
11 |
12 | You can easily install Layout using haxelib:
13 |
14 | haxelib install layout
15 |
16 | To add it to a Lime or OpenFL project, add this to your project file:
17 |
18 |
19 |
20 |
21 | Development Builds
22 | ==================
23 |
24 | Clone the Layout repository:
25 |
26 | git clone https://github.com/openfl/layout
27 |
28 | Tell haxelib where your development copy of Layout is installed:
29 |
30 | haxelib dev layout layout
31 |
32 | To return to release builds:
33 |
34 | haxelib dev layout
35 |
--------------------------------------------------------------------------------
/documentation/ImportAll.hx:
--------------------------------------------------------------------------------
1 | package;
2 |
3 | import skylark.layout.LayoutGroup;
4 | import skylark.layout.LayoutItem;
5 | import skylark.layout.LayoutManager;
6 | import skylark.layout.LayoutType;
--------------------------------------------------------------------------------
/documentation/compile.hxml:
--------------------------------------------------------------------------------
1 | -swf all.swf
2 | --no-output
3 | -xml ../haxedoc.xml
4 | -cp ../
5 | ImportAll
--------------------------------------------------------------------------------
/haxelib.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "layout",
3 | "url": "http://github.com/openfl/layout",
4 | "license": "MIT",
5 | "tags": ["cpp", "flash", "neko", "js"],
6 | "description": "Flexible system for fluid resizing layouts",
7 | "version": "1.2.1",
8 | "releasenote": "Fixed possible stack overflow",
9 | "contributors": [ "singmajesty" ],
10 | "dependencies": {}
11 | }
12 |
--------------------------------------------------------------------------------
/layout/Layout.hx:
--------------------------------------------------------------------------------
1 | package layout;
2 |
3 |
4 | typedef Layout = skylark.layout.Layout;
--------------------------------------------------------------------------------
/layout/LayoutGroup.hx:
--------------------------------------------------------------------------------
1 | package layout;
2 |
3 |
4 | typedef LayoutGroup = skylark.layout.LayoutGroup;
--------------------------------------------------------------------------------
/layout/LayoutItem.hx:
--------------------------------------------------------------------------------
1 | package layout;
2 |
3 |
4 | typedef LayoutItem = skylark.layout.LayoutItem;
--------------------------------------------------------------------------------
/layout/LayoutType.hx:
--------------------------------------------------------------------------------
1 | package layout;
2 |
3 |
4 | typedef LayoutType = skylark.layout.LayoutType;
--------------------------------------------------------------------------------
/skylark/layout/Layout.hx:
--------------------------------------------------------------------------------
1 | package skylark.layout;
2 |
3 |
4 | #if (flash || openfl || nme)
5 | import flash.events.Event;
6 | import flash.events.EventDispatcher;
7 | #end
8 |
9 | @:access(skylark.layout.LayoutGroup)
10 |
11 |
12 | class Layout #if (flash || openfl || nme) extends EventDispatcher #end {
13 |
14 |
15 | public var clampHeight (get, set):Bool;
16 | public var clampWidth (get, set):Bool;
17 | public var height (get, null):Float;
18 | public var initHeight (default, null):Float;
19 | public var initWidth (get, null):Float;
20 | public var minHeight (get, set):Float;
21 | public var minWidth (get, set):Float;
22 | public var pixelScale (get, set):Float;
23 | public var width (get, null):Float;
24 |
25 | private var items:LayoutGroup;
26 |
27 | private var _initHeight:Float;
28 | private var _initWidth:Float;
29 |
30 |
31 | public function new (initWidth:Float = 0, initHeight:Float = 0) {
32 |
33 | #if (flash || openfl || nme)
34 | super ();
35 | #end
36 |
37 | _initWidth = initWidth;
38 | _initHeight = initHeight;
39 |
40 | initialize ();
41 |
42 | }
43 |
44 |
45 | public function addItem (item:LayoutItem, autoConfigureVertical:Bool = true, autoConfigureHorizontal:Bool = true):Void {
46 |
47 | items.addItem (item, autoConfigureVertical, autoConfigureHorizontal, false);
48 |
49 | }
50 |
51 |
52 | private function initialize ():Void {
53 |
54 | items = new LayoutGroup (LayoutType.NONE, LayoutType.NONE, false);
55 | items.resize (_initWidth, _initHeight);
56 |
57 | }
58 |
59 |
60 | public function layoutItems ():Void {
61 |
62 | items.layoutItemGroup ();
63 |
64 | }
65 |
66 |
67 | public function resize (width:Float, height:Float):Void {
68 |
69 | if (_initWidth == 0 && _initHeight == 0) {
70 |
71 | if (items.width == 0 && items.height == 0) {
72 |
73 | items.refreshSize ();
74 |
75 | }
76 |
77 | _initWidth = items.width;
78 | _initHeight = items.height;
79 |
80 | items.setInitSize (_initWidth, _initHeight);
81 | items.configureItems ();
82 |
83 | }
84 |
85 | var cacheWidth = items.width;
86 | var cacheHeight = items.height;
87 |
88 | items.resize (width, height);
89 |
90 | if (items.width != cacheWidth || items.height != cacheHeight) {
91 |
92 | #if (flash || openfl || nme)
93 | dispatchEvent (new Event (Event.RESIZE));
94 | #end
95 |
96 | }
97 |
98 | }
99 |
100 |
101 | public function setMinSize (minWidth:Float = 0, minHeight:Float = 0):Void {
102 |
103 | items.minWidth = minWidth;
104 | items.minHeight = minHeight;
105 |
106 | }
107 |
108 |
109 |
110 |
111 | // Get & Set Methods
112 |
113 |
114 |
115 |
116 | private function get_clampHeight ():Bool {
117 |
118 | return items.clampHeight;
119 |
120 | }
121 |
122 |
123 | private function set_clampHeight (value:Bool):Bool {
124 |
125 | return items.clampHeight = value;
126 |
127 | }
128 |
129 |
130 | private function get_clampWidth ():Bool {
131 |
132 | return items.clampWidth;
133 |
134 | }
135 |
136 |
137 | private function set_clampWidth (value:Bool):Bool {
138 |
139 | return items.clampWidth = value;
140 |
141 | }
142 |
143 |
144 | private function get_height ():Float {
145 |
146 | return items.height;
147 |
148 | }
149 |
150 |
151 | private function get_initHeight ():Float {
152 |
153 | return items.initHeight;
154 |
155 | }
156 |
157 |
158 | private function get_initWidth ():Float {
159 |
160 | return items.initWidth;
161 |
162 | }
163 |
164 |
165 | private function get_minHeight ():Float {
166 |
167 | return items.minHeight;
168 |
169 | }
170 |
171 |
172 | private function set_minHeight (value:Float):Float {
173 |
174 | return items.minHeight = value;
175 |
176 | }
177 |
178 |
179 | private function get_minWidth ():Float {
180 |
181 | return items.minWidth;
182 |
183 | }
184 |
185 |
186 | private function set_minWidth (value:Float):Float {
187 |
188 | return items.minWidth = value;
189 |
190 | }
191 |
192 |
193 | private function get_pixelScale ():Float {
194 |
195 | return items.pixelScale;
196 |
197 | }
198 |
199 |
200 | private function set_pixelScale (value:Float):Float {
201 |
202 | return items.pixelScale = value;
203 |
204 | }
205 |
206 |
207 | private function get_width ():Float {
208 |
209 | return items.width;
210 |
211 | }
212 |
213 |
214 | }
--------------------------------------------------------------------------------
/skylark/layout/LayoutGroup.hx:
--------------------------------------------------------------------------------
1 | package skylark.layout;
2 |
3 |
4 | class LayoutGroup extends LayoutItem {
5 |
6 |
7 | public var clampHeight:Bool;
8 | public var clampWidth:Bool;
9 | public var height (get, set):Float;
10 | public var initHeight (default, null):Float;
11 | public var initScale (default, null):Float;
12 | public var initWidth (default, null):Float;
13 | public var items:Array;
14 | public var pixelScale (get, set):Float;
15 | public var width (get, set):Float;
16 | public var x (get, set):Float;
17 | public var y (get, set):Float;
18 |
19 | private var itemConfigureHorizontal:Array ;
20 | private var itemConfigureVertical:Array ;
21 | private var loop:Bool;
22 |
23 | private var _height:Float;
24 | private var _pixelScale:Float;
25 | private var _width:Float;
26 | private var _x:Float;
27 | private var _y:Float;
28 |
29 |
30 | public function new (verticalLayout:LayoutType = null, horizontalLayout:LayoutType = null, rigidVertical:Bool = true, rigidHorizontal:Bool = true) {
31 |
32 | if (verticalLayout == null) {
33 |
34 | verticalLayout = LayoutType.NONE;
35 |
36 | }
37 |
38 | if (horizontalLayout == null) {
39 |
40 | horizontalLayout = LayoutType.NONE;
41 |
42 | }
43 |
44 | super (this, verticalLayout, horizontalLayout, rigidVertical, rigidHorizontal);
45 |
46 | _x = 0;
47 | _y = 0;
48 | _width = 0;
49 | _height = 0;
50 | _pixelScale = 0;
51 |
52 | resize (0, 0);
53 |
54 | }
55 |
56 |
57 | public function addItem (item:LayoutItem, autoConfigureVertical:Bool = true, autoConfigureHorizontal:Bool = true, updateSize:Bool = true):Void {
58 |
59 | if (initWidth != 0 && initHeight != 0) {
60 |
61 | configureItem (item, autoConfigureVertical, autoConfigureHorizontal);
62 |
63 | }
64 |
65 | items.push (item);
66 | itemConfigureVertical.push (autoConfigureVertical);
67 | itemConfigureHorizontal.push (autoConfigureHorizontal);
68 |
69 | if (updateSize) {
70 |
71 | refreshSize ();
72 |
73 | if (initWidth != 0 && initHeight != 0) {
74 |
75 | configureItems ();
76 |
77 | }
78 |
79 | }
80 |
81 | }
82 |
83 |
84 | private function configureItem (item:LayoutItem, autoConfigureVertical:Bool, autoConfigureHorizontal:Bool):Void {
85 |
86 | item.configureItems ();
87 |
88 | if (autoConfigureVertical) {
89 |
90 | switch (item.verticalLayout) {
91 |
92 | case LayoutType.BOTTOM:
93 |
94 | item.marginBottom = initHeight - item.objectY - item.objectHeight - _y;
95 |
96 | case LayoutType.CENTER:
97 |
98 | var verticalOffset = item.objectY - (initHeight / 2 - item.objectHeight / 2) - _y;
99 |
100 | if (verticalOffset > 0) {
101 |
102 | item.marginTop = verticalOffset;
103 |
104 | } else {
105 |
106 | item.marginBottom = Math.abs (verticalOffset);
107 |
108 | }
109 |
110 | case LayoutType.STRETCH:
111 |
112 | item.marginTop = item.objectY - _y;
113 | item.marginBottom = initHeight - item.objectY - item.objectHeight - _y;
114 |
115 | if (item.rigidVertical && item.minHeight == null) {
116 |
117 | item.minHeight = item.objectHeight;
118 |
119 | }
120 |
121 | case LayoutType.TOP:
122 |
123 | item.marginTop = item.objectY - _y;
124 |
125 | default:
126 |
127 | }
128 |
129 | }
130 |
131 | if (autoConfigureHorizontal) {
132 |
133 | switch (item.horizontalLayout) {
134 |
135 | case LayoutType.CENTER:
136 |
137 | var horizontalOffset = item.objectX - (initWidth / 2 - item.objectWidth / 2) - _x;
138 |
139 | if (horizontalOffset > 0) {
140 |
141 | item.marginLeft = horizontalOffset;
142 |
143 | } else {
144 |
145 | item.marginRight = Math.abs (horizontalOffset);
146 |
147 | }
148 |
149 | case LayoutType.LEFT:
150 |
151 | item.marginLeft = item.objectX - _x;
152 |
153 | case LayoutType.RIGHT:
154 |
155 | item.marginRight = initWidth - item.objectX - item.objectWidth - _x;
156 |
157 | case LayoutType.STRETCH:
158 |
159 | item.marginLeft = item.objectX - _x;
160 | item.marginRight = initWidth - item.objectX - item.objectWidth - _x;
161 |
162 | if (item.rigidHorizontal && item.minWidth == null) {
163 |
164 | item.minWidth = item.objectWidth;
165 |
166 | }
167 |
168 | default:
169 |
170 | }
171 |
172 | }
173 |
174 | }
175 |
176 |
177 | private override function configureItems ():Void {
178 |
179 | for (i in 0...items.length) {
180 |
181 | configureItem (items[i], itemConfigureVertical[i], itemConfigureHorizontal[i]);
182 |
183 | }
184 |
185 | }
186 |
187 |
188 | private override function initialize ():Void {
189 |
190 | items = new Array ();
191 | itemConfigureHorizontal = new Array ();
192 | itemConfigureVertical = new Array ();
193 |
194 | super.initialize ();
195 |
196 | }
197 |
198 |
199 | private function layoutItemGroup ():Void {
200 |
201 | var minWidth = ifDefined (minWidth, 0);
202 | var minHeight = ifDefined (minHeight, 0);
203 |
204 | var minObjectHeight, minObjectWidth;
205 |
206 | for (item in items) {
207 |
208 | item.layoutItem (this);
209 |
210 | if (item.rigidVertical) {
211 |
212 | minObjectHeight = item.marginTop + item.marginBottom;
213 |
214 | if (item.minHeight != null) {
215 |
216 | minObjectHeight += item.minHeight;
217 |
218 | } else {
219 |
220 | minObjectHeight += item.objectHeight;
221 |
222 | }
223 |
224 | if (minHeight < minObjectHeight) {
225 |
226 | minHeight = minObjectHeight;
227 |
228 | }
229 |
230 | }
231 |
232 | if (item.rigidHorizontal) {
233 |
234 | minObjectWidth = item.marginLeft + item.marginRight;
235 |
236 | if (item.minWidth != null) {
237 |
238 | minObjectWidth += item.minWidth;
239 |
240 | } else {
241 |
242 | minObjectWidth += item.objectWidth;
243 |
244 | }
245 |
246 | if (minWidth < minObjectWidth) {
247 |
248 | minWidth = minObjectWidth;
249 |
250 | }
251 |
252 | }
253 |
254 | }
255 |
256 | var newWidth = width;
257 | var newHeight = height;
258 |
259 | if (newWidth < minWidth) {
260 |
261 | newWidth = minWidth;
262 |
263 | }
264 |
265 | if (newHeight < minHeight) {
266 |
267 | newHeight = minHeight;
268 |
269 | }
270 |
271 | if (clampWidth && newWidth > initWidth) {
272 |
273 | newWidth = initWidth;
274 |
275 | }
276 |
277 | if (clampHeight && newHeight > initHeight) {
278 |
279 | newHeight = initHeight;
280 |
281 | }
282 |
283 | if (newWidth != width || newHeight != height) {
284 |
285 | if (!loop) {
286 |
287 | loop = true;
288 | resize (newWidth, newHeight);
289 | loop = false;
290 |
291 | }
292 |
293 | }
294 |
295 | }
296 |
297 |
298 | private override function refreshSize ():Void {
299 |
300 | if (items.length > 0) {
301 |
302 | var beginningX = Math.POSITIVE_INFINITY;
303 | var beginningY = Math.POSITIVE_INFINITY;
304 | var endX = Math.NEGATIVE_INFINITY;
305 | var endY = Math.NEGATIVE_INFINITY;
306 |
307 | for (item in items) {
308 |
309 | item.refreshSize ();
310 |
311 | if (item.verticalLayout != LayoutType.NONE) {
312 |
313 | if (item.objectY < beginningY) {
314 |
315 | beginningY = item.objectY;
316 |
317 | }
318 |
319 | if (item.objectY + item.objectHeight > endY) {
320 |
321 | endY = item.objectY + item.objectHeight;
322 |
323 | }
324 |
325 | }
326 |
327 | if (item.horizontalLayout != LayoutType.NONE) {
328 |
329 | if (item.objectX < beginningX) {
330 |
331 | beginningX = item.objectX;
332 |
333 | }
334 |
335 | if (item.objectX + item.objectWidth > endX) {
336 |
337 | endX = item.objectX + item.objectWidth;
338 |
339 | }
340 |
341 | }
342 |
343 | }
344 |
345 | if (beginningX != Math.POSITIVE_INFINITY && endX != Math.NEGATIVE_INFINITY) {
346 |
347 | _x = beginningX;
348 | _width = initWidth = endX - beginningX;
349 |
350 | }
351 |
352 | if (beginningY != Math.POSITIVE_INFINITY && endY != Math.NEGATIVE_INFINITY) {
353 |
354 | _y = beginningY;
355 | _height = initHeight = endY - beginningY;
356 |
357 | }
358 |
359 | }
360 |
361 | }
362 |
363 |
364 | public function resize (width:Float, height:Float):Void {
365 |
366 | _width = width;
367 | _height = height;
368 |
369 | if (items.length > 0) {
370 |
371 | layoutItemGroup ();
372 |
373 | } else {
374 |
375 | initWidth = width;
376 | initHeight = height;
377 |
378 | }
379 |
380 | }
381 |
382 |
383 | public function scale (scale:Float):Void {
384 |
385 | _pixelScale = scale;
386 |
387 | if (items.length > 0) {
388 |
389 | layoutItemGroup ();
390 |
391 | } else {
392 |
393 | initScale = _pixelScale;
394 |
395 | }
396 |
397 | }
398 |
399 |
400 | public function setInitSize (width:Float, height:Float):Void {
401 |
402 | initWidth = width;
403 | initHeight = height;
404 |
405 | }
406 |
407 |
408 |
409 |
410 | // Get & Set Methods
411 |
412 |
413 |
414 |
415 | private function get_height ():Float {
416 |
417 | return _height;
418 |
419 | }
420 |
421 |
422 | private function set_height (value:Float):Float {
423 |
424 | resize (_width, value);
425 |
426 | return _height;
427 |
428 | }
429 |
430 |
431 | private function get_pixelScale ():Float {
432 |
433 | return _pixelScale;
434 |
435 | }
436 |
437 |
438 | private function set_pixelScale (value:Float):Float {
439 |
440 | scale (value);
441 |
442 | return _pixelScale;
443 |
444 | }
445 |
446 |
447 | private function get_width ():Float {
448 |
449 | return _width;
450 |
451 | }
452 |
453 |
454 | private function set_width (value:Float):Float {
455 |
456 | resize (value, _height);
457 |
458 | return _width;
459 |
460 | }
461 |
462 |
463 | private function get_x ():Float {
464 |
465 | return _x;
466 |
467 | }
468 |
469 |
470 | private function set_x (value:Float):Float {
471 |
472 | _x = value;
473 |
474 | layoutItemGroup ();
475 |
476 | return _x;
477 |
478 | }
479 |
480 |
481 | private function get_y ():Float {
482 |
483 | return _y;
484 |
485 | }
486 |
487 |
488 | private function set_y (value:Float):Float {
489 |
490 | _y = value;
491 |
492 | layoutItemGroup ();
493 |
494 | return _y;
495 |
496 | }
497 |
498 |
499 | }
--------------------------------------------------------------------------------
/skylark/layout/LayoutItem.hx:
--------------------------------------------------------------------------------
1 | package skylark.layout;
2 |
3 |
4 | class LayoutItem {
5 |
6 |
7 | public var horizontalLayout:LayoutType;
8 | public var marginLeft:Float;
9 | public var marginRight:Float;
10 | public var marginTop:Float;
11 | public var marginBottom:Float;
12 | public var minHeight:Null;
13 | public var minWidth:Null;
14 | public var object:Dynamic;
15 | public var rigidHorizontal:Bool;
16 | public var rigidVertical:Bool;
17 | public var verticalLayout:LayoutType;
18 |
19 | private var objectHeight (get, set):Float;
20 | private var objectScaleX (get, set):Float;
21 | private var objectScaleY (get, set):Float;
22 | private var objectWidth (get, set):Float;
23 | private var objectX (get, set):Float;
24 | private var objectY (get, set):Float;
25 |
26 |
27 | public function new (object:Dynamic, verticalLayout:LayoutType = null, horizontalLayout:LayoutType = null, rigidVertical:Bool = true, rigidHorizontal:Bool = true) {
28 |
29 | if (verticalLayout == null) {
30 |
31 | verticalLayout = LayoutType.TOP;
32 |
33 | }
34 |
35 | if (horizontalLayout == null) {
36 |
37 | horizontalLayout = LayoutType.LEFT;
38 |
39 | }
40 |
41 | this.object = object;
42 | this.verticalLayout = verticalLayout;
43 | this.horizontalLayout = horizontalLayout;
44 | this.rigidVertical = rigidVertical;
45 | this.rigidHorizontal = rigidHorizontal;
46 |
47 | initialize ();
48 |
49 | }
50 |
51 |
52 | private function configureItems ():Void {
53 |
54 |
55 |
56 | }
57 |
58 |
59 | private inline function getField (target:Dynamic, propertyName:String):Dynamic {
60 |
61 | #if (haxe_209 || haxe3)
62 |
63 | var value = null;
64 |
65 | if (Reflect.hasField (target, propertyName)) {
66 |
67 | #if flash
68 | value = untyped target[propertyName];
69 | #else
70 | value = Reflect.field (target, propertyName);
71 | #end
72 |
73 | } else {
74 |
75 | value = Reflect.getProperty (target, propertyName);
76 |
77 | }
78 |
79 | return value;
80 |
81 | #else
82 |
83 | return Reflect.field (target, propertyName);
84 |
85 | #end
86 |
87 | }
88 |
89 |
90 | private function ifDefined (value:T, defaultValue:T):T {
91 |
92 | if (value != null) {
93 |
94 | if (!Std.is (value, String) || (Std.is (value, String) && value != cast "")) {
95 |
96 | return value;
97 |
98 | }
99 |
100 | }
101 |
102 | return defaultValue;
103 |
104 | }
105 |
106 |
107 | private function initialize ():Void {
108 |
109 | setMargins ();
110 |
111 | }
112 |
113 |
114 | private function layoutItem (layoutGroup:LayoutGroup):Void {
115 |
116 | switch (verticalLayout) {
117 |
118 | case BOTTOM:
119 |
120 | objectY = layoutGroup.height - objectHeight - marginBottom;
121 |
122 | case CENTER:
123 |
124 | objectY = layoutGroup.height / 2 - objectHeight / 2 + marginTop - marginBottom;
125 |
126 | case STRETCH:
127 |
128 | objectY = marginTop;
129 |
130 | var stretchHeight = layoutGroup.height - marginTop - marginBottom;
131 |
132 | if (stretchHeight < 0) {
133 |
134 | stretchHeight = 0;
135 |
136 | }
137 |
138 | if (rigidVertical && minHeight != null && stretchHeight < minHeight) {
139 |
140 | objectHeight = minHeight;
141 |
142 | } else {
143 |
144 | objectHeight = stretchHeight;
145 |
146 | }
147 |
148 | case TOP:
149 |
150 | objectY = marginTop;
151 |
152 | default:
153 |
154 | }
155 |
156 | switch (horizontalLayout) {
157 |
158 | case CENTER:
159 |
160 | objectX = layoutGroup.width / 2 - objectWidth / 2 + marginLeft - marginRight;
161 |
162 | case LEFT:
163 |
164 | objectX = marginLeft;
165 |
166 | case RIGHT:
167 |
168 | objectX = layoutGroup.width - objectWidth - marginRight;
169 |
170 | case STRETCH:
171 |
172 | objectX = marginLeft;
173 |
174 | var stretchWidth = layoutGroup.width - marginLeft - marginRight;
175 |
176 | if (stretchWidth < 0) {
177 |
178 | stretchWidth = 0;
179 |
180 | }
181 |
182 | if (rigidHorizontal && minWidth != null && stretchWidth < minWidth) {
183 |
184 | objectWidth = minWidth;
185 |
186 | } else {
187 |
188 | objectWidth = stretchWidth;
189 |
190 | }
191 |
192 | default:
193 |
194 | }
195 |
196 | objectX += layoutGroup.x;
197 | objectY += layoutGroup.y;
198 |
199 | }
200 |
201 |
202 | private function refreshSize ():Void {
203 |
204 |
205 |
206 | }
207 |
208 |
209 | private inline function setField (target:Dynamic, propertyName:String, value:Dynamic):Void {
210 |
211 | if (Reflect.hasField (target, propertyName)) {
212 |
213 | #if flash
214 | untyped target[propertyName] = value;
215 | #else
216 | Reflect.setField (target, propertyName, value);
217 | #end
218 |
219 | } else {
220 |
221 | #if (haxe_209 || haxe3)
222 | Reflect.setProperty (target, propertyName, value);
223 | #end
224 |
225 | }
226 |
227 | }
228 |
229 |
230 | public function setMargins (marginTop:Float = 0, marginRight:Float = 0, marginBottom:Float = 0, marginLeft:Float = 0):Void {
231 |
232 | this.marginTop = marginTop;
233 | this.marginRight = marginRight;
234 | this.marginBottom = marginBottom;
235 | this.marginLeft = marginLeft;
236 |
237 | }
238 |
239 |
240 | public function setMinSize (minWidth:Float = 0, minHeight:Float = 0):Void {
241 |
242 | this.minWidth = minWidth;
243 | this.minHeight = minHeight;
244 |
245 | }
246 |
247 |
248 |
249 |
250 | // Get & Set Methods
251 |
252 |
253 |
254 |
255 | private #if (!neko && !js) inline #end function get_objectHeight ():Float {
256 |
257 | return getField (object, "height");
258 |
259 | }
260 |
261 |
262 | private #if (!neko && !js) inline #end function set_objectHeight (value:Float):Float {
263 |
264 | setField (object, "height", value);
265 | return value;
266 |
267 | }
268 |
269 |
270 | private #if (!neko && !js) inline #end function get_objectScaleX ():Float {
271 |
272 | return getField (object, "scaleX");
273 |
274 | }
275 |
276 |
277 | private #if (!neko && !js) inline #end function set_objectScaleX (value:Float):Float {
278 |
279 | setField (object, "scaleX", value);
280 | return value;
281 |
282 | }
283 |
284 |
285 | private #if (!neko && !js) inline #end function get_objectScaleY ():Float {
286 |
287 | return getField (object, "scaleY");
288 |
289 | }
290 |
291 |
292 | private #if (!neko && !js) inline #end function set_objectScaleY (value:Float):Float {
293 |
294 | setField (object, "scaleY", value);
295 | return value;
296 |
297 | }
298 |
299 |
300 | private #if (!neko && !js) inline #end function get_objectWidth ():Float {
301 |
302 | return getField (object, "width");
303 |
304 | }
305 |
306 |
307 | private #if (!neko && !js) inline #end function set_objectWidth (value:Float):Float {
308 |
309 | setField (object, "width", value);
310 | return value;
311 |
312 | }
313 |
314 |
315 | private #if (!neko && !js) inline #end function get_objectX ():Float {
316 |
317 | return getField (object, "x");
318 |
319 | }
320 |
321 |
322 | private #if (!neko && !js) inline #end function set_objectX (value:Float):Float {
323 |
324 | setField (object, "x", value);
325 | return value;
326 |
327 | }
328 |
329 |
330 | private #if (!neko && !js) inline #end function get_objectY ():Float {
331 |
332 | return getField (object, "y");
333 |
334 | }
335 |
336 |
337 | private #if (!neko && !js) inline #end function set_objectY (value:Float):Float {
338 |
339 | setField (object, "y", value);
340 | return value;
341 |
342 | }
343 |
344 |
345 | }
--------------------------------------------------------------------------------
/skylark/layout/LayoutType.hx:
--------------------------------------------------------------------------------
1 | package skylark.layout;
2 |
3 |
4 | enum LayoutType {
5 |
6 | BOTTOM;
7 | CENTER;
8 | LEFT;
9 | NONE;
10 | RIGHT;
11 | STRETCH;
12 | TOP;
13 |
14 | }
--------------------------------------------------------------------------------
/tests/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | report
3 | src
4 | test/ExampleTest.hx
5 | test/TestMain.hx
6 | test/TestSuite.hx
7 |
--------------------------------------------------------------------------------
/tests/.munit:
--------------------------------------------------------------------------------
1 | version=2.1.0
2 | src=test
3 | bin=build
4 | report=report
5 | hxml=test.hxml
6 | classPaths=src
7 |
--------------------------------------------------------------------------------
/tests/test.hxml:
--------------------------------------------------------------------------------
1 | ## Flash 9+
2 | -main TestMain
3 | -lib munit
4 | -lib hamcrest
5 | -lib layout
6 | -cp src
7 |
8 | -cp test
9 | -swf-version 11
10 | -swf build/as3_test.swf
11 |
12 | --next
13 |
14 | ## JavaScript
15 | -main TestMain
16 | -lib munit
17 | -lib hamcrest
18 | -lib layout
19 | -cp src
20 |
21 | -cp test
22 | -js build/js_test.js
23 |
24 | --next
25 |
26 | ## Neko
27 | -main TestMain
28 | -lib munit
29 | -lib hamcrest
30 | -lib layout
31 | -cp src
32 |
33 | -cp test
34 | -neko build/neko_test.n
35 |
36 | --next
37 |
38 | ## CPP
39 | -main TestMain
40 | -lib munit
41 | -lib hamcrest
42 | -lib layout
43 | -cp src
44 |
45 | -cp test
46 | #-D HXCPP_M64
47 | -cpp build/cpp_test
48 |
49 |
50 |
--------------------------------------------------------------------------------
/tests/test/BasicLayoutTest.hx:
--------------------------------------------------------------------------------
1 | package;
2 |
3 |
4 | import skylark.layout.Layout;
5 | import skylark.layout.LayoutItem;
6 | import skylark.layout.LayoutType;
7 | import massive.munit.Assert;
8 |
9 |
10 | class BasicLayoutTest {
11 |
12 |
13 | public static var background:DisplayObject;
14 | public static var logo:DisplayObject;
15 | public static var sidebar:DisplayObject;
16 | public static var footer:DisplayObject;
17 |
18 | private static var layoutHeight = 200;
19 | private static var layoutWidth = 200;
20 |
21 |
22 | @Before public function setup ():Void {
23 |
24 | background = new DisplayObject ();
25 | background.x = 0;
26 | background.y = 0;
27 | background.width = layoutWidth;
28 | background.height = layoutHeight;
29 |
30 | logo = new DisplayObject ();
31 | logo.x = 10;
32 | logo.y = 10;
33 | logo.width = 40;
34 | logo.height = 25;
35 |
36 | sidebar = new DisplayObject ();
37 | sidebar.x = layoutWidth - 60;
38 | sidebar.y = 0;
39 | sidebar.width = 60;
40 | sidebar.height = layoutHeight - 40;
41 |
42 | footer = new DisplayObject ();
43 | footer.x = 0;
44 | footer.y = layoutHeight - 40;
45 | footer.width = layoutWidth;
46 | footer.height = 40;
47 |
48 | }
49 |
50 |
51 | @Test public function testStandard ():Void {
52 |
53 | // Set an exact layout size
54 |
55 | var layout = new Layout (layoutWidth, layoutHeight);
56 |
57 | layout.addItem (new LayoutItem (background, STRETCH, STRETCH));
58 | layout.addItem (new LayoutItem (logo, TOP, LEFT));
59 | layout.addItem (new LayoutItem (sidebar, STRETCH, RIGHT));
60 | layout.addItem (new LayoutItem (footer, BOTTOM, STRETCH));
61 |
62 | var sizesHeight = [ 200, 240, 1370, 1200, 100, 220, 10 ];
63 | var sizesWidth = [ 200, 300, 1200, 1500, 220, 100, 10 ];
64 |
65 | for (i in 0...sizesWidth.length) {
66 |
67 | var width = sizesWidth[i];
68 | var height = sizesHeight[i];
69 |
70 | layout.resize (width, height);
71 |
72 | // Items are rigid horizontal/vertical by default, so the layout should not allow smaller sizes than 200 x 200 (background size)
73 |
74 | if (width < layoutWidth) width = layoutWidth;
75 | if (height < layoutHeight) height = layoutHeight;
76 |
77 | Assert.areEqual (0, background.x);
78 | Assert.areEqual (0, background.y);
79 | Assert.areEqual (width, background.width);
80 | Assert.areEqual (height, background.height);
81 |
82 | Assert.areEqual (10, logo.x);
83 | Assert.areEqual (10, logo.y);
84 | Assert.areEqual (40, logo.width);
85 | Assert.areEqual (25, logo.height);
86 |
87 | Assert.areEqual (width - 60, sidebar.x);
88 | Assert.areEqual (0, sidebar.y);
89 | Assert.areEqual (60, sidebar.width);
90 | Assert.areEqual (height - 40, sidebar.height);
91 |
92 | Assert.areEqual (0, footer.x);
93 | Assert.areEqual (height - 40, footer.y);
94 | Assert.areEqual (width, footer.width);
95 | Assert.areEqual (40, footer.height);
96 |
97 |
98 | }
99 |
100 | }
101 |
102 |
103 | @Test public function testStandardNoInitSize ():Void {
104 |
105 | // Get the init layout size automatically (based on the size of the objects added before resizing)
106 |
107 | var layout = new Layout ();
108 |
109 | layout.addItem (new LayoutItem (background, STRETCH, STRETCH));
110 | layout.addItem (new LayoutItem (logo, TOP, LEFT));
111 | layout.addItem (new LayoutItem (sidebar, STRETCH, RIGHT));
112 | layout.addItem (new LayoutItem (footer, BOTTOM, STRETCH));
113 |
114 | var sizesHeight = [ 200, 240, 1370, 1200, 100, 220, 10 ];
115 | var sizesWidth = [ 200, 300, 1200, 1500, 220, 100, 10 ];
116 |
117 | for (i in 0...sizesWidth.length) {
118 |
119 | var width = sizesWidth[i];
120 | var height = sizesHeight[i];
121 |
122 | layout.resize (width, height);
123 |
124 | // Items are rigid horizontal/vertical by default, so the layout should not allow smaller sizes than 200 x 200 (background size)
125 |
126 | if (width < layoutWidth) width = layoutWidth;
127 | if (height < layoutHeight) height = layoutHeight;
128 |
129 | Assert.areEqual (0, background.x);
130 | Assert.areEqual (0, background.y);
131 | Assert.areEqual (width, background.width);
132 | Assert.areEqual (height, background.height);
133 |
134 | Assert.areEqual (10, logo.x);
135 | Assert.areEqual (10, logo.y);
136 | Assert.areEqual (40, logo.width);
137 | Assert.areEqual (25, logo.height);
138 |
139 | Assert.areEqual (width - 60, sidebar.x);
140 | Assert.areEqual (0, sidebar.y);
141 | Assert.areEqual (60, sidebar.width);
142 | Assert.areEqual (height - 40, sidebar.height);
143 |
144 | Assert.areEqual (0, footer.x);
145 | Assert.areEqual (height - 40, footer.y);
146 | Assert.areEqual (width, footer.width);
147 | Assert.areEqual (40, footer.height);
148 |
149 |
150 | }
151 |
152 | }
153 |
154 |
155 | private inline function testLayout (verticalType:LayoutType, horizontalType:LayoutType, ?pos:haxe.PosInfos) {
156 |
157 | var layout = new Layout (layoutWidth, layoutHeight);
158 |
159 | layout.addItem (new LayoutItem (background, verticalType, horizontalType));
160 | layout.addItem (new LayoutItem (logo, verticalType, horizontalType));
161 | layout.addItem (new LayoutItem (sidebar, verticalType, horizontalType));
162 | layout.addItem (new LayoutItem (footer, verticalType, horizontalType));
163 |
164 | testLayoutSize (layout, verticalType, horizontalType, 200, 200, pos);
165 | testLayoutSize (layout, verticalType, horizontalType, 300, 240, pos);
166 | testLayoutSize (layout, verticalType, horizontalType, 1200, 1370, pos);
167 | testLayoutSize (layout, verticalType, horizontalType, 1500, 1200, pos);
168 | testLayoutSize (layout, verticalType, horizontalType, 220, 1200, pos);
169 | testLayoutSize (layout, verticalType, horizontalType, 100, 220, pos);
170 | testLayoutSize (layout, verticalType, horizontalType, 220, 100, pos);
171 | testLayoutSize (layout, verticalType, horizontalType, 10, 10, pos);
172 |
173 | setup ();
174 |
175 | var layout = new Layout ();
176 |
177 | layout.addItem (new LayoutItem (background, verticalType, horizontalType));
178 | layout.addItem (new LayoutItem (logo, verticalType, horizontalType));
179 | layout.addItem (new LayoutItem (sidebar, verticalType, horizontalType));
180 | layout.addItem (new LayoutItem (footer, verticalType, horizontalType));
181 |
182 | testLayoutSize (layout, verticalType, horizontalType, 200, 200, pos);
183 | testLayoutSize (layout, verticalType, horizontalType, 300, 240, pos);
184 | testLayoutSize (layout, verticalType, horizontalType, 1200, 1370, pos);
185 | testLayoutSize (layout, verticalType, horizontalType, 1500, 1200, pos);
186 | testLayoutSize (layout, verticalType, horizontalType, 220, 1200, pos);
187 | testLayoutSize (layout, verticalType, horizontalType, 100, 220, pos);
188 | testLayoutSize (layout, verticalType, horizontalType, 220, 100, pos);
189 | testLayoutSize (layout, verticalType, horizontalType, 10, 10, pos);
190 |
191 | }
192 |
193 |
194 | private inline function testLayoutSize (layout:Layout, verticalType:LayoutType, horizontalType:LayoutType, width:Float, height:Float, ?pos:haxe.PosInfos) {
195 |
196 | layout.resize (width, height);
197 |
198 | if (width < layoutWidth) width = layoutWidth;
199 | if (height < layoutHeight) height = layoutHeight;
200 |
201 | var scaleWidth = (horizontalType == STRETCH) ? width : layoutWidth;
202 | var scaleHeight = (verticalType == STRETCH) ? height : layoutHeight;
203 |
204 | var offsetY = switch (verticalType) {
205 |
206 | case CENTER: (height / 2) - (layoutHeight / 2);
207 | case BOTTOM: height - layoutHeight;
208 | default: 0;
209 |
210 | }
211 |
212 | var offsetX = switch (horizontalType) {
213 |
214 | case CENTER: (width / 2) - (layoutWidth / 2);
215 | case RIGHT: width - layoutWidth;
216 | default: 0;
217 |
218 | }
219 |
220 | Assert.areEqual (offsetX, background.x, pos);
221 | Assert.areEqual (offsetY, background.y, pos);
222 | Assert.areEqual (scaleWidth, background.width, pos);
223 | Assert.areEqual (scaleHeight, background.height, pos);
224 |
225 | Assert.areEqual (offsetX + 10, logo.x, pos);
226 | Assert.areEqual (offsetY + 10, logo.y, pos);
227 | Assert.areEqual (scaleWidth - layoutWidth + 40, logo.width, pos);
228 | Assert.areEqual (scaleHeight - layoutHeight + 25, logo.height, pos);
229 |
230 | Assert.areEqual (offsetX + layoutWidth - 60, sidebar.x, pos);
231 | Assert.areEqual (offsetY, sidebar.y, pos);
232 | Assert.areEqual (scaleWidth - layoutWidth + 60, sidebar.width, pos);
233 | Assert.areEqual (scaleHeight - 40, sidebar.height, pos);
234 |
235 | Assert.areEqual (offsetX, footer.x, pos);
236 | Assert.areEqual (offsetY + layoutHeight - 40, footer.y, pos);
237 | Assert.areEqual (scaleWidth, footer.width, pos);
238 | Assert.areEqual (scaleHeight - layoutHeight + 40, footer.height, pos);
239 |
240 | //Assert.areEqual (offsetX, background.x);
241 | //Assert.areEqual (offsetY, background.y);
242 | //Assert.areEqual (scaleWidth, background.width);
243 | //Assert.areEqual (scaleHeight, background.height);
244 | //
245 | //Assert.areEqual (offsetX + 10, logo.x);
246 | //Assert.areEqual (offsetY + 10, logo.y);
247 | //Assert.areEqual (scaleWidth - layoutWidth + 40, logo.width);
248 | //Assert.areEqual (scaleHeight - layoutHeight + 25, logo.height);
249 | //
250 | //Assert.areEqual (offsetX + layoutWidth - 60, sidebar.x);
251 | //Assert.areEqual (offsetY, sidebar.y);
252 | //Assert.areEqual (scaleWidth - layoutWidth + 60, sidebar.width);
253 | //Assert.areEqual (scaleHeight - 40, sidebar.height);
254 | //
255 | //Assert.areEqual (offsetX, footer.x);
256 | //Assert.areEqual (offsetY + layoutHeight - 40, footer.y);
257 | //Assert.areEqual (scaleWidth, footer.width);
258 | //Assert.areEqual (scaleHeight - layoutHeight + 40, footer.height);
259 |
260 | }
261 |
262 |
263 | @Test public function testTopLeft ():Void {
264 |
265 | testLayout (TOP, LEFT);
266 |
267 | }
268 |
269 |
270 | @Test public function testTopCenter ():Void {
271 |
272 | testLayout (TOP, CENTER);
273 |
274 | }
275 |
276 |
277 | @Test public function testTopRight ():Void {
278 |
279 | testLayout (TOP, RIGHT);
280 |
281 | }
282 |
283 |
284 | @Test public function testCenterLeft ():Void {
285 |
286 | testLayout (CENTER, LEFT);
287 |
288 | }
289 |
290 |
291 | @Test public function testCenterCenter ():Void {
292 |
293 | testLayout (CENTER, CENTER);
294 |
295 | }
296 |
297 |
298 | @Test public function testCenterRight ():Void {
299 |
300 | testLayout (CENTER, RIGHT);
301 |
302 | }
303 |
304 |
305 | @Test public function testBottomLeft ():Void {
306 |
307 | testLayout (BOTTOM, LEFT);
308 |
309 | }
310 |
311 |
312 | @Test public function testBottomCenter ():Void {
313 |
314 | testLayout (BOTTOM, CENTER);
315 |
316 | }
317 |
318 |
319 | @Test public function testBottomRight ():Void {
320 |
321 | testLayout (BOTTOM, RIGHT);
322 |
323 | }
324 |
325 |
326 | @Test public function testStretchLeft ():Void {
327 |
328 | testLayout (STRETCH, LEFT);
329 |
330 | }
331 |
332 |
333 | @Test public function testStretchCenter ():Void {
334 |
335 | testLayout (STRETCH, CENTER);
336 |
337 | }
338 |
339 |
340 | @Test public function testStretchRight ():Void {
341 |
342 | testLayout (STRETCH, RIGHT);
343 |
344 | }
345 |
346 |
347 | @Test public function testStretchStretch ():Void {
348 |
349 | testLayout (STRETCH, STRETCH);
350 |
351 | }
352 |
353 |
354 | @Test public function testTopStretch ():Void {
355 |
356 | testLayout (TOP, STRETCH);
357 |
358 | }
359 |
360 |
361 | @Test public function testCenterStretch ():Void {
362 |
363 | testLayout (CENTER, STRETCH);
364 |
365 | }
366 |
367 |
368 | @Test public function testBottomStretch ():Void {
369 |
370 | testLayout (BOTTOM, STRETCH);
371 |
372 | }
373 |
374 |
375 | @Test public function testNoneLeft ():Void {
376 |
377 | testLayout (NONE, LEFT);
378 |
379 | }
380 |
381 |
382 | @Test public function testNoneCenter ():Void {
383 |
384 | testLayout (NONE, CENTER);
385 |
386 | }
387 |
388 |
389 | @Test public function testNoneRight ():Void {
390 |
391 | testLayout (NONE, RIGHT);
392 |
393 | }
394 |
395 |
396 | @Test public function testNoneStretch ():Void {
397 |
398 | testLayout (NONE, STRETCH);
399 |
400 | }
401 |
402 |
403 | @Test public function testNoneNone ():Void {
404 |
405 | testLayout (NONE, NONE);
406 |
407 | }
408 |
409 |
410 | @Test public function testStretchNone ():Void {
411 |
412 | testLayout (STRETCH, NONE);
413 |
414 | }
415 |
416 |
417 | @Test public function testTopNone ():Void {
418 |
419 | testLayout (TOP, NONE);
420 |
421 | }
422 |
423 |
424 | @Test public function testCenterNone ():Void {
425 |
426 | testLayout (CENTER, NONE);
427 |
428 | }
429 |
430 |
431 | @Test public function testBottomNone ():Void {
432 |
433 | testLayout (BOTTOM, NONE);
434 |
435 | }
436 |
437 |
438 | }
439 |
440 |
441 | private class DisplayObject {
442 |
443 |
444 | public var x:Float;
445 | public var y:Float;
446 | public var width:Float;
447 | public var height:Float;
448 |
449 |
450 | public function new () {
451 |
452 |
453 |
454 | }
455 |
456 |
457 | }
--------------------------------------------------------------------------------
/tests/test/GroupTest.hx:
--------------------------------------------------------------------------------
1 | package;
2 |
3 |
4 | import skylark.layout.Layout;
5 | import skylark.layout.LayoutGroup;
6 | import skylark.layout.LayoutItem;
7 | import skylark.layout.LayoutType;
8 | import massive.munit.Assert;
9 |
10 | @:access(skylark.layout)
11 |
12 |
13 | class GroupTest {
14 |
15 |
16 | public static var background:DisplayObject;
17 | public static var logo:DisplayObject;
18 | public static var sidebar:DisplayObject;
19 | public static var footer:DisplayObject;
20 |
21 | private static var layoutHeight = 200;
22 | private static var layoutWidth = 200;
23 |
24 |
25 | @Before public function setup ():Void {
26 |
27 | background = new DisplayObject ();
28 | background.x = 0;
29 | background.y = 0;
30 | background.width = layoutWidth;
31 | background.height = layoutHeight;
32 |
33 | logo = new DisplayObject ();
34 | logo.x = 10;
35 | logo.y = 10;
36 | logo.width = 40;
37 | logo.height = 25;
38 |
39 | sidebar = new DisplayObject ();
40 | sidebar.x = layoutWidth - 60;
41 | sidebar.y = 0;
42 | sidebar.width = 60;
43 | sidebar.height = layoutHeight - 40;
44 |
45 | footer = new DisplayObject ();
46 | footer.x = 0;
47 | footer.y = layoutHeight - 40;
48 | footer.width = layoutWidth;
49 | footer.height = 40;
50 |
51 | }
52 |
53 |
54 | private inline function testLayout (verticalType:LayoutType, horizontalType:LayoutType, ?pos:haxe.PosInfos) {
55 |
56 | var layout = new Layout (layoutWidth, layoutHeight);
57 | var layoutGroup = new LayoutGroup (STRETCH, STRETCH);
58 |
59 | layoutGroup.width = layoutWidth;
60 | layoutGroup.height = layoutHeight;
61 |
62 | layoutGroup.addItem (new LayoutItem (background, verticalType, horizontalType));
63 | layoutGroup.addItem (new LayoutItem (logo, verticalType, horizontalType));
64 | layoutGroup.addItem (new LayoutItem (sidebar, verticalType, horizontalType));
65 | layoutGroup.addItem (new LayoutItem (footer, verticalType, horizontalType));
66 |
67 | layout.addItem (layoutGroup);
68 |
69 | testLayoutSize (layout, verticalType, horizontalType, 200, 200, pos);
70 | testLayoutSize (layout, verticalType, horizontalType, 300, 240, pos);
71 | testLayoutSize (layout, verticalType, horizontalType, 1200, 1370, pos);
72 | testLayoutSize (layout, verticalType, horizontalType, 1500, 1200, pos);
73 | testLayoutSize (layout, verticalType, horizontalType, 220, 1200, pos);
74 | testLayoutSize (layout, verticalType, horizontalType, 100, 220, pos);
75 | testLayoutSize (layout, verticalType, horizontalType, 220, 100, pos);
76 | testLayoutSize (layout, verticalType, horizontalType, 10, 10, pos);
77 |
78 | setup ();
79 |
80 | var layout = new Layout ();
81 | var layoutGroup = new LayoutGroup (STRETCH, STRETCH);
82 |
83 | layoutGroup.addItem (new LayoutItem (background, verticalType, horizontalType));
84 | layoutGroup.addItem (new LayoutItem (logo, verticalType, horizontalType));
85 | layoutGroup.addItem (new LayoutItem (sidebar, verticalType, horizontalType));
86 | layoutGroup.addItem (new LayoutItem (footer, verticalType, horizontalType));
87 |
88 | layout.addItem (layoutGroup);
89 |
90 | testLayoutSize (layout, verticalType, horizontalType, 200, 200, pos);
91 | testLayoutSize (layout, verticalType, horizontalType, 300, 240, pos);
92 | testLayoutSize (layout, verticalType, horizontalType, 1200, 1370, pos);
93 | testLayoutSize (layout, verticalType, horizontalType, 1500, 1200, pos);
94 | testLayoutSize (layout, verticalType, horizontalType, 220, 1200, pos);
95 | testLayoutSize (layout, verticalType, horizontalType, 100, 220, pos);
96 | testLayoutSize (layout, verticalType, horizontalType, 220, 100, pos);
97 | testLayoutSize (layout, verticalType, horizontalType, 10, 10, pos);
98 |
99 | }
100 |
101 |
102 | private inline function testLayoutSize (layout:Layout, verticalType:LayoutType, horizontalType:LayoutType, width:Float, height:Float, ?pos:haxe.PosInfos) {
103 |
104 | layout.resize (width, height);
105 |
106 | if (width < layoutWidth) width = layoutWidth;
107 | if (height < layoutHeight) height = layoutHeight;
108 |
109 | var scaleWidth = (horizontalType == STRETCH) ? width : layoutWidth;
110 | var scaleHeight = (verticalType == STRETCH) ? height : layoutHeight;
111 |
112 | var offsetY = switch (verticalType) {
113 |
114 | case CENTER: (height / 2) - (layoutHeight / 2);
115 | case BOTTOM: height - layoutHeight;
116 | default: 0;
117 |
118 | }
119 |
120 | var offsetX = switch (horizontalType) {
121 |
122 | case CENTER: (width / 2) - (layoutWidth / 2);
123 | case RIGHT: width - layoutWidth;
124 | default: 0;
125 |
126 | }
127 |
128 | //Assert.areEqual (offsetX, background.x, pos);
129 | //Assert.areEqual (offsetY, background.y, pos);
130 | //Assert.areEqual (scaleWidth, background.width, pos);
131 | //Assert.areEqual (scaleHeight, background.height, pos);
132 | //
133 | //Assert.areEqual (offsetX + 10, logo.x, pos);
134 | //Assert.areEqual (offsetY + 10, logo.y, pos);
135 | //Assert.areEqual (scaleWidth - layoutWidth + 40, logo.width, pos);
136 | //Assert.areEqual (scaleHeight - layoutHeight + 25, logo.height, pos);
137 | //
138 | //Assert.areEqual (offsetX + layoutWidth - 60, sidebar.x, pos);
139 | //Assert.areEqual (offsetY, sidebar.y, pos);
140 | //Assert.areEqual (scaleWidth - layoutWidth + 60, sidebar.width, pos);
141 | //Assert.areEqual (scaleHeight - 40, sidebar.height, pos);
142 | //
143 | //Assert.areEqual (offsetX, footer.x, pos);
144 | //Assert.areEqual (offsetY + layoutHeight - 40, footer.y, pos);
145 | //Assert.areEqual (scaleWidth, footer.width, pos);
146 | //Assert.areEqual (scaleHeight - layoutHeight + 40, footer.height, pos);
147 |
148 | Assert.areEqual (offsetX, background.x);
149 | Assert.areEqual (offsetY, background.y);
150 | Assert.areEqual (scaleWidth, background.width);
151 | Assert.areEqual (scaleHeight, background.height);
152 |
153 | Assert.areEqual (offsetX + 10, logo.x);
154 | Assert.areEqual (offsetY + 10, logo.y);
155 | Assert.areEqual (scaleWidth - layoutWidth + 40, logo.width);
156 | Assert.areEqual (scaleHeight - layoutHeight + 25, logo.height);
157 |
158 | Assert.areEqual (offsetX + layoutWidth - 60, sidebar.x);
159 | Assert.areEqual (offsetY, sidebar.y);
160 | Assert.areEqual (scaleWidth - layoutWidth + 60, sidebar.width);
161 | Assert.areEqual (scaleHeight - 40, sidebar.height);
162 |
163 | Assert.areEqual (offsetX, footer.x);
164 | Assert.areEqual (offsetY + layoutHeight - 40, footer.y);
165 | Assert.areEqual (scaleWidth, footer.width);
166 | Assert.areEqual (scaleHeight - layoutHeight + 40, footer.height);
167 |
168 | }
169 |
170 |
171 | @Test public function testTopLeft ():Void {
172 |
173 | testLayout (TOP, LEFT);
174 |
175 | }
176 |
177 |
178 | @Test public function testTopCenter ():Void {
179 |
180 | testLayout (TOP, CENTER);
181 |
182 | }
183 |
184 |
185 | @Test public function testTopRight ():Void {
186 |
187 | testLayout (TOP, RIGHT);
188 |
189 | }
190 |
191 |
192 | @Test public function testCenterLeft ():Void {
193 |
194 | testLayout (CENTER, LEFT);
195 |
196 | }
197 |
198 |
199 | @Test public function testCenterCenter ():Void {
200 |
201 | testLayout (CENTER, CENTER);
202 |
203 | }
204 |
205 |
206 | @Test public function testCenterRight ():Void {
207 |
208 | testLayout (CENTER, RIGHT);
209 |
210 | }
211 |
212 |
213 | @Test public function testBottomLeft ():Void {
214 |
215 | testLayout (BOTTOM, LEFT);
216 |
217 | }
218 |
219 |
220 | @Test public function testBottomCenter ():Void {
221 |
222 | testLayout (BOTTOM, CENTER);
223 |
224 | }
225 |
226 |
227 | @Test public function testBottomRight ():Void {
228 |
229 | testLayout (BOTTOM, RIGHT);
230 |
231 | }
232 |
233 |
234 | @Test public function testStretchLeft ():Void {
235 |
236 | testLayout (STRETCH, LEFT);
237 |
238 | }
239 |
240 |
241 | @Test public function testStretchCenter ():Void {
242 |
243 | testLayout (STRETCH, CENTER);
244 |
245 | }
246 |
247 |
248 | @Test public function testStretchRight ():Void {
249 |
250 | testLayout (STRETCH, RIGHT);
251 |
252 | }
253 |
254 |
255 | @Test public function testStretchStretch ():Void {
256 |
257 | testLayout (STRETCH, STRETCH);
258 |
259 | }
260 |
261 |
262 | @Test public function testTopStretch ():Void {
263 |
264 | testLayout (TOP, STRETCH);
265 |
266 | }
267 |
268 |
269 | @Test public function testCenterStretch ():Void {
270 |
271 | testLayout (CENTER, STRETCH);
272 |
273 | }
274 |
275 |
276 | @Test public function testBottomStretch ():Void {
277 |
278 | testLayout (BOTTOM, STRETCH);
279 |
280 | }
281 |
282 |
283 | @Test public function testNoneLeft ():Void {
284 |
285 | testLayout (NONE, LEFT);
286 |
287 | }
288 |
289 |
290 | @Test public function testNoneCenter ():Void {
291 |
292 | testLayout (NONE, CENTER);
293 |
294 | }
295 |
296 |
297 | @Test public function testNoneRight ():Void {
298 |
299 | testLayout (NONE, RIGHT);
300 |
301 | }
302 |
303 |
304 | @Test public function testNoneStretch ():Void {
305 |
306 | testLayout (NONE, STRETCH);
307 |
308 | }
309 |
310 |
311 | @Test public function testNoneNone ():Void {
312 |
313 | testLayout (NONE, NONE);
314 |
315 | }
316 |
317 |
318 | @Test public function testStretchNone ():Void {
319 |
320 | testLayout (STRETCH, NONE);
321 |
322 | }
323 |
324 |
325 | @Test public function testTopNone ():Void {
326 |
327 | testLayout (TOP, NONE);
328 |
329 | }
330 |
331 |
332 | @Test public function testCenterNone ():Void {
333 |
334 | testLayout (CENTER, NONE);
335 |
336 | }
337 |
338 |
339 | @Test public function testBottomNone ():Void {
340 |
341 | testLayout (BOTTOM, NONE);
342 |
343 | }
344 |
345 |
346 | }
347 |
348 |
349 | private class DisplayObject {
350 |
351 |
352 | public var x:Float;
353 | public var y:Float;
354 | public var width:Float;
355 | public var height:Float;
356 |
357 |
358 | public function new () {
359 |
360 |
361 |
362 | }
363 |
364 |
365 | }
--------------------------------------------------------------------------------