[Mod] Smart Formspecs - OO builder + binding [1.1][smartfs]

User avatar
rubenwardy
Moderator
Posts: 6107
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy
Location: United Kingdom
Contact:

[Mod] Smart Formspecs - OO builder + binding [1.1][smartfs]

by rubenwardy » Post

Image

This mod provides a 2nd generation way of creating forms - this means that the modder does not need to worry about complex formspec strings*
  • Expandable: you can register your own elements to use on the form.
  • Easy event handling: use binding to handle events.
  • New elements: includes a toggle button
  • Inventories: add pages to smart inventories, without worrying about which mod is installed.
No longer do you have to use fiddly formspec strings and receive field functions, instead you use code like this:
+ Spoiler
License: CC0

To install this library, install it as a mod and depend on it,
or if you do not like doing that then place the smartfs.lua file in your mod and then include it (dofile).
There is an example.lua file in the download that shows you how to use this library.

Download / GitHub Page

* it is possible to insert custom formspec strings
Last edited by rubenwardy on Fri Oct 21, 2016 16:00, edited 5 times in total.

User avatar
fairiestoy
Member
Posts: 191
Joined: Sun Jun 09, 2013 19:25
Location: Germany

by fairiestoy » Post

Hey Ruben,
first of all, nice idea to add kind of a wrapper for that formspec strings. But one tip for handling this:
Better use it as standalone mod. This way, several modders will not have the same file and can access your
wrapper if they put it into their dependency file. Would make life easier of modders and keeps the data size
smaller due to only one folder with this files.


Greetings
Interesting about new things is, to figure out how it works ...

User avatar
rubenwardy
Moderator
Posts: 6107
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy
Location: United Kingdom
Contact:

by rubenwardy » Post

But nobody likes depending on mods, so they will just not use it.

I have added that.
Last edited by rubenwardy on Mon Oct 28, 2013 19:08, edited 1 time in total.

User avatar
fairiestoy
Member
Posts: 191
Joined: Sun Jun 09, 2013 19:25
Location: Germany

by fairiestoy » Post

Tell me if im wrong, but there are a few libraries that are used as dependency because they are helpful like plantlife. Also the amount of mods with dependencies and without are imo very averaged. But it was just a suggestion, maybe keep it optional :P
Interesting about new things is, to figure out how it works ...

User avatar
LionsDen
Member
Posts: 530
Joined: Thu Jun 06, 2013 03:19

by LionsDen » Post

Or maybe shoot to get it included as part of the minetest download. Maybe part of the default files/mod or something.

User avatar
PilzAdam
Member
Posts: 4026
Joined: Fri Jul 20, 2012 16:19
GitHub: PilzAdam
IRC: PilzAdam
Location: Germany

by PilzAdam » Post

The main problem with formspec strings is not the format, but rather the positioning. It was designed for inventory lists, so creating whole GUIs with it is a PITA.

User avatar
jojoa1997
Member
Posts: 2890
Joined: Thu Dec 13, 2012 05:11
Location: Earth

by jojoa1997 » Post

I agree. I have made my own inventory before and the hardest is the positioning. I remember reloading the game at least 50 times. Now if there was a way to see formspecs changed real time then that would be helpful.
Coding;
1X coding
3X debugging
12X tweaking to be just right

User avatar
rubenwardy
Moderator
Posts: 6107
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy
Location: United Kingdom
Contact:

by rubenwardy » Post

I could make it so you can give positions in pixels from the top left corner, but that could be hacky, and people WILL get confused.

I started work on a Formspec GUI Editor, but I got distracted. There is only a main class in that project so far, no real code at all.

You could make a mod the shows formspecs in game, but it would not have an editor.

User avatar
rubenwardy
Moderator
Posts: 6107
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy
Location: United Kingdom
Contact:

by rubenwardy » Post

Unfortunately state:close() does not currently work as there is no way to do this in the api.

User avatar
cHyper
Member
Posts: 842
Joined: Fri May 06, 2011 08:49
GitHub: cHyper-0815OL
IRC: cHyper
In-game: cHyper cHyper_0815
Location: Austria
Contact:

by cHyper » Post

rubenwardy wrote:Unfortunately state:close() does not currently work as there is no way to do this in the api.
how can i close a GUI by button anyway?
how can i activate a function by enabling a button in a formspec?

User avatar
rubenwardy
Moderator
Posts: 6107
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy
Location: United Kingdom
Contact:

by rubenwardy » Post

This element has not been added yet.

https://github.com/minetest/minetest/bl ... i.txt#L990

Code: Select all

btn:onClick(function(self,state)
    print("Button clicked!")
    self.setText("Hello")
    state:close()
end)
Last edited by rubenwardy on Thu Feb 20, 2014 20:42, edited 1 time in total.

User avatar
rubenwardy
Moderator
Posts: 6107
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy
Location: United Kingdom
Contact:

by rubenwardy » Post

Added the element

Code: Select all

local btn = state:button(0,3,2,1,"btn","Click Me")
btn:setClose(true)
btn:onClick(function(self,state)
    --run on close
end)

User avatar
cHyper
Member
Posts: 842
Joined: Fri May 06, 2011 08:49
GitHub: cHyper-0815OL
IRC: cHyper
In-game: cHyper cHyper_0815
Location: Austria
Contact:

by cHyper » Post

rubenwardy wrote:This element has not been added yet.

https://github.com/minetest/minetest/bl ... i.txt#L990

Code: Select all

btn:onClick(function(self,state)
        print("Button clicked!")
        self.setText("Hello")
        state:close()
    end)
you can add an exit button by default to close the formspec.
does this help?

User avatar
rubenwardy
Moderator
Posts: 6107
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy
Location: United Kingdom
Contact:

by rubenwardy » Post

Please read all my responses.
rubenwardy wrote: Added the element

Code: Select all

local btn = state:button(0,3,2,1,"btn","Click Me")
btn:setClose(true)
btn:onClick(function(self,state)
    --run on close
end)
EDIT: Do you mean the proceed button?
Last edited by rubenwardy on Tue Nov 05, 2013 15:18, edited 1 time in total.

User avatar
rubenwardy
Moderator
Posts: 6107
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy
Location: United Kingdom
Contact:

by rubenwardy » Post

Bump :P

User avatar
rubenwardy
Moderator
Posts: 6107
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy
Location: United Kingdom
Contact:

by rubenwardy » Post

Update!

I have added a wrapper for advanced inventories.

This means that you can add your formspec easily to smart inventories, such as inventory_plus and unified_inventory, without caring which one is installed. You don't have to modify your code for each one.

Adding to the inventory is as simple as:

Code: Select all

smartfs.add_to_inventory(myform, "icon.png", "MyFormLabel")
It works, but is quite buggy at this stage.

Any suggestions?

Have you got any suggestions, such as new elements?

I may be adding a page element (ie: start, back, 1, 2, 3, next, end)
to display stuff.
Last edited by rubenwardy on Thu Feb 20, 2014 20:51, edited 1 time in total.

User avatar
domtron vox
Member
Posts: 111
Joined: Thu Feb 20, 2014 21:07
GitHub: DomtronVox
IRC: Domtron
In-game: Domtron

by domtron vox » Post

Great Mod! I am going to try and use it for my mod.

I do have a question though. It seems like the height value has no effect on the button. Is this a problem with smartfs or is it an engine limitation(I was trying to make a square button)?

EDIT:
I'm using the smartfs.lua as a library. I got the following error. Is using "throw" a mistake or did I do something to cause the error? I replaced all "throw"s with "print" and it worked.

Code: Select all

18:31:27: ERROR[main]: ServerError: ...on/games/minetest/bin/../mods/mod_manuel/smartfs.lua:19: attempt to call global 'throw' (a nil value)
18:31:27: ERROR[main]: stack traceback:
18:31:27: ERROR[main]:     ...on/games/minetest/bin/../mods/mod_manuel/smartfs.lua:19: in function 'create'
Last edited by domtron vox on Thu Feb 20, 2014 23:37, edited 1 time in total.

User avatar
rubenwardy
Moderator
Posts: 6107
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy
Location: United Kingdom
Contact:

by rubenwardy » Post

Lua is stupid.

It uses error instead of throw. Fixed.

Also, if you look at the error:

Form <name> already exists!

You have tried making the same form twice.

eg: you made two forms called foo:bar


As for button heights, it should work.
Last edited by rubenwardy on Fri Feb 21, 2014 17:05, edited 1 time in total.

User avatar
domtron vox
Member
Posts: 111
Joined: Thu Feb 20, 2014 21:07
GitHub: DomtronVox
IRC: Domtron
In-game: Domtron

by domtron vox » Post

rubenwardy wrote:Fixed.
Always a nice thing to hear.
rubenwardy wrote:You have tried making the same form twice.
Yep, I understood since your error is quite clear. I was just referring to the throw vs. error thing.
rubenwardy wrote:As for button heights, it should work.
Then I have no clue what I'm doing wrong. :/


I'm interested in eventually using tables for my mod. I think tables were added after last stable release. If so: are you planning on implementing tables or are you aiming for compatibility with the current minetest stable?

Anyway, don't be rushed on my account. At this stage labels are working quite nicely and your library is exactly what I need. Thanks for making it.

User avatar
domtron vox
Member
Posts: 111
Joined: Thu Feb 20, 2014 21:07
GitHub: DomtronVox
IRC: Domtron
In-game: Domtron

by domtron vox » Post

Hi, I did some documentation for you. Use it, lose it, or shred it. It is yours to do with as you please. I'll write up a section on creating new elements once I get around to trying it out. ;)

I'm not 100% sure how accurate it is.

If you don't use it I would like to point out that some of your function descriptions of the label and field elements refer to button instead of label/field.
Label
...
  • element:setText( text ) - set the caption of the button
Edit: For some reason the file wouldn't upload so I put it in a spoiler:
+ Spoiler
Last edited by domtron vox on Thu Feb 27, 2014 21:46, edited 1 time in total.

User avatar
webdesigner97
Member
Posts: 1327
Joined: Mon Jul 30, 2012 19:16
GitHub: webD97
IRC: webdesigner97
In-game: webdesigner97
Location: Cologne, Germany
Contact:

by webdesigner97 » Post

Would this allow to run function on button click like this one:

Code: Select all

button:onlick(callAFunction(withButtonRelatedParam))
I hope you understand what I mean: I have a formspec with let's say 10 buttons. Whenever one of these buttons gets clicked, it should run a function with a parameter based on its e.g. label text.

User avatar
rubenwardy
Moderator
Posts: 6107
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy
Location: United Kingdom
Contact:

by rubenwardy » Post

Look good!

I will add this later. Good work!

User avatar
domtron vox
Member
Posts: 111
Joined: Thu Feb 20, 2014 21:07
GitHub: DomtronVox
IRC: Domtron
In-game: Domtron

by domtron vox » Post

webdesigner97 wrote:Would this allow to run function on button click like this one:

Code: Select all

button:onlick(callAFunction(withButtonRelatedParam))
if button is a variable that points to an element. For example if button is set using either

Code: Select all

local button = state:button(0,0, 1,4, "btn","a button")
or

Code: Select all

local button = state:get("btn")--if the button you want to get is called "btn"
in a form creation callback function(the function you pass to smartfs.create) then

Code: Select all

button:onlick(callAFunction(withButtonRelatedParam))
would work.

Here is a working example. Each time either button is pressed it adds a label to the form underneath it:

EDIT:I tweaked the code since rubenwardy said this would crash if multiple players joined a game. I tested it with a local host server and two clients.

Code: Select all

dofile(minetest.get_modpath(minetest.get_current_modname()).."/smartfs.lua")

minetest.register_on_joinplayer(function(player)

    local form = smartfs.create("test@"..player:get_player_name(),
                   function(state)

                       state:size(8,8)

                       --set variable using creation assignment
                       local button1 = state:button(0,0, 2,1, "btn1","A button")
                  
                       --set variable using state:get
                       state:button(2,0, 3,1, "btn2","Another button")
                       local button2 = state:get("btn2")

                       --incremented so each new label is in the right spot
                       local ypos1 = 2
                       local ypos2 = 2
                       
                       --button one on clicked function
                       state:get("btn1"):onClick(function(self, state)
                           state:label(0,ypos1, "lable1"..ypos1, "A label!")
                           ypos1 = ypos1 + 1
                       end)

                       --button two on clicked function
                       button2:onClick(function(self, state)
                           state:label(2,ypos2, "lable2"..ypos2, "A label!")
                           ypos2 = ypos2 + 1
                       end)                       


                   end)

    form:show(player:get_player_name())

end)
So far I haven't found a way to edit the elements of a form after creation all editing needs to be defined inside the creation callback.
Last edited by domtron vox on Tue Mar 04, 2014 15:40, edited 1 time in total.

User avatar
domtron vox
Member
Posts: 111
Joined: Thu Feb 20, 2014 21:07
GitHub: DomtronVox
IRC: Domtron
In-game: Domtron

by domtron vox » Post

And since I took the time to figure that out here are the docs on it. I put them after showing forms:
+ Spoiler
Again it is in .md format and yours to do with as you please.

User avatar
rubenwardy
Moderator
Posts: 6107
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy
Location: United Kingdom
Contact:

by rubenwardy » Post

You could edit stuff outside of the callbacks, by getting the stored states.

Code: Select all

state = smartfs.opened[name]
-- gets the open state or null.

inv = smartfs.inv[name]
-- gets the open inventory smartfs, if set.
You could then do

Code: Select all

Btn = state:get("name")
Btn:setText("new")

State:_show_()
I will add a function for this, in the future, so you don't call a private function.
Last edited by rubenwardy on Mon Mar 03, 2014 19:00, edited 1 time in total.

Post Reply

Who is online

Users browsing this forum: Google [Bot] and 5 guests