diff --git a/docs/workorder-recheck.rst b/docs/workorder-recheck.rst index 70f18fdf48..731ca5de96 100644 --- a/docs/workorder-recheck.rst +++ b/docs/workorder-recheck.rst @@ -3,13 +3,13 @@ workorder-recheck .. dfhack-tool:: :summary: Recheck start conditions for a manager workorder. - :tags: unavailable fort workorders + :tags: fort workorders -Sets the status to ``Checking`` (from ``Active``) of the selected work order (in -the ``j-m`` or ``u-m`` screens). This makes the manager reevaluate its -conditions. This is especially useful for an order that had its conditions met -when it was started, but the requisite items have since disappeared and the -workorder is now generating job cancellation spam. +Sets the status to ``Checking`` (from ``Active``) of the selected work order. +This makes the manager reevaluate its conditions. This is especially useful +for an order that had its conditions met when it was started, but the requisite +items have since disappeared and the workorder is now generating job cancellation +spam. Usage ----- diff --git a/workorder-recheck.lua b/workorder-recheck.lua index d16c9755f7..7115cdd09c 100644 --- a/workorder-recheck.lua +++ b/workorder-recheck.lua @@ -1,20 +1,103 @@ -- Resets the selected work order to the `Checking` state ---[====[ - -workorder-recheck -================= -Sets the status to ``Checking`` (from ``Active``) of the selected work order (in the ``j-m`` or ``u-m`` screens). -This makes the manager reevaluate its conditions. -]====] -local scr = dfhack.gui.getCurViewscreen() -if df.viewscreen_jobmanagementst:is_instance(scr) then - local orders = df.global.world.manager_orders - local idx = scr.sel_idx - if idx < #orders then - orders[idx].status.active = false + +--@ module = true + +local widgets = require('gui.widgets') +local overlay = require('plugins.overlay') + +local function set_current_inactive() + local scrConditions = df.global.game.main_interface.info.work_orders.conditions + if scrConditions.open then + local order = scrConditions.wq + order.status.active = false else - qerror("Invalid order selected") + qerror("Order conditions is not open") end -else - qerror('Must be called on the manager screen (j-m or u-m)') end + +local function is_current_active() + local scrConditions = df.global.game.main_interface.info.work_orders.conditions + local order = scrConditions.wq + return order.status.active +end + +-- ------------------- +-- RecheckOverlay +-- + +local focusString = 'dwarfmode/Info/WORK_ORDERS/Conditions' + +RecheckOverlay = defclass(RecheckOverlay, overlay.OverlayWidget) +RecheckOverlay.ATTRS{ + default_pos={x=6,y=8}, + default_enabled=true, + viewscreens=focusString, + -- width is the sum of lengths of `[` + `Ctrl+A` + `: ` + button.label + `]` + frame={w=1 + 6 + 2 + 16 + 1, h=3}, +} + +local function areTabsInTwoRows() + -- get the tile above the order status icon + local pen = dfhack.screen.readTile(7, 7, false) + -- in graphics mode, `0` when one row, something else when two (`67` aka 'C' from "Creatures") + -- in ASCII mode, `32` aka ' ' when one row, something else when two (`196` aka '-' from tab frame's top) + return (pen.ch ~= 0 and pen.ch ~= 32) +end + +function RecheckOverlay:updateTextButtonFrame() + local twoRows = areTabsInTwoRows() + if (self._twoRows == twoRows) then return false end + + self._twoRows = twoRows + local frame = twoRows + and {b=0, l=0, r=0, h=1} + or {t=0, l=0, r=0, h=1} + self.subviews.button.frame = frame + + return true +end + +function RecheckOverlay:init() + self:addviews{ + widgets.TextButton{ + view_id = 'button', + -- frame={t=0, l=0, r=0, h=1}, -- is set in `updateTextButtonFrame()` + label='request re-check', + key='CUSTOM_CTRL_A', + on_activate=set_current_inactive, + enabled=is_current_active, + }, + } + + self:updateTextButtonFrame() +end + +function RecheckOverlay:onRenderBody(dc) + if (self.frame_rect.y1 == 7) then + -- only apply this logic if the overlay is on the same row as + -- originally thought: just above the order status icon + + if self:updateTextButtonFrame() then + self:updateLayout() + end + end + + RecheckOverlay.super.onRenderBody(self, dc) +end + +-- ------------------- + +OVERLAY_WIDGETS = { + recheck=RecheckOverlay, +} + +if dfhack_flags.module then + return +end + +-- Check if on the correct screen and perform the action if so +if not dfhack.gui.matchFocusString(focusString) then + qerror('workorder-recheck must be run from the manager order conditions view') +end + +set_current_inactive()