mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-27 19:45:22 +09:00
348 lines
10 KiB
Lua
348 lines
10 KiB
Lua
--[[-- Gui Module - Task List
|
|
- Adds a task list to the game which players can add remove and edit items on
|
|
@gui Task-List
|
|
@alias task_list
|
|
]]
|
|
|
|
local Gui = require 'expcore.gui' --- @dep expcore.gui
|
|
local Event = require 'utils.event' --- @dep utils.event
|
|
local Roles = require 'expcore.roles' --- @dep expcore.roles
|
|
local config = require 'config.tasks' --- @dep config.tasks
|
|
local format_time,table_keys = ext_require('expcore.common','format_time','table_keys') --- @dep expcore.common
|
|
local Tasks = require 'modules.control.tasks' --- @dep modules.control.tasks
|
|
|
|
--- If a player is allowed to use the edit buttons
|
|
local function player_allowed_edit(player,task)
|
|
if task then
|
|
if config.user_can_edit_own_tasks and task.last_edit_name == player.name then
|
|
return true
|
|
end
|
|
else
|
|
if config.any_user_can_add_new_task then
|
|
return true
|
|
end
|
|
end
|
|
|
|
if config.only_admins_can_edit and not player.admin then
|
|
return false
|
|
end
|
|
|
|
if config.edit_tasks_role_permission and not Roles.player_allowed(player,config.edit_tasks_role_permission) then
|
|
return false
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
--- Button in the header to add a new task
|
|
-- @element add_new_task
|
|
local add_new_task =
|
|
Gui.new_button()
|
|
:set_sprites('utility/add')
|
|
:set_tooltip{'task-list.add-tooltip'}
|
|
:set_style('tool_button',function(style)
|
|
Gui.set_padding_style(style,-2,-2,-2,-2)
|
|
style.height = 20
|
|
style.width = 20
|
|
end)
|
|
:on_click(function(player,element)
|
|
Tasks.add_task(player.force.name,nil,player.name)
|
|
end)
|
|
|
|
--- Used to save changes to a task
|
|
-- @element confirm_edit
|
|
local confirm_edit =
|
|
Gui.new_button()
|
|
:set_sprites('utility/downloaded')
|
|
:set_tooltip{'task-list.confirm-tooltip'}
|
|
:set_style('tool_button',function(style)
|
|
Gui.set_padding_style(style,-2,-2,-2,-2)
|
|
style.height = 20
|
|
style.width = 20
|
|
end)
|
|
:on_click(function(player,element)
|
|
local task_id = element.parent.name
|
|
local new_message = element.parent.task.text
|
|
Tasks.set_editing(task_id,player.name)
|
|
Tasks.update_task(task_id,new_message,player.name)
|
|
end)
|
|
|
|
--- Used to cancel any changes you made to a task
|
|
-- @element cancel_edit
|
|
local cancel_edit =
|
|
Gui.new_button()
|
|
:set_sprites('utility/close_black')
|
|
:set_tooltip{'task-list.cancel-tooltip'}
|
|
:set_style('tool_button',function(style)
|
|
Gui.set_padding_style(style,-2,-2,-2,-2)
|
|
style.height = 20
|
|
style.width = 20
|
|
end)
|
|
:on_click(function(player,element)
|
|
local task_id = element.parent.name
|
|
Tasks.set_editing(task_id,player.name)
|
|
end)
|
|
|
|
--- Removes the task from the list
|
|
-- @element discard_task
|
|
local discard_task =
|
|
Gui.new_button()
|
|
:set_sprites('utility/trash')
|
|
:set_tooltip{'task-list.discard-tooltip'}
|
|
:set_style('tool_button',function(style)
|
|
Gui.set_padding_style(style,-2,-2,-2,-2)
|
|
style.height = 20
|
|
style.width = 20
|
|
end)
|
|
:on_click(function(player,element)
|
|
local task_id = element.parent.name
|
|
Tasks.remove_task(task_id)
|
|
end)
|
|
|
|
--- Opens edit mode for the task
|
|
-- @element edit_task
|
|
local edit_task =
|
|
Gui.new_button()
|
|
:set_sprites('utility/rename_icon_normal')
|
|
:set_tooltip{'task-list.edit-tooltip-none'}
|
|
:set_style('tool_button',function(style)
|
|
Gui.set_padding_style(style,-2,-2,-2,-2)
|
|
style.height = 20
|
|
style.width = 20
|
|
end)
|
|
:on_click(function(player,element)
|
|
local task_id = element.parent.name
|
|
Tasks.set_editing(task_id,player.name,true)
|
|
end)
|
|
|
|
--[[ Generates each task, handles both view and edit mode
|
|
element
|
|
> count-"task_id"
|
|
>> label
|
|
> "task_id"
|
|
>> task
|
|
>> cancel_edit (edit mode)
|
|
>> confirm_edit (edit mode)
|
|
> edit-"task_id"
|
|
>> edit_task
|
|
>> discard_task
|
|
]]
|
|
local function generate_task(player,element,task_id)
|
|
local task = Tasks.get_task(task_id)
|
|
local task_ids = Tasks.get_force_task_ids(player.force.name)
|
|
local task_number = table.index_of(task_ids, task_id)
|
|
|
|
if not task then
|
|
-- task is nil so remove it from the list
|
|
element.parent.no_tasks.visible = #task_ids == 1
|
|
Gui.destroy_if_valid(element['count-'..task_id])
|
|
Gui.destroy_if_valid(element['edit-'..task_id])
|
|
Gui.destroy_if_valid(element[task_id])
|
|
|
|
else
|
|
local message = task.message
|
|
local editing = task.curently_editing[player.name]
|
|
local last_edit_name = task.last_edit_name
|
|
local last_edit_time = task.last_edit_time
|
|
|
|
element.parent.no_tasks.visible = false
|
|
-- if it is not already present then add it now
|
|
local task_area = element[task_id]
|
|
if not task_area then
|
|
-- label to show the task number
|
|
element.add{
|
|
name='count-'..task_id,
|
|
type='label',
|
|
caption=task_number..')'
|
|
}
|
|
|
|
-- area which stores the task and buttons
|
|
task_area =
|
|
element.add{
|
|
name=task_id,
|
|
type='flow',
|
|
}
|
|
Gui.set_padding(task_area)
|
|
|
|
-- if the player can edit then it adds the edit and delete button
|
|
local flow = Gui.create_alignment(element,'edit-'..task_id)
|
|
local sub_flow = flow.add{type='flow',name=task_id}
|
|
|
|
edit_task(sub_flow)
|
|
discard_task(sub_flow)
|
|
|
|
end
|
|
|
|
-- update the number indexes and the current editing players
|
|
element['count-'..task_id].caption = task_number..')'
|
|
|
|
local edit_area = element['edit-'..task_id][task_id]
|
|
local players = table_keys(task.editing)
|
|
local allowed = player_allowed_edit(player,task)
|
|
|
|
edit_area.visible = allowed
|
|
|
|
if #players > 0 then
|
|
edit_area[edit_task.name].tooltip = {'task-list.edit-tooltip',table.concat(players,', ')}
|
|
else
|
|
edit_area[edit_task.name].tooltip = {'task-list.edit-tooltip-none'}
|
|
end
|
|
|
|
-- draws/updates the task area
|
|
local element_type = task_area.task and task_area.task.type or nil
|
|
if not editing and element_type == 'label' then
|
|
-- update the label already present
|
|
task_area.task.caption = message
|
|
task_area.task.tooltip = {'task-list.last-edit',last_edit_name,format_time(last_edit_time)}
|
|
|
|
elseif not editing then
|
|
-- create the label, view mode
|
|
if edit_area then
|
|
edit_area[edit_task.name].enabled = true
|
|
end
|
|
|
|
task_area.clear()
|
|
|
|
local label =
|
|
task_area.add{
|
|
name='task',
|
|
type='label',
|
|
caption=message,
|
|
tooltip={'task-list.last-edit',last_edit_name,format_time(last_edit_time)}
|
|
}
|
|
label.style.single_line = false
|
|
label.style.maximal_width = 150
|
|
|
|
elseif editing and element_type ~= 'textfield' then
|
|
-- create the text field, edit mode, update it omitted as value is being edited
|
|
if edit_area then
|
|
edit_area[edit_task.name].enabled = false
|
|
end
|
|
|
|
task_area.clear()
|
|
|
|
local entry =
|
|
task_area.add{
|
|
name='task',
|
|
type='textfield',
|
|
text=message
|
|
}
|
|
entry.style.maximal_width = 150
|
|
entry.style.height = 20
|
|
|
|
cancel_edit(task_area)
|
|
confirm_edit(task_area)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
--[[ generates the main gui structure
|
|
element
|
|
> container
|
|
>> header
|
|
>>> right aligned add_new_task
|
|
>> scroll
|
|
>>> no_tasks
|
|
>>> table
|
|
]]
|
|
local function generate_container(player,element)
|
|
Gui.set_padding(element,2,2,2,2)
|
|
element.style.minimal_width = 200
|
|
|
|
-- main container which contains the other elements
|
|
local container =
|
|
element.add{
|
|
name='container',
|
|
type='frame',
|
|
direction='vertical',
|
|
style='window_content_frame_packed'
|
|
}
|
|
Gui.set_padding(container)
|
|
container.style.vertically_stretchable = false
|
|
|
|
-- main header for the gui
|
|
local header_area = Gui.create_header(
|
|
container,
|
|
{'task-list.main-caption'},
|
|
{'task-list.sub-tooltip'},
|
|
true
|
|
)
|
|
|
|
--- Right aligned button to toggle the section
|
|
if player_allowed_edit(player) then
|
|
add_new_task(header_area)
|
|
end
|
|
|
|
-- table that stores all the data
|
|
local flow_table = Gui.create_scroll_table(container,3,185)
|
|
flow_table.draw_horizontal_lines = true
|
|
flow_table.vertical_centering = false
|
|
flow_table.style.top_cell_padding = 3
|
|
flow_table.style.bottom_cell_padding = 3
|
|
|
|
-- message to say that you have no tasks
|
|
local non_made =
|
|
flow_table.parent.add{
|
|
name='no_tasks',
|
|
type='label',
|
|
caption={'task-list.no-tasks'}
|
|
}
|
|
non_made.style.width = 200
|
|
non_made.style.single_line = false
|
|
|
|
return flow_table
|
|
end
|
|
|
|
--- Registers the task list
|
|
-- @element task_list
|
|
local task_list =
|
|
Gui.new_left_frame('gui/task-list')
|
|
:set_sprites('utility/not_enough_repair_packs_icon')
|
|
:set_direction('vertical')
|
|
:set_tooltip{'task-list.main-tooltip'}
|
|
:set_open_by_default()
|
|
:on_creation(function(player,element)
|
|
local data_table = generate_container(player,element)
|
|
local task_ids = Tasks.get_force_task_ids(player.force.name)
|
|
|
|
for _,task_id in pairs(task_ids) do
|
|
generate_task(player,data_table,task_id)
|
|
end
|
|
end)
|
|
:on_update(function(player,element)
|
|
local data_table = element.container.scroll.table
|
|
local task_ids = Tasks.get_force_task_ids(player.force.name)
|
|
|
|
for _,task_id in pairs(task_ids) do
|
|
generate_task(player,data_table,task_id)
|
|
end
|
|
end)
|
|
|
|
--- When a new task is added it will udpate the task list for everyone on that force
|
|
Tasks.on_update(function(task,task_id)
|
|
local players
|
|
if task then
|
|
local force = game.forces[task.force_name]
|
|
players = force.connected_players
|
|
else
|
|
players = game.connected_players
|
|
end
|
|
|
|
for _,player in pairs(players) do
|
|
local frame = task_list:get_frame(player)
|
|
local element = frame.container.scroll.table
|
|
generate_task(player,element,task_id)
|
|
end
|
|
end)
|
|
|
|
--- Update the tasks when the player joins
|
|
Event.add(defines.events.on_player_joined_game,task_list 'redraw')
|
|
|
|
--- Makes sure the right buttons are present when roles change
|
|
Event.add(Roles.events.on_role_assigned,task_list 'redraw')
|
|
Event.add(Roles.events.on_role_unassigned,task_list 'redraw')
|
|
|
|
return task_list |