Rewrite the gamebar (#13768)

This commit is contained in:
Gregor Parzefall 2023-09-02 23:02:02 +02:00 committed by GitHub
parent 294ad98776
commit 83b85ba16a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 108 additions and 150 deletions

@ -81,3 +81,9 @@ files["builtin/common/tests"] = {
"assert", "assert",
}, },
} }
files["builtin/fstk"] = {
read_globals = {
"TOUCHSCREEN_GUI",
},
}

@ -1,5 +1,6 @@
--Minetest --Minetest
--Copyright (C) 2014 sapier --Copyright (C) 2014 sapier
--Copyright (C) 2023 Gregor Parzefall
-- --
--This program is free software; you can redistribute it and/or modify --This 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 --it under the terms of the GNU Lesser General Public License as published by
@ -16,116 +17,101 @@
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. --51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
local function buttonbar_formspec(self) local BASE_SPACING = 0.1
local SCROLL_BTN_WIDTH = TOUCHSCREEN_GUI and 0.8 or 0.5
local function buttonbar_formspec(self)
if self.hidden then if self.hidden then
return "" return ""
end end
local formspec = "style_type[box;noclip=true]" .. local formspec = {
string.format("box[%f,%f;%f,%f;%s]", self.pos.x, self.pos.y, self.size.x, self.size.y, self.bgcolor) .. "style_type[box;noclip=true]",
"style_type[box;noclip=false]" string.format("box[%f,%f;%f,%f;%s]", self.pos.x, self.pos.y, self.size.x,
self.size.y, self.bgcolor),
"style_type[box;noclip=false]",
}
for i=self.startbutton,#self.buttons,1 do local btn_size = self.size.y - 2*BASE_SPACING
local btn_name = self.buttons[i].name
local btn_pos = {}
if self.orientation == "horizontal" then -- Spacing works like CSS Flexbox with `justify-content: space-evenly;`.
btn_pos.x = self.pos.x + --base pos -- `BASE_SPACING` is used as the minimum spacing, like `gap` in CSS Flexbox.
(i - self.startbutton) * self.btn_size * 1.25 + --button offset
self.btn_initial_offset -- The number of buttons per page is always calculated as if the scroll
else -- buttons were visible.
btn_pos.x = self.pos.x + self.size.x / 2 - self.btn_size / 2 local avail_space = self.size.x - 2*BASE_SPACING - 2*SCROLL_BTN_WIDTH
local btns_per_page = math.floor((avail_space - BASE_SPACING) / (btn_size + BASE_SPACING))
self.num_pages = math.ceil(#self.buttons / btns_per_page)
self.cur_page = math.min(self.cur_page, self.num_pages)
local first_btn = (self.cur_page - 1) * btns_per_page + 1
local show_scroll_btns = self.num_pages > 1
-- In contrast, the button spacing calculation takes hidden scroll buttons
-- into account.
local real_avail_space = show_scroll_btns and avail_space or self.size.x
local btn_spacing = (real_avail_space - btns_per_page * btn_size) / (btns_per_page + 1)
local btn_start_x = self.pos.x + btn_spacing
if show_scroll_btns then
btn_start_x = btn_start_x + BASE_SPACING + SCROLL_BTN_WIDTH
end end
if self.orientation == "vertical" then for i = first_btn, first_btn + btns_per_page - 1 do
btn_pos.y = self.pos.y + --base pos local btn = self.buttons[i]
(i - self.startbutton) * self.btn_size * 1.25 + --button offset if btn == nil then
self.btn_initial_offset
else
btn_pos.y = self.pos.y + self.size.y / 2 - self.btn_size / 2
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]tooltip[%s;%s]",
btn_pos.x, btn_pos.y, self.btn_size, self.btn_size,
self.buttons[i].image, btn_name, self.buttons[i].caption,
borders, btn_name, self.buttons[i].tooltip)
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 break
end end
local btn_pos = {
x = btn_start_x + (i - first_btn) * (btn_size + btn_spacing),
y = self.pos.y + BASE_SPACING,
}
table.insert(formspec, string.format("image_button[%f,%f;%f,%f;%s;%s;%s;true;false]tooltip[%s;%s]",
btn_pos.x, btn_pos.y, btn_size, btn_size, btn.image, btn.name,
btn.caption, btn.name, btn.tooltip))
end end
if (self.have_move_buttons) then if show_scroll_btns then
local btn_dec_pos = {} local btn_prev_pos = {
btn_dec_pos.x = self.pos.x + (self.btn_size * 0.05) x = self.pos.x + BASE_SPACING,
btn_dec_pos.y = self.pos.y + (self.btn_size * 0.05) y = self.pos.y + BASE_SPACING,
local btn_inc_pos = {} }
local btn_size = {} local btn_next_pos = {
x = self.pos.x + self.size.x - BASE_SPACING - SCROLL_BTN_WIDTH,
y = self.pos.y + BASE_SPACING,
}
if self.orientation == "horizontal" then table.insert(formspec, string.format("style[%s,%s;noclip=true]",
btn_size.x = 0.5 self.btn_prev_name, self.btn_next_name))
btn_size.y = self.btn_size
btn_inc_pos.x = self.pos.x + self.size.x - 0.5 table.insert(formspec, string.format("button[%f,%f;%f,%f;%s;<]",
btn_inc_pos.y = self.pos.y + (self.btn_size * 0.05) btn_prev_pos.x, btn_prev_pos.y, SCROLL_BTN_WIDTH, btn_size,
else self.btn_prev_name))
btn_size.x = self.btn_size
btn_size.y = 0.5 table.insert(formspec, string.format("button[%f,%f;%f,%f;%s;>]",
btn_inc_pos.x = self.pos.x + (self.btn_size * 0.05) btn_next_pos.x, btn_next_pos.y, SCROLL_BTN_WIDTH, btn_size,
btn_inc_pos.y = self.pos.y + self.size.y - 0.5 self.btn_next_name))
end end
local text_dec = "<" return table.concat(formspec)
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_inc_%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 end
local function buttonbar_buttonhandler(self, fields) local function buttonbar_buttonhandler(self, fields)
if fields[self.btn_prev_name] and self.cur_page > 1 then
if fields["btnbar_inc_" .. self.name] ~= nil and self.cur_page = self.cur_page - 1
self.startbutton < #self.buttons then
self.startbutton = self.startbutton + 1
return true return true
end end
if fields["btnbar_dec_" .. self.name] ~= nil and self.startbutton > 1 then if fields[self.btn_next_name] and self.cur_page < self.num_pages then
self.startbutton = self.startbutton - 1 self.cur_page = self.cur_page + 1
return true return true
end end
for i=1,#self.buttons,1 do for _, btn in ipairs(self.buttons) do
if fields[self.buttons[i].name] ~= nil then if fields[btn.name] then
return self.userbuttonhandler(fields) return self.userbuttonhandler(fields)
end end
end end
@ -146,69 +132,39 @@ local buttonbar_metatable = {
if image == nil then image = "" end if image == nil then image = "" end
if tooltip == nil then tooltip = "" end if tooltip == nil then tooltip = "" end
self.buttons[#self.buttons + 1] = { table.insert(self.buttons, {
name = name, name = name,
caption = caption, caption = caption,
image = image, image = image,
tooltip = tooltip tooltip = tooltip,
} })
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, end,
} }
buttonbar_metatable.__index = buttonbar_metatable buttonbar_metatable.__index = buttonbar_metatable
function buttonbar_create(name, cbf_buttonhandler, pos, orientation, size) function buttonbar_create(name, pos, size, bgcolor, cbf_buttonhandler)
assert(name ~= nil) assert(type(name) == "string" )
assert(cbf_buttonhandler ~= nil) assert(type(pos) == "table" )
assert(orientation == "vertical" or orientation == "horizontal") assert(type(size) == "table" )
assert(pos ~= nil and type(pos) == "table") assert(type(bgcolor) == "string" )
assert(size ~= nil and type(size) == "table") assert(type(cbf_buttonhandler) == "function")
local self = {} local self = {}
self.name = name
self.type = "addon" self.type = "addon"
self.bgcolor = "#000000" self.name = name
self.pos = pos self.pos = pos
self.size = size self.size = size
self.orientation = orientation self.bgcolor = bgcolor
self.startbutton = 1
self.have_move_buttons = false
self.hidden = false
if self.btn_initial_offset == nil then
self.btn_initial_offset = 0.375
end
if self.orientation == "horizontal" then
self.btn_size = self.size.y - 2*0.1
else
self.btn_size = self.size.x - 2*0.1
end
self.userbuttonhandler = cbf_buttonhandler self.userbuttonhandler = cbf_buttonhandler
self.hidden = false
self.buttons = {} self.buttons = {}
self.num_pages = 1
self.cur_page = 1
self.btn_prev_name = "btnbar_prev_" .. self.name
self.btn_next_name = "btnbar_next_" .. self.name
setmetatable(self, buttonbar_metatable) setmetatable(self, buttonbar_metatable)

@ -81,9 +81,8 @@ function singleplayer_refresh_gamebar()
end end
end end
local btnbar = buttonbar_create("game_button_bar", local btnbar = buttonbar_create("game_button_bar", {x = 0, y = 7.475},
game_buttonbar_button_handler, {x = 15.5, y = 1.25}, "#000000", game_buttonbar_button_handler)
{x=0,y=7.475}, "horizontal", {x=15.5,y=1.25})
for _, game in ipairs(pkgmgr.games) do for _, game in ipairs(pkgmgr.games) do
local btn_name = "game_btnbar_" .. game.id local btn_name = "game_btnbar_" .. game.id

@ -126,30 +126,27 @@ members:
File: fst/buttonbar.lua File: fst/buttonbar.lua
----------------------- -----------------------
buttonbar_create(name, cbf_buttonhandler, pos, orientation, size) buttonbar_create(name, pos, size, bgcolor, cbf_buttonhandler)
^ create a buttonbar ^ create a buttonbar
^ name: name of component (unique per ui) ^ name: name of component (unique per ui)
^ cbf_buttonhandler: function to be called on button pressed
function(buttonbar,buttonname,buttondata)
^ pos: position relative to upper left of current shown formspec ^ pos: position relative to upper left of current shown formspec
{ {
x, x,
y y
} }
^ orientation: "vertical" or "horizontal"
^ size: size of bar ^ size: size of bar
{ {
width, x,
height y
} }
^ bgcolor: background color as `ColorString`
^ cbf_buttonhandler: function to be called on button pressed
function(fields)
Class reference buttonbar: Class reference buttonbar:
methods: methods:
- add_button(btn_id, caption, button_image) - add_button(name, caption, image, tooltip)
- set_parent(parent)
^ set parent to attach a buttonbar to
^ parent: component to attach to
- show() - show()
^ show buttonbar ^ show buttonbar
- hide() - hide()