Compare commits

..

4 Commits

Author SHA1 Message Date
Jay 7174736ea9 improved bottom right uii 2020-05-03 00:05:49 +01:00
Jay d859b4b0e1 Tutorial fixes 2020-05-02 23:47:29 +01:00
Jay 14a0f6d3ae Updates to tutorial system 2020-05-02 23:25:40 +01:00
Jay 3d714a1450 Text editor improvements, update to tutorial framework 2020-05-02 21:28:09 +01:00
9 changed files with 411 additions and 136 deletions

View File

@ -105,7 +105,7 @@ return {
})
end
if teverse.dev.localTevGit then
if _TEV_VERSION ~= "0.20.6" then
local appGui = createApp({
id = "",
name = "Learn Code",
@ -113,6 +113,7 @@ return {
username = "Teverse"
}
})
appGui.name = "a"
appGui.parent = appsContainer
appGui:on("mouseLeftUp", function()
if not loading.visible then

100
core/editor/editor.lua Normal file
View File

@ -0,0 +1,100 @@
local lex = require("tevgit:core/editor/lexer.lua")
local theme = require("tevgit:core/editor/theme/default.lua")
return {
create = function()
local container = teverse.construct("guiRichTextBox", {
parent = teverse.interface,
size = guiCoord(1, 0, 1, 0),
position = guiCoord(0, 0, 0, 0),
backgroundColour = theme.background
})
teverse.construct("guiTextBox", {
parent = container,
size = guiCoord(1, -20, 0, 24),
position = guiCoord(0, 20, 0, 10),
text = "THIS IS A PROOF OF CONCEPT TEXT EDITOR\nWRITTEN USING OUR LUA API",
textSize = 12,
textColour = theme.foreground,
textAlpha = 0.5,
textWrap = true,
backgroundAlpha = 0,
textFont = "tevurl:fonts/firaCodeBold.otf",
})
local numbers = teverse.construct("guiTextBox", {
parent = container,
size = guiCoord(0, 30, 1, -50),
position = guiCoord(0, 0, 0, 50),
text = "01",
textSize = 18,
textColour = theme.foreground,
textWrap = true,
backgroundColour = theme.highlighted,
textFont = "tevurl:fonts/firaCodeBold.otf",
textAlign = "topRight"
})
local editor = teverse.construct("guiRichTextBox", {
parent = container,
size = guiCoord(1, -35, 1, -50),
position = guiCoord(0, 35, 0, 50),
text = "print(\"Hello World\")\n\n",
textWrap = true,
textSize = 18,
textFont = "tevurl:fonts/firaCodeRegular.otf",
textEditable = true,
textMultiline = true,
name = "editor"
})
editor.backgroundColour = theme.background
editor.textColour = theme.foreground
local function doLex()
editor:clearColours()
local lines = lex(editor.text)
local index = 0
local lastColour = nil
local lineNumbers = ""
for lineNumber, line in pairs(lines) do
local lineCount = 0
for _, token in pairs(line) do
local c = theme[token.type]
if c and lastColour ~= c then
editor:setColour(index + token.posFirst, c)
lastColour = c
end
lineCount = token.posLast
end
index = index + lineCount
lineNumbers = lineNumbers .. string.format("%002d", lineNumber) .. "\n"
end
numbers.text = lineNumbers
end
-- Highlight any pre-entered text
doLex()
local lastStroke = nil
local handler = function()
if lastStroke then
return
end
-- Limit lexxer to once very 0.1 seconds (every keystroke is inefficient)
lastStroke = true
doLex()
sleep(0.1)
lastStroke = nil
end
editor:on("keyUp", handler)
editor:on("changed", handler)
return container, editor
end
}

View File

@ -1,52 +1 @@
local lex = require("tevgit:core/editor/lexer.lua")
local theme = require("tevgit:core/editor/theme/default.lua")
local editor = teverse.construct("guiRichTextBox", {
parent = teverse.interface,
size = guiCoord(1, 0, 1, -50),
position = guiCoord(0, 0, 0, 50),
text = "print(\"Hello World\")\n\n",
textWrap = true,
textFont = "tevurl:fonts/firaCodeRegular.otf",
textEditable = true,
textMultiline = true
})
local function doLex()
editor:clearColours()
editor.backgroundColour = theme.background
editor.textColour = theme.foreground
local lines = lex(editor.text)
local index = 0
local lastColour = nil
for lineNumber, line in pairs(lines) do
local lineCount = 0
for _, token in pairs(line) do
local c = theme[token.type]
if c and lastColour ~= c then
editor:setColour(index + token.posFirst, c)
lastColour = c
end
lineCount = token.posLast
end
index = index + lineCount
end
end
-- Highlight any pre-entered text
doLex()
local lastStroke = nil
editor:on("keyUp", function()
if lastStroke then
return
end
-- Limit lexxer to once very 0.2 seconds (every keystroke is inefficient)
lastStroke = true
sleep(0.2)
doLex()
lastStroke = nil
end)
local editor = require("tevgit:core/editor/editor.lua").create()

View File

@ -24,6 +24,7 @@ local colours = {
return {
background = colours.Base03,
foreground = colours.Base0,
highlighted = colours.Base02,
comment = colours.Base01,
string_start = colours.Cyan,

View File

@ -1,6 +1,8 @@
-- This is the main interface loaded into coreinterface
-- status bar for mobiles:
teverse.construct("guiFrame", {
name = "statusBar",
parent = teverse.coreInterface,
size = guiCoord(1, 0, 0, 50),
position = guiCoord(0, 0, 0, -50),
@ -8,84 +10,61 @@ teverse.construct("guiFrame", {
backgroundAlpha = 0.75
})
local console = require("tevgit:core/teverseUI/console.lua")
local container = teverse.construct("guiFrame", {
local settingsButton = teverse.construct("guiIcon", {
parent = teverse.coreInterface,
size = guiCoord(0, 77, 0, 26),
position = guiCoord(1, -81, 1, -30),
backgroundAlpha = 0.0,
strokeRadius = 13,
zIndex = 1000
})
local homebtn
local ico = teverse.construct("guiIcon", {
parent = container,
size = guiCoord(0, 20, 0, 20),
position = guiCoord(1, -23, 0.5, -10),
size = guiCoord(0, 35, 0, 35),
position = guiCoord(1, -45, 1, -45),
iconId = "wrench",
iconType = "faSolid",
iconColour = colour(0, 0, 0),
iconMax = 12,
iconAlpha = 0.75,
strokeRadius = 10,
strokeAlpha = 0.5,
strokeRadius = 2,
dropShadowAlpha = 0.15,
strokeAlpha = 0.05,
backgroundAlpha = 1,
visible = teverse.networking.localClient ~= nil
visible = teverse.networking.localClient ~= nil,
zIndex = 1000
})
local container = teverse.construct("guiFrame", {
parent = teverse.coreInterface,
size = guiCoord(0, 100, 0, 35),
position = guiCoord(1, -155, 1, -45),
backgroundAlpha = 0,
visible = false
})
local console = require("tevgit:core/teverseUI/console.lua")
local lastClick = 0
ico:on("mouseLeftDown", function()
settingsButton:on("mouseLeftUp", function()
if os.clock() - lastClick < 0.4 then
-- double click
lastClick = 0
console.visible = not console.visible
else
lastClick = os.clock()
container.visible = true
repeat sleep(0.1) until teverse.input.mousePosition.y < container.absolutePosition.y - 25
container.visible = false
end
end)
--if teverse.dev.localTevGit then
homebtn = teverse.construct("guiTextBox", {
local homeButton = teverse.construct("guiIcon", {
parent = container,
size = guiCoord(0, 40, 0, 14),
position = guiCoord(0, 6, 0.5, -7),
text = "HOME",
textAlign = "middle",
textFont = "tevurl:fonts/openSansLight.ttf",
textColour = colour(0, 0, 0),
textSize = 14,
strokeRadius = 7,
strokeAlpha = 0.5,
backgroundAlpha = 0,
visible = false
size = guiCoord(0, 35, 0, 35),
position = guiCoord(1, -35, 0, 0),
iconId = "home",
iconType = "faSolid",
iconColour = colour(0, 0, 0),
iconMax = 12,
iconAlpha = 0.75,
strokeRadius = 2,
dropShadowAlpha = 0.15,
strokeAlpha = 0.05,
backgroundAlpha = 1
})
homebtn:on("mouseLeftUp", function()
homeButton:on("mouseLeftUp", function()
teverse.apps:loadDashboard()
end)
ico:on("mouseLeftUp", function()
container.backgroundAlpha = 1.0
homebtn.visible = true
if teverse.dev.state == "dashboard" then
if teverse.dev.localTevGit then
homebtn.text = "RESET"
homebtn.visible = true
else
homebtn.visible = false
end
else
homebtn.text = "HOME"
homebtn.visible = true
end
repeat sleep(0.1) until teverse.input.mousePosition.y < container.absolutePosition.y - 25
container.backgroundAlpha = 0.0
homebtn.visible = false
end)

View File

@ -5,5 +5,23 @@ return {
title = title,
description = description
}
end,
interactiveCode = function(title, description, code, validator)
return {
type = "titleDescCode",
title = title,
description = description,
code = code,
validator = validator
}
end,
exampleCode = function(title, description, code, exampleOutput)
return {
type = "exampleCode",
title = title,
description = description,
code = code,
output = exampleOutput
}
end
}

View File

@ -4,7 +4,39 @@ return {
name = "Hello World",
description = "test test test",
pages = {
framework.titleDesc("Test ", "Description"),
framework.titleDesc("Test2 ", "Description2")
framework.interactiveCode(
"Saying Hello to the World ",
[[Let's jump straight into writing your first script!
Type Hello World between the two quotation marks, then press run]],
[[print("hello world")]],
function(script, logs)
local correct = script.text:lower() == "print(\"hello world\")"
if not correct then
print("Try again thats not quite right...\n")
else
print("Well done! Press next!\n")
end
return correct
end
),
framework.exampleCode(
"Dissecting your script",
[[A function contains a set of commands that the system follows.
You ran the 'print' function and you passed the parameter "Hello World" to it.
The print function simply outputs the stuff you give it to the console. The console is what you seen on the right of the screen.
Example Output from the script on the left:]],
[[print("Hello World")
print("We can put anything here")
]],
[[Hello World
We can put anything here
]]
),
framework.titleDesc("The end ", "Placeholder")
}
}

View File

@ -8,6 +8,7 @@ local container = teverse.construct("guiScrollView", {
parent = containerNegativePadding,
size = guiCoord(1, 0, 1, -100),
position = guiCoord(0, 0, 0, 50),
canvasSize = guiCoord(1, 0, 1, 0),
backgroundAlpha = 0,
})
@ -26,7 +27,9 @@ local y = 70
local function loadTutorialPage(tutorial, pagei, lessonFrame)
lessonFrame:destroyChildren()
local page = tutorial.pages[pagei]
local allowContinue = true
local btn = nil
if page.type == "titleDesc" then
teverse.construct("guiTextBox", {
parent = lessonFrame,
@ -41,36 +44,56 @@ local function loadTutorialPage(tutorial, pagei, lessonFrame)
teverse.construct("guiTextBox", {
parent = lessonFrame,
size = guiCoord(1.0, -20, 0, 18),
size = guiCoord(1.0, -20, 1, -50),
position = guiCoord(0, 10, 0, 42),
backgroundAlpha = 0,
text = page.description,
textSize = 18,
textAlign = "middleLeft"
textAlign = "topLeft",
textWrap = true
})
elseif page.type == "" then
end
if pagei == #tutorial.pages then
elseif page.type == "titleDescCode" then
teverse.construct("guiTextBox", {
parent = lessonFrame,
size = guiCoord(0, 90, 0, 30),
position = guiCoord(1, -110, 1, -50),
text = "Finished",
textSize = 20,
textAlign = "middle",
textFont = "tevurl:fonts/openSansBold.ttf",
backgroundColour = colour.rgb(235, 187, 83),
textColour = colour.white(),
dropShadowAlpha = 0.2
size = guiCoord(1.0, -20, 0, 32),
position = guiCoord(0, 10, 0, 10),
backgroundAlpha = 0,
text = page.title,
textSize = 32,
textAlign = "middleLeft",
textFont = "tevurl:fonts/openSansBold.ttf"
})
else
local btn = teverse.construct("guiTextBox", {
local desc = teverse.construct("guiTextBox", {
parent = lessonFrame,
size = guiCoord(0, 80, 0, 30),
position = guiCoord(1, -100, 1, -50),
text = "Next",
size = guiCoord(1.0, -20, 1, -50),
position = guiCoord(0, 10, 0, 42),
backgroundAlpha = 0,
text = page.description,
textSize = 18,
textAlign = "topLeft",
textWrap = true
})
local textDimensions = desc.textDimensions.y
desc.size = guiCoord(1, -20, 0, textDimensions)
local output, outputtxt = require("tevgit:core/tutorials/output.lua").create()
output.parent = lessonFrame
output.position = guiCoord(0.5, 10, 0, textDimensions + 52)
output.size = guiCoord(0.5, -20, 1, -(textDimensions + 122))
local editor, editortxt = require("tevgit:core/editor/editor.lua").create()
editor.parent = lessonFrame
editor.position = guiCoord(0, 10, 0, textDimensions + 52)
editor.size = guiCoord(0.5, -20, 1, -(textDimensions + 62))
editortxt.text = page.code
local run = teverse.construct("guiTextBox", {
parent = lessonFrame,
size = guiCoord(0, 90, 0, 30),
position = guiCoord(1, -205, 1, -50),
text = "Run",
textSize = 24,
textAlign = "middle",
textFont = "tevurl:fonts/openSansBold.ttf",
@ -78,12 +101,138 @@ local function loadTutorialPage(tutorial, pagei, lessonFrame)
textColour = colour.white(),
dropShadowAlpha = 0.2
})
teverse.guiHelper.hoverColour(run, colour.rgb(235, 187, 83))
local reset = teverse.construct("guiTextBox", {
parent = lessonFrame,
size = guiCoord(0, 90, 0, 30),
position = guiCoord(1, -310, 1, -50),
text = "Reset",
textSize = 24,
textAlign = "middle",
textFont = "tevurl:fonts/openSansBold.ttf",
backgroundColour = colour.rgb(74, 140, 122),
textColour = colour.white(),
dropShadowAlpha = 0.2
})
teverse.guiHelper.hoverColour(reset, colour.rgb(235, 187, 83))
allowContinue = false
run:on("mouseLeftUp", function()
outputtxt.text = ""
local f, msg = loadstring(editortxt.text)
if not f then
outputtxt.text = "Error when running your code:\n"..msg
else
local success, result = pcall(f)
if not success then
outputtxt.text = "Error when running your code:\n"..result
else
if page.validator then
allowContinue = page.validator(editortxt, outputtxt)
else
allowContinue = true
end
if allowContinue and btn then
btn.backgroundColour = colour.rgb(235, 187, 83)
end
end
end
end)
reset:on("mouseLeftUp", function()
outputtxt.text = ""
editortxt.text = page.code
end)
elseif page.type == "exampleCode" then
local editor, editortxt = require("tevgit:core/editor/editor.lua").create()
editor.parent = lessonFrame
editor.position = guiCoord(0, 10, 0, 10)
editor.size = guiCoord(0.5, -20, 1, -20)
editortxt.text = page.code
editortxt.textEditable = false
teverse.construct("guiTextBox", {
parent = lessonFrame,
size = guiCoord(0.5, -20, 0, 32),
position = guiCoord(0.5, 10, 0, 10),
backgroundAlpha = 0,
text = page.title,
textSize = 32,
textAlign = "middleLeft",
textFont = "tevurl:fonts/openSansBold.ttf"
})
local desc = teverse.construct("guiTextBox", {
parent = lessonFrame,
size = guiCoord(0.5, -20, 1, -100),
position = guiCoord(0.5, 10, 0, 42),
backgroundAlpha = 0,
text = page.description,
textSize = 18,
textAlign = "topLeft",
textWrap = true,
active = false
})
if page.output then
local descDimensions = desc.textDimensions
local output, outputtxt = require("tevgit:core/tutorials/output.lua").create(true)
outputtxt.text = page.output
output.parent = lessonFrame
output.position = guiCoord(0.5, 10, 0, descDimensions.y + 45)
output.size = guiCoord(0.5, -20, 0, outputtxt.textDimensions.y + 44)
end
allowContinue = true
end
if pagei == #tutorial.pages then
btn = teverse.construct("guiTextBox", {
parent = lessonFrame,
size = guiCoord(0, 90, 0, 30),
position = guiCoord(1, -110, 1, -50),
text = "Finished",
textSize = 20,
textAlign = "middle",
textFont = "tevurl:fonts/openSansBold.ttf",
backgroundColour = colour.rgb(122, 122, 122),
textColour = colour.white(),
dropShadowAlpha = 0.2
})
else
btn = teverse.construct("guiTextBox", {
parent = lessonFrame,
size = guiCoord(0, 80, 0, 30),
position = guiCoord(1, -100, 1, -50),
text = "Next",
textSize = 24,
textAlign = "middle",
textFont = "tevurl:fonts/openSansBold.ttf",
backgroundColour = allowContinue and colour.rgb(74, 140, 122) or colour.rgb(122, 122, 122),
textColour = colour.white(),
dropShadowAlpha = 0.2
})
btn:on("mouseLeftUp", function()
loadTutorialPage(tutorial, pagei + 1, lessonFrame)
if allowContinue then
loadTutorialPage(tutorial, pagei + 1, lessonFrame)
end
end)
teverse.guiHelper.hoverColour(btn, colour.rgb(235, 187, 83))
btn:on("mouseEnter", function()
if allowContinue then
btn.backgroundColour = colour.rgb(235, 187, 83)
else
btn.backgroundColour = colour.rgb(122, 122, 122)
end
end)
btn:on("mouseExit", function()
if allowContinue then
btn.backgroundColour = colour.rgb(74, 140, 122)
end
end)
end
end

46
core/tutorials/output.lua Normal file
View File

@ -0,0 +1,46 @@
local theme = require("tevgit:core/editor/theme/default.lua")
return {
create = function(doNotHook)
local container = teverse.construct("guiRichTextBox", {
parent = teverse.interface,
size = guiCoord(1, 0, 1, 0),
position = guiCoord(0, 0, 0, 0),
backgroundColour = theme.background
})
teverse.construct("guiTextBox", {
parent = container,
size = guiCoord(1, -20, 0, 12),
position = guiCoord(0, 20, 0, 10),
text = "OUTPUT",
textSize = 12,
textColour = theme.foreground,
textWrap = true,
backgroundAlpha = 0,
textFont = "tevurl:fonts/firaCodeBold.otf",
})
local text = teverse.construct("guiRichTextBox", {
parent = container,
size = guiCoord(1, -40, 1, -34),
position = guiCoord(0, 20, 0, 34),
text = "",
textWrap = true,
textSize = 18,
textFont = "tevurl:fonts/firaCodeRegular.otf",
textMultiline = true,
backgroundAlpha = 0,
textColour = theme.foreground,
name = "output"
})
if not doNotHook then
teverse.debug:on("print", function(msg)
text.text = string.sub(os.date("%H:%M:%S") .. " : " .. msg .. "\n" .. text.text, 0, 500)
end)
end
return container, text
end
}