[Solved][But still opened ^^]Nifty custom controls, xml definition, creator and builders

Hi again,



This is my second question today (and i promess i’ll stop the spam for a bit after). I am working on this issue without success for 4 days now and its really frustrating :frowning:



So, i would like to know what is the simpliest way to :

1 - define a custom control in an xml file, and add this control somewhere on the screen while in “runtime” (after a button was pressed)

2 - do the same with a java definition of the control



Before some of you get angry and tells me to read the faq, tutorial, … please note that I looked at :

a) all the tutorials on this site about niftyGui

b) the nifty bible (read especially the chapter about creating new controls)

c) tried to understand the way custom controls are done in the NiftyGuiDemo ( but seems they always extend a control already define in the basic libraries → so i miss the simple part :frowning: )

d) tried to google this and search inside this forum



I am already able to create this simple custom control and call it directly inside my screen xml definition :

[xml]<?xml version=“1.0” encoding=“UTF-8”?>

<nifty xmlns=“http://nifty-gui.sourceforge.net/nifty.xsd” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance

xsi:schemaLocation=“http://nifty-gui.sourceforge.net/nifty.xsd http://nifty-gui.sourceforge.net/nifty.xsd”>

<useStyles filename=“nifty-default-styles.xml” />

<useControls filename=“nifty-default-controls.xml” />



<controlDefinition name=“custom”>

<panel childLayout=“center” width=“100%” padding=“20px”>

<text font=“aurulent-sans-16.fnt” color="#000f" text=“TRALALA” align=“center” valign=“center”/>

</panel>

</controlDefinition>



<screen id=“testScreen” controller=“test.MyScreenController”>

<layer id=“background” childLayout=“vertical” backgroundColor="#ffff">

<control name=“custom” backgroundColor="#f00f" />

<control name=“custom” backgroundColor="#f70f" />

<control name=“custom” backgroundColor="#087f" />



<control name=“button” label=“Add” id=“StartButton” align=“center” valign=“center”

visibleToMouse=“true”>

<interact onClick=“add” />

</control>

</layer>

</screen>



</nifty>[/xml]

The sample control before is based on one that void256 gave to someone in a topic before.



Is their a need of a java definition file since the definition is already done in the xml? I mean does nifty create some stuff like this by his own when it parse the xml?



I tried also to see how the controls where defined in the libraries but i can’t explorate the code when i see “//compiled code” :(. Not that i would be skilled enough for sure to understand it but it doesn’t help :D.



Also i tried to take the xml control definition into a separate xml, add it using addXml, and still instantiate it the same in the screen definition => it works fine. But if i use nifty.loadControlFile("") as it is used in the SimpleDemo.java of NiftyGuiDemo it doesn’t work => what am I missing here?



Lastly, what is the right way to add it to an Element on the screen (in a method called when a button is pressed)? I tried to do stuff like nifty.getCurrentScreen().findElementByName(“IdOfTheParent”) then to do something like add on the Element returned but doesn’t work. Is it because the class definition of builders / creators I tried are bad or because this just isn’t the way to add an Element on a currently used screen?



Sorry again if my questions seems to “noobish” but I just feel so stuck here and i can ensure you I really am looking at this issue for nearly a week.

2 Likes

Don’t overexcuse yourself. You’re asking for tricky stuff, so I think this is a proper question.



When Nifty loads your screen.xml you wrote in your post, it is aware of everything you’ve done there. So it knows that the control-def exists and you do not have to redo this in java.



To add an element dynamically you have to create your element with a builder-instance. So for example if you want to create a new panel you have to do this:



[java]

PanelBuilder b = new PanelBuilder();



//the following three lines are only to make the result visible

b.width(“100px”);

b.height(“100px”);

b.backgroundColor(“ffffffff”);



//this is the important line

b.build(nifty, yourScreen, theParentWhereYouWantToAttachTheNewPanel);

[/java]



The same for controls (doesn’t matter if you mean standard or custom-controls. At the end, they are all the same).



[java]

ControlBuilder c = new ControlBuilder(“custom”); //or whatever name your control-def has.



c.build(nifty, screen, parent);

[/java]



And done. just make sure the layout of the parent-element provides enough space for new elements.

1 Like

Unfortunately I’ve not actually written any custom controls so I can’t be a big help. I’ve actually found that I don’t need them, just using images/text with effects and suchlike combined with a few of the existing controls (mostly text field and drop down list) has given me everything I’ve needed.



It is possible to see the code if you follow the instructions here. https://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Build_from_Source



You will find that helps a lot since you can open up the existing controls and see how they work etc.

1 Like

Many thanks to both of you. Played for half an hour with your code sample and links and its promising :

  • @ceiphren => Panel building and “attaching/binding” works fine with your code sample, its nearly ok for my custom control but i’ll try some more, i think i can figure the rest on my own

    -@zarch => real precious link you gave me here, i was able to build a custom control builder and creator looking at the panel builder code! Will try tomorrow to install maven and git (i know git but not maven).



    As for the previous topic i’ll will let it open until i figure a complete custom control creator, builder and stuff ok and i’ll post the code of it. If i succeed i tag it [Solved] else i’ll enquiry again :D. Hope i can make it for tomorow lunch time.
1 Like

Hello folks,



Well I did succeed in creating a custom control using an xml definition of it and instanciate it with java.



So here are the simple custom control code samples.



Xml definition (which I have put in “Project Assets/Interface/Controls/simple.xml) :

[xml]

<controlDefinition name=“simple”>

<panel childLayout=“center” width=“100%” padding=“20px”>

<text font=“aurulent-sans-16.fnt” color=”#000f" text="$text" align=“center” valign=“center”/>

</panel>

</controlDefinition>

[/xml]



Its a simple panel with a variable text.



I can simply create it inside a screen definition, e.g. :

[xml]

<screen id=“testScreen” controller=“mygame.MyScreenController”>

<layer id=“background” childLayout=“vertical” backgroundColor="#ffff">

<control name=“simple” backgroundColor="#f00f" text=“toto”/>

<control name=“simple” backgroundColor="#f70f" text=“titi”/>

<control name=“simple” backgroundColor="#087f" text=“tutu”/>



<control name=“button” label=“Add” id=“StartButton” align=“center” valign=“center”

visibleToMouse=“true”>

<interact onClick=“add()” />

</control>



<panel id=“putItHere” width=“100%” height=“75%” backgroundColor="#000f" childLayout=“vertical”>

</panel>

</layer>

</screen>

[/xml]



And i can also create some more in my add method of mygame.MyScreenController :

[java]

ControlBuilder c = new ControlBuilder(“simple”);

c.backgroundColor("#070f");

c.parameter(“text”, “Yeeppeeeeeeee!”);

c.build(nifty, nifty.getCurrentScreen(), nifty.getCurrentScreen().findElementByName(“putItHere”));

[/java]



That’s for the simple custom control.



Then i tried to look more in detail at panelBuilder, but looking at it seems like doing dangerous exploration for my brain : it is simple at start then you come to the Types that extend ElementType, it seems nice since this allow you even to define the tag of your Element () in our case. But well do I need to define custom tags? No.



So I looked at the Button controls. I was happy to see its partly defined in Xml wich is more in my way of thinking the controls (structure in Xml, specificities in Java) but to be honest it is way beyond my coding capacity to understand how its really done. My brain popped out of my head when I saw : controller=“de.lessvoid.nifty.controls.button.ButtonControl” in the xml button definition and saw that this ButttonControl class is … deprecated :smiley:



@zarch : I understand that for doing simple controls as the one I wrote here you can have the same result using builders (wich I believe is the reason why you didn’t feeled creating some customs). But I don’t see how you can mix Xml definitions and builders without going custom and I really like the Xml way :stuck_out_tongue:



I’ll put the [Solved] tag now, if anybody want’s to react and make me less stupid or else just please go on I will continue to follow my topic.

1 Like

I believe (I’m just guessing based on what I’ve seen) that they are deprecated to get people to move over to using the interfaces to access them - but in fact they aren’t “deprecated” in the traditional sense.



I.e. to external users they are deprecated, not for internal use by nifty.

1 Like

“Deprecating” the control implementations have been a slight mistake in retrospect. This was done only to assist users when the special standard control API interfaces has been introduced. It is quite a bit irritating for new users that look into the source :slight_smile:



In the past you would call element.findControl(ButtonControl.class) which would give you the actual implementation of the Button control. Since this ButtonControl gave you access to internal Nifty methods this has been changed to element.findNiftyControl(Button.class). Button is an interface and is a special designed public API to represent a button control in Nifty.



However you can still use the old code element.findControl(ButtonControl.class) and access the old class. So deprecating this class was used to give users a hint to not use this class anymore. In that respect - from the Nifty user perspective - it is indeed really “deprecated”.



I think it will be best to make the control classes package private or move them to some other package in the future. This will break existing code that still use the “old” way (deprecated!) but would be a lot clearer when you actually look into Niftys source code.

2 Likes

Just label these classes as internal.

Breaking existing code doesn’t make friends.

(I stumbled over the same deprecation irritation.)