Advanced style parsing

While I was using a different style map - I started with a copy of the standard one - the use of absolute paths only bothered me. Now I implemented a new type “File”. The parser checks if there is an attribute called “absolute”. If not, or if it is set to “false”, the path is added to the path of the current document. The style elements in the main xml file work the same.
What do you think about this, @t0neg0d?

Personally, I don’t like spending too much time on grafics and so on. I prefere having someone else to do this. But if this person cannot or should not recompile the whole application, the styles should be usable for a default position, too. Of course not every window has the same position. My solution would be to define a new style element for all those windows. In the code you could create a new Window(screen, (uid,) “elementName”) and it takes position, dimension etc. from the xml.
But this is still not enough for a good solution, the display resolution might change and the whole GUI would no longer be useful. Another case would be huge variety of different display sizes on Android.
I implemented variables, which can be used in the xml files, along with basic math operations. Some standard variable would be app.height and app.width. And hopefully the pixel density for mobile devices can be stored in such a variable too.

All of this is working on my local version, now I could use some feedback on my ideas. If requested, I will upload my code for open use!

PS: While working on the parseStyles method, I saw some strange code. For example you do iterate through the nodeList, but inside the loop you always use item(0). And the file is alwys reloaded. Did I miss the reason for that?

Hey… just letting you know that I am still reading through this… just REALLY groggy, so it’s a bit slow going.

I’ll answer some of these now… and some of the other issues noted, I need a bit of time to look through. Oh, I’ll probably also have a series of stupid questions, so I make sure I’m following you completely.

I’ll answer the last thing first:

When parsing XML, the node and the node text are two separate elements… so, ((Node) fstNm.item(0)).getNodeValue(); would return the text within the current node. Just a note, this is different than attributes and attribute values… this would be for returning the text from, say, the follow XML:

[java]
<x>52</x>
[/java]

The internal text is always item(0)

Now… as for separating out the style/graphical info from the library, I’m all ears (and this will start to show my many short comings as a developer). Can you break down the concept a little more detailed for me… my initial thought on doing this was to explore the use of Asset Packs, as this is JME’s answer to either keeping assets separate, or being able to append to them at a later date.

As for the default position… I honestly have never used this, lol. More than not, I use:

[java]
el.setPosition(
(( screen.getWidth() * 0.5f )-( width * 0.5f )),
(( screen.getHeight() * 0.5f )-( height * 0.5f ))
);
[/java]

for centering and on reshape, I grab all element on the screen level and reposition them according to current placement.

Anyways, back to figuring out the best way of separating style/graphics from the library. if you have the time to further detail your fix for this, I’d LOVE to hear it, as this would be a great improvement.

Take your time, it is nothing too important.

First, the XML nodes: I did not mean the node.item(0), no, this here:
[java]
// Get Audio
docPaths.clear();

		file = Screen.class.getClassLoader().getResourceAsStream(
			path
		);
		dbf = DocumentBuilderFactory.newInstance();
		db = dbf.newDocumentBuilder();
		doc = db.parse(file);
		doc.getDocumentElement().normalize();
		nodeLst = doc.getElementsByTagName("audio");
		
		for (int s = 0; s &lt; nodeLst.getLength(); s++) {
			org.w3c.dom.Node fstNode = nodeLst.item(0);                                            &lt;&lt;&lt;&lt;----- here
                             ...
		}

[/java]
If there are now more than one audio node, the first one will be parsed multiple times. You could simple remove the loop here.

I don’t have any experience with Asset Packs so far.

And for the default position, your code is EXACTLY what I want to reduce. I will show you an example, but tomorrow.

1 Like
<cite>@Erebos3D said:</cite> Take your time, it is nothing too important.

First, the XML nodes: I did not mean the node.item(0), no, this here:
[java]
// Get Audio
docPaths.clear();

		file = Screen.class.getClassLoader().getResourceAsStream(
			path
		);
		dbf = DocumentBuilderFactory.newInstance();
		db = dbf.newDocumentBuilder();
		doc = db.parse(file);
		doc.getDocumentElement().normalize();
		nodeLst = doc.getElementsByTagName("audio");
		
		for (int s = 0; s &lt; nodeLst.getLength(); s++) {
			org.w3c.dom.Node fstNode = nodeLst.item(0);                                            &lt;&lt;&lt;&lt;----- here
                             ...
		}

[/java]
If there are now more than one audio node, the first one will be parsed multiple times. You could simple remove the loop here.

I don’t have any experience with Asset Packs so far.

And for the default position, your code is EXACTLY what I want to reduce. I will show you an example, but tomorrow.

I think that line is a mistake lol and should either be outside of the loop, or was leftover from a cut/paste that I missed.

Anxious to see your idea for positioning through styles. I think I ended up putting a few common methods together for the app I am using to put the library to practical use that center or position things for me… but really wasn’t sure how to integrate them into the library… well… the centering could vary well be a screen method, but… anyways… looking forward to seeing your approach!

I like having relative paths very much. Just make sure that relative paths mentioned inside a file are relative to the file’s location, everything else is too error-prone.
The issue is that you have to find out what the current directory was when the file you currently have in the editor was being called. Things get even worse if a third-party library fiddles with the current directory.

On the expression stuff - maybe you can leveral Spring’s Expression Language module(s). (Spring is usually a net win if you have stuff like “load module Foo only if the current user has an Admin status”. Or have other reasons to reconfigure the application on the fly.)
That said, putting logic (i.e. arithmetic calculations) into configuration just invites poor separations of concerns.

<cite>@toolforger said:</cite> I like having relative paths very much. Just make sure that relative paths mentioned inside a file are relative to the file's location, everything else is too error-prone. The issue is that you have to find out what the current directory was when the file you currently have in the editor was being called. Things get even worse if a third-party library fiddles with the current directory.

On the expression stuff - maybe you can leveral Spring’s Expression Language module(s). (Spring is usually a net win if you have stuff like “load module Foo only if the current user has an Admin status”. Or have other reasons to reconfigure the application on the fly.)
That said, putting logic (i.e. arithmetic calculations) into configuration just invites poor separations of concerns.

Thanks for this advice! Will definitely weigh in when deciding how to proceed with the current style concerns.

As for the last statement: So far, I have provided this type of thing as a static utility class (like the BitmapTextUtil class). I have a feeling that positioning/reshape will end up utilizing something like this that user is still responsible for, but saves an ass load of typing.

Now, @t0neg0d, @toolforger, a short example on how style parsing works for me now:

An excerpt from style_map.xml:
[xml]<root>
<variable key=“test15” value=“15” />
<cursors path=“Common/Cursors/Cursors.xml” />
<audio path=“Common/Audio/Audio.xml” />
<style control=“Font” path=“Fonts/Fonts.xml” />
<style control=“Common” path=“tonegod/gui/style/defAndroid/Common/Common.xml” absolute=“true” />
<style control=“Scrolling” path=“Scrolling/Scrolling.xml” absolute=“false” />

</root>
[/xml]
It introduces a custom variable. Important, every variable is stored as a String, the parsing will be done for every expression where it’s used.
The paths here are relative by default. With an optional attribute, you can change that again.

From Button.xml:

[xml]
<element name=“Button”>
<font>
<property name=“fontSize” type=“float” value=“${test15} * 2” />
<attributes>
<property name=“resizeBorders” type=“Vector4f”>
<x value=“5” />
<y value=“5” />
<z value=“5” />
<w value=“5” />
</property>
<property name=“defaultSize” type=“Vector2f”>
<x value=“${app.width} / 100 * 20” />
<y value=“${app.height} / 100 * (${test15} + 5)” />
</property>
</attributes>
<images>
<property name=“defaultImg” type=“File” value=“button_x_u.png” />
<property name=“hoverImg” type=“File” value=“button_x_h.png” />
<property name=“pressedImg” type=“File” value=“button_x_d.png” />
</images>
</element>
[/xml]
First about paths: In a <property> the type can be set to “String”, which leads to an absolute path, a “File” is always relative. If that sounds error-prone, it is very easy to implement a type “AbsoluteFile”, which would act equally to “String”.
And of course every path is relative to the file where it is stored. And that is no problem inside the parseStyle method. You’ll see that when my source became public.

Then, the expressions.

@toolforger said: On the expression stuff - maybe you can leveral Spring's Expression Language module(s). (Spring is usually a net win if you have stuff like "load module Foo only if the current user has an Admin status". Or have other reasons to reconfigure the application on the fly.) That said, putting logic (i.e. arithmetic calculations) into configuration just invites poor separations of concerns.

I did not think about using a third-prty library. I wanted to write a parser myself, which does exaclty what I want it to do. And now, thinking about it, I am still happy with my own solution. It is a small static Util class, just like BitmapTextUtil. Especially concerning Android, I see this as a good solution.

Now, how do expressions work:
EVERY float, even for colors, is parsed. Integers aren’t yet, I am still thinking about it.
The parser begins with the ${variables}, replacing them with their value. It is possible, to mention another variable inside!
Then he splits up the brackets, throwing errors when something goes wrong. But I did not test invalid input yet.
The operators are called from left to right, so you have to use brackets for more complex expressions.