2023-08-04 10:59:08 -06:00
|
|
|
config.target = 'core'
|
2023-08-04 02:35:51 -06:00
|
|
|
|
2020-03-26 23:38:40 -06:00
|
|
|
local gui = require('gui')
|
|
|
|
|
|
|
|
function test.getKeyDisplay()
|
|
|
|
expect.eq(gui.getKeyDisplay(df.interface_key.CUSTOM_A), 'a')
|
|
|
|
expect.eq(gui.getKeyDisplay('CUSTOM_A'), 'a')
|
|
|
|
expect.eq(gui.getKeyDisplay(df.interface_key._first_item - 1), '?')
|
|
|
|
expect.eq(gui.getKeyDisplay(df.interface_key._last_item + 1), '?')
|
|
|
|
expect.eq(gui.getKeyDisplay(df.interface_key.KEYBINDING_COMPLETE), '?')
|
|
|
|
end
|
|
|
|
|
|
|
|
function test.clear_pen()
|
|
|
|
expect.table_eq(gui.CLEAR_PEN, {
|
2023-08-04 02:35:51 -06:00
|
|
|
tile = df.global.init.texpos_border_interior,
|
2020-03-26 23:38:40 -06:00
|
|
|
ch = string.byte(' '),
|
|
|
|
fg = COLOR_BLACK,
|
|
|
|
bg = COLOR_BLACK,
|
|
|
|
bold = false,
|
|
|
|
tile_color = false,
|
|
|
|
})
|
|
|
|
end
|
2022-06-01 18:42:13 -06:00
|
|
|
|
|
|
|
WantsFocusView = defclass(WantsFocusView, gui.View)
|
|
|
|
function WantsFocusView:getPreferredFocusState()
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
function test.view_wants_focus()
|
|
|
|
local parent = gui.View()
|
|
|
|
expect.false_(parent.focus)
|
|
|
|
|
|
|
|
-- expect first (regular) child to not get focus
|
|
|
|
local regular_child = gui.View()
|
|
|
|
expect.false_(regular_child.focus)
|
|
|
|
expect.ne(parent.focus_group, regular_child.focus_group)
|
|
|
|
parent:addviews{regular_child}
|
|
|
|
expect.false_(regular_child.focus)
|
|
|
|
expect.eq(parent.focus_group, regular_child.focus_group)
|
|
|
|
|
|
|
|
-- the first child who wants focus gets it
|
|
|
|
local focus_child = WantsFocusView()
|
|
|
|
expect.false_(focus_child.focus)
|
|
|
|
parent:addviews{focus_child}
|
|
|
|
expect.true_(focus_child.focus)
|
|
|
|
expect.eq(parent.focus_group.cur, focus_child)
|
|
|
|
|
|
|
|
-- the second child who wants focus doesn't
|
|
|
|
local focus_child2 = WantsFocusView()
|
|
|
|
parent:addviews{focus_child2}
|
|
|
|
expect.false_(focus_child2.focus)
|
|
|
|
expect.eq(parent.focus_group.cur, focus_child)
|
|
|
|
end
|
|
|
|
|
|
|
|
function test.inherit_focus_from_subview()
|
|
|
|
local parent = gui.View()
|
|
|
|
local regular_child = gui.View()
|
|
|
|
local focus_child = WantsFocusView()
|
|
|
|
regular_child:addviews{focus_child}
|
|
|
|
expect.true_(focus_child.focus)
|
|
|
|
parent:addviews{regular_child}
|
|
|
|
expect.eq(parent.focus_group.cur, focus_child)
|
|
|
|
end
|
|
|
|
|
|
|
|
function test.subviews_negotiate_focus()
|
|
|
|
local parent = gui.View()
|
|
|
|
local regular_child = gui.View()
|
|
|
|
local regular_child2 = gui.View()
|
|
|
|
local focus_child = WantsFocusView()
|
|
|
|
local focus_child2 = WantsFocusView()
|
|
|
|
regular_child:addviews{focus_child}
|
|
|
|
regular_child2:addviews{focus_child2}
|
|
|
|
expect.true_(focus_child.focus)
|
|
|
|
expect.true_(focus_child2.focus)
|
|
|
|
expect.ne(regular_child.focus_group, regular_child2.focus_group)
|
|
|
|
parent:addviews{regular_child}
|
|
|
|
expect.eq(parent.focus_group.cur, focus_child)
|
|
|
|
expect.true_(focus_child.focus)
|
|
|
|
expect.true_(focus_child2.focus)
|
|
|
|
parent:addviews{regular_child2}
|
|
|
|
expect.eq(parent.focus_group.cur, focus_child)
|
|
|
|
expect.eq(regular_child.focus_group, regular_child2.focus_group)
|
|
|
|
expect.true_(focus_child.focus)
|
|
|
|
expect.false_(focus_child2.focus)
|
|
|
|
end
|
|
|
|
|
|
|
|
MockInputView = defclass(MockInputView, gui.View)
|
|
|
|
function MockInputView:onInput(keys)
|
|
|
|
self.mock(keys)
|
|
|
|
MockInputView.super.onInput(self, keys)
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
local function reset_child_mocks(parent)
|
|
|
|
for _,child in ipairs(parent.subviews) do
|
|
|
|
child.mock = mock.func()
|
|
|
|
reset_child_mocks(child)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- verify that input got routed as expected
|
|
|
|
local function test_children(expected, parent)
|
|
|
|
local children = parent.subviews
|
|
|
|
for i,val in ipairs(expected) do
|
|
|
|
expect.eq(val, children[i].mock.call_count, 'child '..i)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function test.keyboard_follows_focus()
|
|
|
|
local parent = gui.View()
|
|
|
|
local regular_child = MockInputView{}
|
|
|
|
local regular_child2 = MockInputView{}
|
|
|
|
local last_child = MockInputView{}
|
|
|
|
parent:addviews{regular_child, regular_child2, last_child}
|
|
|
|
|
|
|
|
reset_child_mocks(parent)
|
|
|
|
parent:onInput({'a'})
|
|
|
|
test_children({0,0,1}, parent)
|
|
|
|
|
|
|
|
regular_child:setFocus(true)
|
|
|
|
reset_child_mocks(parent)
|
|
|
|
parent:onInput({'a'})
|
|
|
|
test_children({1,0,0}, parent)
|
|
|
|
|
|
|
|
regular_child2:setFocus(true)
|
|
|
|
reset_child_mocks(parent)
|
|
|
|
parent:onInput({'a'})
|
|
|
|
test_children({0,1,0}, parent)
|
|
|
|
|
|
|
|
regular_child2:setFocus(false)
|
|
|
|
reset_child_mocks(parent)
|
|
|
|
parent:onInput({'a'})
|
|
|
|
test_children({0,0,1}, parent)
|
|
|
|
end
|
|
|
|
|
|
|
|
function test.one_callback_on_double_focus()
|
|
|
|
local on_focus = mock.func()
|
|
|
|
local view = gui.View{on_focus=on_focus}
|
|
|
|
expect.eq(0, on_focus.call_count)
|
|
|
|
view:setFocus(true)
|
|
|
|
expect.eq(1, on_focus.call_count)
|
|
|
|
view:setFocus(true)
|
|
|
|
expect.eq(1, on_focus.call_count)
|
|
|
|
end
|
|
|
|
|
|
|
|
function test.one_callback_on_double_unfocus()
|
|
|
|
local on_unfocus = mock.func()
|
|
|
|
local view = gui.View{on_unfocus=on_unfocus}
|
|
|
|
expect.eq(0, on_unfocus.call_count)
|
|
|
|
view:setFocus(false)
|
|
|
|
expect.eq(0, on_unfocus.call_count)
|
|
|
|
view:setFocus(true)
|
|
|
|
expect.eq(0, on_unfocus.call_count)
|
|
|
|
view:setFocus(false)
|
|
|
|
expect.eq(1, on_unfocus.call_count)
|
|
|
|
view:setFocus(false)
|
|
|
|
expect.eq(1, on_unfocus.call_count)
|
|
|
|
end
|
|
|
|
|
|
|
|
function test.no_input_when_focus_owner_is_hidden()
|
|
|
|
local parent = gui.View()
|
|
|
|
local child1 = MockInputView()
|
|
|
|
local child2 = MockInputView()
|
|
|
|
parent:addviews{child1, child2}
|
|
|
|
child1:setFocus(true)
|
|
|
|
child1.visible = false
|
|
|
|
reset_child_mocks(parent)
|
|
|
|
parent:onInput({'a'})
|
|
|
|
test_children({0,1}, parent)
|
|
|
|
end
|
|
|
|
|
|
|
|
function test.no_input_when_ancestor_is_hidden()
|
|
|
|
local grandparent = gui.View()
|
|
|
|
local parent = MockInputView()
|
|
|
|
local child1 = MockInputView()
|
|
|
|
local child2 = MockInputView()
|
|
|
|
grandparent:addviews{parent}
|
|
|
|
parent:addviews{child1, child2}
|
|
|
|
child1:setFocus(true)
|
|
|
|
parent.visible = false
|
|
|
|
reset_child_mocks(grandparent)
|
|
|
|
grandparent:onInput({'a'})
|
|
|
|
test_children({0}, grandparent)
|
|
|
|
test_children({0,0}, parent)
|
|
|
|
end
|
|
|
|
|
|
|
|
function test.no_input_loop_in_children_of_focus_owner()
|
|
|
|
local grandparent = gui.View()
|
|
|
|
local parent = MockInputView()
|
|
|
|
local child = MockInputView()
|
|
|
|
grandparent:addviews{parent}
|
|
|
|
parent:addviews{child}
|
|
|
|
parent:setFocus(true)
|
|
|
|
reset_child_mocks(grandparent)
|
|
|
|
child:onInput({'a'})
|
|
|
|
test_children({0}, grandparent)
|
|
|
|
test_children({1}, parent)
|
|
|
|
end
|