Layouts – preview & discussion… anyone? please ;)

@rockfire said: 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 ;) This is to illustrate what I meant about extending LayoutHints, and maybe you can get some other ideas from it.

Here is what I found the most interesting about reading how the layout works. I really won’t need to do much to implement the major of it’s functionality, as most of this exists in the library already. It’s like wrapping absolute positioning into short-hand.

The layoutChildren method would just leverage existing code, using the params as a map. Even easier, Idon’t need to actually calc the sizing past the initial grid layout.

@t0neg0d said: @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.

I was seriously considering getting rid of the other layout managers for this very reason. And again, I probably would have kept FlowLayout for the same reason. These two really do cover nearly all cases. The one argument for including simpler layouts is because the are probably slightly simpler to use when you’ve never encountered MigLayout before.

Now back to the implementation and focus in efficient code side…

What is so painful in Nifty i’ve remember @toolforger once said is the String parameters… just don’t use it too much. Overhead of parsing simple and basic strings again and again can be quite a lot. Parsing a String based composed parameter like MigLayout constrainst in other hand are worth the performance cost you have a parser to slurp fast in the string.

Note that Layout data is a “special tiny little lovely” kind of Data that only we will care 'bout if we have to deal with Layouting. More over its Builder will be fine without Bean convention…, so what’s the point of set, get when you actually made it from a Builder.

Now if you can simply put aside some verbose convention of Bean object, and some BuilderPattern as i said above.

so why
[java]
element.getLayoutHint().setFillX(40).setFillXType(Unit.Percentage).setFillY(40).setFillYType(Unit.Percentage)
[/java]

but not
[java]
$(element).fillX(40,Unit.Percentage).fillY(40,Unit.Percentage)
[/java]

or even
[java]
$(element).fill(40,Unit.Per,40,Unit.Per)
$(element).fill(40,Unit.Pix,40,Unit.Pix)
[/java]
also

I repeated the “$” symbol here as is actually quite an interesting and bright idea from JQuery (compatible with Java) to cut down the length of your code when you need to type them fast, and to deal with Layouting and GUI is one solid case.

Later… what will be more awesome than using the same simple to traveling around screen element trees and add behaviours with the same syntax.
[java]
$(screen)._find(“button*”).onClick(new Runnable(){ });

$(screen)._find(“button”)._relateTo()._find(“label”).onClick(new Function<Element,Element>(){
public Element apply(Element label){
label.setText("HelloWorld);
}
});
[/java]

1 Like
@atomix said: Now back to the implementation and focus in efficient code side...

What is so painful in Nifty i’ve remember @toolforger once said is the String parameters… just don’t use it too much. Overhead of parsing simple and basic strings again and again can be quite a lot. Parsing a String based composed parameter like MigLayout constrainst in other hand are worth the performance cost you have a parser to slurp fast in the string.

Note that Layout data is a “special tiny little lovely” kind of Data that only we will care 'bout if we have to deal with Layouting. More over its Builder will be fine without Bean convention…, so what’s the point of set, get when you actually made it from a Builder.

Now if you can simply put aside some verbose convention of Bean object, and some BuilderPattern as i said above.

so why
[java]
element.getLayoutHint().setFillX(40).setFillXType(Unit.Percentage).setFillY(40).setFillYType(Unit.Percentage)
[/java]

but not
[java]
$(element).fillX(40,Unit.Percentage).fillY(40,Unit.Percentage)
[/java]

or even
[java]
$(element).fill(40,Unit.Per,40,Unit.Per)
$(element).fill(40,Unit.Pix,40,Unit.Pix)
[/java]
also

I repeated the “$” symbol here as is actually quite an interesting and bright idea from JQuery (compatible with Java) to cut down the length of your code when you need to type them fast, and to deal with Layouting and GUI is one solid case.

Later… what will be more awesome than using the same simple to traveling around screen element trees and add behaviours with the same syntax.
[java]
$(screen)._find(“button*”).onClick(new Runnable(){ });

$(screen)._find(“button”)._relateTo()._find(“label”).onClick(new Function<Element,Element>(){
public Element apply(Element label){
label.setText("HelloWorld);
}
});
[/java]

I’ve been considering this and I think that the option for setting params will likely provide both methods. When I say both, I mean the set.set.set portion of the Builder pattern, as well as the string params.

It will, however be up to the Layout implementation to provide these individually… meaning that casting would be involved.

The String params will be a bit smarter than must follow syntax… so for instance:

“[.3][.3[.4]”
“[30%][30%[40%]”
“cols [30%][30%[40%]”
“columns [.3][.3][.4]”
“.3,.3,.4”
“30%,30%,40%”
“cols .3, .3, .4”
columns 30%,30%,40%"
“[30%][30%][]"
"[30%][
][40%]”
etc, etc…

would all produce the same results.

The layout would likely be flagged for update, meaning it will only parse once unless some parameter is changed.
The individual component params are separate, and only need to be parsed individually if one changes… and only parsed once for each change.

The params will be converted to a generic LayoutParam that has a ParamType, UnitType and <T> Value (which has a Type and Value associated with it), as an individual LayoutParam might contain more than one value.

LayoutHints will now store a List of LayoutParams so there will really be no need to create individual implementations of LayoutHints per Layout.

I believe that the backing should be generic enough to support both approaches that you and @rockfire have discussed, as I like portions of both… but no matter what I decide to do as a final, will be open enough to allow (as a for instance) you to implement the a JQuery type interface over.

@rockfire
Haven’t have a ton of time to work on this today… but the basics for MigLayout are in place:

EDIT: The constructor looks like…

[java]
// The first param will be constraints, like in Mig
MigLayout ml = new MigLayout(screen, “”, “[10][30][10][50]”, “[][30][][][][]”);
[/java]

You can add params to LayoutHints:

[java]
//either like
el.setLayoutHints(new LayoutHints().set(“cell 2 3”).set(span 2 1").set(etc));
// or
el.setLayoutHints(new LayoutHints(“cell 2 3”,“span 2 1”,etc));
// or
parent.addChild(el, “cell 2 3”, “span 2 1”, etc);
[/java]

I haven’t added to much in the way of other types of common params like insets, padding, gap, whatever… but it won’t be too hard.

Wow ooo…

I think anyone 've read this thread should had a hat off for your for your speed of implementation features… (Rockin silently :))

MigLayout alike constrainst is interesting enough for me in the mean time.

The PreferedSizing and ExtremeSizing actually is not really interest me enough. IF we take a look at Blender interface we will see they does not implement PreferedSizing and ExtremeSizing at all. That’s a design decision which gain flexibility, a lot of user first althogh still complain about the inconvention of it but later change to love it when they get use to the interface.

The 3 Rules

The Blender user interface is based on 3 main principles:

Non Overlapping: The UI permits you to view all relevant options and tools at a glance without pushing or dragging windows around(2).
Non Blocking: Tools and interface options do not block the user from any other parts of Blender. Blender doesn't pop up requesters that require the user to fill in data before things execute.
Non Modal: User input should remain as consistent and predictable as possible without changing commonly used methods (mouse, keyboard) on the fly. </blockquote>

http://wiki.blender.org/index.php/Doc:2.6/Manual/Interface

For ingame UI, I think MigLayout without prefered sizing and extreme sizing is pretty enough.

For ingame editor UI: May be we can support window merging as an default behavior, or bring it to another external library who handle WindowLayouting seperately over ElementLayouting.

As soon as this Layout is finish and downloadable I think I will hook it to my AtomEditor and give you the same Blender style’s WindowLayouting that I write for Nifty.

We can of course make prefered sizing and extreme sizing as an options for non cross platform developer. But I don’t think it will be fitted with the concept of flexibility requirement.

Cheers,

1 Like

Seeeew… I woke up about 30 minutes ago because it dawned on me that layouts could inject themselves into the existing resize process very easily. It also dawned on me that resizing MigLayout would/could be extremely intelligent… especially if constraints could be added to how it resizes.

Anyways, since constraints are a future thing atm, I just quickly set up the resize injection and gave it a go… here be the results:

[video]http://youtu.be/I9ZDYDM8V6Y[/video]

EDIT: And actually, a lot of the constraints are already enforced by Element. So… yeah… not a lot of work to actually make that happen as well.

And now back to bed (I hope)

@atomix I have a few questions about the last two posts… but I’m scattered atm. After sleep I should be able to think a bit more clearly. I’m really interested in making sure that the provided layouts follow the best of both worlds approach API-wise. The .set.set.set was a default for string input… however I think each layout should be able to provide it’s own specific LayoutHints as rockfire originally suggested to provide methods that make it more friendly… something along the lines of:

[java]
el.setLayoutHints(new MigLayoutHints().cell(2,3).spanX(2).pad(5).padBottom(15)); // etc
[/java]

Of course since the underpinning is nothing more than a list of LayoutParams… the layout specific hints would actually extend the default as apposed to implementing an interface, making it nothing more than adding user friendly setters.

1 Like

Individual insets and layout margins work now (seriously simple to add properties and apply them)

Also added a define method for LayoutHints so you can just:

[java]
ba.getLayoutHints().define(“cell 4 0”,“span 2 1”,“pad 12 0 0 0”); // pad can be padding, inset, insets, whatever
[/java]

I need to ensure that the parser fills in properties you don’t set…

so if you just need to define left padding you could say “pad 12” and the remainder would be defined as 0.

EDIT: Eh… it should probably left you set padleft etc… "padleft 12, “insetright 15” and so on. But… later.

I added grow and docking properties. The results are really starting to turn out great!

[video]http://youtu.be/ML8LhPwhL4E[/video]

1 Like

This is looking superb :slight_smile: Although I think you have just created lots of work for me. I just know I will want to use this stuff, which means replacing quite a lot of code. Damn you! shakes fist =D

A question. How well does this work with a CheckBox? I had particular problems with this one, because you normally want a label with a checkbox, but setting the dimensions of the CheckBox actually sets dimensions of the ‘box’ part, and the label effectively exists outside of the bounds you’d expect on most other components.

It makes me think that maybe Button should become a ‘container’ component with a layout manager. An ordinary button would have a single child component. A CheckBox continues to extend Button, but adjusts it’s layout, and has 2 children, the Check, and a separate label.

The same could be applied to TextField to build stuff like Spinner, or perhaps user made custom components like TextFieldWithEllipsesButton.

1 Like
@rockfire said: This is looking superb :) Although I think you have just created lots of work for me. I just know I will want to use this stuff, which means replacing quite a lot of code. Damn you! *shakes fist* =D

A question. How well does this work with a CheckBox? I had particular problems with this one, because you normally want a label with a checkbox, but setting the dimensions of the CheckBox actually sets dimensions of the ‘box’ part, and the label effectively exists outside of the bounds you’d expect on most other components.

It makes me think that maybe Button should become a ‘container’ component with a layout manager. An ordinary button would have a single child component. A CheckBox continues to extend Button, but adjusts it’s layout, and has 2 children, the Check, and a separate label.

The same could be applied to TextField to build stuff like Spinner, or perhaps user made custom components like TextFieldWithEllipsesButton.

Thanks!

CheckBox - I’m seriously looking at the potential of an overhaul to all controls due to the fact that they were all written prior to the concept of containers. The other thing is, I’m going to remove BitmapText from some of these controls (once I’ve fixed the clipping with the code you posted) as LabelElement & TextElement do a spot-on job with alignment. So… these will be updated very soon to reside within a container (sized to content) hopefully making this sort of issue go away completely.

Hah… just read your next paragraph after writing that. My thoughts exactly. I’m experimenting with Window first… as it ALWAYS bugged the crap out of me that there was no defined content area. This seems to work well, so Button will be next on the list just as soon as the Layouts are completed (well… function well… I’ll have to update for parameter additions)

And… speaking of parameter additions… min size in now enforced. If one isn’t set, it defaults to resize borders (l+r),(t+b)

Now… I need your expertise here. I have NO CLUE what the difference between preferred size and max size is. Here is what I think it is… let me know if I am off base.

Min - the absolute smallest size the control can be
Preferred - The size the the control will be if the parent container has enough room.
Max - I guess stops growing once the dimensions reach this point?

@t0neg0d said: Thanks!

CheckBox - I’m seriously looking at the potential of an overhaul to all controls due to the fact that they were all written prior to the concept of containers. The other thing is, I’m going to remove BitmapText from some of these controls (once I’ve fixed the clipping with the code you posted) as LabelElement & TextElement do a spot-on job with alignment. So… these will be updated very soon to reside within a container (sized to content) hopefully making this sort of issue go away completely.

Hah… just read your next paragraph after writing that. My thoughts exactly. I’m experimenting with Window first… as it ALWAYS bugged the crap out of me that there was no defined content area. This seems to work well, so Button will be next on the list just as soon as the Layouts are completed (well… function well… I’ll have to update for parameter additions)

And… speaking of parameter additions… min size in now enforced. If one isn’t set, it defaults to resize borders (l+r),(t+b)

Now… I need your expertise here. I have NO CLUE what the difference between preferred size and max size is. Here is what I think it is… let me know if I am off base.

Min - the absolute smallest size the control can be
Preferred - The size the the control will be if the parent container has enough room.
Max - I guess stops growing once the dimensions reach this point?

:slight_smile:

Regarding sizes, yup thats it exactly. For example, the preferred size of a TextElement with some really long text would be 1 line high, and the entire width of the unwrapped text. And maximum yes, components should not grow beyond that. However, I think in Swing layout managers are allowed to ignore/override that.

I am not sure how far you are taking this, but of course containers have min/max/preferred sizes to. It is the job of Layout to calculate this, as it knows where the bounds of all its children will be.

And yes! Windows and content areas. I have my own FancyWindow class that does exactly this (amongst other things). This will be welcome.

1 Like
@rockfire said: :)

I am not sure how far you are taking this, but of course containers have min/max/preferred sizes to. It is the job of Layout to calculate this, as it knows where the bounds of all its children will be.

I am going to implement Layout params… and factor things that are set with defaults from either the parent element or what the layout’s intent determines. This is currently done for child Elements. Do you calculate the preferred size of the Layout by the initial size if it is not set?

@rockfire said: And yes! Windows and content areas. I have my own FancyWindow class that does exactly this (amongst other things). This will be welcome.

When you get a chance… I’d like to know about the other things. Close button? etc? Or?

Oooops, forgot to ask… should cells clip their content? The clipping bounds can be forced if needed even though Cells are not actual things… past some data.

/sigh… I also want to mention that using these Layouts is supremely awesome in the sense that you have to define nothing in the element… And with the addition of the new constructor that takes screen only as a param… creating elements within a layout looks like:

[java]
ba = new ButtonAdapter(screen);
ba.getLayoutHints().define(“cell 2 1”,“span 1 1”,“pad 24 0 24 0”,“grow true false”,“dock center bottom”,“min 40 20”, “pref 120 20”,“max 240 20”);
p.addChild(ba);
[/java]

So much cleaner.

@t0neg0d said: I am going to implement Layout params... and factor things that are set with defaults from either the parent element or what the layout's intent determines. This is currently done for child Elements. Do you calculate the preferred size of the Layout by the initial size if it is not set?

When you get a chance… I’d like to know about the other things. Close button? etc? Or?

The preferred size of a layout/container is total size of all its children. So if you have grid of 3x3 buttons, each 150 x 32, the preferred size for the layout would be 450 x 96 (plus insets).

Components themselves … In Swing at least, for most components you don’t set a ‘default size’, you let it work it out from font metrics and any other borders or insets it might apply. In the Tonegod world, this would be the same as setting its “defaultSize” style to 0,0.

If you would prefer a precise size, you would use setPreferredSize(), and that would override any calculated size. If the layout manager is respecting the preferred size, you will get it. If you REALLY want an exact size, and never (well nearly never) have the layout manager change it, you set its minimum, maximum and preferred size to the same value. This applies to containers as well.

As for FancyWindows … well they allow …

  • 3 buttons, minimize, maximize and close (all optional)
  • The drag bar consists of 3 separate elements allowing more fancy design
  • Has a content area
  • Has a “Style” attribute that allows multiple styles of window (all in defined in the XML)

I just made a quick video, excuse the alignment of the buttons on the large version. That bug seems to have cropped from nowhere :S

EDIT: ugh, i messed up the video, seems to have been clipped weirdly. hopefully youll get the idea

[video]http://youtu.be/UPjixz1xyXk[/video]

2 Likes
@t0neg0d said: Oooops, forgot to ask... should cells clip their content? The clipping bounds can be forced if needed even though Cells are not actual things... past some data.

I haven’t really worried about this at all, so myself, no. If individual controls want to clip themselves they can. It does like it might be useful though. The Table control comes to mind. That could be made a MigLayout and have it deal with the clipping :slight_smile:

@rockfire said: The preferred size of a layout/container is total size of all its children. So if you have grid of 3x3 buttons, each 150 x 32, the preferred size for the layout would be 450 x 96 (plus insets).

Components themselves … In Swing at least, for most components you don’t set a ‘default size’, you let it work it out from font metrics and any other borders or insets it might apply. In the Tonegod world, this would be the same as setting its “defaultSize” style to 0,0.

If you would prefer a precise size, you would use setPreferredSize(), and that would override any calculated size. If the layout manager is respecting the preferred size, you will get it. If you REALLY want an exact size, and never (well nearly never) have the layout manager change it, you set its minimum, maximum and preferred size to the same value. This applies to containers as well.

As for FancyWindows … well they allow …

  • 3 buttons, minimize, maximize and close (all optional)
  • The drag bar consists of 3 separate elements allowing more fancy design
  • Has a content area
  • Has a “Style” attribute that allows multiple styles of window (all in defined in the XML)

I just made a quick video, excuse the alignment of the buttons on the large version. That bug seems to have cropped from nowhere :S

[video]http://youtu.be/UPjixz1xyXk[/video]

The vid says it’s set to private =( Because youtube talks to me.

1 Like
@t0neg0d said: /sigh... I also want to mention that using these Layouts is supremely awesome in the sense that you have to define nothing in the element... And with the addition of the new constructor that takes screen only as a param... creating elements within a layout looks like:

[java]
ba = new ButtonAdapter(screen);
ba.getLayoutHints().define(“cell 2 1”,“span 1 1”,“pad 24 0 24 0”,“grow true false”,“dock center bottom”,“min 40 20”, “pref 120 20”,“max 240 20”);
p.addChild(ba);
[/java]

So much cleaner.

Isn’t it just! I ended up with the same with thing on all my custom controls, just the Screen constructor in a large number of cases. I have sometimes pondered how to get rid of even that requirement (as I’m sure you have). But it looks like a lot of work for little gain. I guess you would be initialising when a control get’s parented and im sure that has lots of implications.

@t0neg0d said: The vid says it's set to private =( Because youtube talks to me.

Oops. I fail. the PUBLISH button was right in front of me too … err

1 Like