From 82f759c56e6ad86526d3849859461fd6c65b35b8 Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Wed, 19 Oct 2022 21:26:20 +0100 Subject: [PATCH 01/11] Single-character typo adjustment in Lua API.rst --- docs/Lua API.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Lua API.rst b/docs/Lua API.rst index 5cfd8cf09..58d5015b6 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -3354,7 +3354,7 @@ A module for reading custom tokens added to the raws by mods. Where ``typeInstance`` is a unit, entity, item, job, projectile, building, plant, or interaction instance. Gets ``typeDefinition`` and then returns the same as ``getToken(typeDefinition, token)``. - For units, it gets the token from the race or caste instead if applicable. For plants growth items, + For units, it gets the token from the race or caste instead if applicable. For plant growth items, it gets the token from the plant or plant growth instead if applicable. For plants it does the same but with growth number -1. From 43f4d4be399ab02cc4ffb4dd63d110cfb26dedfe Mon Sep 17 00:00:00 2001 From: myk002 Date: Wed, 19 Oct 2022 13:14:35 -0700 Subject: [PATCH 02/11] fix typo in keybinding docs --- docs/builtins/keybinding.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/builtins/keybinding.rst b/docs/builtins/keybinding.rst index e7e738bc8..6d1565509 100644 --- a/docs/builtins/keybinding.rst +++ b/docs/builtins/keybinding.rst @@ -10,7 +10,7 @@ bindings are not remembered between runs of the game unless re-created in `dfhack.init`. Hotkeys can be any combinations of Ctrl/Alt/Shift with A-Z, 0-9, F1-F12, or -``\``` (the key below the ``Esc`` key. +\` (the key below the :kbd:`Esc` key. Usage ----- From 9199f8207fb4f7d3125b09e5a19fcdd69ab04d4a Mon Sep 17 00:00:00 2001 From: myk002 Date: Wed, 19 Oct 2022 14:01:35 -0700 Subject: [PATCH 03/11] add global keybinding for on-screen keyboard --- data/init/dfhack.keybindings.init | 13 ++++++++++--- docs/changelog.txt | 1 + 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/data/init/dfhack.keybindings.init b/data/init/dfhack.keybindings.init index 2ee706b09..fd02635e2 100644 --- a/data/init/dfhack.keybindings.init +++ b/data/init/dfhack.keybindings.init @@ -4,9 +4,9 @@ # defaults when you update DFHack. Instead, add your configuration to # dfhack-config/init/dfhack.init -############################## -# Generic dwarfmode bindings # -############################## +################### +# Global bindings # +################### # the GUI command launcher (two bindings since some keyboards don't have `) keybinding add ` gui/launcher @@ -16,6 +16,13 @@ keybinding add Ctrl-Shift-D gui/launcher keybinding add Ctrl-F1 hotkeys keybinding add Alt-F1 hotkeys +# on-screen keyboard +keybinding add Ctrl-Shift-K gui/cp437-table + +############################## +# Generic dwarfmode bindings # +############################## + # toggle the display of water level as 1-7 tiles keybinding add Ctrl-W twaterlvl diff --git a/docs/changelog.txt b/docs/changelog.txt index a4fef7c57..8b5603a6f 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -53,6 +53,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - UX: You can now drag the scrollbar to scroll to a specific spot - `overlay`: reduce the size of the "DFHack Launcher" button - Constructions module: ``findAtTile`` now uses a binary search intead of a linear search. +- `gui/cp437-table`: new global keybinding for the clickable on-screen keyboard for players with keyboard layouts that prevent them from using certain keys: Ctrl-Shift-K ## Documentation From f94cc3fda04df267431cb1b694601969d732262d Mon Sep 17 00:00:00 2001 From: myk002 Date: Wed, 19 Oct 2022 16:24:21 -0700 Subject: [PATCH 04/11] add backtick to keybinding's hardcoded docs --- library/Core.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/Core.cpp b/library/Core.cpp index 73336b2e7..669015096 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -963,7 +963,7 @@ command_result Core::runCommand(color_ostream &con, const std::string &first_, v << " keybinding set [@context] \"cmdline\" \"cmdline\"..." << endl << " keybinding add [@context] \"cmdline\" \"cmdline\"..." << endl << "Later adds, and earlier items within one command have priority." << endl - << "Supported keys: [Ctrl-][Alt-][Shift-](A-Z, 0-9, F1-F12, or Enter)." << endl + << "Supported keys: [Ctrl-][Alt-][Shift-](A-Z, 0-9, F1-F12, `, or Enter)." << endl << "Context may be used to limit the scope of the binding, by" << endl << "requiring the current context to have a certain prefix." << endl << "Current UI context is: " From 666edd6d60d99f49ce2556af0c58e53d8795c6c0 Mon Sep 17 00:00:00 2001 From: myk002 Date: Wed, 19 Oct 2022 16:47:54 -0700 Subject: [PATCH 05/11] don't overwrite dig priority by accident many callers of setDesignationAt simply didn't bother with the priority parameter. change the default value of the priority param so that by default we will keep the previous value instead of overwriting it --- docs/changelog.txt | 1 + library/include/modules/MapCache.h | 12 +++++++++--- library/modules/MapCache.cpp | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index 8b5603a6f..b2bf9f4c0 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -36,6 +36,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## New Plugins ## Fixes +- `tiletypes`: no longer resets dig priority to the default when updating other properties of a tile ## Misc Improvements - `blueprint`: new ``--smooth`` option for recording all smoothed floors and walls instead of just the ones that require smoothing for later carving diff --git a/library/include/modules/MapCache.h b/library/include/modules/MapCache.h index 70ba0a858..522746fb0 100644 --- a/library/include/modules/MapCache.h +++ b/library/include/modules/MapCache.h @@ -267,7 +267,7 @@ public: { return index_tile(designation,p); } - bool setDesignationAt(df::coord2d p, df::tile_designation des, int32_t priority = 4000) + bool setDesignationAt(df::coord2d p, df::tile_designation des, int32_t priority = 0) { if(!valid) return false; dirty_designations = true; @@ -276,6 +276,12 @@ public: index_tile(designation,p) = des; if((des.bits.dig || des.bits.smooth) && block) { block->flags.bits.designated = true; + // if priority is not specified, keep the existing priority if it + // is set. otherwise default to 4000. + if (priority <= 0) + priority = priorityAt(p); + if (priority <= 0) + priority = 4000; setPriorityAt(p, priority); } return true; @@ -554,8 +560,8 @@ class DFHACK_EXPORT MapCache Block * b= BlockAtTile(tilecoord); return b ? b->DesignationAt(tilecoord) : df::tile_designation(); } - // priority is optional, only set if >= 0 - bool setDesignationAt (DFCoord tilecoord, df::tile_designation des, int32_t priority = 4000) + // if priority is 0, it is kept unchanged if previously set, otherwise 4000 + bool setDesignationAt (DFCoord tilecoord, df::tile_designation des, int32_t priority = 0) { if (Block *b = BlockAtTile(tilecoord)) { diff --git a/library/modules/MapCache.cpp b/library/modules/MapCache.cpp index ce3039ecf..b88a078b1 100644 --- a/library/modules/MapCache.cpp +++ b/library/modules/MapCache.cpp @@ -303,7 +303,7 @@ int32_t MapExtras::Block::priorityAt(df::coord2d pos) bool MapExtras::Block::setPriorityAt(df::coord2d pos, int32_t priority) { - if (!block || priority < 0) + if (!block || priority <= 0) return false; auto event = getPriorityEvent(block, true); From 142b45ef49d4b932239f28afc6a44780a127552a Mon Sep 17 00:00:00 2001 From: myk002 Date: Wed, 19 Oct 2022 17:30:51 -0700 Subject: [PATCH 06/11] move list item hotkey hint left by one tile so it doesn't get covered by the scrollbar --- library/lua/gui/widgets.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/lua/gui/widgets.lua b/library/lua/gui/widgets.lua index eb8d92244..fd5f83a59 100644 --- a/library/lua/gui/widgets.lua +++ b/library/lua/gui/widgets.lua @@ -1192,7 +1192,7 @@ function List:onRenderBody(dc) if obj.key then local keystr = gui.getKeyDisplay(obj.key) - ip = ip-2-#keystr + ip = ip-3-#keystr dc:seek(ip,y):pen(self.text_pen) dc:string('('):string(keystr,COLOR_LIGHTGREEN):string(')') end From 1e21e6546ea61b34e66aad4088eb502ffe21947d Mon Sep 17 00:00:00 2001 From: myk002 Date: Wed, 19 Oct 2022 17:31:28 -0700 Subject: [PATCH 07/11] fix materials selection dialog where the filter was swallowing the sublist hotkeys --- docs/changelog.txt | 1 + library/lua/gui/materials.lua | 2 ++ 2 files changed, 3 insertions(+) diff --git a/docs/changelog.txt b/docs/changelog.txt index b2bf9f4c0..1a2cf1c0a 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -36,6 +36,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## New Plugins ## Fixes +- `gui/create-item`: prevent materials list filter from intercepting sublist hotkeys - `tiletypes`: no longer resets dig priority to the default when updating other properties of a tile ## Misc Improvements diff --git a/library/lua/gui/materials.lua b/library/lua/gui/materials.lua index c81161bc5..165fda3e6 100644 --- a/library/lua/gui/materials.lua +++ b/library/lua/gui/materials.lua @@ -56,6 +56,8 @@ function MaterialDialog:init(info) frame = { l = 0, r = 0, t = 4, b = 2 }, icon_width = 2, on_submit = self:callback('onSubmitItem'), + edit_ignore_keys={'CUSTOM_SHIFT_I', 'CUSTOM_SHIFT_C', + 'CUSTOM_SHIFT_P'}, }, widgets.Label{ text = { { From 0bf53dc0e4f6eb2a971ffb4b0ee744bed74094e4 Mon Sep 17 00:00:00 2001 From: DFHack-Urist via GitHub Actions <63161697+DFHack-Urist@users.noreply.github.com> Date: Thu, 20 Oct 2022 07:30:58 +0000 Subject: [PATCH 08/11] Auto-update submodules scripts: master --- scripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts b/scripts index 0be5cc0ea..efa8aeba8 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 0be5cc0eaf625029ef26392224db5c3d2822a63d +Subproject commit efa8aeba8716afabe42d015346213b1e15438169 From 593b80cfa0ef40ece3b7848b3999e7617d1d1464 Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 21 Oct 2022 12:17:59 -0700 Subject: [PATCH 09/11] make scrollbars more responsive when dragging --- docs/Lua API.rst | 12 +++++-- library/lua/gui/widgets.lua | 64 +++++++++++++++++++++---------------- 2 files changed, 46 insertions(+), 30 deletions(-) diff --git a/docs/Lua API.rst b/docs/Lua API.rst index 58d5015b6..b72221787 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -4052,7 +4052,11 @@ Scrollbars have the following attributes: :fg: Specifies the pen for the scroll icons and the active part of the bar. Default is ``COLOR_LIGHTGREEN``. :bg: Specifies the pen for the background part of the scrollbar. Default is ``COLOR_CYAN``. -:on_scroll: A callback called when the scrollbar is scrolled. It will be called with a single string parameter with a value of "up_large", "down_large", "up_small", or "down_small". +:on_scroll: A callback called when the scrollbar is scrolled. If the scrollbar is clicked, + the callback will be called with one of the following string parameters: "up_large", + "down_large", "up_small", or "down_small". If the scrollbar is dragged, the callback will + be called with the value that ``top_elem`` should be set to on the next call to + ``update()`` (see below). The Scrollbar widget implements the following methods: @@ -4062,8 +4066,10 @@ The Scrollbar widget implements the following methods: The ``top_elem`` param is the (one-based) index of the first visible element. The ``elems_per_page`` param is the maximum number of elements that can be shown at one time. The ``num_elems`` param is the total number of elements - that the paried widget can scroll through. The scrollbar will adjust its - scrollbar size and position accordingly. + that the paried widget can scroll through. If ``elems_per_page`` or + ``num_elems`` is not specified, the most recently specified value for these + parameters is used. The scrollbar will adjust its scrollbar size and position + according to the values passed to this function. Clicking on the arrows at the top or the bottom of a scrollbar will scroll an associated widget by a small amount. Clicking on the unfilled portion of the diff --git a/library/lua/gui/widgets.lua b/library/lua/gui/widgets.lua index fd5f83a59..415bba3d3 100644 --- a/library/lua/gui/widgets.lua +++ b/library/lua/gui/widgets.lua @@ -363,8 +363,6 @@ end -- Scrollbar -- --------------- --- these can be overridden by the user, e.g.: --- require('gui.widgets').SCROLL_DELAY_MS = 100 SCROLL_INITIAL_DELAY_MS = 300 SCROLL_DELAY_MS = 20 @@ -389,6 +387,17 @@ function Scrollbar:init() self:update(1, 1, 1) end +local function scrollbar_get_max_pos_and_height(scrollbar) + local frame_body = scrollbar.frame_body + local scrollbar_body_height = (frame_body and frame_body.height or 3) - 2 + + local height = math.max(1, math.floor( + (math.min(scrollbar.elems_per_page, scrollbar.num_elems) * scrollbar_body_height) / + scrollbar.num_elems)) + + return scrollbar_body_height - height, height +end + -- calculate and cache the number of tiles of empty space above the top of the -- scrollbar and the number of tiles the scrollbar should occupy to represent -- the percentage of text that is on the screen. @@ -398,39 +407,33 @@ function Scrollbar:update(top_elem, elems_per_page, num_elems) if not top_elem then error('must specify index of new top element') end elems_per_page = elems_per_page or self.elems_per_page num_elems = num_elems or self.num_elems + self.top_elem = top_elem + self.elems_per_page, self.num_elems = elems_per_page, num_elems - local frame_height = self.frame_body and self.frame_body.height or 3 - local scrollbar_body_height = frame_height - 2 - local height = math.max(1, math.floor( - (math.min(elems_per_page, num_elems) * scrollbar_body_height) / - num_elems)) - - local max_pos = scrollbar_body_height - height + local max_pos, height = scrollbar_get_max_pos_and_height(self) local pos = (num_elems == elems_per_page) and 0 or math.ceil(((top_elem-1) * max_pos) / (num_elems - elems_per_page)) - self.top_elem = top_elem - self.elems_per_page, self.num_elems = elems_per_page, num_elems self.bar_offset, self.bar_height = pos, height end local function scrollbar_do_drag(scrollbar) - local x,y = dfhack.screen.getMousePos() - x,y = scrollbar.frame_body:localXY(x,y) - local bar_idx = y - scrollbar.bar_offset - local delta = bar_idx - scrollbar.is_dragging - if delta < -scrollbar.bar_height then - scrollbar.on_scroll('up_large') - elseif delta < 0 then - scrollbar.on_scroll('up_small') - elseif delta > scrollbar.bar_height then - scrollbar.on_scroll('down_large') - elseif delta > 0 then - scrollbar.on_scroll('down_small') + local _,y = scrollbar.frame_body:localXY(dfhack.screen.getMousePos()) + local cur_pos = y - scrollbar.is_dragging + local max_top = scrollbar.num_elems - scrollbar.elems_per_page + 1 + local max_pos = scrollbar_get_max_pos_and_height(scrollbar) + local new_top_elem = math.floor(cur_pos * max_top / max_pos) + 1 + new_top_elem = math.max(1, math.min(new_top_elem, max_top)) + if new_top_elem ~= scrollbar.top_elem then + scrollbar.on_scroll(new_top_elem) end end +local function scrollbar_is_visible(scrollbar) + return scrollbar.elems_per_page < scrollbar.num_elems +end + local UP_ARROW_CHAR = string.char(24) local DOWN_ARROW_CHAR = string.char(25) local NO_ARROW_CHAR = string.char(32) @@ -439,7 +442,7 @@ local BAR_BG_CHAR = string.char(179) function Scrollbar:onRenderBody(dc) -- don't draw if all elements are visible - if self.elems_per_page >= self.num_elems then return end + if not scrollbar_is_visible(self) then return end -- render up arrow if we're not at the top dc:seek(0, 0):char( self.top_elem == 1 and NO_ARROW_CHAR or UP_ARROW_CHAR, self.fg, self.bg) @@ -482,7 +485,10 @@ function Scrollbar:onRenderBody(dc) end function Scrollbar:onInput(keys) - if not keys._MOUSE_L_DOWN or not self.on_scroll then return false end + if not keys._MOUSE_L_DOWN or not self.on_scroll + or not scrollbar_is_visible(self) then + return false + end local _,y = self:getMousePos() if not y then return false end local scroll_spec = nil @@ -761,7 +767,9 @@ end function Label:on_scrollbar(scroll_spec) local v = 0 - if scroll_spec == 'down_large' then + if tonumber(scroll_spec) then + v = scroll_spec - self.start_line_num + elseif scroll_spec == 'down_large' then v = '+halfpage' elseif scroll_spec == 'up_large' then v = '-halfpage' @@ -1134,7 +1142,9 @@ end function List:on_scrollbar(scroll_spec) local v = 0 - if scroll_spec == 'down_large' then + if tonumber(scroll_spec) then + v = scroll_spec - self.page_top + elseif scroll_spec == 'down_large' then v = math.ceil(self.page_size / 2) elseif scroll_spec == 'up_large' then v = -math.ceil(self.page_size / 2) From 64b923b9eb02264772757facf34d2bb3c9f4d345 Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 21 Oct 2022 12:43:53 -0700 Subject: [PATCH 10/11] make the materials dialog filter lcase only this allows the capital letter hotkeys to be processed by the list widget without the special-casing of the ignore_keys attribute. --- docs/Lua API.rst | 3 ++- docs/changelog.txt | 1 + library/lua/gui/materials.lua | 3 +-- library/lua/gui/widgets.lua | 12 +++++++++++- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/docs/Lua API.rst b/docs/Lua API.rst index 58d5015b6..c4bf56548 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -4382,7 +4382,8 @@ supports: :edit_pen: If specified, used instead of ``cursor_pen`` for the edit field. :edit_below: If true, the edit field is placed below the list instead of above. :edit_key: If specified, the edit field is disabled until this key is pressed. -:edit_ignore_keys: If specified, must be a list of key names that the filter edit field should ignore. +:edit_ignore_keys: If specified, will be passed to the filter edit field as its ``ignore_keys`` attribute. +:edit_on_char: If specified, will be passed to the filter edit field as its ``on_char`` attribute. :not_found_label: Specifies the text of the label shown when no items match the filter. The list choices may include the following attributes: diff --git a/docs/changelog.txt b/docs/changelog.txt index 1a2cf1c0a..af2e6b3fa 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -66,6 +66,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - ``widgets.Scrollbar``: new scrollbar widget that can be paired with an associated scrollable widget. Integrated with ``widgets.Label`` and ``widgets.List``. - ``dfhack.constructions.findAtTile()``: exposed preexisting function to Lua. - ``dfhack.constructions.insert()``: exposed new function to Lua. +- ``widgets.EditField`` now allows other widgets to process characters that the ``on_char`` callback rejects. # 0.47.05-r7 diff --git a/library/lua/gui/materials.lua b/library/lua/gui/materials.lua index 165fda3e6..1fbce4377 100644 --- a/library/lua/gui/materials.lua +++ b/library/lua/gui/materials.lua @@ -56,8 +56,7 @@ function MaterialDialog:init(info) frame = { l = 0, r = 0, t = 4, b = 2 }, icon_width = 2, on_submit = self:callback('onSubmitItem'), - edit_ignore_keys={'CUSTOM_SHIFT_I', 'CUSTOM_SHIFT_C', - 'CUSTOM_SHIFT_P'}, + edit_on_char=function(c) return c:match('%l') end, }, widgets.Label{ text = { { diff --git a/library/lua/gui/widgets.lua b/library/lua/gui/widgets.lua index fd5f83a59..fb2570b6f 100644 --- a/library/lua/gui/widgets.lua +++ b/library/lua/gui/widgets.lua @@ -326,6 +326,8 @@ function EditField:onInput(keys) if not self.on_char or self.on_char(cv, old) then self:setText(old:sub(1,self.cursor-1)..cv..old:sub(self.cursor), self.cursor + 1) + elseif self.on_char then + return self.modal end end if self.on_change and self.text ~= old then @@ -1274,14 +1276,22 @@ FilteredList.ATTRS { edit_below = false, edit_key = DEFAULT_NIL, edit_ignore_keys = DEFAULT_NIL, + edit_on_char = DEFAULT_NIL, } function FilteredList:init(info) + local on_char = self:callback('onFilterChar') + if self.edit_on_char then + on_char = function(c, text) + return self.edit_on_char(c, text) and self:onFilterChar(c, text) + end + end + self.edit = EditField{ text_pen = info.edit_pen or info.cursor_pen, frame = { l = info.icon_width, t = 0, h = 1 }, on_change = self:callback('onFilterChange'), - on_char = self:callback('onFilterChar'), + on_char = on_char, key = self.edit_key, ignore_keys = self.edit_ignore_keys, } From 75f929ccebcc91fb2ea8638f841d3049051de995 Mon Sep 17 00:00:00 2001 From: DFHack-Urist via GitHub Actions <63161697+DFHack-Urist@users.noreply.github.com> Date: Sun, 23 Oct 2022 07:25:20 +0000 Subject: [PATCH 11/11] Auto-update submodules scripts: master --- scripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts b/scripts index efa8aeba8..23b95d66b 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit efa8aeba8716afabe42d015346213b1e15438169 +Subproject commit 23b95d66b1c6219e7718627edfe02c8a451cc192