dfhack/scripts/gui/workflow.lua

203 lines
5.7 KiB
Lua

-- A GUI front-end for the workflow plugin.
local utils = require 'utils'
local gui = require 'gui'
local guidm = require 'gui.dwarfmode'
local guimat = require 'gui.materials'
local widgets = require 'gui.widgets'
local dlg = require 'gui.dialogs'
local workflow = require 'plugins.workflow'
function check_enabled(cb,...)
if workflow.isEnabled() then
return cb(...)
else
dlg.showYesNoPrompt(
'Enable Plugin',
{ 'The workflow plugin is not enabled currently.', NEWLINE, NEWLINE
'Press ', { key = 'MENU_CONFIRM' }, ' to enable it.' },
COLOR_YELLOW,
curry(function(...)
workflow.setEnabled(true)
return cb(...)
end,...)
)
end
end
JobConstraints = defclass(JobConstraints, guidm.MenuOverlay)
JobConstraints.focus_path = 'workflow-job'
JobConstraints.ATTRS {
job = DEFAULT_NIL,
frame_inset = 1,
frame_background = COLOR_BLACK,
}
function JobConstraints:init(args)
self.building = dfhack.job.getHolder(self.job)
local status = { text = 'No worker', pen = COLOR_DARKGREY }
local worker = dfhack.job.getWorker(self.job)
if self.job.flags.suspend then
status = { text = 'Suspended', pen = COLOR_RED }
elseif worker then
status = { text = dfhack.TranslateName(dfhack.units.getVisibleName(worker)), pen = COLOR_GREEN }
end
self:addviews{
widgets.Label{
frame = { l = 0, t = 0 },
text = {
'Workflow Constraints'
}
},
widgets.List{
view_id = 'list',
frame = { t = 2, b = 2 },
row_height = 4,
scroll_keys = widgets.SECONDSCROLL,
},
widgets.Label{
frame = { l = 0, b = 0 },
text = {
{ key = 'LEAVESCREEN', text = ': Back',
on_activate = self:callback('dismiss') }
}
},
}
self:initListChoices(args.clist)
end
function JobConstraints:onGetSelectedBuilding()
return self.building
end
function JobConstraints:onGetSelectedJob()
return self.job
end
function describe_item_type(iobj)
local itemline = 'any item'
if iobj.item_type >= 0 then
itemline = df.item_type.attrs[iobj.item_type].caption or iobj.item_type
local def = dfhack.items.getSubtypeDef(iobj.item_type, iobj.item_subtype)
local count = dfhack.items.getSubtypeCount(iobj.item_type, iobj.item_subtype)
if def then
itemline = def.name
elseif count >= 0 then
itemline = 'any '..itemline
end
end
return itemline
end
function is_caste_mat(iobj)
return dfhack.items.isCasteMaterial(iobj.item_type)
end
function describe_material(iobj)
local matline = 'any material'
if is_caste_mat(iobj) then
matline = 'material not applicable'
elseif iobj.mat_type >= 0 then
local info = dfhack.matinfo.decode(iobj.mat_type, iobj.mat_index)
if info then
matline = info:toString()
else
matline = iobj.mat_type..':'..iobj.mat_index
end
end
return matline
end
function list_flags(list, bitfield)
for name,val in pairs(bitfield) do
if val then
table.insert(list, name)
end
end
end
function JobConstraints:initListChoices(clist)
clist = clist or workflow.listConstraints(self.job)
local choices = {}
for i,cons in ipairs(clist) do
local goal = (cons.goal_value-cons.goal_gap)..'-'..cons.goal_value
local curval
if cons.goal_by_count then
goal = goal .. ' stacks'
curval = cons.cur_count
else
goal = goal .. ' items'
curval = cons.cur_amount
end
local order_pen = COLOR_GREY
if cons.request == 'resume' then
order_pen = COLOR_GREEN
elseif cons.request == 'suspend' then
order_pen = COLOR_RED
end
local itemstr
if cons.is_craft then
itemstr = 'any craft'
else
itemstr = describe_item_type(cons)
end
if cons.min_quality > 0 then
itemstr = itemstr .. ' ('..df.item_quality[cons.min_quality]..')'
end
local matstr = describe_material(cons)
local matflagstr = ''
local matflags = {}
list_flags(matflags, cons.mat_mask)
if #matflags > 0 then
matflagstr = 'class: '..table.concat(matflags, ', ')
end
table.insert(choices, {
text = {
goal, ' ', { text = '(now '..curval..')', pen = order_pen }, NEWLINE,
' ', itemstr, NEWLINE, ' ', matstr, NEWLINE, ' ', matflagstr
},
obj = cons
})
end
self.subviews.list:setChoices(choices)
end
function JobConstraints:onInput(keys)
if self:propagateMoveKeys(keys) then
if df.global.world.selected_building ~= self.building then
self:dismiss()
end
else
JobConstraints.super.onInput(self, keys)
end
end
if not string.match(dfhack.gui.getCurFocus(), '^dwarfmode/QueryBuilding/Some/Workshop/Job') then
qerror("This script requires a workshop job selected in the 'q' mode")
end
check_enabled(function()
local job = dfhack.gui.getSelectedJob()
if not job.flags['repeat'] then
dlg.showMessage('Not Supported', 'Workflow only tracks repeat jobs.', COLOR_LIGHTRED)
return
end
local clist = workflow.listConstraints(job)
if not clist then
dlg.showMessage('Not Supported', 'This type of job is not supported by workflow.', COLOR_LIGHTRED)
return
end
JobConstraints{ job = job, clist = clist }:show()
end)