diff --git a/Applications/Console.app/Main.lua b/Applications/Console.app/Main.lua index 89e7310c..91e8905a 100644 --- a/Applications/Console.app/Main.lua +++ b/Applications/Console.app/Main.lua @@ -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) diff --git a/Applications/MineCode IDE.app/Main.lua b/Applications/MineCode IDE.app/Main.lua index e47a0aa2..2b482f8f 100755 --- a/Applications/MineCode IDE.app/Main.lua +++ b/Applications/MineCode IDE.app/Main.lua @@ -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 diff --git a/Libraries/GUI.lua b/Libraries/GUI.lua index fee80042..e7868ddc 100755 --- a/Libraries/GUI.lua +++ b/Libraries/GUI.lua @@ -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 function handleContainer(currentContainer, boundsX1, boundsY1, boundsX2, boundsY2) + 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 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, ...) + local focused = workspace.focusedObject == input + if e1 == "touch" or e1 == "drag" then - input:setCursorPosition(input.textCutFrom + math.ceil(e3) - input.x - input.textOffset) + if input:isPointInside(math.ceil(e3), math.ceil(e4)) then + input:setCursorPosition(input.textCutFrom + math.ceil(e3) - input.x - input.textOffset) - if input.focused then - inputCursorBlink(workspace, input, true) + 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 diff --git a/Libraries/System.lua b/Libraries/System.lua index e9c81e02..7c579ada 100755 --- a/Libraries/System.lua +++ b/Libraries/System.lua @@ -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 -- Получаем путь залупы