From 99de6dd191aaa0e65a0b7495a3e92f5a4a32000f Mon Sep 17 00:00:00 2001 From: Igor Timofeev Date: Sat, 14 Jan 2017 22:40:21 +0300 Subject: [PATCH] aefae --- Applications.txt | 2 +- Applications/MineCodeIDE/MineCodeIDE.lua | 42 +- Applications/MineCodeIDE/MineCodeIDE2.lua | 782 ---------------------- 3 files changed, 24 insertions(+), 802 deletions(-) delete mode 100755 Applications/MineCodeIDE/MineCodeIDE2.lua diff --git a/Applications.txt b/Applications.txt index e76f0d0f..49a63d84 100644 --- a/Applications.txt +++ b/Applications.txt @@ -886,7 +886,7 @@ icon="IgorTimofeev/OpenComputers/master/Applications/MineCodeIDE/Icon.pic", createShortcut="dock", forceDownload=true, - version=1.08, + version=1.09, }, { name="MineOS/Applications/Battleship", diff --git a/Applications/MineCodeIDE/MineCodeIDE.lua b/Applications/MineCodeIDE/MineCodeIDE.lua index ad4e3f5a..bd8a805c 100755 --- a/Applications/MineCodeIDE/MineCodeIDE.lua +++ b/Applications/MineCodeIDE/MineCodeIDE.lua @@ -1,10 +1,10 @@ ---------------------------------------------------- Libraries ---------------------------------------------------- --- package.loaded.syntax = nil --- package.loaded.GUI = nil --- package.loaded.windows = nil --- package.loaded.MineOSCore = nil +package.loaded.syntax = nil +package.loaded.GUI = nil +package.loaded.windows = nil +package.loaded.MineOSCore = nil require("advancedLua") local computer = require("computer") @@ -137,10 +137,14 @@ local function setCursorPosition(symbol, line) fixFromLineByCursorPosition() fixFromSymbolByCursorPosition() deselectLastErrorLine() - clearSelection() hideErrorMessage() end +local function setCursorPositionAndClearSelection(symbol, line) + setCursorPosition(symbol, line) + clearSelection() +end + local function convertScreenCoordinatesToCursorPosition(x, y) return x - mainWindow.codeView.codeAreaPosition + mainWindow.codeView.fromSymbol - 1, y - mainWindow.codeView.y + mainWindow.codeView.fromLine end @@ -162,11 +166,11 @@ local function moveCursor(symbolOffset, lineOffset) newLine, newSymbol = newLine + 1, 1 end - setCursorPosition(newSymbol, newLine) + setCursorPositionAndClearSelection(newSymbol, newLine) end local function setCursorPositionToEOF() - setCursorPosition(unicode.len(mainWindow.codeView.lines[#mainWindow.codeView.lines]) + 1, #mainWindow.codeView.lines) + setCursorPositionAndClearSelection(unicode.len(mainWindow.codeView.lines[#mainWindow.codeView.lines]) + 1, #mainWindow.codeView.lines) end local function gotoLine(line) @@ -190,7 +194,7 @@ local function loadFile(path) end file:close() workPath = path - setCursorPosition(1, 1) + setCursorPositionAndClearSelection(1, 1) end local function saveFile(path) @@ -225,7 +229,7 @@ local function open() ) if data[2] == "OK" and fs.exists(data[1]) then loadFile(data[1]) - setCursorPosition(1, 1) + setCursorPositionAndClearSelection(1, 1) end end @@ -284,7 +288,7 @@ end local function deleteLine(line) if #lines > 0 then table.remove(mainWindow.codeView.lines, line) - setCursorPosition(1, cursor.position.line) + setCursorPositionAndClearSelection(1, cursor.position.line) end end @@ -295,7 +299,7 @@ local function deleteSpecifiedData(fromSymbol, fromLine, toSymbol, toLine) table.remove(mainWindow.codeView.lines, fromLine + 1) end mainWindow.codeView.lines[fromLine] = upperLine .. lowerLine - setCursorPosition(fromSymbol, fromLine) + setCursorPositionAndClearSelection(fromSymbol, fromLine) end local function deleteSelectedData() @@ -342,14 +346,14 @@ local function paste(pasteLines) if #pasteLines == 1 then mainWindow.codeView.lines[cursor.position.line] = firstPart .. pasteLines[1] .. secondPart - setCursorPosition(cursor.position.symbol + unicode.len(pasteLines[1]), cursor.position.line) + setCursorPositionAndClearSelection(cursor.position.symbol + unicode.len(pasteLines[1]), cursor.position.line) else mainWindow.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]) end table.insert(mainWindow.codeView.lines, cursor.position.line + #pasteLines - 1, pasteLines[#pasteLines] .. secondPart) - setCursorPosition(unicode.len(pasteLines[#pasteLines]) + 1, cursor.position.line + #pasteLines - 1) + setCursorPositionAndClearSelection(unicode.len(pasteLines[#pasteLines]) + 1, cursor.position.line + #pasteLines - 1) end end end @@ -373,7 +377,7 @@ local function enter() 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) - setCursorPosition(1, cursor.position.line + 1) + setCursorPositionAndClearSelection(1, cursor.position.line + 1) end local function selectAll() @@ -424,11 +428,11 @@ local function toggleComment() else if isLineCommented(cursor.position.line) then if uncommentLine(cursor.position.line) > 0 then - setCursorPosition(cursor.position.symbol - 3, cursor.position.line) + setCursorPositionAndClearSelection(cursor.position.symbol - 3, cursor.position.line) end else commentLine(cursor.position.line) - setCursorPosition(cursor.position.symbol + 3, cursor.position.line) + setCursorPositionAndClearSelection(cursor.position.symbol + 3, cursor.position.line) end end end @@ -482,10 +486,10 @@ local function indentOrUnindent(isIndent) else if isIndent then indentLine(cursor.position.line) - setCursorPosition(cursor.position.symbol + config.indentaionWidth, cursor.position.line) + setCursorPositionAndClearSelection(cursor.position.symbol + config.indentaionWidth, cursor.position.line) else if unindentLine(cursor.position.line) > 0 then - setCursorPosition(cursor.position.symbol - config.indentaionWidth, cursor.position.line) + setCursorPositionAndClearSelection(cursor.position.symbol - config.indentaionWidth, cursor.position.line) end end end @@ -635,7 +639,7 @@ local function createWindow() end menu:show() else - setCursorPosition(convertScreenCoordinatesToCursorPosition(eventData[3], eventData[4])) + setCursorPositionAndClearSelection(convertScreenCoordinatesToCursorPosition(eventData[3], eventData[4])) end elseif eventData[1] == "drag" and isClickedOnCodeArea(eventData[3], eventData[4]) then if eventData[5] ~= 1 then diff --git a/Applications/MineCodeIDE/MineCodeIDE2.lua b/Applications/MineCodeIDE/MineCodeIDE2.lua deleted file mode 100755 index bd8a805c..00000000 --- a/Applications/MineCodeIDE/MineCodeIDE2.lua +++ /dev/null @@ -1,782 +0,0 @@ - ----------------------------------------------------- Libraries ---------------------------------------------------- - -package.loaded.syntax = nil -package.loaded.GUI = nil -package.loaded.windows = nil -package.loaded.MineOSCore = nil - -require("advancedLua") -local computer = require("computer") -local component = require("component") -local gpu = component.gpu -local fs = require("filesystem") -local buffer = require("doubleBuffering") -local GUI = require("GUI") -local windows = require("windows") -local MineOSCore = require("MineOSCore") -local event = require("event") -local syntax = require("syntax") -local unicode = require("unicode") -local ecs = require("ECSAPI") -local image = require("image") -local keyboard = require("keyboard") - ----------------------------------------------------- Constants ---------------------------------------------------- - --- "/MineOS/Desktop/MineCode IDE.app/MineCode IDE.lua" --- "/MineOS/Applications/MineCode IDE.app/MineCode IDE.lua" - -local args = {...} - -local config = { - indentaionWidth = 2, - colorScheme = { - topToolBar = 0xBBBBBB, - topMenu = { - backgroundColor = 0xEEEEEE, - textColor = 0x444444, - backgroundPressedColor = 0x3366CC, - textPressedColor = 0xFFFFFF, - }, - title = { - default = { - background = 0xDDDDDD, - text = 0x444444 - }, - warning = { - background = 0x880000, - text = 0xEEEEEE, - } - } - }, - scrollSpeed = 8, -} - -local cursor = { - position = { - symbol = 20, - line = 8 - }, - color = 0x00A8FF, - symbol = "┃", - blinkDelay = 0.4, - blinkState = false, -} - -local workPath -local clipboard -local lastErrorLine -local mainWindow = {} - ----------------------------------------------------- Safe launch ---------------------------------------------------- - -local function showErrorMessage(text) - mainWindow.errorMessage.errorTextBox.lines = string.wrap({text}, mainWindow.errorMessage.errorTextBox.width) - mainWindow.errorMessage.height = 2 + #mainWindow.errorMessage.errorTextBox.lines - mainWindow.errorMessage.backgroundPanel.height = mainWindow.errorMessage.height - mainWindow.errorMessage.errorTextBox.height = mainWindow.errorMessage.height - 2 - - mainWindow.titleTextBox.colors.background, mainWindow.titleTextBox.colors.text = config.colorScheme.title.warning.background, config.colorScheme.title.warning.text - - for i = 1, 3 do component.computer.beep(1500, 0.08) end - mainWindow.errorMessage.isHidden = false -end - -local function hideErrorMessage() - mainWindow.titleTextBox.colors.background = config.colorScheme.title.default.background - mainWindow.titleTextBox.colors.text = config.colorScheme.title.default.text - mainWindow.errorMessage.isHidden = true -end - ----------------------------------------------------- Cursor methods ---------------------------------------------------- - -local function deselectLastErrorLine() - if lastErrorLine then mainWindow.codeView.highlights[lastErrorLine] = nil end -end - -local function clearSelection() - mainWindow.codeView.selections[1] = nil -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 - 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 - end -end - -local function fixCursorPosition(symbol, line) - if line < 1 then - line = 1 - elseif line > #mainWindow.codeView.lines then - line = #mainWindow.codeView.lines - end - - local lineLength = unicode.len(mainWindow.codeView.lines[line]) - if symbol < 1 or lineLength == 0 then - symbol = 1 - elseif symbol > lineLength then - symbol = lineLength + 1 - end - - return symbol, line -end - -local function setCursorPosition(symbol, line) - cursor.position.symbol, cursor.position.line = fixCursorPosition(symbol, line) - fixFromLineByCursorPosition() - fixFromSymbolByCursorPosition() - deselectLastErrorLine() - hideErrorMessage() -end - -local function setCursorPositionAndClearSelection(symbol, line) - setCursorPosition(symbol, line) - clearSelection() -end - -local function convertScreenCoordinatesToCursorPosition(x, y) - return x - mainWindow.codeView.codeAreaPosition + mainWindow.codeView.fromSymbol - 1, y - mainWindow.codeView.y + mainWindow.codeView.fromLine -end - -local function isClickedOnCodeArea(x, y) - return - x >= mainWindow.codeView.codeAreaPosition and - y >= mainWindow.codeView.y and - x < mainWindow.width and - y < mainWindow.codeView.y + mainWindow.codeView.height - 1 -end - -local function moveCursor(symbolOffset, lineOffset) - local newSymbol, newLine = cursor.position.symbol + symbolOffset, cursor.position.line + lineOffset - - if newSymbol < 1 then - newLine, newSymbol = newLine - 1, math.huge - elseif newSymbol > unicode.len(mainWindow.codeView.lines[newLine] or "") + 1 then - newLine, newSymbol = newLine + 1, 1 - end - - setCursorPositionAndClearSelection(newSymbol, newLine) -end - -local function setCursorPositionToEOF() - setCursorPositionAndClearSelection(unicode.len(mainWindow.codeView.lines[#mainWindow.codeView.lines]) + 1, #mainWindow.codeView.lines) -end - -local function gotoLine(line) - mainWindow.codeView.fromLine = math.floor(line - mainWindow.codeView.height / 2) + 1 - if mainWindow.codeView.fromLine < 1 then - mainWindow.codeView.fromLine = 1 - elseif mainWindow.codeView.fromLine > #mainWindow.codeView.lines then - mainWindow.codeView.fromLine = #mainWindow.codeView.lines - end -end - ----------------------------------------------------- File processing methods ---------------------------------------------------- - -local function loadFile(path) - mainWindow.codeView.fromLine, mainWindow.codeView.fromSymbol, mainWindow.codeView.lines, mainWindow.codeView.maximumLineLength = 1, 1, {}, 0 - local file = io.open(path, "r") - for line in file:lines() do - line = line:gsub("\t", string.rep(" ", config.indentaionWidth)) - table.insert(mainWindow.codeView.lines, line) - mainWindow.codeView.maximumLineLength = math.max(mainWindow.codeView.maximumLineLength, unicode.len(line)) - end - file:close() - workPath = path - setCursorPositionAndClearSelection(1, 1) -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") - end - file:close() -end - -local function newFile() - mainWindow.codeView.lines = { - "", - "for i = 1, 10 do", - " print(\"Hello world!\")", - "end", - "" - } - workPath = nil - setCursorPositionToEOF() -end - -local function open() - local data = ecs.universalWindow("auto", "auto", 30, ecs.windowColors.background, true, - {"EmptyLine"}, - {"CenterText", 0x000000, "Open file"}, - {"EmptyLine"}, - {"Input", 0x262626, 0x880000, ""}, - {"EmptyLine"}, - {"Button", {0xAAAAAA, 0xffffff, "OK"}, {0x888888, 0xffffff, MineOSCore.localization.cancel}} - ) - if data[2] == "OK" and fs.exists(data[1]) then - loadFile(data[1]) - setCursorPositionAndClearSelection(1, 1) - end -end - -local function saveAs() - local data = ecs.universalWindow("auto", "auto", 30, ecs.windowColors.background, true, - {"EmptyLine"}, - {"CenterText", 0x000000, "Save as"}, - {"EmptyLine"}, - {"Input", 0x262626, 0x880000, ""}, - {"EmptyLine"}, - {"Button", {0xAAAAAA, 0xffffff, "OK"}, {0x888888, 0xffffff, MineOSCore.localization.cancel}} - ) - if data[2] == "OK" then - saveFile(data[1]) - workPath = data[1] - end -end - -local function save() - saveFile(workPath) -end - -local function run() - deselectLastErrorLine() - - local loadSuccess, loadReason = load(table.concat(mainWindow.codeView.lines, "\n")) - if loadSuccess then - local oldResolutionX, oldResolutionY = gpu.getResolution() - gpu.setBackground(0x262626); gpu.setForeground(0xFFFFFF); gpu.fill(1, 1, oldResolutionX, oldResolutionY, " "); require("term").setCursor(1, 1) - - local xpcallSuccess, xpcallReason = xpcall(loadSuccess, debug.traceback) - if xpcallSuccess then - MineOSCore.waitForPressingAnyKey() - end - - gpu.setResolution(oldResolutionX, oldResolutionY) - buffer.start() - mainWindow:draw() - - if not xpcallSuccess then - showErrorMessage(xpcallReason) - end - - buffer:draw() - else - local match = string.match(loadReason, ":(%d+)%:") - lastErrorLine = tonumber(match) - mainWindow.codeView.highlights[lastErrorLine] = 0xFF4444 - gotoLine(lastErrorLine) - showErrorMessage(loadReason) - end -end - ----------------------------------------------------- Text processing methods ---------------------------------------------------- - -local function deleteLine(line) - if #lines > 0 then - table.remove(mainWindow.codeView.lines, line) - setCursorPositionAndClearSelection(1, cursor.position.line) - end -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) - for line = fromLine + 1, toLine do - table.remove(mainWindow.codeView.lines, fromLine + 1) - end - mainWindow.codeView.lines[fromLine] = upperLine .. lowerLine - setCursorPositionAndClearSelection(fromSymbol, fromLine) -end - -local function deleteSelectedData() - if mainWindow.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 - ) - clearSelection() - end -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) } - 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]) - end - table.insert(clipboard, unicode.sub(mainWindow.codeView.lines[mainWindow.codeView.selections[1].to.line], 1, mainWindow.codeView.selections[1].to.symbol)) - end - end -end - -local function cut() - if mainWindow.codeView.selections[1] then - copy() - deleteSelectedData() - end -end - -local function paste(pasteLines) - if pasteLines then - if mainWindow.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) - - if #pasteLines == 1 then - mainWindow.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] - for pasteLine = #pasteLines - 1, 2, -1 do - table.insert(mainWindow.codeView.lines, cursor.position.line + 1, pasteLines[pasteLine]) - end - table.insert(mainWindow.codeView.lines, cursor.position.line + #pasteLines - 1, pasteLines[#pasteLines] .. secondPart) - setCursorPositionAndClearSelection(unicode.len(pasteLines[#pasteLines]) + 1, cursor.position.line + #pasteLines - 1) - end - end -end - -local function backspace() - if mainWindow.codeView.selections[1] then - deleteSelectedData() - else - if cursor.position.symbol > 1 then - 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) - end - end - end -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) - setCursorPositionAndClearSelection(1, cursor.position.line + 1) -end - -local function selectAll() - mainWindow.codeView.selections[1] = {from = {}, to = {}} - mainWindow.codeView.selections[1].from.symbol, mainWindow.codeView.selections[1].from.line = 1, 1 - mainWindow.codeView.selections[1].to.symbol, mainWindow.codeView.selections[1].to.line = unicode.len(mainWindow.codeView.lines[#mainWindow.codeView.lines]), #mainWindow.codeView.lines -end - ----------------------------------------------------- Text comments-related methods ---------------------------------------------------- - -local function isLineCommented(line) - return mainWindow.codeView.lines[line]:match("%-%-[^%-]") -end - -local function commentLine(line) - mainWindow.codeView.lines[line] = "-- " .. mainWindow.codeView.lines[line] -end - -local function uncommentLine(line) - mainWindow.codeView.lines[line], countOfReplaces = mainWindow.codeView.lines[line]:gsub("%-%-%s", "", 1) - return countOfReplaces -end - -local function toggleComment() - if mainWindow.codeView.selections[1] then - local allLinesAreCommented = true - - for line = mainWindow.codeView.selections[1].from.line, mainWindow.codeView.selections[1].to.line do - if not isLineCommented(line) then - allLinesAreCommented = false - end - end - - for line = mainWindow.codeView.selections[1].from.line, mainWindow.codeView.selections[1].to.line do - if allLinesAreCommented then - uncommentLine(line) - else - commentLine(line) - end - end - - local modifyer = 3 - if allLinesAreCommented then - modifyer = -3 - 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 - else - if isLineCommented(cursor.position.line) then - if uncommentLine(cursor.position.line) > 0 then - setCursorPositionAndClearSelection(cursor.position.symbol - 3, cursor.position.line) - end - else - commentLine(cursor.position.line) - setCursorPositionAndClearSelection(cursor.position.symbol + 3, cursor.position.line) - end - end -end - ----------------------------------------------------- Text indentation-related methods ---------------------------------------------------- - -local function indentLine(line) - mainWindow.codeView.lines[line] = string.rep(" ", config.indentaionWidth) .. mainWindow.codeView.lines[line] -end - -local function unindentLine(line) - mainWindow.codeView.lines[line], countOfReplaces = string.gsub(mainWindow.codeView.lines[line], "^" .. string.rep("%s", config.indentaionWidth), "") - return countOfReplaces -end - -local function indentOrUnindent(isIndent) - if mainWindow.codeView.selections[1] then - local countOfReplacesInFirstLine, countOfReplacesInLastLine - - for line = mainWindow.codeView.selections[1].from.line, mainWindow.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 - countOfReplacesInFirstLine = countOfReplaces - elseif line == mainWindow.codeView.selections[1].to.line then - countOfReplacesInLastLine = countOfReplaces - end - end - end - - if isIndent then - setCursorPosition(cursor.position.symbol + config.indentaionWidth, cursor.position.line) - mainWindow.codeView.selections[1].from.symbol, mainWindow.codeView.selections[1].to.symbol = mainWindow.codeView.selections[1].from.symbol + config.indentaionWidth, mainWindow.codeView.selections[1].to.symbol + config.indentaionWidth - else - if countOfReplacesInFirstLine > 0 then - mainWindow.codeView.selections[1].from.symbol = mainWindow.codeView.selections[1].from.symbol - config.indentaionWidth - if cursor.position.line == mainWindow.codeView.selections[1].from.line then - setCursorPosition(cursor.position.symbol - config.indentaionWidth, cursor.position.line) - end - end - - if countOfReplacesInLastLine > 0 then - mainWindow.codeView.selections[1].to.symbol = mainWindow.codeView.selections[1].to.symbol - config.indentaionWidth - if cursor.position.line == mainWindow.codeView.selections[1].to.line then - setCursorPosition(cursor.position.symbol - config.indentaionWidth, cursor.position.line) - end - end - end - else - if isIndent then - indentLine(cursor.position.line) - setCursorPositionAndClearSelection(cursor.position.symbol + config.indentaionWidth, cursor.position.line) - else - if unindentLine(cursor.position.line) > 0 then - setCursorPositionAndClearSelection(cursor.position.symbol - config.indentaionWidth, cursor.position.line) - end - end - end -end - ----------------------------------------------------- Main window related methods ---------------------------------------------------- - -local function updateTitle() - mainWindow.titleTextBox.lines[1] = "File: " .. (workPath or "none") - mainWindow.titleTextBox.lines[2] = "Cursor: " .. cursor.position.line .. " line, " .. cursor.position.symbol .. " symbol" - if mainWindow.codeView.selections[1] then - local countOfSelectedLines = mainWindow.codeView.selections[1].to.line - mainWindow.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)) - 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]) - end - countOfSelectedSymbols = countOfSelectedSymbols + unicode.len(unicode.sub(mainWindow.codeView.lines[mainWindow.codeView.selections[1].to.line], 1, mainWindow.codeView.selections[1].to.symbol)) - end - mainWindow.titleTextBox.lines[3] = "Selection: " .. countOfSelectedLines .. " lines, " .. countOfSelectedSymbols .. " symbols" - else - mainWindow.titleTextBox.lines[3] = "Selection: none" - end -end - -local function calculateSizes() - if mainWindow.topToolBar.isHidden then - mainWindow.codeView.localPosition.y, mainWindow.codeView.height = 2, mainWindow.height - 1 - mainWindow.errorMessage.localPosition.y = 2 - else - mainWindow.codeView.localPosition.y, mainWindow.codeView.height = 5, mainWindow.height - 4 - mainWindow.topToolBar.width, mainWindow.topToolBar.backgroundPanel.width = mainWindow.width, mainWindow.width - mainWindow.errorMessage.localPosition.y = 5 - end - - 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.errorMessage.localPosition.x, mainWindow.errorMessage.width = mainWindow.titleTextBox.localPosition.x, mainWindow.titleTextBox.width - mainWindow.errorMessage.backgroundPanel.width, mainWindow.errorMessage.errorTextBox.width = mainWindow.errorMessage.width, mainWindow.errorMessage.width - 4 - - mainWindow.topMenu.width = mainWindow.width - mainWindow.codeView.width = mainWindow.width -end - -local function createWindow() - mainWindow = windows.fullScreen() - - mainWindow.codeView = mainWindow:addCodeView(1, 1, 1, 1, {""}, 1, 1, 1, {}, {}, true) - 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, config.colorScheme.topMenu.backgroundColor, config.colorScheme.topMenu.textColor, config.colorScheme.topMenu.backgroundPressedColor, config.colorScheme.topMenu.textPressedColor) - - local item1 = mainWindow.topMenu:addItem("MineCode", 0x0) - item1.onTouch = function() - local menu = GUI.contextMenu(item1.x, item1.y + 1) - menu:addItem("About", true).onTouch = function() - - end - menu:addItem("Quit MineCode", false, "^W").onTouch = function() - mainWindow:close() - end - menu:show() - end - - local item2 = mainWindow.topMenu:addItem("File") - item2.onTouch = function() - local menu = GUI.contextMenu(item2.x, item2.y + 1) - menu:addItem("New", false, "^N").onTouch = function() - newFile() - end - menu:addItem("Open", false, "^O").onTouch = function() - open() - end - menu:addSeparator() - menu:addItem("Save", not workPath, "^S").onTouch = function() - save() - end - menu:addItem("Save as", false, "^⇧S").onTouch = function() - saveAs() - end - menu:show() - end - - local item3 = mainWindow.topMenu:addItem("View") - item3.onTouch = function() - local menu = GUI.contextMenu(item3.x, item3.y + 1) - menu:addItem("Toggle top toolbar").onTouch = function() - mainWindow.topToolBar.isHidden = not mainWindow.topToolBar.isHidden - calculateSizes() - end - menu:show() - end - - -- mainWindow.topMenu:addItem("Properties") - mainWindow.topToolBar = mainWindow:addContainer(1, 2, 1, 3) - mainWindow.topToolBar.backgroundPanel = mainWindow.topToolBar:addPanel(1, 1, 1, 3, config.colorScheme.topToolBar) - mainWindow.titleTextBox = mainWindow.topToolBar:addTextBox(1, 1, 1, 3, 0x0, 0x0, {}, 1):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) - mainWindow.runButton = mainWindow.topToolBar:addAdaptiveButton(1, 1, 2, 1, 0x444444, 0xFFFFFF, 0xFFFFFF, 0x444444, "Run") - mainWindow.runButton.onTouch = function() - run() - end - - mainWindow.toggleSyntaxHighlightingButton = mainWindow.topToolBar:addAdaptiveButton(8, 1, 2, 1, 0x262626, 0xDDDDDD, 0x262626, 0xDDDDDD, "Syntax") - mainWindow.toggleSyntaxHighlightingButton.onTouch = function() - mainWindow.codeView.highlightLuaSyntax = not mainWindow.codeView.highlightLuaSyntax - local color1, color2 = 0xDDDDDD, 0x262626 - if mainWindow.codeView.highlightLuaSyntax then - color1, color2 = 0x262626, 0xDDDDDD - end - mainWindow.toggleSyntaxHighlightingButton.colors.default.background, mainWindow.toggleSyntaxHighlightingButton.colors.default.text = color1, color2 - mainWindow.toggleSyntaxHighlightingButton.colors.pressed.background, mainWindow.toggleSyntaxHighlightingButton.colors.pressed.text = color1, color2 - end - - mainWindow.errorMessage = mainWindow:addContainer(1, 1, 1, 1) - mainWindow.errorMessage.backgroundPanel = mainWindow.errorMessage:addPanel(1, 1, 1, 1, 0xFFFFFF, 40) - mainWindow.errorMessage.errorTextBox = mainWindow.errorMessage:addTextBox(3, 2, 1, 1, nil, 0x262626, {}, 1) - hideErrorMessage() - - mainWindow.onAnyEvent = function(eventData) - cursor.blinkState = not cursor.blinkState - local oldCursorState = cursor.blinkState - cursor.blinkState = true - - if eventData[1] == "touch" and isClickedOnCodeArea(eventData[3], eventData[4]) then - if eventData[5] == 1 then - local menu = GUI.contextMenu(eventData[3], eventData[4]) - menu:addItem("Cut", not mainWindow.codeView.selections[1], "^C").onTouch = function() - cut() - end - menu:addItem("Copy", not mainWindow.codeView.selections[1], "^C").onTouch = function() - copy() - end - menu:addItem("Paste", not clipboard, "^V").onTouch = function() - paste(clipboard) - end - menu:addSeparator() - menu:addItem("Select all", false, "^A").onTouch = function() - selectAll() - end - menu:show() - else - setCursorPositionAndClearSelection(convertScreenCoordinatesToCursorPosition(eventData[3], eventData[4])) - end - elseif eventData[1] == "drag" and isClickedOnCodeArea(eventData[3], eventData[4]) then - 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(convertScreenCoordinatesToCursorPosition(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) - end - end - end - 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() - -- A - elseif eventData[4] == 30 then - selectAll() - -- C - elseif eventData[4] == 46 then - copy() - -- 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 - open() - -- S + Shift - elseif eventData[4] == 31 and keyboard.isKeyDown(42) then - saveAs() - -- S - elseif eventData[4] == 31 and workPath then - save() - 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) - else - indentOrUnindent(true) - end - -- Enter - elseif eventData[4] == 28 then - enter() - -- F5 - elseif eventData[4] == 63 then - run() - else - if not keyboard.isControl(eventData[3]) then - deleteSelectedData() - paste({unicode.char(eventData[3])}) - end - end - elseif eventData[1] == "clipboard" then - paste({eventData[3]}) - elseif eventData[1] == "scroll" then - if mainWindow.codeView:isClicked(eventData[3], eventData[4]) then - if eventData[5] == 1 then - if mainWindow.codeView.fromLine > config.scrollSpeed then - mainWindow.codeView.fromLine = mainWindow.codeView.fromLine - config.scrollSpeed - else - mainWindow.codeView.fromLine = 1 - end - else - if mainWindow.codeView.fromLine < #mainWindow.codeView.lines - config.scrollSpeed then - mainWindow.codeView.fromLine = mainWindow.codeView.fromLine + config.scrollSpeed - else - mainWindow.codeView.fromLine = #mainWindow.codeView.lines - end - end - end - elseif not eventData[1] then - cursor.blinkState = oldCursorState - end - - updateTitle() - mainWindow:draw() - if cursor.blinkState then - local x, y = mainWindow.codeView.codeAreaPosition + cursor.position.symbol - mainWindow.codeView.fromSymbol + 1, mainWindow.codeView.y + cursor.position.line - mainWindow.codeView.fromLine - if - x >= mainWindow.codeView.codeAreaPosition + 1 and - x <= mainWindow.codeView.codeAreaPosition + mainWindow.codeView.codeAreaWidth - 2 and - y >= mainWindow.codeView.y and - y <= mainWindow.codeView.y + mainWindow.codeView.height - 2 - then - buffer.text(x, y, cursor.color, cursor.symbol) - end - end - buffer.draw() - end -end - ------------------------------------------------------------------------------------------------------------------------------ - -buffer.start() - -createWindow() -calculateSizes() -mainWindow.drawShadow = false -mainWindow:draw() - -if args[1] == "open" and fs.exists(args[2]) then - loadFile(args[2]) -else - newFile() -end - -mainWindow:draw() -buffer.draw() -mainWindow:handleEvents(cursor.blinkDelay) - -