Skip to content

(WIP) Add custom work detail icons & related tools #1387

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 141 additions & 0 deletions gui/work-detail-icons.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
--@ module = true

local gui = require('gui')
local overlay = require('plugins.overlay')
local widgets = require('gui.widgets')
local utils = require('utils')

local wdi = reqscript('work-detail-icons')
local icondefs = reqscript('internal/work-detail-icons/icon-definitions')
local vanilla = icondefs.vanilla
local builtin = icondefs.builtin

local labor = df.global.game.main_interface.info.labor
local work_details = df.global.plotinfo.labor_info.work_details

--
-- GUI window
--

-- detail currently selected on the labor screen
local function get_current_wd()
local idx = dfhack.gui.getWidget(labor, 'Tabs', 'Work Details', 'Details').selected_idx
return work_details[idx]
end

local function make_window_name(wd)
if wd.name == '' then return 'Work detail' .. ': Customize icon'
else return wd.name .. ': Customize icon' end
end

local WINDOW_WIDTH = 60
local WINDOW_HEIGHT = 40

local CUR_ICON_TOTAL_W = 13

local TopPanel = widgets.Panel{
view_id='top',
frame={h=5, t=0},
frame_style=gui.FRAME_INTERIOR,
subviews={
widgets.Label{
frame={l=0, t=0},
text={'Current', NEWLINE, 'icon:'}
},
widgets.Label{
id='current_icon',
frame={l=CUR_ICON_TOTAL_W-5, t=0},
text=wdi.make_icon_text(vanilla.MINERS),
},
widgets.Divider{
frame={w=1, l=CUR_ICON_TOTAL_W},
frame_style_t=false,
frame_style_b=false,
},
}
}

local VanillaIcons = widgets.Panel{
view_id='vanilla',
frame_title='Dwarf Fortress:',
frame={h=10},
frame_style=gui.FRAME_INTERIOR,
}

local guiWindow = widgets.ResizingPanel{
view_id='main_window',
frame_title=make_window_name(get_current_wd()),
frame={w=WINDOW_WIDTH, h=WINDOW_HEIGHT},
frame_style=gui.FRAME_WINDOW,
frame_background=gui.CLEAR_PEN,
draggable=true,
autoarrange_subviews=true,
subviews={
TopPanel,
VanillaIcons,
}
}

local guiwdi = defclass(guiwdi, gui.ZScreen)
guiwdi.ATTRS{
focus_string='work-detail-icons',
}

function guiwdi:init()
self:addviews{guiWindow}
end

function guiwdi:onDismiss()
view = nil
end

local function show_gui(wd)
if wd then
view = view and view:raise() or guiwdi{}:show()
end
end

--
-- WD screen button
--

SummonButton = defclass(SummonButton, overlay.OverlayWidget)
SummonButton.ATTRS{
desc='Adds a button for icon customization to the work details screen',
default_enabled=true,
viewscreens='dwarfmode/Info/LABOR/WORK_DETAILS/Default',
default_pos={x=90, y=11},
frame={w=21, h=3},
frame_style=gui.FRAME_MEDIUM,
}

function SummonButton:init()
self:addviews{
widgets.HotkeyLabel{
view_id='button',
key='CUSTOM_CTRL_C',
label='Change icon',
}
}
end

-- this causes the script to run whenever the overlay is displayed,
-- regardless of input. is it supposed to work like that?
-- function SummonButton:onRenderFrame(dc, rect)
-- self.subviews.button:setOnActivate(show_gui(get_current_wd()))
-- SummonButton.super.onRenderFrame(self, dc, rect)
-- end

OVERLAY_WIDGETS = {
shortcut=SummonButton,
}

--
-- CLI
--

if not dfhack.isMapLoaded() then
qerror('this script requires a fortress map to be loaded')
end

show_gui(get_current_wd())
104 changes: 104 additions & 0 deletions internal/work-detail-icons/icon-definitions.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
-- Vanilla and DFHack duilt-in work detail icon definitions to pass to make_icon_text
--@module=true

if not dfhack_flags.module then
qerror('this script cannot be called directly')
end

-- vanilla icon sprites will be loaded using the asset attribute in widgets.makeButtonLabelText
-- while DFHack ones (including user-defined) will use the tileset attr instead

IconDef = defclass(IconDef)
IconDef.ATTRS{
ch1=' ',
ch2=' ',

fg1=COLOR_WHITE,
fg2=COLOR_WHITE,
bg2=COLOR_BLACK,
bg2=COLOR_BLACK,
}

--
-- Vanilla
--

local lab = 'INTERFACE_BITS_LABOR'
local loc = 'INTERFACE_BITS_LOCATIONS'

VanillaIconDef = defclass(VanillaIconDef, IconDef)
VanillaIconDef.ATTRS{
asset={},
}

vanilla = {
-- adhering to the names given in the raws (graphics_interface.txt) where possible
MINERS = VanillaIconDef{
ch1='-',
ch2=')',

fg1=COLOR_BROWN,
fg2=COLOR_DARKGREY,

asset={page=lab, x=20, y=0},
},
WOODCUTTERS = VanillaIconDef{
-- /♠
ch1='/',
ch2=6,

fg1=COLOR_DARKGREY,
fg2=COLOR_GREEN,

asset={page=lab, x=24, y=0},
},
-- todo: add the rest
}

--
-- DFHack
--

local builtin_sprites = dfhack.textures.loadTileset('hack/data/art/work-details.png', 8, 12, true)
local column_count = 9
-- todo: calculate offset automatically

DFHackIconDef = defclass(DFHackIconDef, IconDef)
DFHackIconDef.ATTRS{
tileset=builtin_sprites,
tileset_stride=4*column_count,
tileset_offset=1,
}

builtin = { -- obv. placeholders
MAGENTA = DFHackIconDef{
-- pasting the ascii for any of these into a comment makes lua unable to parse the script
ch1=176, -- the left one won't show up for some reason
ch2=176,

fg1=COLOR_BLACK,
fg2=COLOR_BLACK,
bg1=COLOR_MAGENTA,
bg2=COLOR_MAGENTA,

tileset_offset=1,
},
YELLOW = DFHackIconDef{ -- causes weird flickering
ch1=177,
ch2=177,

fg1=COLOR_YELLOW,
fg2=COLOR_YELLOW,

tileset_offset=(4*1)+1,
},
CYAN = DFHackIconDef{
ch1=178,
ch2=178,

fg1=COLOR_CYAN,
fg2=COLOR_CYAN,

tileset_offset=(12*column_count*1)+(4*1)+1,
},
}
Loading
Loading