Layout library, using of LayoutGroup

How to right use LayoutGroup? I tried this:

// Base items
var timerViewItem = new LayoutItem(timerView, LayoutType.TOP, LayoutType.CENTER, true, true);
timerViewItem.setMargins(5, 0, 0, 0);

// button group
var buttonsGroup = new LayoutGroup(LayoutType.BOTTOM, LayoutType.CENTER);
buttonsGroup.width = musicButton.size * 3.2;
buttonsGroup.height = musicButton.size;
buttonsGroup.addItem(new LayoutItem(musicButton, LayoutType.CENTER, LayoutType.LEFT));
buttonsGroup.addItem(new LayoutItem(soundButton, LayoutType.CENTER, LayoutType.RIGHT));

var gameOverlayLayout = new Layout();
gameOverlayLayout.addItem(timerViewItem);

// add group as item because LayoutGroup extends LayoutItem
gameOverlayLayout.addItem(buttonsGroup);

// error here :
gameOverlayLayout.layoutItems();

and got this:

[Fault] exception, information=ReferenceError: Error #1056: Cannot create property y on layout.LayoutGroup.

SimpleSWFLayout sample also does not work - I got white screen.

OpenFl 2.2.8 (dev)
Lime 2.1.3 (dev)
SWFLibrary 1.7.7
Haxe - some of dev builds

Would something like this work?

var timerViewItem = new LayoutItem(timerView, LayoutType.TOP, LayoutType.CENTER, true, true);
timerViewItem.setMargins(5, 0, 0, 0);

var buttonsGroup = new LayoutGroup(LayoutType.BOTTOM, LayoutType.CENTER);
buttonsGroup.addItem(new LayoutItem(musicButton, LayoutType.CENTER, LayoutType.LEFT));
buttonsGroup.addItem(new LayoutItem(soundButton, LayoutType.CENTER, LayoutType.RIGHT));

var gameOverlayLayout = new Layout (1024, 768);
gameOverlayLayout.addItem(timerViewItem);
gameOverlayLayout.addItem(buttonsGroup);

// error here :
gameOverlayLayout.resize (800, 600);

I’m not fully sure how setting the width and height manually would affect things, I also am not sure about setting margins, both of these may be fine, or not – most of the time, the layout already has all the positions configured to an original display size.

The key thing I see is that “layoutItems” is not meant to be called directly, usually. I’d recommend calling resize on the top Layout object

Without this I don’t get what I want. Without this all my items haves 0;0 position and changes their position only if the new size of stage more than default. But if I call layoutItems() all my items gets position on top, bottom, left or any other part of the screen.

LayoutGroup haves property for size and position so I thought it is like a “container” which I can place like I want. What is the purpose of this class? Is it allow to use for groups creation outside Layout or is it only for internal use?

Alright, so the initial workflow for the Layout library is as follows:

You already have everything positioned as you want for a specific size, let’s say 800 x 600. The x and y values are perfect. You create a new Layout (800, 600); then specify the layout items as you would like them to adjust if the size changes. Next, you call layout.resize as needed for it to adjust for larger or smaller sizes.

I recently made improvements that should allow the Layout class to work without specifying an initial width or height. Instead, it will use the first resize call to determine the initial size. In fact, now that I think of it, this might be why nothing appears to happen – try setting the width and height, or try calling resize at least twice.

The idea of a LayoutGroup is to align a set of layout items separately. For example, if you had a content area that centers, you could do a LayoutGroup that is centered, but then within the group you could do top left, top right, stretch, etc – and the content within remains constrained within the size of the group, rather than the full layout size.

I’ve only begun to do unit tests to ensure that everything works as desired, but this has already flushed out a few bugs. The original code was written 6 years ago or so, so I’m still (in little ways) discovering again some parts of the methodology

If you’re already rewriting the library, would you be interested in merging mine? Sample usage:

//Optional:
Layout.stageLayout = new Layout(new Area(0, 0, 800, 600));

//You can position and resize objects with respect to the stage:
mySprite.fillWidth(); //Match the stage width.
mySprite.setHeight(299); //Just under half the stage height.
mySprite.setY(50); //A little ways down from the top.
mySprite.alignRight(); //Align to the right edge.

//...or with respect to each other:
mySprite2.below(mySprite, 5); //Put it beneath the other, leaving a small margin.
mySprite2.alignWith(mySprite, RIGHT); //Make the right edges line up.
mySprite2.matchHeight(mySprite); //Make it the same height.

And there’s even support for something akin to LayoutGroup. Still a work in progress, though.

//A Layout covering everything left of mySprite2 and below mySprite.
var subLayout:Layout = Layout.stageLayout.partition(null, mySprite2, mySprite, null);

//To make a sprite take up that whole partition, minus a small margin:
mySprite3.fillWidth(5, subLayout);
mySprite3.fillHeight(5, subLayout);
mySprite3.centerX(subLayout);
mySprite3.centerY(subLayout);

I think those are interesting ideas, it sounds there are at least two use-cases – one at runtime (to dynamically position) and other to work with an existing layout, and to describe how to make it fluid.

The Layout library was built with pre-setup SWC assets in Flash, now I use it with SWF assets from Flash again, but perhaps the workflow for setting up a live layout should be improved, which seems to be how you are using yours?

Yeah, that’s how I’m using mine. And I thought mine supported most of the same functionality as yours, but looking at SimpleSWFLayout again I see what you mean about pre-built layouts.

I’ll see if I can add that functionality.

Done!

To make SimpleSWFLayout work with this library, replace Main.hx with this:

package;

import layout.Layout;
import openfl.Assets;
import openfl.display.DisplayObject;
import openfl.display.Sprite;

using layout.StaticLayout;

class Main extends Sprite {
    
    public function new () {
        
        super ();
        
        var clip = Assets.getMovieClip ("layout:Layout");
        addChild (clip);
        
        Layout.setStageBaseDimensions(Std.int(clip.width), Std.int(clip.height));
        
        var background:DisplayObject = clip.getChildByName ("Background");
        background.stretchX ();
        background.stretchY ();
        
        var header:DisplayObject = clip.getChildByName ("Header");
        header.stretchX ();
        header.stickToTop ();
        
        var column:DisplayObject = clip.getChildByName ("Column");
        column.stickToLeft ();
        column.stretchY ();
        
    }
    
}

By the way, when you download the library, make sure to rename it advlayout or advanced-layout or something to avoid collisions.