--@ module = true -- 遍历当前界面的控件树,导出控件名与矩形坐标,用于定位可点击目标。 -- 用法:dfhack-run "dfannals/widgets" local MAX_DEPTH = 8 local MAX_LINES = 600 local function rect_str(w) local ok, r = pcall(function() return w.rect end) if not ok or not r then return '' end local function g(k) local ok2, v = pcall(function() return r[k] end) return ok2 and tostring(v) or '?' end return string.format('rect=(%s,%s)-(%s,%s)', g('x1'), g('y1'), g('x2'), g('y2')) end local out = {} local function walk(w, depth) if not w or depth > MAX_DEPTH or #out > MAX_LINES then return end local ok, name = pcall(function() return w.name end) local nm = ok and tostring(name) or '' local txt = '' local ok3, t = pcall(function() return w.text end) if ok3 and t then txt = tostring(t) end out[#out + 1] = string.format('%s%s %s %s', string.rep(' ', depth), nm, rect_str(w), txt ~= '' and ('text=' .. txt) or '') local ok2, children = pcall(function() return w.children end) if ok2 and children then for _, c in ipairs(children) do walk(c, depth + 1) end end end local f = io.open('dfannals-widgets.txt', 'w') if not f then return end f:write('# focus=' .. table.concat(dfhack.gui.getCurFocus(), '/') .. '\n') local sw, sh = dfhack.screen.getWindowSize() f:write(string.format('# window=%dx%d\n', sw, sh)) local scr = dfhack.gui.getCurViewscreen() local ok, widgets = pcall(function() return scr.widgets end) if ok and widgets then walk(widgets, 0) else out[#out + 1] = '(该界面没有 widgets 字段)' end for _, l in ipairs(out) do f:write(l .. '\n') end f:close()