From 000b589e3a43bdade8b513bb5a9cb5c7a8cd5a1d Mon Sep 17 00:00:00 2001 From: myk002 Date: Wed, 23 Jun 2021 12:29:37 -0700 Subject: [PATCH] add dwarfmode library function: enterSidebarMode() refactored from quickfort. this common implementation will replace the now redundant functions in quickfort, gui/mass-remove, and gui/blueprint --- library/lua/gui/dwarfmode.lua | 44 ++++++++++++++++++++++ test/library/gui/dwarfmode.lua | 67 ++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 test/library/gui/dwarfmode.lua diff --git a/library/lua/gui/dwarfmode.lua b/library/lua/gui/dwarfmode.lua index 886e0c4df..2c61904a6 100644 --- a/library/lua/gui/dwarfmode.lua +++ b/library/lua/gui/dwarfmode.lua @@ -16,6 +16,50 @@ MENU_WIDTH = 30 refreshSidebar = dfhack.gui.refreshSidebar +-- maps a ui_sidebar_mode to the keycode that would activate that mode when the +-- current screen is 'dwarfmode/Default' +SIDEBAR_MODE_KEYS = { + [df.ui_sidebar_mode.Default]='', + [df.ui_sidebar_mode.QueryBuilding]='D_BUILDJOB', + [df.ui_sidebar_mode.LookAround]='D_LOOK', + [df.ui_sidebar_mode.BuildingItems]='D_BUILDITEM', + [df.ui_sidebar_mode.Stockpiles]='D_STOCKPILES', + [df.ui_sidebar_mode.Zones]='D_CIVZONE', +} + +-- Sends ESC keycodes until we get to dwarfmode/Default and then enters the +-- specified sidebar mode with the corresponding keycode. If we don't get to +-- Default after max_esc presses of ESC (default value is 10), we throw an +-- error. The target sidebar mode must be a member of SIDEBAR_MODE_KEYS +function enterSidebarMode(sidebar_mode, max_esc) + local navkey = SIDEBAR_MODE_KEYS[sidebar_mode] + if not navkey then + error(('Invalid or unsupported sidebar mode: %s (%s)') + :format(sidebar_mode, df.ui_sidebar_mode[sidebar_mode])) + end + local max_esc_num = tonumber(max_esc) + if max_esc and (not max_esc_num or max_esc_num <= 0) then + error(('max_esc must be a positive number: got %s') + :format(tostring(max_esc))) + end + local remaining_esc = max_esc_num or 10 + local focus_string = '' + while remaining_esc > 0 do + local screen = dfhack.gui.getCurViewscreen(true) + focus_string = dfhack.gui.getFocusString(screen) + if df.global.ui.main.mode == df.ui_sidebar_mode.Default and + focus_string == 'dwarfmode/Default' then + if #navkey > 0 then gui.simulateInput(screen, navkey) end + return + end + gui.simulateInput(screen, 'LEAVESCREEN') + remaining_esc = remaining_esc - 1 + end + error(('Unable to get into target sidebar mode (%s) from' .. + ' current UI viewscreen (%s).'):format( + df.ui_sidebar_mode[sidebar_mode], focus_string)) +end + function getPanelLayout() local dims = dfhack.gui.getDwarfmodeViewDims() local area_pos = df.global.ui_menu_width[1] diff --git a/test/library/gui/dwarfmode.lua b/test/library/gui/dwarfmode.lua new file mode 100644 index 000000000..3d013f940 --- /dev/null +++ b/test/library/gui/dwarfmode.lua @@ -0,0 +1,67 @@ +config = { + mode = 'fortress', +} + +local gui = require('gui') +local guidm = require('gui.dwarfmode') + +function test.enterSidebarMode() + expect.error_match('Invalid or unsupported sidebar mode', + function() guidm.enterSidebarMode('badmode') end) + expect.error_match('Invalid or unsupported sidebar mode', + function() guidm.enterSidebarMode( + df.ui_sidebar_mode.OrdersRefuse) end) + + expect.error_match('must be a positive number', + function() guidm.enterSidebarMode(0, 'gg') end) + expect.error_match('must be a positive number', + function() guidm.enterSidebarMode(0, 0) end) + expect.error_match('must be a positive number', + function() guidm.enterSidebarMode(0, '0') end) + expect.error_match('must be a positive number', + function() guidm.enterSidebarMode(0, -1) end) + expect.error_match('must be a positive number', + function() guidm.enterSidebarMode(0, '-1') end) + + -- Simulate not being able to get to default from a screen via mocks. This + -- failure can actually happen in-game in some situations, such as when + -- naming a building with ctrl-N (no way to cancel changes). + mock.patch({{dfhack.gui, 'getFocusString', mock.func()}, + {gui, 'simulateInput', mock.func()}}, + function() + expect.error_match('Unable to get into target sidebar mode', + function() + guidm.enterSidebarMode(df.ui_sidebar_mode.Default) + end) + end) + + -- verify expected starting state + expect.eq(df.ui_sidebar_mode.Default, df.global.ui.main.mode) + expect.eq('dwarfmode/Default', dfhack.gui.getCurFocus(true)) + + -- get into the orders screen + gui.simulateInput(dfhack.gui.getCurViewscreen(true), 'D_JOBLIST') + gui.simulateInput(dfhack.gui.getCurViewscreen(true), 'UNITJOB_MANAGER') + expect.eq(df.ui_sidebar_mode.Default, df.global.ui.main.mode) + expect.eq('jobmanagement/Main', dfhack.gui.getCurFocus(true)) + + -- get back into default from some deep screen + guidm.enterSidebarMode(df.ui_sidebar_mode.Default) + expect.eq(df.ui_sidebar_mode.Default, df.global.ui.main.mode) + expect.eq('dwarfmode/Default', dfhack.gui.getCurFocus(true)) + + -- move from default to some other mode + guidm.enterSidebarMode(df.ui_sidebar_mode.QueryBuilding) + expect.eq(df.ui_sidebar_mode.QueryBuilding, df.global.ui.main.mode) + expect.true_(dfhack.gui.getCurFocus(true):find('^dwarfmode/QueryBuilding')) + + -- move between non-default modes + guidm.enterSidebarMode(df.ui_sidebar_mode.LookAround) + expect.eq(df.ui_sidebar_mode.LookAround, df.global.ui.main.mode) + expect.true_(dfhack.gui.getCurFocus(true):find('^dwarfmode/LookAround')) + + -- get back into default from a supported mode + guidm.enterSidebarMode(df.ui_sidebar_mode.Default) + expect.eq(df.ui_sidebar_mode.Default, df.global.ui.main.mode) + expect.eq('dwarfmode/Default', dfhack.gui.getCurFocus(true)) +end