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",
},
}
files["builtin/fstk"] = {
read_globals = {
"TOUCHSCREEN_GUI",
},
}

@ -1,5 +1,6 @@
--Minetest
--Copyright (C) 2014 sapier
--Copyright (C) 2023 Gregor Parzefall
--
--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
@ -16,116 +17,101 @@
--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
return ""
end
local formspec = "style_type[box;noclip=true]" ..
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]"
local formspec = {
"style_type[box;noclip=true]",
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_name = self.buttons[i].name
local btn_pos = {}
local btn_size = self.size.y - 2*BASE_SPACING
if self.orientation == "horizontal" then
btn_pos.x = self.pos.x + --base pos
(i - self.startbutton) * self.btn_size * 1.25 + --button offset
self.btn_initial_offset
else
btn_pos.x = self.pos.x + self.size.x / 2 - self.btn_size / 2
-- Spacing works like CSS Flexbox with `justify-content: space-evenly;`.
-- `BASE_SPACING` is used as the minimum spacing, like `gap` in CSS Flexbox.
-- The number of buttons per page is always calculated as if the scroll
-- buttons were visible.
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
if self.orientation == "vertical" then
btn_pos.y = self.pos.y + --base pos
(i - self.startbutton) * self.btn_size * 1.25 + --button offset
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))
for i = first_btn, first_btn + btns_per_page - 1 do
local btn = self.buttons[i]
if btn == nil then
break
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
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 show_scroll_btns then
local btn_prev_pos = {
x = self.pos.x + BASE_SPACING,
y = self.pos.y + BASE_SPACING,
}
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
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
table.insert(formspec, string.format("style[%s,%s;noclip=true]",
self.btn_prev_name, self.btn_next_name))
table.insert(formspec, string.format("button[%f,%f;%f,%f;%s;<]",
btn_prev_pos.x, btn_prev_pos.y, SCROLL_BTN_WIDTH, btn_size,
self.btn_prev_name))
table.insert(formspec, string.format("button[%f,%f;%f,%f;%s;>]",
btn_next_pos.x, btn_next_pos.y, SCROLL_BTN_WIDTH, btn_size,
self.btn_next_name))
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_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
return table.concat(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
if fields[self.btn_prev_name] and self.cur_page > 1 then
self.cur_page = self.cur_page - 1
return true
end
if fields["btnbar_dec_" .. self.name] ~= nil and self.startbutton > 1 then
self.startbutton = self.startbutton - 1
if fields[self.btn_next_name] and self.cur_page < self.num_pages then
self.cur_page = self.cur_page + 1
return true
end
for i=1,#self.buttons,1 do
if fields[self.buttons[i].name] ~= nil then
for _, btn in ipairs(self.buttons) do
if fields[btn.name] then
return self.userbuttonhandler(fields)
end
end
@ -146,69 +132,39 @@ local buttonbar_metatable = {
if image == nil then image = "" end
if tooltip == nil then tooltip = "" end
self.buttons[#self.buttons + 1] = {
table.insert(self.buttons, {
name = name,
caption = caption,
image = image,
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
tooltip = tooltip,
})
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")
function buttonbar_create(name, pos, size, bgcolor, cbf_buttonhandler)
assert(type(name) == "string" )
assert(type(pos) == "table" )
assert(type(size) == "table" )
assert(type(bgcolor) == "string" )
assert(type(cbf_buttonhandler) == "function")
local self = {}
self.name = name
self.type = "addon"
self.bgcolor = "#000000"
self.name = name
self.pos = pos
self.size = size
self.orientation = orientation
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.bgcolor = bgcolor
self.userbuttonhandler = cbf_buttonhandler
self.hidden = false
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)

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

@ -126,30 +126,27 @@ members:
File: fst/buttonbar.lua
-----------------------
buttonbar_create(name, cbf_buttonhandler, pos, orientation, size)
buttonbar_create(name, pos, size, bgcolor, cbf_buttonhandler)
^ create a buttonbar
^ 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
{
x,
y
}
^ orientation: "vertical" or "horizontal"
^ size: size of bar
{
width,
height
x,
y
}
^ bgcolor: background color as `ColorString`
^ cbf_buttonhandler: function to be called on button pressed
function(fields)
Class reference buttonbar:
methods:
- add_button(btn_id, caption, button_image)
- set_parent(parent)
^ set parent to attach a buttonbar to
^ parent: component to attach to
- add_button(name, caption, image, tooltip)
- show()
^ show buttonbar
- hide()