Skip to content
Permalink
Browse files

Add formspec toolkit and refactor mainmenu to use it

Fix crash on using cursor keys in client menu without selected server
Add support for non fixed size tabviews
  • Loading branch information...
sapier sapier
sapier authored and sapier committed Apr 18, 2014
1 parent 34d8726 commit c3984569c06dc3c2890516e95adc38dcab9ec89a
@@ -16,6 +16,8 @@
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

--------------------------------------------------------------------------------
-- TODO improve doc --
-- TODO code cleanup --
-- Generic implementation of a filter/sortable list --
-- Usage: --
-- Filterlist needs to be initialized on creation. To achieve this you need to --
@@ -62,6 +64,20 @@ function filterlist.create(raw_fct,compare_fct,uid_match_fct,filter_fct,fetch_pa
this.m_processed_list = nil
this.m_raw_list = this.m_raw_list_fct(this.m_fetch_param)

this.add_sort_mechanism = filterlist.add_sort_mechanism
this.set_filtercriteria = filterlist.set_filtercriteria
this.get_filtercriteria = filterlist.get_filtercriteria
this.set_sortmode = filterlist.set_sortmode
this.get_list = filterlist.get_list
this.get_raw_list = filterlist.get_raw_list
this.get_raw_element = filterlist.get_raw_element
this.get_raw_index = filterlist.get_raw_index
this.get_current_index = filterlist.get_current_index
this.size = filterlist.size
this.uid_exists_raw = filterlist.uid_exists_raw
this.raw_index_by_uid = filterlist.raw_index_by_uid
this.refresh = filterlist.refresh

filterlist.process(this)

return this
@@ -0,0 +1,209 @@
--Minetest
--Copyright (C) 2014 sapier
--
--self program is free software; you can redistribute it and/or modify
--it under the terms of the GNU Lesser General Public License as published by
--the Free Software Foundation; either version 2.1 of the License, or
--(at your option) any later version.
--
--self program is distributed in the hope that it will be useful,
--but WITHOUT ANY WARRANTY; without even the implied warranty of
--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--GNU Lesser General Public License for more details.
--
--You should have received a copy of the GNU Lesser General Public License along
--with self program; if not, write to the Free Software Foundation, Inc.,
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.


local function buttonbar_formspec(self)

if self.hidden then
return ""
end

local formspec = string.format("box[%f,%f;%f,%f;%s]",
self.pos.x,self.pos.y ,self.size.x,self.size.y,self.bgcolor)

for i=self.startbutton,#self.buttons,1 do
local btn_name = self.buttons[i].name
local btn_pos = {}

if self.orientation == "horizontal" then
btn_pos.x = self.pos.x + --base pos
(i - self.startbutton) * self.btn_size + --button offset
self.btn_initial_offset
else
btn_pos.x = self.pos.x + (self.btn_size * 0.05)
end

if self.orientation == "vertical" then
btn_pos.y = self.pos.y + --base pos
(i - self.startbutton) * self.btn_size + --button offset
self.btn_initial_offset
else
btn_pos.y = self.pos.y + (self.btn_size * 0.05)
end

if (self.orientation == "vertical" and
(btn_pos.y + self.btn_size <= self.pos.y + self.size.y)) or
(self.orientation == "horizontal" and
(btn_pos.x + self.btn_size <= self.pos.x + self.size.x)) then

local borders="true"

if self.buttons[i].image ~= nil then
borders="false"
end

formspec = formspec ..
string.format("image_button[%f,%f;%f,%f;%s;%s;%s;true;%s]",
btn_pos.x, btn_pos.y, self.btn_size, self.btn_size,
self.buttons[i].image, btn_name, self.buttons[i].caption,
borders)
else
--print("end of displayable buttons: orientation: " .. self.orientation)
--print( "button_end: " .. (btn_pos.y + self.btn_size - (self.btn_size * 0.05)))
--print( "bar_end: " .. (self.pos.x + self.size.x))
break
end
end

if (self.have_move_buttons) then
local btn_dec_pos = {}
btn_dec_pos.x = self.pos.x + (self.btn_size * 0.05)
btn_dec_pos.y = self.pos.y + (self.btn_size * 0.05)
local btn_inc_pos = {}
local btn_size = {}

if self.orientation == "horizontal" then
btn_size.x = 0.5
btn_size.y = self.btn_size
btn_inc_pos.x = self.pos.x + self.size.x - 0.5
btn_inc_pos.y = self.pos.y + (self.btn_size * 0.05)
else
btn_size.x = self.btn_size
btn_size.y = 0.5
btn_inc_pos.x = self.pos.x + (self.btn_size * 0.05)
btn_inc_pos.y = self.pos.y + self.size.y - 0.5
end

local text_dec = "<"
local text_inc = ">"
if self.orientation == "vertical" then
text_dec = "^"
text_inc = "v"
end

formspec = formspec ..
string.format("image_button[%f,%f;%f,%f;;btnbar_dec_%s;%s;true;true]",
btn_dec_pos.x, btn_dec_pos.y, btn_size.x, btn_size.y,
self.name, text_dec)

formspec = formspec ..
string.format("image_button[%f,%f;%f,%f;;btnbar_dec_%s;%s;true;true]",
btn_inc_pos.x, btn_inc_pos.y, btn_size.x, btn_size.y,
self.name, text_inc)
end

return formspec
end

local function buttonbar_buttonhandler(self, fields)

if fields["btnbar_inc_" .. self.name] ~= nil and
self.startbutton < #self.buttons then

self.startbutton = self.startbutton + 1
return true
end

if fields["btnbar_dec_" .. self.name] ~= nil and self.startbutton > 1 then
self.startbutton = self.startbutton - 1
return true
end

for i=1,#self.buttons,1 do
if fields[self.buttons[i].name] ~= nil then
return self.userbuttonhandler(fields)
end
end
end

local buttonbar_metatable = {
handle_buttons = buttonbar_buttonhandler,
handle_events = function(self, event) end,
get_formspec = buttonbar_formspec,

hide = function(self) self.hidden = true end,
show = function(self) self.hidden = false end,

delete = function(self) ui.delete(self) end,

add_button = function(self, name, caption, image)
if caption == nil then caption = "" end
if image == nil then image = "" end

table.insert(self.buttons,{ name=name, caption=caption, image=image})
if self.orientation == "horizontal" then
if ( (self.btn_size * #self.buttons) + (self.btn_size * 0.05 *2)
> self.size.x ) then

self.btn_initial_offset = self.btn_size * 0.05 + 0.5
self.have_move_buttons = true
end
else
if ((self.btn_size * #self.buttons) + (self.btn_size * 0.05 *2)
> self.size.y ) then

self.btn_initial_offset = self.btn_size * 0.05 + 0.5
self.have_move_buttons = true
end
end
end,

set_bgparams = function(self, bgcolor)
if (type(bgcolor) == "string") then
self.bgcolor = bgcolor
end
end,
}

buttonbar_metatable.__index = buttonbar_metatable

function buttonbar_create(name, cbf_buttonhandler, pos, orientation, size)
assert(name ~= nil)
assert(cbf_buttonhandler ~= nil)
assert(orientation == "vertical" or orientation == "horizontal")
assert(pos ~= nil and type(pos) == "table")
assert(size ~= nil and type(size) == "table")

local self = {}
self.name = name
self.type = "addon"
self.bgcolor = "#000000"
self.pos = pos
self.size = size
self.orientation = orientation
self.startbutton = 1
self.have_move_buttons = false
self.hidden = false

if self.orientation == "horizontal" then
self.btn_size = self.size.y
else
self.btn_size = self.size.x
end

if (self.btn_initial_offset == nil) then
self.btn_initial_offset = self.btn_size * 0.05
end

self.userbuttonhandler = cbf_buttonhandler
self.buttons = {}

setmetatable(self,buttonbar_metatable)

ui.add(self)
return self
end
@@ -0,0 +1,69 @@
--Minetest
--Copyright (C) 2014 sapier
--
--self program is free software; you can redistribute it and/or modify
--it under the terms of the GNU Lesser General Public License as published by
--the Free Software Foundation; either version 2.1 of the License, or
--(at your option) any later version.
--
--self program is distributed in the hope that it will be useful,
--but WITHOUT ANY WARRANTY; without even the implied warranty of
--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--GNU Lesser General Public License for more details.
--
--You should have received a copy of the GNU Lesser General Public License along
--with self program; if not, write to the Free Software Foundation, Inc.,
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

local function dialog_event_handler(self,event)
if self.user_eventhandler == nil or
self.user_eventhandler(event) == false then

--close dialog on esc
if event == "MenuQuit" then
self:delete()
return true
end
end
end

local dialog_metatable = {
eventhandler = dialog_event_handler,
get_formspec = function(self)
if not self.hidden then return self.formspec(self.data) end
end,
handle_buttons = function(self,fields)
if not self.hidden then return self.buttonhandler(self,fields) end
end,
handle_events = function(self,event)
if not self.hidden then return self.eventhandler(self,event) end
end,
hide = function(self) self.hidden = true end,
show = function(self) self.hidden = false end,
delete = function(self)
if self.parent ~= nil then
self.parent:show()
end
ui.delete(self)
end,
set_parent = function(self,parent) self.parent = parent end
}
dialog_metatable.__index = dialog_metatable

function dialog_create(name,get_formspec,buttonhandler,eventhandler)
local self = {}

self.name = name
self.type = "toplevel"
self.hidden = true
self.data = {}

self.formspec = get_formspec
self.buttonhandler = buttonhandler
self.user_eventhandler = eventhandler

setmetatable(self,dialog_metatable)

ui.add(self)
return self
end

0 comments on commit c398456

Please sign in to comment.
You can’t perform that action at this time.