Fixed blit, added smoother animations

Blit had a built-in wrap function, which goes against how CC works, so that was fixed.
You're also now able to scroll both vertically and horizontally at the same time, showing potentially bits of four workspaces at once.
It also tells you how to switch workspaces at startup.
This commit is contained in:
LDDestroier 2019-04-23 14:35:15 -04:00 committed by GitHub
parent 0f255e73fd
commit 3d3be77958
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 77 additions and 65 deletions

View File

@ -1,9 +1,14 @@
-- Workspaces for ComputerCraft -- Workspaces for ComputerCraft
-- by LDDestroier -- by LDDestroier
local tArg = {...}
-- higher number means faster workspace movement animation, caps at 1
local workspaceMoveSpeed = 0.2
-- x,y size of workspace grid -- x,y size of workspace grid
local gridWidth = 3 local gridWidth = math.max(1, tonumber(tArg[1]) or 3)
local gridHeight = 3 local gridHeight = math.max(1, tonumber(tArg[2]) or 3)
local scr_x, scr_y = term.getSize() local scr_x, scr_y = term.getSize()
local windowWidth = scr_x local windowWidth = scr_x
@ -23,14 +28,14 @@ local isRunning = true
-- start up lddterm -- start up lddterm
local lddterm = {} local lddterm = {}
lddterm.alwaysRender = false -- renders after any and all screen-changing functions. lddterm.alwaysRender = false -- renders after any and all screen-changing functions.
lddterm.useColors = true -- normal computers do not allow color, but this variable doesn't do anything yet lddterm.useColors = true -- normal computers do not allow color, but this variable doesn't do anything yet
lddterm.baseTerm = term.current() -- will draw to this terminal lddterm.baseTerm = term.current() -- will draw to this terminal
lddterm.transformation = nil -- will modify the current buffer as an NFT image before rendering lddterm.transformation = nil -- will modify the current buffer as an NFT image before rendering
lddterm.cursorTransformation = nil -- will modify the cursor position lddterm.cursorTransformation = nil -- will modify the cursor position
lddterm.drawFunction = nil -- will draw using this function instead of basic NFT drawing lddterm.drawFunction = nil -- will draw using this function instead of basic NFT drawing
lddterm.adjustX = 0 -- moves entire screen X lddterm.adjustX = 0 -- moves entire screen X
lddterm.adjustY = 0 -- moves entire screen Y lddterm.adjustY = 0 -- moves entire screen Y
lddterm.selectedWindow = 1 -- determines which window controls the cursor lddterm.selectedWindow = 1 -- determines which window controls the cursor
lddterm.windows = {} lddterm.windows = {}
-- converts hex colors to colors api, and back -- converts hex colors to colors api, and back
@ -313,16 +318,7 @@ lddterm.newWindow = function(width, height, x, y, meta)
window.buffer[2][cy][cx] = textCol:sub(i,i) window.buffer[2][cy][cx] = textCol:sub(i,i)
window.buffer[3][cy][cx] = backCol:sub(i,i) window.buffer[3][cy][cx] = backCol:sub(i,i)
end end
if cx >= window.width or cy < 1 then cx = cx + 1
cx = 1
if cy >= window.height then
window.handle.scroll(1)
else
cy = cy + 1
end
else
cx = cx + 1
end
end end
window.cursor = {cx, cy} window.cursor = {cx, cy}
if lddterm.alwaysRender and not ignoreAlwaysRender then if lddterm.alwaysRender and not ignoreAlwaysRender then
@ -441,6 +437,7 @@ lddterm.newWindow = function(width, height, x, y, meta)
end end
window.handle.redraw = lddterm.render window.handle.redraw = lddterm.render
window.handle.current = window.handle
window.layer = #lddterm.windows + 1 window.layer = #lddterm.windows + 1
lddterm.windows[window.layer] = window lddterm.windows[window.layer] = window
@ -522,6 +519,14 @@ local keysDown = {}
local instances = {} local instances = {}
local cwrite = function(text, y, terminal)
terminal = terminal or term.current()
local cx, cy = terminal.getCursorPos()
local sx, sy = terminal.getSize()
terminal.setCursorPos(sx / 2 - #text / 2, y or (sy / 2))
terminal.write(text)
end
local defaultProgram = "rom/programs/shell.lua" local defaultProgram = "rom/programs/shell.lua"
local newInstance = function(x, y, program, initialStart) local newInstance = function(x, y, program, initialStart)
x, y = math.floor(x), math.floor(y) x, y = math.floor(x), math.floor(y)
@ -537,8 +542,9 @@ local newInstance = function(x, y, program, initialStart)
y = y, y = y,
co = coroutine.create(function() co = coroutine.create(function()
term.redirect(window.handle) term.redirect(window.handle)
local evt
while true do while true do
if initialStart then if initialStart then
if not program or type(program) == "string" then if not program or type(program) == "string" then
shell.run(program or defaultProgram) shell.run(program or defaultProgram)
@ -546,12 +552,10 @@ local newInstance = function(x, y, program, initialStart)
program() program()
end end
end end
term.clear() term.clear()
term.setCursorBlink(false) term.setCursorBlink(false)
local text, evt = "Press SPACE to start workspace." cwrite("Press SPACE to start workspace.")
term.setCursorPos(scr_x / 2 - #text / 2, scr_y / 2)
term.write(text)
repeat repeat
evt = {os.pullEventRaw()} evt = {os.pullEventRaw()}
until (evt[1] == "key" and evt[2] == keys.space) or evt[1] == "terminate" until (evt[1] == "key" and evt[2] == keys.space) or evt[1] == "terminate"
@ -560,11 +564,11 @@ local newInstance = function(x, y, program, initialStart)
isRunning = false isRunning = false
return return
end end
term.setCursorPos(1,1) term.setCursorPos(1,1)
term.clear() term.clear()
term.setCursorBlink(true) term.setCursorBlink(true)
if not initialStart then if not initialStart then
if not program or type(program) == "string" then if not program or type(program) == "string" then
shell.run(program or defaultProgram) shell.run(program or defaultProgram)
@ -579,20 +583,40 @@ local newInstance = function(x, y, program, initialStart)
} }
end end
local scroll = {0,0} local scroll = {0,0} -- change this value when scrolling
local realScroll = {0,0} -- this value changes depending on scroll for smoothness purposes
local focus = {1,1} local focus = {1,1}
-- prevents wiseassed-ness
workspaceMoveSpeed = math.min(math.max(workspaceMoveSpeed, 0.01), 1)
local scrollWindows = function() local scrollWindows = function()
local changed = false
if realScroll[1] < scroll[1] then
realScroll[1] = math.min(realScroll[1] + workspaceMoveSpeed, scroll[1])
changed = true
elseif realScroll[1] > scroll[1] then
realScroll[1] = math.max(realScroll[1] - workspaceMoveSpeed, scroll[1])
changed = true
end
if realScroll[2] < scroll[2] then
realScroll[2] = math.min(realScroll[2] + workspaceMoveSpeed, scroll[2])
changed = true
elseif realScroll[2] > scroll[2] then
realScroll[2] = math.max(realScroll[2] - workspaceMoveSpeed, scroll[2])
changed = true
end
for y = 1, #instances do for y = 1, #instances do
if instances[y] then if instances[y] then
for x = 1, #instances[y] do for x = 1, #instances[y] do
if instances[y][x] then if instances[y][x] then
instances[y][x].window.x = math.floor(1 + (instances[y][x].x + scroll[1] - 1) * scr_x) instances[y][x].window.x = math.floor(1 + (instances[y][x].x + realScroll[1] - 1) * scr_x)
instances[y][x].window.y = math.floor(1 + (instances[y][x].y + scroll[2] - 1) * scr_y) instances[y][x].window.y = math.floor(1 + (instances[y][x].y + realScroll[2] - 1) * scr_y)
end end
end end
end end
end end
return changed
end end
for y = 1, gridHeight do for y = 1, gridHeight do
@ -615,37 +639,10 @@ local inputEvt = {
terminate = true terminate = true
} }
local fullScroll = function(xDir, yDir)
local speed = 20
if xDir ~= 0 then
for i = 1, speed - 1 do
scroll[1] = scroll[1] + (xDir / speed)
scrollWindows()
lddterm.render()
end
end
if yDir ~= 0 then
for i = 1, speed - 1 do
scroll[2] = scroll[2] + (yDir / speed)
scrollWindows()
lddterm.render()
end
end
scroll[1] = math.floor(0.5 + scroll[1])
scroll[2] = math.floor(0.5 + scroll[2])
scrollWindows()
keysDown[keys.up] = nil
keysDown[keys.down] = nil
keysDown[keys.left] = nil
keysDown[keys.right] = nil
lddterm.render()
end
local main = function() local main = function()
local enteringCommand local enteringCommand
local justStarted = true local justStarted = true
local tID
while isRunning do while isRunning do
local evt = {os.pullEventRaw()} local evt = {os.pullEventRaw()}
enteringCommand = false enteringCommand = false
@ -654,19 +651,25 @@ local main = function()
elseif evt[1] == "key_up" then elseif evt[1] == "key_up" then
keysDown[evt[2]] = nil keysDown[evt[2]] = nil
end end
if scrollWindows() then
tID = os.startTimer(0.05)
end
if keysDown[keys.leftCtrl] and keysDown[keys.leftShift] then if keysDown[keys.leftCtrl] and keysDown[keys.leftShift] then
if keysDown[keys.left] then if keysDown[keys.left] then
if instances[focus[2]][focus[1] - 1] then if instances[focus[2]][focus[1] - 1] then
focus[1] = focus[1] - 1 focus[1] = focus[1] - 1
fullScroll(1, 0) scroll[1] = scroll[1] + 1
keysDown[keys.left] = false
enteringCommand = true enteringCommand = true
end end
end end
if keysDown[keys.right] then if keysDown[keys.right] then
if instances[focus[2]][focus[1] + 1] then if instances[focus[2]][focus[1] + 1] then
focus[1] = focus[1] + 1 focus[1] = focus[1] + 1
fullScroll(-1, 0) scroll[1] = scroll[1] - 1
keysDown[keys.right] = false
enteringCommand = true enteringCommand = true
end end
end end
@ -674,7 +677,8 @@ local main = function()
if instances[focus[2] - 1] then if instances[focus[2] - 1] then
if instances[focus[2] - 1][focus[1]] then if instances[focus[2] - 1][focus[1]] then
focus[2] = focus[2] - 1 focus[2] = focus[2] - 1
fullScroll(0, 1) scroll[2] = scroll[2] + 1
keysDown[keys.up] = false
enteringCommand = true enteringCommand = true
end end
end end
@ -683,38 +687,46 @@ local main = function()
if instances[focus[2] + 1] then if instances[focus[2] + 1] then
if instances[focus[2] + 1][focus[1]] then if instances[focus[2] + 1][focus[1]] then
focus[2] = focus[2] + 1 focus[2] = focus[2] + 1
fullScroll(0, -1) scroll[2] = scroll[2] - 1
keysDown[keys.down] = false
enteringCommand = true enteringCommand = true
end end
end end
end end
end end
if not enteringCommand then if not enteringCommand then
for y = 1, #instances do for y = 1, #instances do
if instances[y] then if instances[y] then
for x = 1, #instances[y] do for x = 1, #instances[y] do
if instances[y][x] then if instances[y][x] then
if justStarted or (not inputEvt[evt[1]]) or (x == focus[1] and y == focus[2]) then if justStarted or (not inputEvt[evt[1]]) or (x == focus[1] and y == focus[2]) then
local previousTerm = term.redirect(instances[y][x].window.handle) local previousTerm = term.redirect(instances[y][x].window.handle)
coroutine.resume(instances[y][x].co, table.unpack(evt)) coroutine.resume(instances[y][x].co, table.unpack(evt))
term.redirect(previousTerm) term.redirect(previousTerm)
end end
end end
end end
end end
end end
end end
lddterm.selectedWindow = instances[focus[2]][focus[1]].window.layer lddterm.selectedWindow = instances[focus[2]][focus[1]].window.layer
lddterm.render() lddterm.render()
justStarted = false justStarted = false
end end
end end
term.clear()
cwrite("Use CTRL+SHIFT+ARROW to switch workspace.")
sleep(0.1)
os.pullEvent("key")
os.queueEvent("mouse_click", 0, 0, 0)
main() main()
_G.currentlyRunningWorkspace = false _G.currentlyRunningWorkspace = false