Skip to content

stockpiles export include option#5746

Open
Halavus wants to merge 16 commits intoDFHack:developfrom
Halavus:stockpiles-include-option
Open

stockpiles export include option#5746
Halavus wants to merge 16 commits intoDFHack:developfrom
Halavus:stockpiles-include-option

Conversation

@Halavus
Copy link
Contributor

@Halavus Halavus commented Mar 13, 2026

New Feature:
Upon exporting a stockpile settings, a new popup window one step before "Please enter a filename" has been added.
It allows handling the quite neat stockpiles export --include option that is in the code since I remember it, but absent from the current UI.

Default view:
Capture d'écran 2026-03-13 084847

Full toggled view:
image

Comments/issues:

  • TODO?: a toggle to enable/disable the feature entirely
  • TODO?: Save user settings locally (in /dfhack-config/stockpiles?)
  • Code now contains a larger mix of gui.dialogs and gui.widgets
  • Code is getting a bit cranked with all the UI elements:
    There is an unavailable gui/stockpiles piece of code that approximately tried to do what the new UI does.
    I'm wondering if the UI elements of this script shouldn't be moved to and replace the old gui/stockpiles. Or implement a new structure?

Background note:
In my latest playthroughs I have observed issues where imported stockpile settings - with for example 64 max bins set on a 3x3 stockpile - would prevent the dwarves from ever starting to haul stuff to the stockpile. Only stockpiles import is able to set more containers than there are available tiles in a given stockpile. The game prevents it.
This is why I thought of this feature.
The real fix though could be added after the parsing of the .dfstock file, which could avoid setting more containers than there are available tiles in the selected stockpile.
It seems a pretty easy fix computing the value with the help of the vector stockpile.room.extents, but this is C++ and I have zero clue.

Disclaimer:
I'm not a professional programmer. Started learning basic coding 12 years ago in the hope of becoming a DFHack contributor someday (true story). Got sidetracked by life.
This is my first bigger lua piece of code, go ahead and be critical.
Until 2 weeks ago I was only Skill: Adequate Python (rusty).
Eager to learn along the way.
Thank you for your attention.

@Halavus
Copy link
Contributor Author

Halavus commented Mar 13, 2026

pre-commit.ci autofix

Copy link
Member

@chdoc chdoc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the requested changes are quite substantial, please re-request a review from me once you have implemented the desired changes. I anticipate this to require at least one more round of review.

local dialogs = require('gui.dialogs')
local gui = require('gui')
local dialogs = require('gui.dialogs')
local widgets = require('gui.widgets')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do not just shuffle imports. They used to be in alphabetical order. Only change what needs to be changed. Small diffs are easier to review.

Comment on lines +334 to +350
widgets.Panel{
frame={l=0, r=0, h=1},
subviews={
widgets.HotkeyLabel{
frame={l=0},
key='CUSTOM_C',
label='Include containers:',
on_activate=function() self:toggle_option('containers') end,
},
widgets.Label{
view_id='containers_lbl',
frame={r=24, w=10},
text_halign=2,
text='',
},
},
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see no reason for reinventing the wheel here. This should just be a ToggleHotkeyLabel. The same applies of course to the other instances below.

Comment on lines +473 to +492
function IncludeOptionScreen:onInput(keys)
if keys.SELECT then
self:confirm()
return true
elseif keys.CUSTOM_C then
self:toggle_option('containers')
return true
elseif keys.CUSTOM_G then
self:toggle_option('general')
return true
elseif keys.CUSTOM_A then
self:toggle_option('categories')
return true
elseif keys.CUSTOM_T then
self:toggle_option('types')
return true
end

return IncludeOptionScreen.super.onInput(self, keys)
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can actually go away, if you use the suggested ToggleHotkeyLabel. Do not use custom logic if it isn't required.

Comment on lines +508 to +517
dialogs.InputBox{
frame_title='Export Stockpile Settings',
text='Please enter a filename',
on_input=function(text)
export_settings(text, {
id=sp and sp.id,
includes=includes,
})
end,
}:show()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are already creating a window for the export, then this window should also a text field a for the file name. A well-developed name panel can be found in: https://github.com/DFHack/scripts/blob/56c934eb5d4c957ca731705783a0a43397a9ba2c/gui/blueprint.lua#L44-L71

Please have a look and decide whether this can be reused. In any case, the dialog box should be replaced with something along these lines.

widgets.TooltipLabel{
view_id='disclaimer',
frame={r=0, t=3, w=17},
text_to_wrap='All set to [No] skips --include and includes everything!',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is really bad UX design. The two approaches that seem reasonable to me are:

  1. Disable the "submit" button, when all toggles are set to "no"
  2. Change all toggles to "yes", if the last toggle is set to "no"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants