From 18a73574d6df3582daff02c0b5d7710a6db8a81c Mon Sep 17 00:00:00 2001 From: Rubenwardy Date: Mon, 28 Oct 2013 14:50:00 +0000 Subject: [PATCH] Initial Push --- .gitattributes | 22 +++ .gitignore | 215 +++++++++++++++++++++ example.smartfs | 1 + init.lua | 43 +++++ smartfs.lua | 489 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 770 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 example.smartfs create mode 100644 init.lua create mode 100644 smartfs.lua diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..412eeda --- /dev/null +++ b/.gitattributes @@ -0,0 +1,22 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp +*.sln merge=union +*.csproj merge=union +*.vbproj merge=union +*.fsproj merge=union +*.dbproj merge=union + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b9d6bd9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,215 @@ +################# +## Eclipse +################# + +*.pydevproject +.project +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.classpath +.settings/ +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# CDT-specific +.cproject + +# PDT-specific +.buildpath + + +################# +## Visual Studio +################# + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results + +[Dd]ebug/ +[Rr]elease/ +x64/ +build/ +[Bb]in/ +[Oo]bj/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.log +*.scc + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +*.ncrunch* +.*crunch*.local.xml + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.Publish.xml +*.pubxml + +# NuGet Packages Directory +## TODO: If you have NuGet Package Restore enabled, uncomment the next line +#packages/ + +# Windows Azure Build Output +csx +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.[Pp]ublish.xml +*.pfx +*.publishsettings + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +App_Data/*.mdf +App_Data/*.ldf + +############# +## Windows detritus +############# + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Mac crap +.DS_Store + + +############# +## Python +############# + +*.py[co] + +# Packages +*.egg +*.egg-info +dist/ +build/ +eggs/ +parts/ +var/ +sdist/ +develop-eggs/ +.installed.cfg + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox + +#Translations +*.mo + +#Mr Developer +.mr.developer.cfg diff --git a/example.smartfs b/example.smartfs new file mode 100644 index 0000000..cbbaabf --- /dev/null +++ b/example.smartfs @@ -0,0 +1 @@ +return { ["ele"] = { ["c"] = { ["pos"] = { ["y"] = 1, ["x"] = 1 }, ["label"] = "Check", ["value"] = true, ["type"] = "checkbox", ["name"] = "c" }, ["btn"] = { ["pos"] = { ["y"] = 2, ["x"] = 1 }, ["size"] = { ["h"] = 1, ["w"] = 1 }, ["value"] = "Button", ["type"] = "button", ["name"] = "btn" } }, ["size"] = { ["h"] = 3, ["w"] = 5 } } \ No newline at end of file diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..437ac2b --- /dev/null +++ b/init.lua @@ -0,0 +1,43 @@ +dofile(minetest.get_modpath("smartfs").."/smartfs.lua") + +s = smartfs.create("smartfs:form",function(state) + state:size(10,7) + state:label(2,0,"lbl","SmartFS example formspec!") + state:field(7,1,3,1,"txt","Textbox") + state:image(0,0,2,2,"img","default_stone.png") + state:toggle(0,2,3,1,"tg",{"plenty..","of..","custom..","elements"}) + state:checkbox(2,1,"c","Easy code",true) + local res = "smartfs.create(\"smartfs:form\",function(state)\n" + res = res .. "\tstate:size(10,7)\n" + res = res .. "\tstate:label(2,0,\"lbl\",\"SmartFS example formspec!\")\n" + res = res .. "\tstate:field(7,1,3,1,\"txt\",\"Textbox\")\n" + res = res .. "\tstate:image(0,0,2,2,\"img\",\"default_stone.png\")\n" + res = res .. "\tstate:toggle(0,2,3,1,\"tg\",{\"plenty..\",\"of..\",\"custom..\",\"elements\"})\n" + res = res .. "\tstate:checkbox(2,1,\"c\",\"Easy code\",true)\n" + res = res .. "end)" + state:textarea(1,3.5,9,4,"ta","Code:"):setText(res) + return true +end) + +l = smartfs.create("smartfs:load",function(state) + state:load(minetest.get_modpath("smartfs").."/example.smartfs") + state:get("btn"):onClick(function(self,state) + print("Button clicked!") + end) + return true +end) + +minetest.register_chatcommand("s", { + params = "", + description = "SmartFS test formspec 1: basics", + func = function(name, param) + s:show(name) + end, +}) +minetest.register_chatcommand("l", { + params = "", + description = "SmartFS test formspec 2: loading", + func = function(name, param) + l:show(name) + end, +}) \ No newline at end of file diff --git a/smartfs.lua b/smartfs.lua new file mode 100644 index 0000000..8a54dc2 --- /dev/null +++ b/smartfs.lua @@ -0,0 +1,489 @@ +--------------------------- +-- SmartFS: Smart Formspecs +-- by Rubenwardy +--------------------------- + +smartfs = { + _fdef = {}, + _edef = {}, + opened = {} +} + +----------------------------------------------------------------- +-------------------------- THE API ---------------------------- +----------------------------------------------------------------- + +-- Register forms and elements +function smartfs.create(name,onload) + if smartfs._fdef[name] then + throw("Form "..name.." already exists!") + end + + smartfs._fdef[name] = { + _reg = onload, + name = name, + show = smartfs._show_ + } + + return smartfs._fdef[name] +end +function smartfs.element(name,data) + if smartfs._edef[name] then + throw("Element type "..name.." already exists!") + end + smartfs._edef[name] = data + return smartfs._edef[name] +end + +-- Show a formspec to a user +function smartfs._show_(form,player) + local state = { + _ele = {}, + def = form, + player = player, + get = function(self,name) + return self._ele[name] + end, + close = function(self) + self.closed = true + end, + size = function(self,w,h) + self._size = {w=w,h=h} + end, + _show_ = function(self) + local res = "" + if self._size then + res = "size["..self._size.w..","..self._size.h.."]" + end + for key,val in pairs(self._ele) do + res = res .. val:build() + end + print ("FS: "..res) + minetest.show_formspec(player,form.name,res) + return res + end, + load = function(self,file) + local file = io.open(file, "r") + if file then + local table = minetest.deserialize(file:read("*all")) + if type(table) == "table" then + if table.size then + self._size = table.size + end + for key,val in pairs(table.ele) do + self:element(val.type,val) + end + return true + end + end + return false + end, + save = function(self,file) + local res = {ele={}} + + if self._size then + res.size = self._size + end + + for key,val in pairs(self._ele) do + res.ele[key] = val.data + end + + local file = io.open(file, "w") + if file then + file:write(minetest.serialize(res)) + file:close() + return true + end + return false + end, + button = function(self,x,y,w,h,name,text) + return self:element("button",{pos={x=x,y=y},size={w=w,h=h},name=name,value=text}) + end, + label = function(self,x,y,name,text) + return self:element("label",{pos={x=x,y=y},name=name,value=text}) + end, + toggle = function(self,x,y,w,h,name,list) + return self:element("toggle",{pos={x=x,y=y},size={w=w,h=h},name=name,id=1,list=list}) + end, + field = function(self,x,y,w,h,name,label) + return self:element("field",{pos={x=x,y=y},size={w=w,h=h},name=name,value="",label=label}) + end, + pwdfield = function(self,x,y,w,h,name,label) + local res = self:element("field",{pos={x=x,y=y},size={w=w,h=h},name=name,value="",label=label}) + res:isPassword(true) + return res + end, + textarea = function(self,x,y,w,h,name,label) + local res = self:element("field",{pos={x=x,y=y},size={w=w,h=h},name=name,value="",label=label}) + res:isMultiline(true) + return res + end, + image = function(self,x,y,w,h,name,img) + return self:element("image",{pos={x=x,y=y},size={w=w,h=h},name=name,value=img}) + end, + checkbox = function(self,x,y,name,label,selected) + return self:element("checkbox",{pos={x=x,y=y},name=name,value=selected,label=label}) + end, + element = function(self,typen,data) + local type = smartfs._edef[typen] + + if not type then + throw("Element type "..typen.." does not exist!") + end + + if self._ele[data.name] then + throw("Element "..data.name.." already exists") + end + data.type = typen + + local ele = { + name = data.name, + root = self, + data = data, + remove = function(self) + self.root._ele[self.name] = nil + end + } + + for key,val in pairs(type) do + ele[key] = val + end + + self._ele[data.name] = ele + + return self._ele[data.name] + end + } + if form._reg(state)~=false then + smartfs.opened[player] = state + state:_show_() + end +end + +-- Receive fields from formspec +minetest.register_on_player_receive_fields(function(player, formname, fields) + local name = player:get_player_name() + if smartfs.opened[name] then + if smartfs.opened[name].def.name == formname then + local state = smartfs.opened[name] + for key,val in pairs(fields) do + if state._ele[key] then + state._ele[key].data.value = val + end + end + for key,val in pairs(state._ele) do + if val.submit then + val:submit(fields) + end + end + if state.closed ~= true then + state:_show_() + else + minetest.show_formspec(name,"","size[5,1]label[0,0;Formspec closing not yet created!]") + smartfs.opened[name] = nil + end + return true + else + smartfs.opened[name] = nil + end + end + return false +end) + + +----------------------------------------------------------------- +------------------------- ELEMENTS ---------------------------- +----------------------------------------------------------------- + +smartfs.element("button",{ + build = function(self) + if self.data.img then + return "image_button[".. + self.data.pos.x..","..self.data.pos.y.. + ";".. + self.data.size.w..","..self.data.size.h.. + ";".. + self.data.img.. + ";".. + self.name.. + ";".. + self.data.value.. + "]" + else + return "button[".. + self.data.pos.x..","..self.data.pos.y.. + ";".. + self.data.size.w..","..self.data.size.h.. + ";".. + self.name.. + ";".. + self.data.value.. + "]" + end + end, + submit = function(self,fields) + if fields[self.name] and self._click then + self:_click(self.root) + end + end, + setPosition = function(self,x,y) + self.data.pos = {x=x,y=y} + end, + getPosition = function(self,x,y) + return self.data.pos + end, + setSize = function(self,w,h) + self.data.size = {w=w,h=h} + end, + getSize = function(self,x,y) + return self.data.size + end, + onClick = function(self,func) + self._click = func + end, + setText = function(self,text) + self.data.value = text + end, + getText = function(self) + return self.data.value + end, + setImage = function(self,image) + self.data.img = image + end, + getImage = function(self) + return self.data.img + end +}) + +smartfs.element("toggle",{ + build = function(self) + return "button[".. + self.data.pos.x..","..self.data.pos.y.. + ";".. + self.data.size.w..","..self.data.size.h.. + ";".. + self.name.. + ";".. + self.data.list[self.data.id].. + "]" + end, + submit = function(self,fields) + if fields[self.name] then + self.data.id = self.data.id + 1 + if self.data.id > #self.data.list then + self.data.id = 1 + end + if self._tog then + self:_tog(self.root) + end + end + end, + onToggle = function(self,func) + self._tog = func + end, + setPosition = function(self,x,y) + self.data.pos = {x=x,y=y} + end, + getPosition = function(self,x,y) + return self.data.pos + end, + setSize = function(self,w,h) + self.data.size = {w=w,h=h} + end, + getSize = function(self,x,y) + return self.data.size + end, + setId = function(self,id) + self.data.id = id + end, + getId = function(self) + return self.data.id + end, + getText = function(self) + return self.data.list[self.data.id] + end +}) + +smartfs.element("label",{ + build = function(self) + return "label[".. + self.data.pos.x..","..self.data.pos.y.. + ";".. + self.data.value.. + "]" + end, + setPosition = function(self,x,y) + self.data.pos = {x=x,y=y} + end, + getPosition = function(self,x,y) + return self.data.pos + end, + setText = function(self,text) + self.data.value = text + end, + getText = function(self) + return self.data.value + end +}) + +smartfs.element("field",{ + build = function(self) + if self.data.ml then + return "textarea[".. + self.data.pos.x..","..self.data.pos.y.. + ";".. + self.data.size.w..","..self.data.size.h.. + ";".. + self.name.. + ";".. + self.data.label.. + ";".. + self.data.value.. + "]" + elseif self.data.pwd then + return "pwdfield[".. + self.data.pos.x..","..self.data.pos.y.. + ";".. + self.data.size.w..","..self.data.size.h.. + ";".. + self.name.. + ";".. + self.data.label.. + "]" + else + return "field[".. + self.data.pos.x..","..self.data.pos.y.. + ";".. + self.data.size.w..","..self.data.size.h.. + ";".. + self.name.. + ";".. + self.data.label.. + ";".. + self.data.value.. + "]" + end + end, + setPosition = function(self,x,y) + self.data.pos = {x=x,y=y} + end, + getPosition = function(self,x,y) + return self.data.pos + end, + setSize = function(self,w,h) + self.data.size = {w=w,h=h} + end, + getSize = function(self,x,y) + return self.data.size + end, + setText = function(self,text) + self.data.value = text + end, + getText = function(self) + return self.data.value + end, + isPassword = function(self,bool) + self.data.pwd = bool + end, + isMultiline = function(self,bool) + self.data.ml = bool + end +}) + +smartfs.element("image",{ + build = function(self) + return "image[".. + self.data.pos.x..","..self.data.pos.y.. + ";".. + self.data.size.w..","..self.data.size.h.. + ";".. + self.data.value.. + "]" + end, + setPosition = function(self,x,y) + self.data.pos = {x=x,y=y} + end, + getPosition = function(self,x,y) + return self.data.pos + end, + setSize = function(self,w,h) + self.data.size = {w=w,h=h} + end, + getSize = function(self,x,y) + return self.data.size + end, + setImage = function(self,text) + self.data.value = text + end, + getImage = function(self) + return self.data.value + end +}) + +smartfs.element("checkbox",{ + build = function(self) + if self.data.value then + return "checkbox[".. + self.data.pos.x..","..self.data.pos.y.. + ";".. + self.name.. + ";".. + self.data.label.. + ";true]" + else + return "checkbox[".. + self.data.pos.x..","..self.data.pos.y.. + ";".. + self.name.. + ";".. + self.data.label.. + ";false]" + end + end, + setPosition = function(self,x,y) + self.data.pos = {x=x,y=y} + end, + getPosition = function(self,x,y) + return self.data.pos + end, + setSize = function(self,w,h) + self.data.size = {w=w,h=h} + end, + getSize = function(self,x,y) + return self.data.size + end, + setText = function(self,text) + self.data.value = text + end, + getText = function(self) + return self.data.value + end +}) + +smartfs.element("code",{ + build = function(self) + if self._build then + self:_build() + end + + return self.data.code + end, + submit = function(self,fields) + if self._sub then + self:_sub(fields) + end + end, + onSubmit = function(self,func) + self._sub = func + end, + onBuild = function(self,func) + self._build = func + end, + setCode = function(self,code) + self.data.code = code + end, + getCode = function(self) + return self.data.code + end +}) \ No newline at end of file