Skip to content
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

New and improved gui/mechanisms #1016

Closed
wants to merge 0 commits into from
Closed

New and improved gui/mechanisms #1016

wants to merge 0 commits into from

Conversation

Bumber64
Copy link
Contributor

@Bumber64 Bumber64 commented Mar 3, 2024

Gui script for unlinking and freeing mechanisms from buildings

Also fixed typos of "seize" in confirm, and focus_string for gui/teleport being "autodump".

Requires DFHack/dfhack#4319 to move freed mechanisms to ground properly. (Buildings may deconstruct if dwarves are allowed pull out the mechanisms themselves. Don't know what causes this, as it only happens sometimes.)

internal/confirm/specs.lua Outdated Show resolved Hide resolved
gui/mechanisms.lua Outdated Show resolved Hide resolved
Copy link
Member

@myk002 myk002 left a comment

Choose a reason for hiding this comment

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

I like the idea of being able to unlink mechanisms, but I'd rather see this as an overlay than a GUI tool. Specifically, it could draw action buttons to the left or right of the list of linked buildings on this panel:
image

The overlay could be added to https://github.com/DFHack/dfhack/blob/develop/plugins/lua/buildingplan/mechanisms.lua where we already have mechanism-related code

example of overlay that adds widgets to a vanilla list: PreferenceOverlay in https://github.com/DFHack/dfhack/blob/develop/plugins/lua/sort/diplomacy.lua

docs/gui/mechanisms.rst Outdated Show resolved Hide resolved
gui/mechanisms.lua Outdated Show resolved Hide resolved
gui/mechanisms.lua Outdated Show resolved Hide resolved
@Bumber64
Copy link
Contributor Author

Bumber64 commented Mar 6, 2024

I like the idea of being able to unlink mechanisms, but I'd rather see this as an overlay than a GUI tool. Specifically, it could draw action buttons to the left or right of the list of linked buildings on this panel [...]

How do we indicate that the unlink buttons are a DFHack feature?

The auto-freeing settings would go on that panel. Manual freeing buttons would probably go on the "Show items" panel, along with a "Free all unlinked" option there somewhere.

Converting the script is probably more effort than I want to do at the moment, however.

@myk002
Copy link
Member

myk002 commented Mar 7, 2024

How do we indicate that the unlink buttons are a DFHack feature?

the usual method is to either put them in a DFHack-labeled frame or to put red square brackets around it (widgets.TextButton or widgets.BannerPanel):
image
image

@Bumber64
Copy link
Contributor Author

Bumber64 commented Mar 7, 2024

How do we indicate that the unlink buttons are a DFHack feature?

the usual method is to either put them in a DFHack-labeled frame or to put red square brackets around it

What if we were putting a button here:
button

Would we have to make them press something else first to have it appear?

@myk002
Copy link
Member

myk002 commented Mar 8, 2024

that looks like a reasonable spot. A TextButton like [Unlink] instead of an icon might be better to make it clearer that it's not a vanilla button.

The player shouldn't have to press anything else to make the button appear -- the overlay will just render it when in the correct context. I notice that right now this context is represented as dwarfmode/ViewSheets/BUILDING/Trap/Lever and it doesn't differentiate between the "Show linked buildings" and "Show items" tabs. We can modify Gui.cpp to differentiate the context. Then you can attach the overlay to dwarfmode/ViewSheets/BUILDING/Trap/Lever/LinkedBuildings

Edit: done

@Bumber64
Copy link
Contributor Author

Ran into a DF bug: https://dwarffortressbugtracker.com/view.php?id=12721

The linked buildings page doesn't scroll.

@Bumber64
Copy link
Contributor Author

Bumber64 commented Mar 11, 2024

Then you can attach the overlay to dwarfmode/ViewSheets/BUILDING/Trap/Lever/LinkedBuildings

Is there a way to specify any matching */LinkedBuildings, or do we need to specify every linked building screen manually?

@myk002
Copy link
Member

myk002 commented Mar 11, 2024

Is there a way to specify any matching */LinkedBuildings, or do we need to specify every linked building screen manually?

if there are too many to list, you can specify the longest common prefix as your viewscreens attribute and then check the suffix in your render and onInput overrides. e.g. (from gui/notify):

function NotifyOverlay:render(dc)
    if not CONFLICTING_TOOLTIPS[mi.current_hover] then
        NotifyOverlay.super.render(self, dc)
    end
end

you can get the current focus strings from dfhack.gui.getFocusStrings(dfhack.gui.getDFViewscreen(true))

@Bumber64
Copy link
Contributor Author

Bumber64 commented Mar 13, 2024

How does one embed buttons in a scrolling list? The scroll position is defined by main_interface.view_sheets.scroll_position_item, but I'm not sure what the bounds for the list should be considering UI scale, etc. Presumably we have to disable rendering the buttons if they're out of bounds. By default, I think they just sit at the edge of the overlay's rect.

@myk002
Copy link
Member

myk002 commented Mar 13, 2024

implement preUpdateLayout(parent_rect) for your overlay class and dynamically adjust your height based on parent_rect.height. This function gets called whenever the screen is resized. You can then calculate how many visible buttons there are and where to render them. Example: https://github.com/DFHack/dfhack/blob/develop/plugins/lua/sort.lua#L989

@Bumber64
Copy link
Contributor Author

Bumber64 commented Mar 16, 2024

Is there any way to detect the overlay activating? I've got state data when returning to */Items from */LinkedBuildings and I'd prefer not to rebuild my lists every render frame. (I've been checking if the viewing_bldid is different, but that doesn't help when changing tabs on the same building.)

@myk002
Copy link
Member

myk002 commented Mar 17, 2024

(I've been checking if the viewing_bldid is different, but that doesn't help when changing tabs on the same building.)

would that work if a building was selected, deselected, and selected again after the state had changed?

unless the performance is a significant blocker, drawing the UI state directly from DF state and keeping the overlay as stateless as you can is a good idea. Example: https://github.com/DFHack/dfhack/blob/develop/plugins/lua/orders.lua#L391-L415

@Bumber64
Copy link
Contributor Author

Bumber64 commented Mar 17, 2024

would that work if a building was selected, deselected, and selected again after the state had changed?

No, that's the same problem where I'd need to detect the overlay activating. It only catches swapping buildings without closing the view sheet.

unless the performance is a significant blocker, drawing the UI state directly from DF state and keeping the overlay as stateless as you can is a good idea.

It's O(n^2), iterating contained_items and their general_refs (if the item is a mechanism.) I'm not sure how many mechanisms you'd need to cram into a lever to make it a problem.

What's the difference between render and onRenderFrame besides the later receiving a rect?

@myk002
Copy link
Member

myk002 commented Mar 18, 2024

What's the difference between render and onRenderFrame besides the later receiving a rect?

for the purpose of "have a side effect on every rendered frame", there's no difference. render is the View method that is called first. The default implementation of render calls onRenderFrame for widgets.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Status: Done
Development

Successfully merging this pull request may close these issues.

2 participants