Future GUI

miniME89

GUI Lead
Contributor
GUI
x3ro and me just finised our IRC session with some presence of Cervator and the result was a layout for the json style file, along with some discussion about implementing the parser for the json file in groovy.

json style file. an example of the available attributes and the layout.
Code:
{
    "id": "main-menu",
    "class": "UIDisplayWindow",
    "children": [
        {
            "id" : "bg-image",
            "class" : "UIImageOverlay",
            "style" : {
                "image" : "engine:bg.png",
            }
        },
     
        {
            "id" : "some-button",
            "class" : "UIButton",
            "style" : {
                "onclick": "methodeName",          // the function to call
                "onhover" : "otherMethod",
 
                "position-type" : "absolute",      //absolute to whole screen / relative to parent widget
                "position" : ["50%", "50%"],          //pixel position by percentage of the current screen or just by pixels
 
             
                "vertical-align": "center",        //left / center / right - if this is used the position attribute should be added from this location
                "horizontal-align" : "center",      //top / center / bottom - same here
             
                "image" : "engine:someimage.png",  //image to load
                "image-normal" : [0, 0, 100, 30],  //x y width hight in someimage.png
                "image-hover" : [0, 30, 100, 30],
                "image-pressed" : [0, 60, 100, 30]
            }
        }
    ]
}
Along with an short discussion about how to implement the correspondending JAVA class file it should be also quite possible to implement this without much changes of the current system.
 

Immortius

Lead Software Architect
Contributor
Architecture
GUI
Looks good.

One comment, there shouldn't be any need for the ".png" in the image uri IMO. Ignoring the fact we only support png at the moment, in the case where a user has two images with different the same name and different formats I feel it is worth raising an error in return for untying the uris from the specific format of the files. This gives a little bit of flexibility in terms being able to switch resources between formats. Regardless of what file format the image is, the UI will be working with a Texture object.
 

Adeon

terasology.ru
Contributor
Architecture
GUI
Logistics
x3ro and me just finised our IRC session with some presence of Cervator and the result was a layout for the json style file, along with some discussion about implementing the parser for the json file in groovy.
Damn! Time difference sucks!
 

Adeon

terasology.ru
Contributor
Architecture
GUI
Logistics
I think we need to separate the style from the structure of the window.

And I think it is better to borrow the nameS(!) of the style properties from the css.
First, the people who already know css don't need to memorize anything new. Second, css has more logical fields' names.

For examle:

Window structure JSON file:
Code:
{
    "id": "main-menu",
    "class": "UIDisplayWindow",
    "style": "UIDisplayWindow",
    "children": [
        {
            "id" : "bg-image",
            "class" : "UIImageOverlay",
            /*If the property "style" is missing the name of style will be taken from the class name*/
        },
 
        {
            "id" : "some-button",
            "class" : "UIButton",
            "style" : "UIButton", /*Or for examle "MyStyleClassName"*/
            "action": {
                /*Why "onhover"?! Look at JAVASCRIPT events*/
              "onСlick/onDblClick/onChange/onBlur/onKeyDown/onKeyPress/onKeyUp/onMouseOver/onMouseOut/onMouseDown/onMouseUp/": "methodeName"
            }
        }
    ]
}
Style description JSON file:
Code:
      "UIImageOverlay" : {
                "backrgound-image" : "<url>.png",
                "width": "100%",
                "height": "100%"
      },
 
    "UIButton" : {
      "position": "absolute/relative",
      "top/bottom/left/right": "50%/px",
 
      "vertical-align":  "center/top/bottom/right/left",
      "horizontal-align": "center/top/bottom/right/left",
 
      "backrgound-image"    : "<url>.png",
      "background-position" : [0, 0, 100, 30],
        ""
      },
 
    "UIButton:hover" : {
      "background-position" : [0, 30, 100, 30],
      },
 
    "UIButton:active" : {
      "background-position" : [0, 60, 100, 30]
      },
 
    "UIList": {
        "border-image-top": "engine:gui_menu 159/512 18/512 264/512 0 18",
      "border-image-bottom": "engine:gui_menu 159/512 9/512 264/512 81/512 9"
    },
  /*If the UIList is inside the UIDialogBox*/
    "UIImageOverlay UIList": {
      "border-image-top": "engine:gui_menu 159/512 1/512 263/512 17/512 2",
      "border-image-bottom": "engine:gui_menu 159/512 9/512 264/512 81/512 9"
    }
}
 

x3ro

Member
Contributor
GUI
Adeon: The separation of style and structure is a good idea. I hadn't thought about the amount of duplicate stuff we'd put into our structural configuration if we'd for example replicate button styles for every button, over and over.

The problem with replicating CSS is, that people will expect it to behave like CSS, which (at least that is my opinion) is kind of a bad idea. What I mean by that is that e.g. almost every Element in CSS can have properties such as position, background, margin, padding, etc.. Out of these properties, the only one that we'd have in common for our UI is "position" (correct my if I'm wrong). To support all those other properties consistently, we'd need to at least implement the CSS(2/3) box model, and I don't think its worth the effort.

My idea when proposing that JSON structure was that every UI element has specific properties (or style attributes or whatever one may call them), and no other properties may be applied (except for global properties such as position that are necessary for every element).

Also, if style and structure was separated, it would have to be possible to overwrite part of the style in the structural definition for a button, the button text and position for example).

Got to go, will expand later on this when I get back :)
 

Adeon

terasology.ru
Contributor
Architecture
GUI
Logistics
The problem with replicating CSS is, that people will expect it to behave like CSS, which (at least that is my opinion) is kind of a bad idea. What I mean by that is that e.g. almost every Element in CSS can have properties such as position, background, margin, padding, etc.. Out of these properties, the only one that we'd have in common for our UI is "position" (correct my if I'm wrong). To support all those other properties consistently, we'd need to at least implement the CSS(2/3) box model, and I don't think its worth the effort..
In this case, we should list of names of styles properties. Then we should list their possible values format. And then realize new feature of gui. Otherwise, we will kill each other in dispute. Ok? =)
 

miniME89

GUI Lead
Contributor
GUI
Of course we shouldn't implement CSS in detail. But i like the idea of Adeon to seperate the style.

Also it could look like this:
Code:
[
        {
            "id" : "some-button",
            "type" : "UIButton",
            "label" : "MyButtonLabel",
            "style-class" : "MyStyleClass",  //Base style class for every button
            "style" : {                                   //Overwrite the loaded style class with this properties set here
                "position" : [100, 100]
            },
            "action": {some actions here }
        }
]
And common properties in all widgets would be: position / size / position-type / vertical-align / horizontal-align.

But most properties ofcourse differ from widget to widget. Maybe we should have a style description file which holds the available properties for each widget or something.
 

x3ro

Member
Contributor
GUI
Otherwise, we will kill each other in dispute. Ok? =)
I find discussions on architecture actually quite constructive, quite the contrary to what you'd expect from a dispute... But I get your point, it's not worth going back and forth endlessly and not getting anything done in the end :)

miniME89 said:
And common properties in all widgets would be: position / size / position-type / vertical-align / horizontal-align.
If we decide to conform with CSS, these would rather be:

  • position (absolute or relative [to parent])
  • width
  • height
  • top / bottom / left / right (distance from respective border)
  • text-align (there is no "horizontal-align" in CSS :()
  • vertical-align
The semantics of top/bottom/left/right would have to be (in accordance with CSS) "displacement from default position of the element in the opposite direction of the name" (sounds confusing, I know^^). E.g. if "horizontal-align" was "center", and "left" was 50px, then the element would be placed 50pixels to the right of the center.
The only thing I'm not quite sure of is if we put the top-left corner of the element at the position, or the center of the element. Both methods have their advantages I think, but I'd like to hear your opinion :) What I mean:
 

miniME89

GUI Lead
Contributor
GUI
The only thing I'm not quite sure of is if we put the top-left corner of the element at the position, or the center of the element. Both methods have their advantages I think, but I'd like to hear your opinion :) What I mean
yea also thought about this, i would say position should be from upper-left corner. I don't like the idea of setting a position to 0/0 and the element will be out of its window. Also think about the child/parent behaviour. A child should be at the top left corner of its parent at 0/0, for me thats the usual behaviour. Otherwise we could just add "position-origin" style which could be "top left", "bottom right", ... "center" or something like this.
 

Adeon

terasology.ru
Contributor
Architecture
GUI
Logistics
text-align (there is no "horizontal-align" in CSS :()
We can use own property "vertical-align"=)

The semantics of top/bottom/left/right would have to be (in accordance with CSS) "displacement from default position of the element in the opposite direction of the name" (sounds confusing, I know^^). E.g. if "horizontal-align" was "center", and "left" was 50px, then the element would be placed 50pixels to the right of the center.
The only thing I'm not quite sure of is if we put the top-left corner of the element at the position, or the center of the element. Both methods have their advantages I think, but I'd like to hear your opinion :)
I think if there is a property of "vertical-align" or "horizontal-align", then the "top / left / right / bottom" properties are ignored.
 

x3ro

Member
Contributor
GUI
We can use own property "vertical-align"=)
I think if there is a property of "vertical-align" or "horizontal-align", then the "top / left / right / bottom" properties are ignored.
Hmm, as far as I know, in CSS, I think that "text(horizontal)-align" and "vertical-align" only apply to inline elements. "top/bottom/left/right" doesn't apply to inline elements. Therefore you are correct, "-align" and "top/bottom/left/right" are exclusive (i.e. there is no use in using them together).

I guess that we wouldn't need to make that distinction between "block"-level and "inline"-level, therefore all our elements would adhere to the "-align" properties. However, we definitely need a way to displace an element that has been centered. CSS does that with "margin-" and "padding-" properties, but given that we don't really want that box-model complexity, "top/bottom/left/right" would have to be used for that.
 

Adeon

terasology.ru
Contributor
Architecture
GUI
Logistics
Hmm, as far as I know, in CSS, I think that "text(horizontal)-align" and "vertical-align" only apply to inline elements. "top/bottom/left/right" doesn't apply to inline elements. Therefore you are correct, "-align" and "top/bottom/left/right" are exclusive (i.e. there is no use in using them together).
Yes, you are right. I think one property "margin" is enough.
 

x3ro

Member
Contributor
GUI
Yes, you are right. I think one property "margin" is enough.
I would go as far as saying we shouldn't use margin/padding at all. If we start using these, we'll be forced to implement some kind of box-model.
 

x3ro

Member
Contributor
GUI
I did some more thinking on the concept, and believe that we should not put "actions" in JSON definition, because the logic behind any action would be needed to put in a Java or Groovy class anyway. E.g. if anyone was to add a new button to the interface, it is very unlikely that the exact logic for that button has already been implemented.

Therefore, I'm proposing a "View/Controller" style separation. E.g. lets say we'd like to add a new UIButton to our interface, we'd add the following JSON to our structure definition:

Code:
{
    "id" : "some-button",
    "type" : "UIButton",
    "controller": "SomeClassImplementingUIButtonController",
    "label" : "MyButtonLabel",
    "style-class" : "MyStyleClass",
    "style" : {
        "position" : [100, 100]
    }
}
The "UIButtonController" interface would merely contain a method "click", which is the only action that can be sent to a button (not sure about the parameters yet).
 

x3ro

Member
Contributor
GUI
I started writing a concept roundup of all the things we've said so far. You can read it here. Its not finished at all! If you'd like to add something or correct something, please create a [gist](https://gist.github.com/) and point me to it (format: markdown!)
 

Cervator

Org Co-Founder & Project Lead
Contributor
Design
Logistics
SpecOps
Nice writeup, thanks! I'm still going to let you three do your thing, but am thinking about moving this to the Incubator and merging it with a similar thread already there - might want to review it for ideas either way?

http://forum.movingblocks.net/threads/gui-layout.377/

(difficulty: merging would leave that whole thread in the middle of this thread - fun)
 

Adeon

terasology.ru
Contributor
Architecture
GUI
Logistics
A-a--a-a-a-a-a-ah, sorry sorry sorry sorry sorry sorry sorry. I'm idiot.
When I read this
The semantics of top/bottom/left/right would have to be (in accordance with CSS) "displacement from default position of the element in the opposite direction of the name" (sounds confusing, I know^^). E.g. if "horizontal-align" was "center", and "left" was 50px, then the element would be placed 50pixels to the right of the center.
The only thing I'm not quite sure of is if we put the top-left corner of the element at the position, or the center of the element. Both methods have their advantages I think, but I'd like to hear your opinion What I mean:
I didn't undestand you, becouse my translation wasn't correct.
I fully agry with "miniME89". We should put top-left corner of the element at the position.

So which propeties do we have:
Code:
position: "relative"/"absolute'
width: "Npx"/"N%" where "N" is an integer
height: the same as the property "width"
top/right/bottom/left: "Npx" where "N" is an integer
text-align(Should we name it "horizontal-align"?): "center/left/right"
vertical-align; "center/top/bottom/"
background: "[urlImage] x y width hight" where x,y,width,height are integers
background-color: "[string]" where [string] is a hex of color
 
border: "Npx [string]" where N is the border's width and [string] is the hex border's color
 
or
 
border: "borderWidth [urlImage] xImage yImage widthImage hightImage"
 
or
 
border-[top/right/bottom/left]: "borderWidth [urlImage] xImage yImage widthImage hightImage"
 
or
 
border-[top/right/bottom/left]: "Npx [string]"
I'd like to hear your opinion. =)
 

miniME89

GUI Lead
Contributor
GUI
yea, a backgroundcolor option would also be nice.

I have thought about the backtround image stuff:
Code:
"backrgound-image" : "engine:terasology",
"background-position" : [0, 0, 100, 30],
What do we mean by the background-position property currently? The position of the "engine:terasology" image inside the widget itself? In the first concept (on top of this page) i thought about the "image-normal" : [0, 0, 100, 30]" property where to cut out the image out of the "engine:terasology" image, because you will have all 3 button states in one image. So we would need something like this to specify where to cut out the image and where to position it in the widget:
Code:
"backrgound-image" : "engine:terasology",
"background" : [0, 0, 100, 30,        //x, y, width, height where to cut out the image
                0, 0, 100, 30],      //x, y, width, height where to position the image in the widget
This would be more flexible, if you want just a part of a widget fill with a background. Otherwise the background-position property, as you decribed in your concept x3ro would be more like a background-cut property where to cut out the image and than it would alwasy fll the whole background.



And should we really stick with the same concept as in css regarding an extra style for a normal and a hover state for example? I see the advantages, but do we really need this? (default-button-style / default-button-style:hover)
(And how to switch the states: You would just add an Listener, read below for details.)



The "UIButtonController" interface would merely contain a method "click", which is the only action that can be sent to a button (not sure about the parameters yet).
I will add more events to the widgets. So a button would have a mouseOver event in the future for example. But i don't think it would be a good idea to use the concept of the UIButtonController. We already have interfaces such as IClickListener. These should be implemented for a specific action. Or a IChangedListener for the Slider button.

We should also think more about the classes itself and the implementation. What files do you think we should use for the implementation, just to nail down where the magic happens:

- SomeMenu.json: Contains the nested structure of the elements to add to the UI.

- SomeMenuStyle.json: Contains the style classes which can be used in SomeMenu.json. (Need some name convetion here. Maybe call the file SomeMenu.style)

- SomeMenu.java: The class where all the actions will happen. I don't know how this will work currently in interaction with the actual parser for the json files. But there should be some implementations of the different interfaces inside the class to handle the click or changed events (IClickListener/IChangedListener).
 

Adeon

terasology.ru
Contributor
Architecture
GUI
Logistics
We should also think more about the classes itself and the implementation.
The first of all, SomeMenu is a modal window. The second, I think we should implement files with action in groovy. The result should be look like that:

-defaultStyle.json: Contains the style for all basics UI elements.

- startMenuWindow.json: Contains the nested structure of the elements to add to the UI.

- startMenuWindowStyle.[json/style]: Contains the "overridden" style classes which can be used in startMenuWindow .json.

- SomeMenu.groovy: The class where all the actions will happen.
 

x3ro

Member
Contributor
GUI
Adeon: Could you provide examples for the Groovy files you are suggesting?

miniME89:

- SomeMenu.java: The class where all the actions will happen. I don't know how this will work currently in interaction with the actual parser for the json files. But there should be some implementations of the different interfaces inside the class to handle the click or changed events (IClickListener/IChangedListener).
This is pretty much what I am suggesting in a specifically applied way. E.g. you could create a SomeMenuController class which might look like this:

Code:
class SomeMenuController implements UIButtonController, UIProgressbarController {
 
    public void buttonClick(...) {
        // Handle button click
    }
 
    public void progressbarUpdate(...) {
        // Handle progressbar update
    }
}
However, my solution also allows the definition of a class such as "NewGameButtonController", which could be re-used across menus (assuming, as an example, that there is more than one menu with such a button).
 
Top