classroom/gui_dash.lua

429 lines
9.8 KiB
Lua

local S = classroom.S
local FS = classroom.FS
local infos = {
{
title = S"Shout?",
type = "priv",
privs = { shout = true },
},
{
title = S"Fly?",
type = "priv",
privs = { fly = true },
},
{
title = S"Fast?",
type = "priv",
privs = { fast = true },
},
}
local function get_group(context)
if context and context.groupname then
return classroom.get_group_students(context.groupname)
else
return classroom.get_students()
end
end
local function check_perm(player)
return minetest.check_player_privs(player:get_player_name(), { teacher = true })
end
local DASHBOARD_HEADER = "formspec_version[3]size[10.5,10.85]"
local function get_formspec(player, context)
if not check_perm(player) then
return "label[0,0;" .. FS"Access denied" .. "]"
end
local fs = {
"container[0.375,1.1]",
"tablecolumns[color;text",
}
context.select_toggle = context.select_toggle or "all"
for i, col in pairs(infos) do
fs[#fs + 1] = ";color;text,align=center"
if i == 1 then
fs[#fs + 1] = ",padding=2"
end
end
fs[#fs + 1] = "]"
do
fs[#fs + 1] = "tabheader[0,0;5.375,0.8;group;"
fs[#fs + 1] = FS"All"
local selected_group_idx = 1
local i = 2
for name, group in pairs(classroom.get_all_groups()) do
fs[#fs + 1] = ","
fs[#fs + 1] = minetest.formspec_escape(name)
if context.groupname and name == context.groupname then
selected_group_idx = i
end
i = i + 1
end
fs[#fs + 1] = ";"
fs[#fs + 1] = tostring(selected_group_idx)
fs[#fs + 1] = ";false;true]"
end
fs[#fs + 1] = "table[0,0;5.375,9.375;students;,Name"
for _, col in pairs(infos) do
fs[#fs + 1] = ",," .. col.title
end
local students = get_group(context)
local selection_id = ""
context.students = table.copy(students)
for i, student in pairs(students) do
fs[#fs + 1] = ",,"
fs[#fs + 1] = minetest.formspec_escape(student)
if student == context.selected_student then
selection_id = tostring(i + 1)
end
for _, col in pairs(infos) do
local color, value
if col.type == "priv" then
local has_priv = minetest.check_player_privs(student, col.privs)
color = has_priv and "green" or "red"
value = has_priv and FS"Yes" or FS"No"
end
fs[#fs + 1] = ","
fs[#fs + 1] = color
fs[#fs + 1] = ","
fs[#fs + 1] = minetest.formspec_escape(value)
end
end
fs[#fs + 1] = ";"
fs[#fs + 1] = selection_id
fs[#fs + 1] = "]"
fs[#fs + 1] = "container_end[]"
fs[#fs + 1] = "container[6.125,0.375]"
fs[#fs + 1] = "button[0,0;1.4,0.8;new_group;"
fs[#fs + 1] = FS"New Group"
fs[#fs + 1] = "]"
if context.groupname then
fs[#fs + 1] = "button[1.6,0;1.4,0.8;edit_group;"
fs[#fs + 1] = FS"Edit Group"
fs[#fs + 1] = "]"
else
fs[#fs + 1] = "box[1.6,0;1.5,0.8;#222]"
fs[#fs + 1] = "label[1.8,0.4;"
fs[#fs + 1] = FS"Edit Group"
fs[#fs + 1] = "]"
fs[#fs + 1] = "tooltip[1.6,0;1.4,1;"
fs[#fs + 1] = FS"Please select a group first"
fs[#fs + 1] = "]"
end
fs[#fs + 1] = "container[0,1.5]"
fs[#fs + 1] = "label[0,-0.2;"
fs[#fs + 1] = FS"Run actions on:"
fs[#fs + 1] = "]"
if context.select_toggle == "all" then
fs[#fs + 1] = "box[0,0;1,0.8;#53ac56]"
fs[#fs + 1] = "label[0.3,0.5;"
fs[#fs + 1] = FS"All"
fs[#fs + 1] = "]"
else
fs[#fs + 1] = "button[0,0;1,0.8;select_all;"
fs[#fs + 1] = FS"All"
fs[#fs + 1] = "]"
end
if not context.groupname then
fs[#fs + 1] = "box[1.1,0;1,0.8;#333]"
fs[#fs + 1] = "label[1.05,0.5;"
fs[#fs + 1] = FS"Group"
fs[#fs + 1] = "]"
fs[#fs + 1] = "tooltip[0.9,0;1,0.8;"
fs[#fs + 1] = FS"Please select a group first"
fs[#fs + 1] = "]"
elseif context.select_toggle == "group" then
fs[#fs + 1] = "box[1.1,0;1,0.8;#53ac56]"
fs[#fs + 1] = "label[1.05,0.5;"
fs[#fs + 1] = FS"Group"
fs[#fs + 1] = "]"
else
fs[#fs + 1] = "button[1.1,0;1,0.8;select_group;"
fs[#fs + 1] = FS"Group"
fs[#fs + 1] = "]"
end
if not context.selected_student then
fs[#fs + 1] = "box[2.2,0;1,0.8;#333]"
fs[#fs + 1] = "label[2.45,0.5;"
fs[#fs + 1] = FS"Selected"
fs[#fs + 1] = "]"
fs[#fs + 1] = "tooltip[2.2,0;1,0.8;"
fs[#fs + 1] = FS"Please select a student first"
fs[#fs + 1] = "]"
elseif context.select_toggle == "selected" then
fs[#fs + 1] = "box[2.2,0;1,0.8;#53ac56]"
fs[#fs + 1] = "label[2.45,0.5;"
fs[#fs + 1] = FS"Selected"
fs[#fs + 1] = "]"
else
fs[#fs + 1] = "button[2.2,0;1,0.8;select_selected;"
fs[#fs + 1] = FS"Selected"
fs[#fs + 1] = "]"
end
fs[#fs + 1] = "label[0,1.4;"
fs[#fs + 1] = FS"Actions:"
fs[#fs + 1] = "]"
local x = 0
local y = 1.7
local spacing = 0.1
local w = (4 - spacing) / 2
local h = 0.8
for _, action in pairs(classroom.get_actions()) do
fs[#fs + 1] = "button["
fs[#fs + 1] = tostring(x)
fs[#fs + 1] = ","
fs[#fs + 1] = tostring(y)
fs[#fs + 1] = ";" .. w .. "," .. h .. ";action_"
fs[#fs + 1] = action.name
fs[#fs + 1] = ";"
fs[#fs + 1] = minetest.formspec_escape(action.title)
fs[#fs + 1] = "]"
fs[#fs + 1] = "tooltip[action_"
fs[#fs + 1] = action.name
fs[#fs + 1] = ";"
fs[#fs + 1] = minetest.formspec_escape(action.description)
fs[#fs + 1] = "]"
x = x + w + spacing
if x > 4 - w then
x = 0
y = y + h + spacing
end
end
y = y + 0.4
if x > 0 then
y = y + h + spacing
end
context.selected_student = "student1"
if context.selected_student then
fs[#fs + 1] = "container[0,"
fs[#fs + 1] = tostring(y)
fs[#fs + 1] = "]"
fs[#fs + 1] = "label[0,0;"
fs[#fs + 1] = FS("Selected user: @1", context.selected_student)
fs[#fs + 1] = "]"
fs[#fs + 1] = "button[0,0.3;1.5,1;teleport;"
fs[#fs + 1] = FS"Teleport to"
fs[#fs + 1] = "]"
fs[#fs + 1] = "container_end[]"
end
fs[#fs + 1] = "container_end[]"
fs[#fs + 1] = "container_end[]"
-- (8-1)*5/4 + 0.375*2 + 1 = 10.5
-- (8.6-1)*5/4 + 0.375*2 + 1 = 11.25
return table.concat(fs, "")
end
local function handle_results(player, context, fields)
if not check_perm(player) then
return false
end
if fields.students then
local evt = minetest.explode_table_event(fields.students)
local i = (evt.row or 0) - 1
if evt.type == "CHG" and i >= 1 and i <= #context.students then
context.selected_student = context.students[i]
return true
end
end
if fields.group then
if fields.group == "1" then
context.groupname = nil
else
local i = 2
for name, _ in pairs(classroom.get_all_groups()) do
if i == tonumber(fields.group) then
context.groupname = name
break
end
i = i + 1
end
end
return true
end
if fields.select_all then
context.select_toggle = "all"
return true
elseif fields.select_group then
context.select_toggle = "group"
return true
elseif fields.select_selected then
context.select_toggle = "selected"
return true
end
if fields.teleport and context.selected_student then
local student = minetest.get_player_by_name(context.selected_student)
if student then
player:set_pos(student:get_pos())
return false
else
context.selected_student = nil
return true
end
end
if fields.new_group then
classroom.show_new_group(player)
return false
end
if fields.edit_group and context.groupname then
classroom.show_edit_group(player, context.groupname)
return false
end
for _, action in pairs(classroom.get_actions()) do
if fields["action_" .. action.name] then
local selector
if context.select_toggle == "all" then
selector = "*"
elseif context.select_toggle == "group" then
selector = "group:" .. context.groupname
elseif context.select_toggle == "selected" then
selector = "user:" .. context.selected_student
else
error("Unknown selector")
end
classroom.run_action(action.name, player, selector)
return true
end
end
end
--
-- Show formspec
--
local _contexts = {}
function classroom.show_dashboard_formspec(player)
if not check_perm(player) then
return nil
end
local name = player:get_player_name()
local context = _contexts[name] or {}
_contexts[name] = context
minetest.show_formspec(player:get_player_name(), "classroom:dashboard",
DASHBOARD_HEADER .. get_formspec(player, context))
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "classroom:dashboard" or not check_perm(player) then
return false
end
local context = _contexts[player:get_player_name()]
if not context then
return false
end
local ret = handle_results(player, context, fields)
if ret then
classroom.show_dashboard_formspec(player)
end
return ret
end)
--
-- Sfinv
--
if minetest.get_modpath("sfinv") then
sfinv.register_page("classroom:edu", {
title = S"Classroom",
is_in_nav = function(self, player, context)
return check_perm(player)
end,
get = function(self, player, context)
return sfinv.make_formspec(player, context, get_formspec(player, context),
false, DASHBOARD_HEADER)
end,
on_player_receive_fields = function(self, player, context, fields)
local ret = handle_results(player, context, fields)
if ret then
sfinv.set_player_inventory_formspec(player)
end
return ret
end,
})
local function on_grant_revoke(grantee, granter, priv)
if priv ~= "teacher" then
return
end
local player = minetest.get_player_by_name(grantee)
if not player then
return
end
minetest.after(0, function()
sfinv.set_player_inventory_formspec(player)
end)
end
minetest.register_on_priv_grant(on_grant_revoke)
minetest.register_on_priv_revoke(on_grant_revoke)
end
--
-- Chatcommand
--
minetest.register_chatcommand("classroom", {
privs = { teacher = true },
func = function(name, params)
local player = minetest.get_player_by_name(name)
if not player then
return false, "You must be online to open the GUI"
end
classroom.show_dashboard_formspec(player)
return true
end,
})
--
-- Unified Inventory
--
if minetest.get_modpath("unified_inventory") ~= nil then
unified_inventory.register_button("classroom", {
type = "image",
image = "classroom_icon.png",
tooltip = S("Classroom"),
action = classroom.show_dashboard_formspec,
})
end