Layouts – preview & discussion… anyone? please ;)

Let me start by talking about my first run at implementing an integrated Layout solution.

  1. Layout is an interface, so if the DefaultLayout class doesn’t do what you like, you can always write your own.
  2. All Elements can contain their own layout
  3. All Elements also have an instance of LayoutHints for individually adjusting components if you aren’t satisfied with the Layout positioning.
  4. The default Layout has 3 modes to choose from aside from the GUI libraries default absolute positioning… these are:
    — Vertical - positions elements on after another along the y axis
    — Horizontal - positions elements on after another along the x axis until the next element would push past it’s parent bounds and the line wraps
    — Flow - A combination of vertical and horizontal, using LayoutHints to allow you advanceY + set # of line feeds
  5. Layouts have margins and padding settings.
  6. Element now has a centerToParentV and centerToParentH method

Here is a simple example of usage:

[java]
Screen screen = new Screen(this);
guiNode.addControl(screen);

DefaultLayout layout = new DefaultLayout(screen);
layout.setMode(Layout.LayoutMode.Vertical);
layout.setPadding(20);
layout.setMargins(30,30);

Panel p = new Panel(screen, Vector2f.ZERO, new Vector2f(200,500));
p.setLayout(layout);

for (int i = 0; i < 6; i++) {
ButtonAdapter b = new ButtonAdapter(screen, Vector2f.ZERO);
b.setText(String.valueOf(i));
p.addChild(b);
}

p.getLayout().layoutChildren();
p.sizeToContent();
screen.addElement§;
p.centerToParent();
[/java]

And here is the results:

Here is the same test with different margins and padding:

Here is a test of Horizontal mode:

Different margins and padding:

And most importantly, here is the Flow layout results with a complex set of components:

Now for the discussion part!

I have only implemented positioning, however I would like the Layouts to be able to set hints for how to size components as apposed to always using absolute dimensions. Can someone (or multiple someones) talk to me about approaches?

6 Likes

This is completely awesome news, I am very glad you are adding layout management XD

The basic approach I took for sizing was modelled roughly after Swing’s.

  • All components have min/max/preferred size. Preferred size is usually where the hard work is done. Tonegodguis default sizes were a problem for me here. What I generally do is use a special constant to pass in as the default size. The layout managers see this an now they should instead use preferred size. .
  • All layouts also provide min/max/preferred sizes. This is calculated from the components that are using that layout.
  • Laying out starts at the root component, and drills down into each child. If it’s a container, it’s layout will be calculated and so on. So, a containers size is set first, then elements are sized and position within that layout.
  • All controls have their scaling and docking turned off. I consider these two features Tonegodguis basic layout system that I want to override. Each individual control generally has it’s own specific layout manager to position and size stuff. If I don’t turn these off, you get tiny “jumps” as the two layout systems compete with each other.

The main problem my current approach has is when to actually ‘layout’. Currently it does it on every single addChild/removeChild, which can be incredibly wasteful.

Your mention of padding / margins is welcome too. I currently use resize borders/borders (the two always slightly confused me) as a sort of margin. Having something built in would be so useful.

RR

2 Likes

I think here is the place to share my opinion about layouting, in Tonegod GUI and in general.

The problem of Layout and Element is like the relation of Entity and Context. One define another. Element size depend on its Layout data, the Layout progress depend on its run through Elements.

Common GUI system let the Element “define” and “active” its own layout. That’s it has exactly one and only one layout of its own. And the tree of elements refesh in layout in an order, usually and mostly top-down, from container to children. Some of the container sizing may require a pack of its children sizes, so this one is the special case that the order is reverse.

What I did in my GUI system, called SpriteGUI (it’s actually generic enough to map to Swing, SWT, HTML, NiftyGUI and Tonegod…) is to separate layouting (along with other representations), behaviors (interactions) and actually data. So what we call “refreshing operation” actually happen in layouting, interactions and data changing separately, even if it’s happen in underlying system (tonegod gui for example) at once. The jobs are fully concurrent enable progresses, the order also can be defined as Nested-order (like in layouting), Mapping order (like in bean mapping to UI), incremental-order (do operation in one that is current node and floodfill, just care about speed, not the display)…

About layouting only. Layouting job should work in its data, and as i said before an Layout is a Context for Element, Element’s behavior depends in the Context. So Element should not have only ONE layout data, but many depends in the Layout which currently active.

For runtime, the computed value of size and position can be persisted as object attribute. Of course there should be a size and pos Vector2f! But the operation of Layouting should be taken out of Element awareness, or at least minimum.

Now the reason for doing all the verbose “abstract” stuff I mention above … (Wait for it) … is to reuse!!! You can see it transfer from a Strict order Element system (Element nested in strict order), into a Relative free order Component system. Or even later a Component based sizing system… The further you go along the way, the more “data alike” your code and data should become and later the reusable.

One last note, the layouting job (and stylizing) is actually quite a boring job (for poor web dev & artist) , that’s why try to keep the code precise and lean as possible. That’s the reason why we already have CSS, JQuery, JESS … and they still try to minimize it more and more). For example:

Layout.$(element).size(100,100).pos(100,100);
compared to
Layout.layoutElement(element).setSize(100,100).setPos(100,100).revalidateLayout();

is like a wet dream for those artist and web dev, and they will be thankful for it.

I share my opinion and hope for some feedback also.

2 Likes

Thanks for the input you two… I think I am going to need to reread these more than the couple times I have already and let it set in while my brain tries to wrap around all of the pros & cons of the approaches.

In the meantime (because I am fairly fried today), I ran some test with the current implementation of postitional portion of the Default Layout by:

  1. Adding a ControlUtil class that returns a couple of standard Elements, like container… I finally got sick enough of typing the following
    [java]
    Element content = new Element screen, UIDUtil.getUID(), Vector2f.ZERO, Vector2f.ZERO, Vector4f.ZERO, null);
    content.setAsContainerOnly();
    [/java]
    to provide a static utility class for doing these sorts of things.
  2. Updated the Window class with a content area and made use of Layout to position the drag bar/content area.
  3. Added an addWindowContent method
  4. Added a method to set the content area’s layout
  5. Added a pack() method to layout the windows content, and then size the window based on this.

This usage isn’t enforced, but I’ll likely keep the updated version, as after playing with this and adding a series of nested containers with different layouts to the window content area with various layouts… it worked famously. And made stuff sooooo much easier.

Here is the example code:

[java]
Screen screen = new Screen(this);
guiNode.addControl(screen);

Window win = new Window(screen, Vector2f.ZERO);

DefaultLayout layout = new DefaultLayout(screen);
layout.setMode(Layout.LayoutMode.Horizontal);
layout.setMargins(10,10);
layout.setPadding(10);
win.setContentLayout(layout);

DefaultLayout pLayout = new DefaultLayout(screen);
pLayout.setMode(Layout.LayoutMode.Vertical);
pLayout.setMargins(0,0);
pLayout.setPadding(5);

Element p1 = ControlUtil.getContainer(screen);
p1.setLayout(pLayout.clone());

Element p2 = ControlUtil.getContainer(screen);
p2.setLayout(pLayout.clone());

Element p3 = ControlUtil.getContainer(screen);
p3.setLayout(pLayout.clone());

for (int i = 0; i < 6; i++) {
ButtonAdapter b = new ButtonAdapter(screen, Vector2f.ZERO);
b.setText(String.valueOf(i));
p1.addChild(b);
}

for (int i = 0; i < 3; i++) {
ButtonAdapter b = new ButtonAdapter(screen, Vector2f.ZERO);
b.setText(String.valueOf(i));
p2.addChild(b);
}

for (int i = 0; i < 8; i++) {
ButtonAdapter b = new ButtonAdapter(screen, Vector2f.ZERO);
b.setText(String.valueOf(i));
p3.addChild(b);
}

p1.getLayout().layoutChildren();
p1.sizeToContent();

p2.getLayout().layoutChildren();
p2.sizeToContent();

p3.getLayout().layoutChildren();
p3.sizeToContent();

win.addWindowContent(p1);
win.addWindowContent(p2);
win.addWindowContent(p3);

win.pack();

screen.addElement(win);
[/java]

And the results:

Sorry, brain not working this morning. If it suddenly starts somewhat working and by some additional miracle manages to give birth to a viable idea, I’ll keep you in the loop… lucky you lol.
Been frying my last neurones with rotation problems for 10 days now XD, so didn’t play with the new toys, yet. But one day, they shall be mine.

To give an idea of what a wonderful tool this brain is:

  • I thought until yesterday that slerp gave back the rotation from one to another. I even tested that assumption and seem to have botched that test too.
  • found a couple quaternion.add(quaternionb)… instead of mult XD. If I ever put my hands on a mathematician Imma gonna strangle it. Teh hell we need to mult quaternions to add their rotations, while vectors use add XD. Anybody thought of the idiots and people with poor focusing skills?

Anyway, great news about that layout thingy!

1 Like
@loopies said: Sorry, brain not working this morning. If it suddenly starts somewhat working and by some additional miracle manages to give birth to a viable idea, I'll keep you in the loop... lucky you lol. Been frying my last neurones with rotation problems for 10 days now XD, so didn't play with the new toys, yet. But one day, they shall be mine.

To give an idea of what a wonderful tool this brain is:

  • I thought until yesterday that slerp gave back the rotation from one to another. I even tested that assumption and seem to have botched that test too.
  • found a couple quaternion.add(quaternionb)… instead of mult XD. If I ever put my hands on a mathematician Imma gonna strangle it. Teh hell we need to mult quaternions to add their rotations, while vectors use add XD. Anybody thought of the idiots and people with poor focusing skills?

If it helps… do you add a Matrix to another Matrix to compose them? (hint: no) Do you add a vector to a quaternion to transform it? (hint: no) Do you add a vector to a matrix to transform it? (hint: no)

Lesson from the above: adding is never the same thing as transforming. Adding two vectors together is not transforming them. It’s adding them together. Consequently, adding two quaternions together is not transforming them, either. It’s adding them together. If you want to transform one quaternion by another then you multiply them… just like every single other form of transformation, really.

1 Like

Well haha… I’ve kept away from matrices for now :D. I’ve been reading on them, but not ready to use them yet :).

Yah, I totally understand that it makes sense… was totally for the fun, not a rant. But it sure doesn’t help people with poor focusing… I mean, picture a stone age man… “me wanna rotate that stone by 30° and then rotate it again by 45° to get a total rotation of (30+45) 75°”… and boom, an incorrect result, not too easy to spot ^^.

Ok… after giving the above a little time to settle, I wanted to explain how I would like things to work, as I would like Layouts to override (or help determine) certain attribute of the child Elements.

LayoutHints should contain fill properties, like:
— * (Fill the remainder of X or Y)
— % (Fill a percentage of X or Y)
— Docking behavior… NW, NE, SW, SE

Sooo… an enum that looks like:

Fill,
Percent,
Absolute

A property for X & Y behavior --Absolute being the default.
And a default Docking property

I don’t think it needs to go much past this, as Absolute Layouts (the default behavior of the library) covers everything else.

It seems that allowing the library to initially create components at their default size and then just using setDimensions or resize (depending on if child content exists… and actually, resize is just fine in either case) seems to do the trick.

I’ve also noticed that setting the parent container to an initial value of Vector2f.ZERO and calling sizeToContent after the fact… works fine for layout positioning. I think it will be necessary to opt for default (absolute) sizing if the parent container does not have dimensions set.

The idea is to avoid the “chicken or the egg” scenario that sizing components via layouts encounters.

So… now specifically:

@rockfire - I know the above is different than Swing and it is limited to the three choices (Vertical, Horizontal & Flow) for the default provided Layout Modes. Do you see potential snags with my description of how I would like sizing to work? Can you think of anything that it is missing? Did I completely miss the boat here?

@atomix - Consider the above description of how I would like sizing to work, do you think that the Builder Pattern (well… semi-Builder Pattern) is needed for the Layout itself? LayoutHints can be set to adjust element specific params… and actually, I think I’ll add the chaining to simplify setting the properties. Though, I’d like to keep the Layout to a simple no parameter call. Just add, add, add, layoutChildren. Thoughts?

I started experimenting with the sizing properties idea above and it is looking promising:

The general idea would be to add elements like this:

[java]
Panel p1 = new Panel(screen);
p1.getLayoutHints() .setFillTypeX(LayoutHints.FillType.Percent).setFillX(40)
.setFillTypeY(LayoutHints.FillType.Percent).setFillY(100);
[/java]

The percentage property is converted to a value between 0 an 1… so, anything would work: 42.5f… or 0.425f is fine

I think it may be a good idea to overload the setFill methods accepting a String, so it can be simplified to:

[java]
Panel p1 = new Panel(screen);
p1.getLayoutHints() .setFillX(“40%”)
.setFillY(“100%”);
[/java]

Yup, have taken a quick look at the new code, making sense so far :slight_smile: I do question the need for LayoutMode, at least in the Layout interface itself. From what i can tell it’s specific to DefaultLayout? Why not move that into DefaultLayout to keep Layout thinner. I wonder if other methods can be pushed down too.

I’m thinking how this could be adapted to MigLayout. If that was possible with this framework, I’d likely ditch my custom code in favour of it in time, as 90% of my game uses it, the rest could converted relatively easily.

With that in mind, it might be nice if LayoutHints was a bit more uhm generic, perhaps even use generics :wink: I currently pass these hints (or constraints in Mig language) in when using addChild. For example …

[java]
LContainer c = new LContainer(screen);
// The strings here are overall constrains for the whole layout manager
c.setLayoutManager(new MigLayout(screen, “fill, wrap 3”, “[][fill,grow]push[:32:]”, “[][]”));

// row 1
c. addChild(…some label…);
c. addChild(…some text field…, “gapleft 32, ay 50%”); // component specific constraints
c. addChild(…some button…, “ax 50%”);

// row 2
c. addChild(…some label…);
c. addChild(…some text field…, “w 50%, h 1em”);
c. addChild(…some button…, “growy”);

[/java]

So Mig constraints are just simple strings. If LayoutHints was either generified or could contain some kind of arbitrary value, that would work.

Element.setLayoutHints() is a perfectly acceptable replacement for this, although I wonder if it might be nice have an addChild() take also takes a LayoutHints :-

[java]
container.addChild(someElement, new LayoutHints(stuff));
// or chaining
container.addChild(someElement.setLayoutHints(new LayoutHints(stuff));
[/java]

I’m not entirely certain on how sizing will fit. In writing my layout managers, I found that none (or at least almost none) of Tonegod controls seem to have the concept of a default preferred size. Each of my custom controls has a getPreferredSize() that does it’s best to return a size that could be used if there is enough space in it’s parent.

For example, a Button should be the width of it’s text (or icon) + resize borders. A Label should shout the width of it’s text. A CheckBox the width of it’s check and it’s text (CheckBox is a weird one). You are saying that is no longer the case and sizeToContent() should deal with that right?

The other (I think minor thing), is the use of min/max/preferred everywhere. Not all Tonegod has the concept of min and max, although I guess there isn’t any reason there shouldnt be.

If I think of anything else I will of course post again :slight_smile:

1 Like
@rockfire said: Yup, have taken a quick look at the new code, making sense so far :) I do question the need for LayoutMode, at least in the Layout interface itself. From what i can tell it's specific to DefaultLayout? Why not move that into DefaultLayout to keep Layout thinner. I wonder if other methods can be pushed down too.

This was an oversight… thanks for the catch…

Still reading =)

@rockfire said: I'm not entirely certain on how sizing will fit. In writing my layout managers, I found that none (or at least almost none) of Tonegod controls seem to have the concept of a default preferred size. Each of my custom controls has a getPreferredSize() that does it's best to return a size that could be used if there is enough space in it's parent.

For example, a Button should be the width of it’s text (or icon) + resize borders. A Label should shout the width of it’s text. A CheckBox the width of it’s check and it’s text (CheckBox is a weird one). You are saying that is no longer the case and sizeToContent() should deal with that right?

Yes, sizeToContent does just this. it basically sets it’s bounds to the outter extent of all of the child elements postions & sizie. Where this fails is the following scenario:

An Element contains a few Elements that are sized and positioned.
One of these child Elements contains a child Element that is positioned outside of it’s dimensions with clipping turned off.
The absolute parent would not see this.

It’s not the most likely scenario, however… it could happen.

Back to reading. I really like the idea of a Layout specific addChild method… and I like the String param idea. Though, I think I’d need a bit of help understanding how to parse it… considering that any param should be able to be added in any order within the string. <<< Consider me stupid (like people don’t already >.< ) as we continue talking about this.

@rockfire said: The other (I *think* minor thing), is the use of min/max/preferred everywhere. Not all Tonegod has the concept of min and max, although I guess there isn't any reason there shouldnt be.

You can set the minDimensions on any Element… however… aside from being used in resizing… it was a placeholder for implementing Layouts.

I guess since Layouts other than Absolute just ignore sizing (If percent or fill is set), the default dimensions should be considered the preferred size, as this is what it was intended to be (with consideration to % * type sizing)

On the otherhand… there isn’t a concept of maximum size. Aside from enabling setLockToParentBounds(true)… and then resizing is stifled when you hit the bounds of the parent Element or Screen.

BuilderPattern is a wise move. Let me explain the idea a little bit.

The BuilderPattern is NOT set().set().set().get() as it’s usually appear in programming book. Smart dev ulitilize BuildPattern to actually build a thing out of inputs in “smart way” and they are not doing it in a unified way.

Some of this are NOT ALWAYS TRUE:

  • Builder methods are free of order before final build call: you can always call setA().setB() or setB().setA() without an Exception reported.
  • Builder method except final build call always return that Builder instance, final build call always return Built instance.
  • Builder is staless on its operations and only contain state of the built item.

In real life,
50% of the scenario require strict order of functions, the dependency actually rely in the context. You can surely make LayoutBuilder free of order and you should do so … branching in Builder or other type of function (like void) is special case and should also be mark with different syntax. If you used JQuery you may see they actually work out of HTML elements abstraction and make JQuery very dynamic and clean. For example:
$(element).size(10).pos(10);
$(elements)._filter(“red”).size(5);

Now 3 BIG problems of BuilderPattern in Layout data, and Layouting scenario you may also notice already:

  1. Dependency chaos or ordering tangles:
  • Element order and containment is strict (a Checkbox can not contain any Window)
  • It’s layout settings (parameter) is strict and oppinied (the is no use of setting for a Checkbox padding)
  • The order of building the parameters are hard to defined. (how I resolve PosLeft if i don’t know DockLeft before)
  • Some value still unknown at the time of creating the layout data… make the layout data incomplete. For example: if you set the layout before you add the element into its container. So the layout don’t know about the actual parent size yet.
  1. The layout data may also contain link to other layout data or elements making the progress of resolving the layout data actually a tangles and can also be a cycling dependency, or infinite non-stop multi way expanding ( think about 2 or more filled elements) cause visual error, or even deadlock.

  2. Concurent with Trees

  • It’s there a final call .build() which will start the layout processing. This usually make a travel to resolve containments, aligments with a promise “all the styles and size parameters are available and property parsed”.
  • Can the process be splited into serveral separated parallel job and what’s a proper way to determine the split.
  • Can changes of layouts also be optimized.
    [Hint: Tree are actually quite well defined datastructure for concurrent in java already]

To solve 1) DataType & Processing method
Gui system like AWT has serveral of default DataType for layout data, mostly Integer, String. Builder interprete once at the build time to create so call LAF or UI data, layout system (Manager) interprete once again at applying time into specific element.

Gui system like Web browser’s HTML Elements has only one simple Box model and “a lot” of layout attributes (some not even necessary) for Element. Builder may take appropriate parameters, ignore others and build just the simple Box model. Processing just apply the Box to Element at runtime. This is also what Nifty did and I see you trying to do the same.

Gui system like http://elm-lang.org/Examples.elm has Live DataType which is a flow of data signal defined as result of a composable functions. Builder compose function in a type safe manner. Processing actually a loop though main initial signal sources (mouse, window size, focused element, scrolling amount … etc)
2) To solve 2,

  • May or may let them create layout with free order paramaters … but
  • Do not let them link freely, or check and report invalid dependency (cycle, multi demensional expanding…), or reset the invalid entries to a simplized and default scenario (recomended). For example: Two filled elements translated to 50%,50% elements.
  1. https://code.google.com/p/concurrent-trees/wiki/TreeDesign

Quite BIG words but if you read carefully you may find it’s not that hard. And of course take your time, and make what is possible and useful first.

1 Like

@rockfire
Ok, I think I have a general overview of what MigLayout is and does now.

It seems similar to the column, row concept of tables. using span to encompass multiples in any direction.

Of course there is more to it than this, however I needed a simple layout flow concept to start churning over.

The general idea seems to be fairly simple to understand and would be very easy to implement. And should have the impact of genericizing LayoutHints as you suggested.

Atm, I’m feeling pretty ok with how vertical, horizontal and flow layouts work and I’ll start working on building out MigLayout next. Obvious this will impact how the others currently leverage LayoutHints seeing that this will change completely, but the end result should be as you described above.

I’ll likely need a considerable amout of direction as I proceed to make sure that my understanding of what I read about MigLayout matches up with your usage knowledge and what you expect it to do and work like.

My first question is:

  1. How does the layout know if you want to skip a column or row? I see that you can force a line feed (or advance a row by using “wrap”, however, I haven’t stumbled across how you skip slots

Oh, no, I didn’t mean for you to parse them. Those are Mig specific. This was why I was suggesting abstracting LayoutHints a bit. I would imagine implementing Mig like this …

Layout (thin interface with only methods called by Element)
… DefaultLayout (expects DefaultLayoutHints)
… MigLayout (expects MigLayoutHints)
… SomeOtherLayout

LayoutHints (thin interface with only methods called by Element)
… DefaultLayoutHints
… MigLayoutHints

… or some similar arrangement. If you want to be able to parse mig-like strings in DefaultLayoutHints and use them for DefaultLayout, that’s different matter I think.

An excercise, I thought I’d try and show you how to reproduce each of your examples in this thread using how I would imagine a
Mig implementation using this new code would look like (using pseudoish code)

Example 1

6 buttons laid out vertically with a gap between each and some insets.

[java]
MigLayout ml = new MigLayout(“gap 20, ins 20, wrap 1”, “[]”, “[][][][][][]”);
Panel p = new Panel(…);
p.setLayout(ml);
p.addChild(button1);
p.addChild(button2);
p.addChild(button3);
p.addChild(button4);
p.addChild(button5);
p.addChild(button6);
[/java]

Example 2

6 buttons laid out vertically with the smaller default gap between each and only horizontal insets.

[java]
MigLayout ml = new MigLayout(“wrap 1”, “20[]20”, “[][][][][][]”);
Panel p = new Panel(…);
p.setLayout(ml);
p.addChild(button1);
p.addChild(button2);
p.addChild(button3);
p.addChild(button4);
p.addChild(button5);
p.addChild(button6);
[/java]

Example 3

6 buttons laid out in 2x3 grid with gaps left and right.

[java]
MigLayout ml = new MigLayout(“wrap 2”, “20[][][]20”, “[][]”);
Panel p = new Panel(…);
p.setLayout(ml);
p.addChild(button1);
p.addChild(button2);
p.addChild(button3);
p.addChild(button4);
p.addChild(button5);
p.addChild(button6);
[/java]

Example 4

6 buttons laid out in 2x3 gaps between cells.

[java]
MigLayout ml = new MigLayout(“wrap 2, gap 20”, “[][][]”, “[][]”);
Panel p = new Panel(…);
p.setLayout(ml);
p.addChild(button1);
p.addChild(button2);
p.addChild(button3);
p.addChild(button4);
p.addChild(button5);
p.addChild(button6);
[/java]

Example 5

A big one :wink: A more complete form …

[java]
// MiG Layout Cheat Sheet - very useful!!!
MigLayout ml = new MigLayout(“fill, wrap 2”, “[][]”, “[][][][][][][][][][][][][][][][]push[]”);
Panel p = new Panel(…);
p.setLayout(ml);
p.addChild(displayLabel, new MigLayoutHints(“span 2, ax 50%”));
p.addChild(screenResolutionLabel, new MigLayoutHints(“span 2, left”));
p.addChild(screenResolution, new MigLayoutHints(“span 2, growx”)); // stretches along x
p.addChild(vsync, new MigLayoutHints(“span 2”));
p.addChild(guiExtrasLabel, new MigLayoutHints(“span 2, ax 50%”));
p.addChild(uiAlphaLabel, new MigLayoutHints(“span 2”));
p.addChild(uiAlpha, new MigLayoutHints(“span 2, growx”));
p.addChild(audioVolumeLabel, new MigLayoutHints(“span 2”));
p.addChild(audioVolume, new MigLayoutHints(“span 2, growx”));
p.addChild(enableUIAudio, new MigLayoutHints(“span 2”));
p.addChild(enableCursors, new MigLayoutHints(“span 2”));
p.addChild(enableCursorFX, new MigLayoutHints(“span 2”));
p.addChild(enableToolTips, new MigLayoutHints(“span 2”));
p.addChild(enableToolTips, new MigLayoutHints(“span 2, ax 50%”));
p.addChild(os, new MigLayoutHints(“growx”));
p.addChild(load);
p.addChild(someOtherCombo, new MigLayoutHints(“growx”));
p.addChild(unload);
p.addChild(exit, new MigLayoutHints(“ax 50%”));
[/java]

As you can see Mig is extremely concise. I’m not suggesting you try to reproduce that, you might as well just include the Mig library anyway and adapt it if you went that route :wink: This is to illustrate what I meant about extending LayoutHints, and maybe you can get some other ideas from it.

PS shush with the stupid, I am constantly amazed at speed you seem to cool produce stuff XD

Heh. Active post, by the time I finished writing that lot you already nailed it :wink: Hopefully my examples will help though.

@t0neg0d said: @rockfire Ok, I think I have a general overview of what MigLayout is and does now.

It seems similar to the column, row concept of tables. using span to encompass multiples in any direction.

Of course there is more to it than this, however I needed a simple layout flow concept to start churning over.

The general idea seems to be fairly simple to understand and would be very easy to implement. And should have the impact of genericizing LayoutHints as you suggested.

Atm, I’m feeling pretty ok with how vertical, horizontal and flow layouts work and I’ll start working on building out MigLayout next. Obvious this will impact how the others currently leverage LayoutHints seeing that this will change completely, but the end result should be as you described above.

I’ll likely need a considerable amout of direction as I proceed to make sure that my understanding of what I read about MigLayout matches up with your usage knowledge and what you expect it to do and work like.

My first question is:

  1. How does the layout know if you want to skip a column or row? I see that you can force a line feed (or advance a row by using “wrap”, however, I haven’t stumbled across how you skip slots

I think you want span here.

Edit: doh. no. hmm. not sure.

@rockfire
I honestly do not mind taking the time to reproduce MigLayout as closely as possible. The syntax looks very easy to understand and the concept seems quite powerful. I initially missed that params were comma delimited in defining the layout. Should this be the case the addChild method as well? Or should they be a single String that is parsed?

The big question at this point would be… if there was a layout system that mirrored MigLayout, if there really a need for anything else (aside from Flow which ingores the concept of a grid layout)?

Or should the other layouts just build off of Mig or Flow to simplify the input?

It seems to me that Mig encompasses the ability to produce most every other layout…

Do you think that these two base types miss any foreseeable custom implementation (not saying that it wouldn’t be possble to just write something completely different implementing the interfaces provided)? If this is the case… then I think I have a solid foundation to build towards a final implementation… and yes LayoutHints will end up a completely generic interface now that I have a better understanding of what directions Layouts could potentially go in.