1
0
Fork 0
mirror of https://github.com/ctruLua/ctruLua.git synced 2025-10-27 16:39:29 +00:00
ctruLua/sdcard/3ds/ctruLua/editor/main.lua
Reuh 45f3216ed8 Updated font and fs lib; updated editor; updated sf2dlib
Libs additions: font.load, font:unload, font:getWidth, fs.getDirectory, fs.setDirectory, fs.exists

Editor additions: syntaxic coloring and mono font

sf2dlib update: you will need the latest version of ctrulib.

Also, because of the lib font needs, the sftdlib was modified.
2015-09-05 19:00:36 +02:00

183 lines
No EOL
4.9 KiB
Lua

local ctr = require("ctr")
local hid = require("ctr.hid")
local gfx = require("ctr.gfx")
-- Open libs
local keyboard = dofile("sdmc:/3ds/ctruLua/keyboard.lua")
local openfile = dofile("sdmc:/3ds/ctruLua/openfile.lua")
local color = dofile("color.lua")
local syntax = dofile("syntax.lua")
-- Load data
local font = gfx.font.load("VeraMono.ttf")
-- Open file
local path, status = openfile("Choose a file to edit", "/3ds/ctruLua/", nil, "any")
if not path then return end
local lineEnding
local lines = {}
if status == "exist" then
for line in io.lines(path, "L") do
if not lineEnding then lineEnding = line:match("([\n\r]+)$") end
table.insert(lines, line:match("^(.-)[\n\r]*$"))
end
else
lineEnding = "\n"
lines = { "" }
end
-- Syntax coloring
local coloredLines = syntax(lines, color)
-- Variables
local lineHeight = 10
local cursorX, cursorY = 1, 1
local scrollX, scrollY = 0, 0
-- Helper functions
local function displayedText(text)
return text:gsub("\t", " ")
end
-- Set defaults
gfx.set3D(false)
gfx.color.setDefault(color.default)
gfx.color.setBackground(color.background)
gfx.font.setDefault(font)
while ctr.run() do
hid.read()
local keys = hid.keys()
-- Keys input
if keys.down.start then return end
if keys.down.dRight then
cursorX = cursorX + 1
if cursorX > utf8.len(lines[cursorY])+1 then
if cursorY < #lines then
cursorX, cursorY = 1, cursorY + 1
else
cursorX = cursorX - 1
end
end
end
if keys.down.dLeft then
if cursorX > utf8.len(lines[cursorY])+1 then cursorX = utf8.len(lines[cursorY])+1 end
cursorX = cursorX - 1
if cursorX < 1 then
if cursorY > 1 then
cursorX, cursorY = utf8.len(lines[cursorY-1])+1, cursorY - 1
else
cursorX = 1
end
end
end
if keys.down.dUp and cursorY > 1 then cursorY = cursorY - 1 end
if keys.down.dDown and cursorY < #lines then cursorY = cursorY + 1 end
if keys.held.cpadRight or keys.held.a then scrollX = scrollX + 3 end
if keys.held.cpadLeft or keys.held.y then scrollX = scrollX - 3 end
if keys.held.cpadUp or keys.held.x then scrollY = scrollY - 3 end
if keys.held.cpadDown or keys.held.b then scrollY = scrollY + 3 end
if keys.down.select then
local file = io.open(path, "w")
if not file then
local t = os.time()
repeat
gfx.startFrame(gfx.GFX_TOP)
gfx.text(3, 3, "Can't open file in write mode")
gfx.endFrame()
gfx.render()
until t + 5 < os.time()
else
for i = 1, #lines, 1 do
file:write(lines[i]..lineEnding)
gfx.startFrame(gfx.GFX_TOP)
gfx.rectangle(0, 0, math.ceil(i/#lines*gfx.TOP_WIDTH), gfx.TOP_HEIGHT, 0, 0xFFFFFFFF)
gfx.color.setDefault(color.background)
gfx.text(gfx.TOP_WIDTH/2, gfx.TOP_HEIGHT/2, math.ceil(i/#lines*100).."%")
gfx.color.setDefault(color.default)
gfx.endFrame()
gfx.render()
end
file:flush()
file:close()
end
end
-- Keyboard input
local input = keyboard.read()
if input then
if input == "BACK" then
if cursorX > utf8.len(lines[cursorY])+1 then cursorX = utf8.len(lines[cursorY])+1 end
if cursorX > 1 then
lines[cursorY] = lines[cursorY]:sub(1, utf8.offset(lines[cursorY], cursorX-1)-1)..
lines[cursorY]:sub(utf8.offset(lines[cursorY], cursorX), -1)
cursorX = cursorX - 1
elseif cursorY > 1 then
cursorX, cursorY = utf8.len(lines[cursorY-1])+1, cursorY - 1
lines[cursorY] = lines[cursorY]..lines[cursorY+1]
table.remove(lines, cursorY+1)
end
elseif input == "\n" then
local newline = lines[cursorY]:sub(utf8.offset(lines[cursorY], cursorX), -1)
local whitespace = lines[cursorY]:match("^%s+")
if whitespace then newline = whitespace .. newline end
lines[cursorY] = lines[cursorY]:sub(1, utf8.offset(lines[cursorY], cursorX)-1)
table.insert(lines, cursorY + 1, newline)
cursorX, cursorY = whitespace and #whitespace+1 or 1, cursorY + 1
else
lines[cursorY] = lines[cursorY]:sub(1, utf8.offset(lines[cursorY], cursorX)-1)..input..
lines[cursorY]:sub(utf8.offset(lines[cursorY], cursorX), -1)
cursorX = cursorX + 1
end
end
-- Draw
gfx.startFrame(gfx.GFX_TOP)
-- Lines
local sI = math.floor(scrollY / lineHeight)
if sI < 1 then sI = 1 end
local eI = math.ceil((scrollY + gfx.TOP_HEIGHT) / lineHeight)
if eI > #lines then eI = #lines end
for i = sI, eI, 1 do
local x = -scrollX
local y = -scrollY+ (i-1)*lineHeight
for _,colored in ipairs(coloredLines[i]) do
local str = displayedText(colored[1])
gfx.color.setDefault(colored[2])
gfx.text(x, y, str)
gfx.color.setDefault(color.default)
x = x + font:width(str)
end
end
-- Cursor
local curline = lines[cursorY]
gfx.rectangle(-scrollX+ font:width(displayedText(curline:sub(1, (utf8.offset(curline, cursorX) or 0)-1))),
-scrollY+ (cursorY-1)*lineHeight, 1, lineHeight, 0, color.cursor)
gfx.endFrame()
gfx.startFrame(gfx.GFX_BOTTOM)
gfx.text(3, 3, "FPS: "..math.ceil(gfx.getFPS()))
keyboard.draw(5, 115)
gfx.endFrame()
gfx.render()
end
font:unload()