New building selection dialog.

develop
Warmist 2012-11-29 20:49:16 +02:00
parent 346b402a0f
commit 471d15ba4c
2 changed files with 280 additions and 45 deletions

@ -0,0 +1,268 @@
-- Stock dialog for selecting buildings
local _ENV = mkmodule('gui.buildings')
local gui = require('gui')
local widgets = require('gui.widgets')
local dlg = require('gui.dialogs')
local utils = require('utils')
ARROW = string.char(26)
WORKSHOP_ABSTRACT={
[df.building_type.Civzone]=true,[df.building_type.Stockpile]=true,
}
WORKSHOP_SPECIAL={
[df.building_type.Workshop]=true,[df.building_type.Furnace]=true,[df.building_type.Trap]=true,
[df.building_type.Construction]=true
}
BuildingDialog = defclass(BuildingDialog, gui.FramedScreen)
BuildingDialog.focus_path = 'BuildingDialog'
BuildingDialog.ATTRS{
prompt = 'Type or select a building from this list',
frame_style = gui.GREY_LINE_FRAME,
frame_inset = 1,
frame_title = 'Select Building',
-- new attrs
none_caption = 'none',
hide_none = false,
use_abstract = true,
use_workshops = true,
use_tool_workshop=true,
use_furnace = true,
use_construction = true,
use_trap = true,
use_custom = true,
building_filter = DEFAULT_NIL,
on_select = DEFAULT_NIL,
on_cancel = DEFAULT_NIL,
on_close = DEFAULT_NIL,
}
function BuildingDialog:init(info)
self:addviews{
widgets.Label{
text = {
self.prompt, '\n\n',
'Category: ', { text = self:cb_getfield('context_str'), pen = COLOR_CYAN }
},
text_pen = COLOR_WHITE,
frame = { l = 0, t = 0 },
},
widgets.Label{
view_id = 'back',
visible = false,
text = { { key = 'LEAVESCREEN', text = ': Back' } },
frame = { r = 0, b = 0 },
auto_width = true,
},
widgets.FilteredList{
view_id = 'list',
not_found_label = 'No matching buildings',
frame = { l = 0, r = 0, t = 4, b = 2 },
icon_width = 2,
on_submit = self:callback('onSubmitItem'),
},
widgets.Label{
text = { {
key = 'SELECT', text = ': Select',
disabled = function() return not self.subviews.list:canSubmit() end
} },
frame = { l = 0, b = 0 },
}
}
self:initBuiltinMode()
end
function BuildingDialog:getWantedFrameSize(rect)
return math.max(self.frame_width or 40, #self.prompt), math.min(28, rect.height-8)
end
function BuildingDialog:onDestroy()
if self.on_close then
self.on_close()
end
end
function BuildingDialog:initBuiltinMode()
local choices = {}
if not self.hide_none then
table.insert(choices, { text = self.none_caption, type_id = -1, subtype_id = -1, custom_id=-1})
end
if self.use_workshops then
table.insert(choices, {
icon = ARROW, text = 'workshop', key = 'CUSTOM_SHIFT_W',
cb = self:callback('initWorkshopMode')
})
end
if self.use_furnace then
table.insert(choices, {
icon = ARROW, text = 'furnaces', key = 'CUSTOM_SHIFT_F',
cb = self:callback('initFurnaceMode')
})
end
if self.use_trap then
table.insert(choices, {
icon = ARROW, text = 'traps', key = 'CUSTOM_SHIFT_T',
cb = self:callback('initTrapMode')
})
end
if self.use_construction then
table.insert(choices, {
icon = ARROW, text = 'constructions', key = 'CUSTOM_SHIFT_C',
cb = self:callback('initConstructionMode')
})
end
if self.use_custom then
table.insert(choices, {
icon = ARROW, text = 'custom workshop', key = 'CUSTOM_SHIFT_U',
cb = self:callback('initCustomMode')
})
end
for i=0,df.building_type._last_item do
if (not WORKSHOP_ABSTRACT[i] or self.use_abstract)and not WORKSHOP_SPECIAL[i] then
self:addBuilding(choices, df.building_type[i], i, -1,-1,nil)
end
end
self:pushContext('Any building', choices)
end
function BuildingDialog:initWorkshopMode()
local choices = {}
for i=0,df.workshop_type._last_item do
if i~=df.workshop_type.Custom and (i~=df.workshop_type.Tool or self.use_tool_workshop) then
self:addBuilding(choices, df.workshop_type[i], df.building_type.Workshop, i,-1,nil)
end
end
self:pushContext('Workshops', choices)
end
function BuildingDialog:initTrapMode()
local choices = {}
for i=0,df.trap_type._last_item do
self:addBuilding(choices, df.trap_type[i], df.building_type.Trap, i,-1,nil)
end
self:pushContext('Traps', choices)
end
function BuildingDialog:initConstructionMode()
local choices = {}
for i=0,df.construction_type._last_item do
self:addBuilding(choices, df.construction_type[i], df.building_type.Construction, i,-1,nil)
end
self:pushContext('Constructions', choices)
end
function BuildingDialog:initFurnaceMode()
local choices = {}
for i=0,df.furnace_type._last_item do
self:addBuilding(choices, df.furnace_type[i], df.building_type.Furnace, i,-1,nil)
end
self:pushContext('Furnaces', choices)
end
function BuildingDialog:initCustomMode()
local choices = {}
local raws=df.global.world.raws.buildings.all
for k,v in pairs(raws) do
self:addBuilding(choices, v.name, df.building_type.Workshop,df.workshop_type.Custom,v.id,v)
end
self:pushContext('Custom workshops', choices)
end
function BuildingDialog:addBuilding(choices, name,type_id, subtype_id, custom_id, parent)
-- Check the filter
if self.building_filter and not self.building_filter(name,type_id,subtype_id,custom_id, parent) then
return
end
table.insert(choices, {
text = name:lower(),
customshop = parent,
type_id = type_id, subtype_id = subtype_id, custom_id=custom_id
})
end
function BuildingDialog:pushContext(name, choices)
if not self.back_stack then
self.back_stack = {}
self.subviews.back.visible = false
else
table.insert(self.back_stack, {
context_str = self.context_str,
all_choices = self.subviews.list:getChoices(),
edit_text = self.subviews.list:getFilter(),
selected = self.subviews.list:getSelected(),
})
self.subviews.back.visible = true
end
self.context_str = name
self.subviews.list:setChoices(choices, 1)
end
function BuildingDialog:onGoBack()
local save = table.remove(self.back_stack)
self.subviews.back.visible = (#self.back_stack > 0)
self.context_str = save.context_str
self.subviews.list:setChoices(save.all_choices)
self.subviews.list:setFilter(save.edit_text, save.selected)
end
function BuildingDialog:submitBuilding(type_id,subtype_id,custom_id,choice,index)
self:dismiss()
if self.on_select then
self.on_select(type_id,subtype_id,custom_id,choice,index)
end
end
function BuildingDialog:onSubmitItem(idx, item)
if item.cb then
item:cb(idx)
else
self:submitBuilding(item.type_id, item.subtype_id,item.custom_id,item,idx)
end
end
function BuildingDialog:onInput(keys)
if keys.LEAVESCREEN or keys.LEAVESCREEN_ALL then
if self.subviews.back.visible and not keys.LEAVESCREEN_ALL then
self:onGoBack()
else
self:dismiss()
if self.on_cancel then
self.on_cancel()
end
end
else
self:inputToSubviews(keys)
end
end
function showBuildingPrompt(title, prompt, on_select, on_cancel, build_filter)
BuildingDialog{
frame_title = title,
prompt = prompt,
building_filter = build_filter,
on_select = on_select,
on_cancel = on_cancel,
}:show()
end
return _ENV

@ -3,6 +3,7 @@ local gui = require 'gui'
local wid=require 'gui.widgets' local wid=require 'gui.widgets'
local dialog=require 'gui.dialogs' local dialog=require 'gui.dialogs'
local buildings=require 'dfhack.buildings' local buildings=require 'dfhack.buildings'
local bdialog=require 'gui.buildings'
local tile_attrs = df.tiletype.attrs local tile_attrs = df.tiletype.attrs
@ -11,9 +12,9 @@ keybinds={
key_next={key="CUSTOM_SHIFT_T",desc="Next job in the list"}, key_next={key="CUSTOM_SHIFT_T",desc="Next job in the list"},
key_prev={key="CUSTOM_SHIFT_R",desc="Previous job in the list"}, key_prev={key="CUSTOM_SHIFT_R",desc="Previous job in the list"},
key_continue={key="A_WAIT",desc="Continue job if available"}, key_continue={key="A_WAIT",desc="Continue job if available"},
key_down_alt1={key="CUSTOM_CTRL_D",desc="Use job down"},--does not work? key_down_alt1={key="CUSTOM_CTRL_D",desc="Use job down"},
key_down_alt2={key="CURSOR_DOWN_Z_AUX",desc="Use job down"}, key_down_alt2={key="CURSOR_DOWN_Z_AUX",desc="Use job down"},
key_up_alt1={key="CUSTOM_CTRL_E",desc="Use job up"}, --does not work? key_up_alt1={key="CUSTOM_CTRL_E",desc="Use job up"},
key_up_alt2={key="CURSOR_UP_Z_AUX",desc="Use job up"}, key_up_alt2={key="CURSOR_UP_Z_AUX",desc="Use job up"},
key_use_same={key="A_MOVE_SAME_SQUARE",desc="Use job at the tile you are standing"}, key_use_same={key="A_MOVE_SAME_SQUARE",desc="Use job at the tile you are standing"},
} }
@ -233,49 +234,15 @@ function AssignItems(items,args)
end end
--[[ building submodule... ]]-- --[[ building submodule... ]]--
function DialogBuildingChoose(on_select, on_cancel)
blist={} function BuildingChosen(inp_args,type_id,subtype_id,custom_id)
for i=df.building_type._first_item,df.building_type._last_item do
table.insert(blist,df.building_type[i])
end
dialog.showListPrompt("Building list", "Choose building:", COLOR_WHITE, blist, on_select, on_cancel, nil, true)
end
function DialogSubtypeChoose(subtype,on_select, on_cancel)
blist={}
for i=subtype._first_item,subtype._last_item do
table.insert(blist,subtype[i])
end
dialog.showListPrompt("Subtype", "Choose subtype:", COLOR_WHITE, blist, on_select, on_cancel, nil, true)
end
--workshop, furnaces, traps
invalid_buildings={}
function SubtypeChosen(args,index)
args.subtype=index-1
buildings.constructBuilding(args)
end
function BuildingChosen(st_pos,pos,index)
local b_type=index-2
local args={} local args={}
args.type=b_type args.type=type_id
args.pos=pos args.subtype=subtype_id
args.items=itemsAtPos(st_pos) args.custom=custom_id
if invalid_buildings[b_type] then args.pos=inp_args.pos
return args.items=itemsAtPos(inp_args.old_pos)
elseif b_type==df.building_type.Construction then
DialogSubtypeChoose(df.construction_type,dfhack.curry(SubtypeChosen,args))
return
elseif b_type==df.building_type.Furnace then
DialogSubtypeChoose(df.furnace_type,dfhack.curry(SubtypeChosen,args))
return
elseif b_type==df.building_type.Trap then
DialogSubtypeChoose(df.trap_type,dfhack.curry(SubtypeChosen,args))
return
elseif b_type==df.building_type.Workshop then
DialogSubtypeChoose(df.workshop_type,dfhack.curry(SubtypeChosen,args))
return
else
buildings.constructBuilding(args) buildings.constructBuilding(args)
end
end end
--[[ end of buildings ]]-- --[[ end of buildings ]]--
@ -306,7 +273,7 @@ function AssignJobToBuild(args)
end end
else else
DialogBuildingChoose(dfhack.curry(BuildingChosen,args.old_pos,args.pos)) bdialog.BuildingDialog{on_select=dfhack.curry(BuildingChosen,args),hide_none=true}:show()
end end
end end
function CancelJob(unit) function CancelJob(unit)