plan generation finished, selection by dropdown
npc destination search optimizations for cleanup tasks
This commit is contained in:
parent
b4f23d2b02
commit
1f12549e65
75
chest.lua
75
chest.lua
@ -16,14 +16,12 @@ local __get = function(pos)
|
||||
local this = nil
|
||||
if townchest.chest.list[key] then
|
||||
this = townchest.chest.list[key]
|
||||
dprint("get key from list", this)
|
||||
else
|
||||
this = townchest.chest.new()
|
||||
this.key = key
|
||||
this.pos = pos
|
||||
this.meta = minetest.env:get_meta(pos) --just pointer
|
||||
townchest.chest.list[key] = this
|
||||
dprint("get new key", this)
|
||||
end
|
||||
|
||||
-- update chest info
|
||||
@ -114,9 +112,16 @@ townchest.chest.new = function()
|
||||
-- Create the task that should be managed by chest
|
||||
--------------------------------------
|
||||
function chest.set_rawdata(this, taskname)
|
||||
if taskname == "file" then
|
||||
this.plan = townchest.plan.new(this)
|
||||
local we = {}
|
||||
|
||||
if taskname then
|
||||
this.info.taskname = taskname
|
||||
end
|
||||
|
||||
if this.info.taskname == "file" then
|
||||
-- check if file could be read
|
||||
local we = townchest.files.readfile(this.info.filename)
|
||||
we = townchest.files.readfile(this.info.filename)
|
||||
if not we or #we == 0 then
|
||||
this.infotext = "No building found in ".. this.info.filename
|
||||
this:set_form("status")
|
||||
@ -126,39 +131,59 @@ townchest.chest.new = function()
|
||||
minetest.after(3, this.set_form, this, "file_open") --back to file selection
|
||||
return
|
||||
end
|
||||
this.rawdata = we
|
||||
|
||||
elseif taskname == "generate" then
|
||||
local we = {}
|
||||
if this.info.genblock.fill == "true" then
|
||||
--[[ for x = -math.floor(this.info.genblock.x/2), math.floor(this.info.genblock.x/2) do
|
||||
for y = -1, this.info.genblock.y -2 do -- 1 under the chest
|
||||
for z = -math.floor(this.info.genblock.z/2), math.floor(this.info.genblock.z/2) do
|
||||
elseif this.info.taskname == "generate" then
|
||||
if this.info.genblock.variant == 1 then
|
||||
-- Fill with air
|
||||
for x = 0, this.info.genblock.x-1 do
|
||||
for y = 0, this.info.genblock.y-1 do
|
||||
for z = 0, this.info.genblock.z-1 do
|
||||
table.insert(we, {x=x,y=y,z=z, name = "air"})
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif this.info.genblock.variant == 2 then
|
||||
-- Fill with stone
|
||||
for x = 0, this.info.genblock.x-1 do
|
||||
for y = 0, this.info.genblock.y-1 do
|
||||
for z = 0, this.info.genblock.z-1 do
|
||||
table.insert(we, {x=x,y=y,z=z, name = "default:cobble"})
|
||||
end
|
||||
end
|
||||
end
|
||||
]]
|
||||
for x = -math.floor(this.info.genblock.x/2), math.floor(this.info.genblock.x/2) do
|
||||
for y = -1, this.info.genblock.y -2 do -- 1 under the chest
|
||||
for z = -math.floor(this.info.genblock.z/2), math.floor(this.info.genblock.z/2) do
|
||||
if x == -math.floor(this.info.genblock.x/2) or x == math.floor(this.info.genblock.x/2) or
|
||||
y == -1 or y == this.info.genblock.y -2 or
|
||||
z == -math.floor(this.info.genblock.z/2) or z == math.floor(this.info.genblock.z/2) then
|
||||
|
||||
elseif this.info.genblock.variant == 3 then
|
||||
-- Build a box
|
||||
for x = 0, this.info.genblock.x-1 do
|
||||
for y = 0, this.info.genblock.y-1 do
|
||||
for z = 0, this.info.genblock.z-1 do
|
||||
if x == 0 or x == this.info.genblock.x-1 or
|
||||
y == 0 or y == this.info.genblock.y-1 or
|
||||
z == 0 or z == this.info.genblock.z-1 then
|
||||
table.insert(we, {x=x,y=y,z=z, name = "default:cobble"})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
table.insert(we, {x=-math.floor(this.info.genblock.x/2),y=0,z=-math.floor(this.info.genblock.z/2), name = "air"})
|
||||
table.insert(we, {x=math.floor(this.info.genblock.x/2),y=this.info.genblock.y -1,z=math.floor(this.info.genblock.z/2), name = "air"})
|
||||
|
||||
-- build ground level under chest
|
||||
this.plan.relative.ground_y = 1
|
||||
|
||||
-- Build a plate
|
||||
elseif this.info.genblock.variant == 4 then
|
||||
local y = 0
|
||||
for x = 0, this.info.genblock.x-1 do
|
||||
for z = 0, this.info.genblock.z-1 do
|
||||
table.insert(we, {x=x,y=y,z=z, name = "default:cobble"})
|
||||
end
|
||||
end
|
||||
-- build ground level under chest
|
||||
this.plan.relative.ground_y = 1
|
||||
end
|
||||
this.rawdata = we
|
||||
end
|
||||
|
||||
this.info.taskname = taskname
|
||||
this.plan = townchest.plan.new(this)
|
||||
this.rawdata = we
|
||||
|
||||
chest:run_async(this.prepare_building_plan_chain)
|
||||
end
|
||||
|
||||
@ -300,7 +325,7 @@ townchest.chest.new = function()
|
||||
dprint("restoral info", dump(chestinfo))
|
||||
if chestinfo.taskname and not this.current_stage then -- file selected but no plan. Restore the plan
|
||||
this.current_stage = "restore"
|
||||
chest:set_rawdata(this.info.taskname)
|
||||
chest:set_rawdata(chestinfo.taskname)
|
||||
elseif not chestinfo.filename then
|
||||
this:set_form("file_open")
|
||||
end
|
||||
|
@ -1,6 +1,7 @@
|
||||
local dprint = townchest.dprint --debug
|
||||
|
||||
local MAX_SPEED = 5
|
||||
local BUILD_DISTANCE = 3
|
||||
|
||||
|
||||
townchest.npc = {
|
||||
@ -54,8 +55,6 @@ local select_chest = function(self)
|
||||
self.chest = nil
|
||||
self.chestpos = nil
|
||||
end
|
||||
else
|
||||
dprint("Chest ok:",self.chest)
|
||||
end
|
||||
end
|
||||
|
||||
@ -122,12 +121,12 @@ local function prefer_target(npc, t1, t2)
|
||||
end
|
||||
|
||||
local npcpos = npc.object:getpos()
|
||||
-- npc is 1.5 blocks over the work
|
||||
npcpos.y = npcpos.y - 1.5
|
||||
|
||||
-- variables for vectors based preference manipulation
|
||||
-- variables for preference manipulation
|
||||
local t1_c = {x=t1.pos.x, y=t1.pos.y, z=t1.pos.z}
|
||||
local t2_c = {x=t2.pos.x, y=t2.pos.y, z=t2.pos.z}
|
||||
|
||||
-- variable for value based preference manipulation
|
||||
local prefer = 0
|
||||
|
||||
--prefer same items in building order
|
||||
@ -140,37 +139,56 @@ local function prefer_target(npc, t1, t2)
|
||||
end
|
||||
end
|
||||
|
||||
-- note: npc is higher by y+1.5
|
||||
-- in case of clanup task prefer higher node
|
||||
-- prefer the last target node
|
||||
if npc.targetnode then
|
||||
if t1.x == npc.targetnode.pos.x and
|
||||
t1.y == npc.targetnode.pos.y and
|
||||
t1.z == npc.targetnode.pos.z then
|
||||
prefer = prefer + BUILD_DISTANCE
|
||||
end
|
||||
if t2.x == npc.targetnode.pos.x and
|
||||
t2.y == npc.targetnode.pos.y and
|
||||
t2.z == npc.targetnode.pos.z then
|
||||
prefer = prefer - BUILD_DISTANCE
|
||||
end
|
||||
end
|
||||
|
||||
-- prefer air in general
|
||||
if t1.name == "air" then
|
||||
prefer = prefer + 2
|
||||
end
|
||||
if t2.name == "air" then
|
||||
prefer = prefer - 2
|
||||
end
|
||||
|
||||
-- prefer lower node if not air
|
||||
if t1.name ~= "air" then
|
||||
-- calculate as over the npc by additional 1.5. no change means lower then npc by 1.5
|
||||
t1_c.y = t1_c.y + 3
|
||||
else
|
||||
-- prefer air
|
||||
t1_c.y = t1_c.y - 2
|
||||
t1_c.y = t1_c.y + 1
|
||||
elseif math.abs(npcpos.y - t1.pos.y) <= BUILD_DISTANCE then
|
||||
-- prefer higher node if air in reachable distance
|
||||
t1_c.y = t1_c.y - 4
|
||||
end
|
||||
|
||||
-- prefer lower node if not air
|
||||
if t2.name ~= "air" then
|
||||
-- calculate as over the npc by additional 1.5. no change means lower then npc by 1.5
|
||||
t2_c.y = t2_c.y + 3
|
||||
else
|
||||
-- prefer air
|
||||
t2_c.y = t2_c.y - 2
|
||||
t2_c.y = t2_c.y + 1
|
||||
elseif math.abs(npcpos.y - t1.pos.y) <= BUILD_DISTANCE then
|
||||
-- prefer higher node if air in reachable distance
|
||||
t2_c.y = t2_c.y - 4
|
||||
end
|
||||
|
||||
-- avoid build directly under or over the npc. No extra bonus for air in this case
|
||||
if math.abs(npcpos.x - t1.pos.x) < 1 and math.abs(npcpos.z - t1.pos.z) < 1 then
|
||||
prefer = prefer-2
|
||||
elseif t1.name == "air" then
|
||||
prefer = prefer+2
|
||||
-- avoid build directly under or in the npc
|
||||
if math.abs(npcpos.x - t1.pos.x) < 0.5 and
|
||||
math.abs(npcpos.y - t1.pos.y) < 2 and
|
||||
math.abs(npcpos.z - t1.pos.z) < 0.5 then
|
||||
prefer = prefer-1.5
|
||||
end
|
||||
if math.abs(npcpos.x - t2.pos.x) < 1 and math.abs(npcpos.z - t2.pos.z) < 1 then
|
||||
prefer = prefer+2
|
||||
elseif t2.name == "air" then
|
||||
prefer = prefer-2
|
||||
if math.abs(npcpos.x - t2.pos.x) < 0.5 and
|
||||
math.abs(npcpos.y - t1.pos.y) < 2 and
|
||||
math.abs(npcpos.z - t2.pos.z) < 0.5 then
|
||||
prefer = prefer+1.5
|
||||
end
|
||||
|
||||
|
||||
-- compare
|
||||
if vector.distance(npcpos, t1_c) - prefer > vector.distance(npcpos, t2_c) then
|
||||
return t2
|
||||
@ -303,7 +321,7 @@ npcf:register_npc("townchest:npcf_builder" ,{
|
||||
|
||||
yaw = npcf:get_face_direction(pos, self.targetnode.pos)
|
||||
-- target reached build
|
||||
if target_distance < 3 and self.dest_type == "build" then
|
||||
if target_distance <= BUILD_DISTANCE and self.dest_type == "build" then
|
||||
-- do the build
|
||||
local soundspec
|
||||
if minetest.registered_items[self.targetnode.name].sounds then
|
||||
@ -332,13 +350,6 @@ npcf:register_npc("townchest:npcf_builder" ,{
|
||||
if target_distance > 2 then
|
||||
speed = 1
|
||||
state = NPCF_ANIM_WALK_MINE
|
||||
|
||||
-- jump
|
||||
if self.targetnode.name ~= "air" and (self.targetnode.pos.y -(pos.y-1.5)) > 0 and (self.targetnode.pos.y -(pos.y-1.5)) < 2 then
|
||||
acceleration = {x=0, y=0, z=0}
|
||||
pos = {x=pos.x, y=self.targetnode.pos.y + 1.5, z=pos.z}
|
||||
self.object:setpos(pos)
|
||||
end
|
||||
else
|
||||
speed = 0
|
||||
state = NPCF_ANIM_MINE
|
||||
@ -359,14 +370,15 @@ npcf:register_npc("townchest:npcf_builder" ,{
|
||||
--target not reached
|
||||
state = NPCF_ANIM_WALK
|
||||
-- Big jump / teleport upsite
|
||||
if (self.targetnode.pos.y -(pos.y-1.5)) > 0 and
|
||||
math.abs(self.targetnode.pos.x - pos.x) <= 3 and
|
||||
math.abs(self.targetnode.pos.z - pos.z) <= 3 then
|
||||
if (self.targetnode.pos.y -(pos.y-1.5)) > BUILD_DISTANCE and
|
||||
math.abs(self.targetnode.pos.x - pos.x) <= 0.5 and
|
||||
math.abs(self.targetnode.pos.z - pos.z) <= 0.5 then
|
||||
acceleration = {x=0, y=0, z=0}
|
||||
pos = {x=pos.x, y=self.targetnode.pos.y + 1.5, z=pos.z}
|
||||
self.object:setpos(pos)
|
||||
target_distance = 0 -- to skip the next part and set speed to 0
|
||||
local state = NPCF_ANIM_STAND
|
||||
state = NPCF_ANIM_STAND
|
||||
dprint("Big jump to"..minetest.pos_to_string(pos))
|
||||
end
|
||||
|
||||
-- teleport in direction in case of stucking
|
||||
@ -379,6 +391,9 @@ npcf:register_npc("townchest:npcf_builder" ,{
|
||||
end
|
||||
self.object:setpos(pos)
|
||||
acceleration = {x=0, y=0, z=0}
|
||||
target_distance = 0 -- to skip the next part and set speed to 0
|
||||
state = NPCF_ANIM_STAND
|
||||
dprint("Teleport to"..minetest.pos_to_string(pos))
|
||||
end
|
||||
self.var.last_pos = pos
|
||||
speed = get_speed(target_distance)
|
||||
|
@ -1,16 +1,15 @@
|
||||
local dprint = townchest.dprint_off --debug
|
||||
|
||||
|
||||
townchest.specwidgets = {}
|
||||
|
||||
|
||||
--- temporary provide smartfs as builtin, till the needed changes are upstream
|
||||
local smartfs = townchest.smartfs
|
||||
--- temporary end
|
||||
|
||||
|
||||
-----------------------------------------------
|
||||
-- file open dialog form / (tabbed)
|
||||
-----------------------------------------------
|
||||
local _file_open_dialog = function(state)
|
||||
|
||||
--connect to chest object for data
|
||||
local chest = townchest.chest.get(state.location.pos)
|
||||
|
||||
@ -42,7 +41,9 @@ local _file_open_dialog = function(state)
|
||||
end,
|
||||
}
|
||||
|
||||
-- file selection tab button
|
||||
-----------------------------------------------
|
||||
-- file selection tab
|
||||
-----------------------------------------------
|
||||
local tab1 = {}
|
||||
tab1.button = state:button(0,0,2,1,"tab1_btn","Buildings")
|
||||
tab1.button:onClick(function(self)
|
||||
@ -58,20 +59,29 @@ local _file_open_dialog = function(state)
|
||||
end
|
||||
tab_controller:tab_add("tab1", tab1)
|
||||
|
||||
-----------------------------------------------
|
||||
-- Simple form building tab
|
||||
-----------------------------------------------
|
||||
-- Tasks tab button
|
||||
local tab2 = {}
|
||||
tab2.button = state:button(2,0,2,1,"tab2_btn","Tasks")
|
||||
tab2.button:onClick(function(self)
|
||||
tab_controller:set_active("tab2")
|
||||
end)
|
||||
tab2.view = state:view(0.5,1,"tab2_view")
|
||||
tab2.view = state:view(0,1,"tab2_view")
|
||||
tab2.viewstate = tab2.view:getViewState()
|
||||
-- Tasks tab view state
|
||||
tab2.viewstate:label(0,0,"header","Free place for a build")
|
||||
tab2.viewstate:label(0,0.2,"header","Build simple form")
|
||||
local variant = tab2.viewstate:dropdown(3.5,0.2,4,0.5,"variant", 1)
|
||||
variant:addItem("Fill with air") -- 1
|
||||
variant:addItem("Fill with stone") -- 2
|
||||
variant:addItem("Build a box") -- 3
|
||||
variant:addItem("Build a plate") -- 4
|
||||
|
||||
local field_x = tab2.viewstate:field(0,2,2,0.5,"x","width (x)")
|
||||
local field_y = tab2.viewstate:field(2,2,2,0.5,"y","high (y)")
|
||||
local field_z = tab2.viewstate:field(4,2,2,0.5,"z","width (y)")
|
||||
local fill_chk = tab2.viewstate:checkbox(0,3,"fill", "Fill place with stone")
|
||||
|
||||
tab_controller:tab_add("tab2", tab2)
|
||||
|
||||
--process all inputs
|
||||
@ -79,7 +89,8 @@ local _file_open_dialog = function(state)
|
||||
chest.info.genblock.x = tonumber(field_x:getText())
|
||||
chest.info.genblock.y = tonumber(field_y:getText())
|
||||
chest.info.genblock.z = tonumber(field_z:getText())
|
||||
chest.info.genblock.fill = fill_chk:getValue()
|
||||
chest.info.genblock.variant = variant:getSelected()
|
||||
chest.info.genblock.variant_name = variant:getSelectedItem()
|
||||
chest:persist_info()
|
||||
end)
|
||||
|
||||
@ -108,9 +119,10 @@ local _file_open_dialog = function(state)
|
||||
field_x:setText(tostring(chest.info.genblock.x or 1))
|
||||
field_y:setText(tostring(chest.info.genblock.y or 1))
|
||||
field_z:setText(tostring(chest.info.genblock.z or 1))
|
||||
fill_chk:setValue(chest.info.genblock.fill)
|
||||
variant:setSelected(chest.info.genblock.variant or 1)
|
||||
|
||||
return true --successfull build, update needed
|
||||
--successfull build, update needed
|
||||
return true
|
||||
end
|
||||
smartfs.create("file_open", _file_open_dialog)
|
||||
|
||||
@ -165,7 +177,7 @@ local _build_status = function(state)
|
||||
if chest.info.taskname == "file" then
|
||||
l1:setText("Building "..chest.info.filename.." selected")
|
||||
elseif chest.info.taskname == "generate" then
|
||||
l1:setText("Simple task")
|
||||
l1:setText("Simple task: "..chest.info.genblock.variant_name)
|
||||
end
|
||||
l2:setText("Size: "..(relative.max_x-relative.min_x).." x "..(relative.max_z-relative.min_z))
|
||||
l3:setText("Building high: "..(relative.max_y-relative.min_y).." Ground high: "..(relative.ground_y-relative.min_y))
|
||||
|
103
smartfs.lua
103
smartfs.lua
@ -742,6 +742,14 @@ function smartfs._makeState_(form, newplayer, params, is_inv, nodepos)
|
||||
transparent = transparent
|
||||
})
|
||||
end,
|
||||
dropdown = function(self, x, y, w, h, name, selected)
|
||||
return self:element("dropdown", {
|
||||
pos = {x=x, y=y},
|
||||
size = {w=w, h=h},
|
||||
name = name,
|
||||
selected = selected
|
||||
})
|
||||
end,
|
||||
inventory = function(self, x, y, w, h, name)
|
||||
return self:element("inventory", {
|
||||
pos = {x=x, y=y},
|
||||
@ -1002,7 +1010,6 @@ smartfs.element("list", {
|
||||
assert(self.data.size and self.data.size.w and self.data.size.h, "list needs valid size")
|
||||
assert(self.name, "list needs name")
|
||||
self.data.value = minetest.is_yes(self.data.value)
|
||||
self.data.label = self.data.label or ""
|
||||
self.data.items = self.data.items or {}
|
||||
end,
|
||||
build = function(self)
|
||||
@ -1041,27 +1048,17 @@ smartfs.element("list", {
|
||||
self._doubleClick = func
|
||||
end,
|
||||
addItem = function(self, item)
|
||||
if not self.data.items then
|
||||
self.data.items = {}
|
||||
end
|
||||
table.insert(self.data.items, item)
|
||||
-- return the index of item. It is the last one
|
||||
return #self.data.items
|
||||
end,
|
||||
removeItem = function(self,idx)
|
||||
if not self.data.items then
|
||||
self.data.items = {}
|
||||
end
|
||||
table.remove(self.data.items,idx)
|
||||
end,
|
||||
getItem = function(self, idx)
|
||||
if not self.data.items then
|
||||
self.data.items = {}
|
||||
end
|
||||
return self.data.items[idx]
|
||||
end,
|
||||
popItem = function(self)
|
||||
if not self.data.items then
|
||||
self.data.items = {}
|
||||
end
|
||||
local item = self.data.items[#self.data.items]
|
||||
table.remove(self.data.items)
|
||||
return item
|
||||
@ -1080,6 +1077,75 @@ smartfs.element("list", {
|
||||
end,
|
||||
})
|
||||
|
||||
smartfs.element("dropdown", {
|
||||
onCreate = function(self)
|
||||
assert(self.data.pos and self.data.pos.x and self.data.pos.y, "dropdown needs valid pos")
|
||||
assert(self.data.size and self.data.size.w and self.data.size.h, "dropdown needs valid size")
|
||||
assert(self.name, "dropdown needs name")
|
||||
self.data.items = self.data.items or {}
|
||||
self.data.selected = self.data.selected or 1
|
||||
self.data.value = ""
|
||||
end,
|
||||
build = function(self)
|
||||
return "dropdown["..
|
||||
self:getPosString()..";"..
|
||||
self:getSizeString()..";"..
|
||||
self:getAbsName()..";"..
|
||||
table.concat(self.data.items, ",")..";"..
|
||||
tostring(self:getSelected()).."]"..
|
||||
self:getBackgroundString()
|
||||
end,
|
||||
submit = function(self, field, player)
|
||||
self:getSelected()
|
||||
if self._select then
|
||||
self:_select(self.root, field, player)
|
||||
end
|
||||
end,
|
||||
onSelect = function(self, func)
|
||||
self._select = func
|
||||
end,
|
||||
addItem = function(self, item)
|
||||
table.insert(self.data.items, item)
|
||||
if #self.data.items == self.data.selected then
|
||||
self.data.value = item
|
||||
end
|
||||
-- return the index of item. It is the last one
|
||||
return #self.data.items
|
||||
end,
|
||||
removeItem = function(self,idx)
|
||||
table.remove(self.data.items,idx)
|
||||
end,
|
||||
getItem = function(self, idx)
|
||||
return self.data.items[idx]
|
||||
end,
|
||||
popItem = function(self)
|
||||
local item = self.data.items[#self.data.items]
|
||||
table.remove(self.data.items)
|
||||
return item
|
||||
end,
|
||||
clearItems = function(self)
|
||||
self.data.items = {}
|
||||
end,
|
||||
setSelected = function(self,idx)
|
||||
self.data.selected = idx
|
||||
self.data.value = self:getItem(idx) or ""
|
||||
end,
|
||||
getSelected = function(self)
|
||||
self.data.selected = 1
|
||||
if #self.data.items > 1 then
|
||||
for i = 1, #self.data.items do
|
||||
if self.data.items[i] == self.data.value then
|
||||
self.data.selected = i
|
||||
end
|
||||
end
|
||||
end
|
||||
return self.data.selected
|
||||
end,
|
||||
getSelectedItem = function(self)
|
||||
return self.data.value
|
||||
end,
|
||||
})
|
||||
|
||||
smartfs.element("inventory", {
|
||||
onCreate = function(self)
|
||||
assert(self.data.pos and self.data.pos.x and self.data.pos.y, "list needs valid pos")
|
||||
@ -1157,6 +1223,7 @@ smartfs.element("view", {
|
||||
onCreate = function(self)
|
||||
assert(self.data.pos and self.data.pos.x and self.data.pos.y, "view needs valid pos")
|
||||
assert(self.name, "view needs name")
|
||||
self._state = smartfs._makeState_(self, nil, self.root.param)
|
||||
end,
|
||||
-- redefinitions. The size is not handled by data.size but by view-state:size
|
||||
setSize = function(self,w,h)
|
||||
@ -1167,17 +1234,9 @@ smartfs.element("view", {
|
||||
end,
|
||||
-- element interface methods
|
||||
build = function(self)
|
||||
if not self:getIsHiddenOrCutted() == true then
|
||||
return self:getViewState():_buildFormspec_(false)..self:getBackgroundString()
|
||||
else
|
||||
print("SmartFS - (Warning): view outside or hidden")
|
||||
return ""
|
||||
end
|
||||
return self:getViewState():_buildFormspec_(false)..self:getBackgroundString()
|
||||
end,
|
||||
getViewState = function(self)
|
||||
if not self._state then
|
||||
self._state = smartfs._makeState_(self, nil, self.root.param)
|
||||
end
|
||||
return self._state
|
||||
end
|
||||
-- submit is handled by framework for elements with getViewState
|
||||
|
Loading…
x
Reference in New Issue
Block a user