mirror of https://github.com/kepler155c/opus
146 lines
3.0 KiB
Lua
146 lines
3.0 KiB
Lua
local class = require('opus.class')
|
|
local UI = require('opus.ui')
|
|
local Util = require('opus.util')
|
|
|
|
UI.Page = class(UI.Window)
|
|
UI.Page.defaults = {
|
|
UIElement = 'Page',
|
|
accelerators = {
|
|
down = 'focus_next',
|
|
scroll_down = 'focus_next',
|
|
enter = 'focus_next',
|
|
tab = 'focus_next',
|
|
['shift-tab' ] = 'focus_prev',
|
|
up = 'focus_prev',
|
|
scroll_up = 'focus_prev',
|
|
},
|
|
backgroundColor = 'primary',
|
|
textColor = 'white',
|
|
}
|
|
function UI.Page:postInit()
|
|
self.parent = self.parent or UI.term
|
|
self.__target = self
|
|
end
|
|
|
|
function UI.Page:sync()
|
|
if self.enabled then
|
|
self:checkFocus()
|
|
self.parent:setCursorBlink(self.focused and self.focused.cursorBlink)
|
|
self.parent:sync()
|
|
end
|
|
end
|
|
|
|
function UI.Page:capture(child)
|
|
self.__target = child
|
|
end
|
|
|
|
function UI.Page:release(child)
|
|
if self.__target == child then
|
|
self.__target = self
|
|
end
|
|
end
|
|
|
|
function UI.Page:pointToChild(x, y)
|
|
if self.__target == self then
|
|
return UI.Window.pointToChild(self, x, y)
|
|
end
|
|
|
|
local function getPosition(element)
|
|
local x, y = 1, 1
|
|
repeat
|
|
x = element.x + x - 1
|
|
y = element.y + y - 1
|
|
element = element.parent
|
|
until not element
|
|
return x, y
|
|
end
|
|
|
|
local absX, absY = getPosition(self.__target)
|
|
return self.__target:pointToChild(x - absX + self.__target.x, y - absY + self.__target.y)
|
|
end
|
|
|
|
function UI.Page:getFocusables()
|
|
if self.__target == self or not self.__target.modal then
|
|
return UI.Window.getFocusables(self)
|
|
end
|
|
return self.__target:getFocusables()
|
|
end
|
|
|
|
function UI.Page:getFocused()
|
|
return self.focused
|
|
end
|
|
|
|
function UI.Page:focusPrevious()
|
|
local function getPreviousFocus(focused)
|
|
local focusables = self:getFocusables()
|
|
local k = Util.contains(focusables, focused)
|
|
if k then
|
|
if k > 1 then
|
|
return focusables[k - 1]
|
|
end
|
|
return focusables[#focusables]
|
|
end
|
|
end
|
|
|
|
local focused = getPreviousFocus(self.focused)
|
|
if focused then
|
|
self:setFocus(focused)
|
|
end
|
|
end
|
|
|
|
function UI.Page:focusNext()
|
|
local function getNextFocus(focused)
|
|
local focusables = self:getFocusables()
|
|
local k = Util.contains(focusables, focused)
|
|
if k then
|
|
if k < #focusables then
|
|
return focusables[k + 1]
|
|
end
|
|
return focusables[1]
|
|
end
|
|
end
|
|
|
|
local focused = getNextFocus(self.focused)
|
|
if focused then
|
|
self:setFocus(focused)
|
|
end
|
|
end
|
|
|
|
function UI.Page:setFocus(child)
|
|
if not child or not child.focus then
|
|
return
|
|
end
|
|
|
|
if self.focused and self.focused ~= child then
|
|
self.focused.focused = false
|
|
self.focused:focus()
|
|
self.focused:emit({ type = 'focus_lost', focused = child, unfocused = self.focused })
|
|
end
|
|
|
|
self.focused = child
|
|
if not child.focused then
|
|
child.focused = true
|
|
child:emit({ type = 'focus_change', focused = child })
|
|
end
|
|
|
|
child:focus()
|
|
end
|
|
|
|
function UI.Page:checkFocus()
|
|
if not self.focused or not self.focused.enabled then
|
|
self.__target:focusFirst()
|
|
end
|
|
end
|
|
|
|
function UI.Page:eventHandler(event)
|
|
if self.focused then
|
|
if event.type == 'focus_next' then
|
|
self:focusNext()
|
|
return true
|
|
elseif event.type == 'focus_prev' then
|
|
self:focusPrevious()
|
|
return true
|
|
end
|
|
end
|
|
end
|