Start working on gui for workflow.
parent
cfbdf47f6e
commit
09f8e8e419
@ -0,0 +1,14 @@
|
|||||||
|
local _ENV = mkmodule('plugins.workflow')
|
||||||
|
|
||||||
|
--[[
|
||||||
|
|
||||||
|
Native functions:
|
||||||
|
|
||||||
|
* isEnabled()
|
||||||
|
* setEnabled(enable)
|
||||||
|
* listConstraints([job]) -> {...}
|
||||||
|
* setConstraint(token, by_count, goal[, gap]) -> {...}
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
return _ENV
|
@ -0,0 +1,202 @@
|
|||||||
|
-- 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)
|
||||||
|
|
Loading…
Reference in New Issue