Reworked capturing system

This commit is contained in:
IgorTimofeev 2024-01-27 16:22:03 +03:00
parent 278e3b5cf2
commit 1b686708ea
4 changed files with 170 additions and 141 deletions

View File

@ -54,7 +54,7 @@ window.eventHandler = function(workspace, window, ...)
workspace:draw()
elseif e[1] == "key_down" and GUI.focusedObject == window then
elseif e[1] == "key_down" and workspace.focusedObject == window then
-- Return
if e[4] == 28 then
window:addLine("> " .. input)

View File

@ -104,7 +104,7 @@ local overrideCodeViewDraw = codeView.draw
codeView.draw = function(...)
overrideCodeViewDraw(...)
if cursorBlinkState and GUI.focusedObject == window then
if cursorBlinkState and workspace.focusedObject == window then
local x, y = codeView.codeAreaPosition + cursorPositionSymbol - codeView.fromSymbol + 1, codeView.y + cursorPositionLine - codeView.fromLine
if
x >= codeView.codeAreaPosition + 1 and
@ -1385,6 +1385,8 @@ end
local uptime = computer.uptime()
codeView.eventHandler = function(workspace, object, e1, e2, e3, e4, e5)
if e1 == "touch" then
workspace.focusedObject = window
e3, e4 = math.ceil(e3), math.ceil(e4)
if checkScrollbar(e4) then
@ -1426,7 +1428,7 @@ codeView.eventHandler = function(workspace, object, e1, e2, e3, e4, e5)
tick(true)
elseif e1 == "key_down" and GUI.focusedObject == window then
elseif e1 == "key_down" and workspace.focusedObject == window then
-- Ctrl or CMD
if keyboard.isControlDown() or keyboard.isCommandDown() then
-- Slash

View File

@ -262,15 +262,33 @@ local function containerObjectAddAnimation(object, frameHandler, onFinish)
onFinish = onFinish,
}
object.firstParent.animations = object.firstParent.animations or {}
table.insert(object.firstParent.animations, animation)
object.workspace.animations = object.workspace.animations or {}
table.insert(object.workspace.animations, animation)
return animation
end
local function containerAddChild(container, object, atIndex)
-- Parent containers
object.parent = container
local function updateWorkspace(object, workspace)
object.workspace = workspace
if object.children then
for i = 1, #object.children do
updateWorkspace(object.children[i], workspace)
end
end
end
updateWorkspace(object, container.workspace or container)
-- Position
object.localX = object.x
object.localY = object.y
-- Additional methods after adding to parent container
object.indexOf = containerObjectIndexOf
object.moveToFront = containerObjectMoveToFront
object.moveToBack = containerObjectMoveToBack
@ -279,18 +297,6 @@ local function containerAddChild(container, object, atIndex)
object.remove = containerObjectRemove
object.addAnimation = containerObjectAddAnimation
local function updateFirstParent(object, firstParent)
object.firstParent = firstParent
if object.children then
for i = 1, #object.children do
updateFirstParent(object.children[i], firstParent)
end
end
end
object.parent = container
updateFirstParent(object, container.firstParent or container)
if atIndex then
table.insert(container.children, atIndex, object)
else
@ -367,22 +373,77 @@ end
--------------------------------------------------------------------------------
local function workspaceStart(workspace, eventPullTimeout)
local animation, animationIndex, animationOnFinishMethodsIndex, animationOnFinishMethods, roundedX, roundedY, isScreenEvent, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32
local
e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32,
isScreenEvent,
checkBounds,
roundedX,
roundedY,
capturedObject,
animation,
animationIndex,
animationOnFinishMethodsIndex,
animationOnFinishMethods
local function handleContainer(currentContainer, boundsX1, boundsY1, boundsX2, boundsY2)
local processObject, processContainer
processObject = function(child, boundsX1, boundsY1, boundsX2, boundsY2)
-- Container
if child.children then
newBoundsX1, newBoundsY1, newBoundsX2, newBoundsY2 = getRectangleBounds(
boundsX1,
boundsY1,
boundsX2,
boundsY2,
child.x,
child.y,
child.x + child.width - 1,
child.y + child.height - 1
)
if
newBoundsX1
and processContainer(
child,
newBoundsX1,
newBoundsY1,
newBoundsX2,
newBoundsY2
)
then
return true
end
-- Not container
else
if isScreenEvent then
if not checkBounds or child:isPointInside(roundedX, roundedY)then
if child.eventHandler and not child.disabled then
child.eventHandler(workspace, child, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32)
end
if not child.passScreenEvents then
return true
end
end
elseif child.eventHandler then
child.eventHandler(workspace, child, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32)
end
end
end
processContainer = function(currentContainer, boundsX1, boundsY1, boundsX2, boundsY2)
local currentContainerPassed, child, newBoundsX1, newBoundsY1, newBoundsX2, newBoundsY2
if isScreenEvent then
roundedX, roundedY = math.ceil(e3), math.ceil(e4)
if not (
if checkBounds and not (
roundedX >= boundsX1
and roundedX <= boundsX2
and roundedY >= boundsY1
and roundedY <= boundsY2
or currentContainer.ignoresBoundsCheckOnScreenEvents
) then
return
end
@ -401,55 +462,10 @@ local function workspaceStart(workspace, eventPullTimeout)
child = currentContainer.children[i]
if not child.hidden then
-- Container
if child.children then
newBoundsX1, newBoundsY1, newBoundsX2, newBoundsY2 = getRectangleBounds(
boundsX1,
boundsY1,
boundsX2,
boundsY2,
child.x,
child.y,
child.x + child.width - 1,
child.y + child.height - 1
)
checkBounds = true
if
newBoundsX1
and handleContainer(
child,
newBoundsX1,
newBoundsY1,
newBoundsX2,
newBoundsY2,
e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32
)
then
return true
end
-- Not container
else
if workspace.needConsume then
workspace.needConsume = nil
return true
end
if isScreenEvent then
if child:isPointInside(roundedX, roundedY) or child.ignoresBoundsCheckOnScreenEvents then
if child.eventHandler and not child.disabled then
child.eventHandler(workspace, child, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32)
end
if not child.passScreenEvents then
return true
end
end
elseif child.eventHandler then
child.eventHandler(workspace, child, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32)
end
if processObject(child, boundsX1, boundsY1, boundsX2, boundsY2) then
return true
end
end
end
@ -471,13 +487,35 @@ local function workspaceStart(workspace, eventPullTimeout)
e1 == "scroll" or
e1 == "double_touch"
handleContainer(
workspace,
workspace.x,
workspace.y,
workspace.x + workspace.width - 1,
workspace.y + workspace.height - 1
)
if isScreenEvent then
roundedX, roundedY = math.ceil(e3), math.ceil(e4)
end
capturedObject = workspace.capturedObject
if capturedObject then
if not capturedObject.hidden then
checkBounds = false
processObject(
capturedObject,
workspace.x,
workspace.y,
workspace.x + workspace.width - 1,
workspace.y + workspace.height - 1
)
end
else
checkBounds = true
processContainer(
workspace,
workspace.x,
workspace.y,
workspace.x + workspace.width - 1,
workspace.y + workspace.height - 1
)
end
if workspace.animations then
animationIndex, animationOnFinishMethodsIndex, animationOnFinishMethods = 1, 1, {}
@ -532,12 +570,9 @@ local function workspaceStop(workspace)
workspace.needClose = true
end
local function workspaceConsumeEvent(workspace)
workspace.needConsume = true
end
local function workspaceDraw(object, ...)
containerDraw(object)
screen.update(...)
end
@ -547,7 +582,6 @@ function GUI.workspace(x, y, width, height)
workspace.draw = workspaceDraw
workspace.start = workspaceStart
workspace.stop = workspaceStop
workspace.consumeEvent = workspaceConsumeEvent
return workspace
end
@ -2112,7 +2146,7 @@ function GUI.addFilesystemDialog(parentContainer, addPanel, ...)
local function onAnyTouch()
container:remove()
filesystemDialog.firstParent:draw()
filesystemDialog.workspace:draw()
end
filesystemDialog.cancelButton.onTouch = function()
@ -2846,13 +2880,15 @@ end
local function inputDraw(input)
local background, foreground, transparency, text
if input.focused then
if input.workspace.focusedObject == input then
background, transparency = input.colors.focused.background, input.colors.focused.transparency
if input.text == "" then
input.textCutFrom = 1
foreground, text = input.colors.placeholderText, input.text
else
foreground = input.colors.focused.text
if input.textMask then
text = string.rep(input.textMask, unicode.len(input.text))
else
@ -2905,8 +2941,8 @@ local function inputCursorBlink(workspace, input, state)
end
local function inputStopInput(workspace, input)
input.stopInputObject:remove()
input.focused = false
input.workspace.capturedObject = nil
input.workspace.focusedObject = nil
if input.validator then
if not input.validator(input.text) then
@ -2926,7 +2962,8 @@ end
local function inputStartInput(input)
input.startText = input.text
input.focused = true
input.workspace.capturedObject = input
input.workspace.focusedObject = input
if input.historyEnabled then
input.historyIndex = input.historyIndex + 1
@ -2937,26 +2974,26 @@ local function inputStartInput(input)
end
input:setCursorPosition(input.cursorPosition)
input.stopInputObject.width, input.stopInputObject.height = input.firstParent.width, input.firstParent.height
input.firstParent:addChild(input.stopInputObject)
inputCursorBlink(input.firstParent, input, true)
inputCursorBlink(input.workspace, input, true)
end
local function inputEventHandler(workspace, input, e1, e2, e3, e4, e5, e6, ...)
if e1 == "touch" or e1 == "drag" then
input:setCursorPosition(input.textCutFrom + math.ceil(e3) - input.x - input.textOffset)
local focused = workspace.focusedObject == input
if input.focused then
inputCursorBlink(workspace, input, true)
if e1 == "touch" or e1 == "drag" then
if input:isPointInside(math.ceil(e3), math.ceil(e4)) then
input:setCursorPosition(input.textCutFrom + math.ceil(e3) - input.x - input.textOffset)
if focused then
inputCursorBlink(workspace, input, true)
else
input:startInput()
end
else
input:startInput()
inputStopInput(workspace, input)
end
elseif e1 == "key_down" and input.focused then
workspace:consumeEvent()
elseif e1 == "key_down" and focused then
-- Return
if e4 == 28 then
if input.historyEnabled then
@ -3050,14 +3087,13 @@ local function inputEventHandler(workspace, input, e1, e2, e3, e4, e5, e6, ...)
inputCursorBlink(workspace, input, true)
elseif e1 == "clipboard" and input.focused then
elseif e1 == "clipboard" and focused then
input.text = unicode.sub(input.text, 1, input.cursorPosition - 1) .. e3 .. unicode.sub(input.text, input.cursorPosition, -1)
input:setCursorPosition(input.cursorPosition + unicode.len(e3))
inputCursorBlink(workspace, input, true)
workspace:consumeEvent()
elseif not e1 and input.focused and computer.uptime() - input.cursorBlinkUptime > input.cursorBlinkDelay then
elseif not e1 and focused and computer.uptime() - input.cursorBlinkUptime > input.cursorBlinkDelay then
inputCursorBlink(workspace, input, not input.cursorBlinkState)
end
end
@ -3097,17 +3133,6 @@ function GUI.input(x, y, width, height, backgroundColor, textColor, placeholderT
input.historyIndex = 0
input.historyEnabled = false
input.stopInputObject = GUI.object(1, 1, 1, 1)
input.stopInputObject.eventHandler = function(workspace, object, e1, e2, e3, e4, ...)
if e1 == "touch" or e1 == "drop" then
if input:isPointInside(math.ceil(e3), math.ceil(e4)) then
input.eventHandler(workspace, input, e1, e2, e3, e4, ...)
else
inputStopInput(workspace, input)
end
end
end
input.textDrawMethod = inputTextDrawMethod
input.draw = inputDraw
input.eventHandler = inputEventHandler
@ -3493,7 +3518,7 @@ function GUI.palette(x, y, startColor)
local function onAnyInputFinished()
paletteRefreshBigImage()
paletteUpdateCrestsCoordinates()
palette.firstParent:draw()
palette.workspace:draw()
end
local function onHexInputFinished()
@ -4471,7 +4496,7 @@ function GUI.comboBox(x, y, width, height, backgroundColor, textColor, arrowBack
comboBox.dropDownMenu.onMenuClosed = function(index)
comboBox.pressed = false
comboBox.selectedItem = index or comboBox.selectedItem
comboBox.firstParent:draw()
comboBox.workspace:draw()
if index and comboBox.onItemSelected then
comboBox.onItemSelected(index)
@ -4541,7 +4566,7 @@ local function windowEventHandler(workspace, window, e1, e2, e3, e4, ...)
e3, e4 = math.ceil(e3), math.ceil(e4)
if not windowScreenEventCheck(window, e3, e4) then
window.ignoresBoundsCheckOnScreenEvents = true
workspace.capturedObject = window
window.lastTouchX, window.lastTouchY = e3, e4
end
@ -4555,17 +4580,13 @@ local function windowEventHandler(workspace, window, e1, e2, e3, e4, ...)
elseif e1 == "drag" and window.lastTouchX then
e3, e4 = math.ceil(e3), math.ceil(e4)
if windowScreenEventCheck(window, e3, e4) then
return
end
window.localX, window.localY = window.localX + e3 - window.lastTouchX, window.localY + e4 - window.lastTouchY
window.lastTouchX, window.lastTouchY = e3, e4
workspace:draw()
elseif e1 == "drop" then
window.lastTouchX, window.lastTouchY, window.ignoresBoundsCheckOnScreenEvents = nil, nil, nil
window.lastTouchX, window.lastTouchY, workspace.capturedObject = nil, nil, nil
end
end
@ -4632,7 +4653,7 @@ function GUI.windowMaximize(window, animationDisabled)
end
local function windowFocus(window)
GUI.focusedObject = window
window.workspace.focusedObject = window
window.hidden = false
window:moveToFront()
@ -4751,7 +4772,7 @@ local function menuAddContextMenuItem(menu, ...)
item.contextMenu = contextMenuCreate(1, 1)
item.contextMenu.onMenuClosed = function()
item.pressed = false
item.firstParent:draw()
item.workspace:draw()
end
return item.contextMenu

View File

@ -1056,8 +1056,8 @@ local function iconFieldIconEventHandler(workspace, icon, e1, e2, e3, e4, e5, ..
if e1 == "touch" then
local iconField = icon.parent
icon.ignoresBoundsCheckOnScreenEvents = true
GUI.focusedObject = iconField
workspace.focusedObject = iconField
workspace.capturedObject = icon
icon.lastTouchPosition = icon.lastTouchPosition or {}
icon.lastTouchPosition.x, icon.lastTouchPosition.y = e3, e4
@ -1082,17 +1082,16 @@ local function iconFieldIconEventHandler(workspace, icon, e1, e2, e3, e4, e5, ..
elseif e1 == "double_touch" and e5 == 0 then
iconOnDoubleClick(icon, e1, e2, e3, e4, e5, ...)
elseif e1 == "drag" and icon.parent.iconConfigEnabled and icon.lastTouchPosition then
-- Ебучие авторы мода, ну на кой хуй было делать drop-ивент без наличия drag? ПИДОРЫ
icon.dragStarted = true
-- Ебучие авторы мода, ну на кой хуй было делать drop-ивент без наличия drag? ПИДОРЫ
elseif e1 == "drag" and icon.parent.iconConfigEnabled and workspace.capturedObject == icon then
icon.localX = icon.localX + e3 - icon.lastTouchPosition.x
icon.localY = icon.localY + e4 - icon.lastTouchPosition.y
icon.lastTouchPosition.x, icon.lastTouchPosition.y = e3, e4
workspace:draw()
elseif e1 == "drop" then
icon.dragStarted, icon.lastTouchPosition, icon.ignoresBoundsCheckOnScreenEvents = nil, nil, nil
elseif e1 == "drop" and workspace.capturedObject == icon then
icon.lastTouchPosition, workspace.capturedObject = nil, nil
iconFieldSaveIconPosition(
icon.parent,
@ -1247,6 +1246,8 @@ end
local function iconFieldSaveIconConfig(iconField)
filesystem.writeTable(iconField.path .. ".icons", iconField.iconConfig)
-- GUI.alert("SAVE", iconField.path .. ".icons", debug.traceback())
end
local function iconFieldDeleteIconConfig(iconField)
@ -1291,6 +1292,7 @@ end
local function anyIconFieldUpdateFileList(iconField, func)
local list, reason = filesystem.list(iconField.path, userSettings.filesSortingMethod)
if list then
-- Hidden files and filename matcher
local i = 1
@ -1344,7 +1346,7 @@ local function iconFieldUpdateFileList(iconField)
iconField.iconCount.total = iconField.iconCount.horizontal * iconField.iconCount.vertical
-- Clearing eblo
iconField:removeChildren(2)
iconField:removeChildren()
-- Updating icon config if possible
if iconField.iconConfigEnabled then
@ -1398,9 +1400,9 @@ local function iconFieldUpdateFileList(iconField)
nextX()
end
if iconField.iconConfigEnabled then
iconField:saveIconConfig()
end
-- if iconField.iconConfigEnabled then
-- iconField:saveIconConfig()
-- end
end)
end
@ -1729,7 +1731,8 @@ end
local function gridIconFieldEventHandler(workspace, iconField, e1, e2, e3, e4, e5, ...)
if e1 == "touch" then
GUI.focusedObject = iconField
workspace.focusedObject = iconField
workspace.capturedObject = iconField
if e5 == 0 then
iconField:clearSelection()
@ -1777,13 +1780,16 @@ local function gridIconFieldEventHandler(workspace, iconField, e1, e2, e3, e4, e
workspace:draw()
elseif e1 == "drop" then
workspace.focusedObject = nil
workspace.capturedObject = nil
iconField.selection = nil
iconFieldCheckSelection(iconField)
workspace:draw()
elseif e1 == "key_down" then
if GUI.focusedObject ~= iconField then
if workspace.focusedObject ~= iconField then
return
end
@ -2035,7 +2041,7 @@ local function windowRemove(window)
-- Удаляем само окошко
table.remove(window.parent.children, window:indexOf())
GUI.focusedObject = updateDesktopMenuAndGetTopmostWindow()
workspace.focusedObject = updateDesktopMenuAndGetTopmostWindow()
end
function system.addWindow(window, dontAddToDock, preserveCoordinates)
@ -2051,7 +2057,7 @@ function system.addWindow(window, dontAddToDock, preserveCoordinates)
-- Ебурим окно к окнам
desktopWindowsContainer:addChild(window)
GUI.focusedObject = window
workspace.focusedObject = window
if not dontAddToDock then
-- Получаем путь залупы