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 ## Fixes
## Misc Improvements ## Misc Improvements
- Scrollable widgets now react to mouse wheel events when the mouse is over the widget
## Documentation ## Documentation
- `overlay-dev-guide`: added troubleshooting tips and common development workflows - `overlay-dev-guide`: added troubleshooting tips and common development workflows

@ -4316,7 +4316,6 @@ Attributes:
If it returns false, the character is ignored. If it returns false, the character is ignored.
:on_change: Change notification callback; used as ``on_change(new_text,old_text)``. :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_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: 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 :key_sep: If specified, will be used to customize how the activation key is
displayed. See ``token.key_sep`` in the ``Label`` documentation below. 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: following keyboard hotkeys:
- Left/Right arrow: move the cursor one character to the left or right. - 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. - Ctrl-B/Ctrl-F: move the cursor one word back or forward.
- Alt-Left/Right arrow: move the cursor to the beginning/end of the text. - Ctrl-A/Ctrl-E: move the cursor to the beginning/end of the text.
Scrollbar class 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 associated widget, and after scrolling is complete, the associated widget must
call ``scrollbar:update()`` with updated new display info. 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 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 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 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. with an empty list.
:on_submit: Enter key or mouse click callback; if specified, the list reacts to the :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)``. 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 :on_submit2: Shift-click callback; if specified, the list reacts to the click and
reacts to the key/click and calls it as ``on_submit2(index,choice)``. calls the callback as ``on_submit2(index,choice)``.
:row_height: Height of every row in text lines. :row_height: Height of every row in text lines.
:icon_width: If not *nil*, the specified number of character columns :icon_width: If not *nil*, the specified number of character columns
are reserved to the left of the list item for the icons. are reserved to the left of the list item for the icons.

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

@ -48,7 +48,7 @@ end
function MessageBox:onRenderFrame(dc,rect) function MessageBox:onRenderFrame(dc,rect)
MessageBox.super.onRenderFrame(self,dc,rect) MessageBox.super.onRenderFrame(self,dc,rect)
if self.on_accept then 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
end end
@ -59,19 +59,16 @@ function MessageBox:onDestroy()
end end
function MessageBox:onInput(keys) function MessageBox:onInput(keys)
if keys.MENU_CONFIRM then if keys.SELECT or keys.LEAVESCREEN then
self:dismiss() self:dismiss()
if self.on_accept then if keys.SELECT and self.on_accept then
self.on_accept() self.on_accept()
end elseif keys.LEAVESCREEN and self.on_cancel then
elseif keys.LEAVESCREEN or (keys.SELECT and not self.on_accept) then
self:dismiss()
if self.on_cancel then
self.on_cancel() self.on_cancel()
end end
else return true
self:inputToSubviews(keys)
end end
return self:inputToSubviews(keys)
end end
function showMessage(title, text, tcolor, on_close) function showMessage(title, text, tcolor, on_close)
@ -132,14 +129,15 @@ function InputBox:onInput(keys)
if self.on_input then if self.on_input then
self.on_input(self.subviews.edit.text) self.on_input(self.subviews.edit.text)
end end
return true
elseif keys.LEAVESCREEN then elseif keys.LEAVESCREEN then
self:dismiss() self:dismiss()
if self.on_cancel then if self.on_cancel then
self.on_cancel() self.on_cancel()
end end
else return true
self:inputToSubviews(keys)
end end
return self:inputToSubviews(keys)
end end
function showInputPrompt(title, text, tcolor, input, on_input, on_cancel, min_width) 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 if self.on_cancel then
self.on_cancel() self.on_cancel()
end end
else return true
self:inputToSubviews(keys)
end end
return self:inputToSubviews(keys)
end end
function showListPrompt(title, text, tcolor, choices, on_select, on_cancel, min_width, filter) 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 end
MOVEMENT_KEYS = { 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_UP = { 0, -1, 0 }, CURSOR_DOWN = { 0, 1, 0 },
CURSOR_LEFT = { -1, 0, 0 }, CURSOR_RIGHT = { 1, 0, 0 }, CURSOR_LEFT = { -1, 0, 0 }, CURSOR_RIGHT = { 1, 0, 0 },
CURSOR_UPLEFT = { -1, -1, 0 }, CURSOR_UPRIGHT = { 1, -1, 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
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 return _ENV

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

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