Merge pull request #2272 from myk002/myk_ignore_keys

allow EditFields to ignore specified keys
develop
Myk 2022-08-31 10:28:08 -07:00 committed by GitHub
commit ee8f07fed4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 0 deletions

@ -3986,6 +3986,9 @@ Attributes:
widgets while it has focus. You can set this to ``true``, for example, widgets while it has focus. You can set this to ``true``, for example,
if you don't want a ``List`` widget to react to arrow keys while the if you don't want a ``List`` widget to react to arrow keys while the
user is editing. user is editing.
:ignore_keys: If specified, must be a list of key names that the edit field
should ignore. This is useful if you have plain string characters
that you want to use as hotkeys (like ``+``).
An ``EditField`` will only read and process text input if it has keyboard focus. An ``EditField`` will only read and process text input if it has keyboard focus.
It will automatically acquire keyboard focus when it is added as a subview to It will automatically acquire keyboard focus when it is added as a subview to
@ -4311,6 +4314,7 @@ supports:
:edit_pen: If specified, used instead of ``cursor_pen`` for the edit field. :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_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_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.
:not_found_label: Specifies the text of the label shown when no items match the filter. :not_found_label: Specifies the text of the label shown when no items match the filter.
The list choices may include the following attributes: The list choices may include the following attributes:

@ -73,6 +73,8 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
- ``tile-material``: fix the order of declarations. The ``GetTileMat`` function now returns the material as intended (always returned nil before). Also changed the license info, with permission of the original author. - ``tile-material``: fix the order of declarations. The ``GetTileMat`` function now returns the material as intended (always returned nil before). Also changed the license info, with permission of the original author.
- ``widgets.EditField``: new ``onsubmit2`` callback attribute is called when the user hits Shift-Enter. - ``widgets.EditField``: new ``onsubmit2`` callback attribute is called when the user hits Shift-Enter.
- ``widgets.EditField``: new function: ``setCursor(position)`` sets the input cursor. - ``widgets.EditField``: new function: ``setCursor(position)`` sets the input cursor.
- ``widgets.EditField``: new attribute: ``ignore_keys`` lets you ignore specified characters if you want to use them as hotkeys
- ``widgets.FilteredList``: new attribute: ``edit_ignore_keys`` gets passed to the filter EditField as ``ignore_keys``
- ``widgets.Label``: ``scroll`` function now interprets the keywords ``+page``, ``-page``, ``+halfpage``, and ``-halfpage`` in addition to simple positive and negative numbers. - ``widgets.Label``: ``scroll`` function now interprets the keywords ``+page``, ``-page``, ``+halfpage``, and ``-halfpage`` in addition to simple positive and negative numbers.
- ``widgets.HotkeyLabel``: clicking on the widget will now call ``on_activate()``. - ``widgets.HotkeyLabel``: clicking on the widget will now call ``on_activate()``.
- ``widgets.CycleHotkeyLabel``: clicking on the widget will now cycle the options and trigger ``on_change()``. This also applies to the ``ToggleHotkeyLabel`` subclass. - ``widgets.CycleHotkeyLabel``: clicking on the widget will now cycle the options and trigger ``on_change()``. This also applies to the ``ToggleHotkeyLabel`` subclass.

@ -188,6 +188,7 @@ EditField.ATTRS{
key = DEFAULT_NIL, key = DEFAULT_NIL,
key_sep = DEFAULT_NIL, key_sep = DEFAULT_NIL,
modal = false, modal = false,
ignore_keys = DEFAULT_NIL,
} }
function EditField:preinit(init_table) function EditField:preinit(init_table)
@ -270,6 +271,12 @@ function EditField:onInput(keys)
return self:inputToSubviews(keys) return self:inputToSubviews(keys)
end end
if self.ignore_keys then
for _,ignore_key in ipairs(self.ignore_keys) do
if keys[ignore_key] then return false end
end
end
if self.key and keys.LEAVESCREEN then if self.key and keys.LEAVESCREEN then
local old = self.text local old = self.text
self:setText(self.saved_text) self:setText(self.saved_text)
@ -1099,6 +1106,7 @@ FilteredList = defclass(FilteredList, Widget)
FilteredList.ATTRS { FilteredList.ATTRS {
edit_below = false, edit_below = false,
edit_key = DEFAULT_NIL, edit_key = DEFAULT_NIL,
edit_ignore_keys = DEFAULT_NIL,
} }
function FilteredList:init(info) function FilteredList:init(info)
@ -1108,6 +1116,7 @@ function FilteredList:init(info)
on_change = self:callback('onFilterChange'), on_change = self:callback('onFilterChange'),
on_char = self:callback('onFilterChar'), on_char = self:callback('onFilterChar'),
key = self.edit_key, key = self.edit_key,
ignore_keys = self.edit_ignore_keys,
} }
self.list = List{ self.list = List{
frame = { t = 2 }, frame = { t = 2 },

@ -54,3 +54,18 @@ function test.editfield_click()
expect.eq(3, e.cursor) expect.eq(3, e.cursor)
end) end)
end end
function test.editfield_ignore_keys()
local e = widgets.EditField{ignore_keys={'CUSTOM_B', 'CUSTOM_C'}}
e:setFocus(true)
e:onInput{_STRING=string.byte('a'), CUSTOM_A=true}
expect.eq('a', e.text, '"a" should be accepted')
e:onInput{_STRING=string.byte('b'), CUSTOM_B=true}
expect.eq('a', e.text, '"b" should be rejected')
e:onInput{_STRING=string.byte('c'), CUSTOM_C=true}
expect.eq('a', e.text, '"c" should be rejected')
e:onInput{_STRING=string.byte('d'), CUSTOM_D=true}
expect.eq('ad', e.text, '"d" should be accepted')
end