@ -108,6 +108,7 @@ end
-- adjusted from CycleHotkeyLabel on the planner panel
local weapon_quantity = 1
-- TODO: this should account for erroring constructions
local function get_quantity ( filter , hollow , bounds )
if is_pressure_plate ( ) then
local flags = uibs.plate_info . flags
@ -207,40 +208,47 @@ ItemLine.ATTRS{
}
function ItemLine : init ( )
self.frame . h = 1
self.frame . h = 2
self.visible = function ( ) return # get_cur_filters ( ) >= self.idx end
self : addviews {
widgets.Label {
view_id = ' item_symbol ' ,
frame = { t = 0 , l = 0 } ,
text = ' * ' ,
text = string.char ( 16 ) , -- this is the "►" character
text_pen = COLOR_YELLOW ,
auto_width = true ,
visible = self.is_selected_fn ,
} ,
widgets.Label {
frame = { t = 0 , l = 25 } ,
view_id = ' item_desc ' ,
frame = { t = 0 , l = 2 } ,
text = {
{ t ile= pens.BUTTON_START_PEN } ,
{ gap = 6 , tile = pens.BUTTON_END_PEN } ,
{ t ext= self : callback ( ' get_item_line_text ' ) ,
pen = function ( ) return gui.invert_color ( COLOR_WHITE , self.is_selected_fn ( ) ) end } ,
} ,
auto_width = true ,
on_click = function ( ) self.on_filter ( self.idx ) end ,
} ,
widgets.Label {
frame = { t = 0 , l = 33 } ,
view_id = ' item_filter ' ,
frame = { t = 0 , l = 28 } ,
text = {
{ t ile= pens.BUTTON_START_PEN } ,
{ gap = 1 , tile = pens.BUTTON_END_PEN } ,
{ t ext= self : callback ( ' get_filter_text ' ) ,
pen = function ( ) return gui.invert_color ( COLOR_LIGHTCYAN , self.is_selected_fn ( ) ) end } ,
} ,
auto_width = true ,
on_click = function ( ) self.on_filter ( self.idx ) end ,
} ,
widgets.Label {
frame = { t = 0 , l = 42 } ,
text = ' [clear] ' ,
text_pen = COLOR_LIGHTRED ,
auto_width = true ,
visible = self : callback ( ' has_filter ' ) ,
on_click = function ( ) self.on_clear_filter ( self.idx ) end ,
} ,
widgets.Label {
frame = { t = 0 , l = 2 } ,
frame = { t = 1 , l = 2 } ,
text = {
{ width = 21 , text = self : callback ( ' get_item_line_text ' ) } ,
{ gap = 3 , text = ' filter ' , pen = COLOR_GREEN } ,
{ gap = 2 , text = ' x ' , pen = self : callback ( ' get_x_pen ' ) } ,
{ gap = 3 , text = function ( ) return self.note end ,
{ gap = 2 , text = function ( ) return self.note end ,
pen = function ( ) return self.note_pen end } ,
} ,
} ,
@ -259,11 +267,6 @@ function ItemLine:onInput(keys)
return ItemLine.super . onInput ( self , keys )
end
function ItemLine : get_x_pen ( )
return require ( ' plugins.buildingplan ' ) . hasFilter ( uibs.building_type , uibs.building_subtype , uibs.custom_type , self.idx - 1 ) and
COLOR_GREEN or COLOR_GREY
end
function ItemLine : get_item_line_text ( )
local idx = self.idx
local filter = get_cur_filters ( ) [ idx ]
@ -276,15 +279,26 @@ function ItemLine:get_item_line_text()
uibs.building_type , uibs.building_subtype , uibs.custom_type , idx - 1 )
if self.available >= quantity then
self.note_pen = COLOR_GREEN
self.note = ' Available now'
self.note = ' Available now'
else
self.note_pen = COLOR_ YELLOW
self.note = ' Will link later'
self.note_pen = COLOR_ BROWN
self.note = ' Will link later'
end
self.note = string.char ( 192 ) .. self.note -- character 192 is "└"
return ( ' %d %s%s ' ) : format ( quantity , self.desc , quantity == 1 and ' ' or ' s ' )
end
function ItemLine : has_filter ( )
return require ( ' plugins.buildingplan ' ) . hasFilter (
uibs.building_type , uibs.building_subtype , uibs.custom_type , self.idx - 1 )
end
function ItemLine : get_filter_text ( )
-- TODO: make this show the filter's materials instead of "edit filters"
return self : has_filter ( ) and ' [edit filters] ' or ' [any material] '
end
function ItemLine : reduce_quantity ( used_quantity )
if not self.available then return end
local filter = get_cur_filters ( ) [ self.idx ]
@ -310,7 +324,7 @@ PlannerOverlay.ATTRS{
default_pos = { x = 5 , y = 9 } ,
default_enabled = true ,
viewscreens = ' dwarfmode/Building/Placement ' ,
frame = { w = 56 , h = 2 0 } ,
frame = { w = 56 , h = 2 2 } ,
}
function PlannerOverlay : init ( )
@ -319,31 +333,32 @@ function PlannerOverlay:init()
local main_panel = widgets.Panel {
view_id = ' main ' ,
frame = { t = 0 , l = 0 , r = 0 , h = 14 } ,
frame_style = gui. MEDIUM_FRAME,
frame = { t = 1 , l = 0 , r = 0 , h = 14 } ,
frame_style = gui. INTERIOR_ MEDIUM_FRAME,
frame_background = gui.CLEAR_PEN ,
visible = function ( ) return not self.minimized end ,
}
local minimized_panel = widgets.Panel {
frame = { t = 0 , r = 0, w = 4 , h = 1 } ,
frame = { t = 0 , r = 1, w = 17 , h = 1 } ,
subviews = {
widgets.Label {
frame = { t = 0 , l = 0 , w = 1 , h = 1 } ,
text = { { tile = pens.MINIMIZED_LEFT_PEN } } ,
frame = { t = 0 , r = 0 , h = 1 } ,
text = {
{ text = ' show Planner ' , pen = pens.MINI_TEXT_PEN , hpen = pens.MINI_TEXT_HPEN } ,
{ text = ' [ ' .. string.char ( 31 ) .. ' ] ' , pen = pens.MINI_BUTT_PEN , hpen = pens.MINI_BUTT_HPEN } ,
} ,
visible = function ( ) return self.minimized end ,
} ,
widgets.Label {
frame = { t = 0 , l = 1 , w = 2 , h = 1 } ,
text = string.char ( 31 ) .. string.char ( 30 ) ,
text_pen = dfhack.pen . parse { fg = COLOR_BLACK , bg = COLOR_GREY } ,
text_hpen = dfhack.pen . parse { fg = COLOR_BLACK , bg = COLOR_WHITE } ,
on_click = function ( ) self.minimized = not self.minimized end ,
} ,
widgets.Label {
frame = { t = 0 , r = 0 , w = 1 , h = 1 } ,
text = { { tile = pens.MINIMIZED_RIGHT_PEN } } ,
visible = function ( ) return self.minimized end ,
frame = { t = 0 , r = 0 , h = 1 } ,
text = {
{ text = ' hide Planner ' , pen = pens.MINI_TEXT_PEN , hpen = pens.MINI_TEXT_HPEN } ,
{ text = ' [ ' .. string.char ( 30 ) .. ' ] ' , pen = pens.MINI_BUTT_PEN , hpen = pens.MINI_BUTT_HPEN } ,
} ,
visible = function ( ) return not self.minimized end ,
on_click = function ( ) self.minimized = not self.minimized end ,
} ,
} ,
}
@ -387,18 +402,18 @@ function PlannerOverlay:init()
on_clear_filter = self : callback ( ' clear_filter ' ) } ,
widgets.CycleHotkeyLabel {
view_id = ' hollow ' ,
frame = { t= 3 , l = 4 } ,
frame = { b= 4 , l = 1 , w = 21 } ,
key = ' CUSTOM_H ' ,
label = ' Hollow area: ' ,
visible = is_construction ,
options = {
{ label = ' No ' , value = false } ,
{ label = ' Yes ' , value = true },
{ label = ' Yes ' , value = true , pen = COLOR_GREEN },
} ,
} ,
widgets.CycleHotkeyLabel {
view_id = ' stairs_top_subtype ' ,
frame = { t= 4 , l = 4 } ,
frame = { b= 5 , l = 23 , w = 30 } ,
key = ' CUSTOM_R ' ,
label = ' Top Stair Type: ' ,
visible = is_stairs ,
@ -410,7 +425,7 @@ function PlannerOverlay:init()
} ,
widgets.CycleHotkeyLabel {
view_id = ' stairs_bottom_subtype ' ,
frame = { t= 5 , l = 4 } ,
frame = { b= 4 , l = 23 , w = 30 } ,
key = ' CUSTOM_B ' ,
label = ' Bottom Stair Type: ' ,
visible = is_stairs ,
@ -420,19 +435,30 @@ function PlannerOverlay:init()
{ label = ' Up ' , value = df.construction_type . UpStair } ,
} ,
} ,
widgets.CycleHotkeyLabel {
widgets.CycleHotkeyLabel { -- TODO: this thing also needs a slider
view_id = ' weapons ' ,
frame = { t= 5 , l = 4 } ,
frame = { b= 4 , l = 1 , w = 28 } ,
key = ' CUSTOM_T ' ,
key_back = ' CUSTOM_SHIFT_T ' ,
label = ' Num weapons:' ,
label = ' Num ber of weapons:' ,
visible = is_weapon_or_spike_trap ,
options = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 } ,
options = {
{ label = ' (1) ' , value = 1 , pen = COLOR_YELLOW } ,
{ label = ' (2) ' , value = 2 , pen = COLOR_YELLOW } ,
{ label = ' (3) ' , value = 3 , pen = COLOR_YELLOW } ,
{ label = ' (4) ' , value = 4 , pen = COLOR_YELLOW } ,
{ label = ' (5) ' , value = 5 , pen = COLOR_YELLOW } ,
{ label = ' (6) ' , value = 6 , pen = COLOR_YELLOW } ,
{ label = ' (7) ' , value = 7 , pen = COLOR_YELLOW } ,
{ label = ' (8) ' , value = 8 , pen = COLOR_YELLOW } ,
{ label = ' (9) ' , value = 9 , pen = COLOR_YELLOW } ,
{ label = ' (10) ' , value = 10 , pen = COLOR_YELLOW } ,
} ,
on_change = function ( val ) weapon_quantity = val end ,
} ,
widgets.ToggleHotkeyLabel {
view_id = ' engraved ' ,
frame = { t = 5 , l = 4 } ,
frame = { b= 4 , l = 1 , w = 22 } ,
key = ' CUSTOM_T ' ,
label = ' Engraved only: ' ,
visible = is_slab ,
@ -441,7 +467,8 @@ function PlannerOverlay:init()
end ,
} ,
widgets.Label {
frame = { b = 3 , l = 17 } ,
frame = { b = 2 , l = 23 } ,
text_pen = COLOR_DARKGREY ,
text = {
' Selected area: ' ,
{ text = function ( )
@ -457,32 +484,18 @@ function PlannerOverlay:init()
visible = function ( ) return # get_cur_filters ( ) > 0 end ,
subviews = {
widgets.HotkeyLabel {
frame = { b = 1 , l = 0 } ,
key = ' STRING_A042 ' ,
auto_width = true ,
enabled = function ( ) return # get_cur_filters ( ) > 1 end ,
on_activate = function ( ) self.selected = ( ( self.selected - 2 ) % # get_cur_filters ( ) ) + 1 end ,
} ,
widgets.HotkeyLabel {
frame = { b = 1 , l = 1 } ,
key = ' STRING_A047 ' ,
label = ' Prev/next item ' ,
auto_width = true ,
enabled = function ( ) return # get_cur_filters ( ) > 1 end ,
on_activate = function ( ) self.selected = ( self.selected % # get_cur_filters ( ) ) + 1 end ,
} ,
widgets.HotkeyLabel {
frame = { b = 1 , l = 21 } ,
frame = { b = 1 , l = 1 , w = 22 } ,
key = ' CUSTOM_F ' ,
label = ' Set filter ' ,
auto_width = true ,
label = function ( )
return buildingplan.hasFilter ( uibs.building_type , uibs.building_subtype , uibs.custom_type , self.selected - 1 )
and ' Edit filter ' or ' Set filter '
end ,
on_activate = function ( ) self : set_filter ( self.selected ) end ,
} ,
widgets.HotkeyLabel {
frame = { b = 1, l = 37 } ,
frame = { b = 0 , l = 1 , w = 22 } ,
key = ' CUSTOM_X ' ,
label = ' Clear filter ' ,
auto_width = true ,
on_activate = function ( ) self : clear_filter ( self.selected ) end ,
enabled = function ( )
return buildingplan.hasFilter ( uibs.building_type , uibs.building_subtype , uibs.custom_type , self.selected - 1 )
@ -490,19 +503,20 @@ function PlannerOverlay:init()
} ,
widgets.CycleHotkeyLabel {
view_id = ' choose ' ,
frame = { b = 0 , l = 0 } ,
key = ' CUSTOM_I ' ,
label = ' Item selection: ' ,
frame = { b = 0 , l = 23 } ,
key = ' CUSTOM_Z ' ,
label = ' Choose items: ' ,
label_below = true ,
options = {
{ label = ' Use filters' , value = 0 } ,
{ label = ' With filters' , value = 0 } ,
{
label = function ( )
local automaterial = itemselection.get_automaterial_selection ( uibs.building_type )
return ( ' Last choice (%s)' ) : format ( automaterial or ' Will ask ' )
return ( ' Last used (%s)' ) : format ( automaterial or ' pick manually ' )
end ,
value = 2 ,
} ,
{ label = ' Manual choice ' , value = 1 } ,
{ label = ' Manual ly ' , value = 1 } ,
} ,
initial_option = 0 ,
on_change = function ( choose )
@ -511,7 +525,7 @@ function PlannerOverlay:init()
} ,
widgets.CycleHotkeyLabel {
view_id = ' safety ' ,
frame = { b = 0, l = 29 , w = 25 } ,
frame = { b = 2, l = 23 , w = 25 } ,
key = ' CUSTOM_G ' ,
label = ' Building safety: ' ,
options = {
@ -529,36 +543,94 @@ function PlannerOverlay:init()
} ,
}
local divider_widget = widgets.Panel {
view_id = ' divider ' ,
frame = { t = 10 , l = 0 , r = 0 , h = 1 } ,
on_render = self : callback ( ' draw_divider_h ' ) ,
visible = function ( ) return not self.minimized end ,
}
local error_panel = widgets.ResizingPanel {
view_id = ' errors ' ,
frame = { t = 14 , l = 0 , r = 0 } ,
frame_style = gui.MEDIUM_FRAME ,
frame = { t = 1 5 , l = 0 , r = 0 } ,
frame_style = gui. BOLD _FRAME,
frame_background = gui.CLEAR_PEN ,
visible = function ( ) return not self.minimized end ,
}
error_panel : addviews {
widgets.WrappedLabel {
frame = { t = 0 , l = 0 , r = 0 } ,
frame = { t = 0 , l = 1 , r = 0 } ,
text_pen = COLOR_LIGHTRED ,
text_to_wrap = get_placement_errors ,
visible = function ( ) return # uibs.errors > 0 end ,
} ,
widgets.Label {
frame = { t = 0 , l = 0 , r = 0 } ,
frame = { t = 0 , l = 1 , r = 0 } ,
text_pen = COLOR_GREEN ,
text = ' OK to build ' ,
visible = function ( ) return # uibs.errors == 0 end ,
} ,
}
local prev_next_selector = widgets.Panel {
frame = { h = 1 } ,
auto_width = true ,
subviews = {
widgets.HotkeyLabel {
frame = { t = 0 , l = 1 , w = 9 } ,
key = ' CUSTOM_SHIFT_Q ' ,
key_sep = ' \0 ' ,
label = ' : Prev/ ' ,
on_activate = function ( ) self.selected = ( ( self.selected - 2 ) % # get_cur_filters ( ) ) + 1 end ,
} ,
widgets.HotkeyLabel {
frame = { t = 0 , l = 2 , w = 1 } ,
key = ' CUSTOM_Q ' ,
on_activate = function ( ) self.selected = ( self.selected % # get_cur_filters ( ) ) + 1 end ,
} ,
widgets.Label {
frame = { t = 0 , l = 10 } ,
text = ' next item ' ,
on_click = function ( ) self.selected = ( self.selected % # get_cur_filters ( ) ) + 1 end ,
} ,
} ,
visible = function ( ) return # get_cur_filters ( ) > 1 end ,
}
local black_bar = widgets.Panel {
frame = { t = 0 , l = 1 , w = 37 , h = 1 } ,
frame_inset = 0 ,
frame_background = gui.CLEAR_PEN ,
visible = function ( ) return not self.minimized end ,
subviews = {
prev_next_selector ,
} ,
}
self : addviews {
main_panel ,
black_bar ,
minimized_panel ,
main_panel ,
divider_widget ,
error_panel ,
}
end
function PlannerOverlay : draw_divider_h ( dc )
local x2 = dc.width - 1
for x = 0 , x2 do
dc : seek ( x , 0 )
if x == 0 then
dc : char ( nil , pens.HORI_LEFT_PEN )
elseif x == x2 then
dc : char ( nil , pens.HORI_RIGHT_PEN )
else
dc : char ( nil , pens.HORI_MID_PEN )
end
end
end
function PlannerOverlay : reset ( )
self.subviews . item1 : reset ( )
self.subviews . item2 : reset ( )