diff --git a/Applications.cfg b/Applications.cfg index 8eeced98..be31618e 100644 --- a/Applications.cfg +++ b/Applications.cfg @@ -511,76 +511,12 @@ }, { path="/Modules/command_block/Main.lua", - url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/SmartHouse/Modules/command_block/Main.lua", - }, - -- - { - path="/Modules/redstone/Icon.pic", - url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/SmartHouse/Modules/redstone/Icon.pic", - }, - { - path="/Modules/redstone/Main.lua", - url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/SmartHouse/Modules/redstone/Main.lua", - }, - -- - { - path="/Modules/mfsu/Icon.pic", - url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/SmartHouse/Modules/mfsu/Icon.pic", - }, - { - path="/Modules/mfsu/Main.lua", - url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/SmartHouse/Modules/mfsu/Main.lua", - }, - -- - { - path="/Modules/screen/Icon.pic", - url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/SmartHouse/Modules/screen/Icon.pic", - }, - { - path="/Modules/screen/Main.lua", - url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/SmartHouse/Modules/screen/Main.lua", - }, - -- - { - path="/Modules/homePC/Server.pic", - url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/SmartHouse/Modules/homePC/Server.pic", - }, - { - path="/Modules/homePC/Icon.pic", - url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/SmartHouse/Modules/homePC/Icon.pic", - }, - { - path="/Modules/homePC/Main.lua", - url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/SmartHouse/Modules/homePC/Main.lua", - }, - -- - { - path="/Modules/motion_sensor/Icon.pic", - url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/SmartHouse/Modules/motion_sensor/Icon.pic", - }, - { - path="/Modules/motion_sensor/Main.lua", - url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/SmartHouse/Modules/motion_sensor/Main.lua", - }, - -- - { - path="/Modules/reactor/Icon.pic", - url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/SmartHouse/Modules/reactor/Icon.pic", - }, - { - path="/Modules/reactor/Main.lua", - url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/SmartHouse/Modules/reactor/Main.lua", - }, - }, - }, - { path="/MineOS/Applications/VK", url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/VK/VK.lua", about="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/VK/About/", type="Application", icon="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/VK/Icon.pic", createShortcut="desktop", - version=1.27, resources={ { path="/VKLogo.pic", @@ -588,24 +524,6 @@ }, }, }, - { - path="/MineOS/Applications/Control2", - url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Control2/Control2.lua", - type="Application", - icon="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Control2/Icon.pic", - createShortcut="desktop", - version=1.06, - resources={ - { - path="/LuaLogo.pic", - url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Control2/LuaLogo.pic", - }, - { - path="/Modules/00_LuaConsole.lua", - url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Control2/Modules/00_LuaConsole.lua", - }, - }, - }, { path="/MineOS/Applications/Weather", url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Weather/Weather.lua", @@ -818,12 +736,26 @@ version=1.05, resources={ { - path="/Gate.pic", - url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Stargate/Gate.pic", + path="/Ch1.pic", + url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Stargate/Ch1.pic", + path="/Ch2.pic", + url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Stargate/Ch2.pic", }, { - path="/GateCore.pic", - url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Stargate/GateCore.pic", + path="/OnOn.pic", + url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Stargate/OnOn.pic", + }, + { + path="/OnOff.pic", + url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Stargate/OnOff.pic", + }, + { + path="/OffOn.pic", + url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Stargate/OffOn.pic", + }, + { + path="/OffOff.pic", + url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Stargate/OffOff.pic", }, }, }, @@ -880,24 +812,6 @@ createShortcut="desktop", version=1.0, }, - { - path="/MineOS/Applications/MineSweeper", - url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/MineSweeper/MineSweeper.lua", - about="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/MineSweeper/About/", - type="Application", - icon="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/MineSweeper/Icon.pic", - createShortcut="desktop", - version=1.0, - }, - { - path="/MineOS/Applications/DanceFloor", - url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/DanceFloor/DanceFloor.lua", - about="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/DanceFloor/About/", - type="Application", - icon="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/DanceFloor/Icon.pic", - createShortcut="desktop", - version=1.0, - }, { path="/MineOS/Applications/QuantumCube", url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/QuantumCube/QuantumCube.lua", @@ -961,8 +875,11 @@ icon="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/AppMarket/Icon.pic", createShortcut="dock", forceDownload=true, - version=1.55, - resources={ + resources={ + { + path="/Update.pic", + url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/AppMarket/Update.pic", + }, { path="/Localization/Russian.lang", url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/AppMarket/Localization/Russian.lang", @@ -982,15 +899,6 @@ createShortcut="desktop", version=1.0, }, - { - path="/MineOS/Applications/Keyboard", - url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Keyboard/Keyboard.lua", - about="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Keyboard/About/", - type="Application", - icon="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Keyboard/Icon.pic", - createShortcut="desktop", - version=1.0, - }, { path="/MineOS/Applications/Camera", url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Camera/Camera.lua", @@ -1046,22 +954,6 @@ }, } }, - --Приложение Чат - { - path="/MineOS/Applications/Chat", - url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Chat/Chat.lua", - about="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Chat/About/", - type="Application", - icon="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Chat/Icon.pic", - createShortcut="desktop", - version=1.02, - resources = { - { - path="/Avatars/MyAvatar.pic", - url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/Chat/MyAvatar.pic", - } - }, - }, { path="/MineOS/Applications/TurretControl", url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications/TurretControl/TurretControl.lua", diff --git a/Applications/3DTest/3DTest.lua b/Applications/3DTest/3DTest.lua index bbe71275..3c8c9504 100644 --- a/Applications/3DTest/3DTest.lua +++ b/Applications/3DTest/3DTest.lua @@ -27,7 +27,7 @@ local meowEngine = require("MeowEngine/Main") buffer.start() meowEngine.intro(vector.newVector3(0, 0, 0), 20) -local mainWindow = GUI.fullScreenWindow() +local mainContainer = GUI.fullScreenContainer() local scene = meowEngine.newScene(0x1D1D1D) scene.renderMode = OCGL.renderModes.flatShading @@ -280,14 +280,14 @@ local function move(x, y, z) end local function moveLight(x, y, z) - scene.lights[mainWindow.toolbar.lightSelectComboBox.currentItem].position[1] = scene.lights[mainWindow.toolbar.lightSelectComboBox.currentItem].position[1] + x - scene.lights[mainWindow.toolbar.lightSelectComboBox.currentItem].position[2] = scene.lights[mainWindow.toolbar.lightSelectComboBox.currentItem].position[2] + y - scene.lights[mainWindow.toolbar.lightSelectComboBox.currentItem].position[3] = scene.lights[mainWindow.toolbar.lightSelectComboBox.currentItem].position[3] + z + scene.lights[mainContainer.toolbar.lightSelectComboBox.selectedItem].position[1] = scene.lights[mainContainer.toolbar.lightSelectComboBox.selectedItem].position[1] + x + scene.lights[mainContainer.toolbar.lightSelectComboBox.selectedItem].position[2] = scene.lights[mainContainer.toolbar.lightSelectComboBox.selectedItem].position[2] + y + scene.lights[mainContainer.toolbar.lightSelectComboBox.selectedItem].position[3] = scene.lights[mainContainer.toolbar.lightSelectComboBox.selectedItem].position[3] + z end local controls = { -- F1 - [59 ] = function() mainWindow.toolbar.isHidden = not mainWindow.toolbar.isHidden; mainWindow.infoTextBox.isHidden = not mainWindow.infoTextBox.isHidden end, + [59 ] = function() mainContainer.toolbar.hidden = not mainContainer.toolbar.hidden; mainContainer.infoTextBox.hidden = not mainContainer.infoTextBox.hidden end, -- Arrows [200] = function() scene.camera:rotate(-rotationAngle, 0, 0) end, [208] = function() scene.camera:rotate(rotationAngle, 0, 0) end, @@ -314,7 +314,7 @@ local controls = { -------------------------------------------------------- GUI -------------------------------------------------------- -local OCGLView = GUI.object(1, 1, mainWindow.width, mainWindow.height) +local OCGLView = GUI.object(1, 1, mainContainer.width, mainContainer.height) local function drawInvertedText(x, y, text) local index = buffer.getBufferIndexByCoordinates(x, y) @@ -332,157 +332,158 @@ local function drawCross(x, y) end OCGLView.draw = function(object) - mainWindow.oldClock = os.clock() + mainContainer.oldClock = os.clock() if world then renderWorld() end scene:render() - if mainWindow.toolbar.zBufferSwitch.state then + if mainContainer.toolbar.zBufferSwitch.state then renderer.visualizeDepthBuffer() end drawCross(renderer.viewport.xCenter, math.floor(renderer.viewport.yCenter / 2)) end -OCGLView.onTouch = function(e) - local targetVector = vector.newVector3(scene.camera.position[1], scene.camera.position[2], scene.camera.position[3] + 1000) - OCGL.rotateVectorRelativeToXAxis(targetVector, scene.camera.rotation[1]) - OCGL.rotateVectorRelativeToYAxis(targetVector, scene.camera.rotation[2]) - local objectIndex, triangleIndex, distance = meowEngine.sceneRaycast(scene, scene.camera.position, targetVector) +OCGLView.eventHandler = function(mainContainer, object, eventData) + if eventData[1] == "touch" then + local targetVector = vector.newVector3(scene.camera.position[1], scene.camera.position[2], scene.camera.position[3] + 1000) + OCGL.rotateVectorRelativeToXAxis(targetVector, scene.camera.rotation[1]) + OCGL.rotateVectorRelativeToYAxis(targetVector, scene.camera.rotation[2]) + local objectIndex, triangleIndex, distance = meowEngine.sceneRaycast(scene, scene.camera.position, targetVector) - if objectIndex then - local triangle = scene.objects[objectIndex].triangles[triangleIndex] - local xWorld = math.floor(((scene.objects[objectIndex].vertices[scene.objects[objectIndex].triangles[triangleIndex][1]][1] + scene.objects[objectIndex].vertices[scene.objects[objectIndex].triangles[triangleIndex][2]][1] + scene.objects[objectIndex].vertices[scene.objects[objectIndex].triangles[triangleIndex][3]][1]) / 3) / blockSize) + 1 - local yWorld = math.floor(((scene.objects[objectIndex].vertices[triangle[1]][2] + scene.objects[objectIndex].vertices[triangle[2]][2] + scene.objects[objectIndex].vertices[triangle[3]][2]) / 3) / blockSize) + 1 - local zWorld = math.floor(((scene.objects[objectIndex].vertices[triangle[1]][3] + scene.objects[objectIndex].vertices[triangle[2]][3] + scene.objects[objectIndex].vertices[triangle[3]][3]) / 3) / blockSize) + 1 + if objectIndex then + local triangle = scene.objects[objectIndex].triangles[triangleIndex] + local xWorld = math.floor(((scene.objects[objectIndex].vertices[scene.objects[objectIndex].triangles[triangleIndex][1]][1] + scene.objects[objectIndex].vertices[scene.objects[objectIndex].triangles[triangleIndex][2]][1] + scene.objects[objectIndex].vertices[scene.objects[objectIndex].triangles[triangleIndex][3]][1]) / 3) / blockSize) + 1 + local yWorld = math.floor(((scene.objects[objectIndex].vertices[triangle[1]][2] + scene.objects[objectIndex].vertices[triangle[2]][2] + scene.objects[objectIndex].vertices[triangle[3]][2]) / 3) / blockSize) + 1 + local zWorld = math.floor(((scene.objects[objectIndex].vertices[triangle[1]][3] + scene.objects[objectIndex].vertices[triangle[2]][3] + scene.objects[objectIndex].vertices[triangle[3]][3]) / 3) / blockSize) + 1 - local normalVector = vector.getSurfaceNormal( - scene.objects[objectIndex].vertices[triangle[1]], - scene.objects[objectIndex].vertices[triangle[2]], - scene.objects[objectIndex].vertices[triangle[3]] - ) + local normalVector = vector.getSurfaceNormal( + scene.objects[objectIndex].vertices[triangle[1]], + scene.objects[objectIndex].vertices[triangle[2]], + scene.objects[objectIndex].vertices[triangle[3]] + ) - if normalVector[1] > 0 and e[5] ~= 1 or normalVector[1] < 0 and e[5] == 1 then - xWorld = xWorld - 1 - elseif normalVector[2] > 0 and e[5] ~= 1 or normalVector[2] < 0 and e[5] == 1 then - yWorld = yWorld - 1 - elseif normalVector[3] > 0 and e[5] ~= 1 or normalVector[3] < 0 and e[5] == 1 then - zWorld = zWorld - 1 + if normalVector[1] > 0 and eventData[5] ~= 1 or normalVector[1] < 0 and eventData[5] == 1 then + xWorld = xWorld - 1 + elseif normalVector[2] > 0 and eventData[5] ~= 1 or normalVector[2] < 0 and eventData[5] == 1 then + yWorld = yWorld - 1 + elseif normalVector[3] > 0 and eventData[5] ~= 1 or normalVector[3] < 0 and eventData[5] == 1 then + zWorld = zWorld - 1 + end + + setBlock(xWorld, yWorld, zWorld, eventData[5] == 1 and mainContainer.toolbar.blockColorSelector.color or nil) end - - setBlock(xWorld, yWorld, zWorld, e[5] == 1 and mainWindow.toolbar.blockColorSelector.color or nil) end end -mainWindow:addChild(OCGLView) - -mainWindow.infoTextBox = mainWindow:addTextBox(2, 4, 45, mainWindow.height, nil, 0xEEEEEE, {}, 1, 0, 0) +mainContainer:addChild(OCGLView) +mainContainer.infoTextBox = mainContainer:addChild(GUI.textBox(2, 4, 45, mainContainer.height, nil, 0xEEEEEE, {}, 1, 0, 0)) local lines = { "Copyright © 2016-2017 - Developed by ECS Inc.", "Timofeef Igor (vk.com/id7799889), Trifonov Gleb (vk.com/id88323331), Verevkin Yakov (vk.com/id60991376), Bogushevich Victoria (vk.com/id171497518)", "All rights reserved", } -mainWindow:addTextBox(1, buffer.screen.height - #lines + 1, buffer.screen.width, #lines, nil, 0x3C3C3C, lines, 1):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) +mainContainer:addChild(GUI.textBox(1, mainContainer.height - #lines + 1, mainContainer.width, #lines, nil, 0x3C3C3C, lines, 1)):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) local elementY = 2 -mainWindow.toolbar = mainWindow:addContainer(mainWindow.width - 31, 1, 32, mainWindow.height) -local elementWidth = mainWindow.toolbar.width - 2 -mainWindow.toolbar:addPanel(1, 1, mainWindow.toolbar.width, mainWindow.toolbar.height, 0x0, 50) +mainContainer.toolbar = mainContainer:addChild(GUI.container(mainContainer.width - 31, 1, 32, mainContainer.height)) +local elementWidth = mainContainer.toolbar.width - 2 +mainContainer.toolbar:addChild(GUI.panel(1, 1, mainContainer.toolbar.width, mainContainer.toolbar.height, 0x0, 50)) -mainWindow.toolbar:addLabel(2, elementY, elementWidth, 1, 0xEEEEEE, "Render mode"):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); elementY = elementY + 2 -mainWindow.toolbar.renderModeComboBox = mainWindow.toolbar:addComboBox(2, elementY, elementWidth, 1, 0x2D2D2D, 0xAAAAAA, 0x555555, 0x888888); elementY = elementY + mainWindow.toolbar.renderModeComboBox.height + 1 -mainWindow.toolbar.renderModeComboBox:addItem("disabled") -mainWindow.toolbar.renderModeComboBox:addItem("constantShading") -mainWindow.toolbar.renderModeComboBox:addItem("flatShading") -mainWindow.toolbar.renderModeComboBox.currentItem = scene.renderMode -mainWindow.toolbar.renderModeComboBox.onItemSelected = function() - scene.renderMode = mainWindow.toolbar.renderModeComboBox.currentItem +mainContainer.toolbar:addChild(GUI.label(2, elementY, elementWidth, 1, 0xEEEEEE, "Render mode")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); elementY = elementY + 2 +mainContainer.toolbar.renderModeComboBox = mainContainer.toolbar:addChild(GUI.comboBox(2, elementY, elementWidth, 1, 0x2D2D2D, 0xAAAAAA, 0x555555, 0x888888)); elementY = elementY + mainContainer.toolbar.renderModeComboBox.height + 1 +mainContainer.toolbar.renderModeComboBox:addItem("disabled") +mainContainer.toolbar.renderModeComboBox:addItem("constantShading") +mainContainer.toolbar.renderModeComboBox:addItem("flatShading") +mainContainer.toolbar.renderModeComboBox.selectedItem = scene.renderMode +mainContainer.toolbar.renderModeComboBox.onItemSelected = function() + scene.renderMode = mainContainer.toolbar.renderModeComboBox.selectedItem end -mainWindow.toolbar.auxiliaryModeComboBox = mainWindow.toolbar:addComboBox(2, elementY, elementWidth, 1, 0x2D2D2D, 0xAAAAAA, 0x555555, 0x888888); elementY = elementY + mainWindow.toolbar.auxiliaryModeComboBox.height + 1 -mainWindow.toolbar.auxiliaryModeComboBox:addItem("disabled") -mainWindow.toolbar.auxiliaryModeComboBox:addItem("wireframe") -mainWindow.toolbar.auxiliaryModeComboBox:addItem("vertices") -mainWindow.toolbar.auxiliaryModeComboBox.currentItem = scene.auxiliaryMode -mainWindow.toolbar.auxiliaryModeComboBox.onItemSelected = function() - scene.auxiliaryMode = mainWindow.toolbar.auxiliaryModeComboBox.currentItem +mainContainer.toolbar.auxiliaryModeComboBox = mainContainer.toolbar:addChild(GUI.comboBox(2, elementY, elementWidth, 1, 0x2D2D2D, 0xAAAAAA, 0x555555, 0x888888)); elementY = elementY + mainContainer.toolbar.auxiliaryModeComboBox.height + 1 +mainContainer.toolbar.auxiliaryModeComboBox:addItem("disabled") +mainContainer.toolbar.auxiliaryModeComboBox:addItem("wireframe") +mainContainer.toolbar.auxiliaryModeComboBox:addItem("vertices") +mainContainer.toolbar.auxiliaryModeComboBox.selectedItem = scene.auxiliaryMode +mainContainer.toolbar.auxiliaryModeComboBox.onItemSelected = function() + scene.auxiliaryMode = mainContainer.toolbar.auxiliaryModeComboBox.selectedItem end -mainWindow.toolbar:addLabel(2, elementY, elementWidth, 1, 0xAAAAAA, "Perspective proj:") -mainWindow.toolbar.perspectiveSwitch = mainWindow.toolbar:addSwitch(mainWindow.toolbar.width - 8, elementY, 8, 0x66DB80, 0x2D2D2D, 0xEEEEEE, scene.camera.projectionEnabled); elementY = elementY + 2 -mainWindow.toolbar.perspectiveSwitch.onStateChanged = function(state) +mainContainer.toolbar:addChild(GUI.label(2, elementY, elementWidth, 1, 0xAAAAAA, "Perspective proj:")) +mainContainer.toolbar.perspectiveSwitch = mainContainer.toolbar:addChild(GUI.switch(mainContainer.toolbar.width - 8, elementY, 8, 0x66DB80, 0x2D2D2D, 0xEEEEEE, scene.camera.projectionEnabled)); elementY = elementY + 2 +mainContainer.toolbar.perspectiveSwitch.onStateChanged = function(state) scene.camera.projectionEnabled = state end -mainWindow.toolbar:addLabel(2, elementY, elementWidth, 1, 0xAAAAAA, "Z-buffer visualize:") -mainWindow.toolbar.zBufferSwitch = mainWindow.toolbar:addSwitch(mainWindow.toolbar.width - 8, elementY, 8, 0x66DB80, 0x2D2D2D, 0xEEEEEE, false); elementY = elementY + 2 +mainContainer.toolbar:addChild(GUI.label(2, elementY, elementWidth, 1, 0xAAAAAA, "Z-buffer visualize:")) +mainContainer.toolbar.zBufferSwitch = mainContainer.toolbar:addChild(GUI.switch(mainContainer.toolbar.width - 8, elementY, 8, 0x66DB80, 0x2D2D2D, 0xEEEEEE, false)); elementY = elementY + 2 local function calculateLightComboBox() - mainWindow.toolbar.lightSelectComboBox.items = {} + mainContainer.toolbar.lightSelectComboBox.items = {} for i = 1, #scene.lights do - mainWindow.toolbar.lightSelectComboBox:addItem(tostring(i)) + mainContainer.toolbar.lightSelectComboBox:addItem(tostring(i)) end - mainWindow.toolbar.lightSelectComboBox.currentItem = #mainWindow.toolbar.lightSelectComboBox.items - mainWindow.toolbar.lightIntensitySlider.value = scene.lights[mainWindow.toolbar.lightSelectComboBox.currentItem].intensity * 100 - mainWindow.toolbar.lightEmissionSlider.value = scene.lights[mainWindow.toolbar.lightSelectComboBox.currentItem].emissionDistance + mainContainer.toolbar.lightSelectComboBox.selectedItem = #mainContainer.toolbar.lightSelectComboBox.items + mainContainer.toolbar.lightIntensitySlider.value = scene.lights[mainContainer.toolbar.lightSelectComboBox.selectedItem].intensity * 100 + mainContainer.toolbar.lightEmissionSlider.value = scene.lights[mainContainer.toolbar.lightSelectComboBox.selectedItem].emissionDistance end -mainWindow.toolbar:addLabel(2, elementY, elementWidth, 1, 0xEEEEEE, "Light control"):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); elementY = elementY + 2 -mainWindow.toolbar.lightSelectComboBox = mainWindow.toolbar:addComboBox(2, elementY, elementWidth, 1, 0x2D2D2D, 0xAAAAAA, 0x555555, 0x888888); elementY = elementY + mainWindow.toolbar.lightSelectComboBox.height + 1 +mainContainer.toolbar:addChild(GUI.label(2, elementY, elementWidth, 1, 0xEEEEEE, "Light control")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); elementY = elementY + 2 +mainContainer.toolbar.lightSelectComboBox = mainContainer.toolbar:addChild(GUI.comboBox(2, elementY, elementWidth, 1, 0x2D2D2D, 0xAAAAAA, 0x555555, 0x888888)); elementY = elementY + mainContainer.toolbar.lightSelectComboBox.height + 1 -mainWindow.toolbar.addLightButton = mainWindow.toolbar:addButton(2, elementY, elementWidth, 1, 0x2D2D2D, 0xAAAAAA, 0x555555, 0xAAAAAA, "Add light"); elementY = elementY + 2 -mainWindow.toolbar.addLightButton.onTouch = function() - scene:addLight(meowEngine.newLight(vector.newVector3(0, 10, 0), mainWindow.toolbar.lightIntensitySlider.value / 100, mainWindow.toolbar.lightEmissionSlider.value)) +mainContainer.toolbar.addLightButton = mainContainer.toolbar:addChild(GUI.button(2, elementY, elementWidth, 1, 0x2D2D2D, 0xAAAAAA, 0x555555, 0xAAAAAA, "Add light")); elementY = elementY + 2 +mainContainer.toolbar.addLightButton.onTouch = function() + scene:addLight(meowEngine.newLight(vector.newVector3(0, 10, 0), mainContainer.toolbar.lightIntensitySlider.value / 100, mainContainer.toolbar.lightEmissionSlider.value)) calculateLightComboBox() end -mainWindow.toolbar.removeLightButton = mainWindow.toolbar:addButton(2, elementY, elementWidth, 1, 0x2D2D2D, 0xAAAAAA, 0x555555, 0xAAAAAA, "Remove light"); elementY = elementY + 2 -mainWindow.toolbar.removeLightButton.onTouch = function() +mainContainer.toolbar.removeLightButton = mainContainer.toolbar:addChild(GUI.button(2, elementY, elementWidth, 1, 0x2D2D2D, 0xAAAAAA, 0x555555, 0xAAAAAA, "Remove light")); elementY = elementY + 2 +mainContainer.toolbar.removeLightButton.onTouch = function() if #scene.lights > 1 then - table.remove(scene.lights, mainWindow.toolbar.lightSelectComboBox.currentItem) + table.remove(scene.lights, mainContainer.toolbar.lightSelectComboBox.selectedItem) calculateLightComboBox() end end -mainWindow.toolbar.lightIntensitySlider = mainWindow.toolbar:addHorizontalSlider(2, elementY, elementWidth, 0xCCCCCC, 0x2D2D2D, 0xEEEEEE, 0xAAAAAA, 0, 500, 100, false, "Intensity: ", ""); elementY = elementY + 3 -mainWindow.toolbar.lightIntensitySlider.onValueChanged = function(value) - scene.lights[mainWindow.toolbar.lightSelectComboBox.currentItem].intensity = value / 100 +mainContainer.toolbar.lightIntensitySlider = mainContainer.toolbar:addChild(GUI.slider(2, elementY, elementWidth, 0xCCCCCC, 0x2D2D2D, 0xEEEEEE, 0xAAAAAA, 0, 500, 100, false, "Intensity: ", "")); elementY = elementY + 3 +mainContainer.toolbar.lightIntensitySlider.onValueChanged = function() + scene.lights[mainContainer.toolbar.lightSelectComboBox.selectedItem].intensity = mainContainer.toolbar.lightIntensitySlider.value / 100 end -mainWindow.toolbar.lightEmissionSlider = mainWindow.toolbar:addHorizontalSlider(2, elementY, elementWidth, 0xCCCCCC, 0x2D2D2D, 0xEEEEEE, 0xAAAAAA, 0, scene.lights[mainWindow.toolbar.lightSelectComboBox.currentItem].emissionDistance, scene.lights[mainWindow.toolbar.lightSelectComboBox.currentItem].emissionDistance, false, "Distance: ", ""); elementY = elementY + 3 -mainWindow.toolbar.lightEmissionSlider.onValueChanged = function(value) - scene.lights[mainWindow.toolbar.lightSelectComboBox.currentItem].emissionDistance = value +mainContainer.toolbar.lightEmissionSlider = mainContainer.toolbar:addChild(GUI.slider(2, elementY, elementWidth, 0xCCCCCC, 0x2D2D2D, 0xEEEEEE, 0xAAAAAA, 0, scene.lights[mainContainer.toolbar.lightSelectComboBox.selectedItem].emissionDistance, scene.lights[mainContainer.toolbar.lightSelectComboBox.selectedItem].emissionDistance, false, "Distance: ", "")); elementY = elementY + 3 +mainContainer.toolbar.lightEmissionSlider.onValueChanged = function() + scene.lights[mainContainer.toolbar.lightSelectComboBox.selectedItem].emissionDistance = mainContainer.toolbar.lightEmissionSlider.value end calculateLightComboBox() -mainWindow.toolbar.blockColorSelector = mainWindow.toolbar:addColorSelector(2, elementY, elementWidth, 1, 0xEEEEEE, "Block color"); elementY = elementY + mainWindow.toolbar.blockColorSelector.height + 1 -mainWindow.toolbar.backgroundColorSelector = mainWindow.toolbar:addColorSelector(2, elementY, elementWidth, 1, scene.backgroundColor, "Background color"); elementY = elementY + mainWindow.toolbar.blockColorSelector.height + 1 -mainWindow.toolbar.backgroundColorSelector.onTouch = function() - scene.backgroundColor = mainWindow.toolbar.backgroundColorSelector.color +mainContainer.toolbar.blockColorSelector = mainContainer.toolbar:addChild(GUI.colorSelector(2, elementY, elementWidth, 1, 0xEEEEEE, "Block color")); elementY = elementY + mainContainer.toolbar.blockColorSelector.height + 1 +mainContainer.toolbar.backgroundColorSelector = mainContainer.toolbar:addChild(GUI.colorSelector(2, elementY, elementWidth, 1, scene.backgroundColor, "Background color")); elementY = elementY + mainContainer.toolbar.blockColorSelector.height + 1 +mainContainer.toolbar.backgroundColorSelector.onTouch = function() + scene.backgroundColor = mainContainer.toolbar.backgroundColorSelector.color end -mainWindow.toolbar:addLabel(2, elementY, elementWidth, 1, 0xEEEEEE, "RAM monitoring"):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); elementY = elementY + 2 -mainWindow.toolbar.RAMChart = mainWindow.toolbar:addChart(2, elementY, elementWidth, mainWindow.toolbar.height - elementY - 3, 0xEEEEEE, 0xAAAAAA, 0x555555, 0x66DB80, 0.35, 0.25, "s", "%", true, {}); elementY = elementY + mainWindow.toolbar.RAMChart.height + 1 -mainWindow.toolbar.RAMChart.roundValues = true --- mainWindow.toolbar.RAMChart.showXAxisValues = false -mainWindow.toolbar.RAMChart.counter = 1 --- mainWindow.toolbar.RAMProgressBar = mainWindow.toolbar:addProgressBar(2, elementY, elementWidth, 0x66DB80, 0x2D2D2D, 0xAAAAAA, 1, true, true, "", "%") +mainContainer.toolbar:addChild(GUI.label(2, elementY, elementWidth, 1, 0xEEEEEE, "RAM monitoring")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); elementY = elementY + 2 +mainContainer.toolbar.RAMChart = mainContainer.toolbar:addChild(GUI.chart(2, elementY, elementWidth, mainContainer.toolbar.height - elementY - 3, 0xEEEEEE, 0xAAAAAA, 0x555555, 0x66DB80, 0.35, 0.25, "s", "%", true, {})); elementY = elementY + mainContainer.toolbar.RAMChart.height + 1 +mainContainer.toolbar.RAMChart.roundValues = true +-- mainContainer.toolbar.RAMChart.showXAxisValues = false +mainContainer.toolbar.RAMChart.counter = 1 -mainWindow.toolbar:addButton(1, mainWindow.toolbar.height - 2, mainWindow.toolbar.width, 3, 0x2D2D2D, 0xEEEEEE, 0x444444, 0xEEEEEE, "Exit").onTouch = function() - mainWindow:close() -end -mainWindow.onDrawFinished = function() - -- clock sec - 1 frame - -- 1 sec - x frames - renderer.renderFPSCounter(2, 2, tostring(math.ceil(1 / (os.clock() - mainWindow.oldClock) / 10)), 0xFFFF00) +mainContainer.toolbar:addChild(GUI.button(1, mainContainer.toolbar.height - 2, mainContainer.toolbar.width, 3, 0x2D2D2D, 0xEEEEEE, 0x444444, 0xEEEEEE, "Exit")).onTouch = function() + mainContainer:stopEventHandling() end -mainWindow.onAnyEvent = function(e) - if not mainWindow.toolbar.isHidden then +local FPSCounter = GUI.object(2, 2, 8, 3) +FPSCounter.draw = function(FPSCounter) + renderer.renderFPSCounter(FPSCounter.x, FPSCounter.y, tostring(math.ceil(1 / (os.clock() - mainContainer.oldClock) / 10)), 0xFFFF00) +end +mainContainer:addChild(FPSCounter) + +mainContainer.eventHandler = function(mainContainer, object, eventData) + if not mainContainer.toolbar.hidden then local totalMemory = computer.totalMemory() - table.insert(mainWindow.toolbar.RAMChart.values, {mainWindow.toolbar.RAMChart.counter, math.ceil((totalMemory - computer.freeMemory()) / totalMemory * 100)}) - mainWindow.toolbar.RAMChart.counter = mainWindow.toolbar.RAMChart.counter + 1 - if #mainWindow.toolbar.RAMChart.values > 20 then table.remove(mainWindow.toolbar.RAMChart.values, 1) end + table.insert(mainContainer.toolbar.RAMChart.values, {mainContainer.toolbar.RAMChart.counter, math.ceil((totalMemory - computer.freeMemory()) / totalMemory * 100)}) + mainContainer.toolbar.RAMChart.counter = mainContainer.toolbar.RAMChart.counter + 1 + if #mainContainer.toolbar.RAMChart.values > 20 then table.remove(mainContainer.toolbar.RAMChart.values, 1) end - mainWindow.infoTextBox.lines = { + mainContainer.infoTextBox.lines = { " ", "SceneObjects: " .. #scene.objects, " ", @@ -509,13 +510,13 @@ mainWindow.onAnyEvent = function(e) "F1 - toggle GUI overlay", } - mainWindow.infoTextBox.height = #mainWindow.infoTextBox.lines + mainContainer.infoTextBox.height = #mainContainer.infoTextBox.lines end - if e[1] == "key_down" then - if controls[e[4]] then controls[e[4]]() end - elseif e[1] == "scroll" then - if e[5] == 1 then + if eventData[1] == "key_down" then + if controls[eventData[4]] then controls[eventData[4]]() end + elseif eventData[1] == "scroll" then + if eventData[5] == 1 then if scene.camera.FOV < math.rad(170) then scene.camera:setFOV(scene.camera.FOV + math.rad(5)) end @@ -526,13 +527,13 @@ mainWindow.onAnyEvent = function(e) end end - mainWindow:draw() + mainContainer:draw() buffer.draw() end -------------------------------------------------------- Ebat-kopat -------------------------------------------------------- -mainWindow:handleEvents(0) +mainContainer:startEventHandling(0) diff --git a/Applications/AppMarket/AppMarket.lua b/Applications/AppMarket/AppMarket.lua index ca9a14b2..0b176e5c 100755 --- a/Applications/AppMarket/AppMarket.lua +++ b/Applications/AppMarket/AppMarket.lua @@ -1,440 +1,244 @@ --- package.loaded.GUI = nil --- _G.GUI = nil - -local advancedLua = require("advancedLua") -local buffer = require("doubleBuffering") +require("advancedLua") local MineOSCore = require("MineOSCore") +local component = require("component") +local computer = require("computer") local image = require("image") +local buffer = require("doubleBuffering") local GUI = require("GUI") local fs = require("filesystem") -local component = require("component") local unicode = require("unicode") -local event = require("event") local web = require("web") ------------------------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------------------- -local obj = {} -local sizes = {} -local colors = { - main = 0xFFFFFF, - topBar = 0xDDDDDD, - topBarText = 0x555555, - topBarElement = 0xCCCCCC, - topBarElementText = 0x555555, - statusBar = 0xDDDDDD, - statusBarText = 0x888888, - appName = 0x262626, - version = 0x555555, - description = 0x888888, - downloadButton = 0xAAAAAA, - downloadButtonText = 0xFFFFFF, - downloading = 0x009240, - downloadingText = 0xFFFFFF, - downloaded = 0xCCCCCC, - downloadedText = 0xFFFFFF, -} +local applicationListURL = "https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications.cfg" +local applicationList +local localization = MineOSCore.getCurrentApplicationLocalization() +local resources = MineOSCore.getCurrentApplicationResourcesDirectory() +local updateImage = image.load(resources .. "Update.pic") +local temproraryIconPath = "/MineOS/System/AppMarket/TempIcon.pic" +local appsPerPage = 6 -local typeFilters = { - "Application", - "Library", - "Wallpaper", - "Script", -} +local mainContainer, window = MineOSCore.addWindow(GUI.tabbedWindow(nil, nil, 80, 32)) -local localization = table.fromFile("MineOS/Applications/AppMarket.app/Resources/Localization/" .. _G.OSSettings.language .. ".lang") -local appMarketConfigPath = "MineOS/System/AppMarket/" -local pathToApplications = "MineOS/System/OS/Applications.cfg" -local pathToNewApplications = appMarketConfigPath .. "NewApplications.cfg" -local updateImage = image.fromString([[20100000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF A40000 A40000 A40000 A40000 A40000 A40000 A40000 A40000 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF A40000 A40000 A40000 A40000 A40000 A40000 A40000 A40000 A40000 A40000 A40000 A40000 A40000 A40000 A40000 A40000 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 730000 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 430000 430000 430000 430000 430000 430000 430000 430000 430000 430000 430000 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 430000 430000 430000 430000 430000 430000 430000 430000 430000 430000 430000 0000FF 0000FF 0000FF 0000FF 430000 430000 430000 430000 430000 430000 430000 430000 430000 430000 430000 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 430000 430000 430000 430000 430000 430000 430000 430000 430000 430000 430000 0000FF 0000FF 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 130000 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 130000 130000 130000 130000 130000 130000 130000 130000 130000 0000FF 0000FF 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0000FF 0000FF 0000FF 0000FF 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0000FF 0000FF 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0D0000 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0C0000 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF ]]) -local topBarElements = {localization.applications, localization.libraries, localization.wallpapers, localization.other, localization.updates} -local oldApplications, newApplications, currentApps, changes = {}, {}, {}, {} +---------------------------------------------------------------------------------------------------------------- -local currentTopBarElement = 1 -local from, limit, fromY = 1, 8 +local function newApp(x, y, width, applicationListElement, hideDownloadButton) + local app = GUI.container(x, y, width, 4) + + app.icon = app:addChild(GUI.image(1, 1, MineOSCore.icons.script)) + if applicationListElement.icon then + web.downloadFile(applicationListElement.icon, temproraryIconPath) + app.icon.image = image.load(temproraryIconPath) + else + if applicationListElement.type == "Wallpaper" then + app.icon.image = MineOSCore.icons.image + elseif applicationListElement.type == "Library" then + app.icon.image = MineOSCore.icons.lua + end + end ------------------------------------------------------------------------------------------------------------------- + app.downloadButton = app:addChild(GUI.button(1, 1, 13, 1, 0x66DB80, 0xFFFFFF, 0x339240, 0xFFFFFF, localization.download)) + app.downloadButton.localPosition.x = app.width - app.downloadButton.width + 1 + app.downloadButton.onTouch = function() + app.downloadButton.disabled = true + app.downloadButton.colors.disabled.background, app.downloadButton.colors.disabled.text = 0xBBBBBB, 0xFFFFFF + app.downloadButton.text = localization.downloading + mainContainer:draw() + buffer.draw() -local function correctDouble(number) - return string.format("%.2f", number) + web.downloadMineOSApplication(applicationListElement) + + app.downloadButton.text = localization.downloaded + mainContainer:draw() + buffer.draw() + end + app.downloadButton.hidden = hideDownloadButton + + app.pathLabel = app:addChild(GUI.label(app.icon.width + 2, 1, width - app.icon.width - app.downloadButton.width - 3, 1, 0x0, fs.name(applicationListElement.path))) + app.versionLabel = app:addChild(GUI.label(app.icon.width + 2, 2, app.pathLabel.width, 1, 0x555555, localization.version .. applicationListElement.version)) + if applicationListElement.about then + local lines = string.wrap({web.request(applicationListElement.about .. MineOSCore.OSSettings.language .. ".txt")}, app.pathLabel.width) + app.aboutTextBox = app:addChild(GUI.textBox(app.icon.width + 2, 3, app.pathLabel.width, #lines, nil, 0x999999, lines, 1, 0, 0)) + app.aboutTextBox.eventHandler = nil + if #lines > 2 then + app.height = #lines + 2 + end + end + + return app end -local function status(text) - text = unicode.sub(text, 1, sizes.width - 2) - local y = sizes.y + sizes.height - 1 - buffer.square(sizes.x, y, sizes.width, 1, colors.statusBar, colors.statusBarText, " ") - buffer.text(sizes.x + 1, y, colors.statusBarText, text) +local function addUpdateImage() + window.contentContainer:deleteChildren() + local cyka = window.contentContainer:addChild(GUI.image(math.floor(window.contentContainer.width / 2 - image.getWidth(updateImage) / 2), math.floor(window.contentContainer.height / 2 - image.getHeight(updateImage) / 2) - 1, updateImage)) + return cyka.localPosition.y + cyka.height + 2 +end + +local function updateApplicationList() + local y = addUpdateImage() + window.contentContainer:addChild(GUI.label(1, y, window.contentContainer.width, 1, 0x888888, localization.checkingForUpdates)):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) + mainContainer:draw() + buffer.draw() + + applicationList = table.fromString(web.request(applicationListURL)) +end + + +local function displayApps(fromPage, typeFilter, nameFilter, updateCheck) + window.contentContainer:deleteChildren() + + local y = 2 + local finalApplicationList = {} + + if updateCheck then + local oldApplicationList = table.fromFile(MineOSCore.paths.applicationList) + + for j = 1, #applicationList do + local pathFound = false + + for i = 1, #oldApplicationList do + if oldApplicationList[i].path == applicationList[j].path then + if oldApplicationList[i].version < applicationList[j].version then + table.insert(finalApplicationList, applicationList[j]) + end + + pathFound = true + break + end + end + + if not pathFound then + table.insert(finalApplicationList, applicationList[j]) + end + end + + window.contentContainer:addChild(GUI.button(math.floor(window.contentContainer.width / 2 - 10), y, 20, 1, 0xBBBBBB, 0xFFFFFF, 0x999999, 0xFFFFFF, localization.updateAll)).onTouch = function() + y = addUpdateImage() + + local progressBarWidth = math.floor(window.contentContainer.width * 0.65) + local progressBar = window.contentContainer:addChild(GUI.progressBar(math.floor(window.contentContainer.width / 2 - progressBarWidth / 2), y, progressBarWidth, 0x33B6FF, 0xDDDDDD, 0x0, 0, true, false)) + local label = window.contentContainer:addChild(GUI.label(1, y + 1, window.contentContainer.width, 1, 0x888888, "")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) + + for i = 1, #finalApplicationList do + progressBar.value = math.floor(i / #finalApplicationList * 100) + label.text = localization.updating .. fs.name(finalApplicationList[i].path) + + -- web.downloadMineOSApplication(finalApplicationList[i]) + + mainContainer:draw() + buffer.draw() + end + + computer.shutdown(true) + end + + if #finalApplicationList == 0 then + window.contentContainer:addChild(GUI.label(1, 1, window.contentContainer.width, window.contentContainer.height, 0x888888, localization.youHaveNewestApps)):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.center) + mainContainer:draw() + buffer.draw() + return + end + else + window.contentCon4tainer.searchInputTextBox = window.contentContainer:addChild(GUI.inputTextBox(math.floor(window.contentContainer.width / 2 - 10), y, 20, 1, 0xEEEEEE, 0xAAAAAA, 0xEEEEEE, 0x3C3C3C, nil, localization.search, true)) + window.contentContainer.searchInputTextBox.onInputFinished = function() + if window.contentContainer.searchInputTextBox.text then + displayApps(1, typeFilter, window.contentContainer.searchInputTextBox.text) + end + end + + for i = 1, #applicationList do + if (not typeFilter or typeFilter == applicationList[i].type) and (not nameFilter or unicode.find(unicode.lower(fs.name(applicationList[i].path)), unicode.lower(nameFilter))) then + table.insert(finalApplicationList, applicationList[i]) + end + end + end + + y = y + 2 + + mainContainer:draw() + buffer.draw() + + local appOnPageCounter, fromAppCounter, fromApp = 1, 1, (fromPage - 1) * appsPerPage + 1 + for i = 1, #finalApplicationList do + if fromAppCounter >= fromApp then + y, appOnPageCounter = y + window.contentContainer:addChild(newApp(1, y, window.contentContainer.width, finalApplicationList[i])).height + 1, appOnPageCounter + 1 + + mainContainer:draw() + buffer.draw() + + if appOnPageCounter > appsPerPage then + break + end + end + + fromAppCounter = fromAppCounter + 1 + end + + -- Pages buttons CYKA + local buttonWidth, text = 7, localization.page .. fromPage + local textLength = unicode.len(text) + local x = math.floor(window.contentContainer.width / 2 - (buttonWidth * 2 + textLength + 4) / 2) + window.contentContainer:addChild(GUI.button(x, y, buttonWidth, 1, 0xBBBBBB, 0xFFFFFF, 0x999999, 0xFFFFFF, "<")).onTouch = function() + if fromPage > 1 then + displayApps(fromPage - 1, typeFilter, nameFilter) + end + end + x = x + buttonWidth + 2 + + window.contentContainer:addChild(GUI.label(x, y, textLength, 1, 0x3C3C3C, text)) + x = x + textLength + 2 + + window.contentContainer:addChild(GUI.button(x, y, buttonWidth, 1, 0xBBBBBB, 0xFFFFFF, 0x999999, 0xFFFFFF, ">")).onTouch = function() + displayApps(fromPage + 1, typeFilter, nameFilter) + end + + mainContainer:draw() buffer.draw() end -local function calculateSizes() - sizes.width, sizes.height = math.floor(buffer.screen.width * 0.6), math.floor(buffer.screen.height * 0.7) - sizes.x, sizes.y = math.floor(buffer.screen.width / 2 - sizes.width / 2), math.floor(buffer.screen.height / 2 - sizes.height / 2) - sizes.topBarHeight = 3 - obj.main = GUI.object(sizes.x, sizes.y + sizes.topBarHeight, sizes.width, sizes.height - sizes.topBarHeight) - sizes.downloadButtonWidth = 17 - sizes.descriptionTruncateSize = sizes.width - 6 - MineOSCore.iconWidth - sizes.downloadButtonWidth - sizes.searchFieldWidth = math.floor(sizes.width * 0.3) - obj.searchTextField = GUI.inputTextBox(math.floor(sizes.x + sizes.width / 2 - sizes.searchFieldWidth / 2), 1, sizes.searchFieldWidth, 1, 0xEEEEEE, 0x555555, 0xEEEEEE, 0x262626, "", localization.search, true) -end - -local function drawTopBar() - obj.topBarButtons = GUI.tabBar(sizes.x, sizes.y, sizes.width, sizes.topBarHeight, 2, colors.topBar, colors.topBarText, colors.topBarElement, colors.topBarElementText, table.unpack(topBarElements)) - obj.topBarButtons.selectedTab = currentTopBarElement - obj.topBarButtons:draw() - obj.windowActionButtons = GUI.windowActionButtons(sizes.x + 1, sizes.y):draw() -end - -local function getIcon(url) - local path = appMarketConfigPath .. "TempIcon.pic" - - local success, reason = web.downloadFile(url, path) - if not success then - error(reason) - end - - return image.load(path) -end - -local function getDescription(url) - local result, reason = web.request(url) - if not result then - error(reason) - end - - return result -end - -local function getApplication(i) - currentApps[i] = {} - currentApps[i].path = fs.name(newApplications[i].path) - - if newApplications[i].icon then - currentApps[i].icon = getIcon(newApplications[i].icon) - else - if newApplications[i].type == "Application" then - currentApps[i].icon = failureIcon - elseif newApplications[i].type == "Wallpaper" then - currentApps[i].icon = MineOSCore.icons.image - elseif newApplications[i].type == "Library" then - currentApps[i].icon = MineOSCore.icons.lua - else - currentApps[i].icon = MineOSCore.icons.script +window.contentContainer = window:addChild(GUI.container(3, 4, window.width - 4, window.height - 3)) +window.contentContainer.eventHandler = function(mainContainer, object, eventData) + if eventData[1] == "scroll" and (eventData[5] == -1 or window.contentContainer.children[1].localPosition.y <= 1) then + for i = 1, #window.contentContainer.children do + window.contentContainer.children[i].localPosition.y = window.contentContainer.children[i].localPosition.y + eventData[5] end - end - - if newApplications[i].about then - currentApps[i].description = getDescription(newApplications[i].about .. _G.OSSettings.language .. ".txt") - currentApps[i].description = string.wrap({currentApps[i].description}, sizes.descriptionTruncateSize ) - else - currentApps[i].description = {localization.descriptionNotAvailable} - end - - if newApplications[i].version then - currentApps[i].version = localization.version .. correctDouble(newApplications[i].version) - else - currentApps[i].version = localization.versionNotAvailable - end -end - -local function checkAppExists(name, type) - if type == "Application" then - name = name .. ".app" - end - return fs.exists(name) -end - -local function drawApplication(x, y, i, doNotDrawButton) - buffer.image(x, y, currentApps[i].icon) - buffer.text(x + 10, y, colors.appName, currentApps[i].path) - buffer.text(x + 10, y + 1, colors.version, currentApps[i].version) - local appExists = checkAppExists(newApplications[i].path, newApplications[i].type) - local text = appExists and localization.update or localization.download - - if not doNotDrawButton then - local xButton, yButton = sizes.x + sizes.width - sizes.downloadButtonWidth - 2, y + 1 - if currentApps[i].buttonObject then - currentApps[i].buttonObject.x, currentApps[i].buttonObject.y = xButton, yButton - currentApps[i].buttonObject:draw() - else - currentApps[i].buttonObject = GUI.button(xButton, yButton, sizes.downloadButtonWidth, 1, colors.downloadButton, colors.downloadButtonText, 0x555555, 0xFFFFFF, text):draw() - end - end - - for j = 1, #currentApps[i].description do - buffer.text(x + 10, y + j + 1, colors.description, currentApps[i].description[j]) - end - y = y + (#currentApps[i].description > 2 and #currentApps[i].description - 2 or 0) - y = y + 5 - - return x, y -end - -local function drawPageSwitchButtons(y) - local text = localization.applicationsFrom .. from .. localization.applicationsTo .. from + limit - 1 - local textLength = unicode.len(text) - local buttonWidth = 5 - local width = buttonWidth * 2 + textLength + 2 - local x = math.floor(sizes.x + sizes.width / 2 - width / 2) - obj.prevPageButton = GUI.button(x, y, buttonWidth, 1, colors.downloadButton, colors.downloadButtonText, 0x262626, 0xFFFFFF, "<"):draw() - x = x + obj.prevPageButton.width + 1 - buffer.text(x, y, colors.version, text) - x = x + textLength + 1 - obj.nextPageButton = GUI.button(x, y, buttonWidth, 1, colors.downloadButton, colors.downloadButtonText, 0x262626, 0xFFFFFF, ">"):draw() -end - -local function clearMainZone() - buffer.square(sizes.x, obj.main.y, sizes.width, obj.main.height, 0xFFFFFF) -end - -local function drawMain(refreshData) - clearMainZone() - local x, y = sizes.x + 2, fromY - - buffer.setDrawLimit(sizes.x, obj.main.y, sizes.width, obj.main.height) - - obj.searchTextField.y, obj.searchTextField.isHidden = y, false - obj.searchTextField:draw() - y = y + 2 - - local matchCount = 1 - for i = 1, #newApplications do - if newApplications[i].type == typeFilters[currentTopBarElement] then - if obj.searchTextField.text == "" or (string.find(unicode.lower(fs.name(newApplications[i].path)), unicode.lower(obj.searchTextField.text))) then - if matchCount >= from and matchCount <= from + limit - 1 then - if refreshData and not currentApps[i] then - status(localization.downloadingInfoAboutApplication .. " \"" .. newApplications[i].path .. "\"") - getApplication(i) - end - x, y = drawApplication(x, y, i) - end - matchCount = matchCount + 1 - end - end - end - - if matchCount > limit then - drawPageSwitchButtons(y) - end - - buffer.resetDrawLimit() -end - -local function getNewApplications() - web.downloadFile("https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/Applications.cfg", pathToNewApplications) - newApplications = table.fromFile(pathToNewApplications) -end - -local function getChanges() - changes = {} - for j = 1, #newApplications do - local matchFound = false - for i = 1, #oldApplications do - if oldApplications[i].path == newApplications[j].path then - if oldApplications[i].version < newApplications[j].version then table.insert(changes, j) end - matchFound = true - break - end - end - if not matchFound then table.insert(changes, j) end - end -end - -local function updates() - clearMainZone() - - obj.searchTextField.isHidden = true - - if #changes > 0 then - buffer.setDrawLimit(sizes.x, obj.main.y, sizes.width, obj.main.height) - local x, y = sizes.x + 2, fromY - obj.updateAllButton = GUI.button(math.floor(sizes.x + sizes.width / 2 - sizes.downloadButtonWidth / 2), y, 20, 1, colors.downloadButton, colors.downloadButtonText, 0x555555, 0xFFFFFF, "Обновить все"):draw() - y = y + 2 - - for i = from, (from + limit) do - if not changes[i] then break end - if not currentApps[changes[i]] then - status(localization.downloadingInfoAboutApplication .. " \"" .. fs.name(newApplications[changes[i]].path) .. "\"") - getApplication(changes[i]) - end - x, y = drawApplication(x, y, changes[i], true) - end - - if #changes > limit then - drawPageSwitchButtons(y) - end - buffer.resetDrawLimit() - else - local text = localization.youHaveNewestApps - buffer.text(math.floor(sizes.x + sizes.width / 2 - unicode.len(text) / 2), math.floor(obj.main.y + obj.main.height / 2 - 1), colors.description, text) - end -end - -local function flush() - fromY = obj.main.y + 1 - from = 1 - currentApps = {} -end - -local function loadOldApplications() - oldApplications = table.fromFile(pathToApplications) -end - -local function saveOldApplications() - table.toFile(pathToApplications, oldApplications) -end - -local function drawAll(refreshIcons, force) - drawTopBar() - if currentTopBarElement == 5 then - updates() - else - drawMain(refreshIcons) - end - buffer.draw(force) -end - -local function updateImageWindow() - clearMainZone() - local x, y = math.floor(sizes.x + sizes.width / 2 - updateImage[1] / 2), math.floor(obj.main.y + obj.main.height / 2 - updateImage[2] / 2 - 2) - buffer.image(x, y, updateImage) - return y + updateImage[2] -end - -local function updateImageWindowWithText(text) - local y = updateImageWindow() + 2 - local x = math.floor(sizes.x + sizes.width / 2 - unicode.len(text) / 2) - buffer.text(x, y, colors.description, text) -end - -local function updateAll() - local y = updateImageWindow() - local barWidth = math.floor(sizes.width * 0.6) - local xBar = math.floor(sizes.x + sizes.width / 2 - barWidth / 2) - y = y + 2 - for i = 1, #changes do - local text = localization.updating .. " " .. fs.name(newApplications[changes[i]].path) - local xText = math.floor(sizes.x + sizes.width / 2 - unicode.len(text) / 2) - buffer.square(sizes.x, y + 1, sizes.width, 1, 0xFFFFFF) - buffer.text(xText, y + 1, colors.description, text) - GUI.progressBar(xBar, y, barWidth, 0x0092FF, 0xCCCCCC, 0x0, math.ceil(i / #changes * 100), true, false):draw() + mainContainer:draw() buffer.draw() - web.downloadMineOSApplication(newApplications[changes[i]]) - end - changes = {} - oldApplications = newApplications - saveOldApplications() - fs.remove(pathToNewApplications) - require("computer").shutdown(true) -end - ------------------------------------------------------------------------------------------------------------------- - --- buffer.start() --- buffer.clear(0xFF8888) - -local args = {...} -if args[1] == "updateCheck" then - currentTopBarElement = 5 -end - -fs.makeDirectory(appMarketConfigPath) -calculateSizes() -flush() -loadOldApplications() -drawTopBar() -GUI.windowShadow(sizes.x, sizes.y, sizes.width, sizes.height, 50) -updateImageWindowWithText(localization.downloadingApplicationsList) -buffer.draw() -getNewApplications() -getChanges() -drawAll(true, false) - -while true do - local e = {event.pull()} - if e[1] == "touch" then - - if obj.main:isClicked(e[3], e[4]) then - if obj.searchTextField:isClicked(e[3], e[4]) then - obj.searchTextField:input() - flush() - drawAll(true, false) - end - - if currentTopBarElement < 5 then - for appIndex, app in pairs(currentApps) do - if app.buttonObject:isClicked(e[3], e[4]) then - app.buttonObject:pressAndRelease(0.3) - if app.buttonObject.text == localization.update or app.buttonObject.text == localization.download then - app.buttonObject.text = localization.downloading - app.buttonObject.disabled = true - app.buttonObject.colors.disabled.button, app.buttonObject.colors.disabled.text = colors.downloading, colors.downloadingText - app.buttonObject:draw() - buffer.draw() - web.downloadMineOSApplication(newApplications[appIndex]) - app.buttonObject.text = localization.downloaded - app.buttonObject.colors.disabled.button, app.buttonObject.colors.disabled.text = colors.downloaded, colors.downloadedText - app.buttonObject:draw() - buffer.draw() - end - break - end - end - else - if obj.updateAllButton and obj.updateAllButton:isClicked(e[3], e[4]) then - obj.updateAllButton:pressAndRelease() - updateAll() - flush() - drawAll() - end - end - - if obj.nextPageButton then - if obj.nextPageButton:isClicked(e[3], e[4]) then - obj.nextPageButton:pressAndRelease() - fromY = obj.main.y + 1 - from = from + limit - currentApps = {} - drawAll(true, false) - elseif obj.prevPageButton:isClicked(e[3], e[4]) then - if from > limit then - fromY = obj.main.y + 1 - from = from - limit - currentApps = {} - drawAll(true, false) - end - end - end - end - - - if obj.windowActionButtons.close:isClicked(e[3], e[4]) then - obj.windowActionButtons.close:pressAndRelease() - return - end - - for key, button in pairs(obj.topBarButtons.tabs.children) do - if button:isClicked(e[3], e[4]) then - currentTopBarElement = key - flush() - drawAll(true, false) - break - end - end - elseif e[1] == "scroll" then - if e[5] == 1 then - if (fromY < obj.main.y) then - fromY = fromY + 2 - drawAll(false, false) - end - else - fromY = fromY - 2 - drawAll(false, false) - end end end +local oldResize = window.onResize +window.onResize = function(window, width, height) + window.contentContainer.width, window.contentContainer.height = width - 4, height - 3 + oldResize(window, width, height) + tabs[window.tabBar.selectedItem].onTouch() +end + +local tabs = { + window.tabBar:addItem(localization.applications), + window.tabBar:addItem(localization.libraries), + window.tabBar:addItem(localization.wallpapers), + window.tabBar:addItem(localization.other), + window.tabBar:addItem(localization.updates) +} + +tabs[1].onTouch = function() displayApps(1, "Application") end +tabs[2].onTouch = function() displayApps(1, "Library") end +tabs[3].onTouch = function() displayApps(1, "Wallpaper") end +tabs[4].onTouch = function() displayApps(1, "Script") end +tabs[5].onTouch = function() displayApps(1, nil, nil, true) end + +---------------------------------------------------------------------------------------------------------------- + +updateApplicationList() + +if ({...})[1] == "updates" then + window.tabBar.selectedItem = 5 +end + +tabs[window.tabBar.selectedItem].onTouch() diff --git a/Applications/AppMarket/Localization/English.lang b/Applications/AppMarket/Localization/English.lang index bb5a126c..f667b67f 100644 --- a/Applications/AppMarket/Localization/English.lang +++ b/Applications/AppMarket/Localization/English.lang @@ -4,20 +4,14 @@ wallpapers = "Wallpapers", other = "Other", updates = "Updates", - downloadingApplicationsList = "Downloading applications list", + checkingForUpdates = "Checking for updates", version = "Version: ", - descriptionNotAvailable = "No description", - versionNotAvailable = "No version", - update = "Update", + updateAll = "Update all", download = "Install", downloading = "Installing", downloaded = "Installed", search = "Search", - errorWhileLoadingIcon = "Error while downloading icon", - errorWhileLoadingDescription = "Error while downloading description", - applicationsFrom = "Application from ", - applicationsTo = " to ", + page = "Page ", youHaveNewestApps = "You have no updates.", - downloadingInfoAboutApplication = "Downloading information about application", - updating = "Installing", + updating = "Installing ", } \ No newline at end of file diff --git a/Applications/AppMarket/Localization/Russian.lang b/Applications/AppMarket/Localization/Russian.lang index 4d155b62..ab152772 100644 --- a/Applications/AppMarket/Localization/Russian.lang +++ b/Applications/AppMarket/Localization/Russian.lang @@ -4,20 +4,14 @@ wallpapers = "Обои", other = "Другое", updates = "Обновления", - downloadingApplicationsList = "Загрузка списка приложений", + checkingForUpdates = "Проверка наличия обновлений", version = "Версия: ", - descriptionNotAvailable = "Описание отсутствует", - versionNotAvailable = "Версия не указана", - update = "Обновить", + updateAll = "Обновить все", download = "Загрузить", downloading = "Загрузка", downloaded = "Установлено", search = "Поиск", - errorWhileLoadingIcon = "Ошибка при загрузке иконки приложения", - errorWhileLoadingDescription = "Ошибка при загрузке описания приложения", - applicationsFrom = "Приложения с ", - applicationsTo = " по ", + page = "Страница ", youHaveNewestApps = "У вас самое новое ПО", - downloadingInfoAboutApplication = "Загрузка информации о приложении", - updating = "Обновление", + updating = "Обновление ", } \ No newline at end of file diff --git a/Applications/AppMarket/Update.pic b/Applications/AppMarket/Update.pic new file mode 100644 index 00000000..a0bc87cd Binary files /dev/null and b/Applications/AppMarket/Update.pic differ diff --git a/Applications/FlappyBird/FlappyBird.lua b/Applications/FlappyBird/FlappyBird.lua index 30add6a9..2a5727d9 100644 --- a/Applications/FlappyBird/FlappyBird.lua +++ b/Applications/FlappyBird/FlappyBird.lua @@ -36,15 +36,15 @@ local colors = { local columns = {} -local pathToHighScores = "MineOS/System/FlappyBird/Scores.txt" -local pathToFlappyImage = "MineOS/Applications/FlappyBird.app/Resources/Flappy.pic" +local pathToHighScores = "/MineOS/System/FlappyBird/Scores.txt" +local pathToFlappyImage = "/MineOS/Applications/FlappyBird.app/Resources/Flappy.pic" local bird = image.load(pathToFlappyImage) -local xBird, yBird = 8, math.floor(buffer.screen.height / 2 - 3) +local xBird, yBird = 8, math.floor(buffer.height / 2 - 3) local birdIsAlive = true local scores = {} local currentScore, currentUser = 0, 0 -local xScore, yScore = math.floor(buffer.screen.width / 2 - 6), math.floor(buffer.screen.height * 0.16) +local xScore, yScore = math.floor(buffer.width / 2 - 6), math.floor(buffer.height * 0.16) local function drawColumn(x, upperCornerStartPosition) local y = 1 @@ -54,7 +54,7 @@ local function drawColumn(x, upperCornerStartPosition) y = upperCornerStartPosition + config.columnFreeSpace buffer.square(x, y, config.columnPipeWidth, config.columnPipeHeight, colors.columnAlternative) y = y + config.columnPipeHeight - buffer.square(x + 1, y, config.columnWidth, buffer.screen.height - y + 1, colors.columnMain) + buffer.square(x + 1, y, config.columnWidth, buffer.height - y + 1, colors.columnMain) end local function dieBirdDie() @@ -65,8 +65,8 @@ local function dieBirdDie() end local function generateColumn() - local yFreeZone = math.random(config.columnPipeHeight + 2, buffer.screen.height - config.columnPipeHeight - config.columnFreeSpace) - table.insert(columns, {x = buffer.screen.width - 1, yFreeZone = yFreeZone}) + local yFreeZone = math.random(config.columnPipeHeight + 2, buffer.height - config.columnPipeHeight - config.columnFreeSpace) + table.insert(columns, {x = buffer.width - 1, yFreeZone = yFreeZone}) end local scoreCanBeAdded = true @@ -111,7 +111,7 @@ end local function drawBigCenterText(y, textColor, usePseudoShadow, text) local width = bigLetters.getTextSize(text) - local x = math.floor(buffer.screen.width / 2 - width / 2) + local x = math.floor(buffer.width / 2 - width / 2) if usePseudoShadow then buffer.square(x - 2, y - 1, width + 4, 7, colors.scoreTextBackground) end bigLetters.drawText(x, y, textColor, text) @@ -195,8 +195,8 @@ local function finalGUI() local heightOfBoard = 40 local function draw() - local y = math.floor(buffer.screen.height / 2 - 19) - local x = math.floor(buffer.screen.width / 2 - widthOfBoard / 2) + local y = math.floor(buffer.height / 2 - 19) + local x = math.floor(buffer.width / 2 - widthOfBoard / 2) drawAll() @@ -232,7 +232,7 @@ local function finalGUI() scoreCanBeAdded = true columns = {} bird = image.load(pathToFlappyImage) - yBird = math.floor(buffer.screen.height / 2 - 3) + yBird = math.floor(buffer.height / 2 - 3) drawAll() wait() return @@ -271,7 +271,7 @@ while true do end if not somethingHappend then - if yBird + image.getHeight(bird) - 1 < buffer.screen.height then + if yBird + image.getHeight(bird) - 1 < buffer.height then yBird = yBird + config.birdFlyDownSpeed else scores[currentUser] = math.max(scores[currentUser] or 0, currentScore) diff --git a/Applications/GeoScan2/GeoScan2.lua b/Applications/GeoScan2/GeoScan2.lua index 9c4fde5b..3b41c4a7 100644 --- a/Applications/GeoScan2/GeoScan2.lua +++ b/Applications/GeoScan2/GeoScan2.lua @@ -22,10 +22,10 @@ buffer.start() local resourcesDirectory = MineOSCore.getCurrentApplicationResourcesDirectory() local earthImage = image.load(resourcesDirectory .. "Earth.pic") -local onScreenDataXOffset, onScreenDataYOffset = math.floor(buffer.screen.width / 2), buffer.screen.height +local onScreenDataXOffset, onScreenDataYOffset = math.floor(buffer.width / 2), buffer.height local onProjectorDataYOffset = 0 local scanResult = {horizontalRange = 0, verticalRange = 0} -local window = GUI.fullScreenWindow() +local mainContainer = GUI.fullScreenContainer() -------------------------------------------------------------------------------------------------------------------- @@ -69,7 +69,7 @@ end local function progressReport(value, text) local width = 40 - local x, y = math.floor(buffer.screen.width / 2 - width / 2), math.floor(buffer.screen.height / 2) + local x, y = math.floor(buffer.width / 2 - width / 2), math.floor(buffer.height / 2) GUI.progressBar(x, y, width, 0x00B6FF, 0xFFFFFF, 0xEEEEEE, value, true, true, text, "%"):draw() buffer.draw() end @@ -81,8 +81,8 @@ local function updateData(onScreen, onProjector, onGlasses) if onProjector then component.hologram.clear() end if onGlasses and glassesAvailable then component.glasses.removeAll() end - local min, max = tonumber(window.minimumHardnessTextBox.text), tonumber(window.maximumHardnessTextBox.text) - local horizontalRange, verticalRange = math.floor(window.horizontalScanRangeSlider.value), math.floor(window.verticalScanRangeSlider.value) + local min, max = tonumber(mainContainer.minimumHardnessTextBox.text), tonumber(mainContainer.maximumHardnessTextBox.text) + local horizontalRange, verticalRange = math.floor(mainContainer.horizontalScanRangeSlider.value), math.floor(mainContainer.verticalScanRangeSlider.value) for x = -horizontalRange, horizontalRange do for z = -horizontalRange, horizontalRange do @@ -91,11 +91,11 @@ local function updateData(onScreen, onProjector, onGlasses) if onScreen then buffer.semiPixelSet(onScreenDataXOffset + x, onScreenDataYOffset + 32 - y, 0x454545) end - if onProjector and window.projectorUpdateSwitch.state then - component.hologram.set(horizontalRange + x, math.floor(window.projectorYOffsetSlider.value) + y - 32, horizontalRange + z, 1) + if onProjector and mainContainer.projectorUpdateSwitch.state then + component.hologram.set(horizontalRange + x, math.floor(mainContainer.projectorYOffsetSlider.value) + y - 32, horizontalRange + z, 1) end - if onGlasses and window.glassesUpdateSwitch.state and glassesAvailable then - glassesCreateCube(x, y - 32, z, window.glassesOreColorButton.colors.default.background, "Hardness: " .. string.format("%.2f", scanResult[x][z][y])) + if onGlasses and mainContainer.glassesUpdateSwitch.state and glassesAvailable then + glassesCreateCube(x, y - 32, z, mainContainer.glassesOreColorButton.colors.default.background, "Hardness: " .. string.format("%.2f", scanResult[x][z][y])) os.sleep(0) end end @@ -104,91 +104,93 @@ local function updateData(onScreen, onProjector, onGlasses) end end -window.onDrawStarted = function() +local oldDraw = mainContainer.draw +mainContainer.draw = function() updateData(true, false, false) + oldDraw(mainContainer) end local panelWidth = 30 -local panelX = buffer.screen.width - panelWidth + 1 +local panelX = buffer.width - panelWidth + 1 local buttonX, objectY = panelX + 2, 2 local buttonWidth = panelWidth - 4 -window:addPanel(panelX, 1, panelWidth, buffer.screen.height, 0x444444) +mainContainer:addChild(GUI.panel(panelX, 1, panelWidth, buffer.height, 0x444444)) -window.planetImage = window:addImage(buttonX, objectY, earthImage) -objectY = objectY + window.planetImage.image[2] + 1 +mainContainer.planetImage = mainContainer:addChild(GUI.image(buttonX, objectY, earthImage)) +objectY = objectY + mainContainer.planetImage.image[2] + 1 -window:addLabel(buttonX, objectY, buttonWidth, 1, 0xFFFFFF, "GeoScan v2.0"):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) +mainContainer:addChild(GUI.label(buttonX, objectY, buttonWidth, 1, 0xFFFFFF, "GeoScan v2.0")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) objectY = objectY + 2 -window.horizontalScanRangeSlider = window:addHorizontalSlider(buttonX, objectY, buttonWidth, 0xFFDB80, 0x000000, 0xFFDB40, 0xBBBBBB, 4, 24, 16, false, "Horizontal scan range: ") -window.horizontalScanRangeSlider.roundValues = true +mainContainer.horizontalScanRangeSlider = mainContainer:addChild(GUI.slider(buttonX, objectY, buttonWidth, 0xFFDB80, 0x000000, 0xFFDB40, 0xBBBBBB, 4, 24, 16, false, "Horizontal scan range: ")) +mainContainer.horizontalScanRangeSlider.roundValues = true objectY = objectY + 3 -window.verticalScanRangeSlider = window:addHorizontalSlider(buttonX, objectY, buttonWidth, 0xFFDB80, 0x000000, 0xFFDB40, 0xBBBBBB, 4, 32, 16, false, "Vertical show range: ") -window.verticalScanRangeSlider.roundValues = true +mainContainer.verticalScanRangeSlider = mainContainer:addChild(GUI.slider(buttonX, objectY, buttonWidth, 0xFFDB80, 0x000000, 0xFFDB40, 0xBBBBBB, 4, 32, 16, false, "Vertical show range: ")) +mainContainer.verticalScanRangeSlider.roundValues = true objectY = objectY + 4 -window:addLabel(buttonX, objectY, buttonWidth, 1, 0xFFFFFF, "Rendering properties"):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) +mainContainer:addChild(GUI.label(buttonX, objectY, buttonWidth, 1, 0xFFFFFF, "Rendering properties")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) objectY = objectY + 2 -window.minimumHardnessTextBox = window:addInputTextBox(buttonX, objectY, 12, 3, 0x262626, 0xBBBBBB, 0x262626, 0xFFFFFF, tostring(2.7), nil, true) -window.minimumHardnessTextBox.validator = function(text) if tonumber(text) then return true end end -window.maximumHardnessTextBox = window:addInputTextBox(buttonX + 14, objectY, 12, 3, 0x262626, 0xBBBBBB, 0x262626, 0xFFFFFF, tostring(10), nil, true) -window.maximumHardnessTextBox.validator = function(text) if tonumber(text) then return true end end +mainContainer.minimumHardnessTextBox = mainContainer:addChild(GUI.inputTextBox(buttonX, objectY, 12, 3, 0x262626, 0xBBBBBB, 0x262626, 0xFFFFFF, tostring(2.7), nil, true)) +mainContainer.minimumHardnessTextBox.validator = function(text) if tonumber(text) then return true end end +mainContainer.maximumHardnessTextBox = mainContainer:addChild(GUI.inputTextBox(buttonX + 14, objectY, 12, 3, 0x262626, 0xBBBBBB, 0x262626, 0xFFFFFF, tostring(10), nil, true)) +mainContainer.maximumHardnessTextBox.validator = function(text) if tonumber(text) then return true end end objectY = objectY + 3 -window:addLabel(buttonX, objectY, buttonWidth, 1, 0xBBBBBB, "Hardness min Hardness max"):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) +mainContainer:addChild(GUI.label(buttonX, objectY, buttonWidth, 1, 0xBBBBBB, "Hardness min Hardness max")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) objectY = objectY + 2 -window.projectorScaleSlider = window:addHorizontalSlider(buttonX, objectY, buttonWidth, 0xFFDB80, 0x000000, 0xFFDB40, 0xBBBBBB, 0.33, 3, component.hologram.getScale(), false, "Projection scale: ") -window.projectorScaleSlider.onValueChanged = function() - component.hologram.setScale(window.projectorScaleSlider.value) +mainContainer.projectorScaleSlider = mainContainer:addChild(GUI.slider(buttonX, objectY, buttonWidth, 0xFFDB80, 0x000000, 0xFFDB40, 0xBBBBBB, 0.33, 3, component.hologram.getScale(), false, "Projection scale: ")) +mainContainer.projectorScaleSlider.onValueChanged = function() + component.hologram.setScale(mainContainer.projectorScaleSlider.value) end objectY = objectY + 3 -window.projectorYOffsetSlider = window:addHorizontalSlider(buttonX, objectY, buttonWidth, 0xFFDB80, 0x000000, 0xFFDB40, 0xBBBBBB, 0, 64, 4, false, "Projection Y offset: ") -window.projectorYOffsetSlider.roundValues = true +mainContainer.projectorYOffsetSlider = mainContainer:addChild(GUI.slider(buttonX, objectY, buttonWidth, 0xFFDB80, 0x000000, 0xFFDB40, 0xBBBBBB, 0, 64, 4, false, "Projection Y offset: ")) +mainContainer.projectorYOffsetSlider.roundValues = true objectY = objectY + 3 local function setButtonColorFromPalette(button) local selectedColor = require("palette").show("auto", "auto", button.colors.default.background) if selectedColor then button.colors.default.background = selectedColor end - window:draw(); buffer.draw() + mainContainer:draw(); buffer.draw() end local function updateProjectorColors() - component.hologram.setPaletteColor(1, window.color1Button.colors.default.background) + component.hologram.setPaletteColor(1, mainContainer.color1Button.colors.default.background) end local color1, color2, color3 = component.hologram.getPaletteColor(1), component.hologram.getPaletteColor(2), component.hologram.getPaletteColor(3) -window.color1Button = window:addButton(buttonX, objectY, buttonWidth, 1, color1, 0xBBBBBB, 0xEEEEEE, 0x262626, "Projector color"); objectY = objectY + 1 -window.color1Button.onTouch = function() - setButtonColorFromPalette(window.color1Button) +mainContainer.color1Button = mainContainer:addChild(GUI.button(buttonX, objectY, buttonWidth, 1, color1, 0xBBBBBB, 0xEEEEEE, 0x262626, "Projector color")); objectY = objectY + 1 +mainContainer.color1Button.onTouch = function() + setButtonColorFromPalette(mainContainer.color1Button) updateProjectorColors() end -window.glassesOreColorButton = window:addButton(buttonX, objectY, buttonWidth, 1, 0x0044FF, 0xBBBBBB, 0xEEEEEE, 0x262626, "Glasses ore color") -window.glassesOreColorButton.onTouch = function() - setButtonColorFromPalette(window.glassesOreColorButton) +mainContainer.glassesOreColorButton = mainContainer:addChild(GUI.button(buttonX, objectY, buttonWidth, 1, 0x0044FF, 0xBBBBBB, 0xEEEEEE, 0x262626, "Glasses ore color")) +mainContainer.glassesOreColorButton.onTouch = function() + setButtonColorFromPalette(mainContainer.glassesOreColorButton) end objectY = objectY + 2 -window:addLabel(buttonX, objectY, buttonWidth, 1, 0xBBBBBB, "Projector update:") -window.projectorUpdateSwitch = window:addSwitch(buffer.screen.width - 8, objectY, 7, 0xFFDB40, 0xAAAAAA, 0xFFFFFF, true) +mainContainer:addChild(GUI.label(buttonX, objectY, buttonWidth, 1, 0xBBBBBB, "Projector update:")) +mainContainer.projectorUpdateSwitch = mainContainer:addChild(GUI.switch(buffer.width - 8, objectY, 7, 0xFFDB40, 0xAAAAAA, 0xFFFFFF, true)) objectY = objectY + 2 -window:addLabel(buttonX, objectY, buttonWidth, 1, 0xBBBBBB, "Glasses update:") -window.glassesUpdateSwitch = window:addSwitch(buffer.screen.width - 8, objectY, 7, 0xFFDB40, 0xAAAAAA, 0xFFFFFF, true) +mainContainer:addChild(GUI.label(buttonX, objectY, buttonWidth, 1, 0xBBBBBB, "Glasses update:")) +mainContainer.glassesUpdateSwitch = mainContainer:addChild(GUI.switch(buffer.width - 8, objectY, 7, 0xFFDB40, 0xAAAAAA, 0xFFFFFF, true)) objectY = objectY + 2 -window:addButton(buffer.screen.width, 1, 1, 1, nil, 0xEEEEEE, nil, 0xFF2222, "X").onTouch = function() - window:close() +mainContainer:addChild(GUI.button(buffer.width, 1, 1, 1, nil, 0xEEEEEE, nil, 0xFF2222, "X")).onTouch = function() + mainContainer:stopEventHandling() createDick(math.random(-48, 48), math.random(1, 32), math.random(-48, 48), 100, false) end -window:addButton(panelX, buffer.screen.height - 5, panelWidth, 3, 0x353535, 0xEEEEEE, 0xAAAAAA, 0x262626, "Update").onTouch = function() +mainContainer:addChild(GUI.button(panelX, buffer.height - 5, panelWidth, 3, 0x353535, 0xEEEEEE, 0xAAAAAA, 0x262626, "Update")).onTouch = function() updateData(false, true, true) end -window.scanButton = window:addButton(panelX, buffer.screen.height - 2, panelWidth, 3, 0x262626, 0xEEEEEE, 0xAAAAAA, 0x262626, "Scan") -window.scanButton.onTouch = function() +mainContainer.scanButton = mainContainer:addChild(GUI.button(panelX, buffer.height - 2, panelWidth, 3, 0x262626, 0xEEEEEE, 0xAAAAAA, 0x262626, "Scan")) +mainContainer.scanButton.onTouch = function() scanResult = {} - local horizontalRange, verticalRange = math.floor(window.horizontalScanRangeSlider.value), math.floor(window.verticalScanRangeSlider.value) + local horizontalRange, verticalRange = math.floor(mainContainer.horizontalScanRangeSlider.value), math.floor(mainContainer.verticalScanRangeSlider.value) local total, current = (horizontalRange * 2 + 1) ^ 2, 0 buffer.clear(0x0, 0x30) @@ -202,7 +204,7 @@ window.scanButton.onTouch = function() end end - window:draw() + mainContainer:draw() buffer.draw() updateData(false, true, true) end @@ -210,7 +212,7 @@ end -------------------------------------------------------------------------------------------------------------------- buffer.clear(0x0) -window:draw() +mainContainer:draw() buffer.draw() -window:handleEvents() +mainContainer:startEventHandling() diff --git a/Applications/Graph/Graph.lua b/Applications/Graph/Graph.lua index 6e37efe0..da482946 100755 --- a/Applications/Graph/Graph.lua +++ b/Applications/Graph/Graph.lua @@ -5,7 +5,7 @@ _G.unicode = require("unicode") _G.event = require("event") _G.ecs = require("ECSAPI") -local xGraph, yGraph = math.floor(buffer.screen.width / 2), buffer.screen.height +local xGraph, yGraph = math.floor(buffer.width / 2), buffer.height local yDependencyString = "math.sin(x) * 5" local graphScale = 4 local graphResizeSpeed = 0.4 @@ -34,7 +34,7 @@ end local function drawButtons() buttons = {} local buttonNames = {"Функция", "Масштаб", "Очистить точки", "Выход"} - local x, y = math.floor(buffer.screen.width / 2 - (#buttonNames * (buttonWidth + 2) - 2) / 2), buffer.screen.height - 4 + local x, y = math.floor(buffer.width / 2 - (#buttonNames * (buttonWidth + 2) - 2) / 2), buffer.height - 4 for i = 1, #buttonNames do buttons[buttonNames[i]] = { buffer.button(x, y, buttonWidth, 3, buttonColor, buttonTextColor, buttonNames[i]) } @@ -51,8 +51,8 @@ local function drawVerticalLine(x, y, y2, color) end local function drawAxis() - drawHorizontalLine(1, yGraph, buffer.screen.width, axisColor) - drawVerticalLine(xGraph, 1, buffer.screen.height * 2, axisColor) + drawHorizontalLine(1, yGraph, buffer.width, axisColor) + drawVerticalLine(xGraph, 1, buffer.height * 2, axisColor) end local function limit(n) diff --git a/Applications/HEX/HEX.lua b/Applications/HEX/HEX.lua index 91003909..dc631fe2 100644 --- a/Applications/HEX/HEX.lua +++ b/Applications/HEX/HEX.lua @@ -8,7 +8,7 @@ local ecs = require("ECSAPI") -------------------------------------------------------------------------------------------------------------------------------- -local xSize, ySize = buffer.screen.width, buffer.screen.height +local xSize, ySize = buffer.width, buffer.height local file = {} local config = { @@ -108,7 +108,7 @@ end local function printDebug(line, text) if debug then - ecs.square(1, line, buffer.screen.width, 1, 0x262626) + ecs.square(1, line, buffer.width, 1, 0x262626) ecs.colorText(2, line, 0xFFFFFF, text) end end diff --git a/Applications/HoloClock/HoloClock.lua b/Applications/HoloClock/HoloClock.lua index 67400689..25ded337 100755 --- a/Applications/HoloClock/HoloClock.lua +++ b/Applications/HoloClock/HoloClock.lua @@ -193,20 +193,20 @@ local function getDate() end local function flashback() - buffer.square(1, 1, buffer.screen.width, buffer.screen.height, 0x000000, 0x000000, " ", 50) + buffer.square(1, 1, buffer.width, buffer.height, 0x000000, 0x000000, " ", 50) end local function drawOnScreen() local width, height = 58, 7 - local x, y = math.floor(buffer.screen.width / 2 - width / 2), math.floor(buffer.screen.height / 2 - height / 2) + local x, y = math.floor(buffer.width / 2 - width / 2), math.floor(buffer.height / 2 - height / 2) drawText(x, y, "88:88", 0x000000) drawText(x, y, date, config.dateColor) y = y + 9 - GUI.label(1, y, buffer.screen.width, 1, config.dateColor, "Press R to randomize clock color, scroll to change projection scale,"):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top):draw(); y = y + 1 - GUI.label(1, y, buffer.screen.width, 1, config.dateColor, "or press Enter to save and quit"):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top):draw() - -- GUI.label(1, y, buffer.screen.width, 1, 0xFFFFFF, ""):draw() + GUI.label(1, y, buffer.width, 1, config.dateColor, "Press R to randomize clock color, scroll to change projection scale,"):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top):draw(); y = y + 1 + GUI.label(1, y, buffer.width, 1, config.dateColor, "or press Enter to save and quit"):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top):draw() + -- GUI.label(1, y, buffer.width, 1, 0xFFFFFF, ""):draw() buffer.draw() end diff --git a/Applications/MineCodeIDE/MineCodeIDE.lua b/Applications/MineCodeIDE/MineCodeIDE.lua index 316c462f..60c7a2b5 100755 --- a/Applications/MineCodeIDE/MineCodeIDE.lua +++ b/Applications/MineCodeIDE/MineCodeIDE.lua @@ -129,19 +129,18 @@ local clipboard local breakpointLines local lastErrorLine local lastClickUptime = computer.uptime() -local mainWindow = {} local autocompleteDatabase ------------------------------------------------------------------------------------------------------------------ local function convertTextPositionToScreenCoordinates(symbol, line) return - mainWindow.codeView.codeAreaPosition + symbol - mainWindow.codeView.fromSymbol + 1, - mainWindow.codeView.y + line - mainWindow.codeView.fromLine + mainContainer.codeView.codeAreaPosition + symbol - mainContainer.codeView.fromSymbol + 1, + mainContainer.codeView.y + line - mainContainer.codeView.fromLine end local function convertScreenCoordinatesToTextPosition(x, y) - return x - mainWindow.codeView.codeAreaPosition + mainWindow.codeView.fromSymbol - 1, y - mainWindow.codeView.y + mainWindow.codeView.fromLine + return x - mainContainer.codeView.codeAreaPosition + mainContainer.codeView.fromSymbol - 1, y - mainContainer.codeView.y + mainContainer.codeView.fromLine end ------------------------------------------------------------------------------------------------------------------ @@ -172,8 +171,8 @@ end local function updateAutocompleteDatabaseFromFile() if config.enableAutocompletion then autocompleteDatabase = {} - for line = 1, #mainWindow.codeView.lines do - updateAutocompleteDatabaseFromString(mainWindow.codeView.lines[line], true) + for line = 1, #mainContainer.codeView.lines do + updateAutocompleteDatabaseFromString(mainContainer.codeView.lines[line], true) end end end @@ -182,12 +181,12 @@ local function getCurrentWordStartingAndEnding(fromSymbol) local shittySymbolsRegexp, from, to = "[%s%c%p]" for i = fromSymbol, 1, -1 do - if unicode.sub(mainWindow.codeView.lines[cursor.position.line], i, i):match(shittySymbolsRegexp) then break end + if unicode.sub(mainContainer.codeView.lines[cursor.position.line], i, i):match(shittySymbolsRegexp) then break end from = i end - for i = fromSymbol, unicode.len(mainWindow.codeView.lines[cursor.position.line]) do - if unicode.sub(mainWindow.codeView.lines[cursor.position.line], i, i):match(shittySymbolsRegexp) then break end + for i = fromSymbol, unicode.len(mainContainer.codeView.lines[cursor.position.line]) do + if unicode.sub(mainContainer.codeView.lines[cursor.position.line], i, i):match(shittySymbolsRegexp) then break end to = i end @@ -215,25 +214,25 @@ local function getAutocompleteDatabaseMatches(stringToSearch) end local function hideAutocompleteWindow() - mainWindow.autocompleteWindow.isHidden = true + mainContainer.autocompleteWindow.hidden = true end local function showAutocompleteWindow() if config.enableAutocompletion then - mainWindow.autocompleteWindow.currentWordStarting, mainWindow.autocompleteWindow.currentWordEnding = getCurrentWordStartingAndEnding(cursor.position.symbol - 1) + mainContainer.autocompleteWindow.currentWordStarting, mainContainer.autocompleteWindow.currentWordEnding = getCurrentWordStartingAndEnding(cursor.position.symbol - 1) - if mainWindow.autocompleteWindow.currentWordStarting then - mainWindow.autocompleteWindow.matches = getAutocompleteDatabaseMatches( + if mainContainer.autocompleteWindow.currentWordStarting then + mainContainer.autocompleteWindow.matches = getAutocompleteDatabaseMatches( unicode.sub( - mainWindow.codeView.lines[cursor.position.line], - mainWindow.autocompleteWindow.currentWordStarting, - mainWindow.autocompleteWindow.currentWordEnding + mainContainer.codeView.lines[cursor.position.line], + mainContainer.autocompleteWindow.currentWordStarting, + mainContainer.autocompleteWindow.currentWordEnding ) ) - if #mainWindow.autocompleteWindow.matches > 0 then - mainWindow.autocompleteWindow.fromMatch, mainWindow.autocompleteWindow.currentMatch = 1, 1 - mainWindow.autocompleteWindow.isHidden = false + if #mainContainer.autocompleteWindow.matches > 0 then + mainContainer.autocompleteWindow.fromMatch, mainContainer.autocompleteWindow.currentMatch = 1, 1 + mainContainer.autocompleteWindow.hidden = false else hideAutocompleteWindow() end @@ -252,161 +251,161 @@ end ------------------------------------------------------------------------------------------------------------------ local function calculateSizes() - mainWindow.width, mainWindow.height = buffer.screen.width, buffer.screen.height - mainWindow.leftTreeView.width = math.floor(mainWindow.width * 0.165) + mainContainer.width, mainContainer.height = buffer.width, buffer.height + mainContainer.leftTreeView.width = math.floor(mainContainer.width * 0.165) - if mainWindow.leftTreeView.isHidden then - mainWindow.codeView.localPosition.x, mainWindow.codeView.width = 1, mainWindow.width - mainWindow.bottomToolBar.localPosition.x, mainWindow.bottomToolBar.width = mainWindow.codeView.localPosition.x, mainWindow.codeView.width + if mainContainer.leftTreeView.hidden then + mainContainer.codeView.localPosition.x, mainContainer.codeView.width = 1, mainContainer.width + mainContainer.bottomToolBar.localPosition.x, mainContainer.bottomToolBar.width = mainContainer.codeView.localPosition.x, mainContainer.codeView.width else - mainWindow.codeView.localPosition.x, mainWindow.codeView.width = mainWindow.leftTreeView.width + 1, mainWindow.width - mainWindow.leftTreeView.width - mainWindow.bottomToolBar.localPosition.x, mainWindow.bottomToolBar.width = mainWindow.codeView.localPosition.x, mainWindow.codeView.width + mainContainer.codeView.localPosition.x, mainContainer.codeView.width = mainContainer.leftTreeView.width + 1, mainContainer.width - mainContainer.leftTreeView.width + mainContainer.bottomToolBar.localPosition.x, mainContainer.bottomToolBar.width = mainContainer.codeView.localPosition.x, mainContainer.codeView.width end - if mainWindow.topToolBar.isHidden then - mainWindow.leftTreeView.localPosition.y, mainWindow.leftTreeView.height = 2, mainWindow.height - 1 - mainWindow.codeView.localPosition.y, mainWindow.codeView.height = 2, mainWindow.height - 1 - mainWindow.errorContainer.localPosition.y = 2 + if mainContainer.topToolBar.hidden then + mainContainer.leftTreeView.localPosition.y, mainContainer.leftTreeView.height = 2, mainContainer.height - 1 + mainContainer.codeView.localPosition.y, mainContainer.codeView.height = 2, mainContainer.height - 1 + mainContainer.errorContainer.localPosition.y = 2 else - mainWindow.leftTreeView.localPosition.y, mainWindow.leftTreeView.height = 5, mainWindow.height - 4 - mainWindow.codeView.localPosition.y, mainWindow.codeView.height = 5, mainWindow.height - 4 - mainWindow.errorContainer.localPosition.y = 5 + mainContainer.leftTreeView.localPosition.y, mainContainer.leftTreeView.height = 5, mainContainer.height - 4 + mainContainer.codeView.localPosition.y, mainContainer.codeView.height = 5, mainContainer.height - 4 + mainContainer.errorContainer.localPosition.y = 5 end - if mainWindow.bottomToolBar.isHidden then + if mainContainer.bottomToolBar.hidden then else - mainWindow.codeView.height = mainWindow.codeView.height - 3 + mainContainer.codeView.height = mainContainer.codeView.height - 3 end - mainWindow.settingsContainer.width, mainWindow.settingsContainer.height = mainWindow.width, mainWindow.height - mainWindow.settingsContainer.backgroundPanel.width, mainWindow.settingsContainer.backgroundPanel.height = mainWindow.settingsContainer.width, mainWindow.settingsContainer.height + mainContainer.settingsContainer.width, mainContainer.settingsContainer.height = mainContainer.width, mainContainer.height + mainContainer.settingsContainer.backgroundPanel.width, mainContainer.settingsContainer.backgroundPanel.height = mainContainer.settingsContainer.width, mainContainer.settingsContainer.height - mainWindow.bottomToolBar.localPosition.y = mainWindow.height - 2 - mainWindow.bottomToolBar.findButton.localPosition.x = mainWindow.bottomToolBar.width - mainWindow.bottomToolBar.findButton.width + 1 - mainWindow.bottomToolBar.inputTextBox.width = mainWindow.bottomToolBar.width - mainWindow.bottomToolBar.inputTextBox.localPosition.x - mainWindow.bottomToolBar.findButton.width + 1 + mainContainer.bottomToolBar.localPosition.y = mainContainer.height - 2 + mainContainer.bottomToolBar.findButton.localPosition.x = mainContainer.bottomToolBar.width - mainContainer.bottomToolBar.findButton.width + 1 + mainContainer.bottomToolBar.inputTextBox.width = mainContainer.bottomToolBar.width - mainContainer.bottomToolBar.inputTextBox.localPosition.x - mainContainer.bottomToolBar.findButton.width + 1 - mainWindow.topToolBar.width, mainWindow.topToolBar.backgroundPanel.width = mainWindow.width, mainWindow.width - mainWindow.titleTextBox.width = math.floor(mainWindow.topToolBar.width * 0.32) - mainWindow.titleTextBox.localPosition.x = math.floor(mainWindow.topToolBar.width / 2 - mainWindow.titleTextBox.width / 2) - mainWindow.runButton.localPosition.x = mainWindow.titleTextBox.localPosition.x - mainWindow.runButton.width - 2 - mainWindow.toggleSyntaxHighlightingButton.localPosition.x = mainWindow.runButton.localPosition.x - mainWindow.toggleSyntaxHighlightingButton.width - 2 - mainWindow.addBreakpointButton.localPosition.x = mainWindow.toggleSyntaxHighlightingButton.localPosition.x - mainWindow.addBreakpointButton.width - 2 - mainWindow.toggleLeftToolBarButton.localPosition.x = mainWindow.titleTextBox.localPosition.x + mainWindow.titleTextBox.width + 2 - mainWindow.toggleBottomToolBarButton.localPosition.x = mainWindow.toggleLeftToolBarButton.localPosition.x + mainWindow.toggleLeftToolBarButton.width + 2 - mainWindow.toggleTopToolBarButton.localPosition.x = mainWindow.toggleBottomToolBarButton.localPosition.x + mainWindow.toggleBottomToolBarButton.width + 2 + mainContainer.topToolBar.width, mainContainer.topToolBar.backgroundPanel.width = mainContainer.width, mainContainer.width + mainContainer.titleTextBox.width = math.floor(mainContainer.topToolBar.width * 0.32) + mainContainer.titleTextBox.localPosition.x = math.floor(mainContainer.topToolBar.width / 2 - mainContainer.titleTextBox.width / 2) + mainContainer.runButton.localPosition.x = mainContainer.titleTextBox.localPosition.x - mainContainer.runButton.width - 2 + mainContainer.toggleSyntaxHighlightingButton.localPosition.x = mainContainer.runButton.localPosition.x - mainContainer.toggleSyntaxHighlightingButton.width - 2 + mainContainer.addBreakpointButton.localPosition.x = mainContainer.toggleSyntaxHighlightingButton.localPosition.x - mainContainer.addBreakpointButton.width - 2 + mainContainer.toggleLeftToolBarButton.localPosition.x = mainContainer.titleTextBox.localPosition.x + mainContainer.titleTextBox.width + 2 + mainContainer.toggleBottomToolBarButton.localPosition.x = mainContainer.toggleLeftToolBarButton.localPosition.x + mainContainer.toggleLeftToolBarButton.width + 2 + mainContainer.toggleTopToolBarButton.localPosition.x = mainContainer.toggleBottomToolBarButton.localPosition.x + mainContainer.toggleBottomToolBarButton.width + 2 - mainWindow.RAMUsageProgressBar.localPosition.x = mainWindow.toggleTopToolBarButton.localPosition.x + mainWindow.toggleTopToolBarButton.width + 3 - mainWindow.RAMUsageProgressBar.width = mainWindow.topToolBar.width - mainWindow.RAMUsageProgressBar.localPosition.x - 3 + mainContainer.RAMUsageProgressBar.localPosition.x = mainContainer.toggleTopToolBarButton.localPosition.x + mainContainer.toggleTopToolBarButton.width + 3 + mainContainer.RAMUsageProgressBar.width = mainContainer.topToolBar.width - mainContainer.RAMUsageProgressBar.localPosition.x - 3 - mainWindow.errorContainer.localPosition.x, mainWindow.errorContainer.width = mainWindow.titleTextBox.localPosition.x, mainWindow.titleTextBox.width - mainWindow.errorContainer.backgroundPanel.width, mainWindow.errorContainer.errorTextBox.width = mainWindow.errorContainer.width, mainWindow.errorContainer.width - 4 + mainContainer.errorContainer.localPosition.x, mainContainer.errorContainer.width = mainContainer.titleTextBox.localPosition.x, mainContainer.titleTextBox.width + mainContainer.errorContainer.backgroundPanel.width, mainContainer.errorContainer.errorTextBox.width = mainContainer.errorContainer.width, mainContainer.errorContainer.width - 4 - mainWindow.topMenu.width = mainWindow.width + mainContainer.topMenu.width = mainContainer.width end local function updateTitle() - if not mainWindow.topToolBar.isHidden then - if mainWindow.errorContainer.isHidden then - mainWindow.titleTextBox.lines[1] = string.limit(localization.file .. ": " .. (mainWindow.leftTreeView.currentFile or localization.none), mainWindow.titleTextBox.width - 4) - mainWindow.titleTextBox.lines[2] = string.limit(localization.cursor .. cursor.position.line .. localization.line .. cursor.position.symbol .. localization.symbol, mainWindow.titleTextBox.width - 4) - if mainWindow.codeView.selections[1] then - local countOfSelectedLines = mainWindow.codeView.selections[1].to.line - mainWindow.codeView.selections[1].from.line + 1 + if not mainContainer.topToolBar.hidden then + if mainContainer.errorContainer.hidden then + mainContainer.titleTextBox.lines[1] = string.limit(localization.file .. ": " .. (mainContainer.leftTreeView.currentFile or localization.none), mainContainer.titleTextBox.width - 4) + mainContainer.titleTextBox.lines[2] = string.limit(localization.cursor .. cursor.position.line .. localization.line .. cursor.position.symbol .. localization.symbol, mainContainer.titleTextBox.width - 4) + if mainContainer.codeView.selections[1] then + local countOfSelectedLines = mainContainer.codeView.selections[1].to.line - mainContainer.codeView.selections[1].from.line + 1 local countOfSelectedSymbols - if mainWindow.codeView.selections[1].from.line == mainWindow.codeView.selections[1].to.line then - countOfSelectedSymbols = unicode.len(unicode.sub(mainWindow.codeView.lines[mainWindow.codeView.selections[1].from.line], mainWindow.codeView.selections[1].from.symbol, mainWindow.codeView.selections[1].to.symbol)) + if mainContainer.codeView.selections[1].from.line == mainContainer.codeView.selections[1].to.line then + countOfSelectedSymbols = unicode.len(unicode.sub(mainContainer.codeView.lines[mainContainer.codeView.selections[1].from.line], mainContainer.codeView.selections[1].from.symbol, mainContainer.codeView.selections[1].to.symbol)) else - countOfSelectedSymbols = unicode.len(unicode.sub(mainWindow.codeView.lines[mainWindow.codeView.selections[1].from.line], mainWindow.codeView.selections[1].from.symbol, -1)) - for line = mainWindow.codeView.selections[1].from.line + 1, mainWindow.codeView.selections[1].to.line - 1 do - countOfSelectedSymbols = countOfSelectedSymbols + unicode.len(mainWindow.codeView.lines[line]) + countOfSelectedSymbols = unicode.len(unicode.sub(mainContainer.codeView.lines[mainContainer.codeView.selections[1].from.line], mainContainer.codeView.selections[1].from.symbol, -1)) + for line = mainContainer.codeView.selections[1].from.line + 1, mainContainer.codeView.selections[1].to.line - 1 do + countOfSelectedSymbols = countOfSelectedSymbols + unicode.len(mainContainer.codeView.lines[line]) end - countOfSelectedSymbols = countOfSelectedSymbols + unicode.len(unicode.sub(mainWindow.codeView.lines[mainWindow.codeView.selections[1].to.line], 1, mainWindow.codeView.selections[1].to.symbol)) + countOfSelectedSymbols = countOfSelectedSymbols + unicode.len(unicode.sub(mainContainer.codeView.lines[mainContainer.codeView.selections[1].to.line], 1, mainContainer.codeView.selections[1].to.symbol)) end - mainWindow.titleTextBox.lines[3] = string.limit(localization.selection .. countOfSelectedLines .. localization.lines .. countOfSelectedSymbols .. localization.symbols, mainWindow.titleTextBox.width - 4) + mainContainer.titleTextBox.lines[3] = string.limit(localization.selection .. countOfSelectedLines .. localization.lines .. countOfSelectedSymbols .. localization.symbols, mainContainer.titleTextBox.width - 4) else - mainWindow.titleTextBox.lines[3] = string.limit(localization.selection .. localization.none, mainWindow.titleTextBox.width - 4) + mainContainer.titleTextBox.lines[3] = string.limit(localization.selection .. localization.none, mainContainer.titleTextBox.width - 4) end else - mainWindow.titleTextBox.lines[1], mainWindow.titleTextBox.lines[3] = " ", " " + mainContainer.titleTextBox.lines[1], mainContainer.titleTextBox.lines[3] = " ", " " if lastErrorLine then - mainWindow.titleTextBox.lines[2] = localization.runtimeError + mainContainer.titleTextBox.lines[2] = localization.runtimeError else - mainWindow.titleTextBox.lines[2] = localization.debugging .. (_G.MineCodeIDEDebugInfo and _G.MineCodeIDEDebugInfo.line or "N/A") + mainContainer.titleTextBox.lines[2] = localization.debugging .. (_G.MineCodeIDEDebugInfo and _G.MineCodeIDEDebugInfo.line or "N/A") end end end end local function gotoLine(line) - mainWindow.codeView.fromLine = math.ceil(line - mainWindow.codeView.height / 2) - if mainWindow.codeView.fromLine < 1 then - mainWindow.codeView.fromLine = 1 - elseif mainWindow.codeView.fromLine > #mainWindow.codeView.lines then - mainWindow.codeView.fromLine = #mainWindow.codeView.lines + mainContainer.codeView.fromLine = math.ceil(line - mainContainer.codeView.height / 2) + if mainContainer.codeView.fromLine < 1 then + mainContainer.codeView.fromLine = 1 + elseif mainContainer.codeView.fromLine > #mainContainer.codeView.lines then + mainContainer.codeView.fromLine = #mainContainer.codeView.lines end end local function updateHighlights() - mainWindow.codeView.highlights = {} + mainContainer.codeView.highlights = {} if breakpointLines then for i = 1, #breakpointLines do - mainWindow.codeView.highlights[breakpointLines[i]] = colors.highlights.onBreakpoint + mainContainer.codeView.highlights[breakpointLines[i]] = colors.highlights.onBreakpoint end end if lastErrorLine then - mainWindow.codeView.highlights[lastErrorLine] = colors.highlights.onError + mainContainer.codeView.highlights[lastErrorLine] = colors.highlights.onError end end local function calculateErrorContainerSizeAndBeep(hideBreakpointButtons, frequency, times) - mainWindow.errorContainer.errorTextBox.height = #mainWindow.errorContainer.errorTextBox.lines - mainWindow.errorContainer.height = 2 + mainWindow.errorContainer.errorTextBox.height - mainWindow.errorContainer.backgroundPanel.height = mainWindow.errorContainer.height + mainContainer.errorContainer.errorTextBox.height = #mainContainer.errorContainer.errorTextBox.lines + mainContainer.errorContainer.height = 2 + mainContainer.errorContainer.errorTextBox.height + mainContainer.errorContainer.backgroundPanel.height = mainContainer.errorContainer.height - mainWindow.errorContainer.breakpointExitButton.isHidden, mainWindow.errorContainer.breakpointContinueButton.isHidden = hideBreakpointButtons, hideBreakpointButtons + mainContainer.errorContainer.breakpointExitButton.hidden, mainContainer.errorContainer.breakpointContinueButton.hidden = hideBreakpointButtons, hideBreakpointButtons if not hideBreakpointButtons then - mainWindow.errorContainer.height = mainWindow.errorContainer.height + 1 - mainWindow.errorContainer.breakpointExitButton.localPosition.y, mainWindow.errorContainer.breakpointContinueButton.localPosition.y = mainWindow.errorContainer.height, mainWindow.errorContainer.height - mainWindow.errorContainer.breakpointExitButton.width = math.floor(mainWindow.errorContainer.width / 2) - mainWindow.errorContainer.breakpointContinueButton.localPosition.x, mainWindow.errorContainer.breakpointContinueButton.width = mainWindow.errorContainer.breakpointExitButton.width + 1, mainWindow.errorContainer.width - mainWindow.errorContainer.breakpointExitButton.width + mainContainer.errorContainer.height = mainContainer.errorContainer.height + 1 + mainContainer.errorContainer.breakpointExitButton.localPosition.y, mainContainer.errorContainer.breakpointContinueButton.localPosition.y = mainContainer.errorContainer.height, mainContainer.errorContainer.height + mainContainer.errorContainer.breakpointExitButton.width = math.floor(mainContainer.errorContainer.width / 2) + mainContainer.errorContainer.breakpointContinueButton.localPosition.x, mainContainer.errorContainer.breakpointContinueButton.width = mainContainer.errorContainer.breakpointExitButton.width + 1, mainContainer.errorContainer.width - mainContainer.errorContainer.breakpointExitButton.width end updateTitle() - mainWindow:draw() + mainContainer:draw() buffer.draw() for i = 1, times do component.computer.beep(frequency, 0.08) end end local function showBreakpointMessage(variables) - mainWindow.titleTextBox.colors.background, mainWindow.titleTextBox.colors.text = colors.title.onError.background, colors.title.onError.text - mainWindow.errorContainer.isHidden = false + mainContainer.titleTextBox.colors.background, mainContainer.titleTextBox.colors.text = colors.title.onError.background, colors.title.onError.text + mainContainer.errorContainer.hidden = false - mainWindow.errorContainer.errorTextBox:setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) - mainWindow.errorContainer.errorTextBox.lines = {} + mainContainer.errorContainer.errorTextBox:setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) + mainContainer.errorContainer.errorTextBox.lines = {} for variable, value in pairs(variables) do - table.insert(mainWindow.errorContainer.errorTextBox.lines, variable .. " = " .. value) + table.insert(mainContainer.errorContainer.errorTextBox.lines, variable .. " = " .. value) end - if #mainWindow.errorContainer.errorTextBox.lines > 0 then - table.insert(mainWindow.errorContainer.errorTextBox.lines, 1, " ") - table.insert(mainWindow.errorContainer.errorTextBox.lines, 1, {text = localization.variables, color = 0x0}) + if #mainContainer.errorContainer.errorTextBox.lines > 0 then + table.insert(mainContainer.errorContainer.errorTextBox.lines, 1, " ") + table.insert(mainContainer.errorContainer.errorTextBox.lines, 1, {text = localization.variables, color = 0x0}) else - table.insert(mainWindow.errorContainer.errorTextBox.lines, 1, {text = localization.variablesNotAvailable, color = 0x0}) + table.insert(mainContainer.errorContainer.errorTextBox.lines, 1, {text = localization.variablesNotAvailable, color = 0x0}) end calculateErrorContainerSizeAndBeep(false, 1800, 1) end local function showErrorContainer(errorCode) - mainWindow.titleTextBox.colors.background, mainWindow.titleTextBox.colors.text = colors.title.onError.background, colors.title.onError.text - mainWindow.errorContainer.isHidden = false + mainContainer.titleTextBox.colors.background, mainContainer.titleTextBox.colors.text = colors.title.onError.background, colors.title.onError.text + mainContainer.errorContainer.hidden = false - mainWindow.errorContainer.errorTextBox:setAlignment(GUI.alignment.horizontal.left, GUI.alignment.vertical.top) - mainWindow.errorContainer.errorTextBox.lines = string.wrap({errorCode}, mainWindow.errorContainer.errorTextBox.width) + mainContainer.errorContainer.errorTextBox:setAlignment(GUI.alignment.horizontal.left, GUI.alignment.vertical.top) + mainContainer.errorContainer.errorTextBox.lines = string.wrap({errorCode}, mainContainer.errorContainer.errorTextBox.width) -- Извлекаем ошибочную строку текущего скрипта lastErrorLine = tonumber(errorCode:match("%:(%d+)%: in main chunk")) @@ -430,21 +429,21 @@ local function showErrorContainer(errorCode) end local function hideErrorContainer() - mainWindow.titleTextBox.colors.background, mainWindow.titleTextBox.colors.text = colors.title.default.background, colors.title.default.text - mainWindow.errorContainer.isHidden = true + mainContainer.titleTextBox.colors.background, mainContainer.titleTextBox.colors.text = colors.title.default.background, colors.title.default.text + mainContainer.errorContainer.hidden = true lastErrorLine, scriptCoroutine = nil, nil updateHighlights() end local function hideSettingsContainer() - for childIndex = 2, #mainWindow.settingsContainer.children do mainWindow.settingsContainer.children[childIndex] = nil end - mainWindow.settingsContainer.isHidden = true - mainWindow:draw() + for childIndex = 2, #mainContainer.settingsContainer.children do mainContainer.settingsContainer.children[childIndex] = nil end + mainContainer.settingsContainer.hidden = true + mainContainer:draw() buffer.draw() end local function clearSelection() - mainWindow.codeView.selections[1] = nil + mainContainer.codeView.selections[1] = nil end local function clearBreakpoints() @@ -480,29 +479,29 @@ local function addBreakpoint() end local function fixFromLineByCursorPosition() - if mainWindow.codeView.fromLine > cursor.position.line then - mainWindow.codeView.fromLine = cursor.position.line - elseif mainWindow.codeView.fromLine + mainWindow.codeView.height - 2 < cursor.position.line then - mainWindow.codeView.fromLine = cursor.position.line - mainWindow.codeView.height + 2 + if mainContainer.codeView.fromLine > cursor.position.line then + mainContainer.codeView.fromLine = cursor.position.line + elseif mainContainer.codeView.fromLine + mainContainer.codeView.height - 2 < cursor.position.line then + mainContainer.codeView.fromLine = cursor.position.line - mainContainer.codeView.height + 2 end end local function fixFromSymbolByCursorPosition() - if mainWindow.codeView.fromSymbol > cursor.position.symbol then - mainWindow.codeView.fromSymbol = cursor.position.symbol - elseif mainWindow.codeView.fromSymbol + mainWindow.codeView.codeAreaWidth - 3 < cursor.position.symbol then - mainWindow.codeView.fromSymbol = cursor.position.symbol - mainWindow.codeView.codeAreaWidth + 3 + if mainContainer.codeView.fromSymbol > cursor.position.symbol then + mainContainer.codeView.fromSymbol = cursor.position.symbol + elseif mainContainer.codeView.fromSymbol + mainContainer.codeView.codeAreaWidth - 3 < cursor.position.symbol then + mainContainer.codeView.fromSymbol = cursor.position.symbol - mainContainer.codeView.codeAreaWidth + 3 end end local function fixCursorPosition(symbol, line) if line < 1 then line = 1 - elseif line > #mainWindow.codeView.lines then - line = #mainWindow.codeView.lines + elseif line > #mainContainer.codeView.lines then + line = #mainContainer.codeView.lines end - local lineLength = unicode.len(mainWindow.codeView.lines[line]) + local lineLength = unicode.len(mainContainer.codeView.lines[line]) if symbol < 1 or lineLength == 0 then symbol = 1 elseif symbol > lineLength then @@ -526,35 +525,35 @@ local function setCursorPositionAndClearSelection(symbol, line) end local function moveCursor(symbolOffset, lineOffset) - if mainWindow.autocompleteWindow.isHidden or lineOffset == 0 then - if mainWindow.codeView.selections[1] then + if mainContainer.autocompleteWindow.hidden or lineOffset == 0 then + if mainContainer.codeView.selections[1] then if symbolOffset < 0 or lineOffset < 0 then - setCursorPositionAndClearSelection(mainWindow.codeView.selections[1].from.symbol, mainWindow.codeView.selections[1].from.line) + setCursorPositionAndClearSelection(mainContainer.codeView.selections[1].from.symbol, mainContainer.codeView.selections[1].from.line) else - setCursorPositionAndClearSelection(mainWindow.codeView.selections[1].to.symbol, mainWindow.codeView.selections[1].to.line) + setCursorPositionAndClearSelection(mainContainer.codeView.selections[1].to.symbol, mainContainer.codeView.selections[1].to.line) end else local newSymbol, newLine = cursor.position.symbol + symbolOffset, cursor.position.line + lineOffset if symbolOffset < 0 and newSymbol < 1 then newLine, newSymbol = newLine - 1, math.huge - elseif symbolOffset > 0 and newSymbol > unicode.len(mainWindow.codeView.lines[newLine] or "") + 1 then + elseif symbolOffset > 0 and newSymbol > unicode.len(mainContainer.codeView.lines[newLine] or "") + 1 then newLine, newSymbol = newLine + 1, 1 end setCursorPositionAndClearSelection(newSymbol, newLine) end - elseif not mainWindow.autocompleteWindow.isHidden then - mainWindow.autocompleteWindow.currentMatch = mainWindow.autocompleteWindow.currentMatch + lineOffset + elseif not mainContainer.autocompleteWindow.hidden then + mainContainer.autocompleteWindow.currentMatch = mainContainer.autocompleteWindow.currentMatch + lineOffset - if mainWindow.autocompleteWindow.currentMatch < 1 then - mainWindow.autocompleteWindow.currentMatch = 1 - elseif mainWindow.autocompleteWindow.currentMatch > #mainWindow.autocompleteWindow.matches then - mainWindow.autocompleteWindow.currentMatch = #mainWindow.autocompleteWindow.matches - elseif mainWindow.autocompleteWindow.currentMatch < mainWindow.autocompleteWindow.fromMatch then - mainWindow.autocompleteWindow.fromMatch = mainWindow.autocompleteWindow.currentMatch - elseif mainWindow.autocompleteWindow.currentMatch > mainWindow.autocompleteWindow.fromMatch + mainWindow.autocompleteWindow.height - 1 then - mainWindow.autocompleteWindow.fromMatch = mainWindow.autocompleteWindow.currentMatch - mainWindow.autocompleteWindow.height + 1 + if mainContainer.autocompleteWindow.currentMatch < 1 then + mainContainer.autocompleteWindow.currentMatch = 1 + elseif mainContainer.autocompleteWindow.currentMatch > #mainContainer.autocompleteWindow.matches then + mainContainer.autocompleteWindow.currentMatch = #mainContainer.autocompleteWindow.matches + elseif mainContainer.autocompleteWindow.currentMatch < mainContainer.autocompleteWindow.fromMatch then + mainContainer.autocompleteWindow.fromMatch = mainContainer.autocompleteWindow.currentMatch + elseif mainContainer.autocompleteWindow.currentMatch > mainContainer.autocompleteWindow.fromMatch + mainContainer.autocompleteWindow.height - 1 then + mainContainer.autocompleteWindow.fromMatch = mainContainer.autocompleteWindow.currentMatch - mainContainer.autocompleteWindow.height + 1 end end end @@ -564,37 +563,37 @@ local function setCursorPositionToHome() end local function setCursorPositionToEnd() - setCursorPositionAndClearSelection(unicode.len(mainWindow.codeView.lines[#mainWindow.codeView.lines]) + 1, #mainWindow.codeView.lines) + setCursorPositionAndClearSelection(unicode.len(mainContainer.codeView.lines[#mainContainer.codeView.lines]) + 1, #mainContainer.codeView.lines) end local function scroll(direction, speed) if direction == 1 then - if mainWindow.codeView.fromLine > speed then - mainWindow.codeView.fromLine = mainWindow.codeView.fromLine - speed + if mainContainer.codeView.fromLine > speed then + mainContainer.codeView.fromLine = mainContainer.codeView.fromLine - speed else - mainWindow.codeView.fromLine = 1 + mainContainer.codeView.fromLine = 1 end else - if mainWindow.codeView.fromLine < #mainWindow.codeView.lines - speed then - mainWindow.codeView.fromLine = mainWindow.codeView.fromLine + speed + if mainContainer.codeView.fromLine < #mainContainer.codeView.lines - speed then + mainContainer.codeView.fromLine = mainContainer.codeView.fromLine + speed else - mainWindow.codeView.fromLine = #mainWindow.codeView.lines + mainContainer.codeView.fromLine = #mainContainer.codeView.lines end end end local function pageUp() - scroll(1, mainWindow.codeView.height - 2) + scroll(1, mainContainer.codeView.height - 2) end local function pageDown() - scroll(-1, mainWindow.codeView.height - 2) + scroll(-1, mainContainer.codeView.height - 2) end local function selectWord() local from, to = getCurrentWordStartingAndEnding(cursor.position.symbol) if from and to then - mainWindow.codeView.selections[1] = { + mainContainer.codeView.selections[1] = { from = {symbol = from, line = cursor.position.line}, to = {symbol = to, line = cursor.position.line}, } @@ -603,7 +602,7 @@ local function selectWord() end local function removeTabs(text) - local result = text:gsub("\t", string.rep(" ", mainWindow.codeView.indentationWidth)) + local result = text:gsub("\t", string.rep(" ", mainContainer.codeView.indentationWidth)) return result end @@ -615,20 +614,20 @@ end local function changeResolution(width, height) buffer.setResolution(width, height) calculateSizes() - mainWindow:draw() + mainContainer:draw() buffer.draw() config.screenResolution.width = width config.screenResolution.height = height end local function changeResolutionWindow() - mainWindow.settingsContainer.isHidden = false - local textBoxesWidth = math.floor(mainWindow.width * 0.3) - local textBoxWidth, x, y = math.floor(textBoxesWidth / 2), math.floor(mainWindow.width / 2 - textBoxesWidth / 2), math.floor(mainWindow.height / 2) - 3 + mainContainer.settingsContainer.hidden = false + local textBoxesWidth = math.floor(mainContainer.width * 0.3) + local textBoxWidth, x, y = math.floor(textBoxesWidth / 2), math.floor(mainContainer.width / 2 - textBoxesWidth / 2), math.floor(mainContainer.height / 2) - 3 - mainWindow.settingsContainer:addLabel(1, y, mainWindow.width, 1, 0xFFFFFF, localization.changeResolution):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); y = y + 3 - local inputTextBoxWidth = mainWindow.settingsContainer:addInputTextBox(x, y, textBoxWidth, 3, 0xCCCCCC, 0x777777, 0xCCCCCC, 0x2D2D2D, tostring(config.screenResolution.width)); x = x + textBoxWidth + 2 - local inputTextBoxHeight = mainWindow.settingsContainer:addInputTextBox(x, y, textBoxWidth, 3, 0xCCCCCC, 0x777777, 0xCCCCCC, 0x2D2D2D, tostring(config.screenResolution.height)) + mainContainer.settingsContainer:addChild(GUI.label(1, y, mainContainer.width, 1, 0xFFFFFF, localization.changeResolution)):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); y = y + 3 + local inputTextBoxWidth = mainContainer.settingsContainer:addChild(GUI.inputTextBox(x, y, textBoxWidth, 3, 0xCCCCCC, 0x777777, 0xCCCCCC, 0x2D2D2D, tostring(config.screenResolution.width))); x = x + textBoxWidth + 2 + local inputTextBoxHeight = mainContainer.settingsContainer:addChild(GUI.inputTextBox(x, y, textBoxWidth, 3, 0xCCCCCC, 0x777777, 0xCCCCCC, 0x2D2D2D, tostring(config.screenResolution.height))) local maxResolutionWidth, maxResolutionHeight = component.gpu.maxResolution() inputTextBoxWidth.validator = function(text) @@ -640,26 +639,26 @@ local function changeResolutionWindow() if number and number >= 1 and number <= maxResolutionHeight then return true end end - local oldOnTouch = mainWindow.settingsContainer.backgroundPanel.onTouch - mainWindow.settingsContainer.backgroundPanel.onTouch = function() - config.screenResolution.width, config.screenResolution.height = tonumber(inputTextBoxWidth.text), tonumber(inputTextBoxHeight.text) - saveConfig() - hideSettingsContainer() - changeResolution(config.screenResolution.width, config.screenResolution.height) - mainWindow.settingsContainer.backgroundPanel.onTouch = oldOnTouch + mainContainer.settingsContainer.backgroundPanel.eventHandler = function(mainContainer, object, eventData) + if eventData[1] == "touch" then + config.screenResolution.width, config.screenResolution.height = tonumber(inputTextBoxWidth.text), tonumber(inputTextBoxHeight.text) + saveConfig() + hideSettingsContainer() + changeResolution(config.screenResolution.width, config.screenResolution.height) + end end end local function createInputTextBoxForSettingsWindow(title, placeholder, onInputFinishedMethod, validatorMethod) - mainWindow.settingsContainer.isHidden = false - local textBoxWidth = math.floor(mainWindow.width * 0.3) - local x, y = math.floor(mainWindow.width / 2 - textBoxWidth / 2), math.floor(mainWindow.height / 2) - 3 + mainContainer.settingsContainer.hidden = false + local textBoxWidth = math.floor(mainContainer.width * 0.3) + local x, y = math.floor(mainContainer.width / 2 - textBoxWidth / 2), math.floor(mainContainer.height / 2) - 3 - mainWindow.settingsContainer:addLabel(1, y, mainWindow.width, 1, 0xFFFFFF, title):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); y = y + 3 - local inputTextBox = mainWindow.settingsContainer:addInputTextBox(x, y, textBoxWidth, 3, 0xCCCCCC, 0x777777, 0xCCCCCC, 0x2D2D2D, "", placeholder) + mainContainer.settingsContainer:addChild(GUI.label(1, y, mainContainer.width, 1, 0xFFFFFF, title)):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); y = y + 3 + mainContainer.settingsContainer.inputTextBox = mainContainer.settingsContainer:addChild(GUI.inputTextBox(x, y, textBoxWidth, 3, 0xCCCCCC, 0x777777, 0xCCCCCC, 0x2D2D2D, "", placeholder)) - inputTextBox.validator = validatorMethod - inputTextBox.onInputFinished = function(...) + mainContainer.settingsContainer.inputTextBox.validator = validatorMethod + mainContainer.settingsContainer.inputTextBox.onInputFinished = function(...) onInputFinishedMethod(...) hideSettingsContainer() end @@ -667,10 +666,10 @@ end local function newFile() autocompleteDatabase = {} - mainWindow.codeView.lines = {""} - mainWindow.codeView.maximumLineLength = 1 + mainContainer.codeView.lines = {""} + mainContainer.codeView.maximumLineLength = 1 setCursorPositionAndClearSelection(1, 1) - mainWindow.leftTreeView.currentFile = nil + mainContainer.leftTreeView.currentFile = nil clearBreakpoints() end @@ -680,65 +679,65 @@ local function loadFile(path) local file = io.open(path, "r") for line in file:lines() do line = removeWindowsLineEndings(removeTabs(line)) - table.insert(mainWindow.codeView.lines, line) - mainWindow.codeView.maximumLineLength = math.max(mainWindow.codeView.maximumLineLength, unicode.len(line)) + table.insert(mainContainer.codeView.lines, line) + mainContainer.codeView.maximumLineLength = math.max(mainContainer.codeView.maximumLineLength, unicode.len(line)) end file:close() - if #mainWindow.codeView.lines > 1 then - table.remove(mainWindow.codeView.lines, 1) + if #mainContainer.codeView.lines > 1 then + table.remove(mainContainer.codeView.lines, 1) end - - mainWindow.leftTreeView.currentFile = path + + mainContainer.leftTreeView.currentFile = path updateAutocompleteDatabaseFromFile() end local function saveFile(path) fs.makeDirectory(fs.path(path)) local file = io.open(path, "w") - for line = 1, #mainWindow.codeView.lines do - file:write(mainWindow.codeView.lines[line], "\n") + for line = 1, #mainContainer.codeView.lines do + file:write(mainContainer.codeView.lines[line], "\n") end file:close() end local function gotoLineWindow() createInputTextBoxForSettingsWindow(localization.gotoLine, localization.lineNumber, - function(text) - gotoLine(tonumber(text)) + function() + gotoLine(tonumber(mainContainer.settingsContainer.inputTextBox.text)) end, - function(text) - if text:match("%d+") then return true end + function() + if mainContainer.settingsContainer.inputTextBox.text:match("%d+") then return true end end ) end local function openFileWindow() createInputTextBoxForSettingsWindow(localization.openFile, localization.pathToFile, - function(text) - loadFile(text) + function() + loadFile(mainContainer.settingsContainer.inputTextBox.text) end, - function(text) - if fs.exists(text) then return true end + function() + if fs.exists(mainContainer.settingsContainer.inputTextBox.text) then return true end end ) end local function saveFileAsWindow() createInputTextBoxForSettingsWindow(localization.saveAs, localization.pathToFile, - function(text) - saveFile(text) - mainWindow.leftTreeView.currentFile = text - if unicode.sub(mainWindow.leftTreeView.currentFile, 1, 1) ~= "/" then - mainWindow.leftTreeView.currentFile = "/" .. mainWindow.leftTreeView.currentFile + function() + saveFile(mainContainer.settingsContainer.inputTextBox.text) + mainContainer.leftTreeView.currentFile = mainContainer.settingsContainer.inputTextBox.text + if unicode.sub(mainContainer.leftTreeView.currentFile, 1, 1) ~= "/" then + mainContainer.leftTreeView.currentFile = "/" .. mainContainer.leftTreeView.currentFile end - mainWindow.leftTreeView:updateFileList() + mainContainer.leftTreeView:updateFileList() end ) end local function saveFileWindow() - saveFile(mainWindow.leftTreeView.currentFile) + saveFile(mainContainer.leftTreeView.currentFile) end local function splitStringIntoLines(s) @@ -763,11 +762,11 @@ end local function downloadFileFromWeb() createInputTextBoxForSettingsWindow(localization.getFromWeb, localization.url, - function(text) - local result, reason = web.request(text) + function() + local result, reason = web.request(mainContainer.settingsContainer.inputTextBox.text) if result then newFile() - mainWindow.codeView.lines, mainWindow.codeView.maximumLineLength = splitStringIntoLines(result) + mainContainer.codeView.lines, mainContainer.codeView.maximumLineLength = splitStringIntoLines(result) else GUI.error(reason, {title = {color = 0xFFDB40, text = "Failed to connect to URL"}}) end @@ -842,17 +841,17 @@ local function continue() if coroutine.status(scriptCoroutine) == "dead" then MineOSCore.waitForPressingAnyKey() hideErrorContainer() - buffer.setResolution(oldResolutionX, oldResolutionY); mainWindow:draw(); buffer.draw(true) + buffer.setResolution(oldResolutionX, oldResolutionY); mainContainer:draw(); buffer.draw(true) else -- Тест на пидора, мало ли у чувака в проге тоже есть yield if _G.MineCodeIDEDebugInfo then - buffer.setResolution(oldResolutionX, oldResolutionY); mainWindow:draw(); buffer.draw(true) + buffer.setResolution(oldResolutionX, oldResolutionY); mainContainer:draw(); buffer.draw(true) gotoLine(_G.MineCodeIDEDebugInfo.line) showBreakpointMessage(_G.MineCodeIDEDebugInfo.variables) end end else - buffer.setResolution(oldResolutionX, oldResolutionY); mainWindow:draw(); buffer.draw(true) + buffer.setResolution(oldResolutionX, oldResolutionY); mainContainer:draw(); buffer.draw(true) showErrorContainer(debug.traceback(scriptCoroutine, coroutineResumeReason)) end end @@ -864,7 +863,7 @@ local function run() if breakpointLines then local offset = 0 for i = 1, #breakpointLines do - local variables = getVariables(mainWindow.codeView.lines[breakpointLines[i] + offset]) + local variables = getVariables(mainContainer.codeView.lines[breakpointLines[i] + offset]) local breakpointMessage = "_G.MineCodeIDEDebugInfo = {variables = {" for variable in pairs(variables) do @@ -872,18 +871,18 @@ local function run() end breakpointMessage = breakpointMessage .. "}, line = " .. breakpointLines[i] .. "}; coroutine.yield()" - table.insert(mainWindow.codeView.lines, breakpointLines[i] + offset, breakpointMessage) + table.insert(mainContainer.codeView.lines, breakpointLines[i] + offset, breakpointMessage) offset = offset + 1 end end -- Лоадим кодыч - local loadSuccess, loadReason = load(table.concat(mainWindow.codeView.lines, "\n")) + local loadSuccess, loadReason = load(table.concat(mainContainer.codeView.lines, "\n")) -- Чистим дерьмо вилочкой, чистим if breakpointLines then for i = 1, #breakpointLines do - table.remove(mainWindow.codeView.lines, breakpointLines[i]) + table.remove(mainContainer.codeView.lines, breakpointLines[i]) end end @@ -897,8 +896,8 @@ local function run() end local function deleteLine(line) - if #mainWindow.codeView.lines > 1 then - table.remove(mainWindow.codeView.lines, line) + if #mainContainer.codeView.lines > 1 then + table.remove(mainContainer.codeView.lines, line) setCursorPositionAndClearSelection(1, cursor.position.line) updateAutocompleteDatabaseFromFile() @@ -906,24 +905,24 @@ local function deleteLine(line) end local function deleteSpecifiedData(fromSymbol, fromLine, toSymbol, toLine) - local upperLine = unicode.sub(mainWindow.codeView.lines[fromLine], 1, fromSymbol - 1) - local lowerLine = unicode.sub(mainWindow.codeView.lines[toLine], toSymbol + 1, -1) + local upperLine = unicode.sub(mainContainer.codeView.lines[fromLine], 1, fromSymbol - 1) + local lowerLine = unicode.sub(mainContainer.codeView.lines[toLine], toSymbol + 1, -1) for line = fromLine + 1, toLine do - table.remove(mainWindow.codeView.lines, fromLine + 1) + table.remove(mainContainer.codeView.lines, fromLine + 1) end - mainWindow.codeView.lines[fromLine] = upperLine .. lowerLine + mainContainer.codeView.lines[fromLine] = upperLine .. lowerLine setCursorPositionAndClearSelection(fromSymbol, fromLine) updateAutocompleteDatabaseFromFile() end local function deleteSelectedData() - if mainWindow.codeView.selections[1] then + if mainContainer.codeView.selections[1] then deleteSpecifiedData( - mainWindow.codeView.selections[1].from.symbol, - mainWindow.codeView.selections[1].from.line, - mainWindow.codeView.selections[1].to.symbol, - mainWindow.codeView.selections[1].to.line + mainContainer.codeView.selections[1].from.symbol, + mainContainer.codeView.selections[1].from.line, + mainContainer.codeView.selections[1].to.symbol, + mainContainer.codeView.selections[1].to.line ) clearSelection() @@ -931,52 +930,52 @@ local function deleteSelectedData() end local function copy() - if mainWindow.codeView.selections[1] then - if mainWindow.codeView.selections[1].to.line == mainWindow.codeView.selections[1].from.line then - clipboard = { unicode.sub(mainWindow.codeView.lines[mainWindow.codeView.selections[1].from.line], mainWindow.codeView.selections[1].from.symbol, mainWindow.codeView.selections[1].to.symbol) } + if mainContainer.codeView.selections[1] then + if mainContainer.codeView.selections[1].to.line == mainContainer.codeView.selections[1].from.line then + clipboard = { unicode.sub(mainContainer.codeView.lines[mainContainer.codeView.selections[1].from.line], mainContainer.codeView.selections[1].from.symbol, mainContainer.codeView.selections[1].to.symbol) } else - clipboard = { unicode.sub(mainWindow.codeView.lines[mainWindow.codeView.selections[1].from.line], mainWindow.codeView.selections[1].from.symbol, -1) } - for line = mainWindow.codeView.selections[1].from.line + 1, mainWindow.codeView.selections[1].to.line - 1 do - table.insert(clipboard, mainWindow.codeView.lines[line]) + clipboard = { unicode.sub(mainContainer.codeView.lines[mainContainer.codeView.selections[1].from.line], mainContainer.codeView.selections[1].from.symbol, -1) } + for line = mainContainer.codeView.selections[1].from.line + 1, mainContainer.codeView.selections[1].to.line - 1 do + table.insert(clipboard, mainContainer.codeView.lines[line]) end - table.insert(clipboard, unicode.sub(mainWindow.codeView.lines[mainWindow.codeView.selections[1].to.line], 1, mainWindow.codeView.selections[1].to.symbol)) + table.insert(clipboard, unicode.sub(mainContainer.codeView.lines[mainContainer.codeView.selections[1].to.line], 1, mainContainer.codeView.selections[1].to.symbol)) end end end local function cut() - if mainWindow.codeView.selections[1] then + if mainContainer.codeView.selections[1] then copy() deleteSelectedData() end end local function pasteSelectedAutocompletion() - local firstPart = unicode.sub(mainWindow.codeView.lines[cursor.position.line], 1, mainWindow.autocompleteWindow.currentWordStarting - 1) - local secondPart = unicode.sub(mainWindow.codeView.lines[cursor.position.line], mainWindow.autocompleteWindow.currentWordEnding + 1, -1) - mainWindow.codeView.lines[cursor.position.line] = firstPart .. mainWindow.autocompleteWindow.matches[mainWindow.autocompleteWindow.currentMatch][1] .. secondPart - setCursorPositionAndClearSelection(unicode.len(firstPart .. mainWindow.autocompleteWindow.matches[mainWindow.autocompleteWindow.currentMatch][1]) + 1, cursor.position.line) + local firstPart = unicode.sub(mainContainer.codeView.lines[cursor.position.line], 1, mainContainer.autocompleteWindow.currentWordStarting - 1) + local secondPart = unicode.sub(mainContainer.codeView.lines[cursor.position.line], mainContainer.autocompleteWindow.currentWordEnding + 1, -1) + mainContainer.codeView.lines[cursor.position.line] = firstPart .. mainContainer.autocompleteWindow.matches[mainContainer.autocompleteWindow.currentMatch][1] .. secondPart + setCursorPositionAndClearSelection(unicode.len(firstPart .. mainContainer.autocompleteWindow.matches[mainContainer.autocompleteWindow.currentMatch][1]) + 1, cursor.position.line) hideAutocompleteWindow() end local function paste(pasteLines) if pasteLines then - if mainWindow.codeView.selections[1] then + if mainContainer.codeView.selections[1] then deleteSelectedData() end - local firstPart = unicode.sub(mainWindow.codeView.lines[cursor.position.line], 1, cursor.position.symbol - 1) - local secondPart = unicode.sub(mainWindow.codeView.lines[cursor.position.line], cursor.position.symbol, -1) + local firstPart = unicode.sub(mainContainer.codeView.lines[cursor.position.line], 1, cursor.position.symbol - 1) + local secondPart = unicode.sub(mainContainer.codeView.lines[cursor.position.line], cursor.position.symbol, -1) if #pasteLines == 1 then - mainWindow.codeView.lines[cursor.position.line] = firstPart .. pasteLines[1] .. secondPart + mainContainer.codeView.lines[cursor.position.line] = firstPart .. pasteLines[1] .. secondPart setCursorPositionAndClearSelection(cursor.position.symbol + unicode.len(pasteLines[1]), cursor.position.line) else - mainWindow.codeView.lines[cursor.position.line] = firstPart .. pasteLines[1] + mainContainer.codeView.lines[cursor.position.line] = firstPart .. pasteLines[1] for pasteLine = #pasteLines - 1, 2, -1 do - table.insert(mainWindow.codeView.lines, cursor.position.line + 1, pasteLines[pasteLine]) + table.insert(mainContainer.codeView.lines, cursor.position.line + 1, pasteLines[pasteLine]) end - table.insert(mainWindow.codeView.lines, cursor.position.line + #pasteLines - 1, pasteLines[#pasteLines] .. secondPart) + table.insert(mainContainer.codeView.lines, cursor.position.line + #pasteLines - 1, pasteLines[#pasteLines] .. secondPart) setCursorPositionAndClearSelection(unicode.len(pasteLines[#pasteLines]) + 1, cursor.position.line + #pasteLines - 1) end @@ -986,8 +985,8 @@ end local function selectAndPasteColor() local startColor = 0xFF0000 - if mainWindow.codeView.selections[1] and mainWindow.codeView.selections[1].from.line == mainWindow.codeView.selections[1].to.line then - startColor = tonumber(unicode.sub(mainWindow.codeView.lines[mainWindow.codeView.selections[1].from.line], mainWindow.codeView.selections[1].from.symbol, mainWindow.codeView.selections[1].to.symbol)) or startColor + if mainContainer.codeView.selections[1] and mainContainer.codeView.selections[1].from.line == mainContainer.codeView.selections[1].to.line then + startColor = tonumber(unicode.sub(mainContainer.codeView.lines[mainContainer.codeView.selections[1].from.line], mainContainer.codeView.selections[1].from.symbol, mainContainer.codeView.selections[1].to.symbol)) or startColor end local selectedColor = require("palette").show("auto", "auto", startColor) @@ -1008,7 +1007,7 @@ end local function pasteAutoBrackets(unicodeByte) local char = unicode.char(unicodeByte) - local currentSymbol = unicode.sub(mainWindow.codeView.lines[cursor.position.line], cursor.position.symbol, cursor.position.symbol) + local currentSymbol = unicode.sub(mainContainer.codeView.lines[cursor.position.line], cursor.position.symbol, cursor.position.symbol) -- Если у нас вообще врублен режим автоскобок, то чекаем их if config.enableAutoBrackets then @@ -1019,19 +1018,19 @@ local function pasteAutoBrackets(unicodeByte) -- Если нажата открывающая скобка elseif possibleBrackets.openers[char] then -- А вот тут мы берем в скобочки уже выделенный текст - if mainWindow.codeView.selections[1] then - local firstPart = unicode.sub(mainWindow.codeView.lines[mainWindow.codeView.selections[1].from.line], 1, mainWindow.codeView.selections[1].from.symbol - 1) - local secondPart = unicode.sub(mainWindow.codeView.lines[mainWindow.codeView.selections[1].from.line], mainWindow.codeView.selections[1].from.symbol, -1) - mainWindow.codeView.lines[mainWindow.codeView.selections[1].from.line] = firstPart .. char .. secondPart - mainWindow.codeView.selections[1].from.symbol = mainWindow.codeView.selections[1].from.symbol + 1 + if mainContainer.codeView.selections[1] then + local firstPart = unicode.sub(mainContainer.codeView.lines[mainContainer.codeView.selections[1].from.line], 1, mainContainer.codeView.selections[1].from.symbol - 1) + local secondPart = unicode.sub(mainContainer.codeView.lines[mainContainer.codeView.selections[1].from.line], mainContainer.codeView.selections[1].from.symbol, -1) + mainContainer.codeView.lines[mainContainer.codeView.selections[1].from.line] = firstPart .. char .. secondPart + mainContainer.codeView.selections[1].from.symbol = mainContainer.codeView.selections[1].from.symbol + 1 - if mainWindow.codeView.selections[1].to.line == mainWindow.codeView.selections[1].from.line then - mainWindow.codeView.selections[1].to.symbol = mainWindow.codeView.selections[1].to.symbol + 1 + if mainContainer.codeView.selections[1].to.line == mainContainer.codeView.selections[1].from.line then + mainContainer.codeView.selections[1].to.symbol = mainContainer.codeView.selections[1].to.symbol + 1 end - firstPart = unicode.sub(mainWindow.codeView.lines[mainWindow.codeView.selections[1].to.line], 1, mainWindow.codeView.selections[1].to.symbol) - secondPart = unicode.sub(mainWindow.codeView.lines[mainWindow.codeView.selections[1].to.line], mainWindow.codeView.selections[1].to.symbol + 1, -1) - mainWindow.codeView.lines[mainWindow.codeView.selections[1].to.line] = firstPart .. possibleBrackets.openers[char] .. secondPart + firstPart = unicode.sub(mainContainer.codeView.lines[mainContainer.codeView.selections[1].to.line], 1, mainContainer.codeView.selections[1].to.symbol) + secondPart = unicode.sub(mainContainer.codeView.lines[mainContainer.codeView.selections[1].to.line], mainContainer.codeView.selections[1].to.symbol + 1, -1) + mainContainer.codeView.lines[mainContainer.codeView.selections[1].to.line] = firstPart .. possibleBrackets.openers[char] .. secondPart cursor.position.symbol = cursor.position.symbol + 2 -- А тут мы делаем двойную автоскобку, если можем elseif possibleBrackets.openers[char] and not currentSymbol:match("[%a%d%_]") then @@ -1053,22 +1052,22 @@ local function pasteAutoBrackets(unicodeByte) end local function backspaceAutoBrackets() - local previousSymbol = unicode.sub(mainWindow.codeView.lines[cursor.position.line], cursor.position.symbol - 1, cursor.position.symbol - 1) - local currentSymbol = unicode.sub(mainWindow.codeView.lines[cursor.position.line], cursor.position.symbol, cursor.position.symbol) + local previousSymbol = unicode.sub(mainContainer.codeView.lines[cursor.position.line], cursor.position.symbol - 1, cursor.position.symbol - 1) + local currentSymbol = unicode.sub(mainContainer.codeView.lines[cursor.position.line], cursor.position.symbol, cursor.position.symbol) if config.enableAutoBrackets and possibleBrackets.openers[previousSymbol] and possibleBrackets.openers[previousSymbol] == currentSymbol then deleteSpecifiedData(cursor.position.symbol, cursor.position.line, cursor.position.symbol, cursor.position.line) end end local function delete() - if mainWindow.codeView.selections[1] then + if mainContainer.codeView.selections[1] then deleteSelectedData() else - if cursor.position.symbol < unicode.len(mainWindow.codeView.lines[cursor.position.line]) + 1 then + if cursor.position.symbol < unicode.len(mainContainer.codeView.lines[cursor.position.line]) + 1 then deleteSpecifiedData(cursor.position.symbol, cursor.position.line, cursor.position.symbol, cursor.position.line) else if cursor.position.line > 1 then - deleteSpecifiedData(unicode.len(mainWindow.codeView.lines[cursor.position.line]) + 1, cursor.position.line, 0, cursor.position.line + 1) + deleteSpecifiedData(unicode.len(mainContainer.codeView.lines[cursor.position.line]) + 1, cursor.position.line, 0, cursor.position.line + 1) end end @@ -1078,7 +1077,7 @@ local function delete() end local function backspace() - if mainWindow.codeView.selections[1] then + if mainContainer.codeView.selections[1] then deleteSelectedData() else if cursor.position.symbol > 1 then @@ -1086,7 +1085,7 @@ local function backspace() deleteSpecifiedData(cursor.position.symbol - 1, cursor.position.line, cursor.position.symbol - 1, cursor.position.line) else if cursor.position.line > 1 then - deleteSpecifiedData(unicode.len(mainWindow.codeView.lines[cursor.position.line - 1]) + 1, cursor.position.line - 1, 0, cursor.position.line) + deleteSpecifiedData(unicode.len(mainContainer.codeView.lines[cursor.position.line - 1]) + 1, cursor.position.line - 1, 0, cursor.position.line) end end @@ -1096,50 +1095,50 @@ local function backspace() end local function enter() - local firstPart = unicode.sub(mainWindow.codeView.lines[cursor.position.line], 1, cursor.position.symbol - 1) - local secondPart = unicode.sub(mainWindow.codeView.lines[cursor.position.line], cursor.position.symbol, -1) - mainWindow.codeView.lines[cursor.position.line] = firstPart - table.insert(mainWindow.codeView.lines, cursor.position.line + 1, secondPart) + local firstPart = unicode.sub(mainContainer.codeView.lines[cursor.position.line], 1, cursor.position.symbol - 1) + local secondPart = unicode.sub(mainContainer.codeView.lines[cursor.position.line], cursor.position.symbol, -1) + mainContainer.codeView.lines[cursor.position.line] = firstPart + table.insert(mainContainer.codeView.lines, cursor.position.line + 1, secondPart) setCursorPositionAndClearSelection(1, cursor.position.line + 1) end local function selectAll() - mainWindow.codeView.selections[1] = { + mainContainer.codeView.selections[1] = { from = { symbol = 1, line = 1 }, to = { - symbol = unicode.len(mainWindow.codeView.lines[#mainWindow.codeView.lines]), line = #mainWindow.codeView.lines + symbol = unicode.len(mainContainer.codeView.lines[#mainContainer.codeView.lines]), line = #mainContainer.codeView.lines } } end local function isLineCommented(line) - if mainWindow.codeView.lines[line] == "" or mainWindow.codeView.lines[line]:match("%-%-%s?") then return true end + if mainContainer.codeView.lines[line] == "" or mainContainer.codeView.lines[line]:match("%-%-%s?") then return true end end local function commentLine(line) - mainWindow.codeView.lines[line] = "-- " .. mainWindow.codeView.lines[line] + mainContainer.codeView.lines[line] = "-- " .. mainContainer.codeView.lines[line] end local function uncommentLine(line) local countOfReplaces - mainWindow.codeView.lines[line], countOfReplaces = mainWindow.codeView.lines[line]:gsub("%-%-%s?", "", 1) + mainContainer.codeView.lines[line], countOfReplaces = mainContainer.codeView.lines[line]:gsub("%-%-%s?", "", 1) return countOfReplaces end local function toggleComment() - if mainWindow.codeView.selections[1] then + if mainContainer.codeView.selections[1] then local allLinesAreCommented = true - for line = mainWindow.codeView.selections[1].from.line, mainWindow.codeView.selections[1].to.line do + for line = mainContainer.codeView.selections[1].from.line, mainContainer.codeView.selections[1].to.line do if not isLineCommented(line) then allLinesAreCommented = false break end end - for line = mainWindow.codeView.selections[1].from.line, mainWindow.codeView.selections[1].to.line do + for line = mainContainer.codeView.selections[1].from.line, mainContainer.codeView.selections[1].to.line do if allLinesAreCommented then uncommentLine(line) else @@ -1150,7 +1149,7 @@ local function toggleComment() local modifyer = 3 if allLinesAreCommented then modifyer = -modifyer end setCursorPosition(cursor.position.symbol + modifyer, cursor.position.line) - mainWindow.codeView.selections[1].from.symbol, mainWindow.codeView.selections[1].to.symbol = mainWindow.codeView.selections[1].from.symbol + modifyer, mainWindow.codeView.selections[1].to.symbol + modifyer + mainContainer.codeView.selections[1].from.symbol, mainContainer.codeView.selections[1].to.symbol = mainContainer.codeView.selections[1].from.symbol + modifyer, mainContainer.codeView.selections[1].to.symbol + modifyer else if isLineCommented(cursor.position.line) then if uncommentLine(cursor.position.line) > 0 then @@ -1164,82 +1163,82 @@ local function toggleComment() end local function indentLine(line) - mainWindow.codeView.lines[line] = string.rep(" ", mainWindow.codeView.indentationWidth) .. mainWindow.codeView.lines[line] + mainContainer.codeView.lines[line] = string.rep(" ", mainContainer.codeView.indentationWidth) .. mainContainer.codeView.lines[line] end local function unindentLine(line) - mainWindow.codeView.lines[line], countOfReplaces = string.gsub(mainWindow.codeView.lines[line], "^" .. string.rep("%s", mainWindow.codeView.indentationWidth), "") + mainContainer.codeView.lines[line], countOfReplaces = string.gsub(mainContainer.codeView.lines[line], "^" .. string.rep("%s", mainContainer.codeView.indentationWidth), "") return countOfReplaces end local function indentOrUnindent(isIndent) - if mainWindow.codeView.selections[1] then + if mainContainer.codeView.selections[1] then local countOfReplacesInFirstLine, countOfReplacesInLastLine - for line = mainWindow.codeView.selections[1].from.line, mainWindow.codeView.selections[1].to.line do + for line = mainContainer.codeView.selections[1].from.line, mainContainer.codeView.selections[1].to.line do if isIndent then indentLine(line) else local countOfReplaces = unindentLine(line) - if line == mainWindow.codeView.selections[1].from.line then + if line == mainContainer.codeView.selections[1].from.line then countOfReplacesInFirstLine = countOfReplaces - elseif line == mainWindow.codeView.selections[1].to.line then + elseif line == mainContainer.codeView.selections[1].to.line then countOfReplacesInLastLine = countOfReplaces end end end if isIndent then - setCursorPosition(cursor.position.symbol + mainWindow.codeView.indentationWidth, cursor.position.line) - mainWindow.codeView.selections[1].from.symbol, mainWindow.codeView.selections[1].to.symbol = mainWindow.codeView.selections[1].from.symbol + mainWindow.codeView.indentationWidth, mainWindow.codeView.selections[1].to.symbol + mainWindow.codeView.indentationWidth + setCursorPosition(cursor.position.symbol + mainContainer.codeView.indentationWidth, cursor.position.line) + mainContainer.codeView.selections[1].from.symbol, mainContainer.codeView.selections[1].to.symbol = mainContainer.codeView.selections[1].from.symbol + mainContainer.codeView.indentationWidth, mainContainer.codeView.selections[1].to.symbol + mainContainer.codeView.indentationWidth else if countOfReplacesInFirstLine > 0 then - mainWindow.codeView.selections[1].from.symbol = mainWindow.codeView.selections[1].from.symbol - mainWindow.codeView.indentationWidth - if cursor.position.line == mainWindow.codeView.selections[1].from.line then - setCursorPosition(cursor.position.symbol - mainWindow.codeView.indentationWidth, cursor.position.line) + mainContainer.codeView.selections[1].from.symbol = mainContainer.codeView.selections[1].from.symbol - mainContainer.codeView.indentationWidth + if cursor.position.line == mainContainer.codeView.selections[1].from.line then + setCursorPosition(cursor.position.symbol - mainContainer.codeView.indentationWidth, cursor.position.line) end end if countOfReplacesInLastLine > 0 then - mainWindow.codeView.selections[1].to.symbol = mainWindow.codeView.selections[1].to.symbol - mainWindow.codeView.indentationWidth - if cursor.position.line == mainWindow.codeView.selections[1].to.line then - setCursorPosition(cursor.position.symbol - mainWindow.codeView.indentationWidth, cursor.position.line) + mainContainer.codeView.selections[1].to.symbol = mainContainer.codeView.selections[1].to.symbol - mainContainer.codeView.indentationWidth + if cursor.position.line == mainContainer.codeView.selections[1].to.line then + setCursorPosition(cursor.position.symbol - mainContainer.codeView.indentationWidth, cursor.position.line) end end end else if isIndent then indentLine(cursor.position.line) - setCursorPositionAndClearSelection(cursor.position.symbol + mainWindow.codeView.indentationWidth, cursor.position.line) + setCursorPositionAndClearSelection(cursor.position.symbol + mainContainer.codeView.indentationWidth, cursor.position.line) else if unindentLine(cursor.position.line) > 0 then - setCursorPositionAndClearSelection(cursor.position.symbol - mainWindow.codeView.indentationWidth, cursor.position.line) + setCursorPositionAndClearSelection(cursor.position.symbol - mainContainer.codeView.indentationWidth, cursor.position.line) end end end end local function updateRAMProgressBar() - if not mainWindow.topToolBar.isHidden then + if not mainContainer.topToolBar.hidden then local totalMemory = computer.totalMemory() - mainWindow.RAMUsageProgressBar.value = math.ceil((totalMemory - computer.freeMemory()) / totalMemory * 100) + mainContainer.RAMUsageProgressBar.value = math.ceil((totalMemory - computer.freeMemory()) / totalMemory * 100) end end local function find() - if not mainWindow.bottomToolBar.isHidden and mainWindow.bottomToolBar.inputTextBox.text ~= "" then + if not mainContainer.bottomToolBar.hidden and mainContainer.bottomToolBar.inputTextBox.text ~= "" then findStartFrom = findStartFrom + 1 - for line = findStartFrom, #mainWindow.codeView.lines do - local whereToFind, whatToFind = mainWindow.codeView.lines[line], mainWindow.bottomToolBar.inputTextBox.text - if not mainWindow.bottomToolBar.caseSensitiveButton.pressed then + for line = findStartFrom, #mainContainer.codeView.lines do + local whereToFind, whatToFind = mainContainer.codeView.lines[line], mainContainer.bottomToolBar.inputTextBox.text + if not mainContainer.bottomToolBar.caseSensitiveButton.pressed then whereToFind, whatToFind = unicode.lower(whereToFind), unicode.lower(whatToFind) end local success, starting, ending = pcall(string.unicodeFind, whereToFind, whatToFind) if success then if starting then - mainWindow.codeView.selections[1] = { + mainContainer.codeView.selections[1] = { from = {symbol = starting, line = line}, to = {symbol = ending, line = line}, color = 0xCC9200 @@ -1258,40 +1257,40 @@ local function find() end local function findFromFirstDisplayedLine() - findStartFrom = mainWindow.codeView.fromLine + findStartFrom = mainContainer.codeView.fromLine find() end local function toggleBottomToolBar() - mainWindow.bottomToolBar.isHidden = not mainWindow.bottomToolBar.isHidden - mainWindow.toggleBottomToolBarButton.pressed = not mainWindow.bottomToolBar.isHidden + mainContainer.bottomToolBar.hidden = not mainContainer.bottomToolBar.hidden + mainContainer.toggleBottomToolBarButton.pressed = not mainContainer.bottomToolBar.hidden calculateSizes() - if not mainWindow.bottomToolBar.isHidden then - mainWindow:draw() - mainWindow.bottomToolBar.inputTextBox:input() + if not mainContainer.bottomToolBar.hidden then + mainContainer:draw() + mainContainer.bottomToolBar.inputTextBox:input() findFromFirstDisplayedLine() end end local function toggleTopToolBar() - mainWindow.topToolBar.isHidden = not mainWindow.topToolBar.isHidden - mainWindow.toggleTopToolBarButton.pressed = not mainWindow.topToolBar.isHidden + mainContainer.topToolBar.hidden = not mainContainer.topToolBar.hidden + mainContainer.toggleTopToolBarButton.pressed = not mainContainer.topToolBar.hidden calculateSizes() end local function toggleLeftToolBar() - mainWindow.leftTreeView.isHidden = not mainWindow.leftTreeView.isHidden - mainWindow.toggleLeftToolBarButton.pressed = not mainWindow.leftTreeView.isHidden + mainContainer.leftTreeView.hidden = not mainContainer.leftTreeView.hidden + mainContainer.toggleLeftToolBarButton.pressed = not mainContainer.leftTreeView.hidden calculateSizes() end local function createEditOrRightClickMenu(x, y) local editOrRightClickMenu = GUI.contextMenu(x, y) - editOrRightClickMenu:addItem(localization.cut, not mainWindow.codeView.selections[1], "^X").onTouch = function() + editOrRightClickMenu:addItem(localization.cut, not mainContainer.codeView.selections[1], "^X").onTouch = function() cut() end - editOrRightClickMenu:addItem(localization.copy, not mainWindow.codeView.selections[1], "^C").onTouch = function() + editOrRightClickMenu:addItem(localization.copy, not mainContainer.codeView.selections[1], "^C").onTouch = function() copy() end editOrRightClickMenu:addItem(localization.paste, not clipboard, "^V").onTouch = function() @@ -1313,6 +1312,8 @@ local function createEditOrRightClickMenu(x, y) editOrRightClickMenu:addSeparator() editOrRightClickMenu:addItem(localization.addBreakpoint, false, "F9").onTouch = function() addBreakpoint() + mainContainer:draw() + buffer.draw() end editOrRightClickMenu:addItem(localization.clearBreakpoints, not breakpointLines, "^F9").onTouch = function() clearBreakpoints() @@ -1330,38 +1331,60 @@ local function createEditOrRightClickMenu(x, y) editOrRightClickMenu:show() end -local function createWindow() - mainWindow = GUI.fullScreenWindow() - - mainWindow.codeView = mainWindow:addCodeView(1, 1, 1, 1, {""}, 1, 1, 1, {}, {}, config.highlightLuaSyntax, 2) - mainWindow.codeView.scrollBars.vertical.onTouch = function() - mainWindow.codeView.fromLine = mainWindow.codeView.scrollBars.vertical.value - end - mainWindow.codeView.scrollBars.horizontal.onTouch = function() - mainWindow.codeView.fromSymbol = mainWindow.codeView.scrollBars.horizontal.value - end - - mainWindow.topMenu = mainWindow:addMenu(1, 1, 1, colors.topMenu.backgroundColor, colors.topMenu.textColor, colors.topMenu.backgroundPressedColor, colors.topMenu.textPressedColor) +local function tick() + updateTitle() + updateRAMProgressBar() + mainContainer:draw() - local item1 = mainWindow.topMenu:addItem("MineCode", 0x0) + if cursor.blinkState and mainContainer.settingsContainer.hidden then + local x, y = convertTextPositionToScreenCoordinates(cursor.position.symbol, cursor.position.line) + if + x >= mainContainer.codeView.codeAreaPosition + 1 and + y >= mainContainer.codeView.y and + x <= mainContainer.codeView.codeAreaPosition + mainContainer.codeView.codeAreaWidth - 2 and + y <= mainContainer.codeView.y + mainContainer.codeView.height - 2 + then + buffer.text(x, y, config.cursorColor, config.cursorSymbol) + end + end + + buffer.draw() +end + +local function createMainContainer() + mainContainer = GUI.fullScreenContainer() + + mainContainer.codeView = mainContainer:addChild(GUI.codeView(1, 1, 1, 1, {""}, 1, 1, 1, {}, {}, config.highlightLuaSyntax, 2)) + mainContainer.codeView.scrollBars.vertical.onTouch = function() + mainContainer.codeView.fromLine = mainContainer.codeView.scrollBars.vertical.value + end + mainContainer.codeView.scrollBars.horizontal.onTouch = function() + mainContainer.codeView.fromSymbol = mainContainer.codeView.scrollBars.horizontal.value + end + + mainContainer.topMenu = mainContainer:addChild(GUI.menu(1, 1, 1, colors.topMenu.backgroundColor, colors.topMenu.textColor, colors.topMenu.backgroundPressedColor, colors.topMenu.textPressedColor)) + + local item1 = mainContainer.topMenu:addItem("MineCode", 0x0) item1.onTouch = function() local menu = GUI.contextMenu(item1.x, item1.y + 1) menu:addItem(localization.about).onTouch = function() - mainWindow.settingsContainer.isHidden = false - local y = math.floor(mainWindow.settingsContainer.height / 2 - #about / 2) - mainWindow.settingsContainer:addTextBox(1, y, mainWindow.settingsContainer.width, #about, nil, 0xEEEEEE, about, 1):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) + mainContainer.settingsContainer.hidden = false + local y = math.floor(mainContainer.settingsContainer.height / 2 - #about / 2) + mainContainer.settingsContainer:addChild(GUI.textBox(1, y, mainContainer.settingsContainer.width, #about, nil, 0xEEEEEE, about, 1)):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) end menu:addItem(localization.quit, false, "^W").onTouch = function() - mainWindow:close() + mainContainer:stopEventHandling() end menu:show() end - local item2 = mainWindow.topMenu:addItem(localization.file) + local item2 = mainContainer.topMenu:addItem(localization.file) item2.onTouch = function() local menu = GUI.contextMenu(item2.x, item2.y + 1) menu:addItem(localization.new, false, "^N").onTouch = function() newFile() + mainContainer:draw() + buffer.draw() end menu:addItem(localization.open, false, "^O").onTouch = function() openFileWindow() @@ -1372,7 +1395,7 @@ local function createWindow() end end menu:addSeparator() - menu:addItem(localization.save, not mainWindow.leftTreeView.currentFile, "^S").onTouch = function() + menu:addItem(localization.save, not mainContainer.leftTreeView.currentFile, "^S").onTouch = function() saveFileWindow() end menu:addItem(localization.saveAs, false, "^⇧S").onTouch = function() @@ -1381,23 +1404,23 @@ local function createWindow() menu:show() end - local item3 = mainWindow.topMenu:addItem(localization.edit) + local item3 = mainContainer.topMenu:addItem(localization.edit) item3.onTouch = function() createEditOrRightClickMenu(item3.x, item3.y + 1) end - local item4 = mainWindow.topMenu:addItem(localization.properties) + local item4 = mainContainer.topMenu:addItem(localization.properties) item4.onTouch = function() local menu = GUI.contextMenu(item4.x, item4.y + 1) menu:addItem(localization.colorScheme).onTouch = function() - mainWindow.settingsContainer.isHidden = false + mainContainer.settingsContainer.hidden = false local colorSelectorsCount, colorSelectorCountX = 0, 4; for key in pairs(config.syntaxColorScheme) do colorSelectorsCount = colorSelectorsCount + 1 end local colorSelectorCountY = math.ceil(colorSelectorsCount / colorSelectorCountX) - local colorSelectorWidth, colorSelectorHeight, colorSelectorSpaceX, colorSelectorSpaceY = math.floor(mainWindow.settingsContainer.width / colorSelectorCountX * 0.8), 3, 2, 1 + local colorSelectorWidth, colorSelectorHeight, colorSelectorSpaceX, colorSelectorSpaceY = math.floor(mainContainer.settingsContainer.width / colorSelectorCountX * 0.8), 3, 2, 1 - local startX, y = math.floor(mainWindow.settingsContainer.width / 2 - (colorSelectorCountX * (colorSelectorWidth + colorSelectorSpaceX) - colorSelectorSpaceX) / 2), math.floor(mainWindow.settingsContainer.height / 2 - (colorSelectorCountY * (colorSelectorHeight + colorSelectorSpaceY) - colorSelectorSpaceY + 3) / 2) - mainWindow.settingsContainer:addLabel(1, y, mainWindow.settingsContainer.width, 1, 0xFFFFFF, localization.colorScheme):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); y = y + 3 + local startX, y = math.floor(mainContainer.settingsContainer.width / 2 - (colorSelectorCountX * (colorSelectorWidth + colorSelectorSpaceX) - colorSelectorSpaceX) / 2), math.floor(mainContainer.settingsContainer.height / 2 - (colorSelectorCountY * (colorSelectorHeight + colorSelectorSpaceY) - colorSelectorSpaceY + 3) / 2) + mainContainer.settingsContainer:addChild(GUI.label(1, y, mainContainer.settingsContainer.width, 1, 0xFFFFFF, localization.colorScheme)):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); y = y + 3 local x, counter = startX, 1 local colors = {} @@ -1408,7 +1431,7 @@ local function createWindow() aplhabeticalSort(colors) for i = 1, #colors do - local colorSelector = mainWindow.settingsContainer:addColorSelector(x, y, colorSelectorWidth, colorSelectorHeight, config.syntaxColorScheme[colors[i][1]], colors[i][1]) + local colorSelector = mainContainer.settingsContainer:addChild(GUI.colorSelector(x, y, colorSelectorWidth, colorSelectorHeight, config.syntaxColorScheme[colors[i][1]], colors[i][1])) colorSelector.onTouch = function() config.syntaxColorScheme[colors[i][1]] = colorSelector.color syntax.colorScheme = config.syntaxColorScheme @@ -1422,29 +1445,29 @@ local function createWindow() end end menu:addItem(localization.cursorProperties).onTouch = function() - mainWindow.settingsContainer.isHidden = false + mainContainer.settingsContainer.hidden = false - local elementWidth = math.floor(mainWindow.width * 0.3) - local x, y = math.floor(mainWindow.width / 2 - elementWidth / 2), math.floor(mainWindow.height / 2) - 7 - mainWindow.settingsContainer:addLabel(1, y, mainWindow.settingsContainer.width, 1, 0xFFFFFF, localization.cursorProperties):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); y = y + 3 - local inputTextBox = mainWindow.settingsContainer:addInputTextBox(x, y, elementWidth, 3, 0xCCCCCC, 0x777777, 0xCCCCCC, 0x2D2D2D, config.cursorSymbol, localization.cursorSymbol); y = y + 5 + local elementWidth = math.floor(mainContainer.width * 0.3) + local x, y = math.floor(mainContainer.width / 2 - elementWidth / 2), math.floor(mainContainer.height / 2) - 7 + mainContainer.settingsContainer:addChild(GUI.label(1, y, mainContainer.settingsContainer.width, 1, 0xFFFFFF, localization.cursorProperties)):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); y = y + 3 + local inputTextBox = mainContainer.settingsContainer:addChild(GUI.inputTextBox(x, y, elementWidth, 3, 0xCCCCCC, 0x777777, 0xCCCCCC, 0x2D2D2D, config.cursorSymbol, localization.cursorSymbol)); y = y + 5 inputTextBox.validator = function(text) if unicode.len(text) == 1 then return true end end inputTextBox.onInputFinished = function() config.cursorSymbol = inputTextBox.text; saveConfig() end - local colorSelector = mainWindow.settingsContainer:addColorSelector(x, y, elementWidth, 3, config.cursorColor, localization.cursorColor); y = y + 5 + local colorSelector = mainContainer.settingsContainer:addChild(GUI.colorSelector(x, y, elementWidth, 3, config.cursorColor, localization.cursorColor)); y = y + 5 colorSelector.onTouch = function() config.cursorColor = colorSelector.color; saveConfig() end - local horizontalSlider = mainWindow.settingsContainer:addHorizontalSlider(x, y, elementWidth, 0xFFDB80, 0x000000, 0xFFDB40, 0xDDDDDD, 1, 1000, config.cursorBlinkDelay * 1000, false, localization.cursorBlinkDelay .. ": ", " ms") + local horizontalSlider = mainContainer.settingsContainer:addChild(GUI.slider(x, y, elementWidth, 0xFFDB80, 0x000000, 0xFFDB40, 0xDDDDDD, 1, 1000, config.cursorBlinkDelay * 1000, false, localization.cursorBlinkDelay .. ": ", " ms")) horizontalSlider.onValueChanged = function() config.cursorBlinkDelay = horizontalSlider.value / 1000; saveConfig() end end - if mainWindow.topToolBar.isHidden then + if mainContainer.topToolBar.hidden then menu:addItem(localization.toggleTopToolBar).onTouch = function() toggleTopToolBar() end @@ -1464,7 +1487,7 @@ local function createWindow() menu:show() end - local item5 = mainWindow.topMenu:addItem(localization.gotoCyka) + local item5 = mainContainer.topMenu:addItem(localization.gotoCyka) item5.onTouch = function() local menu = GUI.contextMenu(item5.x, item5.y + 1) menu:addItem(localization.pageUp, false, "PgUp").onTouch = function() @@ -1486,104 +1509,119 @@ local function createWindow() menu:show() end - mainWindow.topToolBar = mainWindow:addContainer(1, 2, 1, 3) - mainWindow.topToolBar.backgroundPanel = mainWindow.topToolBar:addPanel(1, 1, 1, 3, colors.topToolBar) - mainWindow.titleTextBox = mainWindow.topToolBar:addTextBox(1, 1, 1, 3, 0x0, 0x0, {}, 1):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) - local titleTextBoxOldDraw = mainWindow.titleTextBox.draw - mainWindow.titleTextBox.draw = function(titleTextBox) + mainContainer.topToolBar = mainContainer:addChild(GUI.container(1, 2, 1, 3)) + mainContainer.topToolBar.backgroundPanel = mainContainer.topToolBar:addChild(GUI.panel(1, 1, 1, 3, colors.topToolBar)) + mainContainer.titleTextBox = mainContainer.topToolBar:addChild(GUI.textBox(1, 1, 1, 3, 0x0, 0x0, {}, 1):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top)) + local titleTextBoxOldDraw = mainContainer.titleTextBox.draw + mainContainer.titleTextBox.draw = function(titleTextBox) titleTextBoxOldDraw(titleTextBox) - local sidesColor = mainWindow.errorContainer.isHidden and colors.title.default.sides or colors.title.onError.sides + local sidesColor = mainContainer.errorContainer.hidden and colors.title.default.sides or colors.title.onError.sides buffer.square(titleTextBox.x, titleTextBox.y, 1, titleTextBox.height, sidesColor, titleTextBox.colors.text, " ") buffer.square(titleTextBox.x + titleTextBox.width - 1, titleTextBox.y, 1, titleTextBox.height, sidesColor, titleTextBox.colors.text, " ") end - mainWindow.RAMUsageProgressBar = mainWindow.topToolBar:addProgressBar(1, 2, 1, 0x777777, 0xBBBBBB, 0xAAAAAA, 50, true, true, "RAM: ", "%") + mainContainer.RAMUsageProgressBar = mainContainer.topToolBar:addChild(GUI.progressBar(1, 2, 1, 0x777777, 0xBBBBBB, 0xAAAAAA, 50, true, true, "RAM: ", "%")) --☯◌☺ - mainWindow.addBreakpointButton = mainWindow.topToolBar:addAdaptiveButton(1, 1, 3, 1, 0x878787, 0xEEEEEE, 0xCCCCCC, 0x444444, "x") - mainWindow.addBreakpointButton.onTouch = function() + mainContainer.addBreakpointButton = mainContainer.topToolBar:addChild(GUI.adaptiveButton(1, 1, 3, 1, 0x878787, 0xEEEEEE, 0xCCCCCC, 0x444444, "x")) + mainContainer.addBreakpointButton.onTouch = function() addBreakpoint() + mainContainer:draw() + buffer.draw() end - mainWindow.toggleSyntaxHighlightingButton = mainWindow.topToolBar:addAdaptiveButton(1, 1, 3, 1, 0xCCCCCC, 0x444444, 0x696969, 0xEEEEEE, "◌") - mainWindow.toggleSyntaxHighlightingButton.switchMode, mainWindow.toggleSyntaxHighlightingButton.pressed = true, true - mainWindow.toggleSyntaxHighlightingButton.onTouch = function() - mainWindow.codeView.highlightLuaSyntax = not mainWindow.codeView.highlightLuaSyntax - config.highlightLuaSyntax = mainWindow.codeView.highlightLuaSyntax + mainContainer.toggleSyntaxHighlightingButton = mainContainer.topToolBar:addChild(GUI.adaptiveButton(1, 1, 3, 1, 0xCCCCCC, 0x444444, 0x696969, 0xEEEEEE, "◌")) + mainContainer.toggleSyntaxHighlightingButton.switchMode, mainContainer.toggleSyntaxHighlightingButton.pressed = true, true + mainContainer.toggleSyntaxHighlightingButton.onTouch = function() + mainContainer.codeView.highlightLuaSyntax = not mainContainer.codeView.highlightLuaSyntax + config.highlightLuaSyntax = mainContainer.codeView.highlightLuaSyntax saveConfig() + mainContainer:draw() + buffer.draw() end - mainWindow.runButton = mainWindow.topToolBar:addAdaptiveButton(1, 1, 3, 1, 0x4B4B4B, 0xEEEEEE, 0xCCCCCC, 0x444444, "▷") - mainWindow.runButton.onTouch = function() + mainContainer.runButton = mainContainer.topToolBar:addChild(GUI.adaptiveButton(1, 1, 3, 1, 0x4B4B4B, 0xEEEEEE, 0xCCCCCC, 0x444444, "▷")) + mainContainer.runButton.onTouch = function() run() end - mainWindow.toggleLeftToolBarButton = mainWindow.topToolBar:addAdaptiveButton(1, 1, 3, 1, 0xCCCCCC, 0x444444, 0x4B4B4B, 0xEEEEEE, "⇦") - mainWindow.toggleLeftToolBarButton.switchMode, mainWindow.toggleLeftToolBarButton.pressed = true, true - mainWindow.toggleLeftToolBarButton.onTouch = function() - mainWindow.leftTreeView.isHidden = not mainWindow.toggleLeftToolBarButton.pressed + mainContainer.toggleLeftToolBarButton = mainContainer.topToolBar:addChild(GUI.adaptiveButton(1, 1, 3, 1, 0xCCCCCC, 0x444444, 0x4B4B4B, 0xEEEEEE, "⇦")) + mainContainer.toggleLeftToolBarButton.switchMode, mainContainer.toggleLeftToolBarButton.pressed = true, true + mainContainer.toggleLeftToolBarButton.onTouch = function() + mainContainer.leftTreeView.hidden = not mainContainer.toggleLeftToolBarButton.pressed calculateSizes() + mainContainer:draw() + buffer.draw() end - mainWindow.toggleBottomToolBarButton = mainWindow.topToolBar:addAdaptiveButton(1, 1, 3, 1, 0xCCCCCC, 0x444444, 0x696969, 0xEEEEEE, "⇩") - mainWindow.toggleBottomToolBarButton.switchMode, mainWindow.toggleBottomToolBarButton.pressed = true, false - mainWindow.toggleBottomToolBarButton.onTouch = function() - mainWindow.bottomToolBar.isHidden = not mainWindow.toggleBottomToolBarButton.pressed + mainContainer.toggleBottomToolBarButton = mainContainer.topToolBar:addChild(GUI.adaptiveButton(1, 1, 3, 1, 0xCCCCCC, 0x444444, 0x696969, 0xEEEEEE, "⇩")) + mainContainer.toggleBottomToolBarButton.switchMode, mainContainer.toggleBottomToolBarButton.pressed = true, false + mainContainer.toggleBottomToolBarButton.onTouch = function() + mainContainer.bottomToolBar.hidden = not mainContainer.toggleBottomToolBarButton.pressed calculateSizes() + mainContainer:draw() + buffer.draw() end - mainWindow.toggleTopToolBarButton = mainWindow.topToolBar:addAdaptiveButton(1, 1, 3, 1, 0xCCCCCC, 0x444444, 0x878787, 0xEEEEEE, "⇧") - mainWindow.toggleTopToolBarButton.switchMode, mainWindow.toggleTopToolBarButton.pressed = true, true - mainWindow.toggleTopToolBarButton.onTouch = function() - mainWindow.topToolBar.isHidden = not mainWindow.toggleTopToolBarButton.pressed + mainContainer.toggleTopToolBarButton = mainContainer.topToolBar:addChild(GUI.adaptiveButton(1, 1, 3, 1, 0xCCCCCC, 0x444444, 0x878787, 0xEEEEEE, "⇧")) + mainContainer.toggleTopToolBarButton.switchMode, mainContainer.toggleTopToolBarButton.pressed = true, true + mainContainer.toggleTopToolBarButton.onTouch = function() + mainContainer.topToolBar.hidden = not mainContainer.toggleTopToolBarButton.pressed calculateSizes() + mainContainer:draw() + buffer.draw() end - mainWindow.bottomToolBar = mainWindow:addContainer(1, 1, 1, 1) - mainWindow.bottomToolBar.caseSensitiveButton = mainWindow.bottomToolBar:addAdaptiveButton(1, 1, 2, 1, 0x3C3C3C, 0xEEEEEE, 0xBBBBBB, 0x2D2D2D, "Aa") - mainWindow.bottomToolBar.caseSensitiveButton.switchMode = true - mainWindow.bottomToolBar.onTouch = function() + mainContainer.bottomToolBar = mainContainer:addChild(GUI.container(1, 1, 1, 1)) + mainContainer.bottomToolBar.caseSensitiveButton = mainContainer.bottomToolBar:addChild(GUI.adaptiveButton(1, 1, 2, 1, 0x3C3C3C, 0xEEEEEE, 0xBBBBBB, 0x2D2D2D, "Aa")) + mainContainer.bottomToolBar.caseSensitiveButton.switchMode = true + mainContainer.bottomToolBar.onTouch = function() find() end - mainWindow.bottomToolBar.inputTextBox = mainWindow.bottomToolBar:addInputTextBox(7, 1, 10, 3, 0xCCCCCC, 0x999999, 0xCCCCCC, 0x2D2D2D, "", localization.findSomeShit) - mainWindow.bottomToolBar.inputTextBox.onInputFinished = function() + mainContainer.bottomToolBar.inputTextBox = mainContainer.bottomToolBar:addChild(GUI.inputTextBox(7, 1, 10, 3, 0xCCCCCC, 0x999999, 0xCCCCCC, 0x2D2D2D, "", localization.findSomeShit)) + mainContainer.bottomToolBar.inputTextBox.onInputFinished = function() findFromFirstDisplayedLine() end - mainWindow.bottomToolBar.findButton = mainWindow.bottomToolBar:addAdaptiveButton(1, 1, 3, 1, 0x3C3C3C, 0xEEEEEE, 0xBBBBBB, 0x2D2D2D, localization.find) - mainWindow.bottomToolBar.findButton.onTouch = function() + mainContainer.bottomToolBar.findButton = mainContainer.bottomToolBar:addChild(GUI.adaptiveButton(1, 1, 3, 1, 0x3C3C3C, 0xEEEEEE, 0xBBBBBB, 0x2D2D2D, localization.find)) + mainContainer.bottomToolBar.findButton.onTouch = function() find() end - mainWindow.bottomToolBar.isHidden = true + mainContainer.bottomToolBar.hidden = true - mainWindow.leftTreeView = mainWindow:addTreeView(1, 1, 1, 1, colors.leftTreeView.background, 0x3C3C3C, 0x3C3C3C, 0xEEEEEE, 0x888888, 0x444444, 0x00DBFF, "/") - mainWindow.leftTreeView.onFileSelected = function(path) + mainContainer.leftTreeView = mainContainer:addChild(GUI.treeView(1, 1, 1, 1, colors.leftTreeView.background, 0x3C3C3C, 0x3C3C3C, 0xEEEEEE, 0x888888, 0x444444, 0x00DBFF, "/")) + mainContainer.leftTreeView.onFileSelected = function(path) loadFile(path) + mainContainer:draw() + buffer.draw() end - mainWindow.errorContainer = mainWindow:addContainer(1, 1, 1, 1) - mainWindow.errorContainer.backgroundPanel = mainWindow.errorContainer:addPanel(1, 1, 1, 1, 0xFFFFFF, 30) - mainWindow.errorContainer.errorTextBox = mainWindow.errorContainer:addTextBox(3, 2, 1, 1, nil, 0x4B4B4B, {}, 1) - mainWindow.errorContainer.breakpointExitButton = mainWindow.errorContainer:addButton(1, 1, 1, 1, 0x3C3C3C, 0xCCCCCC, 0x2D2D2D, 0x888888, localization.finishDebug) - mainWindow.errorContainer.breakpointContinueButton = mainWindow.errorContainer:addButton(1, 1, 1, 1, 0x444444, 0xCCCCCC, 0x2D2D2D, 0x888888, localization.continueDebug) - - mainWindow.errorContainer.breakpointExitButton.onTouch = hideErrorContainer - mainWindow.errorContainer.breakpointContinueButton.onTouch = continue + mainContainer.errorContainer = mainContainer:addChild(GUI.container(1, 1, 1, 1)) + mainContainer.errorContainer.backgroundPanel = mainContainer.errorContainer:addChild(GUI.panel(1, 1, 1, 1, 0xFFFFFF, 30)) + mainContainer.errorContainer.errorTextBox = mainContainer.errorContainer:addChild(GUI.textBox(3, 2, 1, 1, nil, 0x4B4B4B, {}, 1)) + mainContainer.errorContainer.breakpointExitButton = mainContainer.errorContainer:addChild(GUI.button(1, 1, 1, 1, 0x3C3C3C, 0xCCCCCC, 0x2D2D2D, 0x888888, localization.finishDebug)) + mainContainer.errorContainer.breakpointContinueButton = mainContainer.errorContainer:addChild(GUI.button(1, 1, 1, 1, 0x444444, 0xCCCCCC, 0x2D2D2D, 0x888888, localization.continueDebug)) + mainContainer.errorContainer.breakpointExitButton.onTouch = hideErrorContainer + mainContainer.errorContainer.breakpointContinueButton.onTouch = continue hideErrorContainer() - mainWindow.settingsContainer = mainWindow:addContainer(1, 1, 1, 1) - mainWindow.settingsContainer.backgroundPanel = mainWindow.settingsContainer:addPanel(1, 1, mainWindow.settingsContainer.width, mainWindow.settingsContainer.height, 0x0, 30) - mainWindow.settingsContainer.backgroundPanel.onTouch = hideSettingsContainer - mainWindow.settingsContainer.isHidden = true + mainContainer.settingsContainer = mainContainer:addChild(GUI.container(1, 1, 1, 1)) + mainContainer.settingsContainer.backgroundPanel = mainContainer.settingsContainer:addChild(GUI.panel(1, 1, mainContainer.settingsContainer.width, mainContainer.settingsContainer.height, 0x0, 30)) + mainContainer.settingsContainer.backgroundPanel.eventHandler = function(mainContainer, object, eventData) + if eventData[1] == "touch" then + hideSettingsContainer() + end + end + mainContainer.settingsContainer.hidden = true - mainWindow.autocompleteWindow = mainWindow:addObject(1, 1, 40, 1) - mainWindow.autocompleteWindow.maximumHeight = 8 - mainWindow.autocompleteWindow.matches = {} - mainWindow.autocompleteWindow.fromMatch = 1 - mainWindow.autocompleteWindow.currentMatch = 1 - mainWindow.autocompleteWindow.isHidden = true - mainWindow.autocompleteWindow.draw = function(object) - mainWindow.autocompleteWindow.x, mainWindow.autocompleteWindow.y = convertTextPositionToScreenCoordinates(mainWindow.autocompleteWindow.currentWordStarting, cursor.position.line) - mainWindow.autocompleteWindow.x, mainWindow.autocompleteWindow.y = mainWindow.autocompleteWindow.x, mainWindow.autocompleteWindow.y + 1 + mainContainer.autocompleteWindow = mainContainer:addChild(GUI.object(1, 1, 40, 1)) + mainContainer.autocompleteWindow.maximumHeight = 8 + mainContainer.autocompleteWindow.matches = {} + mainContainer.autocompleteWindow.fromMatch = 1 + mainContainer.autocompleteWindow.currentMatch = 1 + mainContainer.autocompleteWindow.hidden = true + mainContainer.autocompleteWindow.draw = function(object) + mainContainer.autocompleteWindow.x, mainContainer.autocompleteWindow.y = convertTextPositionToScreenCoordinates(mainContainer.autocompleteWindow.currentWordStarting, cursor.position.line) + mainContainer.autocompleteWindow.x, mainContainer.autocompleteWindow.y = mainContainer.autocompleteWindow.x, mainContainer.autocompleteWindow.y + 1 object.height = object.maximumHeight if object.height > #object.matches then object.height = #object.matches end @@ -1611,203 +1649,186 @@ local function createWindow() end end - mainWindow.onTouch = function(eventData) - cursor.blinkState = true + mainContainer.codeView.eventHandler = function(mainContainer, object, eventData) + if eventData[1] == "touch" then + if eventData[5] == 1 then + createEditOrRightClickMenu(eventData[3], eventData[4]) + else + setCursorPositionAndClearSelection(convertScreenCoordinatesToTextPosition(eventData[3], eventData[4])) - if eventData[5] == 1 then - createEditOrRightClickMenu(eventData[3], eventData[4]) - else - setCursorPositionAndClearSelection(convertScreenCoordinatesToTextPosition(eventData[3], eventData[4])) + local newUptime = computer.uptime() + if newUptime - lastClickUptime <= config.doubleClickDelay then selectWord() end + lastClickUptime = newUptime + end - local newUptime = computer.uptime() - if newUptime - lastClickUptime <= config.doubleClickDelay then selectWord() end - lastClickUptime = newUptime - end - end - - mainWindow.onDrag = function(eventData) - cursor.blinkState = true - - if eventData[5] ~= 1 then - mainWindow.codeView.selections[1] = mainWindow.codeView.selections[1] or {from = {}, to = {}} - mainWindow.codeView.selections[1].from.symbol, mainWindow.codeView.selections[1].from.line = cursor.position.symbol, cursor.position.line - mainWindow.codeView.selections[1].to.symbol, mainWindow.codeView.selections[1].to.line = fixCursorPosition(convertScreenCoordinatesToTextPosition(eventData[3], eventData[4])) - - if mainWindow.codeView.selections[1].from.line > mainWindow.codeView.selections[1].to.line then - mainWindow.codeView.selections[1].from.line, mainWindow.codeView.selections[1].to.line = swap(mainWindow.codeView.selections[1].from.line, mainWindow.codeView.selections[1].to.line) - mainWindow.codeView.selections[1].from.symbol, mainWindow.codeView.selections[1].to.symbol = swap(mainWindow.codeView.selections[1].from.symbol, mainWindow.codeView.selections[1].to.symbol) - elseif mainWindow.codeView.selections[1].from.line == mainWindow.codeView.selections[1].to.line then - if mainWindow.codeView.selections[1].from.symbol > mainWindow.codeView.selections[1].to.symbol then - mainWindow.codeView.selections[1].from.symbol, mainWindow.codeView.selections[1].to.symbol = swap(mainWindow.codeView.selections[1].from.symbol, mainWindow.codeView.selections[1].to.symbol) + cursor.blinkState = true + tick() + elseif eventData[1] == "drag" then + if eventData[5] ~= 1 then + mainContainer.codeView.selections[1] = mainContainer.codeView.selections[1] or {from = {}, to = {}} + mainContainer.codeView.selections[1].from.symbol, mainContainer.codeView.selections[1].from.line = cursor.position.symbol, cursor.position.line + mainContainer.codeView.selections[1].to.symbol, mainContainer.codeView.selections[1].to.line = fixCursorPosition(convertScreenCoordinatesToTextPosition(eventData[3], eventData[4])) + + if mainContainer.codeView.selections[1].from.line > mainContainer.codeView.selections[1].to.line then + mainContainer.codeView.selections[1].from.line, mainContainer.codeView.selections[1].to.line = swap(mainContainer.codeView.selections[1].from.line, mainContainer.codeView.selections[1].to.line) + mainContainer.codeView.selections[1].from.symbol, mainContainer.codeView.selections[1].to.symbol = swap(mainContainer.codeView.selections[1].from.symbol, mainContainer.codeView.selections[1].to.symbol) + elseif mainContainer.codeView.selections[1].from.line == mainContainer.codeView.selections[1].to.line then + if mainContainer.codeView.selections[1].from.symbol > mainContainer.codeView.selections[1].to.symbol then + mainContainer.codeView.selections[1].from.symbol, mainContainer.codeView.selections[1].to.symbol = swap(mainContainer.codeView.selections[1].from.symbol, mainContainer.codeView.selections[1].to.symbol) + end end end - end - end - mainWindow.onKeyDown = function(eventData) - cursor.blinkState = true - -- Ctrl or CMD - if keyboard.isKeyDown(29) or keyboard.isKeyDown(219) then - -- Slash - if eventData[4] == 53 then - toggleComment() - -- ] - elseif eventData[4] == 27 then - config.enableAutoBrackets = not config.enableAutoBrackets - saveConfig() - -- I - elseif eventData[4] == 23 then - toggleEnableAutocompleteDatabase() - -- A - elseif eventData[4] == 30 then - selectAll() - -- C - elseif eventData[4] == 46 then - -- Shift - if keyboard.isKeyDown(42) then - selectAndPasteColor() - else - copy() + cursor.blinkState = true + tick() + elseif eventData[1] == "key_down" then + -- Ctrl or CMD + if keyboard.isKeyDown(29) or keyboard.isKeyDown(219) then + -- Slash + if eventData[4] == 53 then + toggleComment() + -- ] + elseif eventData[4] == 27 then + config.enableAutoBrackets = not config.enableAutoBrackets + saveConfig() + -- I + elseif eventData[4] == 23 then + toggleEnableAutocompleteDatabase() + -- A + elseif eventData[4] == 30 then + selectAll() + -- C + elseif eventData[4] == 46 then + -- Shift + if keyboard.isKeyDown(42) then + selectAndPasteColor() + else + copy() + end + -- V + elseif eventData[4] == 47 then + paste(clipboard) + -- X + elseif eventData[4] == 45 then + cut() + -- W + elseif eventData[4] == 17 then + mainContainer:stopEventHandling() + -- N + elseif eventData[4] == 49 then + newFile() + -- O + elseif eventData[4] == 24 then + openFileWindow() + -- U + elseif eventData[4] == 22 and component.isAvailable("internet") then + downloadFileFromWeb() + -- S + elseif eventData[4] == 31 then + -- Shift + if mainContainer.leftTreeView.currentFile and not keyboard.isKeyDown(42) then + saveFileWindow() + else + saveFileAsWindow() + end + -- F + elseif eventData[4] == 33 then + toggleBottomToolBar() + -- G + elseif eventData[4] == 34 then + find() + -- L + elseif eventData[4] == 38 then + gotoLineWindow() + -- Backspace + elseif eventData[4] == 14 then + deleteLine(cursor.position.line) + -- Delete + elseif eventData[4] == 211 then + deleteLine(cursor.position.line) + -- R + elseif eventData[4] == 19 then + changeResolutionWindow() end - -- V - elseif eventData[4] == 47 then - paste(clipboard) - -- X - elseif eventData[4] == 45 then - cut() - -- W - elseif eventData[4] == 17 then - mainWindow:close() - -- N - elseif eventData[4] == 49 then - newFile() - -- O - elseif eventData[4] == 24 then - openFileWindow() - -- U - elseif eventData[4] == 22 and component.isAvailable("internet") then - downloadFileFromWeb() - -- S - elseif eventData[4] == 31 then - -- Shift - if mainWindow.leftTreeView.currentFile and not keyboard.isKeyDown(42) then - saveFileWindow() - else - saveFileAsWindow() - end - -- F - elseif eventData[4] == 33 then - toggleBottomToolBar() - -- G - elseif eventData[4] == 34 then - find() - -- L - elseif eventData[4] == 38 then - gotoLineWindow() + -- Arrows up, down, left, right + elseif eventData[4] == 200 then + moveCursor(0, -1) + elseif eventData[4] == 208 then + moveCursor(0, 1) + elseif eventData[4] == 203 then + moveCursor(-1, 0) + elseif eventData[4] == 205 then + moveCursor(1, 0) -- Backspace elseif eventData[4] == 14 then - deleteLine(cursor.position.line) + backspace() + -- Tab + elseif eventData[4] == 15 then + if keyboard.isKeyDown(42) then + indentOrUnindent(false) + else + indentOrUnindent(true) + end + -- Enter + elseif eventData[4] == 28 then + if mainContainer.autocompleteWindow.hidden then + enter() + else + pasteSelectedAutocompletion() + end + -- F5 + elseif eventData[4] == 63 then + run() + -- F9 + elseif eventData[4] == 67 then + -- Shift + if keyboard.isKeyDown(42) then + clearBreakpoints() + else + addBreakpoint() + end + -- Home + elseif eventData[4] == 199 then + setCursorPositionToHome() + -- End + elseif eventData[4] == 207 then + setCursorPositionToEnd() + -- Page Up + elseif eventData[4] == 201 then + pageUp() + -- Page Down + elseif eventData[4] == 209 then + pageDown() -- Delete elseif eventData[4] == 211 then - deleteLine(cursor.position.line) - -- R - elseif eventData[4] == 19 then - changeResolutionWindow() - end - -- Arrows up, down, left, right - elseif eventData[4] == 200 then - moveCursor(0, -1) - elseif eventData[4] == 208 then - moveCursor(0, 1) - elseif eventData[4] == 203 then - moveCursor(-1, 0) - elseif eventData[4] == 205 then - moveCursor(1, 0) - -- Backspace - elseif eventData[4] == 14 then - backspace() - -- Tab - elseif eventData[4] == 15 then - if keyboard.isKeyDown(42) then - indentOrUnindent(false) + delete() else - indentOrUnindent(true) + pasteAutoBrackets(eventData[3]) end - -- Enter - elseif eventData[4] == 28 then - if mainWindow.autocompleteWindow.isHidden then - enter() - else - pasteSelectedAutocompletion() - end - -- F5 - elseif eventData[4] == 63 then - run() - -- F9 - elseif eventData[4] == 67 then - -- Shift - if keyboard.isKeyDown(42) then - clearBreakpoints() - else - addBreakpoint() - end - -- Home - elseif eventData[4] == 199 then - setCursorPositionToHome() - -- End - elseif eventData[4] == 207 then - setCursorPositionToEnd() - -- Page Up - elseif eventData[4] == 201 then - pageUp() - -- Page Down - elseif eventData[4] == 209 then - pageDown() - -- Delete - elseif eventData[4] == 211 then - delete() - else - pasteAutoBrackets(eventData[3]) - end - end - mainWindow.onScroll = function(eventData) - scroll(eventData[5], config.scrollSpeed) - end - - mainWindow.onAnyEvent = function(eventData) - if eventData[1] == "clipboard" then + cursor.blinkState = true + tick() + elseif eventData[1] == "scroll" then + scroll(eventData[5], config.scrollSpeed) + tick() + elseif eventData[1] == "clipboard" then paste(splitStringIntoLines(eventData[3])) + tick() elseif not eventData[1] then cursor.blinkState = not cursor.blinkState + tick() end - - updateTitle() - updateRAMProgressBar() - mainWindow:draw() - if cursor.blinkState and mainWindow.settingsContainer.isHidden then - local x, y = convertTextPositionToScreenCoordinates(cursor.position.symbol, cursor.position.line) - if - x >= mainWindow.codeView.codeAreaPosition + 1 and - y >= mainWindow.codeView.y and - x <= mainWindow.codeView.codeAreaPosition + mainWindow.codeView.codeAreaWidth - 2 and - y <= mainWindow.codeView.y + mainWindow.codeView.height - 2 - then - buffer.text(x, y, config.cursorColor, config.cursorSymbol) - end - end - buffer.draw() end end ---------------------------------------------------- RUSH B! ---------------------------------------------------- loadConfig() -createWindow() +createMainContainer() changeResolution(config.screenResolution.width, config.screenResolution.height) updateTitle() updateRAMProgressBar() -mainWindow:draw() +mainContainer:draw() if args[1] == "open" and fs.exists(args[2] or "") then loadFile(args[2]) @@ -1815,8 +1836,8 @@ else newFile() end -mainWindow:draw() +mainContainer:draw() buffer.draw() -mainWindow:handleEvents(config.cursorBlinkDelay) +mainContainer:startEventHandling(config.cursorBlinkDelay) diff --git a/Applications/Palette/Palette.lua b/Applications/Palette/Palette.lua index ddf9e2a0..269c097b 100755 --- a/Applications/Palette/Palette.lua +++ b/Applications/Palette/Palette.lua @@ -1 +1,8 @@ -loadfile("lib/palette.lua")().show("auto", "auto", 0x00DBFF) \ No newline at end of file + +local MineOSCore = require("MineOSCore") + +local mainContainer, window = MineOSCore.addWindow(require("palette").window(nil, nil, 0x9900FF)) +window.OKButton.onTouch = function() + window:close() +end +window.cancelButton.onTouch = window.OKButton.onTouch \ No newline at end of file diff --git a/Applications/Photoshop/Photoshop.lua b/Applications/Photoshop/Photoshop.lua index 694ffa29..b4031a72 100755 --- a/Applications/Photoshop/Photoshop.lua +++ b/Applications/Photoshop/Photoshop.lua @@ -3,60 +3,6 @@ local photoshopVersion = "Photoshop v6.6" -local copyright = [[ - - Photoshop v6.6 для OpenComputers - - Автор: ECS - Контактый адрес: https://vk.com/id7799889 - Соавтор: Pornogion - Контактый адрес: https://vk.com/id88323331 - - Что нового в версии 6.6: - - Программа адаптирована под работу с нумерически индексированным форматом изображения - - Добавлена поддержка кодирования формата OCIF6 - - Что нового в версии 6.5: - - Палитра заменена на более быструю и стильную, работающую на тройном буфере - - Добавлена возможность загрузки изображения из строки, созданной методом сохранения StringImage - - Что нового в версии 6.4: - - Добавлена возможность выбора цвета сетки прозрачности во вкладке "Вид" - - Что нового в версии 6.3: - - Добавлена поддержка языковых пакетов - - Что нового в версии 6.2: - - Добавлен суб-инструмент "Полигон" - - Улучшен инструмент "Выделение", теперь можно выделять области с шириной или высотой, равными 1 - - Что нового в версии 6.1: - - Добавлен суб-инструмент "Эллипс" - - Что нового в версии 6.0: - - Добавлен иструмент "Фигура", включающий в себя линию, прямоугольник и рамку - - Добавлен фильтр размытия по Гауссу - - Переработана концепция работы с выделениями - - Что нового в версии 5.1: - - Цветовая гамма программы изменена на более детальную - - Добавлена информационная мини-панель к инструменту "выделение" - - Добавлена информация о размере изображения, отображаемая под самим изображением - - Ускорен алгоритм рисования кистью и ластиком - - Что нового в версии 5.0: - - Добавлен инструмент "выделение" и несколько функций для работы с ним - - Добавлено меню "Горячие клавиши", подсказывающее, как можно удобнее работать с программой - - Что нового в версии 4.0: - - Программа переведена на библиотеку тройного буфера, скорость работы увеличена в десятки раз - - Добавлены функции обрезки, расширения, поворота и отражения картинки - - Добавлены функции тона/насыщенности, цветового баланса и наложения фотофильтра - -]] - -copyright = nil - ------------------------------------------------ Библиотеки -------------------------------------------------------------- local ecs = require("ECSAPI") @@ -115,12 +61,12 @@ local sizes = { widthOfLeftBar = 6, } sizes.xStartOfDrawingArea = sizes.widthOfLeftBar + 1 -sizes.xEndOfDrawingArea = buffer.screen.width +sizes.xEndOfDrawingArea = buffer.width sizes.yStartOfDrawingArea = 2 -sizes.yEndOfDrawingArea = buffer.screen.height - 1 +sizes.yEndOfDrawingArea = buffer.height - 1 sizes.widthOfDrawingArea = sizes.xEndOfDrawingArea - sizes.xStartOfDrawingArea + 1 sizes.heightOfDrawingArea = sizes.yEndOfDrawingArea - sizes.yStartOfDrawingArea + 1 -sizes.heightOfLeftBar = buffer.screen.height - 1 +sizes.heightOfLeftBar = buffer.height - 1 sizes.sizeOfPixelData = 4 --Для изображения @@ -215,7 +161,7 @@ end --Отрисовка цветов local function drawColors() - local xPos, yPos = 2, buffer.screen.height - 4 + local xPos, yPos = 2, buffer.height - 4 buffer.square(xPos, yPos, 3, 2, currentBackground, 0xFFFFFF, " ") buffer.square(xPos + 3, yPos + 1, 1, 2, currentForeground, 0xFFFFFF, " ") buffer.square(xPos + 1, yPos + 2, 2, 1, currentForeground, 0xFFFFFF, " ") @@ -251,7 +197,7 @@ end --Отрисовка верхнего меню local function drawTopMenu() - obj.menu = GUI.menu(1, 1, buffer.screen.width, colors.topMenu, colors.topMenuText, 0x3366CC, 0xFFFFFF, 0) + obj.menu = GUI.menu(1, 1, buffer.width, colors.topMenu, colors.topMenuText, 0x3366CC, 0xFFFFFF, 0) obj.menu:addItem("PS", ecs.colors.blue) obj.menu:addItem(localization.file) obj.menu:addItem(localization.image) @@ -274,13 +220,13 @@ end --Мини-консолька для отладки, сообщающая снизу, че происходит ваще local function console(text) - buffer.square(sizes.xStartOfDrawingArea, buffer.screen.height, sizes.widthOfDrawingArea, 1, colors.console, colors.consoleText, " ") + buffer.square(sizes.xStartOfDrawingArea, buffer.height, sizes.widthOfDrawingArea, 1, colors.console, colors.consoleText, " ") local _, total, used = ecs.getInfoAboutRAM() local RAMText = used .. "/" .. total .. " KB RAM" - buffer.text(sizes.xEndOfDrawingArea - unicode.len(RAMText), buffer.screen.height, colors.consoleText, RAMText) + buffer.text(sizes.xEndOfDrawingArea - unicode.len(RAMText), buffer.height, colors.consoleText, RAMText) - buffer.text(sizes.xStartOfDrawingArea + 1, buffer.screen.height, colors.consoleText, text) + buffer.text(sizes.xStartOfDrawingArea + 1, buffer.height, colors.consoleText, text) end --Функция, берущая указанный пиксель из массива изображения и рисующая его в буфере корректно, @@ -1061,10 +1007,10 @@ while true do for key in pairs(obj["Colors"]) do if ecs.clickedAtArea(e[3], e[4], obj["Colors"][key][1], obj["Colors"][key][2], obj["Colors"][key][3], obj["Colors"][key][4]) then if key == 1 then - currentBackground = palette.show("auto", "auto", currentBackground) or currentBackground + currentBackground = palette.show(math.floor(buffer.width / 2 - 35), math.floor(buffer.height / 2 - 12), currentBackground) or currentBackground drawAll() elseif key == 2 or key == 3 then - currentForeground = palette.show("auto", "auto", currentForeground) or currentForeground + currentForeground = palette.show(math.floor(buffer.width / 2 - 35), math.floor(buffer.height / 2 - 12), currentForeground) or currentForeground drawAll() elseif key == 4 then buffer.text(obj["Colors"][key][1], obj["Colors"][key][2], 0xFF0000, "←→") @@ -1104,7 +1050,13 @@ while true do end --Верхний меню-бар - local object = obj.menu:getClickedObject(e[3], e[4]) + local object + for i = 1, #obj.menu.children do + if obj.menu.children[i]:isClicked(e[3], e[4]) then + object = obj.menu.children[i] + break + end + end if object then object:press() buffer.draw() @@ -1333,8 +1285,8 @@ while true do else local x, y, width, height = e[3], e[4], 30, 12 --А это чтоб за края экрана не лезло - if y + height >= buffer.screen.height then y = buffer.screen.height - height end - if x + width + 1 >= buffer.screen.width then x = buffer.screen.width - width - 1 end + if y + height >= buffer.height then y = buffer.height - height end + if x + width + 1 >= buffer.width then x = buffer.width - width - 1 end currentBrushSize, currentAlpha = table.unpack(ecs.universalWindow(x, y, width, 0xeeeeee, true, {"EmptyLine"}, {"CenterText", 0x880000, localization.brushParameters}, {"Slider", 0x262626, 0x880000, 1, 10, currentBrushSize, localization.size .. ": ", " px"}, {"Slider", 0x262626, 0x880000, 0, 255, currentAlpha, localization.transparency .. ": ", ""}, {"EmptyLine"}, {"Button", {0xbbbbbb, 0xffffff, "OK"}})) buffer.draw() diff --git a/Applications/PrintImage/PrintImage.lua b/Applications/PrintImage/PrintImage.lua index 0de8114c..32ad92d7 100755 --- a/Applications/PrintImage/PrintImage.lua +++ b/Applications/PrintImage/PrintImage.lua @@ -18,7 +18,7 @@ local args, options = require("shell").parse(...) local startImagePath = args[1] == "open" and args[2] or "/MineOS/System/OS/Icons/Steve.pic" local configPath = "/MineOS/System/PrintImage/Config.cfg" local panelWidth = 34 -local window +local mainContainer local mainImage local printers local currentPrinter = 1 @@ -102,7 +102,7 @@ local function beginPrint() addShapePixel(i, jReplacer - 1, foreground, xImage, yImage * 2) end - GUI.progressBar(math.floor(buffer.screen.width / 2 - 25), math.floor(buffer.screen.height / 2), 50, 0x3366CC, 0xFFFFFF, 0xFFFFFF, math.ceil(counter * 100 / (xShapeCount * yShapeCount)), true, true, "Progress: ", "%"):draw() + GUI.progressBar(math.floor(buffer.width / 2 - 25), math.floor(buffer.height / 2), 50, 0x3366CC, 0xFFFFFF, 0xFFFFFF, math.ceil(counter * 100 / (xShapeCount * yShapeCount)), true, true, "Progress: ", "%"):draw() buffer.draw() -- else -- error("Printing out of mainImage range") @@ -138,7 +138,7 @@ local function beginPrint() end buffer.clear() - window:draw() + mainContainer:draw() buffer.draw(true) end @@ -146,7 +146,7 @@ end local function getStatus() local xBlocks, yBlocks = math.ceil(image.getWidth(mainImage) / shapeResolutionLimit), math.ceil(image.getHeight(mainImage) * 2 / shapeResolutionLimit) - window.shadeContainer.statusTextBox.lines = { + mainContainer.shadeContainer.statusTextBox.lines = { "Image size: " .. image.getWidth(mainImage) .. "x" .. image.getHeight(mainImage) .. " px", "Count of printers: " .. #printers, "Print result: " .. xBlocks .. "x" .. yBlocks .. " blocks", @@ -170,8 +170,8 @@ end local function drawMainImageObject(object) if mainImage then - local xImage = image.getWidth(mainImage) < buffer.screen.width and math.floor(buffer.screen.width / 2 - image.getWidth(mainImage) / 2) or 1 - local yImage = image.getHeight(mainImage) < buffer.screen.height and math.floor(buffer.screen.height / 2 - image.getHeight(mainImage) / 2) or 1 + local xImage = image.getWidth(mainImage) < buffer.width and math.floor(buffer.width / 2 - image.getWidth(mainImage) / 2) or 1 + local yImage = image.getHeight(mainImage) < buffer.height and math.floor(buffer.height / 2 - image.getHeight(mainImage) / 2) or 1 buffer.image(xImage, yImage, mainImage) GUI.windowShadow(xImage, yImage, image.getWidth(mainImage), image.getHeight(mainImage), 50, true) if config.showGrid then @@ -183,20 +183,20 @@ local function drawMainImageObject(object) end local function createWindow() - window = GUI.fullScreenWindow() - window:addPanel(1, 1, window.width, window.height, 0xEEEEEE) - window:addObject(1, 1, window.width, window.height).draw = drawMainImageObject + mainContainer = GUI.fullScreenContainer() + mainContainer:addChild(GUI.panel(1, 1, mainContainer.width, mainContainer.height, 0xEEEEEE)) + mainContainer:addChild(GUI.object(1, 1, mainContainer.width, mainContainer.height)).draw = drawMainImageObject local textBoxesWidth = math.floor(panelWidth * 0.55) - window.shadeContainer = window:addContainer(window.width - panelWidth + 1, 1, panelWidth, window.height) - window.shadeContainer:addPanel(1, 1, window.shadeContainer.width, window.shadeContainer.height, 0x0000000, 40) + mainContainer.shadeContainer = mainContainer:addChild(GUI.container(mainContainer.width - panelWidth + 1, 1, panelWidth, mainContainer.height)) + mainContainer.shadeContainer:addChild(GUI.panel(1, 1, mainContainer.shadeContainer.width, mainContainer.shadeContainer.height, 0x0000000, 40)) local y = 2 - window.shadeContainer:addLabel(1, y, window.shadeContainer.width, 1, 0xFFFFFF, "Main properties"):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) + mainContainer.shadeContainer:addChild(GUI.label(1, y, mainContainer.shadeContainer.width, 1, 0xFFFFFF, "Main properties")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) y = y + 2 - window.shadeContainer:addLabel(3, y, window.shadeContainer.width, 1, 0xCCCCCC, "Image path:") - window.shadeContainer:addInputTextBox(window.shadeContainer.width - textBoxesWidth - 1, y, textBoxesWidth, 1, 0xEEEEEE, 0x555555, 0xEEEEEE, 0x262626, startImagePath, nil, true).validator = function(text) + mainContainer.shadeContainer:addChild(GUI.label(3, y, mainContainer.shadeContainer.width, 1, 0xCCCCCC, "Image path:")) + mainContainer.shadeContainer:addChild(GUI.inputTextBox(mainContainer.shadeContainer.width - textBoxesWidth - 1, y, textBoxesWidth, 1, 0xEEEEEE, 0x555555, 0xEEEEEE, 0x262626, startImagePath, nil, true)).validator = function(text) if text and fs.exists(text) then if unicode.sub(text, -4, -1) == ".pic" then mainImage = image.load(text) @@ -211,75 +211,75 @@ local function createWindow() end y = y + 2 - window.shadeContainer:addLabel(3, y, window.shadeContainer.width, 1, 0xCCCCCC, "Material:") - local mainMaterialTextBox = window.shadeContainer:addInputTextBox(window.shadeContainer.width - textBoxesWidth - 1, y, textBoxesWidth, 1, 0xEEEEEE, 0x555555, 0xEEEEEE, 0x262626, config.mainMaterial, nil, false) + mainContainer.shadeContainer:addChild(GUI.label(3, y, mainContainer.shadeContainer.width, 1, 0xCCCCCC, "Material:")) + local mainMaterialTextBox = mainContainer.shadeContainer:addChild(GUI.inputTextBox(mainContainer.shadeContainer.width - textBoxesWidth - 1, y, textBoxesWidth, 1, 0xEEEEEE, 0x555555, 0xEEEEEE, 0x262626, config.mainMaterial, nil, false)) mainMaterialTextBox.onInputFinished = function() config.mainMaterial = mainMaterialTextBox.text save() end y = y + 2 - window.shadeContainer:addLabel(3, y, window.shadeContainer.width, 1, 0xCCCCCC, "Print name:") - local printNameTextBox = window.shadeContainer:addInputTextBox(window.shadeContainer.width - textBoxesWidth - 1, y, textBoxesWidth, 1, 0xEEEEEE, 0x555555, 0xEEEEEE, 0x262626, config.printName, nil, false) + mainContainer.shadeContainer:addChild(GUI.label(3, y, mainContainer.shadeContainer.width, 1, 0xCCCCCC, "Print name:")) + local printNameTextBox = mainContainer.shadeContainer:addChild(GUI.inputTextBox(mainContainer.shadeContainer.width - textBoxesWidth - 1, y, textBoxesWidth, 1, 0xEEEEEE, 0x555555, 0xEEEEEE, 0x262626, config.printName, nil, false)) printNameTextBox.onInputFinished = function() config.printName = printNameTextBox.text save() end y = y + 2 - window.shadeContainer:addLabel(3, y, window.shadeContainer.width, 1, 0xCCCCCC, "Floor mode:") - local floorSwitch = window.shadeContainer:addSwitch(window.shadeContainer.width - 9, y, 8, 0xFFDB40, 0xAAAAAA, 0xFFFFFF, config.floorMode) + mainContainer.shadeContainer:addChild(GUI.label(3, y, mainContainer.shadeContainer.width, 1, 0xCCCCCC, "Floor mode:")) + local floorSwitch = mainContainer.shadeContainer:addChild(GUI.switch(mainContainer.shadeContainer.width - 9, y, 8, 0xFFDB40, 0xAAAAAA, 0xFFFFFF, config.floorMode)) floorSwitch.onStateChanged = function() config.floorMode = floorSwitch.state save() end y = y + 2 - window.shadeContainer:addLabel(3, y, window.shadeContainer.width, 1, 0xCCCCCC, "Show grid:") - local gridSwitch = window.shadeContainer:addSwitch(window.shadeContainer.width - 9, y, 8, 0xFFDB40, 0xAAAAAA, 0xFFFFFF, config.showGrid) + mainContainer.shadeContainer:addChild(GUI.label(3, y, mainContainer.shadeContainer.width, 1, 0xCCCCCC, "Show grid:")) + local gridSwitch = mainContainer.shadeContainer:addChild(GUI.switch(mainContainer.shadeContainer.width - 9, y, 8, 0xFFDB40, 0xAAAAAA, 0xFFFFFF, config.showGrid)) gridSwitch.onStateChanged = function() config.showGrid = gridSwitch.state save() - window:draw() + mainContainer:draw() end y = y + 4 - window.shadeContainer:addLabel(1, y, window.shadeContainer.width, 1, 0xFFFFFF, "Frame properties"):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) + mainContainer.shadeContainer:addChild(GUI.label(1, y, mainContainer.shadeContainer.width, 1, 0xFFFFFF, "Frame properties")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) y = y + 2 - window.shadeContainer:addLabel(3, y, window.shadeContainer.width, 1, 0xCCCCCC, "Enabled:") - local frameSwitch = window.shadeContainer:addSwitch(window.shadeContainer.width - 9, y, 8, 0xFFDB40, 0xAAAAAA, 0xFFFFFF, config.frame.enabled) + mainContainer.shadeContainer:addChild(GUI.label(3, y, mainContainer.shadeContainer.width, 1, 0xCCCCCC, "Enabled:")) + local frameSwitch = mainContainer.shadeContainer:addChild(GUI.switch(mainContainer.shadeContainer.width - 9, y, 8, 0xFFDB40, 0xAAAAAA, 0xFFFFFF, config.frame.enabled)) frameSwitch.onStateChanged = function() config.frame.enabled = frameSwitch.state save() end y = y + 2 - window.shadeContainer:addLabel(3, y, window.shadeContainer.width, 1, 0xCCCCCC, "Material:") - local frameMaterialTextBox = window.shadeContainer:addInputTextBox(window.shadeContainer.width - textBoxesWidth - 1, y, textBoxesWidth, 1, 0xEEEEEE, 0x555555, 0xEEEEEE, 0x262626, config.frame.material, nil, false) + mainContainer.shadeContainer:addChild(GUI.label(3, y, mainContainer.shadeContainer.width, 1, 0xCCCCCC, "Material:")) + local frameMaterialTextBox = mainContainer.shadeContainer:addChild(GUI.inputTextBox(mainContainer.shadeContainer.width - textBoxesWidth - 1, y, textBoxesWidth, 1, 0xEEEEEE, 0x555555, 0xEEEEEE, 0x262626, config.frame.material, nil, false)) frameMaterialTextBox.onInputFinished = function() config.frame.material = frameMaterialTextBox.text save() end y = y + 2 - local frameWidthSlider = window.shadeContainer:addHorizontalSlider(3, y, window.shadeContainer.width - 4, 0xFFDB80, 0x000000, 0xFFDB40, 0xCCCCCC, 1, shapeResolutionLimit - 1, config.frame.width, false, "Width: " , " voxel(s)") - frameWidthSlider.onValueChanged = function(value) + local frameWidthSlider = mainContainer.shadeContainer:addChild(GUI.slider(3, y, mainContainer.shadeContainer.width - 4, 0xFFDB80, 0x000000, 0xFFDB40, 0xCCCCCC, 1, shapeResolutionLimit - 1, config.frame.width, false, "Width: " , " voxel(s)")) + frameWidthSlider.onValueChanged = function() config.frame.width = frameWidthSlider.value save() end frameWidthSlider.roundValues = true y = y + 5 - window.shadeContainer:addLabel(1, y, window.shadeContainer.width, 1, 0xFFFFFF, "Light emission"):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) + mainContainer.shadeContainer:addChild(GUI.label(1, y, mainContainer.shadeContainer.width, 1, 0xFFFFFF, "Light emission")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) y = y + 2 - window.shadeContainer:addLabel(3, y, window.shadeContainer.width, 1, 0xCCCCCC, "Enabled:") - local lightSwitch = window.shadeContainer:addSwitch(window.shadeContainer.width - 9, y, 8, 0xFFDB40, 0xAAAAAA, 0xFFFFFF, config.lightEmission.enabled) + mainContainer.shadeContainer:addChild(GUI.label(3, y, mainContainer.shadeContainer.width, 1, 0xCCCCCC, "Enabled:")) + local lightSwitch = mainContainer.shadeContainer:addChild(GUI.switch(mainContainer.shadeContainer.width - 9, y, 8, 0xFFDB40, 0xAAAAAA, 0xFFFFFF, config.lightEmission.enabled)) lightSwitch.onStateChanged = function() config.lightEmission.enabled = true save() end y = y + 2 - local lightSlider = window.shadeContainer:addHorizontalSlider(3, y, window.shadeContainer.width - 4, 0xFFDB80, 0x000000, 0xFFDB40, 0xCCCCCC, 1, 8, 8, false, "Radius: " , " block(s)") + local lightSlider = mainContainer.shadeContainer:addChild(GUI.slider(3, y, mainContainer.shadeContainer.width - 4, 0xFFDB80, 0x000000, 0xFFDB40, 0xCCCCCC, 1, 8, 8, false, "Radius: " , " block(s)")) lightSlider.roundValues = true lightSlider.onValueChanged = function() config.lightEmission.value = lightSlider.value @@ -287,23 +287,24 @@ local function createWindow() end y = y + 5 - window.shadeContainer:addLabel(1, y, window.shadeContainer.width, 1, 0xFFFFFF, "Summary information:"):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) + mainContainer.shadeContainer:addChild(GUI.label(1, y, mainContainer.shadeContainer.width, 1, 0xFFFFFF, "Summary information:")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) y = y + 2 - window.shadeContainer.statusTextBox = window.shadeContainer:addTextBox(3, y, window.shadeContainer.width - 4, 5, nil, 0xCCCCCC, {}, 1):setAlignment(GUI.alignment.horizontal.left, GUI.alignment.vertical.top) + mainContainer.shadeContainer.statusTextBox = mainContainer.shadeContainer:addChild(GUI.textBox(3, y, mainContainer.shadeContainer.width - 4, 5, nil, 0xCCCCCC, {}, 1)):setAlignment(GUI.alignment.horizontal.left, GUI.alignment.vertical.top) - window.shadeContainer:addButton(1, window.shadeContainer.height - 5, window.shadeContainer.width, 3, 0x363636, 0xFFFFFF, 0xFFFFFF, 0x262626, "Exit").onTouch = function() - window:close() + mainContainer.shadeContainer:addChild(GUI.button(1, mainContainer.shadeContainer.height - 5, mainContainer.shadeContainer.width, 3, 0x363636, 0xFFFFFF, 0xFFFFFF, 0x262626, "Exit")).onTouch = function() + mainContainer:stopEventHandling() end - window.shadeContainer:addButton(1, window.shadeContainer.height - 2, window.shadeContainer.width, 3, 0x262626, 0xFFFFFF, 0xFFFFFF, 0x262626, "Start print").onTouch = function() + mainContainer.shadeContainer:addChild(GUI.button(1, mainContainer.shadeContainer.height - 2, mainContainer.shadeContainer.width, 3, 0x262626, 0xFFFFFF, 0xFFFFFF, 0x262626, "Start print")).onTouch = function() beginPrint() end - window.onAnyEvent = function(eventData) + mainContainer.eventHandler = function(mainContainer, object, eventData) if (eventData[1] == "component_added" or eventData[1] == "component_removed") and eventData[3] == "printer3d" then getPrinters() getStatus() - window:draw() + mainContainer:draw() + buffer.draw() end end end @@ -316,10 +317,10 @@ getPrinters() createWindow() mainImage = image.load(startImagePath) getStatus() -window:draw() +mainContainer:draw() buffer.draw() -window:handleEvents() +mainContainer:startEventHandling() diff --git a/Applications/Radio/Radio.lua b/Applications/Radio/Radio.lua index 5f8d8edb..572a69f1 100644 --- a/Applications/Radio/Radio.lua +++ b/Applications/Radio/Radio.lua @@ -68,7 +68,7 @@ local function drawStation(x, y, name, color) end local function drawLine() - local x = math.floor(buffer.screen.width / 2) + local x = math.floor(buffer.width / 2) for i = 1, lineHeight do buffer.text(x + 1, i, config.colors.lineShadow, "▎") buffer.text(x, i, config.colors.line, "▍") @@ -101,7 +101,7 @@ end local function drawMenu() local width = 36 + (3 * 2 + 2) * #radioStations - local x, y = math.floor(buffer.screen.width / 2 - width / 2), lineHeight + math.floor((buffer.screen.height - lineHeight) / 2 - 1) + local x, y = math.floor(buffer.width / 2 - width / 2), lineHeight + math.floor((buffer.height - lineHeight) / 2 - 1) obj.gromkostPlus = {x, y, x + 4, y + 3} x = bigLetters.drawText(x, y, config.colors.bottomToolBarDefaultColor, "+", "*") + 1 @@ -132,7 +132,7 @@ local function drawStations() -- Текущая станция name = ecs.stringLimit("end", unicode.lower(radioStations[radioStations.currentStation].name), stationNameLimit, true) currentWidth = bigLetters.getTextSize(name) - local x, y = math.floor(buffer.screen.width / 2 - currentWidth / 2), math.floor(buffer.screen.height / 2 - 3) + local x, y = math.floor(buffer.width / 2 - currentWidth / 2), math.floor(buffer.height / 2 - 3) drawStation(x, y, name, config.colors.activeStation) -- Предедущая @@ -159,7 +159,7 @@ local function drawAll() radioStations.currentStation = #radioStations end - buffer.square(1, 1, buffer.screen.width, buffer.screen.height, config.colors.background, 0xFFFFFF, " ") + buffer.square(1, 1, buffer.width, buffer.height, config.colors.background, 0xFFFFFF, " ") drawStations() drawLine() @@ -215,7 +215,7 @@ end buffer.start() -lineHeight = math.floor(buffer.screen.height * 0.7) +lineHeight = math.floor(buffer.height * 0.7) loadStations() radio.stop() radio.setURL(radioStations[radioStations.currentStation].url) @@ -292,7 +292,7 @@ while true do {"Button", {ecs.colors.orange, 0xffffff, "OK"}} ) elseif action == "Выход" then - buffer.square(1, 1, buffer.screen.width, buffer.screen.height, config.colors.background, 0xFFFFFF, " ") + buffer.square(1, 1, buffer.width, buffer.height, config.colors.background, 0xFFFFFF, " ") buffer.draw() ecs.prepareToExit() radio.stop() diff --git a/Applications/RayWalk/RayWalk.lua b/Applications/RayWalk/RayWalk.lua index 3c693988..d7112306 100755 --- a/Applications/RayWalk/RayWalk.lua +++ b/Applications/RayWalk/RayWalk.lua @@ -25,53 +25,57 @@ local function menuBackground() end local function settings() - local window = GUI.window(1, 1, buffer.screen.width, buffer.screen.height, buffer.screen.width, buffer.screen.height) - window.onDrawStarted = menuBackground + local window = GUI.container(1, 1, buffer.width, buffer.height, buffer.width, buffer.height) + local oldDraw = window.draw + window.draw = function() + menuBackground() + oldDraw(window) + end local sliderWidth, textBoxWidth = 43, 19 local x, y = math.floor(window.width / 2 - sliderWidth / 2), math.floor(window.height / 2 - 19) - window:addLabel(1, y, window.width, 1, 0xFFFFFF, localization.rayEngineProperties):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); y = y + 3 + window:addChild(GUI.label(1, y, window.width, 1, 0xFFFFFF, localization.rayEngineProperties)):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); y = y + 3 - local resolutionTextBoxWidth = window:addInputTextBox(x, y, textBoxWidth, 3, 0x262626, 0xBBBBBB, 0x262626, 0xFFFFFF, tostring(buffer.screen.width), nil, true) - window:addLabel(x + textBoxWidth + 2, y + 1, 1, 1, 0xFFFFFF, "X") - local resolutionTextBoxHeight = window:addInputTextBox(x + textBoxWidth + 5, y, textBoxWidth, 3, 0x262626, 0xBBBBBB, 0x262626, 0xFFFFFF, tostring(buffer.screen.height), nil, true); y = y + 4 - window:addLabel(1, y, window.width, 1, 0xDDDDDD, localization.screenResolution):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); y = y + 3 + local resolutionTextBoxWidth = window:addChild(GUI.inputTextBox(x, y, textBoxWidth, 3, 0x262626, 0xBBBBBB, 0x262626, 0xFFFFFF, tostring(buffer.width), nil, true)) + window:addChild(GUI.label(x + textBoxWidth + 2, y + 1, 1, 1, 0xFFFFFF, "X")) + local resolutionTextBoxHeight = window:addChild(GUI.inputTextBox(x + textBoxWidth + 5, y, textBoxWidth, 3, 0x262626, 0xBBBBBB, 0x262626, 0xFFFFFF, tostring(buffer.height), nil, true)); y = y + 4 + window:addChild(GUI.label(1, y, window.width, 1, 0xDDDDDD, localization.screenResolution)):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); y = y + 3 resolutionTextBoxWidth.validator = function(text) local num = tonumber(text); if num and num >= 40 and num <= 160 then return true end end resolutionTextBoxHeight.validator = function(text) local num = tonumber(text); if num and num >= 12 and num <= 50 then return true end end - local function onAnyResolutionTextBoxInputFinished() window:close(); rayEngine.changeResolution(tonumber(resolutionTextBoxWidth.text), tonumber(resolutionTextBoxHeight.text)); settings() end + local function onAnyResolutionTextBoxInputFinished() window:stopEventHandling(); rayEngine.changeResolution(tonumber(resolutionTextBoxWidth.text), tonumber(resolutionTextBoxHeight.text)); settings() end resolutionTextBoxWidth.onInputFinished = onAnyResolutionTextBoxInputFinished resolutionTextBoxHeight.onInputFinished = onAnyResolutionTextBoxInputFinished - local drawDistanceSlider = window:addHorizontalSlider(x, y, sliderWidth, 0xFFDB80, 0x000000, 0xFFDB40, 0xDDDDDD, 100, 5000, rayEngine.properties.drawDistance, true, localization.drawDistance) + local drawDistanceSlider = window:addChild(GUI.slider(x, y, sliderWidth, 0xFFDB80, 0x000000, 0xFFDB40, 0xDDDDDD, 100, 5000, rayEngine.properties.drawDistance, true, localization.drawDistance)) drawDistanceSlider.onValueChanged = function() rayEngine.properties.drawDistance = drawDistanceSlider.value window:draw() buffer.draw() end; y = y + 4 - local shadingDistanceSlider = window:addHorizontalSlider(x, y, sliderWidth, 0xFFDB80, 0x000000, 0xFFDB40, 0xDDDDDD, 100, 3000, rayEngine.properties.shadingDistance, true, localization.shadingDistance) + local shadingDistanceSlider = window:addChild(GUI.slider(x, y, sliderWidth, 0xFFDB80, 0x000000, 0xFFDB40, 0xDDDDDD, 100, 3000, rayEngine.properties.shadingDistance, true, localization.shadingDistance)) shadingDistanceSlider.onValueChanged = function() rayEngine.properties.shadingDistance = shadingDistanceSlider.value window:draw() buffer.draw() end; y = y + 4 - local shadingCascadesSlider = window:addHorizontalSlider(x, y, sliderWidth, 0xFFDB80, 0x000000, 0xFFDB40, 0xDDDDDD, 2, 48, rayEngine.properties.shadingCascades, true, localization.shadingCascades) + local shadingCascadesSlider = window:addChild(GUI.slider(x, y, sliderWidth, 0xFFDB80, 0x000000, 0xFFDB40, 0xDDDDDD, 2, 48, rayEngine.properties.shadingCascades, true, localization.shadingCascades)) shadingCascadesSlider.onValueChanged = function() rayEngine.properties.shadingCascades = shadingCascadesSlider.value window:draw() buffer.draw() end; y = y + 4 - local raycastQualitySlider = window:addHorizontalSlider(x, y, sliderWidth, 0xFFDB80, 0x000000, 0xFFDB40, 0xDDDDDD, 0.5, 32, rayEngine.properties.raycastQuality, true, localization.raycastQuality) + local raycastQualitySlider = window:addChild(GUI.slider(x, y, sliderWidth, 0xFFDB80, 0x000000, 0xFFDB40, 0xDDDDDD, 0.5, 32, rayEngine.properties.raycastQuality, true, localization.raycastQuality)) raycastQualitySlider.onValueChanged = function() rayEngine.properties.raycastQuality = raycastQualitySlider.value window:draw() buffer.draw() end; y = y + 4 - local currentTimeSlider = window:addHorizontalSlider(x, y, sliderWidth, rayEngine.world.colors.sky.current, 0x000000, rayEngine.world.colors.sky.current, 0xDDDDDD, 0, rayEngine.world.dayNightCycle.length, rayEngine.world.dayNightCycle.currentTime, true, localization.dayNightCycle, localization.seconds) + local currentTimeSlider = window:addChild(GUI.slider(x, y, sliderWidth, rayEngine.world.colors.sky.current, 0x000000, rayEngine.world.colors.sky.current, 0xDDDDDD, 0, rayEngine.world.dayNightCycle.length, rayEngine.world.dayNightCycle.currentTime, true, localization.dayNightCycle, localization.seconds)) currentTimeSlider.onValueChanged = function() rayEngine.world.dayNightCycle.currentTime = currentTimeSlider.value rayEngine.refreshTimeDependentColors() @@ -81,55 +85,59 @@ local function settings() buffer.draw() end; y = y + 4 - window:addLabel(x, y, sliderWidth, 1, 0xDDDDDD, localization.enableSemipixelRenderer) + window:addChild(GUI.label(x, y, sliderWidth, 1, 0xDDDDDD, localization.enableSemipixelRenderer)) - local graphonSwitch = window:addSwitch(x + sliderWidth - 8, y, 8, 0xFFDB40, 0xAAAAAA, 0xFFFFFF, not rayEngine.properties.useSimpleRenderer) + local graphonSwitch = window:addChild(GUI.switch(x + sliderWidth - 8, y, 8, 0xFFDB40, 0xAAAAAA, 0xFFFFFF, not rayEngine.properties.useSimpleRenderer)) graphonSwitch.onStateChanged = function() rayEngine.properties.useSimpleRenderer = not graphonSwitch.state window:draw() buffer.draw() end; y = y + 3 - window:addLabel(x, y, sliderWidth, 1, 0xDDDDDD, localization.enableDayNightCycle) + window:addChild(GUI.label(x, y, sliderWidth, 1, 0xDDDDDD, localization.enableDayNightCycle)) - local lockTimeSwitch = window:addSwitch(x + sliderWidth - 8, y, 8, 0xFFDB40, 0xAAAAAA, 0xFFFFFF, rayEngine.world.dayNightCycle.enabled) + local lockTimeSwitch = window:addChild(GUI.switch(x + sliderWidth - 8, y, 8, 0xFFDB40, 0xAAAAAA, 0xFFFFFF, rayEngine.world.dayNightCycle.enabled)) lockTimeSwitch.onStateChanged = function() rayEngine.world.dayNightCycle.enabled = lockTimeSwitch.state window:draw() buffer.draw() end; y = y + 3 - window:addButton(x, y, sliderWidth, 3, 0xEEEEEE, 0x262626, 0xBBBBBB, 0x262626, localization.continue).onTouch = function() window:close(); table.toFile(applicationResourcesDirectory .. "RayEngine.cfg", rayEngine.properties, true) end + window:addChild(GUI.button(x, y, sliderWidth, 3, 0xEEEEEE, 0x262626, 0xBBBBBB, 0x262626, localization.continue)).onTouch = function() window:stopEventHandling(); table.toFile(applicationResourcesDirectory .. "RayEngine.cfg", rayEngine.properties, true) end - window:draw(); buffer.draw(); window:handleEvents() + window:draw(); buffer.draw(); window:startEventHandling() end local function menu() - local window = GUI.window(1, 1, buffer.screen.width, buffer.screen.height, buffer.screen.width, buffer.screen.height) - window.onDrawStarted = menuBackground + local window = GUI.container(1, 1, buffer.width, buffer.height, buffer.width, buffer.height) + local oldDraw = window.draw + window.draw = function() + menuBackground() + oldDraw(window) + end local buttonWidth, buttonHeight = 50, 3 local worlds = {} for file in fs.list(worldsPath) do table.insert(worlds, unicode.sub(file, 1, -2)) end local x, y = math.floor(window.width / 2 - buttonWidth / 2), math.floor(window.height / 2 - #worlds * (buttonHeight + 1) / 2 - 11) - window:addLabel(1, y, window.width, 1, 0xFFFFFF, rayWalkVersion):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); y = y + 3 - window:addButton(x, y, buttonWidth, buttonHeight, 0xEEEEEE, 0x262626, 0xBBBBBB, 0x262626, localization.continue).onTouch = function() window:close() end; y = y + buttonHeight + 1 - window:addButton(x, y, buttonWidth, buttonHeight, 0xEEEEEE, 0x262626, 0xBBBBBB, 0x262626, localization.settings).onTouch = function() window:close(); settings() end; y = y + buttonHeight + 1 - window:addButton(x, y, buttonWidth, buttonHeight, 0xEEEEEE, 0x262626, 0x999999, 0x262626, localization.exit).onTouch = function() buffer.clear(0x000000); buffer.draw(); os.exit() end; y = y + buttonHeight + 1 - window:addLabel(1, y, window.width, 1, 0xFFFFFF, localization.loadWorld):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); y = y + 2 + window:addChild(GUI.label(1, y, window.width, 1, 0xFFFFFF, rayWalkVersion)):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); y = y + 3 + window:addChild(GUI.button(x, y, buttonWidth, buttonHeight, 0xEEEEEE, 0x262626, 0xBBBBBB, 0x262626, localization.continue)).onTouch = function() window:stopEventHandling() end; y = y + buttonHeight + 1 + window:addChild(GUI.button(x, y, buttonWidth, buttonHeight, 0xEEEEEE, 0x262626, 0xBBBBBB, 0x262626, localization.settings)).onTouch = function() window:stopEventHandling(); settings() end; y = y + buttonHeight + 1 + window:addChild(GUI.button(x, y, buttonWidth, buttonHeight, 0xEEEEEE, 0x262626, 0x999999, 0x262626, localization.exit)).onTouch = function() buffer.clear(0x000000); buffer.draw(); os.exit() end; y = y + buttonHeight + 1 + window:addChild(GUI.label(1, y, window.width, 1, 0xFFFFFF, localization.loadWorld)):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); y = y + 2 for i = 1, #worlds do - window:addButton(x, y, buttonWidth, buttonHeight, 0xEEEEEE, 0x262626, 0xBBBBBB, 0x262626, worlds[i]).onTouch = function() rayEngine.loadWorld(worldsPath .. worlds[i]); window:close() end + window:addChild(GUI.button(x, y, buttonWidth, buttonHeight, 0xEEEEEE, 0x262626, 0xBBBBBB, 0x262626, worlds[i])).onTouch = function() rayEngine.loadWorld(worldsPath .. worlds[i]); window:stopEventHandling() end y = y + buttonHeight + 1 end local lines = {}; for i = 1, #localization.controlsHelp do table.insert(lines, localization.controlsHelp[i]) end table.insert(lines, 1, " ") table.insert(lines, 1, {text = localization.controls, color = 0xFFFFFF}) - window:addTextBox(1, y, window.width, #lines, nil, 0xCCCCCC, lines, 1):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); y = y + #lines + 1 + window:addChild(GUI.textBox(1, y, window.width, #lines, nil, 0xCCCCCC, lines, 1):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top)); y = y + #lines + 1 - window:draw(); buffer.draw(); window:handleEvents() + window:draw(); buffer.draw(); window:startEventHandling() end diff --git a/Applications/Stargate/Ch1.pic b/Applications/Stargate/Ch1.pic new file mode 100644 index 00000000..8ab765ec Binary files /dev/null and b/Applications/Stargate/Ch1.pic differ diff --git a/Applications/Stargate/Ch2.pic b/Applications/Stargate/Ch2.pic new file mode 100644 index 00000000..b5c53a97 Binary files /dev/null and b/Applications/Stargate/Ch2.pic differ diff --git a/Applications/Stargate/Gate.pic b/Applications/Stargate/Gate.pic deleted file mode 100644 index 1522b174..00000000 Binary files a/Applications/Stargate/Gate.pic and /dev/null differ diff --git a/Applications/Stargate/GateCore.pic b/Applications/Stargate/GateCore.pic deleted file mode 100644 index 44ec4bab..00000000 Binary files a/Applications/Stargate/GateCore.pic and /dev/null differ diff --git a/Applications/Stargate/Icon.pic b/Applications/Stargate/Icon.pic index 2c3153d7..d99d3812 100644 Binary files a/Applications/Stargate/Icon.pic and b/Applications/Stargate/Icon.pic differ diff --git a/Applications/Stargate/OffOff.pic b/Applications/Stargate/OffOff.pic new file mode 100644 index 00000000..2e59b39f Binary files /dev/null and b/Applications/Stargate/OffOff.pic differ diff --git a/Applications/Stargate/OffOn.pic b/Applications/Stargate/OffOn.pic new file mode 100644 index 00000000..0d28f6f6 Binary files /dev/null and b/Applications/Stargate/OffOn.pic differ diff --git a/Applications/Stargate/OnOff.pic b/Applications/Stargate/OnOff.pic new file mode 100644 index 00000000..75cde429 Binary files /dev/null and b/Applications/Stargate/OnOff.pic differ diff --git a/Applications/Stargate/OnOn.pic b/Applications/Stargate/OnOn.pic new file mode 100644 index 00000000..5c9e6fcf Binary files /dev/null and b/Applications/Stargate/OnOn.pic differ diff --git a/Applications/Stargate/Stargate.lua b/Applications/Stargate/Stargate.lua index cebeb537..0943f2c7 100755 --- a/Applications/Stargate/Stargate.lua +++ b/Applications/Stargate/Stargate.lua @@ -1,36 +1,29 @@ -local ecs = require("ECSAPI") local fs = require("filesystem") local image = require("image") local buffer = require("doubleBuffering") local GUI = require("GUI") local component = require("component") local unicode = require("unicode") -local event = require("event") -local stargate - +local MineOSCore = require("MineOSCore") if not component.isAvailable("stargate") then - GUI.error("Этой программе требуются Звездные Врата из мода \"SGCraft\"", {title = {color = 0xFF8888, text = "Ошибка"}}) + GUI.error("This program requires stargate from mod \"SGCraft\"", {title = {color = 0xFF8888, text = "Ошибка"}}) return -else - stargate = component.stargate end +local stargate = component.stargate -local toolbarWidth = 32 -local sg = image.load("MineOS/Applications/Stargate.app/Resources/Gate.pic") -local sgCore = image.load("MineOS/Applications/Stargate.app/Resources/GateCore.pic") -local pathToContacts = "MineOS/System/Stargate/Contacts2.cfg" -local buttons = {} -local contacts = {addresses = {}} -local chevrons = { - {x = 5, y = 26, isActivated = false}, - {x = 1, y = 15, isActivated = false}, - {x = 12, y = 5, isActivated = false}, - {x = 34, y = 1, isActivated = false}, - {x = 56, y = 5, isActivated = false}, - {x = 66, y = 15, isActivated = false}, - {x = 63, y = 26, isActivated = false}, -} +--------------------------------------------------------------------------------------------- + +local resources = MineOSCore.getCurrentApplicationResourcesDirectory() +local pathToContacts = "MineOS/System/Stargate/Contacts3.cfg" +local contacts = {} +local Ch1Image = image.load(resources .. "Ch1.pic") +local Ch2Image = image.load(resources .. "Ch2.pic") + +buffer.start() +local mainContainer = GUI.fullScreenContainer() + +--------------------------------------------------------------------------------------------- local function loadContacts() if fs.exists(pathToContacts) then @@ -42,244 +35,277 @@ local function saveContacts() table.toFile(pathToContacts, contacts) end -local function getArraySize(array) - local size = 0; for key in pairs(array) do size = size + 1 end; return size +local function chevronDraw(object) + local inactiveColor, activeColor, fadeColor = 0x332400, 0xFFDB00, 0xCC6D00 + -- buffer.square(object.x, object.y, object.width, object.height, object.isActivated and fadeColor or inactiveColor) + -- buffer.square(object.x + 1, object.y, 3, object.height, object.isActivated and activeColor or inactiveColor) + -- buffer.text(object.x + 2, object.y + 1, object.isActivated and 0x0 or 0xFFFFFF, object.text) + buffer.image(object.x, object.y, object.isActivated and Ch1Image or Ch2Image) + return object end -local function drawDock(xDock, yDock, currentDockWidth, heightOfDock) - local transparency = 25 - for i = 1, heightOfDock do - buffer.text(xDock, yDock, 0xFFFFFF, "▟", transparency) - buffer.square(xDock + 1, yDock, currentDockWidth, 1, 0xFFFFFF, 0xFFFFFF, " ", transparency) - buffer.text(xDock + currentDockWidth + 1, yDock, 0xFFFFFF, "▙", transparency) +local function newChevronObject(x, y) + local object = GUI.object(x, y, 5, 3) - transparency = transparency + 15 - currentDockWidth = currentDockWidth - 2 - xDock = xDock + 1; yDock = yDock - 1 + object.draw = chevronDraw + object.isActivated = false + object.text = " " + + return object +end + +local function addChevron(x, y) + table.insert(mainContainer.chevrons, mainContainer.chevronsContainer:addChild(newChevronObject(x, y))) +end + +local function updateChevrons(state) + for i = 1, #mainContainer.chevrons do + mainContainer.chevrons[i].isActivated = state + if not state then mainContainer.chevrons[i].text = " " end end end -local function stateOfChevrons(state) - for i = 1, #chevrons do chevrons[i].isActivated = state end -end - -local function drawChevrons(xSg, ySg) - local inactiveColor = 0x332400 - local activeColor = 0xFFDB00 - local fadeColor = 0xCC6D00 - for i = 1, #chevrons do - buffer.square(xSg + chevrons[i].x - 1, ySg + chevrons[i].y - 1, 4, 2, chevrons[i].isActivated and fadeColor or inactiveColor) - buffer.square(xSg + chevrons[i].x, ySg + chevrons[i].y - 1, 2, 2, chevrons[i].isActivated and activeColor or inactiveColor) - end -end - -local function drawSG() - buffer.clear(0x1b1b1b) - - buttons = {} - - local toolbarHeight = 34 - local x, y = math.floor((buffer.screen.width - toolbarWidth) / 2 - sg[1] / 2), math.floor(buffer.screen.height / 2 - sg[2] / 2) - buffer.image(x, y, sg) - - local stargateState = stargate.stargateState() - local irisState = stargate.irisState() - local remoteAddress = stargate.remoteAddress() +local function update() + local stargateState, irisState, imagePath = stargate.stargateState(), stargate.irisState() + mainContainer.irisButton.text = irisState == "Closed" and "Open Iris" or "Close Iris" + mainContainer.connectionButton.text = stargateState == "Connected" and "Disconnect" or "Connect" + mainContainer.connectedToLabel.text = stargateState == "Connected" and "(Connected to " .. stargate.remoteAddress() .. ")" or "(Not connected)" if stargateState == "Connected" then - stateOfChevrons(true) - buffer.image(x, y, sgCore) - end - drawChevrons(x, y) - local currentDockWidth, heightOfDock = 50, 4 - drawDock(math.floor(x + sg[1] / 2 - currentDockWidth / 2), y + sg[2] + 1, currentDockWidth, heightOfDock ) + mainContainer.connectContactButton.disabled = true + mainContainer.messageContactButton.disabled = false - local function centerText(y, color, text) - local x = math.floor(buffer.screen.width - toolbarWidth / 2 - unicode.len(text) / 2 + 1) - buffer.text(x, y, color, text) - end - - local lineColor = 0xFFFFFF - local pressColor = 0x6692FF - local buttonDisabledColor = 0xAAAAAA - - local pizdos = math.floor(buffer.screen.height / 2) - x, y = x + sg[1] + 5, pizdos - local width = buffer.screen.width - x - toolbarWidth - buffer.text(x, y, lineColor, string.rep("─", width)) - x = x + width - y = math.floor(buffer.screen.height / 2 - toolbarHeight / 2) - for i = y, y + toolbarHeight do - local bg = buffer.get(x, i) - buffer.set(x, i, bg, lineColor, "│") - end - buffer.text(x, pizdos, lineColor, "┤") - - x = x + 3 - local buttonWidth = buffer.screen.width - x - 1 - centerText(y, lineColor, "Stargate " .. stargate.localAddress()); y = y + 1 - centerText(y, 0x888888, stargateState == "Connected" and "(подключено к " .. remoteAddress .. ")" or "(не подключено)"); y = y + 1 - - - y = y + 1 - buttons.connectButton = GUI.framedButton(x, y, buttonWidth, 3, lineColor, lineColor, pressColor, pressColor, "Прямое подключение", stargateState == "Connected"):draw(); y = y + 3 - buttons.disconnectButton = GUI.framedButton(x, y, buttonWidth, 3, lineColor, lineColor, pressColor, pressColor, "Отключиться", stargateState ~= "Connected"):draw(); y = y + 3 - buttons.messageButton = GUI.framedButton(x, y, buttonWidth, 3, lineColor, lineColor, pressColor, pressColor, "Сообщение", stargateState ~= "Connected"):draw(); y = y + 3 - buttons.closeIrisButton = GUI.framedButton(x, y, buttonWidth, 3, lineColor, lineColor, pressColor, pressColor, irisState == "Closed" and "Открыть Iris" or "Закрыть Iris", irisState == "Offline"):draw(); y = y + 3 - - y = y + 1 - centerText(y, lineColor, "Контакты"); y = y + 2 - local sizeOfContacts = getArraySize(contacts.addresses) - buttons.addContactButton = GUI.framedButton(x, y, buttonWidth, 3, lineColor, lineColor, pressColor, pressColor, "Добавить"):draw(); y = y + 3 - buttons.removeContactButton = GUI.framedButton(x, y, buttonWidth, 3, lineColor, lineColor, pressColor, pressColor, "Удалить", sizeOfContacts <= 0):draw(); y = y + 3 - buttons.connectToContactButton = GUI.framedButton(x, y, buttonWidth, 3, lineColor, lineColor, pressColor, pressColor, "Соединиться", sizeOfContacts <= 0 or stargateState == "Connected"):draw(); y = y + 3 - y = y + 1 - centerText(y, lineColor, "Затраты на активацию"); y = y + 2 - buffer.text(x, y, 0x228822, string.rep("━", buttonWidth)) - - if remoteAddress ~= "" then - local pidor = stargate.energyToDial(remoteAddress) - local cyka = stargate.energyAvailable() - local blyad = math.ceil(pidor * buttonWidth / cyka) - centerText(y, lineColor, tostring(blyad) .. "%") - buffer.text(x, y, 0x55FF55, string.rep("━", blyad)) - end - - y = y + 2 - buttons.quitButton = GUI.framedButton(x, y, buttonWidth, 3, lineColor, lineColor, pressColor, pressColor, "Выйти"):draw(); y = y + 3 - -end - -local function drawAll(force) - drawSG() - buffer.draw(force) -end - -local function connectSG(address) - address = unicode.upper(address) - - local success, reason = stargate.dial(address) - if success then - contacts.lastAddress = address - saveContacts() + if irisState == "Closed" then + imagePath = "OnOn.pic" + else + imagePath = "OnOff.pic" + end else - GUI.error(reason, {title = {color = 0xFFDB40, text = "Ошибка подключения к Вратам"}, backgroundColor = 0x262626}) + mainContainer.connectContactButton.disabled = false + mainContainer.messageContactButton.disabled = true + + if irisState == "Closed" then + imagePath = "OffOn.pic" + else + imagePath = "OffOff.pic" + end + end + mainContainer.SGImage.image = image.load(resources .. imagePath) +end + +local function updateContacts() + mainContainer.contactsComboBox.items = {} + if #contacts == 0 then + mainContainer.contactsComboBox:addItem("No contacts found") + else + for i = 1, #contacts do + mainContainer.contactsComboBox:addItem(contacts[i].name) + end end end +local function newThing(x, y, width, height) + local object = GUI.object(x, y, width, height) + + object.draw = function(object) + local x, y = object.x + object.width - 1, math.floor(object.y + object.height / 2) + for i = object.y, object.y + object.height - 1 do + buffer.text(x, i, 0xEEEEEE, "│") + end + for i = object.x, object.x + width - 1 do + buffer.text(i, y, 0xEEEEEE, "─") + end + buffer.text(x, y, 0xEEEEEE, "┤") + end --- ecs.prepareToExit() --- for key, val in pairs(stargate) do print(key, val) end --- ecs.wait() + return object +end -loadContacts() +local function dial(address) + local success = stargate.dial(address) + if success then + mainContainer.fuelProgressBar.value = math.ceil(stargate.energyToDial(address) / stargate.energyAvailable() * 100) + mainContainer:draw() + buffer.draw() + end +end -buffer.start() +--------------------------------------------------------------------------------------------- -drawAll(true) +mainContainer:addChild(GUI.panel(1, 1, mainContainer.width, mainContainer.height, 0x1E1E1E)) +mainContainer.SGImage = mainContainer:addChild(GUI.image(1, 1, image.load(resources .. "OffOff.pic"))) +mainContainer.chevronsContainer = mainContainer:addChild(GUI.container(mainContainer.SGImage.localPosition.x, mainContainer.SGImage.localPosition.y, mainContainer.SGImage.width, mainContainer.SGImage.height)) +mainContainer.chevrons = {} +addChevron(13, 30) +addChevron(8, 17) +addChevron(21, 6) +addChevron(45, 1) +addChevron(72, 6) +addChevron(83, 17) +addChevron(79, 30) -while true do - local e = {event.pull()} - if e[1] == "touch" then - for _, button in pairs(buttons) do - if button:isClicked(e[3], e[4]) then - button:pressAndRelease() +local width, height = 32, 37 +local x, y = mainContainer.width - width - 3, math.floor(mainContainer.height / 2 - height / 2) - if button.text == "Прямое подключение" then - local data = ecs.universalWindow("auto", "auto", 36, 0x262626, true, - {"EmptyLine"}, - {"CenterText", ecs.colors.orange, "Прямое подключение"}, - {"EmptyLine"}, - {"Input", 0xFFFFFF, ecs.colors.orange, contacts.lastAddress or "Введите адрес"}, - {"EmptyLine"}, - {"Button", {ecs.colors.orange, 0xffffff, "OK"}, {0x999999, 0xffffff, "Отмена"}} - ) - if data[2] == "OK" then - connectSG(data[1]) - end - elseif button.text == "Открыть Iris" then - stargate.openIris() - elseif button.text == "Добавить" then - local remoteAddress = stargate.remoteAddress() - local data = ecs.universalWindow("auto", "auto", 36, 0x262626, true, - {"EmptyLine"}, - {"CenterText", ecs.colors.orange, "Добавить контакт"}, - {"EmptyLine"}, - {"Input", 0xFFFFFF, ecs.colors.orange, "Название"}, - {"Input", 0xFFFFFF, ecs.colors.orange, contacts.lastAddress or component.stargate.remoteAddress() or "Адрес Звездных Врат"}, - {"EmptyLine"}, - -- remoteAddress ~= "" and - -- {"Button", {ecs.colors.orange, 0xffffff, "OK"}, {0x999999, 0xffffff, "Добавить текущий"}, {0x777777, 0xffffff, "Отмена"}} - -- or - {"Button", {ecs.colors.orange, 0xffffff, "OK"}, {0x777777, 0xffffff, "Отмена"}} - ) - if data[3] == "OK" then - contacts.addresses[data[1]] = data[2] - saveContacts() - -- elseif data[3] == "Добавить текущий" then - -- contacts.addresses[data[1]] = remoteAddress - -- saveContacts() - end - drawAll() - elseif button.text == "Соединиться" or button.text == "Удалить" then - local isConnect = (button.text == "Соединиться") - local names = {}; for name in pairs(contacts.addresses) do table.insert(names, name) end - local data = ecs.universalWindow("auto", "auto", 36, 0x262626, true, - {"EmptyLine"}, - {"CenterText", ecs.colors.orange, isConnect and "Соединиться" or "Удалить контакт"}, - {"EmptyLine"}, - {"Selector", 0xFFFFFF, ecs.colors.orange, table.unpack(names)}, - {"EmptyLine"}, - {"Button", {ecs.colors.orange, 0xffffff, "OK"}, {0x999999, 0xffffff, "Отмена"}} - ) - if data[2] == "OK" then - if isConnect then - connectSG(contacts.addresses[data[1]]) - else - for name in pairs(contacts.addresses) do - if name == data[1] then contacts.addresses[name] = nil; break end - end - saveContacts() - end - drawAll() - end - elseif button.text == "Закрыть Iris" then - stargate.closeIris() - elseif button.text == "Отключиться" then - stateOfChevrons(false) - stargate.disconnect() - elseif button.text == "Выйти" then - buffer.clear(0x262626) - return - elseif button.text == "Сообщение" then - local data = ecs.universalWindow("auto", "auto", 36, 0x262626, true, - {"EmptyLine"}, - {"CenterText", ecs.colors.orange, "Сообщение"}, - {"EmptyLine"}, - {"Input", 0xFFFFFF, ecs.colors.orange, "Текст сообщения"}, - {"EmptyLine"}, - {"Button", {ecs.colors.orange, 0xffffff, "OK"}, {0x999999, 0xffffff, "Отмена"}} - ) - if data[2] == "OK" then - component.stargate.sendMessage(data[1] or "Пустое сообщение") - end - end +mainContainer.SGImage.localPosition.x, mainContainer.SGImage.localPosition.y = math.floor((x - 2) / 2 - image.getWidth(mainContainer.SGImage.image) / 2), mainContainer.height - image.getHeight(mainContainer.SGImage.image) + 1 +mainContainer.chevronsContainer.localPosition = mainContainer.SGImage.localPosition + +mainContainer:addChild(newThing(mainContainer.SGImage.localPosition.x + mainContainer.SGImage.width, y, mainContainer.width - mainContainer.SGImage.localPosition.x - mainContainer.SGImage.width - width - 7, height)) + +mainContainer:addChild(GUI.label(x, y, width, 1, 0xEEEEEE, "Stargate " .. stargate.localAddress())):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); y = y + 1 +mainContainer.connectedToLabel = mainContainer:addChild(GUI.label(x, y, width, 1, 0x555555, "(Not connected)")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); y = y + 2 +mainContainer.connectionButton = mainContainer:addChild(GUI.framedButton(x, y, width, 3, 0xEEEEEE, 0xEEEEEE, 0xBBBBBB, 0xBBBBBB, "Connect")); y = y + 3 +mainContainer.connectionButton.onTouch = function() + if stargate.stargateState() == "Idle" then + local container = MineOSCore.addUniversalContainer(mainContainer, "Connect") + local inputTextBox = container.layout:addChild(GUI.inputTextBox(1, 1, 36, 3, 0xEEEEEE, 0x666666, 0xEEEEEE, 0x262626, contacts.last, "Type address here")) + inputTextBox.onInputFinished = function() + if inputTextBox.text then + dial(inputTextBox.text) + contacts.last = inputTextBox.text + saveContacts() + container:delete() + + mainContainer:draw() + buffer.draw() end end - elseif e[1] == "sgIrisStateChange" then - drawAll() - elseif e[1] == "sgStargateStateChange" then - if e[3] == "Closing" then stateOfChevrons(false) end - drawAll() - elseif e[1] == "sgChevronEngaged" then - chevrons[e[3]].isActivated = true - drawAll() - elseif e[1] == "sgMessageReceived" then - GUI.error(tostring(e[3]), {title = {color = 0xFFDB40, text = "Соообщение от Врат"}, backgroundColor = 0x262626}) + + container.panel.eventHandler = function() + inputTextBox.onInputFinished() + end + + mainContainer:draw() + buffer.draw() + else + stargate.disconnect() end end - - + +mainContainer.irisButton = mainContainer:addChild(GUI.framedButton(x, y, width, 3, 0xEEEEEE, 0xEEEEEE, 0xBBBBBB, 0xBBBBBB, "Open Iris")); y = y + 3 +mainContainer.irisButton.onTouch = function() + if stargate.irisState() == "Open" then + stargate.closeIris() + else + stargate.openIris() + end +end + +mainContainer.messageContactButton = mainContainer:addChild(GUI.framedButton(x, y, width, 3, 0xEEEEEE, 0xEEEEEE, 0xBBBBBB, 0xBBBBBB, "Message")); y = y + 4 +mainContainer.messageContactButton.onTouch = function() + local container = MineOSCore.addUniversalContainer(mainContainer, "Message") + local inputTextBox = container.layout:addChild(GUI.inputTextBox(1, 1, 36, 3, 0xEEEEEE, 0x666666, 0xEEEEEE, 0x262626, nil, "Type message text here")) + inputTextBox.onInputFinished = function() + if inputTextBox.text then + container:delete() + stargate.sendMessage(inputTextBox.text) + + mainContainer:draw() + buffer.draw() + end + end + + container.panel.eventHandler = function() + inputTextBox.onInputFinished() + end + + mainContainer:draw() + buffer.draw() +end + +mainContainer:addChild(GUI.label(x, y, width, 1, 0xEEEEEE, "Contacts")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); y = y + 2 +mainContainer.contactsComboBox = mainContainer:addChild(GUI.comboBox(x, y, width, 3, 0x3C3C3C, 0xBBBBBB, 0x555555, 0x888888)); y = y + 4 + +mainContainer.connectContactButton = mainContainer:addChild(GUI.framedButton(x, y, width, 3, 0xEEEEEE, 0xEEEEEE, 0xBBBBBB, 0xBBBBBB, "Connect")); y = y + 3 +mainContainer.connectContactButton.onTouch = function() + if #contacts > 0 then + dial(contacts[mainContainer.contactsComboBox.selectedItem].address) + end +end + +mainContainer.addContactButton = mainContainer:addChild(GUI.framedButton(x, y, width, 3, 0xEEEEEE, 0xEEEEEE, 0xBBBBBB, 0xBBBBBB, "Add contact")); y = y + 3 +mainContainer.addContactButton.onTouch = function() + local container = MineOSCore.addUniversalContainer(mainContainer, "Add contact") + local inputTextBox1 = container.layout:addChild(GUI.inputTextBox(1, 1, 36, 3, 0xEEEEEE, 0x666666, 0xEEEEEE, 0x262626, nil, "Name")) + local inputTextBox2 = container.layout:addChild(GUI.inputTextBox(1, 1, 36, 3, 0xEEEEEE, 0x666666, 0xEEEEEE, 0x262626, contacts.last, "Address")) + + container.panel.eventHandler = function(mainContainer, object, eventData) + if eventData[1] == "touch" then + if inputTextBox1.text and inputTextBox2.text then + local exists = false + for i = 1, #contacts do + if contacts[i].address == inputTextBox2.text then + exists = true + break + end + end + if not exists then + table.insert(contacts, {name = inputTextBox1.text, address = inputTextBox2.text}) + updateContacts() + saveContacts() + end + + container:delete() + mainContainer:draw() + buffer.draw() + end + end + end + + mainContainer:draw() + buffer.draw() +end + +mainContainer.removeContactButton = mainContainer:addChild(GUI.framedButton(x, y, width, 3, 0xEEEEEE, 0xEEEEEE, 0xBBBBBB, 0xBBBBBB, "Remove contact")); y = y + 4 +mainContainer.removeContactButton.onTouch = function() + if #contacts > 0 then + table.remove(contacts, mainContainer.contactsComboBox.selectedItem) + updateContacts() + saveContacts() + + mainContainer:draw() + buffer.draw() + end +end + +mainContainer:addChild(GUI.label(x, y, width, 1, 0xEEEEEE, "Energy to dial")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top); y = y + 2 +mainContainer.fuelProgressBar = mainContainer:addChild(GUI.progressBar(x, y, width, 0xBBBBBB, 0x0, 0xEEEEEE, 100, true, true, "", "%")); y = y + 3 +mainContainer.exitButton = mainContainer:addChild(GUI.framedButton(x, y, width, 3, 0xEEEEEE, 0xEEEEEE, 0xBBBBBB, 0xBBBBBB, "Exit")); y = y + 4 +mainContainer.exitButton.onTouch = function() + mainContainer:stopEventHandling() +end + +mainContainer.eventHandler = function(mainContainer, object, eventData) + if eventData[1] == "sgIrisStateChange" then + update() + mainContainer:draw() + buffer.draw() + elseif eventData[1] == "sgStargateStateChange" then + if eventData[3] == "Idle" or eventData[3] == "Connected" then + update() + updateChevrons(eventData[3] == "Connected") + mainContainer:draw() + buffer.draw() + end + elseif eventData[1] == "sgChevronEngaged" then + if mainContainer.chevrons[eventData[3]] then + mainContainer.chevrons[eventData[3]].isActivated = true + mainContainer.chevrons[eventData[3]].text = eventData[4] + mainContainer:draw() + buffer.draw() + end + elseif eventData[1] == "sgMessageReceived" then + GUI.error(tostring(eventData[3]), {title = {color = 0xBBBBBB, text = "Incoming message"}, backgroundColor = 0x262626}) + end +end + +loadContacts() +updateContacts() +update() +updateChevrons(stargate.stargateState() == "Connected") +mainContainer:draw() +buffer.draw() +mainContainer:startEventHandling() diff --git a/Applications/VK/VK.lua b/Applications/VK/VK.lua index dd5eeaab..7a61a5b5 100755 --- a/Applications/VK/VK.lua +++ b/Applications/VK/VK.lua @@ -53,13 +53,13 @@ local colors = { messsageInputBarTextColor = 0x262626, } -local leftBarHeight = buffer.screen.height - 9 -local leftBarWidth = math.floor(buffer.screen.width * 0.20) +local leftBarHeight = buffer.height - 9 +local leftBarWidth = math.floor(buffer.width * 0.20) local topBarHeight = 3 -local mainZoneWidth = buffer.screen.width - leftBarWidth -local mainZoneHeight = buffer.screen.height - topBarHeight - 1 +local mainZoneWidth = buffer.width - leftBarWidth +local mainZoneHeight = buffer.height - topBarHeight - 1 local mainZoneX = leftBarWidth + 1 local mainZoneY = topBarHeight + 1 @@ -311,7 +311,7 @@ local function loginGUI(startUsername, startPassword) local textFieldWidth = 50 local textFieldHeight = 3 - local x, y = math.floor(buffer.screen.width / 2 - textFieldWidth / 2), math.floor(buffer.screen.height / 2) + local x, y = math.floor(buffer.width / 2 - textFieldWidth / 2), math.floor(buffer.height / 2) local obj = {} obj.username = {x, y, x + textFieldWidth - 1, y + 2}; y = y + textFieldHeight + 1 @@ -369,8 +369,8 @@ local function drawPersonalAvatar(x, y, width, height) end local function status(text) - buffer.square(mainZoneX, buffer.screen.height, mainZoneWidth, 1, colors.statusBar) - buffer.text(mainZoneX + 1, buffer.screen.height, colors.statusBarText, text) + buffer.square(mainZoneX, buffer.height, mainZoneWidth, 1, colors.statusBar) + buffer.text(mainZoneX + 1, buffer.height, colors.statusBarText, text) buffer.draw() end @@ -444,7 +444,7 @@ local function getAttachments(messageArray) end local function drawMessageInputBar(currentText) - local x, y = mainZoneX, buffer.screen.height - 5 + local x, y = mainZoneX, buffer.height - 5 buffer.square(x, y, mainZoneWidth, 5, colors.messageInputBarColor) obj.messageInputBar = GUI.inputTextBox(x + 2, y + 1, mainZoneWidth - 4, 3, 0xFFFFFF, 0x444444, 0xFFFFFF, 0x262626, "", "Введите сообщение", true) obj.messageInputBar:draw() @@ -492,9 +492,9 @@ local function messagesGUI() buffer.setDrawLimit(mainZoneX, mainZoneY, mainZoneWidth, mainZoneHeight) - local y = buffer.screen.height - 7 + local y = buffer.height - 7 local xSender = mainZoneX + 2 - local xYou = buffer.screen.width - 7 + local xYou = buffer.width - 7 for i = 1, #messages.response.items do @@ -627,7 +627,7 @@ local function dialogsGUI() if dialogs.response.items[i].unread and dialogs.response.items[i].unread ~= 0 then local cyka = tostring(dialogs.response.items[i].unread) local cykaWidth = unicode.len(cyka) + 2 - local cykaX = buffer.screen.width - cykaWidth - 2 + local cykaX = buffer.width - cykaWidth - 2 buffer.square(cykaX, y + 2, cykaWidth, 1, ecs.colors.blue) buffer.text(cykaX + 1, y + 2, 0xFFFFFF, cyka) end @@ -752,7 +752,7 @@ local function userProfileGUI() local function drawInfo(x, y2, key, value) if checkField(value) then value = {value} - value = string.wrap(value, buffer.screen.width - x - 4 - informationOffset) + value = string.wrap(value, buffer.width - x - 4 - informationOffset) buffer.text(x, y2, informationKeyColor, key) for i = 1, #value do buffer.text(x + informationOffset, y2, informationValueColor, value[i]) @@ -764,7 +764,7 @@ local function userProfileGUI() local function drawSeparator(x, y2, text) buffer.text(x, y2, informationTitleColor, text) - buffer.text(x + unicode.len(text) + 1, y2, informationSeparatorColor, string.rep("─", buffer.screen.width - x - unicode.len(text))) + buffer.text(x + unicode.len(text) + 1, y2, informationSeparatorColor, string.rep("─", buffer.width - x - unicode.len(text))) y = y + 1 end @@ -794,7 +794,7 @@ local function userProfileGUI() -- А ВОТ И СТЕНОЧКА ПОДЪЕХАЛА НА ПРАЗДНИК ДУШИ y = y + 1 - buffer.square(x, y, buffer.screen.width - x - 2, 1, 0xCCCCCC); buffer.text(x + 1, y, 0x262626, "Стена"); y = y + 2 + buffer.square(x, y, buffer.width - x - 2, 1, 0xCCCCCC); buffer.text(x + 1, y, 0x262626, "Стена"); y = y + 2 --Перебираем всю стенку for i = 1, #currentProfile.wall.response.items do --Если это не репост или еще не хуйня какая-то @@ -803,10 +803,10 @@ local function userProfileGUI() drawAvatar(x, y, 6, 3, currentProfile.wall.response.items[i].from_id, unicode.sub(currentProfile.userNames[currentProfile.wall.response.items[i].from_id].first_name, 1, 1) .. unicode.sub(currentProfile.userNames[currentProfile.wall.response.items[i].from_id].last_name, 1, 1)) buffer.text(x + 8, y, informationValueColor, currentProfile.userNames[currentProfile.wall.response.items[i].from_id].first_name .. " " .. currentProfile.userNames[currentProfile.wall.response.items[i].from_id].last_name) local date = os.date("%d.%m.%y в %H:%M", currentProfile.wall.response.items[i].date) - buffer.text(buffer.screen.width - unicode.len(date) - 2, y, 0xCCCCCC, date) + buffer.text(buffer.width - unicode.len(date) - 2, y, 0xCCCCCC, date) y = y + 1 local text = {currentProfile.wall.response.items[i].text} - text = string.wrap(text, buffer.screen.width - x - 10) + text = string.wrap(text, buffer.width - x - 10) for i = 1, #text do buffer.text(x + 8, y, 0x000000, text[i]) y = y + 1 @@ -964,7 +964,7 @@ local function newsGUI() end end --Делаем его еще пизже - local text = {news.response.items[item].text}; text = string.wrap(text, buffer.screen.width - x - 10) + local text = {news.response.items[item].text}; text = string.wrap(text, buffer.width - x - 10) --Получаем инфу нужную local avatarText, name = getAvatarTextAndNameForNews(news.response.items[item].source_id) --Сместиться потом на стока вот @@ -1001,7 +1001,7 @@ end local function drawLeftBar() --Подложка под элементы - buffer.square(1, 1, leftBarWidth, buffer.screen.height, colors.leftBar, 0xFFFFFF, " ") + buffer.square(1, 1, leftBarWidth, buffer.height, colors.leftBar, 0xFFFFFF, " ") if personalInfo then drawPersonalAvatar(3, 2, 6, 3) diff --git a/Applications/Weather/Weather.lua b/Applications/Weather/Weather.lua index 28fb24dd..cd9a2954 100755 --- a/Applications/Weather/Weather.lua +++ b/Applications/Weather/Weather.lua @@ -13,6 +13,7 @@ local image = require("image") local unicode = require("unicode") local component = require("component") local GUI = require("GUI") +local MineOSCore = require("MineOSCore") ---------------------------------------------------- Константы ---------------------------------------------------------------- @@ -20,15 +21,16 @@ local weather = {} local changeCityButton = {} local exitButton = {} -local pathToWeatherFile = "MineOS/System/Weather/Forecast.cfg" +local resources = MineOSCore.getCurrentApplicationResourcesDirectory() +local pathToWeatherFile = "/MineOS/System/Weather/Forecast.cfg" local pathsToWeatherTypes = { - sunny = "MineOS/Applications/Weather.app/Resources/Sunny.pic", - sunnyWithClouds = "MineOS/Applications/Weather.app/Resources/SunnyWithClouds.pic", - snowy = "MineOS/Applications/Weather.app/Resources/Snowy.pic", - rainy = "MineOS/Applications/Weather.app/Resources/Rainy.pic", - cloudy = "MineOS/Applications/Weather.app/Resources/Cloudy.pic", - stormy = "MineOS/Applications/Weather.app/Resources/Stormy.pic", + sunny = resources .. "Sunny.pic", + sunnyWithClouds = resources .. "SunnyWithClouds.pic", + snowy = resources .. "Snowy.pic", + rainy = resources .. "Rainy.pic", + cloudy = resources .. "Cloudy.pic", + stormy = resources .. "Stormy.pic", } local weatherIcons = { @@ -177,15 +179,15 @@ end local function drawWeather() --Рисуем обоинку или просто говнофон ССАНЫЙ - if fs.exists(_G.OSSettings.wallpaper) then - buffer.image(1, 1, image.load(_G.OSSettings.wallpaper)) - buffer.square(1, 1, buffer.screen.width, buffer.screen.height, 0x0, 0x0, " ", 60) + if fs.exists(MineOSCore.OSSettings.wallpaper or "---aefaefaefaefae") then + buffer.image(1, 1, image.load(MineOSCore.OSSettings.wallpaper)) + buffer.square(1, 1, buffer.width, buffer.height, 0x0, 0x0, " ", 60) else buffer.clear(0x262626) end --Рисуем текущую температуру - local x, y = 10, buffer.screen.height - 25 + local x, y = 10, buffer.height - 25 bigLetters.drawText(x, y, 0xFFFFFF, weather.temperature, drawWithSymbol) y = y + 6 --Рисуем название города @@ -200,7 +202,7 @@ local function drawWeather() --Рисуем КНОПАЧКИ y = y + 2 changeCityButton = {buffer.button(x, y, 22, 1, 0xEEEEEE, 0x262626, "Другой город")} - exitButton = {buffer.button(buffer.screen.width - 4, 2, 3, 1, 0xEEEEEE, 0x262626, "X")} + exitButton = {buffer.button(buffer.width - 4, 2, 3, 1, 0xEEEEEE, 0x262626, "X")} --Рисуем долгосрочный прогноз y = y + 3 diff --git a/Applications/clear.lua b/Applications/clear.lua index f7ee9561..19f6961f 100644 --- a/Applications/clear.lua +++ b/Applications/clear.lua @@ -1,8 +1,8 @@ -local component = require("component") -local term = require("term") -component.gpu.setBackground(_G.OSSettings.shellBackground or 0x1B1B1B) -component.gpu.setForeground(_G.OSSettings.shellBackground or 0xEEEEEE) -local width, height = component.gpu.getResolution() -component.gpu.fill(1, 1, width, height, " ") -term.setCursor(1, 1) \ No newline at end of file +local gpu = require("component").gpu +gpu.setBackground(0x1B1B1B) +gpu.setForeground(0xEEEEEE) + +local width, height = gpu.getResolution() +gpu.fill(1, 1, width, height, " ") +require("term").setCursor(1, 1) \ No newline at end of file diff --git a/ImageConverter/.idea/workspace.xml b/ImageConverter/.idea/workspace.xml index 8a8e11f7..84259615 100644 --- a/ImageConverter/.idea/workspace.xml +++ b/ImageConverter/.idea/workspace.xml @@ -77,7 +77,7 @@ - + @@ -89,8 +89,8 @@ - - + + @@ -164,7 +164,7 @@ @@ -518,7 +518,7 @@ - - - + + + @@ -657,15 +657,15 @@ - - - + + + @@ -722,15 +722,15 @@ - - - + + + @@ -787,15 +787,15 @@ - - - + + + @@ -862,15 +862,15 @@ - - - + + + @@ -950,15 +950,15 @@ - - - + + + @@ -988,7 +988,7 @@ - + @@ -998,8 +998,8 @@ - - + + diff --git a/MineOS/Localization/English.lang b/MineOS/Localization/English.lang index 321f7875..158481bb 100644 --- a/MineOS/Localization/English.lang +++ b/MineOS/Localization/English.lang @@ -104,6 +104,7 @@ viewTab = "View", errorWhileRunningProgram = "Error while running ", + sendedFeedback = "Feedback was sent", sendFeedback = "Send feedback", yourContacts = "Your contacts", additionalInfo = "Additional information", diff --git a/MineOS/Localization/Russian.lang b/MineOS/Localization/Russian.lang index c2d43eae..29b5a1e2 100644 --- a/MineOS/Localization/Russian.lang +++ b/MineOS/Localization/Russian.lang @@ -104,6 +104,7 @@ viewTab = "Вид", errorWhileRunningProgram = "Ошибка при выполнении ", + sendedFeedback = "Отчет отправлен", sendFeedback = "Отправить отчет", yourContacts = "Ваши контакты", additionalInfo = "Дополнительная информация", diff --git a/MineOS/OS.lua b/MineOS/OS.lua index 0ada0a1a..bc23fec6 100755 --- a/MineOS/OS.lua +++ b/MineOS/OS.lua @@ -14,11 +14,11 @@ local copyright = [[ ]] -- Вычищаем копирайт из оперативки, ибо мы не можем тратить СТОЛЬКО памяти. --- Сколько тут, раз, два, три... 282 UTF-8 символа! --- А это, между прочим, 56 раз по слову "Пидор". Но один раз - не пидорас, поэтому очищаем. +-- Сколько тут, раз, два, три... 286 UTF-8 символов! +-- А это, между прочим, 57 раз по слову "Пидор". Но один раз - не пидорас, поэтому очищаем. copyright = nil ----------------------------------------------- Адаптивная загрузка библиотек ------------------------------------------------------------------------ +---------------------------------------------- Либсы-хуибсы ------------------------------------------------------------------------ -- package.loaded.MineOSCore = nil @@ -32,15 +32,15 @@ local GUI = require("GUI") local MineOSCore = require("MineOSCore") local ecs = require("ECSAPI") ----------------------------------------------- Базовые константы ------------------------------------------------------------------------ +---------------------------------------------- Всякая константная залупа ------------------------------------------------------------------------ local colors = { background = 0x1B1B1B, topBarTransparency = 20, selection = ecs.colors.lightBlue, interface = 0xCCCCCC, - dockBaseTransparency = 70, - dockTransparencyAdder = 10, + dockBaseTransparency = 60, + dockTransparencyAdder = 8, iconsSelectionTransparency = 20, desktopCounter = 0x999999, desktopCounterActive = 0xFFFFFF, @@ -54,18 +54,15 @@ local sizes = { } local screensaversPath, screensaverTimer = MineOSCore.paths.system .. "OS/Screensavers/", 0 - local currentWorkpathHistoryIndex, workpathHistory = 1, {MineOSCore.paths.desktop} -local workspace local currentDesktop, countOfDesktops = 1 - ---------------------------------------------- Система защиты пекарни ------------------------------------------------------------------------ local function drawBiometry(backgroundColor, textColor, text) local width, height = 70, 21 local fingerWidth, fingerHeight = 24, 14 - local x, y = math.floor(buffer.screen.width / 2 - width / 2), math.floor(buffer.screen.height / 2 - height / 2) + local x, y = math.floor(buffer.width / 2 - width / 2), math.floor(buffer.height / 2 - height / 2) buffer.square(x, y, width, height, backgroundColor, 0x000000, " ", nil) buffer.image(math.floor(x + width / 2 - fingerWidth / 2), y + 2, image.fromString([[180E0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 000000 000000 000000 000000 000000 000000 000000 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 000000 000000 000000 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 000000 000000 000000 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 000000 000000 000000 0000FF 0000FF 0000FF 0000FF 000000 000000 000000 000000 0000FF 0000FF 0000FF 0000FF 0000FF 000000 000000 0000FF 0000FF 0000FF 0000FF 0000FF 000000 000000 0000FF 0000FF 0000FF 000000 000000 000000 000000 0000FF 0000FF 000000 000000 000000 000000 0000FF 0000FF 0000FF 000000 000000 0000FF 0000FF 0000FF 000000 000000 0000FF 0000FF 0000FF 000000 000000 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 000000 000000 0000FF 0000FF 000000 0000FF 0000FF 000000 000000 0000FF 0000FF 0000FF 000000 000000 0000FF 0000FF 0000FF 000000 000000 000000 000000 000000 000000 0000FF 0000FF 000000 0000FF 0000FF 000000 000000 0000FF 000000 0000FF 0000FF 0000FF 000000 0000FF 0000FF 0000FF 0000FF 000000 000000 0000FF 0000FF 0000FF 0000FF 000000 000000 0000FF 000000 000000 0000FF 0000FF 000000 0000FF 000000 0000FF 0000FF 0000FF 000000 000000 0000FF 0000FF 000000 0000FF 0000FF 0000FF 000000 000000 0000FF 0000FF 000000 0000FF 0000FF 000000 0000FF 0000FF 000000 000000 0000FF 000000 0000FF 0000FF 0000FF 000000 0000FF 0000FF 000000 000000 0000FF 0000FF 0000FF 000000 0000FF 0000FF 000000 0000FF 0000FF 000000 0000FF 0000FF 000000 0000FF 0000FF 000000 000000 0000FF 0000FF 000000 0000FF 0000FF 0000FF 000000 0000FF 0000FF 0000FF 0000FF 0000FF 000000 000000 0000FF 000000 0000FF 0000FF 000000 000000 0000FF 0000FF 0000FF 000000 0000FF 0000FF 000000 000000 0000FF 0000FF 0000FF 000000 0000FF 0000FF 0000FF 0000FF 000000 0000FF 000000 0000FF 0000FF 0000FF 000000 0000FF 0000FF 0000FF 0000FF 000000 000000 0000FF 0000FF 000000 000000 0000FF 0000FF 000000 000000 0000FF 0000FF 0000FF 0000FF 000000 000000 0000FF 000000 000000 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 000000 000000 0000FF 0000FF 000000 000000 0000FF 0000FF 0000FF 0000FF 0000FF 000000 000000 000000 0000FF 000000 000000 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 000000 000000 0000FF 0000FF 000000 000000 0000FF 0000FF 0000FF 0000FF 000000 0000FF 0000FF 000000 000000 0000FF 0000FF 0000FF 0000FF 0000FF ]])) @@ -91,7 +88,7 @@ local function waitForBiometry(username) success = true end os.sleep(0.2) - workspace:draw() + MineOSCore.OSMainContainer:draw() buffer.draw() return success, e[6] end @@ -101,8 +98,8 @@ local function setBiometry() while true do local success, username = waitForBiometry() if success then - _G.OSSettings.protectionMethod = "biometric" - _G.OSSettings.passwordHash = require("SHA2").hash(username) + MineOSCore.OSSettings.protectionMethod = "biometric" + MineOSCore.OSSettings.passwordHash = require("SHA2").hash(username) MineOSCore.saveOSSettings() break end @@ -110,109 +107,117 @@ local function setBiometry() end local function checkPassword() - local container = GUI.addUniversalContainer(workspace, MineOSCore.localization.inputPassword) - local inputTextBox = container.layout:addInputTextBox(1, 1, 36, 3, 0xEEEEEE, 0x666666, 0xEEEEEE, 0x262626, nil, "Password", true, "*") - local label = container.layout:addLabel(1, 1, 36, 1, 0xFF4940, " "):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) + local container = MineOSCore.addUniversalContainer(MineOSCore.OSMainContainer, MineOSCore.localization.inputPassword) + local inputTextBox = container.layout:addChild(GUI.inputTextBox(1, 1, 36, 3, 0xEEEEEE, 0x666666, 0xEEEEEE, 0x262626, nil, "Password", true, "*")) + local label = container.layou:addChild(GUI.label(1, 1, 36, 1, 0xFF4940, " ")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) - container.panel.onTouch = function() - local hash = require("SHA2").hash(inputTextBox.text or "") - if hash == _G.OSSettings.passwordHash then - container:delete() - workspace:draw() - buffer.draw() - elseif hash == "c925be318b0530650b06d7f0f6a51d8289b5925f1b4117a43746bc99f1f81bc1" then - GUI.error(MineOSCore.localization.mineOSCreatorUsedMasterPassword) - container:delete() - workspace:draw() - buffer.draw() - else - label.text = MineOSCore.localization.incorrectPassword - workspace:draw() - buffer.draw() + container.panel.eventHandler = function(mainContainer, object, eventData) + if eventData[1] == "touch" then + local hash = require("SHA2").hash(inputTextBox.text or "") + if hash == MineOSCore.OSSettings.passwordHash then + container:delete() + MineOSCore.OSMainContainer:draw() + buffer.draw() + elseif hash == "c925be318b0530650b06d7f0f6a51d8289b5925f1b4117a43746bc99f1f81bc1" then + GUI.error(MineOSCore.localization.mineOSCreatorUsedMasterPassword) + container:delete() + MineOSCore.OSMainContainer:draw() + buffer.draw() + else + label.text = MineOSCore.localization.incorrectPassword + MineOSCore.OSMainContainer:draw() + buffer.draw() + end end end end local function setPassword() - local container = GUI.addUniversalContainer(workspace, MineOSCore.localization.passwordProtection) - local inputTextBox1 = container.layout:addInputTextBox(1, 1, 36, 3, 0xEEEEEE, 0x666666, 0xEEEEEE, 0x262626, nil, MineOSCore.localization.inputPassword, true, "*") - local inputTextBox2 = container.layout:addInputTextBox(1, 1, 36, 3, 0xEEEEEE, 0x666666, 0xEEEEEE, 0x262626, nil, MineOSCore.localization.confirmInputPassword, true, "*") - local label = container.layout:addLabel(1, 1, 36, 1, 0xFF4940, " "):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) + local container = MineOSCore.addUniversalContainer(MineOSCore.OSMainContainer, MineOSCore.localization.passwordProtection) + local inputTextBox1 = container.layout:addChild(GUI.inputTextBox(1, 1, 36, 3, 0xEEEEEE, 0x666666, 0xEEEEEE, 0x262626, nil, MineOSCore.localization.inputPassword, true, "*")) + local inputTextBox2 = container.layout:addChild(GUI.inputTextBox(1, 1, 36, 3, 0xEEEEEE, 0x666666, 0xEEEEEE, 0x262626, nil, MineOSCore.localization.confirmInputPassword, true, "*")) + local label = container.layou:addChild(GUI.label(1, 1, 36, 1, 0xFF4940, " ")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) - workspace:draw() + MineOSCore.OSMainContainer:draw() buffer.draw() - container.panel.onTouch = function() - if inputTextBox1.text == inputTextBox2.text then - container:delete() - - _G.OSSettings.protectionMethod = "password" - _G.OSSettings.passwordHash = require("SHA2").hash(inputTextBox1.text or "") - MineOSCore.saveOSSettings() - else - label.text = MineOSCore.localization.passwordsAreDifferent - end + container.panel.eventHandler = function(mainContainer, object, eventData) + if eventData[1] == "touch" then + if inputTextBox1.text == inputTextBox2.text then + container:delete() + + MineOSCore.OSSettings.protectionMethod = "password" + MineOSCore.OSSettings.passwordHash = require("SHA2").hash(inputTextBox1.text or "") + MineOSCore.saveOSSettings() + else + label.text = MineOSCore.localization.passwordsAreDifferent + end - workspace:draw() - buffer.draw() + MineOSCore.OSMainContainer:draw() + buffer.draw() + end end end local function setWithoutProtection() - _G.OSSettings.passwordHash = nil - _G.OSSettings.protectionMethod = "withoutProtection" + MineOSCore.OSSettings.passwordHash = nil + MineOSCore.OSSettings.protectionMethod = "withoutProtection" MineOSCore.saveOSSettings() end local function setProtectionMethod() - local container = GUI.addUniversalContainer(workspace, MineOSCore.localization.protectYourComputer) + local container = MineOSCore.addUniversalContainer(MineOSCore.OSMainContainer, MineOSCore.localization.protectYourComputer) - local comboBox = container.layout:addComboBox(1, 1, 36, 3, 0xEEEEEE, 0x262626, 0x666666, 0xEEEEEE) + local comboBox = container.layout:addChild(GUI.comboBox(1, 1, 36, 3, 0xEEEEEE, 0x262626, 0x666666, 0xEEEEEE)) comboBox:addItem(MineOSCore.localization.biometricProtection) comboBox:addItem(MineOSCore.localization.passwordProtection) comboBox:addItem(MineOSCore.localization.withoutProtection) - container.panel.onTouch = function() - container:delete() - workspace:draw() - buffer.draw() + container.panel.eventHandler = function(mainContainer, object, eventData) + if eventData[1] == "touch" then + container:delete() + MineOSCore.OSMainContainer:draw() + buffer.draw() - if comboBox.currentItem == 1 then - setBiometry() - elseif comboBox.currentItem == 2 then - setPassword() - elseif comboBox.currentItem == 3 then - setWithoutProtection() + if comboBox.selectedItem == 1 then + setBiometry() + elseif comboBox.selectedItem == 2 then + setPassword() + elseif comboBox.selectedItem == 3 then + setWithoutProtection() + end end end end local function login() event.interuptingEnabled = false - if not _G.OSSettings.protectionMethod then + if not MineOSCore.OSSettings.protectionMethod then setProtectionMethod() - elseif _G.OSSettings.protectionMethod == "password" then + elseif MineOSCore.OSSettings.protectionMethod == "password" then checkPassword() - elseif _G.OSSettings.protectionMethod == "biometric" then + elseif MineOSCore.OSSettings.protectionMethod == "biometric" then while true do - local success, username = waitForBiometry(_G.OSSettings.passwordHash) + local success, username = waitForBiometry(MineOSCore.OSSettings.passwordHash) if success then break end end end event.interuptingEnabled = true - workspace:draw() + MineOSCore.OSMainContainer:draw() buffer.draw() end ----------------------------------------------- Система нотификаций ------------------------------------------------------------------------ +---------------------------------------------- Винда-хуенда ------------------------------------------------------------------------ local function windows10() - if math.random(1, 100) > 25 or _G.OSSettings.showWindows10Upgrade == false then return end + if math.random(1, 100) > 25 or MineOSCore.OSSettings.showWindows10Upgrade == false then + return + end local width = 44 local height = 12 - local x = math.floor(buffer.screen.width / 2 - width / 2) + local x = math.floor(buffer.width / 2 - width / 2) local y = 2 local function draw(background) @@ -235,7 +240,7 @@ local function windows10() end local function disableUpdates() - _G.OSSettings.showWindows10Upgrade = false + MineOSCore.OSSettings.showWindows10Upgrade = false MineOSCore.saveOSSettings() end @@ -246,7 +251,7 @@ local function windows10() if ecs.clickedAtArea(eventData[3], eventData[4], x, y, x + width - 1, x + height - 1) then draw(0x0092FF) os.sleep(0.2) - workspace:draw() + MineOSCore.OSMainContainer:draw() buffer.draw() disableUpdates() return @@ -257,154 +262,156 @@ end ---------------------------------------------- Основные функции ------------------------------------------------------------------------ local function changeWallpaper() - if _G.OSSettings.wallpaper and fs.exists(_G.OSSettings.wallpaper) then - workspace.wallpaper.image = image.load(_G.OSSettings.wallpaper) - workspace.wallpaper.isHidden = false + if MineOSCore.OSSettings.wallpaper and fs.exists(MineOSCore.OSSettings.wallpaper) then + MineOSCore.OSMainContainer.wallpaper.image = image.load(MineOSCore.OSSettings.wallpaper) + MineOSCore.OSMainContainer.wallpaper.hidden = false else - workspace.wallpaper.image = nil - workspace.wallpaper.isHidden = true + MineOSCore.OSMainContainer.wallpaper.image = nil + MineOSCore.OSMainContainer.wallpaper.hidden = true end end local function changeWorkpath(newWorkpathHistoryIndex) currentDesktop = 1 currentWorkpathHistoryIndex = newWorkpathHistoryIndex - workspace.iconField.workpath = workpathHistory[currentWorkpathHistoryIndex] - workspace.background.onTouch = function(eventData) - if eventData[5] == 1 then - MineOSCore.emptyZoneClick(eventData, workspace, workspace.iconField.workpath) + MineOSCore.OSMainContainer.iconField.workpath = workpathHistory[currentWorkpathHistoryIndex] + MineOSCore.OSMainContainer.background.eventHandler = function(mainContainer, object, eventData) + if eventData[1] == "touch" then + if eventData[5] == 1 then + MineOSCore.emptyZoneClick(eventData, MineOSCore.OSMainContainer, MineOSCore.OSMainContainer.iconField.workpath) + end end end - workspace.wallpaper.onTouch = workspace.background.onTouch + MineOSCore.OSMainContainer.wallpaper.eventHandler = MineOSCore.OSMainContainer.background.eventHandler end local function updateDesktopCounters() - countOfDesktops = math.ceil(#workspace.iconField.fileList / workspace.iconField.iconCount.total) - workspace.desktopCounters.children = {} + countOfDesktops = math.ceil(#MineOSCore.OSMainContainer.iconField.fileList / MineOSCore.OSMainContainer.iconField.iconCount.total) + MineOSCore.OSMainContainer.desktopCounters.children = {} local x = 1 if #workpathHistory > 1 then - workspace.desktopCounters:addButton(x, 1, 1, 1, nil, 0xEEEEEE, nil, 0x888888, "<").onTouch = function() + MineOSCore.OSMainContainer.desktopCounters:addChild(GUI.button(x, 1, 1, 1, nil, 0xEEEEEE, nil, 0x888888, "<")).onTouch = function() table.remove(workpathHistory, #workpathHistory) changeWorkpath(#workpathHistory) - workspace.updateAndDraw() + MineOSCore.OSMainContainer.updateAndDraw() end; x = x + 3 end if workpathHistory[currentWorkpathHistoryIndex] ~= "/" then - workspace.desktopCounters:addButton(x, 1, 4, 1, nil, 0xEEEEEE, nil, 0x888888, "Root").onTouch = function() + MineOSCore.OSMainContainer.desktopCounters:addChild(GUI.button(x, 1, 4, 1, nil, 0xEEEEEE, nil, 0x888888, "Root")).onTouch = function() table.insert(workpathHistory, "/") changeWorkpath(#workpathHistory) - workspace.updateAndDraw() + MineOSCore.OSMainContainer.updateAndDraw() end; x = x + 6 end if workpathHistory[currentWorkpathHistoryIndex] ~= MineOSCore.paths.desktop then - workspace.desktopCounters:addButton(x, 1, 7, 1, nil, 0xEEEEEE, nil, 0x888888, "Desktop").onTouch = function() + MineOSCore.OSMainContainer.desktopCounters:addChild(GUI.button(x, 1, 7, 1, nil, 0xEEEEEE, nil, 0x888888, "Desktop")).onTouch = function() table.insert(workpathHistory, MineOSCore.paths.desktop) changeWorkpath(#workpathHistory) - workspace.updateAndDraw() + MineOSCore.OSMainContainer.updateAndDraw() end; x = x + 9 end if countOfDesktops > 1 then for i = 1, countOfDesktops do - workspace.desktopCounters:addButton(x, 1, 1, 1, nil, i == currentDesktop and 0xEEEEEE or 0xBBBBBB, nil, 0x888888, "●").onTouch = function() + MineOSCore.OSMainContainer.desktopCounters:addChild(GUI.button(x, 1, 1, 1, nil, i == currentDesktop and 0xEEEEEE or 0xBBBBBB, nil, 0x888888, "●")).onTouch = function() if currentDesktop ~= i then currentDesktop = i - workspace.updateAndDraw() + MineOSCore.OSMainContainer.updateAndDraw() end end; x = x + 3 end end - workspace.desktopCounters.width = x - 3 - workspace.desktopCounters.localPosition.x = math.floor(workspace.width / 2 - workspace.desktopCounters.width / 2) - workspace.desktopCounters.localPosition.y = workspace.height - sizes.heightOfDock - 2 + MineOSCore.OSMainContainer.desktopCounters.width = x - 3 + MineOSCore.OSMainContainer.desktopCounters.localPosition.x = math.floor(MineOSCore.OSMainContainer.width / 2 - MineOSCore.OSMainContainer.desktopCounters.width / 2) + MineOSCore.OSMainContainer.desktopCounters.localPosition.y = MineOSCore.OSMainContainer.height - sizes.heightOfDock - 2 end local function updateDock() local function moveDockShortcut(iconIndex, direction) - _G.OSSettings.dockShortcuts[iconIndex], _G.OSSettings.dockShortcuts[iconIndex + direction] = swap(_G.OSSettings.dockShortcuts[iconIndex], _G.OSSettings.dockShortcuts[iconIndex + direction]) + MineOSCore.OSSettings.dockShortcuts[iconIndex], MineOSCore.OSSettings.dockShortcuts[iconIndex + direction] = swap(MineOSCore.OSSettings.dockShortcuts[iconIndex], MineOSCore.OSSettings.dockShortcuts[iconIndex + direction]) MineOSCore.saveOSSettings() updateDock() - workspace:draw() + MineOSCore.OSMainContainer:draw() buffer.draw() end - workspace.dockContainer.width = (#_G.OSSettings.dockShortcuts + 1) * (MineOSCore.iconWidth + sizes.xSpaceBetweenIcons) - sizes.xSpaceBetweenIcons - workspace.dockContainer.localPosition.x = math.floor(workspace.width / 2 - workspace.dockContainer.width / 2) - workspace.dockContainer.localPosition.y = workspace.height - sizes.heightOfDock + 1 - workspace.dockContainer:deleteChildren() + MineOSCore.OSMainContainer.dockContainer.width = (#MineOSCore.OSSettings.dockShortcuts + 1) * (MineOSCore.iconWidth + sizes.xSpaceBetweenIcons) - sizes.xSpaceBetweenIcons + MineOSCore.OSMainContainer.dockContainer.localPosition.x = math.floor(MineOSCore.OSMainContainer.width / 2 - MineOSCore.OSMainContainer.dockContainer.width / 2) + MineOSCore.OSMainContainer.dockContainer.localPosition.y = MineOSCore.OSMainContainer.height - sizes.heightOfDock + 1 + MineOSCore.OSMainContainer.dockContainer:deleteChildren() local xPos = 1 - for iconIndex = 1, #_G.OSSettings.dockShortcuts do - local icon = MineOSCore.createIcon(xPos, 1, _G.OSSettings.dockShortcuts[iconIndex].path, 0x262626, _G.OSSettings.showExtension) + for iconIndex = 1, #MineOSCore.OSSettings.dockShortcuts do + local icon = MineOSCore.createIcon(xPos, 1, MineOSCore.OSSettings.dockShortcuts[iconIndex].path, 0x262626, MineOSCore.OSSettings.showExtension, 0xFFFFFF) icon.onRightClick = function(icon, eventData) local menu = GUI.contextMenu(eventData[3], eventData[4]) menu:addItem(MineOSCore.localization.contextMenuShowContainingFolder).onTouch = function() table.insert(workpathHistory, fs.path(icon.path)) changeWorkpath(#workpathHistory) - workspace.updateAndDraw() + MineOSCore.OSMainContainer.updateAndDraw() end menu:addSeparator() - menu:addItem(MineOSCore.localization.contextMenuMoveRight, iconIndex >= #_G.OSSettings.dockShortcuts).onTouch = function() + menu:addItem(MineOSCore.localization.contextMenuMoveRight, iconIndex >= #MineOSCore.OSSettings.dockShortcuts).onTouch = function() moveDockShortcut(iconIndex, 1) end menu:addItem(MineOSCore.localization.contextMenuMoveLeft, iconIndex <= 1).onTouch = function() moveDockShortcut(iconIndex, -1) end menu:addSeparator() - menu:addItem(MineOSCore.localization.contextMenuRemoveFromDock, _G.OSSettings.dockShortcuts[iconIndex].canNotBeDeleted or #_G.OSSettings.dockShortcuts < 2).onTouch = function() - table.remove(_G.OSSettings.dockShortcuts, iconIndex) + menu:addItem(MineOSCore.localization.contextMenuRemoveFromDock, MineOSCore.OSSettings.dockShortcuts[iconIndex].canNotBeDeleted or #MineOSCore.OSSettings.dockShortcuts < 2).onTouch = function() + table.remove(MineOSCore.OSSettings.dockShortcuts, iconIndex) MineOSCore.saveOSSettings() updateDock() - workspace:draw() + MineOSCore.OSMainContainer:draw() buffer.draw() end menu:show() end - workspace.dockContainer:addChild(icon, GUI.objectTypes.container) + MineOSCore.OSMainContainer.dockContainer:addChild(icon) xPos = xPos + MineOSCore.iconWidth + sizes.xSpaceBetweenIcons end - local icon = MineOSCore.createIcon(xPos, 1, MineOSCore.paths.trash, 0x262626, _G.OSSettings.showExtension) + local icon = MineOSCore.createIcon(xPos, 1, MineOSCore.paths.trash, 0x262626, MineOSCore.OSSettings.showExtension, 0xFFFFFF) icon.iconImage.image = MineOSCore.icons.trash icon.onRightClick = function(icon, eventData) local menu = GUI.contextMenu(eventData[3], eventData[4]) menu:addItem(MineOSCore.localization.emptyTrash).onTouch = function() - local container = GUI.addUniversalContainer(workspace, MineOSCore.localization.areYouSure) + local container = MineOSCore.addUniversalContainer(MineOSCore.OSMainContainer, MineOSCore.localization.areYouSure) - container.layout:addButton(1, 1, 30, 3, 0xEEEEEE, 0x262626, 0xA, 0x262626, "OK").onTouch = function() + container.layout:addChild(GUI.button(1, 1, 30, 3, 0xEEEEEE, 0x262626, 0xA, 0x262626, "OK")).onTouch = function() for file in fs.list(MineOSCore.paths.trash) do fs.remove(MineOSCore.paths.trash .. file) end container:delete() - workspace.updateAndDraw() + MineOSCore.OSMainContainer.updateAndDraw() end container.panel.onTouch = function() container:delete() - workspace:draw() + MineOSCore.OSMainContainer:draw() buffer.draw() end - workspace:draw() + MineOSCore.OSMainContainer:draw() buffer.draw() end menu:show() end - workspace.dockContainer:addChild(icon, GUI.objectTypes.container) + MineOSCore.OSMainContainer.dockContainer:addChild(icon) end -- Отрисовка дока local function createDock() - workspace.dockContainer = workspace:addContainer(1, 1, workspace.width, sizes.heightOfDock) + MineOSCore.OSMainContainer.dockContainer = MineOSCore.OSMainContainer:addChild(GUI.container(1, 1, MineOSCore.OSMainContainer.width, sizes.heightOfDock)) -- Отрисовка дока - local oldDraw = workspace.dockContainer.draw - workspace.dockContainer.draw = function(dockContainer) + local oldDraw = MineOSCore.OSMainContainer.dockContainer.draw + MineOSCore.OSMainContainer.dockContainer.draw = function(dockContainer) local currentDockTransparency, currentDockWidth, xPos, yPos = colors.dockBaseTransparency, dockContainer.width, dockContainer.x, dockContainer.y + 2 - local color = _G.OSSettings.interfaceColor or colors.interface + local color = MineOSCore.OSSettings.interfaceColor or colors.interface for i = 1, dockContainer.height do buffer.text(xPos, yPos, color, "▟", currentDockTransparency) buffer.square(xPos + 1, yPos, currentDockWidth - 2, 1, color, 0xFFFFFF, " ", currentDockTransparency) @@ -419,56 +426,54 @@ end local function changeResolution() currentDesktop = 1 - buffer.setResolution(table.unpack(_G.OSSettings.resolution or {160, 50})) + buffer.setResolution(table.unpack(MineOSCore.OSSettings.resolution or {160, 50})) - workspace.width, workspace.height = buffer.screen.width, buffer.screen.height + MineOSCore.OSMainContainer.width, MineOSCore.OSMainContainer.height = buffer.width, buffer.height - workspace.iconField.iconCount.width, workspace.iconField.iconCount.height, workspace.iconField.iconCount.total = MineOSCore.getParametersForDrawingIcons(workspace.width, workspace.height - sizes.heightOfDock - 5, sizes.xSpaceBetweenIcons, sizes.ySpaceBetweenIcons) - workspace.iconField.localPosition.x = math.floor(workspace.width / 2 - (workspace.iconField.iconCount.width * (MineOSCore.iconWidth + sizes.xSpaceBetweenIcons) - sizes.xSpaceBetweenIcons) / 2) - workspace.iconField.localPosition.y = 3 + MineOSCore.OSMainContainer.iconField.width, MineOSCore.OSMainContainer.iconField.height = MineOSCore.OSMainContainer.width, MineOSCore.OSMainContainer.height - sizes.heightOfDock - 5 + MineOSCore.OSMainContainer.iconField.iconCount.width, MineOSCore.OSMainContainer.iconField.iconCount.height, MineOSCore.OSMainContainer.iconField.iconCount.total = MineOSCore.getParametersForDrawingIcons(MineOSCore.OSMainContainer.iconField.width, MineOSCore.OSMainContainer.iconField.height, sizes.xSpaceBetweenIcons, sizes.ySpaceBetweenIcons) + MineOSCore.OSMainContainer.iconField.localPosition.x = math.floor(MineOSCore.OSMainContainer.width / 2 - (MineOSCore.OSMainContainer.iconField.iconCount.width * (MineOSCore.iconWidth + sizes.xSpaceBetweenIcons) - sizes.xSpaceBetweenIcons) / 2) + MineOSCore.OSMainContainer.iconField.localPosition.y = 3 - workspace.menu.width = workspace.width - workspace.background.width, workspace.background.height = workspace.width, workspace.height + MineOSCore.OSMainContainer.menu.width = MineOSCore.OSMainContainer.width + MineOSCore.OSMainContainer.background.width, MineOSCore.OSMainContainer.background.height = MineOSCore.OSMainContainer.width, MineOSCore.OSMainContainer.height + + MineOSCore.OSMainContainer.windowsContainer.width, MineOSCore.OSMainContainer.windowsContainer.height = MineOSCore.OSMainContainer.width, MineOSCore.OSMainContainer.height - 1 end -local function createWorkspace() - workspace = GUI.fullScreenWindow() - workspace.background = workspace:addPanel(1, 1, workspace.width, workspace.height, _G.OSSettings.backgroundColor or colors.background) - workspace.wallpaper = workspace:addImage(1, 1, {workspace.width, workspace.height}) +local function createOSWindow() + MineOSCore.OSMainContainer = GUI.fullScreenContainer() + MineOSCore.OSMainContainer.background = MineOSCore.OSMainContainer:addChild(GUI.panel(1, 1, MineOSCore.OSMainContainer.width, MineOSCore.OSMainContainer.height, MineOSCore.OSSettings.backgroundColor or colors.background)) + MineOSCore.OSMainContainer.wallpaper = MineOSCore.OSMainContainer:addChild(GUI.image(1, 1, {MineOSCore.OSMainContainer.width, MineOSCore.OSMainContainer.height})) - workspace.desktopCounters = workspace:addContainer(1, 1, 1, 1) + MineOSCore.OSMainContainer.desktopCounters = MineOSCore.OSMainContainer:addChild(GUI.container(1, 1, 1, 1)) - workspace.iconField = workspace:addChild( + MineOSCore.OSMainContainer.iconField = MineOSCore.OSMainContainer:addChild( MineOSCore.createIconField( 1, 1, 1, 1, 1, 1, 1, sizes.xSpaceBetweenIcons, sizes.ySpaceBetweenIcons, 0xFFFFFF, - _G.OSSettings.showExtension == nil and true or _G.OSSettings.showExtension, - _G.OSSettings.showHiddenFiles == nil and true or _G.OSSettings.showHiddenFiles, - (_G.OSSettings.sortingMethod or "type"), - "/" - ), - GUI.objectTypes.container + MineOSCore.OSSettings.showExtension or true, + MineOSCore.OSSettings.showHiddenFiles or true, + MineOSCore.OSSettings.sortingMethod or "type", + "/", + 0xFFFFFF + ) ) createDock() + MineOSCore.OSMainContainer.windowsContainer = MineOSCore.OSMainContainer:addChild(GUI.container(1, 2, 1, 1)) - workspace.menu = workspace:addMenu(1, 1, workspace.width, _G.OSSettings.interfaceColor or colors.interface, 0x444444, 0x3366CC, 0xFFFFFF, colors.topBarTransparency) - local item1 = workspace.menu:addItem("MineOS", 0x000000) + MineOSCore.OSMainContainer.menu = MineOSCore.OSMainContainer:addChild(GUI.menu(1, 1, MineOSCore.OSMainContainer.width, MineOSCore.OSSettings.interfaceColor or colors.interface, 0x444444, 0x3366CC, 0xFFFFFF, colors.topBarTransparency)) + local item1 = MineOSCore.OSMainContainer.menu:addItem("MineOS", 0x000000) item1.onTouch = function() local menu = GUI.contextMenu(item1.x, item1.y + 1) - -- menu:addItem(MineOSCore.localization.aboutSystem).onTouch = function() - -- ecs.prepareToExit() - -- print(copyright) - -- ecs.waitForTouchOrClick() - -- buffer.draw(true) - -- end menu:addItem(MineOSCore.localization.updates).onTouch = function() - MineOSCore.safeLaunch("/MineOS/Applications/AppMarket.app/Main.lua", "updateCheck") + MineOSCore.safeLaunch("/MineOS/Applications/AppMarket.app/Main.lua", "updates") end menu:addSeparator() - menu:addItem(MineOSCore.localization.logout, _G.OSSettings.protectionMethod == "withoutProtection").onTouch = function() + menu:addItem(MineOSCore.localization.logout, MineOSCore.OSSettings.protectionMethod == "withoutProtection").onTouch = function() login() end menu:addItem(MineOSCore.localization.reboot).onTouch = function() @@ -482,135 +487,141 @@ local function createWorkspace() end menu:addSeparator() menu:addItem(MineOSCore.localization.returnToShell).onTouch = function() - workspace:close() + MineOSCore.OSMainContainer:stopEventHandling() ecs.prepareToExit() os.exit() end menu:show() end - local item2 = workspace.menu:addItem(MineOSCore.localization.viewTab) + local item2 = MineOSCore.OSMainContainer.menu:addItem(MineOSCore.localization.viewTab) item2.onTouch = function() local menu = GUI.contextMenu(item2.x, item2.y + 1) - menu:addItem(workspace.iconField.showExtension and MineOSCore.localization.hideExtension or MineOSCore.localization.showExtension).onTouch = function() - workspace.iconField.showExtension = not workspace.iconField.showExtension - _G.OSSettings.showExtension = workspace.iconField.showExtension + menu:addItem(MineOSCore.OSMainContainer.iconField.showExtension and MineOSCore.localization.hideExtension or MineOSCore.localization.showExtension).onTouch = function() + MineOSCore.OSMainContainer.iconField.showExtension = not MineOSCore.OSMainContainer.iconField.showExtension + MineOSCore.OSSettings.showExtension = MineOSCore.OSMainContainer.iconField.showExtension MineOSCore.saveOSSettings() - workspace.updateAndDraw() + MineOSCore.OSMainContainer.updateAndDraw() end - menu:addItem(workspace.iconField.showHiddenFiles and MineOSCore.localization.hideHiddenFiles or MineOSCore.localization.showHiddenFiles).onTouch = function() - workspace.iconField.showHiddenFiles = not workspace.iconField.showHiddenFiles - _G.OSSettings.showHiddenFiles = workspace.iconField.showHiddenFiles + menu:addItem(MineOSCore.OSMainContainer.iconField.showHiddenFiles and MineOSCore.localization.hideHiddenFiles or MineOSCore.localization.showHiddenFiles).onTouch = function() + MineOSCore.OSMainContainer.iconField.showHiddenFiles = not MineOSCore.OSMainContainer.iconField.showHiddenFiles + MineOSCore.OSSettings.showHiddenFiles = MineOSCore.OSMainContainer.iconField.showHiddenFiles MineOSCore.saveOSSettings() - workspace.updateAndDraw() + MineOSCore.OSMainContainer.updateAndDraw() end menu:addItem(MineOSCore.showApplicationIcons and MineOSCore.localization.hideApplicationIcons or MineOSCore.localization.showApplicationIcons).onTouch = function() MineOSCore.showApplicationIcons = not MineOSCore.showApplicationIcons - workspace.updateAndDraw() + MineOSCore.OSMainContainer.updateAndDraw() end menu:addSeparator() menu:addItem(MineOSCore.localization.sortByName).onTouch = function() - _G.OSSettings.sortingMethod = "name" + MineOSCore.OSSettings.sortingMethod = "name" MineOSCore.saveOSSettings() - workspace.iconField.sortingMethod = _G.OSSettings.sortingMethod - workspace.updateAndDraw() + MineOSCore.OSMainContainer.iconField.sortingMethod = MineOSCore.OSSettings.sortingMethod + MineOSCore.OSMainContainer.updateAndDraw() end menu:addItem(MineOSCore.localization.sortByDate).onTouch = function() - _G.OSSettings.sortingMethod = "date" + MineOSCore.OSSettings.sortingMethod = "date" MineOSCore.saveOSSettings() - workspace.iconField.sortingMethod = _G.OSSettings.sortingMethod - workspace.updateAndDraw() + MineOSCore.OSMainContainer.iconField.sortingMethod = MineOSCore.OSSettings.sortingMethod + MineOSCore.OSMainContainer.updateAndDraw() end menu:addItem(MineOSCore.localization.sortByType).onTouch = function() - _G.OSSettings.sortingMethod = "type" + MineOSCore.OSSettings.sortingMethod = "type" MineOSCore.saveOSSettings() - workspace.iconField.sortingMethod = _G.OSSettings.sortingMethod - workspace.updateAndDraw() + MineOSCore.OSMainContainer.iconField.sortingMethod = MineOSCore.OSSettings.sortingMethod + MineOSCore.OSMainContainer.updateAndDraw() end menu:addSeparator() menu:addItem(MineOSCore.localization.screensaver).onTouch = function() - local container = GUI.addUniversalContainer(workspace, MineOSCore.localization.screensaver) + local container = MineOSCore.addUniversalContainer(MineOSCore.OSMainContainer, MineOSCore.localization.screensaver) - local comboBox = container.layout:addComboBox(1, 1, 36, 3, 0xEEEEEE, 0x262626, 0x666666, 0xEEEEEE) + local comboBox = container.layout:addChild(GUI.comboBox(1, 1, 36, 3, 0xEEEEEE, 0x262626, 0x666666, 0xEEEEEE)) comboBox:addItem(MineOSCore.localization.screensaverDisabled) for file in fs.list(screensaversPath) do comboBox:addItem(fs.hideExtension(file)) end - local slider = container.layout:addHorizontalSlider(1, 1, 36, 0xFFDB40, 0xEEEEEE, 0xFFDB80, 0xBBBBBB, 1, 100, _G.OSSettings.screensaverDelay or 20, false, MineOSCore.localization.screensaverDelay .. ": ", "") + local slider = container.layout:addChild(GUI.slider(1, 1, 36, 0xFFDB40, 0xEEEEEE, 0xFFDB80, 0xBBBBBB, 1, 100, MineOSCore.OSSettings.screensaverDelay or 20, false, MineOSCore.localization.screensaverDelay .. ": ", "")) - workspace:draw() + MineOSCore.OSMainContainer:draw() buffer.draw() - container.panel.onTouch = function() - container:delete() - if comboBox.currentItem == 1 then - _G.OSSettings.screensaver = nil - else - _G.OSSettings.screensaver, _G.OSSettings.screensaverDelay = comboBox.items[comboBox.currentItem].text, slider.value - end - MineOSCore.saveOSSettings() + container.panel.eventHandler = function(mainContainer, object, eventData) + if eventData[1] == "touch" then + container:delete() + if comboBox.selectedItem == 1 then + MineOSCore.OSSettings.screensaver = nil + else + MineOSCore.OSSettings.screensaver, MineOSCore.OSSettings.screensaverDelay = comboBox.items[comboBox.selectedItem].text, slider.value + end + MineOSCore.saveOSSettings() - workspace:draw() - buffer.draw() + MineOSCore.OSMainContainer:draw() + buffer.draw() + end end end menu:addItem(MineOSCore.localization.colorScheme).onTouch = function() - local container = GUI.addUniversalContainer(workspace, MineOSCore.localization.colorScheme) + local container = MineOSCore.addUniversalContainer(MineOSCore.OSMainContainer, MineOSCore.localization.colorScheme) - local backgroundColorSelector = container.layout:addColorSelector(1, 1, 36, 3, workspace.background.colors.background, MineOSCore.localization.backgroundColor) - local interfaceColorSelector = container.layout:addColorSelector(1, 1, 36, 3, workspace.menu.colors.default.background, MineOSCore.localization.interfaceColor) + local backgroundColorSelector = container.layout:addChild(GUI.colorSelector(1, 1, 36, 3, MineOSCore.OSMainContainer.background.colors.background, MineOSCore.localization.backgroundColor)) + local interfaceColorSelector = container.layout:addChild(GUI.colorSelector(1, 1, 36, 3, MineOSCore.OSMainContainer.menu.colors.default.background, MineOSCore.localization.interfaceColor)) backgroundColorSelector.onTouch = function() - _G.OSSettings.backgroundColor, _G.OSSettings.interfaceColor = backgroundColorSelector.color, interfaceColorSelector.color - workspace.background.colors.background, workspace.menu.colors.default.background = _G.OSSettings.backgroundColor, _G.OSSettings.interfaceColor + MineOSCore.OSSettings.backgroundColor, MineOSCore.OSSettings.interfaceColor = backgroundColorSelector.color, interfaceColorSelector.color + MineOSCore.OSMainContainer.background.colors.background, MineOSCore.OSMainContainer.menu.colors.default.background = MineOSCore.OSSettings.backgroundColor, MineOSCore.OSSettings.interfaceColor MineOSCore.saveOSSettings() - workspace:draw() + MineOSCore.OSMainContainer:draw() buffer.draw() end interfaceColorSelector.onTouch = backgroundColorSelector.onTouch - workspace:draw() + MineOSCore.OSMainContainer:draw() buffer.draw() - container.panel.onTouch = function() - container:delete() - workspace:draw() - buffer.draw() + container.panel.eventHandler = function(mainContainer, object, eventData) + if eventData[1] == "touch" then + container:delete() + MineOSCore.OSMainContainer:draw() + buffer.draw() + end end end - menu:addItem(MineOSCore.localization.contextMenuRemoveWallpaper, workspace.wallpaper.isHidden).onTouch = function() - _G.OSSettings.wallpaper = nil + menu:addItem(MineOSCore.localization.contextMenuRemoveWallpaper, MineOSCore.OSMainContainer.wallpaper.hidden).onTouch = function() + MineOSCore.OSSettings.wallpaper = nil MineOSCore.saveOSSettings() changeWallpaper() end menu:show() end - local item3 = workspace.menu:addItem(MineOSCore.localization.settings) + local item3 = MineOSCore.OSMainContainer.menu:addItem(MineOSCore.localization.settings) item3.onTouch = function() local menu = GUI.contextMenu(item3.x, item3.y + 1) menu:addItem(MineOSCore.localization.screenResolution).onTouch = function() - local container = GUI.addUniversalContainer(workspace, MineOSCore.localization.screenResolution) + local container = MineOSCore.addUniversalContainer(MineOSCore.OSMainContainer, MineOSCore.localization.screenResolution) - local widthTextBox = container.layout:addInputTextBox(1, 1, 36, 3, 0xEEEEEE, 0x666666, 0xEEEEEE, 0x262626, tostring(_G.OSSettings.resolution and _G.OSSettings.resolution[1] or 160), "Width", true) + local widthTextBox = container.layout:addChild(GUI.inputTextBox(1, 1, 36, 3, 0xEEEEEE, 0x666666, 0xEEEEEE, 0x262626, tostring(MineOSCore.OSSettings.resolution and MineOSCore.OSSettings.resolution[1] or 160), "Width", true)) widthTextBox.validator = function(text) local number = tonumber(text) if number then return number >= 1 and number <= 160 end end - local heightTextBox = container.layout:addInputTextBox(1, 1, 36, 3, 0xEEEEEE, 0x666666, 0xEEEEEE, 0x262626, tostring(_G.OSSettings.resolution and _G.OSSettings.resolution[2] or 50), "Height", true) + local heightTextBox = container.layout:addChild(GUI.inputTextBox(1, 1, 36, 3, 0xEEEEEE, 0x666666, 0xEEEEEE, 0x262626, tostring(MineOSCore.OSSettings.resolution and MineOSCore.OSSettings.resolution[2] or 50), "Height", true)) heightTextBox.validator = function(text) local number = tonumber(text) if number then return number >= 1 and number <= 50 end end - container.panel.onTouch = function() - container:delete() - _G.OSSettings.resolution = {tonumber(widthTextBox.text), tonumber(heightTextBox.text)} - MineOSCore.saveOSSettings() - changeResolution() - workspace.updateAndDraw() + container.panel.eventHandler = function(mainContainer, object, eventData) + if eventData[1] == "touch" then + container:delete() + MineOSCore.OSSettings.resolution = {tonumber(widthTextBox.text), tonumber(heightTextBox.text)} + MineOSCore.saveOSSettings() + changeResolution() + MineOSCore.OSMainContainer.updateAndDraw() + end end end menu:addSeparator() @@ -620,61 +631,61 @@ local function createWorkspace() menu:show() end - workspace.update = function() - workspace.iconField.fromFile = (currentDesktop - 1) * workspace.iconField.iconCount.total + 1 - workspace.iconField:updateFileList() + MineOSCore.OSMainContainer.update = function() + MineOSCore.OSMainContainer.iconField.fromFile = (currentDesktop - 1) * MineOSCore.OSMainContainer.iconField.iconCount.total + 1 + MineOSCore.OSMainContainer.iconField:updateFileList() updateDock() updateDesktopCounters() end - workspace.updateAndDraw = function(forceRedraw) - workspace.update() - workspace:draw() + MineOSCore.OSMainContainer.updateAndDraw = function(forceRedraw) + MineOSCore.OSMainContainer.update() + MineOSCore.OSMainContainer:draw() buffer.draw(forceRedraw) end - workspace.onAnyEvent = function(eventData) + MineOSCore.OSMainContainer.eventHandler = function(mainContainer, object, eventData) if eventData[1] == "scroll" then if eventData[5] == 1 then if currentDesktop < countOfDesktops then currentDesktop = currentDesktop + 1 - workspace.updateAndDraw() + MineOSCore.OSMainContainer.updateAndDraw() end else if currentDesktop > 1 then currentDesktop = currentDesktop - 1 - workspace.updateAndDraw() + MineOSCore.OSMainContainer.updateAndDraw() end end elseif eventData[1] == "MineOSCore" then if eventData[2] == "updateFileList" then - workspace.updateAndDraw() + MineOSCore.OSMainContainer.updateAndDraw() elseif eventData[2] == "updateFileListAndBufferTrueRedraw" then - workspace.updateAndDraw(true) + MineOSCore.OSMainContainer.updateAndDraw(true) elseif eventData[2] == "changeWorkpath" then table.insert(workpathHistory, eventData[3]) changeWorkpath(#workpathHistory) elseif eventData[2] == "updateWallpaper" then changeWallpaper() - workspace:draw() + MineOSCore.OSMainContainer:draw() buffer.draw() elseif eventData[2] == "newApplication" then - MineOSCore.newApplication(workspace, workspace.iconField.workpath) + MineOSCore.newApplication(MineOSCore.OSMainContainer, MineOSCore.OSMainContainer.iconField.workpath) elseif eventData[2] == "newFile" then - MineOSCore.newFile(workspace, workspace.iconField.workpath) + MineOSCore.newFile(MineOSCore.OSMainContainer, MineOSCore.OSMainContainer.iconField.workpath) elseif eventData[2] == "newFolder" then - MineOSCore.newFolder(workspace, workspace.iconField.workpath) + MineOSCore.newFolder(MineOSCore.OSMainContainer, MineOSCore.OSMainContainer.iconField.workpath) elseif eventData[2] == "rename" then - MineOSCore.rename(workspace, eventData[3]) + MineOSCore.rename(MineOSCore.OSMainContainer, eventData[3]) elseif eventData[2] == "applicationHelp" then - MineOSCore.applicationHelp(workspace, eventData[3]) + MineOSCore.applicationHelp(MineOSCore.OSMainContainer, eventData[3]) end elseif not eventData[1] then screensaverTimer = screensaverTimer + 0.5 - if _G.OSSettings.screensaver and screensaverTimer > _G.OSSettings.screensaverDelay and fs.exists(screensaversPath .. _G.OSSettings.screensaver .. ".lua") then - MineOSCore.safeLaunch(screensaversPath .. _G.OSSettings.screensaver .. ".lua") + if MineOSCore.OSSettings.screensaver and screensaverTimer > MineOSCore.OSSettings.screensaverDelay and fs.exists(screensaversPath .. MineOSCore.OSSettings.screensaver .. ".lua") then + MineOSCore.safeLaunch(screensaversPath .. MineOSCore.OSSettings.screensaver .. ".lua") screensaverTimer = 0 - workspace:draw() + MineOSCore.OSMainContainer:draw() buffer.draw(true) end else @@ -685,14 +696,31 @@ end ---------------------------------------------- Сама ОС ------------------------------------------------------------------------ -createWorkspace() +createOSWindow() changeResolution() changeWorkpath(1) changeWallpaper() -workspace.update() +MineOSCore.OSMainContainer.update() login() windows10() -workspace:handleEvents(0.5) + +while true do + local success, path, line, traceback = MineOSCore.call(MineOSCore.OSMainContainer.startEventHandling, MineOSCore.OSMainContainer, 1) + if success then + break + else + buffer.start() + changeResolution() + MineOSCore.OSMainContainer.windowsContainer:deleteChildren() + -- MineOSCore.OSMainContainer:draw() + -- buffer.draw() + + -- MineOSCore.showErrorWindow(path, line, traceback) + + MineOSCore.OSMainContainer:draw() + buffer.draw() + end +end diff --git a/lib/ECSAPI.lua b/lib/ECSAPI.lua index 2f011cb4..b30b376f 100755 --- a/lib/ECSAPI.lua +++ b/lib/ECSAPI.lua @@ -2038,7 +2038,7 @@ function ecs.universalWindow(x, y, width, background, closeWindowAfter, ...) local screenWidth, screenHeight = component.gpu.getResolution() local paletteX, paletteY = math.floor(screenWidth / 2 - paletteWidth / 2), math.floor(screenHeight / 2 - paletteHeight / 2) local oldPixels = ecs.rememberOldPixels(paletteX, paletteY, paletteX + paletteWidth - 1, paletteY + paletteHeight - 1) - local color = require("palette").draw("auto", "auto", objects[key][3]) + local color = require("palette").show(paletteX, paletteY, objects[key][3]) ecs.drawOldPixels(oldPixels) objects[key][3] = color or oldColor diff --git a/lib/GUI.lua b/lib/GUI.lua index 9adcf0b2..104a4c2a 100755 --- a/lib/GUI.lua +++ b/lib/GUI.lua @@ -8,8 +8,9 @@ local buffer = require("doubleBuffering") local unicode = require("unicode") local event = require("event") local fs = require("filesystem") +local image = require("image") ------------------------------------------ Core constants ----------------------------------------- +----------------------------------------- Constants ----------------------------------------- local GUI = {} @@ -31,6 +32,11 @@ GUI.directions = enum( "vertical" ) +GUI.dropDownMenuElementTypes = enum( + "default", + "separator" +) + GUI.colors = { disabled = { background = 0x888888, @@ -53,74 +59,58 @@ GUI.colors = { background = 20, shadow = 50 } + }, + windows = { + title = { + background = 0xEEEEEE, + text = 0x3C3C3C + }, + backgroundPanel = 0xFFFFFF, + tabBar = { + default = { + background = 0xDDDDDD, + text = 0x3C3C3C + }, + selected = { + background = 0xCCCCCC, + text = 0x3C3C3C + } + } } } -GUI.dropDownMenuElementTypes = enum( - "default", - "separator" -) +----------------------------------------- Interface objects ----------------------------------------- -GUI.objectTypes = enum( - "unknown", - "empty", - "panel", - "label", - "button", - "framedButton", - "roundedButton", - "image", - "windowActionButtons", - "windowActionButton", - "tabBar", - "tabBarTab", - "menu", - "menuItem", - "window", - "inputTextBox", - "textBox", - "horizontalSlider", - "switch", - "progressBar", - "chart", - "comboBox", - "scrollBar", - "codeView", - "treeView", - "colorSelector", - "layout" -) - ------------------------------------------ Primitive objects ----------------------------------------- - --- Universal method to check if object was clicked by following coordinates -local function isObjectClicked(object, x, y) - if x >= object.x and y >= object.y and x <= object.x + object.width - 1 and y <= object.y + object.height - 1 and not object.disabled and not object.isHidden then return true end - return false -end - --- Limit object's text field to its' size -local function objectTextLimit(object) - local text, textLength = object.text, unicode.len(object.text) - if textLength > object.width then text = unicode.sub(text, 1, object.width); textLength = object.width end - return text, textLength -end - --- Base object to use in everything -function GUI.object(x, y, width, height) - return { - x = x, - y = y, - width = width, - height = height, - isClicked = isObjectClicked - } +local function callMethod(method, ...) + if method then method(...) end end function GUI.point(x, y) return { x = x, y = y } end +function GUI.rectangle(x, y, width, height) + return { x = x, y = y, width = width, height = height} +end + +-- Universal method to check if object was clicked by following coordinates +local function isObjectClicked(object, x, y) + return + x >= object.x and + y >= object.y and + x <= object.x + object.width - 1 and + y <= object.y + object.height - 1 and + not object.disabled and + not object.hidden +end + +-- Main reactangle object to use in everything +function GUI.object(x, y, width, height) + local rectangle = GUI.rectangle(x, y, width, height) + rectangle.isClicked = isObjectClicked + return rectangle +end + ----------------------------------------- Object alignment ----------------------------------------- -- Set children alignment in parent object @@ -160,25 +150,6 @@ end ----------------------------------------- Containers ----------------------------------------- --- Go recursively through every container's object (including other containers) and return object that was clicked firstly by it's GUI-layer position -function GUI.getClickedObject(container, xEvent, yEvent) - local clickedObject, clickedIndex - for childIndex = #container.children, 1, -1 do - if not container.children[childIndex].isHidden then - container.children[childIndex].x, container.children[childIndex].y = container.children[childIndex].localPosition.x + container.x - 1, container.children[childIndex].localPosition.y + container.y - 1 - if container.children[childIndex].children and #container.children[childIndex].children > 0 then - clickedObject, clickedIndex = GUI.getClickedObject(container.children[childIndex], xEvent, yEvent) - if clickedObject then break end - elseif container.children[childIndex]:isClicked(xEvent, yEvent) then - clickedObject, clickedIndex = container.children[childIndex], childIndex - break - end - end - end - - return clickedObject, clickedIndex -end - local function checkObjectParentExists(object) if not object.parent then error("Object doesn't have a parent container") end end @@ -238,10 +209,8 @@ local function selfDelete(object) table.remove(object.parent.children, containerObjectIndexOf(object)) end --- Add any object as children to parent container with specified objectType -function GUI.addChildToContainer(container, object, objectType) - object.type = objectType or GUI.objectTypes.unknown - object.parent = container +-- Add any object as children to parent container +function GUI.addChildToContainer(container, object) object.indexOf = containerObjectIndexOf object.moveToFront = containerObjectMoveToFront object.moveToBack = containerObjectMoveToBack @@ -250,135 +219,13 @@ function GUI.addChildToContainer(container, object, objectType) object.getFirstParent = containerGetFirstParent object.delete = selfDelete object.localPosition = {x = object.x, y = object.y} + object.parent = container table.insert(container.children, object) return object end -local function addEmptyObjectToContainer(container, ...) - return GUI.addChildToContainer(container, GUI.object(...), GUI.objectTypes.empty) -end - -local function addButtonObjectToContainer(container, ...) - return GUI.addChildToContainer(container, GUI.button(...), GUI.objectTypes.button) -end - -local function addAdaptiveButtonObjectToContainer(container, ...) - return GUI.addChildToContainer(container, GUI.adaptiveButton(...), GUI.objectTypes.button) -end - -local function addFramedButtonObjectToContainer(container, ...) - return GUI.addChildToContainer(container, GUI.framedButton(...), GUI.objectTypes.button) -end - -local function addRoundedButtonObjectToContainer(container, ...) - return GUI.addChildToContainer(container, GUI.roundedButton(...), GUI.objectTypes.button) -end - -local function addAdaptiveRoundedButtonObjectToContainer(container, ...) - return GUI.addChildToContainer(container, GUI.adaptiveRoundedButton(...), GUI.objectTypes.button) -end - -local function addAdaptiveFramedButtonObjectToContainer(container, ...) - return GUI.addChildToContainer(container, GUI.adaptiveFramedButton(...), GUI.objectTypes.button) -end - -local function addLabelObjectToContainer(container, ...) - return GUI.addChildToContainer(container, GUI.label(...), GUI.objectTypes.label) -end - -local function addPanelObjectToContainer(container, ...) - return GUI.addChildToContainer(container, GUI.panel(...), GUI.objectTypes.panel) -end - -local function addWindowActionButtonsObjectToContainer(container, ...) - return GUI.addChildToContainer(container, GUI.windowActionButtons(...), GUI.objectTypes.windowActionButtons) -end - -local function addContainerToContainer(container, ...) - return GUI.addChildToContainer(container, GUI.container(...), GUI.objectTypes.container) -end - -local function addImageObjectToContainer(container, ...) - return GUI.addChildToContainer(container, GUI.image(...), GUI.objectTypes.image) -end - -local function addTabBarObjectToContainer(container, ...) - return GUI.addChildToContainer(container, GUI.tabBar(...), GUI.objectTypes.tabBar) -end - -local function addInputTextBoxObjectToContainer(container, ...) - return GUI.addChildToContainer(container, GUI.inputTextBox(...), GUI.objectTypes.inputTextBox) -end - -local function addTextBoxObjectToContainer(container, ...) - return GUI.addChildToContainer(container, GUI.textBox(...), GUI.objectTypes.textBox) -end - -local function addHorizontalSliderObjectToContainer(container, ...) - return GUI.addChildToContainer(container, GUI.horizontalSlider(...), GUI.objectTypes.horizontalSlider) -end - -local function addProgressBarObjectToContainer(container, ...) - return GUI.addChildToContainer(container, GUI.progressBar(...), GUI.objectTypes.progressBar) -end - -local function addSwitchObjectToContainer(container, ...) - return GUI.addChildToContainer(container, GUI.switch(...), GUI.objectTypes.switch) -end - -local function addChartObjectToContainer(container, ...) - return GUI.addChildToContainer(container, GUI.chart(...), GUI.objectTypes.chart) -end - -local function addComboBoxObjectToContainer(container, ...) - return GUI.addChildToContainer(container, GUI.comboBox(...), GUI.objectTypes.comboBox) -end - -local function addMenuObjectToContainer(container, ...) - return GUI.addChildToContainer(container, GUI.menu(...), GUI.objectTypes.menu) -end - -local function addScrollBarObjectToContainer(container, ...) - return GUI.addChildToContainer(container, GUI.scrollBar(...), GUI.objectTypes.scrollBar) -end - -local function addCodeViewObjectToContainer(container, ...) - return GUI.addChildToContainer(container, GUI.codeView(...), GUI.objectTypes.codeView) -end - -local function addTreeViewObjectToContainer(container, ...) - return GUI.addChildToContainer(container, GUI.treeView(...), GUI.objectTypes.treeView) -end - -local function addColorSelectorObjectToContainer(container, ...) - return GUI.addChildToContainer(container, GUI.colorSelector(...), GUI.objectTypes.colorSelector) -end - -local function addLayoutObjectToContainer(container, ...) - return GUI.addChildToContainer(container, GUI.layout(...), GUI.objectTypes.layout) -end - --- Recursively draw container's content including all children container's content -local function drawContainerContent(container) - for objectIndex = 1, #container.children do - if not container.children[objectIndex].isHidden then - container.children[objectIndex].x, container.children[objectIndex].y = container.children[objectIndex].localPosition.x + container.x - 1, container.children[objectIndex].localPosition.y + container.y - 1 - if container.children[objectIndex].children then - -- cyka blyad - -- drawContainerContent(container.children[objectIndex]) - -- We use :draw() method against of recursive call. The reason is possible user-defined :draw() reimplementations - container.children[objectIndex]:draw() - else - container.children[objectIndex]:draw() - end - end - end - - return container -end - -- Delete every container's children object local function deleteContainersContent(container, from, to) from = from or 1 @@ -387,58 +234,136 @@ local function deleteContainersContent(container, from, to) end end +local function getRectangleIntersection(R1X1, R1Y1, R1X2, R1Y2, R2X1, R2Y1, R2X2, R2Y2) + if R2X1 <= R1X2 and R2Y1 <= R2Y2 and R2X2 >= R1X1 and R2Y2 >= R1Y1 then + return + math.max(R2X1, R1X1), + math.max(R2Y1, R1Y1), + math.min(R2X2, R1X2), + math.min(R2Y2, R1Y2) + end +end + +-- Recursively draw container's content including all children container's content +function GUI.drawContainerContent(container) + local R1X1, R1Y1, R1X2, R1Y2 = buffer.getDrawLimit() + local x1, y1, x2, y2 = getRectangleIntersection(R1X1, R1Y1, R1X2, R1Y2, container.x, container.y, container.x + container.width - 1, container.y + container.height - 1) + + if x1 then + buffer.setDrawLimit(x1, y1, x2, y2) + + for objectIndex = 1, #container.children do + if not container.children[objectIndex].hidden then + container.children[objectIndex].x, container.children[objectIndex].y = container.children[objectIndex].localPosition.x + container.x - 1, container.children[objectIndex].localPosition.y + container.y - 1 + container.children[objectIndex]:draw() + end + end + + buffer.setDrawLimit(R1X1, R1Y1, R1X2, R1Y2) + end + + return container +end + +local function handleContainer(isScreenEvent, mainContainer, currentContainer, eventData, x1, y1, x2, y2) + local breakRecursion = false + + if not isScreenEvent or x1 and eventData[3] >= x1 and eventData[4] >= y1 and eventData[3] <= x2 and eventData[4] <= y2 then + for i = #currentContainer.children, 1, -1 do + if not currentContainer.children[i].hidden then + if currentContainer.children[i].children then + if handleContainer(isScreenEvent, mainContainer, currentContainer.children[i], eventData, getRectangleIntersection( + x1, y1, x2, y2, + currentContainer.children[i].x, + currentContainer.children[i].y, + currentContainer.children[i].x + currentContainer.children[i].width - 1, + currentContainer.children[i].y + currentContainer.children[i].height - 1 + )) then + breakRecursion = true + break + end + else + if isScreenEvent then + if currentContainer.children[i]:isClicked(eventData[3], eventData[4]) then + callMethod(currentContainer.children[i].eventHandler, mainContainer, currentContainer.children[i], eventData) + breakRecursion = true + break + end + else + callMethod(currentContainer.children[i].eventHandler, mainContainer, currentContainer.children[i], eventData) + end + end + end + end + + -- if isScreenEvent then + -- if currentContainer.eventHandler then + -- currentContainer.eventHandler(mainContainer, currentContainer, eventData) + -- breakRecursion = true + -- end + -- else + callMethod(currentContainer.eventHandler, mainContainer, currentContainer, eventData) + -- end + end + + if breakRecursion then + return true + end +end + +local function containerHandleEventData(mainContainer, eventData) + handleContainer(eventData[1] == "touch" or eventData[1] == "drag" or eventData[1] == "drop" or eventData[1] == "scroll", mainContainer, mainContainer, eventData, mainContainer.x, mainContainer.y, mainContainer.x + mainContainer.width - 1, mainContainer.y + mainContainer.height - 1) +end + +local function containerStartEventHandling(container, pullTime) + while true do + containerHandleEventData(container, {event.pull(pullTime)}) + if container.dataToReturn then + return table.unpack(container.dataToReturn) + end + end +end + +local function containerReturnData(container, ...) + container.dataToReturn = {...} + computer.pushSignal("containerAction") +end + +local function containerStopEventHandling(container) + containerReturnData(container, nil) +end + -- Universal container to store any other objects like buttons, labels, etc function GUI.container(x, y, width, height) local container = GUI.object(x, y, width, height) - container.children = {} - container.draw = drawContainerContent - container.getClickedObject = GUI.getClickedObject - container.deleteChildren = deleteContainersContent + container.children = {} + container.draw = GUI.drawContainerContent + container.deleteChildren = deleteContainersContent container.addChild = GUI.addChildToContainer - container.addObject = addEmptyObjectToContainer - container.addContainer = addContainerToContainer - container.addPanel = addPanelObjectToContainer - container.addLabel = addLabelObjectToContainer - container.addButton = addButtonObjectToContainer - container.addAdaptiveButton = addAdaptiveButtonObjectToContainer - container.addFramedButton = addFramedButtonObjectToContainer - container.addRoundedButton = addRoundedButtonObjectToContainer - container.addAdaptiveRoundedButton = addAdaptiveRoundedButtonObjectToContainer - container.addAdaptiveFramedButton = addAdaptiveFramedButtonObjectToContainer - container.addWindowActionButtons = addWindowActionButtonsObjectToContainer - container.addImage = addImageObjectToContainer - container.addTabBar = addTabBarObjectToContainer - container.addTextBox = addTextBoxObjectToContainer - container.addInputTextBox = addInputTextBoxObjectToContainer - container.addHorizontalSlider = addHorizontalSliderObjectToContainer - container.addSwitch = addSwitchObjectToContainer - container.addProgressBar = addProgressBarObjectToContainer - container.addChart = addChartObjectToContainer - container.addComboBox = addComboBoxObjectToContainer - container.addMenu = addMenuObjectToContainer - container.addScrollBar = addScrollBarObjectToContainer - container.addCodeView = addCodeViewObjectToContainer - container.addTreeView = addTreeViewObjectToContainer - container.addColorSelector = addColorSelectorObjectToContainer - container.addLayout = addLayoutObjectToContainer + container.returnData = containerReturnData + container.startEventHandling = containerStartEventHandling + container.stopEventHandling = containerStopEventHandling return container end +-- Container fitted to screen resolution +function GUI.fullScreenContainer() + return GUI.container(1, 1, buffer.width, buffer.height) +end + ----------------------------------------- Buttons ----------------------------------------- local function drawButton(object) - local text, textLength = objectTextLimit(object) - - local xText, yText = GUI.getAlignmentCoordinates(object, {width = textLength, height = 1}) + local xText, yText = GUI.getAlignmentCoordinates(object, {width = unicode.len(object.text), height = 1}) local buttonColor = object.disabled and object.colors.disabled.background or (object.pressed and object.colors.pressed.background or object.colors.default.background) local textColor = object.disabled and object.colors.disabled.text or (object.pressed and object.colors.pressed.text or object.colors.default.text) if buttonColor then - if object.buttonType == GUI.objectTypes.button then + if object.buttonType == 1 then buffer.square(object.x, object.y, object.width, object.height, buttonColor, textColor, " ") - elseif object.buttonType == GUI.objectTypes.roundedButton then + elseif object.buttonType == 2 then buffer.text(object.x + 1, object.y, buttonColor, string.rep("▄", object.width - 2)) buffer.square(object.x, object.y + 1, object.width, object.height - 2, buttonColor, textColor, " ") buffer.text(object.x + 1, object.y + object.height - 1, buttonColor, string.rep("▀", object.width - 2)) @@ -447,7 +372,7 @@ local function drawButton(object) end end - buffer.text(xText, yText, textColor, text) + buffer.text(xText, yText, textColor, object.text) return object end @@ -470,9 +395,30 @@ local function pressAndReleaseButton(object, pressTime) buffer.draw() end +local function buttonEventHandler(mainContainer, object, eventData) + if eventData[1] == "touch" then + if object.switchMode then + object.pressed = not object.pressed + mainContainer:draw() + buffer.draw() + callMethod(object.onTouch, mainContainer, object, eventData) + else + object.pressed = true + mainContainer:draw() + buffer.draw() + os.sleep(0.2) + object.pressed = false + mainContainer:draw() + buffer.draw() + callMethod(object.onTouch, mainContainer, object, eventData) + end + end +end + -- Создание таблицы кнопки со всеми необходимыми параметрами local function createButtonObject(buttonType, x, y, width, height, buttonColor, textColor, buttonPressedColor, textPressedColor, text, disabledState) local object = GUI.object(x, y, width, height) + object.colors = { default = { background = buttonColor, @@ -487,6 +433,8 @@ local function createButtonObject(buttonType, x, y, width, height, buttonColor, text = GUI.colors.disabled.text, } } + + object.eventHandler = buttonEventHandler object.buttonType = buttonType object.disabled = disabledState object.text = text @@ -497,70 +445,105 @@ local function createButtonObject(buttonType, x, y, width, height, buttonColor, object.setAlignment = GUI.setAlignment object:setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.center) + return object end -- Кнопка фиксированных размеров function GUI.button(...) - return createButtonObject(GUI.objectTypes.button, ...) + return createButtonObject(1, ...) end -- Кнопка, подстраивающаяся под размер текста function GUI.adaptiveButton(x, y, xOffset, yOffset, buttonColor, textColor, buttonPressedColor, textPressedColor, text, ...) - return createButtonObject(GUI.objectTypes.button, x, y, unicode.len(text) + xOffset * 2, yOffset * 2 + 1, buttonColor, textColor, buttonPressedColor, textPressedColor, text, ...) -end - --- Кнопка в рамке -function GUI.framedButton(...) - return createButtonObject(GUI.objectTypes.framedButton, ...) -end - -function GUI.adaptiveFramedButton(x, y, xOffset, yOffset, buttonColor, textColor, buttonPressedColor, textPressedColor, text, ...) - return createButtonObject(GUI.objectTypes.framedButton, x, y, unicode.len(text) + xOffset * 2, yOffset * 2 + 1, buttonColor, textColor, buttonPressedColor, textPressedColor, text, ...) + return createButtonObject(1, x, y, unicode.len(text) + xOffset * 2, yOffset * 2 + 1, buttonColor, textColor, buttonPressedColor, textPressedColor, text, ...) end -- Rounded button function GUI.roundedButton(...) - return createButtonObject(GUI.objectTypes.roundedButton, ...) + return createButtonObject(2, ...) end function GUI.adaptiveRoundedButton(x, y, xOffset, yOffset, buttonColor, textColor, buttonPressedColor, textPressedColor, text, ...) - return createButtonObject(GUI.objectTypes.roundedButton, x, y, unicode.len(text) + xOffset * 2, yOffset * 2 + 1, buttonColor, textColor, buttonPressedColor, textPressedColor, text, ...) + return createButtonObject(2, x, y, unicode.len(text) + xOffset * 2, yOffset * 2 + 1, buttonColor, textColor, buttonPressedColor, textPressedColor, text, ...) +end + +-- Кнопка в рамке +function GUI.framedButton(...) + return createButtonObject(3, ...) +end + +function GUI.adaptiveFramedButton(x, y, xOffset, yOffset, buttonColor, textColor, buttonPressedColor, textPressedColor, text, ...) + return createButtonObject(3, x, y, unicode.len(text) + xOffset * 2, yOffset * 2 + 1, buttonColor, textColor, buttonPressedColor, textPressedColor, text, ...) end ----------------------------------------- TabBar ----------------------------------------- -local function drawTabBar(object) - for tab = 1, #object.tabs.children do - if tab == object.selectedTab then - object.tabs.children[tab].pressed = true - else - object.tabs.children[tab].pressed = false - end +local function tabBarTabEventHandler(mainContainer, object, eventData) + if eventData[1] == "touch" then + object.parent.selectedItem = object:indexOf() - 1 + mainContainer:draw() + buffer.draw() + callMethod(object.onTouch, mainContainer, object, eventData) end - - object:reimplementedDraw() - return object end -function GUI.tabBar(x, y, width, height, spaceBetweenElements, backgroundColor, textColor, backgroundSelectedColor, textSelectedColor, ...) - local elements, object = {...}, GUI.container(x, y, width, height) - object.selectedTab = 1 - object.tabsWidth = 0; for elementIndex = 1, #elements do object.tabsWidth = object.tabsWidth + unicode.len(elements[elementIndex]) + 2 + spaceBetweenElements end; object.tabsWidth = object.tabsWidth - spaceBetweenElements - object.reimplementedDraw = object.draw - object.draw = drawTabBar +local function tabBarDraw(tabBar) + tabBar.backgroundPanel.width, tabBar.backgroundPanel.height, tabBar.backgroundPanel.colors.background = tabBar.width, tabBar.height, tabBar.colors.default.background + + local totalWidth = 0 + for i = 2, #tabBar.children do + totalWidth = totalWidth + tabBar.children[i].width + tabBar.spaceBetweenTabs + end + totalWidth = totalWidth - tabBar.spaceBetweenTabs - object:addPanel(1, 1, object.width, object.height, backgroundColor) - object.tabs = object:addContainer(1, 1, object.width, object.height) + local x = math.floor(tabBar.width / 2 - totalWidth / 2) + for i = 2, #tabBar.children do + tabBar.children[i].localPosition.x = x + x = x + tabBar.children[i].width + tabBar.spaceBetweenTabs + tabBar.children[i].pressed = (i - 1) == tabBar.selectedItem + end - x = math.floor(width / 2 - object.tabsWidth / 2) - for elementIndex = 1, #elements do - local tab = object.tabs:addButton(x, 1, unicode.len(elements[elementIndex]) + 2, height, backgroundColor, textColor, backgroundSelectedColor, textSelectedColor, elements[elementIndex]) - tab.type = GUI.objectTypes.tabBarTab - x = x + tab.width + spaceBetweenElements - end + GUI.drawContainerContent(tabBar) - return object + return tabBar +end + +local function tabBarAddItem(tabBar, text) + local item = tabBar:addChild(GUI.button(1, 1, unicode.len(text) + tabBar.horizontalTabOffset * 2, tabBar.height, tabBar.colors.default.background, tabBar.colors.default.text, tabBar.colors.selected.background, tabBar.colors.selected.text, text)) + + item.switchMode = true + item.eventHandler = tabBarTabEventHandler + + return item +end + +function GUI.tabBar(x, y, width, height, horizontalTabOffset, spaceBetweenTabs, backgroundColor, textColor, backgroundSelectedColor, textSelectedColor, ...) + local tabBar = GUI.container(x, y, width, height) + + tabBar.backgroundPanel = tabBar:addChild(GUI.panel(1, 1, 1, 1, backgroundColor)) + tabBar.horizontalTabOffset = horizontalTabOffset + tabBar.spaceBetweenTabs = spaceBetweenTabs + tabBar.colors = { + default = { + background = backgroundColor, + text = textColor + }, + selected = { + background = backgroundSelectedColor, + text = textSelectedColor + } + } + tabBar.selectedItem = 1 + tabBar.draw = tabBarDraw + tabBar.addItem = tabBarAddItem + + local items = {...} + for i = 1, #items do + tabBar:addItem(items[i]) + end + + return tabBar end ----------------------------------------- Panel ----------------------------------------- @@ -572,17 +555,18 @@ end function GUI.panel(x, y, width, height, color, transparency) local object = GUI.object(x, y, width, height) + object.colors = {background = color, transparency = transparency} object.draw = drawPanel + return object end ----------------------------------------- Label ----------------------------------------- local function drawLabel(object) - local text, textLength = objectTextLimit(object) - local xText, yText = GUI.getAlignmentCoordinates(object, {width = textLength, height = 1}) - buffer.text(xText, yText, object.colors.text, text) + local xText, yText = GUI.getAlignmentCoordinates(object, {width = unicode.len(object.text), height = 1}) + buffer.text(xText, yText, object.colors.text, object.text) return object end @@ -610,15 +594,15 @@ function GUI.image(x, y, image) return object end ------------------------------------------ Window action buttons ----------------------------------------- +----------------------------------------- Action buttons ----------------------------------------- -function GUI.windowActionButtons(x, y, fatSymbol) +function GUI.actionButtons(x, y, fatSymbol) local symbol = fatSymbol and "⬤" or "●" local container = GUI.container(x, y, 5, 1) - container.close = container:addButton(1, 1, 1, 1, nil, 0xFF4940, nil, 0x992400, symbol) - container.minimize = container:addButton(3, 1, 1, 1, nil, 0xFFB640, nil, 0x996D00, symbol) - container.maximize = container:addButton(5, 1, 1, 1, nil, 0x00B640, nil, 0x006D40, symbol) + container.close = container:addChild(GUI.button(1, 1, 1, 1, nil, 0xFF4940, nil, 0x992400, symbol)) + container.minimize = container:addChild(GUI.button(3, 1, 1, 1, nil, 0xFFB640, nil, 0x996D00, symbol)) + container.maximize = container:addChild(GUI.button(5, 1, 1, 1, nil, 0x00B640, nil, 0x006D40, symbol)) return container end @@ -651,19 +635,23 @@ end local function drawDropDownMenu(object) buffer.square(object.x, object.y, object.width, object.height, object.colors.default.background, object.colors.default.text, " ", object.colors.transparency) - if object.drawShadow then GUI.windowShadow(object.x, object.y, object.width, object.height, GUI.colors.contextMenu.transparency.shadow, true) end - for itemIndex = 1, #object.items do drawDropDownMenuElement(object, itemIndex, false) end + + if object.drawShadow then + GUI.windowShadow(object.x, object.y, object.width, object.height, GUI.colors.contextMenu.transparency.shadow, true) + end + + for itemIndex = 1, #object.items do + drawDropDownMenuElement(object, itemIndex, false) + end end local function showDropDownMenu(object) - local oldDrawLimit = buffer.getDrawLimit(); buffer.resetDrawLimit() object.height = #object.items * object.elementHeight local oldPixels = buffer.copy(object.x, object.y, object.width + 1, object.height + 1) local function quit() buffer.paste(object.x, object.y, oldPixels) buffer.draw() - buffer.setDrawLimit(oldDrawLimit) end drawDropDownMenu(object) @@ -764,8 +752,8 @@ local function showContextMenu(object) object.height = #object.items * object.elementHeight -- А это чтоб за края экрана не лезло - if object.y + object.height >= buffer.screen.height then object.y = buffer.screen.height - object.height end - if object.x + object.width + 1 >= buffer.screen.width then object.x = buffer.screen.width - object.width - 1 end + if object.y + object.height >= buffer.height then object.y = buffer.height - object.height end + if object.x + object.width + 1 >= buffer.width then object.x = buffer.width - object.width - 1 end return object:reimplementedShow() end @@ -797,15 +785,29 @@ local function menuDraw(menu) menu:reimplementedDraw() end +local function menuItemEventHandler(mainContainer, object, eventData) + if eventData[1] == "touch" then + object.pressed = true + mainContainer:draw() + buffer.draw() + callMethod(object.onTouch, eventData) + object.pressed = false + mainContainer:draw() + buffer.draw() + end +end + local function menuAddItem(menu, text, textColor) local x = 2; for i = 1, #menu.children do x = x + unicode.len(menu.children[i].text) + 2; end - local item = menu:addAdaptiveButton(x, 1, 1, 0, nil, textColor or menu.colors.default.text, menu.colors.pressed.background, menu.colors.pressed.text, text) - item.type = GUI.objectTypes.menuItem + local item = menu:addChild(GUI.adaptiveButton(x, 1, 1, 0, nil, textColor or menu.colors.default.text, menu.colors.pressed.background, menu.colors.pressed.text, text)) + item.eventHandler = menuItemEventHandler + return item end function GUI.menu(x, y, width, backgroundColor, textColor, backgroundPressedColor, textPressedColor, backgroundTransparency) local menu = GUI.container(x, y, width, 1) + menu.colors = { default = { background = backgroundColor, @@ -817,7 +819,6 @@ function GUI.menu(x, y, width, backgroundColor, textColor, backgroundPressedColo }, transparency = backgroundTransparency } - menu.addItem = menuAddItem menu.reimplementedDraw = menu.draw menu.draw = menuDraw @@ -847,6 +848,7 @@ end function GUI.progressBar(x, y, width, activeColor, passiveColor, valueColor, value, thin, showValue, valuePrefix, valuePostfix) local object = GUI.object(x, y, width, 1) + object.value = value object.colors = {active = activeColor, passive = passiveColor, value = valueColor} object.thin = thin @@ -854,6 +856,7 @@ function GUI.progressBar(x, y, width, activeColor, passiveColor, valueColor, val object.showValue = showValue object.valuePrefix = valuePrefix object.valuePostfix = valuePostfix + return object end @@ -871,90 +874,54 @@ function GUI.windowShadow(x, y, width, height, transparency, thin) end end -------------------------------------------------- Окна ------------------------------------------------------------------- +------------------------------------------------- Error window ------------------------------------------------------------------- --- Красивое окошко для отображения сообщения об ошибке. Аргумент errorWindowParameters может принимать следующие значения: --- local errorWindowParameters = { --- backgroundColor = 0x262626, --- textColor = 0xFFFFFF, --- truncate = 50, --- title = {color = 0xFF8888, text = "Ошибочка"} --- noAnimation = true, --- } -function GUI.error(text, errorWindowParameters) - --Всякие константы, бла-бла - local backgroundColor = (errorWindowParameters and errorWindowParameters.backgroundColor) or 0x1b1b1b - local errorPixMap = { - {{0xffdb40 , 0xffffff,"#"}, {0xffdb40 , 0xffffff, "#"}, {backgroundColor, 0xffdb40, "▟"}, {backgroundColor, 0xffdb40, "▙"}, {0xffdb40 , 0xffffff, "#"}, {0xffdb40 , 0xffffff, "#"}}, - {{0xffdb40 , 0xffffff,"#"}, {backgroundColor, 0xffdb40, "▟"}, {0xffdb40 , 0xffffff, " "}, {0xffdb40 , 0xffffff, " "}, {backgroundColor, 0xffdb40, "▙"}, {0xffdb40 , 0xffffff, "#"}}, - {{backgroundColor, 0xffdb40,"▟"}, {0xffdb40 , 0xffffff, "c"}, {0xffdb40 , 0xffffff, "y"}, {0xffdb40 , 0xffffff, "k"}, {0xffdb40 , 0xffffff, "a"}, {backgroundColor, 0xffdb40, "▙"}}, - } - local textColor = (errorWindowParameters and errorWindowParameters.textColor) or 0xFFFFFF - local buttonWidth = 12 - local verticalOffset = 2 - local minimumHeight = verticalOffset * 2 + #errorPixMap - local height = 0 - local widthOfText = math.floor(buffer.screen.width * 0.5) - - --Ебемся с текстом, делаем его пиздатым во всех смыслах - if type(text) ~= "table" then - text = tostring(text) - text = (errorWindowParameters and errorWindowParameters.truncate) and unicode.sub(text, 1, errorWindowParameters.truncate) or text - text = { text } - end - text = string.wrap(text, widthOfText) - - - --Ебашим высоту правильнуюe - height = verticalOffset * 2 + #text + 1 - if errorWindowParameters and errorWindowParameters.title then height = height + 2 end - if height < minimumHeight then height = minimumHeight end - - --Ебашим стартовые коорды отрисовки - local x, y = math.ceil(buffer.screen.width / 2 - widthOfText / 2), math.ceil(buffer.screen.height / 2 - height / 2) - local OKButton = {} - local oldPixels = buffer.copy(1, y, buffer.screen.width, height) - - --Отрисовочка - local function draw() - local yPos = y - --Подложка - buffer.square(1, yPos, buffer.screen.width, height, backgroundColor, 0x000000); yPos = yPos + verticalOffset - buffer.customImage(x - #errorPixMap[1] - 3, yPos, errorPixMap) - --Титл, епта! - if errorWindowParameters and errorWindowParameters.title then buffer.text(x, yPos, errorWindowParameters.title.color, errorWindowParameters.title.text); yPos = yPos + 2 end - --Текстус - for i = 1, #text do buffer.text(x, yPos, textColor, text[i]); yPos = yPos + 1 end; yPos = yPos + 1 - --Кнопачка - OKButton = GUI.button(x + widthOfText - buttonWidth, y + height - 2, buttonWidth, 1, 0x3392FF, 0xFFFFFF, 0xFFFFFF, 0x262626, "OK"):draw() - --Атрисовачка - buffer.draw() - end - - --Графонистый выход - local function quit() - OKButton:pressAndRelease(0.2) - buffer.paste(1, y, oldPixels) - buffer.draw() - end - - --Онимацыя - if not (errorWindowParameters and errorWindowParameters.noAnimation) then for i = 1, height do buffer.setDrawLimit(1, math.floor(buffer.screen.height / 2) - i, buffer.screen.width, i * 2); draw(); os.sleep(0.05) end; buffer.resetDrawLimit() end - draw() - - --Анализ говнища - while true do - local e = {event.pull()} - if e[1] == "key_down" then - if e[4] == 28 then - quit(); return - end - elseif e[1] == "touch" then - if OKButton:isClicked(e[3], e[4]) then - quit(); return - end +function GUI.error(...) + local args = {...} + for i = 1, #args do + if type(args[i]) == "table" then + args[i] = table.toString(args[i]) + else + args[i] = tostring(args[i]) end end + + local sign = image.fromString([[06030000FF 0000FF 00F7FF▟00F7FF▙0000FF 0000FF 0000FF 00F7FF▟F7FF00 F7FF00 00F7FF▙0000FF 00F7FF▟F7FF00CF7FF00yF7FF00kF7FF00a00F7FF▙]]) + local offset = 2 + local lines = #args > 1 and "\"" .. table.concat(args, "\", \"") .. "\"" or args[1] + local width = math.floor(buffer.width * 0.5) + local textWidth = width - image.getWidth(sign) - 2 + + lines = string.wrap(lines, textWidth) + local height = image.getHeight(sign) + if #lines + 2 > height then + height = #lines + 2 + end + + local mainContainer = GUI.container(1, math.floor(buffer.height / 2 - height / 2), buffer.width, height + offset * 2) + local oldPixels = buffer.copy(mainContainer.x, mainContainer.y, mainContainer.width, mainContainer.height) + + local x, y = math.floor(buffer.width / 2 - width / 2), offset + 1 + mainContainer:addChild(GUI.panel(1, 1, mainContainer.width, mainContainer.height, 0x1D1D1D)) + mainContainer:addChild(GUI.image(x, y, sign)) + mainContainer:addChild(GUI.textBox(x + image.getWidth(sign) + 2, y, textWidth, #lines, 0x1D1D1D, 0xEEEEEE, lines, 1, 0, 0)).eventHandler = nil + local buttonWidth = 12 + local button = mainContainer:addChild(GUI.button(x + image.getWidth(sign) + textWidth - buttonWidth + 2, mainContainer.height - offset, buttonWidth, 1, 0x3366CC, 0xEEEEEE, 0xEEEEEE, 0x3366CC, "Ok")) + button.onTouch = function() + mainContainer:stopEventHandling() + buffer.paste(mainContainer.x, mainContainer.y, oldPixels) + buffer.draw() + end + mainContainer.eventHandler = function(mainContainer, object, eventData) + if eventData[1] == "key_down" and eventData[4] == 28 then + button:pressAndRelease() + button.onTouch() + end + end + + mainContainer:draw() + buffer.draw(true) + mainContainer:startEventHandling() end ----------------------------------------- Universal keyboard-input function ----------------------------------------- @@ -1015,7 +982,7 @@ local function autocompleteVariables(sourceText) end local function inputFieldDraw(inputField) - if inputField.x < 1 or inputField.y < 1 or inputField.x + inputField.width - 1 > buffer.screen.width or inputField.y > buffer.screen.height then return inputField end + if inputField.x < 1 or inputField.y < 1 or inputField.x + inputField.width - 1 > buffer.width or inputField.y > buffer.height then return inputField end if inputField.oldPixels then buffer.paste(inputField.x, inputField.y, inputField.oldPixels) else @@ -1189,6 +1156,15 @@ local function inputTextBoxBeginInput(inputTextBox) return inputTextBox end +local function inputTextBoxEventHandler(mainContainer, object, eventData) + if eventData[1] == "touch" then + object:input() + mainContainer:draw() + buffer.draw() + callMethod(object.onInputFinished, mainContainer, object, eventData, object.text) + end +end + function GUI.inputTextBox(x, y, width, height, inputTextBoxColor, textColor, inputTextBoxFocusedColor, textFocusedColor, text, placeholderText, eraseTextOnFocus, textMask, highlightLuaSyntax, autocompleteVariables) local inputTextBox = GUI.object(x, y, width, height) inputTextBox.colors = { @@ -1201,6 +1177,8 @@ function GUI.inputTextBox(x, y, width, height, inputTextBoxColor, textColor, inp text = textFocusedColor } } + + inputTextBox.eventHandler = inputTextBoxEventHandler inputTextBox.text = text inputTextBox.placeholderText = placeholderText inputTextBox.draw = drawInputTextBox @@ -1274,8 +1252,24 @@ local function scrollToEndTextBox(object) return object end +local function textBoxScrollEventHandler(mainContainer, object, eventData) + if eventData[1] == "scroll" then + if eventData[5] == 1 then + object:scrollUp() + mainContainer:draw() + buffer.draw() + else + object:scrollDown() + mainContainer:draw() + buffer.draw() + end + end +end + function GUI.textBox(x, y, width, height, backgroundColor, textColor, lines, currentLine, horizontalOffset, verticalOffset) local object = GUI.object(x, y, width, height) + + object.eventHandler = textBoxScrollEventHandler object.colors = { text = textColor, background = backgroundColor } object.setAlignment = GUI.setAlignment object:setAlignment(GUI.alignment.horizontal.left, GUI.alignment.vertical.top) @@ -1319,8 +1313,20 @@ local function drawHorizontalSlider(object) return object end -function GUI.horizontalSlider(x, y, width, activeColor, passiveColor, pipeColor, valueColor, minimumValue, maximumValue, value, showMaximumAndMinimumValues, currentValuePrefix, currentValuePostfix) +local function sliderEventHandler(mainContainer, object, eventData) + if eventData[1] == "touch" or eventData[1] == "drag" then + local clickPosition = eventData[3] - object.x + 1 + object.value = object.minimumValue + (clickPosition * (object.maximumValue - object.minimumValue) / object.width) + mainContainer:draw() + buffer.draw() + callMethod(object.onValueChanged, object.value, eventData) + end +end + +function GUI.slider(x, y, width, activeColor, passiveColor, pipeColor, valueColor, minimumValue, maximumValue, value, showMaximumAndMinimumValues, currentValuePrefix, currentValuePostfix) local object = GUI.object(x, y, width, 1) + + object.eventHandler = sliderEventHandler object.colors = {active = activeColor, passive = passiveColor, pipe = pipeColor, value = valueColor} object.draw = drawHorizontalSlider object.minimumValue = minimumValue @@ -1330,26 +1336,40 @@ function GUI.horizontalSlider(x, y, width, activeColor, passiveColor, pipeColor, object.currentValuePrefix = currentValuePrefix object.currentValuePostfix = currentValuePostfix object.roundValues = false + return object end ----------------------------------------- Switch object ----------------------------------------- -local function drawSwitch(object) - local pipeWidth = object.height * 2 +local function drawSwitch(switch) + local pipeWidth = switch.height * 2 local pipePosition, backgroundColor - if object.state then pipePosition, backgroundColor = object.x + object.width - pipeWidth, object.colors.active else pipePosition, backgroundColor = object.x, object.colors.passive end - buffer.square(object.x, object.y, object.width, object.height, backgroundColor, 0x000000, " ") - buffer.square(pipePosition, object.y, pipeWidth, object.height, object.colors.pipe, 0x000000, " ") - return object + if switch.state then pipePosition, backgroundColor = switch.x + switch.width - pipeWidth, switch.colors.active else pipePosition, backgroundColor = switch.x, switch.colors.passive end + buffer.square(switch.x, switch.y, switch.width, switch.height, backgroundColor, 0x000000, " ") + buffer.square(pipePosition, switch.y, pipeWidth, switch.height, switch.colors.pipe, 0x000000, " ") + + return switch +end + +local function switchEventHandler(mainContainer, object, eventData) + if eventData[1] == "touch" then + object.state = not object.state + mainContainer:draw() + buffer.draw() + callMethod(object.onStateChanged, object.state, eventData) + end end function GUI.switch(x, y, width, activeColor, passiveColor, pipeColor, state) - local object = GUI.object(x, y, width, 1) - object.colors = {active = activeColor, passive = passiveColor, pipe = pipeColor, value = valueColor} - object.draw = drawSwitch - object.state = state or false - return object + local switch = GUI.object(x, y, width, 1) + + switch.eventHandler = switchEventHandler + switch.colors = {active = activeColor, passive = passiveColor, pipe = pipeColor, value = valueColor} + switch.draw = drawSwitch + switch.state = state or false + + return switch end ----------------------------------------- Combo Box Object ----------------------------------------- @@ -1357,7 +1377,7 @@ end local function drawComboBox(object) buffer.square(object.x, object.y, object.width, object.height, object.colors.default.background) local x, y, limit, arrowSize = object.x + 1, math.floor(object.y + object.height / 2), object.width - 5, object.height - buffer.text(x, y, object.colors.default.text, string.limit(object.items[object.currentItem].text, limit, "right")) + buffer.text(x, y, object.colors.default.text, string.limit(object.items[object.selectedItem].text, limit, "right")) GUI.button(object.x + object.width - arrowSize * 2 + 1, object.y, arrowSize * 2 - 1, arrowSize, object.colors.arrow.background, object.colors.arrow.text, 0x0, 0x0, object.state and "▲" or "▼"):draw() end @@ -1370,14 +1390,23 @@ local function selectComboBoxItem(object) dropDownMenu.sidesOffset = 1 local _, itemIndex = dropDownMenu:show() - object.currentItem = itemIndex or object.currentItem + object.selectedItem = itemIndex or object.selectedItem object.state = false object:draw() buffer.draw() end +local function comboBoxEventHandler(mainContainer, object, eventData) + if eventData[1] == "touch" then + object:selectItem() + callMethod(object.onItemSelected, object.items[object.selectedItem], eventData) + end +end + function GUI.comboBox(x, y, width, elementHeight, backgroundColor, textColor, arrowBackgroundColor, arrowTextColor, items) local object = GUI.object(x, y, width, elementHeight) + + object.eventHandler = comboBoxEventHandler object.colors = { default = { background = backgroundColor, @@ -1393,7 +1422,7 @@ function GUI.comboBox(x, y, width, elementHeight, backgroundColor, textColor, ar } } object.items = {} - object.currentItem = 1 + object.selectedItem = 1 object.addItem = addDropDownMenuItem object.addSeparator = addDropDownMenuSeparator object.draw = drawComboBox @@ -1457,9 +1486,44 @@ local function scrollBarDraw(scrollBar) return scrollBar end +local function scrollBarEventHandler(mainContainer, object, eventData) + local newValue = object.value + + if eventData[1] == "touch" or eventData[1] == "drag" then + local delta = object.maximumValue - object.minimumValue + 1 + if object.height > object.width then + newValue = math.floor((eventData[4] - object.y + 1) / object.height * delta) + else + newValue = math.floor((eventData[3] - object.x + 1) / object.width * delta) + end + elseif eventData[1] == "scroll" then + if eventData[5] == 1 then + if object.value >= object.minimumValue + object.onScrollValueIncrement then + newValue = object.value - object.onScrollValueIncrement + else + newValue = object.minimumValue + end + else + if object.value <= object.maximumValue - object.onScrollValueIncrement then + newValue = object.value + object.onScrollValueIncrement + else + newValue = object.maximumValue + end + end + end + + if eventData[1] == "touch" or eventData[1] == "drag" or eventData[1] == "scroll" then + object.value = newValue + callMethod(object.onTouch, eventData) + mainContainer:draw() + buffer.draw() + end +end + function GUI.scrollBar(x, y, width, height, backgroundColor, foregroundColor, minimumValue, maximumValue, value, shownValueCount, onScrollValueIncrement, thinHorizontalMode) local scrollBar = GUI.object(x, y, width, height) + scrollBar.eventHandler = scrollBarEventHandler scrollBar.maximumValue = maximumValue scrollBar.minimumValue = minimumValue scrollBar.value = value @@ -1479,7 +1543,7 @@ end ----------------------------------------- CodeView object ----------------------------------------- local function codeViewDraw(codeView) - -- local toLine = codeView.fromLine + codeView.height - (codeView.scrollBars.horizontal.isHidden and 1 or 2) + -- local toLine = codeView.fromLine + codeView.height - (codeView.scrollBars.horizontal.hidden and 1 or 2) local toLine = codeView.fromLine + codeView.height - 1 -- Line numbers bar and code area @@ -1505,9 +1569,8 @@ local function codeViewDraw(codeView) end end - -- Selections - local oldDrawLimit = buffer.getDrawLimit() - buffer.setDrawLimit(codeView.codeAreaPosition, codeView.y, codeView.codeAreaWidth, codeView.height) + local oldDrawLimitX1, oldDrawLimitY1, oldDrawLimitX2, oldDrawLimitY2 = buffer.getDrawLimit() + buffer.setDrawLimit(codeView.codeAreaPosition, codeView.y, codeView.codeAreaPosition + codeView.codeAreaWidth - 1, codeView.y + codeView.height - 1) local function drawUpperSelection(y, selectionIndex) buffer.square( @@ -1556,7 +1619,7 @@ local function codeViewDraw(codeView) -- Code strings y = codeView.y - buffer.setDrawLimit(codeView.codeAreaPosition + 1, y, codeView.codeAreaWidth - 2, codeView.height) + buffer.setDrawLimit(codeView.codeAreaPosition + 1, y, codeView.codeAreaPosition + codeView.codeAreaWidth - 2, y + codeView.height - 1) for i = codeView.fromLine, toLine do if codeView.lines[i] then if codeView.highlightLuaSyntax then @@ -1569,27 +1632,27 @@ local function codeViewDraw(codeView) break end end - buffer.setDrawLimit(oldDrawLimit) + buffer.setDrawLimit(oldDrawLimitX1, oldDrawLimitY1, oldDrawLimitX2, oldDrawLimitY2) if #codeView.lines > codeView.height then - codeView.scrollBars.vertical.isHidden = false + codeView.scrollBars.vertical.hidden = false codeView.scrollBars.vertical.colors.background, codeView.scrollBars.vertical.colors.foreground = require("syntax").colorScheme.scrollBarBackground, require("syntax").colorScheme.scrollBarForeground codeView.scrollBars.vertical.minimumValue, codeView.scrollBars.vertical.maximumValue, codeView.scrollBars.vertical.value, codeView.scrollBars.vertical.shownValueCount = 1, #codeView.lines, codeView.fromLine, codeView.height codeView.scrollBars.vertical.localPosition.x = codeView.width codeView.scrollBars.vertical.localPosition.y = 1 codeView.scrollBars.vertical.height = codeView.height else - codeView.scrollBars.vertical.isHidden = true + codeView.scrollBars.vertical.hidden = true end if codeView.maximumLineLength > codeView.codeAreaWidth - 2 then - codeView.scrollBars.horizontal.isHidden = false + codeView.scrollBars.horizontal.hidden = false codeView.scrollBars.horizontal.colors.background, codeView.scrollBars.horizontal.colors.foreground = require("syntax").colorScheme.scrollBarBackground, require("syntax").colorScheme.scrollBarForeground codeView.scrollBars.horizontal.minimumValue, codeView.scrollBars.horizontal.maximumValue, codeView.scrollBars.horizontal.value, codeView.scrollBars.horizontal.shownValueCount = 1, codeView.maximumLineLength, codeView.fromSymbol, codeView.codeAreaWidth - 2 codeView.scrollBars.horizontal.localPosition.x, codeView.scrollBars.horizontal.width = codeView.lineNumbersWidth + 1, codeView.codeAreaWidth - 1 codeView.scrollBars.horizontal.localPosition.y = codeView.height else - codeView.scrollBars.horizontal.isHidden = true + codeView.scrollBars.horizontal.hidden = true end codeView:reimplementedDraw() @@ -1608,8 +1671,8 @@ function GUI.codeView(x, y, width, height, lines, fromSymbol, fromLine, maximumL codeView.indentationWidth = indentationWidth codeView.scrollBars = { - vertical = codeView:addScrollBar(1, 1, 1, 1, 0x0, 0x0, 1, 1, 1, 1, 1, false), - horizontal = codeView:addScrollBar(1, 1, 1, 1, 0x0, 0x0, 1, 1, 1, 1, 1, true) + vertical = codeView:addChild(GUI.scrollBar(1, 1, 1, 1, 0x0, 0x0, 1, 1, 1, 1, 1, false)), + horizontal = codeView:addChild(GUI.scrollBar(1, 1, 1, 1, 0x0, 0x0, 1, 1, 1, 1, 1, true)) } codeView.reimplementedDraw = codeView.draw @@ -1710,9 +1773,47 @@ local function treeViewDraw(treeView) return treeView end +local function treeViewEventHandler(mainContainer, object, eventData) + if eventData[1] == "touch" then + local fileIndex = eventData[4] - object.y + object.fromFile - 1 + if object.fileList[fileIndex] then + if object.fileList[fileIndex].isDirectory then + if object.directoriesToShowContent[object.fileList[fileIndex].path] then + object.directoriesToShowContent[object.fileList[fileIndex].path] = nil + else + object.directoriesToShowContent[object.fileList[fileIndex].path] = true + end + object:updateFileList() + mainContainer:draw() + buffer.draw() + else + object.currentFile = object.fileList[fileIndex].path + mainContainer:draw() + buffer.draw() + callMethod(object.onFileSelected, object.currentFile, eventData) + end + end + elseif eventData[1] == "scroll" then + if eventData[5] == 1 then + if object.fromFile > 1 then + object.fromFile = object.fromFile - 1 + mainContainer:draw() + buffer.draw() + end + else + if object.fromFile < #object.fileList then + object.fromFile = object.fromFile + 1 + mainContainer:draw() + buffer.draw() + end + end + end +end + function GUI.treeView(x, y, width, height, backgroundColor, textColor, selectionColor, selectionTextColor, arrowColor, scrollBarBackground, scrollBarForeground, workPath) local treeView = GUI.container(x, y, width, height) + treeView.eventHandler = treeViewEventHandler treeView.colors = { default = { background = backgroundColor, @@ -1757,11 +1858,29 @@ local function colorSelectorDraw(colorSelector) return colorSelector end +local function colorSelectorEventHandler(mainContainer, object, eventData) + if eventData[1] == "touch" then + object.pressed = true + mainContainer:draw() + buffer.draw() + + object.color = require("palette").show(math.floor(mainContainer.width / 2 - 35), math.floor(mainContainer.height / 2 - 12), object.color) or object.color + + object.pressed = false + mainContainer:draw() + buffer.draw() + callMethod(object.onTouch, eventData) + end +end + function GUI.colorSelector(x, y, width, height, color, text) local colorSelector = GUI.object(x, y, width, height) + + colorSelector.eventHandler = colorSelectorEventHandler colorSelector.color = color colorSelector.text = text colorSelector.draw = colorSelectorDraw + return colorSelector end @@ -1890,280 +2009,6 @@ function GUI.chart(x, y, width, height, axisColor, axisValueColor, axisHelpersCo return object end ------------------------------------------ Window object ----------------------------------------- - -local function windowExecuteMethod(method, ...) - if method then method(...) end -end - -local function windowButtonHandler(window, object, objectIndex, eventData) - if object.switchMode then - object.pressed = not object.pressed - window:draw(); buffer.draw() - windowExecuteMethod(object.onTouch, eventData) - else - object.pressed = true - window:draw(); buffer.draw() - os.sleep(0.2) - object.pressed = false - window:draw(); buffer.draw() - windowExecuteMethod(object.onTouch, eventData) - end -end - -local function windowTabBarTabHandler(window, object, objectIndex, eventData) - object.parent.parent.selectedTab = objectIndex - window:draw(); buffer.draw() - windowExecuteMethod(object.parent.parent.onTabSwitched, object.parent.parent.selectedTab, eventData) -end - -local function windowInputTextBoxHandler(window, object, objectIndex, eventData) - object:input() - window:draw(); buffer.draw() - windowExecuteMethod(object.onInputFinished, object.text, eventData) -end - -local function windowTextBoxScrollHandler(window, object, objectIndex, eventData) - if eventData[5] == 1 then - object:scrollUp() - window:draw(); buffer.draw() - else - object:scrollDown() - window:draw(); buffer.draw() - end -end - -local function windowHorizontalSliderHandler(window, object, objectIndex, eventData) - local clickPosition = eventData[3] - object.x + 1 - object.value = object.minimumValue + (clickPosition * (object.maximumValue - object.minimumValue) / object.width) - window:draw(); buffer.draw() - windowExecuteMethod(object.onValueChanged, object.value, eventData) -end - -local function windowSwitchHandler(window, object, objectIndex, eventData) - object.state = not object.state - window:draw(); buffer.draw() - windowExecuteMethod(object.onStateChanged, object.state, eventData) -end - -local function windowComboBoxHandler(window, object, objectIndex, eventData) - object:selectItem() - windowExecuteMethod(object.onItemSelected, object.items[object.currentItem], eventData) -end - -local function windowMenuItemHandler(window, object, objectIndex, eventData) - object.pressed = true - window:draw(); buffer.draw() - windowExecuteMethod(object.onTouch, eventData) - object.pressed = false - window:draw(); buffer.draw() -end - -local function windowScrollBarHandler(window, object, objectIndex, eventData) - local newValue = object.value - - if eventData[1] == "touch" or eventData[1] == "drag" then - local delta = object.maximumValue - object.minimumValue + 1 - if object.height > object.width then - newValue = math.floor((eventData[4] - object.y + 1) / object.height * delta) - else - newValue = math.floor((eventData[3] - object.x + 1) / object.width * delta) - end - elseif eventData[1] == "scroll" then - if eventData[5] == 1 then - if object.value >= object.minimumValue + object.onScrollValueIncrement then - newValue = object.value - object.onScrollValueIncrement - else - newValue = object.minimumValue - end - else - if object.value <= object.maximumValue - object.onScrollValueIncrement then - newValue = object.value + object.onScrollValueIncrement - else - newValue = object.maximumValue - end - end - end - object.value = newValue - windowExecuteMethod(object.onTouch, eventData) - window:draw(); buffer.draw() -end - -local function windowTreeViewHandler(window, object, objectIndex, eventData) - if eventData[1] == "touch" then - local fileIndex = eventData[4] - object.y + object.fromFile - 1 - if object.fileList[fileIndex] then - if object.fileList[fileIndex].isDirectory then - if object.directoriesToShowContent[object.fileList[fileIndex].path] then - object.directoriesToShowContent[object.fileList[fileIndex].path] = nil - else - object.directoriesToShowContent[object.fileList[fileIndex].path] = true - end - object:updateFileList() - object:draw(); buffer.draw() - else - object.currentFile = object.fileList[fileIndex].path - object:draw(); buffer.draw() - windowExecuteMethod(object.onFileSelected, object.currentFile, eventData) - end - end - elseif eventData[1] == "scroll" then - if eventData[5] == 1 then - if object.fromFile > 1 then - object.fromFile = object.fromFile - 1 - object:draw(); buffer.draw() - end - else - if object.fromFile < #object.fileList then - object.fromFile = object.fromFile + 1 - object:draw(); buffer.draw() - end - end - end -end - -local function windowColorSelectorHandler(window, object, objectIndex, eventData) - object.pressed = true - object:draw(); buffer.draw() - object.color = require("palette").show("auto", "auto", object.color) or object.color - object.pressed = false - object:draw(); buffer.draw() - windowExecuteMethod(object.onTouch, eventData) -end - -local function windowHandleEventData(window, eventData) - if eventData[1] == "touch" then - local object, objectIndex = window:getClickedObject(eventData[3], eventData[4]) - - if object then - if object.type == GUI.objectTypes.button then - windowButtonHandler(window, object, objectIndex, eventData) - elseif object.type == GUI.objectTypes.tabBarTab then - windowTabBarTabHandler(window, object, objectIndex, eventData) - elseif object.type == GUI.objectTypes.inputTextBox then - windowInputTextBoxHandler(window, object, objectIndex, eventData) - elseif object.type == GUI.objectTypes.horizontalSlider then - windowHorizontalSliderHandler(window, object, objectIndex, eventData) - elseif object.type == GUI.objectTypes.switch then - windowSwitchHandler(window, object, objectIndex, eventData) - elseif object.type == GUI.objectTypes.comboBox then - windowComboBoxHandler(window, object, objectIndex, eventData) - elseif object.type == GUI.objectTypes.menuItem then - windowMenuItemHandler(window, object, objectIndex, eventData) - elseif object.type == GUI.objectTypes.scrollBar then - windowScrollBarHandler(window, object, objectIndex, eventData) - elseif object.type == GUI.objectTypes.treeView then - windowTreeViewHandler(window, object, objectIndex, eventData) - elseif object.type == GUI.objectTypes.colorSelector then - windowColorSelectorHandler(window, object, objectIndex, eventData) - elseif object.onTouch then - windowExecuteMethod(object.onTouch, eventData) - end - else - windowExecuteMethod(window.onTouch, eventData) - end - elseif eventData[1] == "scroll" then - local object, objectIndex = window:getClickedObject(eventData[3], eventData[4]) - - if object then - if object.type == GUI.objectTypes.textBox then - windowTextBoxScrollHandler(window, object, objectIndex, eventData) - elseif object.type == GUI.objectTypes.scrollBar then - windowScrollBarHandler(window, object, objectIndex, eventData) - elseif object.type == GUI.objectTypes.treeView then - windowTreeViewHandler(window, object, objectIndex, eventData) - elseif object.onScroll then - windowExecuteMethod(object.onScroll, eventData) - end - else - windowExecuteMethod(window.onScroll, eventData) - end - elseif eventData[1] == "drag" then - local object, objectIndex = window:getClickedObject(eventData[3], eventData[4]) - if object then - if object.type == GUI.objectTypes.horizontalSlider then - windowHorizontalSliderHandler(window, object, objectIndex, eventData) - elseif object.type == GUI.objectTypes.scrollBar then - windowScrollBarHandler(window, object, objectIndex, eventData) - elseif object.onDrag then - windowExecuteMethod(object.onDrag, eventData) - end - else - windowExecuteMethod(window.onDrag, eventData) - end - elseif eventData[1] == "drop" then - local object, objectIndex = window:getClickedObject(eventData[3], eventData[4]) - if object then - if object.onDrag then - windowExecuteMethod(object.onDrop, eventData) - end - else - windowExecuteMethod(window.onDrop, eventData) - end - elseif eventData[1] == "key_down" then - windowExecuteMethod(window.onKeyDown, eventData) - elseif eventData[1] == "key_up" then - windowExecuteMethod(window.onKeyUp, eventData) - end - - windowExecuteMethod(window.onAnyEvent, eventData) -end - -local function windowHandleEvents(window, pullTime) - while true do - windowHandleEventData(window, {event.pull(pullTime)}) - if window.dataToReturn then - local data = window.dataToReturn - window = nil - return table.unpack(data) - end - end -end - -local function windowReturnData(window, ...) - window.dataToReturn = {...} - computer.pushSignal("windowAction") -end - -local function windowClose(window) - windowReturnData(window, nil) -end - -local function windowCorrectCoordinates(x, y, width, height, minimumWidth, minimumHeight) - width = minimumWidth and math.max(width, minimumWidth) or width - height = minimumHeight and math.max(height, minimumHeight) or height - x = (x == "auto" and math.floor(buffer.screen.width / 2 - width / 2)) or x - y = (y == "auto" and math.floor(buffer.screen.height / 2 - height / 2)) or y - - return x, y, width, height -end - -local function windowDraw(window) - if window.onDrawStarted then window.onDrawStarted() end - drawContainerContent(window) - if window.drawShadow then GUI.windowShadow(window.x, window.y, window.width, window.height, 50) end - if window.onDrawFinished then window.onDrawFinished() end -end - -function GUI.window(x, y, width, height, minimumWidth, minimumHeight) - x, y, width, height = windowCorrectCoordinates(x, y, width, height, minimumWidth, minimumHeight) - local window = GUI.container(x, y, width, height) - - window.minimumWidth = minimumWidth - window.minimumHeight = minimumHeight - window.drawShadow = false - window.draw = windowDraw - window.handleEvents = windowHandleEvents - window.close = windowClose - window.returnData = windowReturnData - - return window -end - -function GUI.fullScreenWindow() - return GUI.window(1, 1, buffer.screen.width, buffer.screen.height) -end - ----------------------------------------- Layout object ----------------------------------------- local function layoutCheckCell(layout, column, row) @@ -2235,7 +2080,7 @@ end local function layoutDraw(layout) layoutCalculate(layout) - drawContainerContent(layout) + GUI.drawContainerContent(layout) end function GUI.layout(x, y, width, height, columnCount, rowCount) @@ -2255,49 +2100,123 @@ function GUI.layout(x, y, width, height, columnCount, rowCount) return layout end ------------------------------------------ Layout object ----------------------------------------- +----------------------------------------- Window object ----------------------------------------- -function GUI.addUniversalContainer(parentWindow, title) - local container = parentWindow:addContainer(1, 1, parentWindow.width, parentWindow.height) - container.panel = container:addPanel(1, 1, container.width, container.height, 0x0, 30) - container.layout = container:addLayout(1, 1, container.width, container.height, 1, 1) - container.layout:addLabel(1, 1, unicode.len(title), 1, 0xEEEEEE, title):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) +local function windowDraw(window) + GUI.drawContainerContent(window) + GUI.windowShadow(window.x, window.y, window.width, window.height, 50, true) + return window +end + +local function windowCheck(container, x, y) + for i = #container.children, 1, -1 do + if container.children[i].children then + if windowCheck(container.children[i], x, y) then + return true + end + elseif container.children[i].eventHandler and container.children[i]:isClicked(x, y) then + return true + end + end +end + +local function windowEventHandler(mainContainer, object, eventData) + if eventData ~= mainContainer.focusedWindowEventData then + mainContainer.focusedWindowEventData = eventData + + if eventData[1] == "touch" then + mainContainer.focusedWindow = object + object.lastTouchPosition = object.lastTouchPosition or {} + object.lastTouchPosition.x, object.lastTouchPosition.y = eventData[3], eventData[4] + + if object ~= object.parent.children[#object.parent.children] then + object:moveToFront() + mainContainer:draw() + buffer.draw() + end + elseif eventData[1] == "drag" and object == mainContainer.focusedWindow and object.lastTouchPosition and not windowCheck(object, eventData[3], eventData[4]) then + local xOffset, yOffset = eventData[3] - object.lastTouchPosition.x, eventData[4] - object.lastTouchPosition.y + object.lastTouchPosition.x, object.lastTouchPosition.y = eventData[3], eventData[4] + + if xOffset ~= 0 or yOffset ~= 0 then + object.localPosition.x, object.localPosition.y = object.localPosition.x + xOffset, object.localPosition.y + yOffset + mainContainer:draw() + buffer.draw() + end + elseif eventData[1] == "drop" then + mainContainer.focusedWindow = nil + object.lastTouchPosition = nil + end + end +end + +function GUI.window(x, y, width, height) + local window = GUI.container(x, y, width, height) - return container + window.eventHandler = windowEventHandler + window.allowDragMovement = true + window.draw = windowDraw + + return window +end + +function GUI.filledWindow(x, y, width, height, backgroundColor) + local window = GUI.window(x, y, width, height) + + window.backgroundPanel = window:addChild(GUI.panel(1, 1, width, height, backgroundColor)) + window.actionButtons = window:addChild(GUI.actionButtons(2, 1, false)) + + return window +end + +function GUI.titledWindow(x, y, width, height, title, addTitlePanel) + local window = GUI.filledWindow(x, y, width, height, GUI.colors.windows.backgroundPanel) + + if addTitlePanel then + window.titlePanel = window:addChild(GUI.panel(1, 1, width, 1, GUI.colors.windows.title.background)) + window.backgroundPanel.localPosition.y, window.backgroundPanel.height = 2, window.height - 1 + end + window.titleLabel = window:addChild(GUI.label(1, 1, width, height, GUI.colors.windows.title.text, title)):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) + window.actionButtons:moveToFront() + + return window +end + +function GUI.tabbedWindow(x, y, width, height, ...) + local window = GUI.filledWindow(x, y, width, height, GUI.colors.windows.backgroundPanel) + + window.tabBar = window:addChild(GUI.tabBar(1, 1, window.width, 3, 2, 0, GUI.colors.windows.tabBar.default.background, GUI.colors.windows.tabBar.default.text, GUI.colors.windows.tabBar.selected.background, GUI.colors.windows.tabBar.selected.text, ...)) + window.backgroundPanel.localPosition.y, window.backgroundPanel.height = 4, window.height - 3 + window.actionButtons:moveToFront() + window.actionButtons.localPosition.y = 2 + + return window end -------------------------------------------------------------------------------------------------------------------------------- --- buffer.start() +buffer.start() --- local lines = {} --- for line in io.lines("/OS.lua") do --- table.insert(lines, line) +-- local mainContainer = GUI.fullScreenContainer() +-- mainContainer:addChild(GUI.panel(1, 1, mainContainer.width, mainContainer.height, 0xFF8888)) + +-- for i = 1, 2 do +-- -- local window = mainContainer:addChild(GUI.titledWindow(4 + i * 8, 2 + i * 4, 40, 16, "Окно " .. i, true)) +-- local window = mainContainer:addChild(GUI.tabbedWindow(4 + i * 8, 2 + i * 4, 80, 25, "Вкладка", "Еще вкладка", "Ты пидор", "Ебаный в рот")) +-- window.counter = 0 +-- local label = window:addChild(GUI.label(1, 7, window.width, 1, 0x0, "Количество кликов: 0")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) +-- window:addChild(GUI.roundedButton(-5, 9, 33, 3, 0x999999, 0xFFFFFF, 0x2D2D2D, 0xFFFFFF, "Нажимай")).onTouch = function() +-- window.counter = window.counter + 1 +-- label.text = "Количество кликов: " .. window.counter +-- mainContainer:draw() +-- buffer.draw() +-- end +-- window:addChild(GUI.button(2, 24, 10, 3, 0x0, 0xFFFFFF, 0x0, 0xFF0000, "AFAE")) -- end --- buffer.clear(0xFF8888) --- GUI.codeView(2, 2, 100, 40, lines, 1, 1, 40, {{from = {line = 7, symbol = 5}, to = {line = 7, symbol = 8}}}, {}, true, 2):draw() - --- buffer.draw(true) - --- local window = GUI.fullScreenWindow() --- window:addImage(1, 1, require("image").load("/MineOS/Pictures/Raspberry.pic")) --- window:addPanel(1, 1, window.width, window.height, 0x000000, 40) - --- local layout = window:addLayout(1, 1, window.width, window.height, 5, 1) --- layout:setCellPosition(layout:addButton(1, 1, 26, 3, 0xEEEEEE, 0x000000, 0xAAAAAA, 0x000000, "Button 1"), 1, 1) --- layout:setCellPosition(layout:addButton(1, 1, 26, 3, 0xEEEEEE, 0x000000, 0xAAAAAA, 0x000000, "Button 2"), 2, 1) --- layout:setCellPosition(layout:addButton(1, 1, 26, 3, 0xEEEEEE, 0x000000, 0xAAAAAA, 0x000000, "Button 3"), 2, 1) --- layout:setCellPosition(layout:addButton(1, 1, 26, 3, 0xEEEEEE, 0x000000, 0xAAAAAA, 0x000000, "Button 4"), 3, 1) --- layout:setCellPosition(layout:addButton(1, 1, 26, 3, 0xEEEEEE, 0x000000, 0xAAAAAA, 0x000000, "Button 5"), 3, 1) --- layout:setCellPosition(layout:addButton(1, 1, 26, 3, 0xEEEEEE, 0x000000, 0xAAAAAA, 0x000000, "Button 6"), 3, 1) --- layout:setCellPosition(layout:addButton(1, 1, 26, 3, 0xEEEEEE, 0x000000, 0xAAAAAA, 0x000000, "Button 7"), 4, 1) --- layout:setCellPosition(layout:addButton(1, 1, 26, 3, 0xEEEEEE, 0x000000, 0xAAAAAA, 0x000000, "Button 8"), 4, 1) --- layout:setCellPosition(layout:addButton(1, 1, 26, 3, 0xEEEEEE, 0x000000, 0xAAAAAA, 0x000000, "Button 9"), 5, 1) - --- window:draw() --- buffer.draw(true) --- window:handleEvents() +-- mainContainer:draw() +-- buffer.draw() +-- mainContainer:startEventHandling() -------------------------------------------------------------------------------------------------------------------------------- diff --git a/lib/MeowEngine/Main.lua b/lib/MeowEngine/Main.lua index c44303bd..c16790ff 100644 --- a/lib/MeowEngine/Main.lua +++ b/lib/MeowEngine/Main.lua @@ -296,7 +296,7 @@ local function sceneAddObjects(scene, objects) end local function sceneRender(scene) - renderer.setViewport( 1, 1, buffer.screen.width, buffer.screen.height * 2, scene.camera.nearClippingSurface, scene.camera.farClippingSurface, scene.camera.projectionSurface) + renderer.setViewport( 1, 1, buffer.width, buffer.height * 2, scene.camera.nearClippingSurface, scene.camera.farClippingSurface, scene.camera.projectionSurface) OCGL.clearBuffer(scene.backgroundColor) OCGL.renderMode = scene.renderMode OCGL.auxiliaryMode = scene.auxiliaryMode diff --git a/lib/MineOSCore.lua b/lib/MineOSCore.lua index 60b18156..a22c5207 100755 --- a/lib/MineOSCore.lua +++ b/lib/MineOSCore.lua @@ -116,7 +116,7 @@ function MineOSCore.getCurrentApplicationResourcesDirectory() end function MineOSCore.getLocalization(pathToLocalizationFolder) - local localizationFileName = pathToLocalizationFolder .. _G.OSSettings.language .. ".lang" + local localizationFileName = pathToLocalizationFolder .. MineOSCore.OSSettings.language .. ".lang" if fs.exists(localizationFileName) then return table.fromFile(localizationFileName) else @@ -164,11 +164,11 @@ function MineOSCore.readShortcut(path) end function MineOSCore.saveOSSettings() - table.toFile(MineOSCore.paths.OSSettings, _G.OSSettings, true) + table.toFile(MineOSCore.paths.OSSettings, MineOSCore.OSSettings, true) end function MineOSCore.loadOSSettings() - _G.OSSettings = table.fromFile(MineOSCore.paths.OSSettings) + MineOSCore.OSSettings = table.fromFile(MineOSCore.paths.OSSettings) end function MineOSCore.loadIcon(name, path) @@ -198,7 +198,7 @@ end function MineOSCore.init() fs.makeDirectory(MineOSCore.paths.trash) MineOSCore.loadOSSettings() - MineOSCore.localization = table.fromFile(MineOSCore.paths.localizationFiles .. _G.OSSettings.language .. ".lang") + MineOSCore.localization = table.fromFile(MineOSCore.paths.localizationFiles .. MineOSCore.OSSettings.language .. ".lang") MineOSCore.loadStandartIcons() end @@ -246,6 +246,13 @@ local function launch3DPrint(icon) MineOSCore.safeLaunch(MineOSCore.paths.applications .. "3DPrint.app/Main.lua", "open", icon.path) end +local function launchLnk(icon) + local oldPath = icon.path + icon.path = icon.shortcutPath + icon:shortcutLaunch() + icon.path = oldPath +end + local function launchCorrupted(icon) GUI.error("Application is corrupted") end @@ -278,9 +285,9 @@ function MineOSCore.analyzeIconExtension(icon) iconImage = icon.iconImage }) - icon.path = shortcutIcon.path icon.iconImage.image = shortcutIcon.iconImage.image - icon.launch = shortcutIcon.launch + icon.shortcutLaunch = shortcutIcon.launch + icon.launch = launchLnk shortcutIcon = nil elseif icon.extension == ".cfg" or icon.extension == ".config" then @@ -319,7 +326,7 @@ function MineOSCore.getParametersForDrawingIcons(fieldWidth, fieldHeight, xSpace return xCountOfIcons, yCountOfIcons, totalCountOfIcons end -function MineOSCore.createIcon(x, y, path, textColor, showExtension) +function MineOSCore.createIcon(x, y, path, textColor, showExtension, selectionColor) local icon = GUI.container(x, y, MineOSCore.iconWidth, MineOSCore.iconHeight) icon.path = path @@ -330,12 +337,12 @@ function MineOSCore.createIcon(x, y, path, textColor, showExtension) icon.isShortcut = false icon.isSelected = false - icon.iconImage = icon:addImage(3, 1, {8, 4}) - icon.textLabel = icon:addLabel(1, MineOSCore.iconHeight, MineOSCore.iconWidth, 1, textColor, fs.name(icon.path)):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) + icon.iconImage = icon:addChild(GUI.image(3, 1, {8, 4})) + icon.textLabel = icon:addChild(GUI.label(1, MineOSCore.iconHeight, MineOSCore.iconWidth, 1, textColor, fs.name(icon.path))):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) local oldDraw = icon.draw icon.draw = function(icon) - if icon.isSelected then buffer.square(icon.x, icon.y, icon.width, icon.height, 0xFFFFFF, 0x000000, " ", 50) end + if icon.isSelected then buffer.square(icon.x, icon.y, icon.width, icon.height, selectionColor, 0x000000, " ", 50) end if icon.showExtension then icon.textLabel.text = string.limit(fs.name(icon.path), icon.textLabel.width, "center") else @@ -350,22 +357,21 @@ function MineOSCore.createIcon(x, y, path, textColor, showExtension) icon.onRightClick = MineOSCore.iconRightClick -- Обработка клика непосредственно на иконку - icon.iconImage.onTouch = function(eventData) - icon.isSelected = true - local firstParent = icon:getFirstParent() - firstParent:draw() - buffer.draw() + icon.iconImage.eventHandler = function(mainContainer, object, eventData) + if eventData[1] == "touch" then + icon.isSelected = true + MineOSCore.OSDraw() - if eventData[5] == 0 then - os.sleep(MineOSCore.iconClickDelay) - icon.onLeftClick(icon, eventData) - else - icon.onRightClick(icon, eventData) + if eventData[5] == 0 then + os.sleep(MineOSCore.iconClickDelay) + icon.onLeftClick(icon, eventData) + else + icon.onRightClick(icon, eventData) + end + + icon.isSelected = false + MineOSCore.OSDraw() end - - icon.isSelected = false - firstParent:draw() - buffer.draw() end -- Онализ формата и прочего говна иконки для последующего получения изображения иконки и функции-лаунчера @@ -384,9 +390,13 @@ local function updateIconFieldFileList(iconField) iconField:addChild( MineOSCore.createIcon( - xPos, yPos, iconField.workpath .. iconField.fileList[i], iconField.colors.iconText, iconField.showExtension - ), - GUI.objectTypes.container + xPos, + yPos, + iconField.workpath .. iconField.fileList[i], + iconField.colors.iconText, + iconField.showExtension, + iconField.selectionColor + ) ) xPos, counter = xPos + MineOSCore.iconWidth + iconField.spaceBetweenIcons.x, counter + 1 @@ -399,7 +409,7 @@ local function updateIconFieldFileList(iconField) return iconField end -function MineOSCore.createIconField(x, y, width, height, xCountOfIcons, yCountOfIcons, totalCountOfIcons, xSpaceBetweenIcons, ySpaceBetweenIcons, iconTextColor, showExtension, showHiddenFiles, sortingMethod, workpathworkpath) +function MineOSCore.createIconField(x, y, width, height, xCountOfIcons, yCountOfIcons, totalCountOfIcons, xSpaceBetweenIcons, ySpaceBetweenIcons, iconTextColor, showExtension, showHiddenFiles, sortingMethod, workpath, selectionColor) local iconField = GUI.container(x, y, width, height) iconField.colors = {iconText = iconTextColor} @@ -413,7 +423,8 @@ function MineOSCore.createIconField(x, y, width, height, xCountOfIcons, yCountOf iconField.showHiddenFiles = showHiddenFiles iconField.sortingMethod = sortingMethod iconField.fileList = {} - iconField.fromFile = fromFile + iconField.fromFile = 1 + iconField.selectionColor = selectionColor iconField.updateFileList = updateIconFieldFileList @@ -448,154 +459,134 @@ function MineOSCore.parseErrorMessage(error, indentationWidth) return parsedError end -local function drawErrorWindow(path, programVersion, errorLine, reason) - local oldDrawLimit = buffer.getDrawLimit(); buffer.resetDrawLimit() - local width, height = buffer.screen.width, math.floor(buffer.screen.height * 0.45) - local y = math.floor(buffer.screen.height / 2 - height / 2) +function MineOSCore.showErrorWindow(path, errorLine, reason) + buffer.clear(0x0, 50) - -- Окошечко и всякая шняжка на нем - local window = GUI.window(1, y, width, height, width, height) - window:addPanel(1, 1, width, 3, 0x383838) - window:addLabel(1, 2, width, 1, 0xFFFFFF, MineOSCore.localization.errorWhileRunningProgram .. "\"" .. fs.name(path) .. "\""):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) - local windowActionButtons = window:addWindowActionButtons(2, 2, false) - local sendToDeveloperButton = window:addAdaptiveButton(9, 1, 2, 1, 0x444444, 0xFFFFFF, 0x343434, 0xFFFFFF, MineOSCore.localization.sendFeedback) + local mainContainer = GUI.container(1, 1, buffer.width, math.floor(buffer.height * 0.45)) + mainContainer.y = math.floor(buffer.height / 2 - mainContainer.height / 2) + + mainContainer:addChild(GUI.panel(1, 1, mainContainer.width, 3, 0x383838)) + mainContainer:addChild(GUI.label(1, 2, mainContainer.width, 1, 0xFFFFFF, MineOSCore.localization.errorWhileRunningProgram .. "\"" .. fs.name(path) .. "\"")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) + local actionButtons = mainContainer:addChild(GUI.actionButtons(2, 2, false)) + local sendToDeveloperButton = mainContainer:addChild(GUI.adaptiveButton(9, 1, 2, 1, 0x444444, 0xFFFFFF, 0x343434, 0xFFFFFF, MineOSCore.localization.sendFeedback)) - --Кодик на окошечке - local lines = {} - local fromLine = errorLine - math.floor((height - 3) / 2) + 1; if fromLine <= 0 then fromLine = 1 end - local toLine = fromLine + window.height - 3 - 1 - local file = io.open(path, "r") - local lineCounter = 1 - for line in file:lines() do - if lineCounter >= fromLine and lineCounter <= toLine then - lines[lineCounter] = string.gsub(line, " ", " ") - elseif lineCounter < fromLine then - lines[lineCounter] = " " + local codeView = mainContainer:addChild(GUI.codeView(1, 4, math.floor(mainContainer.width * 0.62), mainContainer.height - 3, {}, 1, 1, 100, {}, {[errorLine] = 0xFF4444}, true, 2)) + codeView.scrollBars.horizontal.hidden = true + + codeView.fromLine = errorLine - math.floor((mainContainer.height - 3) / 2) + 1 + if codeView.fromLine <= 0 then codeView.fromLine = 1 end + local toLine, lineCounter = codeView.fromLine + codeView.height - 1, 1 + for line in io.lines(path) do + if lineCounter >= codeView.fromLine and lineCounter <= toLine then + codeView.lines[lineCounter] = string.gsub(line, " ", " ") + elseif lineCounter < codeView.fromLine then + codeView.lines[lineCounter] = " " elseif lineCounter > toLine then break end lineCounter = lineCounter + 1 end - file:close() - local codeView = window:addCodeView(1, 4, math.floor(width * 0.62), height - 3, lines, 1, fromLine, 100, {}, {[errorLine] = 0xFF4444}, true, 2) - codeView.scrollBars.horizontal.isHidden = true - - -- Текстбоксик - local stackTextBox = window:addTextBox(codeView.width + 1, 4, window.width - codeView.width, codeView.height, 0xFFFFFF, 0x000000, string.wrap(MineOSCore.parseErrorMessage(reason, 4), window.width - codeView.width - 2), 1, 1, 0) - - -- Всякие действия пиздатые - local function exit() - windowActionButtons.close:pressAndRelease() - buffer.setDrawLimit(oldDrawLimit) - window:close() - end + mainContainer:addChild(GUI.textBox(codeView.width + 1, 4, mainContainer.width - codeView.width, codeView.height, 0xFFFFFF, 0x000000, string.wrap(MineOSCore.parseErrorMessage(reason, 4), mainContainer.width - codeView.width - 2), 1, 1, 0)) - windowActionButtons.close.onTouch = exit - - window.onDrawStarted = function() - buffer.clear(0x000000, 50) + actionButtons.close.onTouch = function() + mainContainer:stopEventHandling() end - window.onKeyDown = function(eventData) - if eventData[4] == 28 then exit() end - end - - sendToDeveloperButton.onTouch = function() - local data = ecs.universalWindow("auto", "auto", 36, 0xeeeeee, true, - {"EmptyLine"}, - {"CenterText", 0x880000, MineOSCore.localization.sendFeedback}, - {"EmptyLine"}, - {"Input", 0x262626, 0x880000, MineOSCore.localization.yourContacts}, - {"Input", 0x262626, 0x880000, MineOSCore.localization.additionalInfo}, - {"EmptyLine"}, - {"CenterText", 0x880000, MineOSCore.localization.stackTraceback .. ":"}, - {"EmptyLine"}, - {"TextField", 5, 0xFFFFFF, 0x000000, 0xcccccc, 0x3366CC, reason}, - {"Button", {0x999999, 0xffffff, "OK"}, {0x777777, 0xffffff, MineOSCore.localization.cancel}} - ) - - if data[3] == "OK" then - if component.isAvailable("internet") then - local url = "https://api.mcmodder.ru/ECS/report.php?path=" .. path .. "&version=" .. string.optimizeForURLRequests(programVersion) .. "&userContacts=" .. string.optimizeForURLRequests(data[1]) .. "&userMessage=" .. string.optimizeForURLRequests(data[2]) .. "&errorMessage=" .. string.optimizeForURLRequests(reason) - local success, reason = component.internet.request(url) - if success then - success:close() - else - ecs.error(reason) - end - end - exit() + mainContainer.eventHandler = function(mainContainer, object, eventData) + if eventData[1] == "key_down" and eventData[4] == 28 then + actionButtons.close.onTouch() end end - -- Начинаем гомоеблю! - window:draw() + sendToDeveloperButton.onTouch = function() + if component.isAvailable("internet") then + local url = "https://api.mcmodder.ru/ECS/report.php?path=" .. path .. "&errorMessage=" .. string.optimizeForURLRequests(reason) + local success, reason = component.internet.request(url) + if success then + success:close() + else + ecs.error(reason) + end + + sendToDeveloperButton.text = MineOSCore.localization.sendedFeedback + mainContainer:draw() + buffer.draw() + os.sleep(1) + end + actionButtons.close.onTouch() + end + + mainContainer:draw() buffer.draw() - for i = 1, 3 do component.computer.beep(1500, 0.08) end - window:handleEvents() + for i = 1, 3 do + component.computer.beep(1500, 0.08) + end + mainContainer:startEventHandling() +end + +function MineOSCore.call(method, ...) + local args = {...} + local function launchMethod() + method(table.unpack(args)) + end + + local function tracebackMethod(xpcallTraceback) + local traceback, info, firstMatch = tostring(xpcallTraceback) .. "\n" .. debug.traceback() + for runLevel = 0, math.huge do + info = debug.getinfo(runLevel) + if info then + if (info.what == "main" or info.what == "Lua") and info.source ~= "=machine" then + if firstMatch then + return { + path = info.source:sub(2, -1), + line = info.currentline, + traceback = traceback + } + else + firstMatch = true + end + end + else + error("Failed to get debug info for runlevel " .. runLevel) + end + end + end + + local xpcallSuccess, xpcallReason = xpcall(launchMethod, tracebackMethod) + if not xpcallSuccess and not xpcallReason.traceback:match("^table") and not xpcallReason.traceback:match("interrupted") then + return false, xpcallReason.path, xpcallReason.line, xpcallReason.traceback + end + + return true end function MineOSCore.safeLaunch(path, ...) - local args = {...} - local oldResolutionWidth, oldResolutionHeight = buffer.screen.width, buffer.screen.height + local oldResolutionWidth, oldResolutionHeight = buffer.width, buffer.height local finalSuccess, finalPath, finalLine, finalTraceback = true if fs.exists(path) then - local loadSuccess, loadReason = loadfile(string.canonicalPath("/" .. path)) - + local loadSuccess, loadReason = loadfile("/" .. path) if loadSuccess then - local function launchMethod() - loadSuccess(table.unpack(args)) - end - - local function tracebackMethod(xpcallTraceback) - local traceback, info, firstMatch = tostring(xpcallTraceback) .. "\n" .. debug.traceback() - for runLevel = 0, math.huge do - info = debug.getinfo(runLevel) - if info then - if (info.what == "main" or info.what == "Lua") and info.source ~= "=machine" then - if firstMatch then - return { - path = info.source:sub(2, -1), - line = info.currentline, - traceback = traceback - } - else - firstMatch = true - end - end - else - error("Failed to get debug info for runlevel " .. runLevel) - end - end - end - - local runSuccess, runReason = xpcall(launchMethod, tracebackMethod) - if type(runReason) == "string" then - GUI.error(runReason, {title = {color = 0xFFDB40, text = "Warning"}}) - else - if not runSuccess and not string.match(runReason.traceback, "^table") and not string.find(runReason.traceback, "interrupted", 1, 15) then - finalSuccess, finalPath, finalLine, finalTraceback = false, runReason.path, runReason.line, runReason.traceback - end + local success, path, line, traceback = MineOSCore.call(loadSuccess, ...) + if not success then + finalSuccess, finalPath, finalLine, finalTraceback = false, path, line, traceback end else - finalSuccess, finalPath, finalTraceback = false, path, loadReason local match = string.match(loadReason, ":(%d+)%:") - finalLine = tonumber(match) - if not match or not finalLine then error("Дебажь говно! " .. tostring(loadReason)) end + finalSuccess, finalPath, finalLine, finalTraceback = false, path, tonumber(match) or 1, loadReason end else GUI.error("Failed to safely launch file that doesn't exists: \"" .. path .. "\"", {title = {color = 0xFFDB40, text = "Warning"}}) end - if not finalSuccess then - drawErrorWindow(finalPath, "1.0", finalLine, finalTraceback) - end - component.screen.setPrecise(false) - gpu.setResolution(oldResolutionWidth, oldResolutionHeight) - buffer.start() + buffer.setResolution(oldResolutionWidth, oldResolutionHeight) + MineOSCore.OSDraw() + + if not finalSuccess then + MineOSCore.showErrorWindow(finalPath, finalLine, finalTraceback) + end return finalSuccess, finalPath, finalLine, finalTraceback end @@ -709,7 +700,7 @@ function MineOSCore.iconRightClick(icon, eventData) MineOSCore.safeLaunch(MineOSCore.paths.applications .. "/MineCode IDE.app/Main.lua", "open", icon.path) computer.pushSignal("MineOSCore", "updateFileList") elseif action == "Свойства" then - MineOSCore.showPropertiesWindow(eventData[3], eventData[4], 40, icon) + MineOSCore.propertiesWindow(eventData[3], eventData[4], 40, icon) elseif action == MineOSCore.localization.contextMenuShowContainingFolder then computer.pushSignal("MineOSCore", "changeWorkpath", fs.path(icon.shortcutPath)) computer.pushSignal("MineOSCore", "updateFileList") @@ -746,7 +737,7 @@ function MineOSCore.iconRightClick(icon, eventData) require("compressor").pack(fs.path(icon.path) .. fs.hideExtension(fs.name(icon.path)) .. ".pkg", icon.path) computer.pushSignal("MineOSCore", "updateFileList") elseif action == MineOSCore.localization.contextMenuSetAsWallpaper then - _G.OSSettings.wallpaper = icon.path + MineOSCore.OSSettings.wallpaper = icon.path MineOSCore.saveOSSettings() computer.pushSignal("MineOSCore", "updateWallpaper") elseif action == MineOSCore.localization.contextMenuFlashEEPROM then @@ -755,13 +746,13 @@ function MineOSCore.iconRightClick(icon, eventData) file:close() computer.beep(1500, 0.2) elseif action == MineOSCore.localization.contextMenuAddToDock then - table.insert(_G.OSSettings.dockShortcuts, {path = icon.path}) + table.insert(MineOSCore.OSSettings.dockShortcuts, {path = icon.path}) MineOSCore.saveOSSettings() computer.pushSignal("MineOSCore", "updateFileList") end end -function MineOSCore.emptyZoneClick(eventData, workspace, workpath) +function MineOSCore.emptyZoneClick(eventData, mainContainer, workpath) local action = GUI.contextMenu(eventData[3], eventData[4], {MineOSCore.localization.contextMenuNewFile}, {MineOSCore.localization.contextMenuNewFolder}, @@ -787,53 +778,24 @@ function MineOSCore.emptyZoneClick(eventData, workspace, workpath) end end -local function addKeyAndValue(window, x, y, key, value) - window:addLabel(x, y, window.width , 1, 0x333333, key .. ":"); x = x + unicode.len(key) + 2 - return window:addLabel(x, y, window.width, 1, 0x555555, value) -end +----------------------------------------------------------------------------------------------------------------------------------- -function MineOSCore.showPropertiesWindow(x, y, width, icon) - local window = GUI.window(x, y, width, 1) - local backgroundPanel = window:addPanel(1, 2, window.width, 1, 0xDDDDDD) - window:addPanel(1, 1, window.width, 1, 0xEEEEEE) - window:addLabel(1, 1, window.width, 1, 0x333333, MineOSCore.localization.contextMenuProperties):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) - window:addButton(2, 1, 1, 1, nil, 0xFF4940, nil, 0x992400, "●").onTouch = function() window:close() end - - window:addImage(3, 3, icon.iconImage.image) - - local y = 3 - addKeyAndValue(window, 13, y, MineOSCore.localization.type, icon.extension and icon.extension or (icon.isDirectory and MineOSCore.localization.folder or MineOSCore.localization.unknown)); y = y + 1 - local fileSizeLabel = addKeyAndValue(window, 13, y, MineOSCore.localization.size, icon.isDirectory and MineOSCore.localization.calculatingSize or string.format("%.2f", icon.size / 1024) .. " KB"); y = y + 1 - addKeyAndValue(window, 13, y, MineOSCore.localization.date, os.date("%d.%m.%y, %H:%M", fs.lastModified(icon.path))); y = y + 1 - addKeyAndValue(window, 13, y, MineOSCore.localization.path, " ") - - local lines = string.wrap(icon.path, window.width - 19) - local textBox = window:addTextBox(19, y, window.width - 19, #lines, nil, 0x555555, lines, 1) - window.height = textBox.y + textBox.height - backgroundPanel.height = window.height - 1 - - if window.x + window.width > buffer.screen.width then window.x = window.x - (window.x + window.width - buffer.screen.width) end - if window.y + window.height > buffer.screen.height then window.y = window.y - (window.y + window.height - buffer.screen.height) end - - window:draw() - buffer.draw() - - if icon.isDirectory then - fileSizeLabel.text = string.format("%.2f", fs.directorySize(icon.path) / 1024) .. " KB" - window:draw() - buffer.draw() - end - - window:handleEvents() +function MineOSCore.addUniversalContainer(parentContainer, title) + local container = parentContainer:addChild(GUI.container(1, 1, parentContainer.width, parentContainer.height)) + container.panel = container:addChild(GUI.panel(1, 1, container.width, container.height, 0x0, 30)) + container.layout = container:addChild(GUI.layout(1, 1, container.width, container.height, 1, 1)) + container.layout:addChild(GUI.label(1, 1, unicode.len(title), 1, 0xEEEEEE, title)):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) + + return container end ----------------------------------------------------------------------------------------------------------------------------------- -local function createUniversalContainer(parentWindow, path, text, title, placeholder) - local container = GUI.addUniversalContainer(parentWindow, title) +local function addUniversalContainerWithInputTextBoxes(parentWindow, path, text, title, placeholder) + local container = MineOSCore.addUniversalContainer(parentWindow, title) - container.inputTextBox = container.layout:addInputTextBox(1, 1, 36, 3, 0xEEEEEE, 0x666666, 0xEEEEEE, 0x262626, text, placeholder, false) - container.label = container.layout:addLabel(1, 1, 36, 3, 0xFF4940, " "):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) + container.inputTextBox = container.layout:addChild(GUI.inputTextBox(1, 1, 36, 3, 0xEEEEEE, 0x666666, 0xEEEEEE, 0x262626, text, placeholder, false)) + container.label = container.layout:addChild(GUI.label(1, 1, 36, 3, 0xFF4940, " ")):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) parentWindow:draw() buffer.draw() @@ -854,7 +816,7 @@ local function checkFileToExists(container, path) end function MineOSCore.newApplication(parentWindow, path) - local container = createUniversalContainer(parentWindow, path, nil, MineOSCore.localization.contextMenuNewApplication, MineOSCore.localization.applicationName) + local container = addUniversalContainerWithInputTextBoxes(parentWindow, path, nil, MineOSCore.localization.contextMenuNewApplication, MineOSCore.localization.applicationName) container.inputTextBox.onInputFinished = function() local finalPath = path .. container.inputTextBox.text .. ".app/" @@ -871,7 +833,7 @@ function MineOSCore.newApplication(parentWindow, path) end function MineOSCore.newFile(parentWindow, path) - local container = createUniversalContainer(parentWindow, path, nil, MineOSCore.localization.contextMenuNewFile, MineOSCore.localization.fileName) + local container = addUniversalContainerWithInputTextBoxes(parentWindow, path, nil, MineOSCore.localization.contextMenuNewFile, MineOSCore.localization.fileName) container.inputTextBox.onInputFinished = function() if checkFileToExists(container, path .. container.inputTextBox.text) then @@ -884,7 +846,7 @@ function MineOSCore.newFile(parentWindow, path) end function MineOSCore.newFolder(parentWindow, path) - local container = createUniversalContainer(parentWindow, path, nil, MineOSCore.localization.contextMenuNewFolder, MineOSCore.localization.folderName) + local container = addUniversalContainerWithInputTextBoxes(parentWindow, path, nil, MineOSCore.localization.contextMenuNewFolder, MineOSCore.localization.folderName) container.inputTextBox.onInputFinished = function() if checkFileToExists(container, path .. container.inputTextBox.text) then @@ -895,7 +857,7 @@ function MineOSCore.newFolder(parentWindow, path) end function MineOSCore.rename(parentWindow, path) - local container = createUniversalContainer(parentWindow, path, fs.name(path), MineOSCore.localization.contextMenuRename, MineOSCore.localization.newName) + local container = addUniversalContainerWithInputTextBoxes(parentWindow, path, fs.name(path), MineOSCore.localization.contextMenuRename, MineOSCore.localization.newName) container.inputTextBox.onInputFinished = function() if checkFileToExists(container, fs.path(path) .. container.inputTextBox.text) then @@ -906,9 +868,9 @@ function MineOSCore.rename(parentWindow, path) end function MineOSCore.applicationHelp(parentWindow, path) - local pathToAboutFile = path .. "/resources/About/" .. _G.OSSettings.language .. ".txt" - if _G.OSSettings.showHelpOnApplicationStart and fs.exists(pathToAboutFile) then - local container = GUI.addUniversalContainer(parentWindow, MineOSCore.localization.applicationHelp .. "\"" .. fs.name(path) .. "\"") + local pathToAboutFile = path .. "/resources/About/" .. MineOSCore.OSSettings.language .. ".txt" + if MineOSCore.OSSettings.showHelpOnApplicationStart and fs.exists(pathToAboutFile) then + local container = MineOSCore.addUniversalContainer(parentWindow, MineOSCore.localization.applicationHelp .. "\"" .. fs.name(path) .. "\"") local lines = {} for line in io.lines(pathToAboutFile) do @@ -916,21 +878,23 @@ function MineOSCore.applicationHelp(parentWindow, path) end lines = string.wrap(lines, 50) - container.layout:addTextBox(1, 1, 50, #lines, nil, 0xcccccc, lines, 1, 0, 0) - local button = container.layout:addButton(1, 1, 30, 1, 0xEEEEEE, 0x262626, 0xAAAAAA, 0x262626, MineOSCore.localization.dontShowAnymore) + container.layout:addChild(GUI.textBox(1, 1, 50, #lines, nil, 0xcccccc, lines, 1, 0, 0)) + local button = container.layout:addChild(GUI.button(1, 1, 30, 1, 0xEEEEEE, 0x262626, 0xAAAAAA, 0x262626, MineOSCore.localization.dontShowAnymore)) parentWindow:draw() buffer.draw() - container.panel.onTouch = function() - container:delete() - MineOSCore.safeLaunch(path .. "/Main.lua") - parentWindow:draw() - buffer.draw() + container.panel.eventHandler = function(mainContainer, object, eventData) + if eventData[1] == "touch" then + container:delete() + MineOSCore.safeLaunch(path .. "/Main.lua") + parentWindow:draw() + buffer.draw() + end end button.onTouch = function() - _G.OSSettings.showHelpOnApplicationStart = false + MineOSCore.OSSettings.showHelpOnApplicationStart = false MineOSCore.saveOSSettings() container.panel.onTouch() @@ -942,6 +906,118 @@ function MineOSCore.applicationHelp(parentWindow, path) end end +----------------------------------------- Windows patterns ----------------------------------------- + +local function onWindowResize(window, width, height) + if window.titleLabel then + window.titleLabel.width = width + end + + if window.titlePanel then + window.titlePanel.width = height + end + + if window.tabBar then + window.tabBar.width = width + end + + window.backgroundPanel.width, window.backgroundPanel.height = width, height - (window.titlePanel and 1 or 0) +end + +local function windowResize(window, width, height) + window.width, window.height = width, height + window:onResize(width, height) + + return window +end + +local function windowMinimize(window) + window.localPosition.x, window.localPosition.y = window.oldGeometry.x, window.oldGeometry.y + window:resize(window.oldGeometry.width, window.oldGeometry.height) + MineOSCore.OSDraw() +end + +local function windowMaximize(window) + window.localPosition.x, window.localPosition.y = 1, 1 + if window.width ~= window.parent.width or window.height ~= window.parent.height then + window.oldGeometry.x, window.oldGeometry.y, window.oldGeometry.width, window.oldGeometry.height = window.localPosition.x, window.localPosition.y, window.width, window.height + window:resize(window.parent.width, window.parent.height) + end + MineOSCore.OSDraw() +end + +local function windowClose(window) + window:delete() + MineOSCore.OSDraw() +end + +function MineOSCore.addWindow(window) + window.x = window.x or math.floor(MineOSCore.OSMainContainer.windowsContainer.width / 2 - window.width / 2) + window.y = window.y or math.floor(MineOSCore.OSMainContainer.windowsContainer.height / 2 - window.height / 2) + + MineOSCore.OSMainContainer.windowsContainer:addChild(window) + + window.resize = windowResize + window.onResize = onWindowResize + window.close = windowClose + + if window.actionButtons then + window.oldGeometry = {x = window.x, y = window.y, width = window.width, height = window.height} + + window.actionButtons.close.onTouch = function() + windowClose(window) + end + window.actionButtons.maximize.onTouch = function() + windowMaximize(window) + end + window.actionButtons.minimize.onTouch = function() + windowMinimize(window) + end + end + + return MineOSCore.OSMainContainer, window +end + +----------------------------------------------------------------------------------------------------------------------------------- + +local function addKeyAndValue(window, x, y, key, value) + x = x + window:addChild(GUI.label(x, y, unicode.len(key) + 1, 1, 0x333333, key .. ":")).width + 1 + return window:addChild(GUI.label(x, y, unicode.len(value), 1, 0x555555, value)) +end + +function MineOSCore.propertiesWindow(x, y, width, icon) + local mainContainer, window = MineOSCore.addWindow(GUI.titledWindow(x, y, width, 1, package.loaded.MineOSCore.localization.contextMenuProperties)) + + window.backgroundPanel.colors.transparency = 25 + window:addChild(GUI.image(2, 3, icon.iconImage.image)) + + local x, y = 11, 3 + addKeyAndValue(window, x, y, package.loaded.MineOSCore.localization.type, icon.extension and icon.extension or (icon.isDirectory and package.loaded.MineOSCore.localization.folder or package.loaded.MineOSCore.localization.unknown)); y = y + 1 + local fileSizeLabel = addKeyAndValue(window, x, y, package.loaded.MineOSCore.localization.size, icon.isDirectory and package.loaded.MineOSCore.localization.calculatingSize or string.format("%.2f", icon.size / 1024) .. " KB"); y = y + 1 + addKeyAndValue(window, x, y, package.loaded.MineOSCore.localization.date, os.date("%d.%m.%y, %H:%M", fs.lastModified(icon.path))); y = y + 1 + addKeyAndValue(window, x, y, package.loaded.MineOSCore.localization.path, " ") + + local lines = string.wrap(icon.path, window.width - 18) + local textBox = window:addChild(GUI.textBox(17, y, window.width - 18, #lines, nil, 0x555555, lines, 1)) + window:resize(window.width, textBox.y + textBox.height) + + mainContainer:draw() + buffer.draw() + + if icon.isDirectory then + fileSizeLabel.text = string.format("%.2f", fs.directorySize(icon.path) / 1024) .. " KB" + mainContainer:draw() + buffer.draw() + end +end + +----------------------------------------------------------------------------------------------------------------------------------- + +function MineOSCore.OSDraw(force) + MineOSCore.OSMainContainer:draw() + buffer.draw(force) +end + ----------------------------------------------------------------------------------------------------------------------------------- MineOSCore.init() diff --git a/lib/OpenComputersGL/Main.lua b/lib/OpenComputersGL/Main.lua index e5f6eb21..1e7b1305 100644 --- a/lib/OpenComputersGL/Main.lua +++ b/lib/OpenComputersGL/Main.lua @@ -151,24 +151,24 @@ function OCGL.getTriangleLightIntensity(vertex1, vertex2, vertex3, indexedLight) if lightDistance <= indexedLight[3] then local normalVector = vector.getSurfaceNormal(vertex1, vertex2, vertex3) - -- buffer.text(2, buffer.screen.height - 2, 0x0, "normalVector: " .. normalVector[1] .. " x " .. normalVector[2] .. " x " .. normalVector[3]) + -- buffer.text(2, buffer.height - 2, 0x0, "normalVector: " .. normalVector[1] .. " x " .. normalVector[2] .. " x " .. normalVector[3]) local cameraScalar = vector.scalarMultiply({0, 0, 100}, normalVector) local lightScalar = vector.scalarMultiply(lightVector, normalVector ) - -- buffer.text(2, buffer.screen.height - 1, 0xFFFFFF, "Scalars: " .. cameraScalar .. " x " .. lightScalar) + -- buffer.text(2, buffer.height - 1, 0xFFFFFF, "Scalars: " .. cameraScalar .. " x " .. lightScalar) if cameraScalar < 0 and lightScalar >= 0 or cameraScalar >= 0 and lightScalar < 0 then local absAngle = math.abs(math.acos(lightScalar / (lightDistance * vector.length(normalVector)))) if absAngle > 1.5707963267949 then absAngle = 3.1415926535898 - absAngle end - -- buffer.text(2, buffer.screen.height, 0xFFFFFF, "Angle: " .. math.deg(angle) .. ", newAngle: " .. math.deg(absAngle) .. ", intensity: " .. absAngle / 1.5707963267949) + -- buffer.text(2, buffer.height, 0xFFFFFF, "Angle: " .. math.deg(angle) .. ", newAngle: " .. math.deg(absAngle) .. ", intensity: " .. absAngle / 1.5707963267949) return indexedLight[2] * (1 - lightDistance / indexedLight[3]) * (1 - absAngle / 1.5707963267949) else return 0 end else - -- buffer.text(2, buffer.screen.height, 0x0, "Out of light range: " .. lightDistance .. " vs " .. indexedLight[2]) + -- buffer.text(2, buffer.height, 0x0, "Out of light range: " .. lightDistance .. " vs " .. indexedLight[2]) return 0 end end diff --git a/lib/advancedLua.lua b/lib/advancedLua.lua index 60ed3986..7769d947 100755 --- a/lib/advancedLua.lua +++ b/lib/advancedLua.lua @@ -249,11 +249,11 @@ end function filesystem.directorySize(path) local size = 0 - for file in filesystmem.list(path) do - if filesystmem.isDirectory(path .. file) then + for file in filesystem.list(path) do + if filesystem.isDirectory(path .. file) then size = size + filesystem.directorySize(path .. file) else - size = size + filesystmem.size(path .. file) + size = size + filesystem.size(path .. file) end end diff --git a/lib/color.lua b/lib/color.lua index 59ab0028..475ea792 100755 --- a/lib/color.lua +++ b/lib/color.lua @@ -121,6 +121,10 @@ function color.to24Bit(color8Bit) return openComputersPalette[color8Bit + 1] end +function color.optimize(color24Bit) + return color.to24Bit(color.to8Bit(color24Bit)) +end + ----------------------------------------------------------------------------------------------------------------------- return color diff --git a/lib/doubleBuffering.lua b/lib/doubleBuffering.lua index 7f4fa23c..bf4b638e 100755 --- a/lib/doubleBuffering.lua +++ b/lib/doubleBuffering.lua @@ -8,7 +8,6 @@ local image = require("image") ------------------------------------------------- Constants ------------------------------------------------- - local gpu = component.gpu local buffer = {} @@ -16,55 +15,49 @@ local buffer = {} --Формула конвертации индекса массива изображения в абсолютные координаты пикселя изображения function buffer.getBufferCoordinatesByIndex(index) - local integer, fractional = math.modf(index / (buffer.screen.tripleWidth)) - return math.ceil(fractional * buffer.screen.width), integer + 1 + local integer, fractional = math.modf(index / (buffer.tripleWidth)) + return math.ceil(fractional * buffer.width), integer + 1 end --Формула конвертации абсолютных координат пикселя изображения в индекс для массива изображения function buffer.getBufferIndexByCoordinates(x, y) - return buffer.screen.tripleWidth * (y - 1) + x * 3 - 2 + return buffer.tripleWidth * (y - 1) + x * 3 - 2 end -- Установить ограниченную зону рисования. Все пиксели, не попадающие в эту зону, будут игнорироваться. -function buffer.setDrawLimit(xOrPasteArray, y, width, height) - if type(xOrPasteArray) == "table" then - buffer.drawLimit.x, buffer.drawLimit.y, buffer.drawLimit.x2, buffer.drawLimit.y2, buffer.drawLimit.width, buffer.drawLimit.height = xOrPasteArray.x, xOrPasteArray.y, xOrPasteArray.x2, xOrPasteArray.y2, xOrPasteArray.width, xOrPasteArray.height - else - buffer.drawLimit.x, buffer.drawLimit.y, buffer.drawLimit.x2, buffer.drawLimit.y2, buffer.drawLimit.width, buffer.drawLimit.height = xOrPasteArray, y, xOrPasteArray + width - 1, y + height - 1, width, height - end +function buffer.setDrawLimit(x1, y1, x2, y2) + buffer.drawLimit.x1, buffer.drawLimit.y1, buffer.drawLimit.x2, buffer.drawLimit.y2 = x1, y1, x2, y2 end -- Удалить ограничение зоны рисования, по умолчанию она будет от 1х1 до координат размера экрана. function buffer.resetDrawLimit() - buffer.drawLimit.x, buffer.drawLimit.y, buffer.drawLimit.x2, buffer.drawLimit.y2, buffer.drawLimit.width, buffer.drawLimit.height = 1, 1, buffer.screen.width, buffer.screen.height, buffer.screen.width, buffer.screen.height + buffer.drawLimit.x1, buffer.drawLimit.y1, buffer.drawLimit.x2, buffer.drawLimit.y2 = 1, 1, buffer.width, buffer.height end -- Cкопировать ограничение зоны рисования в виде отдельного массива function buffer.getDrawLimit() - return { x = buffer.drawLimit.x, y = buffer.drawLimit.y, x2 = buffer.drawLimit.x2, y2 = buffer.drawLimit.y2, width = buffer.drawLimit.width, height = buffer.drawLimit.height } + return buffer.drawLimit.x1, buffer.drawLimit.y1, buffer.drawLimit.x2, buffer.drawLimit.y2 end -- Создание массивов буфера и всех необходимых параметров function buffer.flush(width, height) - buffer.screen = { - current = {}, - new = {}, - width = width, - height = height, - tripleWidth = width * 3 - } + buffer.currentFrame = {} + buffer.newFrame = {} + buffer.width = width + buffer.height = height + buffer.tripleWidth = width * 3 buffer.drawLimit = {} buffer.resetDrawLimit() - for y = 1, buffer.screen.height do - for x = 1, buffer.screen.width do - table.insert(buffer.screen.current, 0x010101) - table.insert(buffer.screen.current, 0xFEFEFE) - table.insert(buffer.screen.current, " ") + for y = 1, buffer.height do + for x = 1, buffer.width do + table.insert(buffer.currentFrame, 0x010101) + table.insert(buffer.currentFrame, 0xFEFEFE) + table.insert(buffer.currentFrame, " ") - table.insert(buffer.screen.new, 0x010101) - table.insert(buffer.screen.new, 0xFEFEFE) - table.insert(buffer.screen.new, " ") + table.insert(buffer.newFrame, 0x010101) + table.insert(buffer.newFrame, 0xFEFEFE) + table.insert(buffer.newFrame, " ") end end end @@ -83,17 +76,17 @@ end ------------------------------------------------- Методы отрисовки ----------------------------------------------------------------- function buffer.rawSet(index, background, foreground, symbol) - buffer.screen.new[index], buffer.screen.new[index + 1], buffer.screen.new[index + 2] = background, foreground, symbol + buffer.newFrame[index], buffer.newFrame[index + 1], buffer.newFrame[index + 2] = background, foreground, symbol end function buffer.rawGet(index) - return buffer.screen.new[index], buffer.screen.new[index + 1], buffer.screen.new[index + 2] + return buffer.newFrame[index], buffer.newFrame[index + 1], buffer.newFrame[index + 2] end -- Получить информацию о пикселе из буфера function buffer.get(x, y) local index = buffer.getBufferIndexByCoordinates(x, y) - if x >= 1 and y >= 1 and x <= buffer.screen.width and y <= buffer.screen.height then + if x >= 1 and y >= 1 and x <= buffer.width and y <= buffer.height then return buffer.rawGet(index) else return 0x000000, 0x000000, " " @@ -103,7 +96,7 @@ end -- Установить пиксель в буфере function buffer.set(x, y, background, foreground, symbol) local index = buffer.getBufferIndexByCoordinates(x, y) - if x >= buffer.drawLimit.x and y >= buffer.drawLimit.y and x <= buffer.drawLimit.x2 and y <= buffer.drawLimit.y2 then + if x >= buffer.drawLimit.x1 and y >= buffer.drawLimit.y1 and x <= buffer.drawLimit.x2 and y <= buffer.drawLimit.y2 then buffer.rawSet(index, background, foreground or 0x0, symbol or " ") end end @@ -120,18 +113,18 @@ function buffer.square(x, y, width, height, background, foreground, symbol, tran if not foreground then foreground = 0x000000 end if not symbol then symbol = " " end - local index, indexStepForward, indexPlus1 = buffer.getBufferIndexByCoordinates(x, y), (buffer.screen.width - width) * 3 + local index, indexStepForward, indexPlus1 = buffer.getBufferIndexByCoordinates(x, y), (buffer.width - width) * 3 for j = y, (y + height - 1) do for i = x, (x + width - 1) do - if i >= buffer.drawLimit.x and j >= buffer.drawLimit.y and i <= buffer.drawLimit.x2 and j <= buffer.drawLimit.y2 then + if i >= buffer.drawLimit.x1 and j >= buffer.drawLimit.y1 and i <= buffer.drawLimit.x2 and j <= buffer.drawLimit.y2 then indexPlus1 = index + 1 if transparency then - buffer.screen.new[index] = color.blend(buffer.screen.new[index], background, transparency) - buffer.screen.new[indexPlus1] = color.blend(buffer.screen.new[indexPlus1], background, transparency) + buffer.newFrame[index] = color.blend(buffer.newFrame[index], background, transparency) + buffer.newFrame[indexPlus1] = color.blend(buffer.newFrame[indexPlus1], background, transparency) else - buffer.screen.new[index] = background - buffer.screen.new[indexPlus1] = foreground - buffer.screen.new[index + 2] = symbol + buffer.newFrame[index] = background + buffer.newFrame[indexPlus1] = foreground + buffer.newFrame[index + 2] = symbol end end index = index + 3 @@ -143,7 +136,7 @@ buffer.rectangle = buffer.square --Очистка экрана, по сути более короткая запись buffer.square function buffer.clear(color, transparency) - buffer.square(1, 1, buffer.screen.width, buffer.screen.height, color or 0x262626, 0x000000, " ", transparency) + buffer.square(1, 1, buffer.width, buffer.height, color or 0x262626, 0x000000, " ", transparency) end --Скопировать область изображения и вернуть ее в виде массива @@ -153,7 +146,7 @@ function buffer.copy(x, y, width, height) height = height, } - if x < 1 or y < 1 or x + width - 1 > buffer.screen.width or y + height - 1 > buffer.screen.height then + if x < 1 or y < 1 or x + width - 1 > buffer.width or y + height - 1 > buffer.height then error("Copy field is out of screen range") end @@ -161,9 +154,9 @@ function buffer.copy(x, y, width, height) for j = y, (y + height - 1) do for i = x, (x + width - 1) do index = buffer.getBufferIndexByCoordinates(i, j) - table.insert(copyArray, buffer.screen.new[index]) - table.insert(copyArray, buffer.screen.new[index + 1]) - table.insert(copyArray, buffer.screen.new[index + 2]) + table.insert(copyArray, buffer.newFrame[index]) + table.insert(copyArray, buffer.newFrame[index + 1]) + table.insert(copyArray, buffer.newFrame[index + 2]) end end @@ -177,16 +170,16 @@ function buffer.paste(x, y, copyArray) for j = y, (y + copyArray.height - 1) do for i = x, (x + copyArray.width - 1) do - if i >= buffer.drawLimit.x and j >= buffer.drawLimit.y and i <= buffer.drawLimit.x2 and j <= buffer.drawLimit.y2 then + if i >= buffer.drawLimit.x1 and j >= buffer.drawLimit.y1 and i <= buffer.drawLimit.x2 and j <= buffer.drawLimit.y2 then --Рассчитываем индекс массива основного изображения index = buffer.getBufferIndexByCoordinates(i, j) --Копипаст формулы, аккуратнее! --Рассчитываем индекс массива вставочного изображения arrayIndex = (copyArray.width * (j - y) + (i - x + 1)) * 3 - 2 --Вставляем данные - buffer.screen.new[index] = copyArray[arrayIndex] - buffer.screen.new[index + 1] = copyArray[arrayIndex + 1] - buffer.screen.new[index + 2] = copyArray[arrayIndex + 2] + buffer.newFrame[index] = copyArray[arrayIndex] + buffer.newFrame[index + 1] = copyArray[arrayIndex + 1] + buffer.newFrame[index + 2] = copyArray[arrayIndex + 2] end end end @@ -233,9 +226,9 @@ function buffer.text(x, y, textColor, text, transparency) local index, sText = buffer.getBufferIndexByCoordinates(x, y), unicode.len(text) for i = 1, sText do - if x >= buffer.drawLimit.x and y >= buffer.drawLimit.y and x <= buffer.drawLimit.x2 and y <= buffer.drawLimit.y2 then - buffer.screen.new[index + 1] = not transparency and textColor or color.blend(buffer.screen.new[index], textColor, transparency) - buffer.screen.new[index + 2] = unicode.sub(text, i, i) + if x >= buffer.drawLimit.x1 and y >= buffer.drawLimit.y1 and x <= buffer.drawLimit.x2 and y <= buffer.drawLimit.y2 then + buffer.newFrame[index + 1] = not transparency and textColor or color.blend(buffer.newFrame[index], textColor, transparency) + buffer.newFrame[index + 2] = unicode.sub(text, i, i) end index = index + 3 x = x + 1 @@ -244,25 +237,25 @@ end -- Отрисовка изображения function buffer.image(x, y, picture) - local xPos, xEnd, bufferIndexStepOnReachOfImageWidth = x, x + picture[1] - 1, (buffer.screen.width - picture[1]) * 3 + local xPos, xEnd, bufferIndexStepOnReachOfImageWidth = x, x + picture[1] - 1, (buffer.width - picture[1]) * 3 local bufferIndex = buffer.getBufferIndexByCoordinates(x, y) local imageIndexPlus2, imageIndexPlus3 for imageIndex = 3, #picture, 4 do - if xPos >= buffer.drawLimit.x and y >= buffer.drawLimit.y and xPos <= buffer.drawLimit.x2 and y <= buffer.drawLimit.y2 then + if xPos >= buffer.drawLimit.x1 and y >= buffer.drawLimit.y1 and xPos <= buffer.drawLimit.x2 and y <= buffer.drawLimit.y2 then imageIndexPlus2, imageIndexPlus3 = imageIndex + 2, imageIndex + 3 if picture[imageIndexPlus2] == 0x00 then - buffer.screen.new[bufferIndex] = picture[imageIndex] - buffer.screen.new[bufferIndex + 1] = picture[imageIndex + 1] - buffer.screen.new[bufferIndex + 2] = picture[imageIndexPlus3] + buffer.newFrame[bufferIndex] = picture[imageIndex] + buffer.newFrame[bufferIndex + 1] = picture[imageIndex + 1] + buffer.newFrame[bufferIndex + 2] = picture[imageIndexPlus3] elseif picture[imageIndexPlus2] > 0x00 and picture[imageIndexPlus2] < 0xFF then - buffer.screen.new[bufferIndex] = color.blend(buffer.screen.new[bufferIndex], picture[imageIndex], picture[imageIndexPlus2]) - buffer.screen.new[bufferIndex + 1] = picture[imageIndex + 1] - buffer.screen.new[bufferIndex + 2] = picture[imageIndexPlus3] + buffer.newFrame[bufferIndex] = color.blend(buffer.newFrame[bufferIndex], picture[imageIndex], picture[imageIndexPlus2]) + buffer.newFrame[bufferIndex + 1] = picture[imageIndex + 1] + buffer.newFrame[bufferIndex + 2] = picture[imageIndexPlus3] elseif picture[imageIndexPlus2] == 0xFF and picture[imageIndexPlus3] ~= " " then - buffer.screen.new[bufferIndex + 1] = picture[imageIndex + 1] - buffer.screen.new[bufferIndex + 2] = picture[imageIndexPlus3] + buffer.newFrame[bufferIndex + 1] = picture[imageIndex + 1] + buffer.newFrame[bufferIndex + 2] = picture[imageIndexPlus3] end end @@ -273,6 +266,18 @@ function buffer.image(x, y, picture) end end +-- Прамоугольная рамочка +function buffer.frame(x, y, width, height, color) + local stringUp, stringDown, x2 = "┌" .. string.rep("─", width - 2) .. "┐", "└" .. string.rep("─", width - 2) .. "┘", x + width - 1 + buffer.text(x, y, color, stringUp); y = y + 1 + for i = 1, (height - 2) do + buffer.text(x, y, color, "│") + buffer.text(x2, y, color, "│") + y = y + 1 + end + buffer.text(x, y, color, stringDown) +end + -- Кнопка фиксированных размеров function buffer.button(x, y, width, height, background, foreground, text) local textLength = unicode.len(text) @@ -297,6 +302,17 @@ function buffer.adaptiveButton(x, y, xOffset, yOffset, background, foreground, t return x, y, (x + width - 1), (y + height - 1) end +-- Кнопка в виде текста в рамке +function buffer.framedButton(x, y, width, height, backColor, buttonColor, text) + buffer.square(x, y, width, height, backColor, buttonColor, " ") + buffer.frame(x, y, width, height, buttonColor) + + x = math.floor(x + width / 2 - unicode.len(text) / 2) + y = math.floor(y + height / 2) + + buffer.text(x, y, buttonColor, text) +end + -- Вертикальный скролл-бар function buffer.scrollBar(x, y, width, height, countOfAllElements, currentElement, backColor, frontColor) local sizeOfScrollBar = math.ceil(height / countOfAllElements) @@ -332,102 +348,59 @@ function buffer.customImage(x, y, pixels) return (x + 1), (y + 1), (x + #pixels[1]), (y + #pixels) end ---Нарисовать топ-меню, горизонтальная полоска такая с текстами -function buffer.menu(x, y, width, color, selectedObject, ...) - local objects = { ... } - local objectsToReturn = {} - local xPos = x + 2 - local spaceBetween = 2 - buffer.square(x, y, width, 1, color, 0xFFFFFF, " ") - for i = 1, #objects do - if i == selectedObject then - buffer.square(xPos - 1, y, unicode.len(objects[i][1]) + spaceBetween, 1, 0x3366CC, 0xFFFFFF, " ") - buffer.text(xPos, y, 0xFFFFFF, objects[i][1]) - else - buffer.text(xPos, y, objects[i][2], objects[i][1]) - end - objectsToReturn[objects[i][1]] = { xPos, y, xPos + unicode.len(objects[i][1]) - 1, y, i } - xPos = xPos + unicode.len(objects[i][1]) + spaceBetween - end - return objectsToReturn -end - --- Прамоугольная рамочка -function buffer.frame(x, y, width, height, color) - local stringUp, stringDown, x2 = "┌" .. string.rep("─", width - 2) .. "┐", "└" .. string.rep("─", width - 2) .. "┘", x + width - 1 - buffer.text(x, y, color, stringUp); y = y + 1 - for i = 1, (height - 2) do - buffer.text(x, y, color, "│") - buffer.text(x2, y, color, "│") - y = y + 1 - end - buffer.text(x, y, color, stringDown) -end - --- Кнопка в виде текста в рамке -function buffer.framedButton(x, y, width, height, backColor, buttonColor, text) - buffer.square(x, y, width, height, backColor, buttonColor, " ") - buffer.frame(x, y, width, height, buttonColor) - - x = math.floor(x + width / 2 - unicode.len(text) / 2) - y = math.floor(y + height / 2) - - buffer.text(x, y, buttonColor, text) -end - ------------------------------------------- Semipixel methods ------------------------------------------------------------------------ function buffer.semiPixelRawSet(index, color, yPercentTwoEqualsZero) local upperPixel, lowerPixel, bothPixel, indexPlus1, indexPlus2 = "▀", "▄", " ", index + 1, index + 2 - local background, foreground, symbol = buffer.screen.new[index], buffer.screen.new[indexPlus1], buffer.screen.new[indexPlus2] + local background, foreground, symbol = buffer.newFrame[index], buffer.newFrame[indexPlus1], buffer.newFrame[indexPlus2] if yPercentTwoEqualsZero then if symbol == upperPixel then if color == foreground then - buffer.screen.new[index], buffer.screen.new[indexPlus1], buffer.screen.new[indexPlus2] = color, foreground, bothPixel + buffer.newFrame[index], buffer.newFrame[indexPlus1], buffer.newFrame[indexPlus2] = color, foreground, bothPixel else - buffer.screen.new[index], buffer.screen.new[indexPlus1], buffer.screen.new[indexPlus2] = color, foreground, symbol + buffer.newFrame[index], buffer.newFrame[indexPlus1], buffer.newFrame[indexPlus2] = color, foreground, symbol end elseif symbol == bothPixel then if color ~= background then - buffer.screen.new[index], buffer.screen.new[indexPlus1], buffer.screen.new[indexPlus2] = background, color, lowerPixel + buffer.newFrame[index], buffer.newFrame[indexPlus1], buffer.newFrame[indexPlus2] = background, color, lowerPixel end else - buffer.screen.new[index], buffer.screen.new[indexPlus1], buffer.screen.new[indexPlus2] = background, color, lowerPixel + buffer.newFrame[index], buffer.newFrame[indexPlus1], buffer.newFrame[indexPlus2] = background, color, lowerPixel end else if symbol == lowerPixel then if color == foreground then - buffer.screen.new[index], buffer.screen.new[indexPlus1], buffer.screen.new[indexPlus2] = color, foreground, bothPixel + buffer.newFrame[index], buffer.newFrame[indexPlus1], buffer.newFrame[indexPlus2] = color, foreground, bothPixel else - buffer.screen.new[index], buffer.screen.new[indexPlus1], buffer.screen.new[indexPlus2] = color, foreground, symbol + buffer.newFrame[index], buffer.newFrame[indexPlus1], buffer.newFrame[indexPlus2] = color, foreground, symbol end elseif symbol == bothPixel then if color ~= background then - buffer.screen.new[index], buffer.screen.new[indexPlus1], buffer.screen.new[indexPlus2] = background, color, upperPixel + buffer.newFrame[index], buffer.newFrame[indexPlus1], buffer.newFrame[indexPlus2] = background, color, upperPixel end else - buffer.screen.new[index], buffer.screen.new[indexPlus1], buffer.screen.new[indexPlus2] = background, color, upperPixel + buffer.newFrame[index], buffer.newFrame[indexPlus1], buffer.newFrame[indexPlus2] = background, color, upperPixel end end end function buffer.semiPixelSet(x, y, color) local yFixed = math.ceil(y / 2) - if x >= buffer.drawLimit.x and yFixed >= buffer.drawLimit.y and x <= buffer.drawLimit.x2 and yFixed <= buffer.drawLimit.y2 then + if x >= buffer.drawLimit.x1 and yFixed >= buffer.drawLimit.y1 and x <= buffer.drawLimit.x2 and yFixed <= buffer.drawLimit.y2 then buffer.semiPixelRawSet(buffer.getBufferIndexByCoordinates(x, yFixed), color, y % 2 == 0) end end function buffer.semiPixelSquare(x, y, width, height, color) -- for j = y, y + height - 1 do for i = x, x + width - 1 do buffer.semiPixelSet(i, j, color) end end - local index, indexStepForward, indexStepBackward, jPercentTwoEqualsZero, jFixed = buffer.getBufferIndexByCoordinates(x, math.ceil(y / 2)), (buffer.screen.width - width) * 3, width * 3 + local index, indexStepForward, indexStepBackward, jPercentTwoEqualsZero, jFixed = buffer.getBufferIndexByCoordinates(x, math.ceil(y / 2)), (buffer.width - width) * 3, width * 3 for j = y, y + height - 1 do jPercentTwoEqualsZero = j % 2 == 0 for i = x, x + width - 1 do jFixed = math.ceil(j / 2) - -- if x >= buffer.drawLimit.x and jFixed >= buffer.drawLimit.y and x <= buffer.drawLimit.x2 and jFixed <= buffer.drawLimit.y2 then + -- if x >= buffer.drawLimit.x1 and jFixed >= buffer.drawLimit.y1 and x <= buffer.drawLimit.x2 and jFixed <= buffer.drawLimit.y2 then buffer.semiPixelRawSet(index, color, jPercentTwoEqualsZero) -- end index = index + 3 @@ -536,9 +509,9 @@ function buffer.calculateDifference(index) local somethingIsChanged = false --Если цвет фона на новом экране отличается от цвета фона на текущем, то - if buffer.screen.new[index] ~= buffer.screen.current[index] then + if buffer.newFrame[index] ~= buffer.currentFrame[index] then --Присваиваем цвету фона на текущем экране значение цвета фона на новом экране - buffer.screen.current[index] = buffer.screen.new[index] + buffer.currentFrame[index] = buffer.newFrame[index] --Говорим системе, что что-то изменилось somethingIsChanged = true end @@ -546,16 +519,16 @@ function buffer.calculateDifference(index) index = index + 1 --Аналогично для цвета текста - if buffer.screen.new[index] ~= buffer.screen.current[index] then - buffer.screen.current[index] = buffer.screen.new[index] + if buffer.newFrame[index] ~= buffer.currentFrame[index] then + buffer.currentFrame[index] = buffer.newFrame[index] somethingIsChanged = true end index = index + 1 --И для символа - if buffer.screen.new[index] ~= buffer.screen.current[index] then - buffer.screen.current[index] = buffer.screen.new[index] + if buffer.newFrame[index] ~= buffer.currentFrame[index] then + buffer.currentFrame[index] = buffer.newFrame[index] somethingIsChanged = true end @@ -565,12 +538,12 @@ end -- Функция группировки изменений и их отрисовки на экран function buffer.draw(force) -- Всякое дерьмо, необходимое для расчетов - local index, indexStepOnEveryLine, somethingIsChanged, indexPlus1, indexPlus2, sameCharArray, x, xCharCheck, indexCharCheck, currentBackground, currentForeground = buffer.getBufferIndexByCoordinates(buffer.drawLimit.x, buffer.drawLimit.y), (buffer.screen.width - buffer.drawLimit.width) * 3 + local index, indexStepOnEveryLine, somethingIsChanged, indexPlus1, indexPlus2, sameCharArray, x, xCharCheck, indexCharCheck, currentBackground, currentForeground = buffer.getBufferIndexByCoordinates(buffer.drawLimit.x1, buffer.drawLimit.y1), (buffer.width - buffer.drawLimit.x2 + buffer.drawLimit.x1 - 1) * 3 -- Массив третьего буфера, содержащий в себе измененные пиксели - buffer.screen.changes = {} + buffer.changes = {} - for y = buffer.drawLimit.y, buffer.drawLimit.y2 do - x = buffer.drawLimit.x + for y = buffer.drawLimit.y1, buffer.drawLimit.y2 do + x = buffer.drawLimit.x1 while x <= buffer.drawLimit.x2 do --Чутка оптимизируем расчеты indexPlus1, indexPlus2 = index + 1, index + 2 @@ -579,22 +552,22 @@ function buffer.draw(force) --Если хоть что-то изменилось, то начинаем работу if somethingIsChanged or force then --Оптимизация by Krutoy, создаем массив, в который заносим чарсы. Работает быстрее, чем конкатенейт строк - sameCharArray = { buffer.screen.current[indexPlus2] } + sameCharArray = { buffer.currentFrame[indexPlus2] } --Загоняем в наш чарс-массив одинаковые пиксели справа, если таковые имеются xCharCheck, indexCharCheck = x + 1, index + 3 while xCharCheck <= buffer.drawLimit.x2 do indexCharCheckPlus2 = indexCharCheck + 2 if - buffer.screen.current[index] == buffer.screen.new[indexCharCheck] + buffer.currentFrame[index] == buffer.newFrame[indexCharCheck] and ( - buffer.screen.new[indexCharCheckPlus2] == " " + buffer.newFrame[indexCharCheckPlus2] == " " or - buffer.screen.current[indexPlus1] == buffer.screen.new[indexCharCheck + 1] + buffer.currentFrame[indexPlus1] == buffer.newFrame[indexCharCheck + 1] ) then buffer.calculateDifference(indexCharCheck) - table.insert(sameCharArray, buffer.screen.current[indexCharCheckPlus2]) + table.insert(sameCharArray, buffer.currentFrame[indexCharCheckPlus2]) else break end @@ -604,12 +577,12 @@ function buffer.draw(force) end --Заполняем третий буфер полученными данными - buffer.screen.changes[buffer.screen.current[index]] = buffer.screen.changes[buffer.screen.current[index]] or {} - buffer.screen.changes[buffer.screen.current[index]][buffer.screen.current[indexPlus1]] = buffer.screen.changes[buffer.screen.current[index]][buffer.screen.current[indexPlus1]] or {} + buffer.changes[buffer.currentFrame[index]] = buffer.changes[buffer.currentFrame[index]] or {} + buffer.changes[buffer.currentFrame[index]][buffer.currentFrame[indexPlus1]] = buffer.changes[buffer.currentFrame[index]][buffer.currentFrame[indexPlus1]] or {} - table.insert(buffer.screen.changes[buffer.screen.current[index]][buffer.screen.current[indexPlus1]], x) - table.insert(buffer.screen.changes[buffer.screen.current[index]][buffer.screen.current[indexPlus1]], y) - table.insert(buffer.screen.changes[buffer.screen.current[index]][buffer.screen.current[indexPlus1]], table.concat(sameCharArray)) + table.insert(buffer.changes[buffer.currentFrame[index]][buffer.currentFrame[indexPlus1]], x) + table.insert(buffer.changes[buffer.currentFrame[index]][buffer.currentFrame[indexPlus1]], y) + table.insert(buffer.changes[buffer.currentFrame[index]][buffer.currentFrame[indexPlus1]], table.concat(sameCharArray)) --Смещаемся по иксу вправо index = index + #sameCharArray * 3 - 3 @@ -627,18 +600,18 @@ function buffer.draw(force) currentBackground, currentForeground = nil, nil --Перебираем все цвета текста и фона, выполняя гпу-операции - for background in pairs(buffer.screen.changes) do + for background in pairs(buffer.changes) do gpu.setBackground(background) - for foreground in pairs(buffer.screen.changes[background]) do + for foreground in pairs(buffer.changes[background]) do if currentForeground ~= foreground then gpu.setForeground(foreground); currentForeground = foreground end - for i = 1, #buffer.screen.changes[background][foreground], 3 do - gpu.set(buffer.screen.changes[background][foreground][i], buffer.screen.changes[background][foreground][i + 1], buffer.screen.changes[background][foreground][i + 2]) + for i = 1, #buffer.changes[background][foreground], 3 do + gpu.set(buffer.changes[background][foreground][i], buffer.changes[background][foreground][i + 1], buffer.changes[background][foreground][i + 2]) end end end --Очищаем память, ибо на кой хер нам хранить третий буфер - buffer.screen.changes = nil + buffer.changes = nil end ------------------------------------------------------------------------------------------------------ diff --git a/lib/palette.lua b/lib/palette.lua index 74836788..6f6ad36c 100755 --- a/lib/palette.lua +++ b/lib/palette.lua @@ -1,6 +1,4 @@ --- _G.GUI, package.loaded.GUI = nil, nil - local advancedLua = require("advancedLua") local component = require("component") local fs = require("filesystem") @@ -12,283 +10,275 @@ local GUI = require("GUI") -------------------------------------------------------------------------------------------------------------- local palette = {} -local window -local currentColor, favourites -local xBigCrest, yBigCrest, yMiniCrest -local favouritesContainer, bigRainbow, miniRainbow, currentColorPanel -local pathToFavouritesConfig = "/MineOS/System/Palette/Favourites.cfg" -local inputs +local pathToFavouritesConfig, favourites = "/MineOS/System/Palette/Favourites.cfg" -------------------------------------------------------------------------------------------------------------- -local function switchColorFromHex(hex) - currentColor = {hsb = {}, rgb = {}, hex = hex} - currentColor.rgb.red, currentColor.rgb.green, currentColor.rgb.blue = color.HEXToRGB(hex) - currentColor.hsb.hue, currentColor.hsb.saturation, currentColor.hsb.brightness = color.RGBToHSB(currentColor.rgb.red, currentColor.rgb.green, currentColor.rgb.blue) -end - -local function switchColorFromHsb(hue, saturation, brightness) - currentColor = {hsb = {hue = hue, saturation = saturation, brightness = brightness}, rgb = {}, hex = nil} - currentColor.rgb.red, currentColor.rgb.green, currentColor.rgb.blue = color.HSBToRGB(hue, saturation, brightness) - currentColor.hex = color.RGBToHEX(currentColor.rgb.red, currentColor.rgb.green, currentColor.rgb.blue) -end - -local function switchColorFromRgb(red, green, blue) - currentColor = {hsb = {}, rgb = {red = red, green = green, blue = blue}, hex = nil} - currentColor.hsb.hue, currentColor.hsb.saturation, currentColor.hsb.brightness = color.RGBToHSB(red, green, blue) - currentColor.hex = color.RGBToHEX(red, green, blue) -end - --------------------------------------------------------------------------------------------------------------- - -local function randomizeFavourites() - favourites = {}; for i = 1, 6 do favourites[i] = math.random(0x000000, 0xFFFFFF) end -end - -local function saveFavoutites() +local function saveFavourites() table.toFile(pathToFavouritesConfig, favourites) end -local function loadFavourites() - if fs.exists(pathToFavouritesConfig) then - favourites = table.fromFile(pathToFavouritesConfig) - else - randomizeFavourites() - saveFavoutites() - end +-------------------------------------------------------------------------------------------------------------- + +local function changeInputsValueToCurrentColor(window) + window.inputs[1].inputTextBox.text = tostring(window.color.rgb.red) + window.inputs[2].inputTextBox.text = tostring(window.color.rgb.green) + window.inputs[3].inputTextBox.text = tostring(window.color.rgb.blue) + window.inputs[4].inputTextBox.text = tostring(math.floor(window.color.hsb.hue)) + window.inputs[5].inputTextBox.text = tostring(math.floor(window.color.hsb.saturation)) + window.inputs[6].inputTextBox.text = tostring(math.floor(window.color.hsb.brightness)) + window.inputs[7].inputTextBox.text = string.format("%06X", window.color.hex) + window.colorPanel.colors.background = window.color.hex +end + +local function switchColorFromHex(window, hex) + window.color.hex = hex + window.color.rgb.red, window.color.rgb.green, window.color.rgb.blue = color.HEXToRGB(hex) + window.color.hsb.hue, window.color.hsb.saturation, window.color.hsb.brightness = color.RGBToHSB(window.color.rgb.red, window.color.rgb.green, window.color.rgb.blue) + changeInputsValueToCurrentColor(window) +end + +local function switchColorFromHsb(window, hue, saturation, brightness) + window.color.hsb.hue, window.color.hsb.saturation, window.color.hsb.brightness = hue, saturation, brightness + window.color.rgb.red, window.color.rgb.green, window.color.rgb.blue = color.HSBToRGB(hue, saturation, brightness) + window.color.hex = color.RGBToHEX(window.color.rgb.red, window.color.rgb.green, window.color.rgb.blue) + changeInputsValueToCurrentColor(window) +end + +local function switchColorFromRgb(window, red, green, blue) + window.color.rgb.red, window.color.rgb.green, window.color.rgb.blue = red, green, blue + window.color.hsb.hue, window.color.hsb.saturation, window.color.hsb.brightness = color.RGBToHSB(red, green, blue) + window.color.hex = color.RGBToHEX(red, green, blue) + changeInputsValueToCurrentColor(window) end -------------------------------------------------------------------------------------------------------------- -local function changeInputsValueToCurrentColor() - inputs[1].object.text = tostring(currentColor.rgb.red) - inputs[2].object.text = tostring(currentColor.rgb.green) - inputs[3].object.text = tostring(currentColor.rgb.blue) - inputs[4].object.text = tostring(math.floor(currentColor.hsb.hue)) - inputs[5].object.text = tostring(math.floor(currentColor.hsb.saturation)) - inputs[6].object.text = tostring(math.floor(currentColor.hsb.brightness)) - inputs[7].object.text = string.format("%06X", currentColor.hex) -end - --------------------------------------------------------------------------------------------------------------- - -local function refreshBigRainbow(width, height) - local saturationStep, brightnessStep, saturation, brightness = 100 / width, 100 / (height * 2), 0, 100 - for j = 1, height do - for i = 1, width do - local background = color.HSBToHEX(currentColor.hsb.hue, saturation, brightness) - local foreground = color.HSBToHEX(currentColor.hsb.hue, saturation, brightness - brightnessStep) - image.set(bigRainbow.image, i, j, background, foreground, 0x0, "▄") +local function refreshBigRainbow(window) + local saturationStep, brightnessStep, saturation, brightness = 100 / image.getWidth(window.bigRainbow.image), 100 / (image.getHeight(window.bigRainbow.image)), 0, 100 + for j = 1, image.getHeight(window.bigRainbow.image) do + for i = 1, image.getWidth(window.bigRainbow.image) do + image.set(window.bigRainbow.image, i, j, color.optimize(color.HSBToHEX(window.color.hsb.hue, saturation, brightness)), 0x0, 0x0, " ") saturation = saturation + saturationStep end - saturation = 0; brightness = brightness - brightnessStep - brightnessStep + saturation, brightness = 0, brightness - brightnessStep end end -local function refreshMiniRainbow(width, height) - local hueStep, hue = 360 / (height * 2), 0 - for j = 1, height do - for i = 1, width do - local background = color.HSBToHEX(hue, 100, 100) - local foreground = color.HSBToHEX(hue + hueStep, 100, 100) - image.set(miniRainbow.image, i, j, background, foreground, 0x0, "▄") +local function refreshMiniRainbow(window) + local hueStep, hue = 360 / (image.getHeight(window.miniRainbow.image)), 0 + for j = 1, image.getHeight(window.miniRainbow.image) do + for i = 1, image.getWidth(window.miniRainbow.image) do + image.set(window.miniRainbow.image, i, j, color.optimize(color.HSBToHEX(hue, 100, 100)), 0x0, 0x0, " ") end - hue = hue + hueStep + hueStep + hue = hue + hueStep end end -local function refreshRainbows() - refreshBigRainbow(50, 25) - refreshMiniRainbow(3, 25) -end - -local function betterVisiblePixel(x, y, symbol) - local background, foreground = buffer.get(x, y) - if background > 0x888888 then foreground = 0x000000 else foreground = 0xFFFFFF end - buffer.set(x, y, background, foreground, symbol) -end - -local function drawBigCrest() - local drawLimit = buffer.getDrawLimit(); buffer.setDrawLimit(window.x, window.y, bigRainbow.width + 2, bigRainbow.height) - betterVisiblePixel(xBigCrest - 2, yBigCrest, "─") - betterVisiblePixel(xBigCrest - 1, yBigCrest, "─") - betterVisiblePixel(xBigCrest + 1, yBigCrest, "─") - betterVisiblePixel(xBigCrest + 2, yBigCrest, "─") - betterVisiblePixel(xBigCrest, yBigCrest - 1, "│") - betterVisiblePixel(xBigCrest, yBigCrest + 1, "│") - buffer.setDrawLimit(drawLimit) -end - -local function drawMiniCrest() - buffer.text(miniRainbow.x - 1, yMiniCrest, 0x000000, ">") - buffer.text(miniRainbow.x + miniRainbow.width, yMiniCrest, 0x000000, "<") -end - -local function drawCrests() - drawBigCrest() - drawMiniCrest() -end - -local function drawAll() - currentColorPanel.colors.background = currentColor.hex - changeInputsValueToCurrentColor() - window:draw() - drawCrests() - buffer.draw() -end - -------------------------------------------------------------------------------------------------------------- -local function createCrestsCoordinates() - local xBigCrestModifyer = (bigRainbow.width - 1) * currentColor.hsb.saturation / 100 - local yBigCrestModifyer = (bigRainbow.height - 1) - (bigRainbow.height - 1) * currentColor.hsb.brightness / 100 - local yMiniCrestModifyer = (miniRainbow.height - 1) - (miniRainbow.height - 1) * currentColor.hsb.hue / 360 - - xBigCrest, yBigCrest, yMiniCrest = math.floor(window.x + xBigCrestModifyer), math.floor(window.y + yBigCrestModifyer), math.floor(window.y + yMiniCrestModifyer) +local function createCrestsCoordinates(window) + window.bigCrest.localPosition.x = math.floor((window.bigRainbow.width - 1) * window.color.hsb.saturation / 100) - 1 + window.bigCrest.localPosition.y = math.floor((window.bigRainbow.height - 1) - (window.bigRainbow.height - 1) * window.color.hsb.brightness / 100) + window.miniCrest.localPosition.y = math.floor(window.color.hsb.hue / 360 * window.miniRainbow.height) end -local function createInputs(x, y) - local function onAnyInputFinished() refreshRainbows(); createCrestsCoordinates(); drawAll() end - local function onHexInputFinished(object) switchColorFromHex(tonumber("0x" .. inputs[7].object.text)); onAnyInputFinished() end - local function onRgbInputFinished(object) switchColorFromRgb(tonumber(inputs[1].object.text), tonumber(inputs[2].object.text), tonumber(inputs[3].object.text)); onAnyInputFinished() end - local function onHsbInputFinished(object) switchColorFromHsb(tonumber(inputs[4].object.text), tonumber(inputs[5].object.text), tonumber(inputs[6].object.text)); onAnyInputFinished() end - - local function rgbValidaror(text) local num = tonumber(text) if num and num >= 0 and num <= 255 then return true end end - local function hValidator(text) local num = tonumber(text) if num and num >= 0 and num <= 359 then return true end end - local function sbValidator(text) local num = tonumber(text) if num and num >= 0 and num <= 100 then return true end end - local function hexValidator(text) if string.match(text, "^[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]$") then return true end end - - inputs = { - { shortcut = "R:", arrayName = "red", validator = rgbValidaror, onInputFinished = onRgbInputFinished }, - { shortcut = "G:", arrayName = "green", validator = rgbValidaror, onInputFinished = onRgbInputFinished }, - { shortcut = "B:", arrayName = "blue", validator = rgbValidaror, onInputFinished = onRgbInputFinished }, - { shortcut = "H:", arrayName = "hue", validator = hValidator, onInputFinished = onHsbInputFinished }, - { shortcut = "S:", arrayName = "saturation", validator = sbValidator, onInputFinished = onHsbInputFinished }, - { shortcut = "L:", arrayName = "brightness", validator = sbValidator, onInputFinished = onHsbInputFinished }, - { shortcut = "0x", arrayName = "red", validator = hexValidator, onInputFinished = onHexInputFinished } - } - - for i = 1, #inputs do - window:addLabel(x, y, 2, 1, 0x000000, inputs[i].shortcut) - inputs[i].object = window:addInputTextBox(x + 3, y, 9, 1, 0xFFFFFF, 0x444444, 0xFFFFFF, 0x000000, "", "", true) - inputs[i].object.validator = inputs[i].validator - inputs[i].object.onInputFinished = inputs[i].onInputFinished - y = y + 2 +local function drawBigCrestPixel(window, x, y, symbol) + if window.bigRainbow:isClicked(x, y) then + local background, foreground = buffer.get(x, y) + if background >= 0x888888 then + foreground = 0x000000 + else + foreground = 0xFFFFFF + end + buffer.set(x, y, background, foreground, symbol) end - - return y end -local function createFavourites() - for i = 1, #favourites do - local button = favouritesContainer:addButton(i * 2 - 1, 1, 2, 1, favourites[i], 0x0, 0x0, 0x0, " ") - button.onTouch = function() - switchColorFromHex(button.colors.default.background) - refreshRainbows() - createCrestsCoordinates() - drawAll() +-------------------------------------------------------------------------------------------------------------- + +function palette.window(x, y, startColor) + local window = GUI.window(x, y, 71, 25) + + window.color = {hsb = {}, rgb = {}} + window:addChild(GUI.panel(1, 1, window.width, window.height, 0xEEEEEE)) + + window.bigRainbow = window:addChild(GUI.image(1, 1, image.create(50, 25))) + window.bigCrest = window:addChild(GUI.object(1, 1, 5, 3)) + window.bigCrest.draw = function(object) + drawBigCrestPixel(window, object.x, object.y + 1, "─") + drawBigCrestPixel(window, object.x + 1, object.y + 1, "─") + drawBigCrestPixel(window, object.x + 3, object.y + 1, "─") + drawBigCrestPixel(window, object.x + 4, object.y + 1, "─") + drawBigCrestPixel(window, object.x + 2, object.y, "│") + drawBigCrestPixel(window, object.x + 2, object.y + 2, "│") + end + window.bigRainbow.eventHandler = function(mainContainer, object, eventData) + if eventData[1] == "touch" or eventData[1] == "drag" and window.bigRainbow:isClicked(eventData[3], eventData[4]) then + window.bigCrest.localPosition.x, window.bigCrest.localPosition.y = eventData[3] - window.x - 1, eventData[4] - window.y + switchColorFromHex(window, select(3, component.gpu.get(eventData[3], eventData[4]))) + mainContainer:draw() + buffer.draw() end end -end - -local function createWindow(x, y) - window = GUI.window(x, y, 71, 25, 71, 25) - x, y = 1, 1 - window:addPanel(x, y, window.width, window.height, 0xEEEEEE) - - bigRainbow = window:addImage(x, y, image.create(50, 25)) - bigRainbow.onTouch = function(eventData) - xBigCrest, yBigCrest = eventData[3], eventData[4] - local _, _, background = component.gpu.get(eventData[3], eventData[4]) - switchColorFromHex(background) - drawAll() + window.miniRainbow = window:addChild(GUI.image(53, 1, image.create(3, 25))) + window.miniCrest = window:addChild(GUI.object(52, 1, 5, 1)) + window.miniCrest.draw = function(object) + buffer.text(object.x, object.y, 0x0, ">") + buffer.text(object.x + 4, object.y, 0x0, "<") end - bigRainbow.onDrag = bigRainbow.onTouch - x = x + bigRainbow.width + 2 - - miniRainbow = window:addImage(x, y, image.create(3, 25)) - miniRainbow.onTouch = function(eventData) - yMiniCrest = eventData[4] - switchColorFromHsb((eventData[4] - miniRainbow.y) * 360 / miniRainbow.height, currentColor.hsb.saturation, currentColor.hsb.brightness) - refreshRainbows() - drawAll() - end - miniRainbow.onDrag = miniRainbow.onTouch - x, y = x + 5, y + 1 - - currentColorPanel = window:addPanel(x, y, 12, 3, currentColor.hex) - y = y + 4 - - window.okButton = window:addButton(x, y, 12, 1, 0x444444, 0xFFFFFF, 0x88FF88, 0xFFFFFF, "OK") - window.okButton.onTouch = function() - window:returnData(currentColor.hex) - end - y = y + 2 - - window:addButton(x, y, 12, 1, 0xFFFFFF, 0x444444, 0x88FF88, 0xFFFFFF, "Cancel").onTouch = function() - window:close() - end - y = y + 2 - - y = createInputs(x, y) - - favouritesContainer = window:addContainer(x, y, 12, 1) - createFavourites() - y = y + 1 - - window:addButton(x, y, 12, 1, 0xFFFFFF, 0x444444, 0x88FF88, 0xFFFFFF, "+").onTouch = function() - local favouriteExists = false; for i = 1, #favourites do if favourites[i] == currentColor.hex then favouriteExists = true; break end end - if not favouriteExists then - table.insert(favourites, 1, currentColor.hex); table.remove(favourites, #favourites) - for i = 1, #favourites do favouritesContainer.children[i].colors.default.background = favourites[i]; favouritesContainer.children[i].colors.pressed.background = 0x0 end - saveFavoutites() - drawAll() + window.miniRainbow.eventHandler = function(mainContainer, object, eventData) + if eventData[1] == "touch" or eventData[1] == "drag" then + window.miniCrest.localPosition.y = eventData[4] - window.y + 1 + switchColorFromHsb(window, (eventData[4] - window.miniRainbow.y) * 360 / window.miniRainbow.height, window.color.hsb.saturation, window.color.hsb.brightness) + refreshBigRainbow(window) + mainContainer:draw() + buffer.draw() end end + + window.colorPanel = window:addChild(GUI.panel(58, 2, 12, 3, 0x0)) + window.OKButton = window:addChild(GUI.button(58, 6, 12, 1, 0x444444, 0xFFFFFF, 0x88FF88, 0xFFFFFF, "OK")) + window.cancelButton = window:addChild(GUI.button(58, 8, 12, 1, 0xFFFFFF, 0x444444, 0x88FF88, 0xFFFFFF, "Cancel")) - window.onDrawFinished = function() - drawCrests() + local function onAnyInputFinished(mainContainer, object, eventData) + refreshBigRainbow(window) + createCrestsCoordinates(window) + mainContainer:draw() buffer.draw() end - window.onKeyDown = function(eventData) - if eventData[4] == 28 then - window.okButton:press() - drawAll() - window:returnData(currentColor.hex) + local function onHexInputFinished(mainContainer, object, eventData, newText) + switchColorFromHex(window, tonumber("0x" .. newText)) + onAnyInputFinished(mainContainer, object, eventData) + end + + local function onRgbInputFinished(mainContainer, object, eventData, newText) + switchColorFromRgb(window, tonumber(window.inputs[1].inputTextBox.text), tonumber(window.inputs[2].inputTextBox.text), tonumber(window.inputs[3].inputTextBox.text)) + onAnyInputFinished(mainContainer, object, eventData) + end + + local function onHsbInputFinished(mainContainer, object, eventData, newText) + switchColorFromHsb(window, tonumber(window.inputs[4].inputTextBox.text), tonumber(window.inputs[5].inputTextBox.text), tonumber(window.inputs[6].inputTextBox.text)) + onAnyInputFinished(mainContainer, object, eventData) + end + + local function rgbValidaror(text) + local num = tonumber(text) if num and num >= 0 and num <= 255 then return true end + end + + local function hValidator(text) + local num = tonumber(text) if num and num >= 0 and num <= 359 then return true end + end + + local function sbValidator(text) + local num = tonumber(text) if num and num >= 0 and num <= 100 then return true end + end + + local function hexValidator(text) + if string.match(text, "^[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]$") then + return true end end + + window.inputs = { + { shortcut = "R:", validator = rgbValidaror, onInputFinished = onRgbInputFinished }, + { shortcut = "G:", validator = rgbValidaror, onInputFinished = onRgbInputFinished }, + { shortcut = "B:", validator = rgbValidaror, onInputFinished = onRgbInputFinished }, + { shortcut = "H:", validator = hValidator, onInputFinished = onHsbInputFinished }, + { shortcut = "S:", validator = sbValidator, onInputFinished = onHsbInputFinished }, + { shortcut = "L:", validator = sbValidator, onInputFinished = onHsbInputFinished }, + { shortcut = "0x", validator = hexValidator, onInputFinished = onHexInputFinished } + } + + local y = 10 + for i = 1, #window.inputs do + window:addChild(GUI.label(58, y, 2, 1, 0x000000, window.inputs[i].shortcut)) + + window.inputs[i].inputTextBox = window:addChild(GUI.inputTextBox(61, y, 9, 1, 0xFFFFFF, 0x444444, 0xFFFFFF, 0x000000, "", "", true)) + window.inputs[i].inputTextBox.validator = window.inputs[i].validator + window.inputs[i].inputTextBox.onInputFinished = window.inputs[i].onInputFinished + + y = y + 2 + end + + if fs.exists(pathToFavouritesConfig) then + favourites = table.fromFile(pathToFavouritesConfig) + else + favourites = {} + for i = 1, 6 do favourites[i] = math.random(0x000000, 0xFFFFFF) end + saveFavourites() + end + + palette.favouritesContainer = window:addChild(GUI.container(58, 24, 12, 1)) + for i = 1, #favourites do + local button = palette.favouritesContainer:addChild(GUI.button(i * 2 - 1, 1, 2, 1, favourites[i], 0x0, 0x0, 0x0, " ")) + button.onTouch = function(mainContainer, object, eventData) + switchColorFromHex(window, button.colors.default.background) + refreshBigRainbow(window) + createCrestsCoordinates(window) + mainContainer:draw() + buffer.draw() + end + end + + window:addChild(GUI.button(58, 25, 12, 1, 0xFFFFFF, 0x444444, 0x88FF88, 0xFFFFFF, "+")).onTouch = function(mainContainer, object, eventData) + local favouriteExists = false + for i = 1, #favourites do + if favourites[i] == window.color.hex then + favouriteExists = true + break + end + end + + if not favouriteExists then + table.insert(favourites, 1, window.color.hex) + table.remove(favourites, #favourites) + for i = 1, #favourites do + palette.favouritesContainer.children[i].colors.default.background = favourites[i] + palette.favouritesContainer.children[i].colors.pressed.background = 0x0 + end + saveFavourites() + mainContainer:draw() + buffer.draw() + end + end + + switchColorFromHex(window, startColor) + createCrestsCoordinates(window) + refreshBigRainbow(window) + refreshMiniRainbow(window) + + return window end --------------------------------------------------------------------------------------------------------------- - function palette.show(x, y, startColor) - buffer.start() - loadFavourites() - switchColorFromHex(startColor or 0x00B6FF) - createWindow(x or "auto", y or "auto") - createCrestsCoordinates() - refreshRainbows() - - window.drawShadow = false - drawAll() - window.drawShadow = false + local mainContainer = GUI.container(1, 1, buffer.width, buffer.height) - local selectedColor = window:handleEvents() - window = nil + local selectedColor + local window = mainContainer:addChild(palette.window(x, y, startColor)) + window.eventHandler = nil + window.OKButton.onTouch = function(mainContainer, object, eventData) + mainContainer:stopEventHandling() + selectedColor = window.color.hex + end + window.cancelButton.onTouch = function(mainContainer, object, eventData) + mainContainer:stopEventHandling() + end + + mainContainer:draw() + buffer.draw() + mainContainer:startEventHandling() return selectedColor end --- Поддержим олдфагов! -palette.draw = palette.show - -------------------------------------------------------------------------------------------------------------- -- buffer.start() -- buffer.draw(true) --- require("ECSAPI").error(palette.show("auto", "auto", 0xFF5555)) +-- GUI.error(tostring(palette.show(5, 5, 0xFF00FF))) -------------------------------------------------------------------------------------------------------------- diff --git a/lib/rayEngine.lua b/lib/rayEngine.lua index df472cdf..b3b0bcd5 100755 --- a/lib/rayEngine.lua +++ b/lib/rayEngine.lua @@ -24,33 +24,33 @@ rayEngine.chatHistory = {} -- Позиция горизонта, относительно которой рисуется мир function rayEngine.calculateHorizonPosition() - rayEngine.horizonPosition = math.floor(buffer.screen.height / 2) + rayEngine.horizonPosition = math.floor(buffer.height / 2) end -- Размер панели чата и лимита его истории function rayEngine.calculateChatSize() - rayEngine.chatPanelWidth, rayEngine.chatPanelHeight = math.floor(buffer.screen.width * 0.4), math.floor(buffer.screen.height * 0.4) + rayEngine.chatPanelWidth, rayEngine.chatPanelHeight = math.floor(buffer.width * 0.4), math.floor(buffer.height * 0.4) rayEngine.chatHistoryLimit = rayEngine.chatPanelHeight end -- Шаг, с которым будет изменяться угол рейкаста function rayEngine.calculateRaycastStep() - rayEngine.raycastStep = rayEngine.player.fieldOfView / buffer.screen.width + rayEngine.raycastStep = rayEngine.player.fieldOfView / buffer.width end -- Позиция оружия на экране и всех его вспомогательных текстур function rayEngine.calculateWeaponPosition() - rayEngine.currentWeapon.xWeapon = buffer.screen.width - rayEngine.currentWeapon.weaponTexture[1] + 1 - rayEngine.currentWeapon.yWeapon = buffer.screen.height - rayEngine.currentWeapon.weaponTexture[2] + 1 + rayEngine.currentWeapon.xWeapon = buffer.width - rayEngine.currentWeapon.weaponTexture[1] + 1 + rayEngine.currentWeapon.yWeapon = buffer.height - rayEngine.currentWeapon.weaponTexture[2] + 1 rayEngine.currentWeapon.xFire = rayEngine.currentWeapon.xWeapon + rayEngine.weapons[rayEngine.currentWeapon.ID].firePosition.x rayEngine.currentWeapon.yFire = rayEngine.currentWeapon.yWeapon + rayEngine.weapons[rayEngine.currentWeapon.ID].firePosition.y - rayEngine.currentWeapon.xCrosshair = math.floor(buffer.screen.width / 2 - rayEngine.currentWeapon.crosshairTexture[1] / 2) - rayEngine.currentWeapon.yCrosshair = math.floor(buffer.screen.height / 2 - rayEngine.currentWeapon.crosshairTexture[2] / 2) + rayEngine.currentWeapon.xCrosshair = math.floor(buffer.width / 2 - rayEngine.currentWeapon.crosshairTexture[1] / 2) + rayEngine.currentWeapon.yCrosshair = math.floor(buffer.height / 2 - rayEngine.currentWeapon.crosshairTexture[2] / 2) end -- Грубо говоря, это расстояние от камеры до виртуального экрана, на котором рисуется весь наш мир, влияет на размер блоков function rayEngine.calculateDistanceToProjectionPlane() - rayEngine.distanceToProjectionPlane = (buffer.screen.width / 2) / math.tan(math.rad((rayEngine.player.fieldOfView / 2))) + rayEngine.distanceToProjectionPlane = (buffer.width / 2) / math.tan(math.rad((rayEngine.player.fieldOfView / 2))) end -- Быстрый перерасчет всего, что нужно @@ -286,11 +286,11 @@ end function rayEngine.intro() local logo = image.fromString("17060000FF 0000FF 0000FF 0000FF 007EFF▄007EFF▄007EFF▄007EFF▀007EFF▀007EFF▀007EFF▀007EFF▀007EFF▀007EFF▀007EFF▄007EFF▄007EFF▄0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 007EFF▄007EFF▀007EFF▀0000FF 0000FF 0000FF 0000FF 0053FF▄0053FF▀0053FF▀0053FF▀0053FF▄0000FF 0000FF 0000FF 0000FF 007EFF▀007EFF▀007EFF▄0000FF 0000FF 0000FF 007EFF▀007EFF▄0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 530000 0000FF 0078FF▀0000FF 537800▀0078FF▀0078FF▀0078FF▀0078FF▀0078FF▀0078FF▀7E7800▀0078FF▀0000FF 0078FF▀0000FF 0000FF 007EFF▀007EFF▀007EFF▄007EFF▄007EFF▄0000FF 0000FF 0053FF▀0053FF▀0053FF▀0000FF 0000FF 007EFF▄007EFF▄007EFF▄007EFF▀007EFF▀0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 007EFF▀007EFF▀007EFF▀007EFF▀007EFF▀007EFF▀007EFF▀0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 007EFFP007EFFo007EFFw007EFFe007EFFr007EFFe007EFFd0000FF 007EFFb007EFFy0000FF 007EFFR007EFFa007EFFy007EFFE007EFFn007EFFg007EFFi007EFFn007EFFe007EFF™0000FF 0000FF ") - local x, y = math.floor(buffer.screen.width / 2 - logo[1] / 2), math.floor(buffer.screen.height / 2 - logo[2] / 2) + local x, y = math.floor(buffer.width / 2 - logo[1] / 2), math.floor(buffer.height / 2 - logo[2] / 2) local function draw(transparency) buffer.clear(0xF0F0F0); buffer.image(x, y, logo) - buffer.square(1, 1, buffer.screen.width, buffer.screen.height, 0x000000, 0x000000, " ", transparency) + buffer.square(1, 1, buffer.width, buffer.height, 0x000000, 0x000000, " ", transparency) buffer.draw() os.sleep(0) end @@ -346,7 +346,7 @@ local function addItemToChatHistory(text, color) end function rayEngine.chat(transparency) - local x, y = 1, buffer.screen.height - rayEngine.chatPanelHeight - 3 + local x, y = 1, buffer.height - rayEngine.chatPanelHeight - 3 buffer.square(x, y, rayEngine.chatPanelWidth, rayEngine.chatPanelHeight, 0x000000, 0xFFFFFF, " ", transparency or 50) buffer.setDrawLimit(x, y, rayEngine.chatPanelWidth, rayEngine.chatPanelHeight) local yMessage = y + rayEngine.chatPanelHeight - 1 @@ -366,15 +366,15 @@ end function rayEngine.commandLine(transparency) transparency = transparency or 50 local inputPanelHeight = 3 - local x, y = 1, buffer.screen.height - inputPanelHeight + 1 + local x, y = 1, buffer.height - inputPanelHeight + 1 --Врубаем чат и рисуем все, включая его rayEngine.chatEnabled = true rayEngine.update() --Рисуем панель ввода - buffer.square(x, y, buffer.screen.width, inputPanelHeight, 0x000000, 0xFFFFFF, " ", transparency) + buffer.square(x, y, buffer.width, inputPanelHeight, 0x000000, 0xFFFFFF, " ", transparency) --Ввод данных - local text = GUI.input(x + 2, y + 1, buffer.screen.width - 4, 0xFFFFFF, "") + local text = GUI.input(x + 2, y + 1, buffer.width - 4, 0xFFFFFF, "") local words = {}; for word in string.gmatch(text, "[^%s]+") do table.insert(words, unicode.lower(word)) end if #words > 0 then if unicode.sub(words[1], 1, 1) == "/" then @@ -456,9 +456,9 @@ function rayEngine.drawWeapon() end function rayEngine.drawStats() - local width = math.floor(buffer.screen.width * 0.3) + local width = math.floor(buffer.width * 0.3) local height = 5 - local x, y = buffer.screen.width - width - 1, 2 + local x, y = buffer.width - width - 1, 2 buffer.square(x, y, width, height, 0x000000, 0xFFFFFF, " ", 50) GUI.progressBar(x + 1, y + 4, width - 2, 1, 0x000000, 0xFF5555, rayEngine.player.health.current, rayEngine.player.health.maximum, true) @@ -489,7 +489,7 @@ function rayEngine.drawWorld() --Земля buffer.clear(rayEngine.world.colors.groundByTime) --Небо - buffer.square(1, 1, buffer.screen.width, rayEngine.horizonPosition, rayEngine.world.colors.sky.current) + buffer.square(1, 1, buffer.width, rayEngine.horizonPosition, rayEngine.world.colors.sky.current) --Сцена local startAngle, endAngle, startX, distanceToTile, tileID, height, startY, tileColor = rayEngine.player.rotation - rayEngine.player.fieldOfView / 2, rayEngine.player.rotation + rayEngine.player.fieldOfView / 2, 1 for angle = startAngle, endAngle, rayEngine.raycastStep do @@ -511,7 +511,7 @@ function rayEngine.drawWorld() --ТИКСТУРКА)))00 -- local xTexture = startX % rayEngine.properties.tileWidth + 1 - -- if xTexture >= 1 and xTexture <= buffer.screen.width then + -- if xTexture >= 1 and xTexture <= buffer.width then -- local column = image.getColumn(rayEngine.wallsTexture, xTexture) -- column = image.transform(column, 1, height) -- buffer.image(math.floor(startX), math.floor(startY), column) @@ -528,7 +528,7 @@ function rayEngine.update() if rayEngine.currentWeapon then rayEngine.drawWeapon() end if rayEngine.minimapEnabled then rayEngine.drawMap(3, 2, 24, 24, 50) end -- rayEngine.drawStats() - local xTools, yTools = 3, buffer.screen.height - 25 + local xTools, yTools = 3, buffer.height - 25 if rayEngine.compassEnabled then rayEngine.compass(xTools, yTools); xTools = xTools + 30 end if rayEngine.watchEnabled then rayEngine.watch(xTools, yTools) end if rayEngine.chatEnabled then rayEngine.chat() end diff --git a/lib/syntax.lua b/lib/syntax.lua index 9c696629..bd88b55d 100755 --- a/lib/syntax.lua +++ b/lib/syntax.lua @@ -86,7 +86,7 @@ syntax.patterns = { -- Отрисовка строки с подсвеченным синтаксисом function syntax.highlightString(x, y, str, indentationWidth) - if y >= buffer.drawLimit.y and y <= buffer.drawLimit.y2 then + if y >= buffer.drawLimit.y1 and y <= buffer.drawLimit.y2 then local stringLength, symbols, colors, searchFrom, starting, ending, bufferIndex = unicode.len(str), {}, {} for symbol = 1, stringLength do @@ -126,10 +126,10 @@ function syntax.highlightString(x, y, str, indentationWidth) if x > buffer.drawLimit.x2 then break - elseif x >= buffer.drawLimit.x then + elseif x >= buffer.drawLimit.x1 then bufferIndex = bufferIndex or buffer.getBufferIndexByCoordinates(x, y) - buffer.screen.new[bufferIndex + 1] = colors[symbol] or syntax.colorScheme.text - buffer.screen.new[bufferIndex + 2] = symbols[symbol] + buffer.newFrame[bufferIndex + 1] = colors[symbol] or syntax.colorScheme.text + buffer.newFrame[bufferIndex + 2] = symbols[symbol] bufferIndex = bufferIndex + 3 end @@ -144,13 +144,11 @@ end -- buffer.clear(0x1b1b1b) -- buffer.square(5, 5, 30, 3, syntax.colorScheme.background, 0x0, " ") --- -- buffer.setDrawLimit(5, 5, 30, 3) -- -- syntax.highlightString(5, 6, "if not fs.exists(path) then error(\"File \\\"\"..path..\"\\\" doesnt't exsists.\\n\") end") -- syntax.highlightString(5, 6, "for i = 1, 10 do", 2) -- syntax.highlightString(5, 7, " local abc = print(123)", 2) -- syntax.highlightString(5, 8, " local abc = print(123)", 2) -- syntax.highlightString(5, 9, "end", 2) --- -- buffer.resetDrawLimit() -- buffer.draw(true) diff --git a/lib/windows.lua b/lib/windows.lua index 4e1427a4..4fb5f51d 100755 --- a/lib/windows.lua +++ b/lib/windows.lua @@ -1,4 +1,2 @@ - -error("Ты че, долбоеб? Виндолиба удалена уже, пиздец") - +error("ДОЛБОЕБ СОСИ ХУЙ ПИДАР МАТЬ ЕБАЛ") \ No newline at end of file