Merge pull request #2533 from myk002/myk_lua_input

adjust Lua widgets to new input scheme
develop
Myk 2022-12-30 22:37:12 -08:00 committed by GitHub
commit bf995a0968
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 82 additions and 125 deletions

@ -38,6 +38,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
## Fixes
## Misc Improvements
- Scrollable widgets now react to mouse wheel events when the mouse is over the widget
## Documentation
- `overlay-dev-guide`: added troubleshooting tips and common development workflows

@ -4316,7 +4316,6 @@ Attributes:
If it returns false, the character is ignored.
:on_change: Change notification callback; used as ``on_change(new_text,old_text)``.
:on_submit: Enter key callback; if set the field will handle the key and call ``on_submit(text)``.
:on_submit2: Shift-Enter key callback; if set the field will handle the key and call ``on_submit2(text)``.
:key: If specified, the field is disabled until this key is pressed. Must be given as a string.
:key_sep: If specified, will be used to customize how the activation key is
displayed. See ``token.key_sep`` in the ``Label`` documentation below.
@ -4346,8 +4345,8 @@ You can click where you want the cursor to move or you can use any of the
following keyboard hotkeys:
- Left/Right arrow: move the cursor one character to the left or right.
- Ctrl-Left/Right arrow: move the cursor one word to the left or right.
- Alt-Left/Right arrow: move the cursor to the beginning/end of the text.
- Ctrl-B/Ctrl-F: move the cursor one word back or forward.
- Ctrl-A/Ctrl-E: move the cursor to the beginning/end of the text.
Scrollbar class
---------------
@ -4385,6 +4384,10 @@ direction. The amount of scrolling done in each case in determined by the
associated widget, and after scrolling is complete, the associated widget must
call ``scrollbar:update()`` with updated new display info.
If the mouse wheel is scrolled while the mouse is over the Scrollbar widget's
parent view, then the parent is scrolled accordingly. Holding :kbd:`Shift`
while scrolling will result in faster movement.
You can click and drag the scrollbar to scroll to a specific spot, or you can
click and hold on the end arrows or in the unfilled portion of the scrollbar to
scroll multiple times, just like in a normal browser scrollbar. The speed of
@ -4629,8 +4632,8 @@ It has the following attributes:
with an empty list.
:on_submit: Enter key or mouse click callback; if specified, the list reacts to the
key/click and calls the callback as ``on_submit(index,choice)``.
:on_submit2: Shift-Enter key or shift-mouse click callback; if specified, the list
reacts to the key/click and calls it as ``on_submit2(index,choice)``.
:on_submit2: Shift-click callback; if specified, the list reacts to the click and
calls the callback as ``on_submit2(index,choice)``.
:row_height: Height of every row in text lines.
:icon_width: If not *nil*, the specified number of character columns
are reserved to the left of the list item for the icons.

@ -258,8 +258,8 @@ function BuildingDialog:onSubmitItem(idx, item)
end
function BuildingDialog:onInput(keys)
if keys.LEAVESCREEN or keys.LEAVESCREEN_ALL then
if self.subviews.back.visible and not keys.LEAVESCREEN_ALL then
if keys.LEAVESCREEN then
if self.subviews.back.visible then
self:onGoBack()
else
self:dismiss()
@ -267,9 +267,9 @@ function BuildingDialog:onInput(keys)
self.on_cancel()
end
end
else
self:inputToSubviews(keys)
return true
end
self:inputToSubviews(keys)
end
function showBuildingPrompt(title, prompt, on_select, on_cancel, build_filter)

@ -48,7 +48,7 @@ end
function MessageBox:onRenderFrame(dc,rect)
MessageBox.super.onRenderFrame(self,dc,rect)
if self.on_accept then
dc:seek(rect.x1+2,rect.y2):key('LEAVESCREEN'):string('/'):key('MENU_CONFIRM')
dc:seek(rect.x1+2,rect.y2):key('LEAVESCREEN'):string('/'):key('SELECT')
end
end
@ -59,19 +59,16 @@ function MessageBox:onDestroy()
end
function MessageBox:onInput(keys)
if keys.MENU_CONFIRM then
if keys.SELECT or keys.LEAVESCREEN then
self:dismiss()
if self.on_accept then
if keys.SELECT and self.on_accept then
self.on_accept()
end
elseif keys.LEAVESCREEN or (keys.SELECT and not self.on_accept) then
self:dismiss()
if self.on_cancel then
elseif keys.LEAVESCREEN and self.on_cancel then
self.on_cancel()
end
else
self:inputToSubviews(keys)
return true
end
return self:inputToSubviews(keys)
end
function showMessage(title, text, tcolor, on_close)
@ -132,14 +129,15 @@ function InputBox:onInput(keys)
if self.on_input then
self.on_input(self.subviews.edit.text)
end
return true
elseif keys.LEAVESCREEN then
self:dismiss()
if self.on_cancel then
self.on_cancel()
end
else
self:inputToSubviews(keys)
return true
end
return self:inputToSubviews(keys)
end
function showInputPrompt(title, text, tcolor, input, on_input, on_cancel, min_width)
@ -238,9 +236,9 @@ function ListBox:onInput(keys)
if self.on_cancel then
self.on_cancel()
end
else
self:inputToSubviews(keys)
return true
end
return self:inputToSubviews(keys)
end
function showListPrompt(title, text, tcolor, choices, on_select, on_cancel, min_width, filter)

@ -267,6 +267,10 @@ function Viewport:reveal(target,gap,max_scroll,scroll_gap,scroll_z)
end
MOVEMENT_KEYS = {
KEYBOARD_CURSOR_UP = { 0, -1, 0 }, KEYBOARD_CURSOR_DOWN = { 0, 1, 0 },
KEYBOARD_CURSOR_LEFT = { -1, 0, 0 }, KEYBOARD_CURSOR_RIGHT = { 1, 0, 0 },
KEYBOARD_CURSOR_UP_FAST = { 0, -1, 0, true }, KEYBOARD_CURSOR_DOWN_FAST = { 0, 1, 0, true },
KEYBOARD_CURSOR_LEFT_FAST = { -1, 0, 0, true }, KEYBOARD_CURSOR_RIGHT_FAST = { 1, 0, 0, true },
CURSOR_UP = { 0, -1, 0 }, CURSOR_DOWN = { 0, 1, 0 },
CURSOR_LEFT = { -1, 0, 0 }, CURSOR_RIGHT = { 1, 0, 0 },
CURSOR_UPLEFT = { -1, -1, 0 }, CURSOR_UPRIGHT = { 1, -1, 0 },
@ -553,66 +557,4 @@ function MenuOverlay:renderMapOverlay(get_overlay_char_fn, bounds_rect)
end
end
--fakes a "real" workshop sidebar menu, but on exactly selected workshop
WorkshopOverlay = defclass(WorkshopOverlay, MenuOverlay)
WorkshopOverlay.focus_path="WorkshopOverlay"
WorkshopOverlay.ATTRS={
workshop=DEFAULT_NIL,
}
function WorkshopOverlay:onAboutToShow(below)
WorkshopOverlay.super.onAboutToShow(self,below)
if df.global.world.selected_building ~= self.workshop then
error("The workshop overlay tried to show up for incorrect workshop")
end
end
function WorkshopOverlay:onInput(keys)
local allowedKeys={ --TODO add options: job management, profile, etc...
"CURSOR_RIGHT","CURSOR_RIGHT_FAST","CURSOR_LEFT","CURSOR_LEFT_FAST","CURSOR_UP","CURSOR_UP_FAST","CURSOR_DOWN","CURSOR_DOWN_FAST",
"CURSOR_UPRIGHT","CURSOR_UPRIGHT_FAST","CURSOR_UPLEFT","CURSOR_UPLEFT_FAST","CURSOR_DOWNRIGHT","CURSOR_DOWNRIGHT_FAST","CURSOR_DOWNLEFT","CURSOR_DOWNLEFT_FAST",
"CURSOR_UP_Z","CURSOR_DOWN_Z","DESTROYBUILDING","CHANGETAB","SUSPENDBUILDING"}
if keys.LEAVESCREEN then
self:dismiss()
self:sendInputToParent('LEAVESCREEN')
elseif keys.CHANGETAB then
self:sendInputToParent("CHANGETAB")
self:inputToSubviews(keys)
self:updateLayout()
else
for _,name in ipairs(allowedKeys) do
if keys[name] then
self:sendInputToParent(name)
break
end
end
self:inputToSubviews(keys)
end
if df.global.world.selected_building ~= self.workshop then
self:dismiss()
return
end
end
function WorkshopOverlay:onGetSelectedBuilding()
return self.workshop
end
local function is_slated_for_remove( bld )
for i,v in ipairs(bld.jobs) do
if v.job_type==df.job_type.DestroyBuilding then
return true
end
end
return false
end
function WorkshopOverlay:render(dc)
self:renderParent()
if df.global.world.selected_building ~= self.workshop then
return
end
if is_slated_for_remove(self.workshop) then
return
end
WorkshopOverlay.super.render(self, dc)
end
return _ENV

@ -255,8 +255,8 @@ function MaterialDialog:onSubmitItem(idx, item)
end
function MaterialDialog:onInput(keys)
if keys.LEAVESCREEN or keys.LEAVESCREEN_ALL then
if self.subviews.back.visible and not keys.LEAVESCREEN_ALL then
if keys.LEAVESCREEN then
if self.subviews.back.visible then
self:onGoBack()
else
self:dismiss()
@ -264,9 +264,9 @@ function MaterialDialog:onInput(keys)
self.on_cancel()
end
end
else
self:inputToSubviews(keys)
return true
end
return self:inputToSubviews(keys)
end
function showMaterialPrompt(title, prompt, on_select, on_cancel, mat_filter)

@ -26,16 +26,13 @@ end
STANDARDSCROLL = {
STANDARDSCROLL_UP = -1,
KEYBOARD_CURSOR_UP = -1,
STANDARDSCROLL_DOWN = 1,
KEYBOARD_CURSOR_DOWN = 1,
STANDARDSCROLL_PAGEUP = '-page',
KEYBOARD_CURSOR_UP_FAST = '-page',
STANDARDSCROLL_PAGEDOWN = '+page',
}
SECONDSCROLL = {
SECONDSCROLL_UP = -1,
SECONDSCROLL_DOWN = 1,
SECONDSCROLL_PAGEUP = '-page',
SECONDSCROLL_PAGEDOWN = '+page',
KEYBOARD_CURSOR_DOWN_FAST = '+page',
}
------------
@ -366,8 +363,10 @@ function Panel:setKeyboardDragEnabled(enabled)
return
end
if enabled then
local kbd_get_pos = function() return {x=0, y=0} end
Panel_begin_drag(self, kbd_get_pos())
local kbd_get_pos = function()
return {x=self.frame_rect.x1, y=self.frame_rect.y1}
end
Panel_begin_drag(self)
self.kbd_get_pos = kbd_get_pos
else
Panel_end_drag(self)
@ -680,22 +679,20 @@ function EditField:onInput(keys)
return true
end
if keys.SELECT then
if keys.SELECT or keys.CUSTOM_SHIFT_ENTER then
if self.key then
self:setFocus(false)
end
if keys.CUSTOM_SHIFT_ENTER then
if self.on_submit2 then
self.on_submit2(self.text)
return true
end
else
if self.on_submit then
self.on_submit(self.text)
return true
end
return not not self.key
elseif keys.SEC_SELECT then
if self.key then
self:setFocus(false)
end
if self.on_submit2 then
self.on_submit2(self.text)
return true
end
return not not self.key
elseif keys._MOUSE_L then
@ -726,25 +723,25 @@ function EditField:onInput(keys)
self.on_change(self.text, old)
end
return true
elseif keys.CURSOR_LEFT then
elseif keys.KEYBOARD_CURSOR_LEFT then
self:setCursor(self.cursor - 1)
return true
elseif keys.A_MOVE_W_DOWN then -- Ctrl-Left (end of prev word)
elseif keys.CUSTOM_CTRL_B then -- back one word
local _, prev_word_end = self.text:sub(1, self.cursor-1):
find('.*[%w_%-][^%w_%-]')
self:setCursor(prev_word_end or 1)
return true
elseif keys.A_CARE_MOVE_W then -- Alt-Left (home)
elseif keys.CUSTOM_CTRL_A then -- home
self:setCursor(1)
return true
elseif keys.CURSOR_RIGHT then
elseif keys.KEYBOARD_CURSOR_RIGHT then
self:setCursor(self.cursor + 1)
return true
elseif keys.A_MOVE_E_DOWN then -- Ctrl-Right (beginning of next word)
elseif keys.CUSTOM_CTRL_F then -- forward one word
local _,next_word_start = self.text:find('[^%w_%-][%w_%-]', self.cursor)
self:setCursor(next_word_start)
return true
elseif keys.A_CARE_MOVE_E then -- Alt-Right (end)
elseif keys.CUSTOM_CTRL_E then -- end
self:setCursor()
return true
end
@ -938,10 +935,26 @@ function Scrollbar:onRenderBody(dc)
end
function Scrollbar:onInput(keys)
if not keys._MOUSE_L_DOWN or not self.on_scroll
or not scrollbar_is_visible(self) then
if not self.on_scroll or not scrollbar_is_visible(self) then
return false
end
if self.parent_view:getMousePos() then
if keys.CONTEXT_SCROLL_UP then
self.on_scroll('up_small')
return true
elseif keys.CONTEXT_SCROLL_DOWN then
self.on_scroll('down_small')
return true
elseif keys.CONTEXT_SCROLL_PAGEUP then
self.on_scroll('up_large')
return true
elseif keys.CONTEXT_SCROLL_PAGEDOWN then
self.on_scroll('down_large')
return true
end
end
if not keys._MOUSE_L_DOWN then return false end
local _,y = self:getMousePos()
if not y then return false end
local scroll_spec = nil
@ -1683,12 +1696,14 @@ end
function List:submit()
if self.on_submit and #self.choices > 0 then
self.on_submit(self:getSelected())
return true
end
end
function List:submit2()
if self.on_submit2 and #self.choices > 0 then
self.on_submit2(self:getSelected())
return true
end
end
@ -1696,12 +1711,10 @@ function List:onInput(keys)
if self:inputToSubviews(keys) then
return true
end
if self.on_submit and keys.SELECT then
self:submit()
return true
elseif self.on_submit2 and keys.SEC_SELECT then
self:submit2()
return true
if keys.SELECT then
return self:submit()
elseif keys.CUSTOM_SHIFT_ENTER then
return self:submit2()
elseif keys._MOUSE_L_DOWN then
local idx = self:getIdxUnderMouse()
if idx then